hw_caps is normally derived during realize, at
vfio_device_hiod_create_and_realize -> hiod_iommufd_vfio_realize ->
iommufd_backend_get_device_info.  However, this depends on the devid, which
is not preserved during CPR.

Save devid in vmstate.  Defer the vfio_device_hiod_create_and_realize call
to post_load time, after devid has been recovered from vmstate.

Signed-off-by: Steve Sistare <steven.sist...@oracle.com>
---
 hw/vfio/cpr-iommufd.c  | 15 +++++++++++++++
 hw/vfio/iommufd.c      |  6 ++----
 hw/vfio/vfio-iommufd.h |  3 +++
 3 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/hw/vfio/cpr-iommufd.c b/hw/vfio/cpr-iommufd.c
index 3d430f0..24cdf10 100644
--- a/hw/vfio/cpr-iommufd.c
+++ b/hw/vfio/cpr-iommufd.c
@@ -100,12 +100,27 @@ void 
vfio_iommufd_cpr_unregister_container(VFIOIOMMUFDContainer *container)
     migration_remove_notifier(&bcontainer->cpr_reboot_notifier);
 }
 
+static int vfio_device_post_load(void *opaque, int version_id)
+{
+    VFIODevice *vbasedev = opaque;
+    Error *err = NULL;
+
+    if (!vfio_device_hiod_create_and_realize(vbasedev,
+                     TYPE_HOST_IOMMU_DEVICE_IOMMUFD_VFIO, &err)) {
+        error_report_err(err);
+        return false;
+    }
+    return true;
+}
+
 static const VMStateDescription vfio_device_vmstate = {
     .name = "vfio-iommufd-device",
     .version_id = 0,
     .minimum_version_id = 0,
+    .post_load = vfio_device_post_load,
     .needed = cpr_needed_for_reuse,
     .fields = (VMStateField[]) {
+        VMSTATE_INT32(devid, VFIODevice),
         VMSTATE_END_OF_LIST()
     }
 };
diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
index c49a7e7..d980684 100644
--- a/hw/vfio/iommufd.c
+++ b/hw/vfio/iommufd.c
@@ -32,9 +32,6 @@
 #include "vfio-helpers.h"
 #include "vfio-listener.h"
 
-#define TYPE_HOST_IOMMU_DEVICE_IOMMUFD_VFIO             \
-            TYPE_HOST_IOMMU_DEVICE_IOMMUFD "-vfio"
-
 static int iommufd_cdev_map(const VFIOContainerBase *bcontainer, hwaddr iova,
                             ram_addr_t size, void *vaddr, bool readonly)
 {
@@ -557,7 +554,8 @@ static bool iommufd_cdev_attach(const char *name, 
VFIODevice *vbasedev,
 
     space = vfio_address_space_get(as);
 
-    if (!vfio_device_hiod_create_and_realize(vbasedev,
+    if (!vbasedev->cpr.reused &&
+        !vfio_device_hiod_create_and_realize(vbasedev,
             TYPE_HOST_IOMMU_DEVICE_IOMMUFD_VFIO, errp)) {
         goto err_alloc_ioas;
     }
diff --git a/hw/vfio/vfio-iommufd.h b/hw/vfio/vfio-iommufd.h
index cc57a05..148ce89 100644
--- a/hw/vfio/vfio-iommufd.h
+++ b/hw/vfio/vfio-iommufd.h
@@ -11,6 +11,9 @@
 
 #include "hw/vfio/vfio-container-base.h"
 
+#define TYPE_HOST_IOMMU_DEVICE_IOMMUFD_VFIO             \
+            TYPE_HOST_IOMMU_DEVICE_IOMMUFD "-vfio"
+
 typedef struct VFIODevice VFIODevice;
 
 typedef struct VFIOIOASHwpt {
-- 
1.8.3.1


Reply via email to