@@ -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()
}
};
@@ -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;
}
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.sistare@oracle.com> --- hw/vfio/cpr-iommufd.c | 14 ++++++++++++++ hw/vfio/iommufd.c | 3 ++- 2 files changed, 16 insertions(+), 1 deletion(-)