hw_caps is normally derived during realize, at vfio_device_hiod_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_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 | 14 ++++++++++++++
 hw/vfio/iommufd.c     |  3 ++-
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/hw/vfio/cpr-iommufd.c b/hw/vfio/cpr-iommufd.c
index 8453d76..a1ac517 100644
--- a/hw/vfio/cpr-iommufd.c
+++ b/hw/vfio/cpr-iommufd.c
@@ -99,12 +99,26 @@ 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_realize(vbasedev, &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 3fc530d..693ed19 100644
--- a/hw/vfio/iommufd.c
+++ b/hw/vfio/iommufd.c
@@ -536,7 +536,8 @@ static bool iommufd_cdev_attach(const char *name, 
VFIODevice *vbasedev,
      * FD to be connected and having a devid to be able to successfully call
      * iommufd_backend_get_device_info().
      */
-    if (!vfio_device_hiod_realize(vbasedev, errp)) {
+    if (!vbasedev->cpr.reused &&
+        !vfio_device_hiod_realize(vbasedev, errp)) {
         goto err_alloc_ioas;
     }
 
-- 
1.8.3.1


Reply via email to