summary refs log tree commit diff stats
path: root/hw/vfio/container.c
diff options
context:
space:
mode:
authorSteve Sistare <steven.sistare@oracle.com>2025-06-10 08:39:19 -0700
committerCédric Le Goater <clg@redhat.com>2025-06-11 14:01:58 +0200
commit7e9f21411302d823e9ee563ff6a2a40b1ffc1266 (patch)
tree0c6c8539d7c63e0b84ba19dd95278b5a91f983f9 /hw/vfio/container.c
parent1faadd96306b428f2e8e35f71761c333a6777f55 (diff)
downloadfocaccia-qemu-7e9f21411302d823e9ee563ff6a2a40b1ffc1266.tar.gz
focaccia-qemu-7e9f21411302d823e9ee563ff6a2a40b1ffc1266.zip
vfio/container: restore DMA vaddr
In new QEMU, do not register the memory listener at device creation time.
Register it later, in the container post_load handler, after all vmstate
that may affect regions and mapping boundaries has been loaded.  The
post_load registration will cause the listener to invoke its callback on
each flat section, and the calls will match the mappings remembered by the
kernel.

The listener calls a special dma_map handler that passes the new VA of each
section to the kernel using VFIO_DMA_MAP_FLAG_VADDR.  Restore the normal
handler at the end.

Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Link: https://lore.kernel.org/qemu-devel/1749569991-25171-7-git-send-email-steven.sistare@oracle.com
Signed-off-by: Cédric Le Goater <clg@redhat.com>
Diffstat (limited to 'hw/vfio/container.c')
-rw-r--r--hw/vfio/container.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/hw/vfio/container.c b/hw/vfio/container.c
index 5caae4ccae..936ce37f19 100644
--- a/hw/vfio/container.c
+++ b/hw/vfio/container.c
@@ -136,6 +136,8 @@ static int vfio_legacy_dma_unmap_one(const VFIOContainerBase *bcontainer,
     int ret;
     Error *local_err = NULL;
 
+    g_assert(!cpr_is_incoming());
+
     if (iotlb && vfio_container_dirty_tracking_is_started(bcontainer)) {
         if (!vfio_container_devices_dirty_tracking_is_supported(bcontainer) &&
             bcontainer->dirty_pages_supported) {
@@ -690,8 +692,17 @@ static bool vfio_container_connect(VFIOGroup *group, AddressSpace *as,
     }
     group_was_added = true;
 
-    if (!vfio_listener_register(bcontainer, errp)) {
-        goto fail;
+    /*
+     * If CPR, register the listener later, after all state that may
+     * affect regions and mapping boundaries has been cpr load'ed.  Later,
+     * the listener will invoke its callback on each flat section and call
+     * dma_map to supply the new vaddr, and the calls will match the mappings
+     * remembered by the kernel.
+     */
+    if (!cpr_is_incoming()) {
+        if (!vfio_listener_register(bcontainer, errp)) {
+            goto fail;
+        }
     }
 
     bcontainer->initialized = true;