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