libvhost-user: return the backend mapping address for added regions

In postcopy mode the backend must tell QEMU where it mapped a region, so
that QEMU can translate the backend's fault addresses back into a RAMBlock
and offset.  vu_add_mem_reg() works on a copy of the region and lets
_vu_add_mem_reg() fill the mapping address into that copy, but never writes
it back into the reply payload.  QEMU then stores its own address as the
postcopy client base, so fault resolution fails:

  vhost_user_postcopy_fault_handler: Failed to find region for fault ...

The VHOST_USER_SET_MEM_TABLE path is unaffected, it fills the payload
directly.  Put the updated region back into the payload before replying; a
pointer into the payload cannot be used instead, as VhostUserMsg is packed.

Fixes: ec94c8e621 ("Support adding individual regions in libvhost-user")
Signed-off-by: Bin Guo <guobin@linux.alibaba.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260813095501.20282-3-guobin@linux.alibaba.com>
This commit is contained in:
Bin Guo authored and Michael S. Tsirkin committed 2026-09-11 15:54:47 -04:00
1 parent 228117b4cd
commit 905e8c7e26
1 file changed
+7 -1
+7 -1
View File
@@ -989,7 +989,13 @@ vu_add_mem_reg(VuDev *dev, VhostUserMsg *vmsg) {
close(vmsg->fds[0]); close(vmsg->fds[0]);
if (dev->postcopy_listening) { if (dev->postcopy_listening) {
/* Send the message back to qemu with the addresses filled in. */ /*
* Send the message back to qemu with the addresses filled in.
* _vu_add_mem_reg() worked on our copy of the region, so it has to be
* put back into the message payload. A pointer into the payload
* cannot be handed out instead, VhostUserMsg is packed.
*/
vmsg->payload.memreg.region = m;
vmsg->fd_num = 0; vmsg->fd_num = 0;
DPRINT("Successfully added new region in postcopy\n"); DPRINT("Successfully added new region in postcopy\n");
return true; return true;