>-----Original Message-----
>From: Steve Sistare <steven.sist...@oracle.com>
>Subject: [PATCH V3 37/42] vfio/iommufd: reconstruct device
>
>Reconstruct userland device state after CPR.  During vfio_realize, skip
>all ioctls that configure the device, as it was already configured in old
>QEMU.
>
>Save the ioas_id in vmstate, and skip its allocation in vfio_realize.
>Because we skip ioctl's, it is not needed at realize time.  However, we do
>need the range info, so defer the call to iommufd_cdev_get_info_iova_range
>to a post_load handler, at which time the ioas_id is known.
>
>This reconstruction is not complete.  hwpt_id and devid need special
>treatment, handled in subsequent patches.
>
>Signed-off-by: Steve Sistare <steven.sist...@oracle.com>
>---
> hw/vfio/cpr-iommufd.c |  8 ++++++++
> hw/vfio/iommufd.c     | 17 +++++++++++++++++
> 2 files changed, 25 insertions(+)
>
>diff --git a/hw/vfio/cpr-iommufd.c b/hw/vfio/cpr-iommufd.c
>index b760bd3..3d430f0 100644
>--- a/hw/vfio/cpr-iommufd.c
>+++ b/hw/vfio/cpr-iommufd.c
>@@ -31,6 +31,13 @@ static int vfio_container_post_load(void *opaque, int
>version_id)
>     VFIOIOMMUFDContainer *container = opaque;
>     VFIOContainerBase *bcontainer = &container->bcontainer;
>     VFIODevice *vbasedev;
>+    Error *err = NULL;
>+    uint32_t ioas_id = container->ioas_id;
>+
>+    if (!iommufd_cdev_get_info_iova_range(container, ioas_id, &err)) {
>+        error_report_err(err);
>+        return -1;
>+    }
>
>     QLIST_FOREACH(vbasedev, &bcontainer->device_list, container_next) {
>         vbasedev->cpr.reused = false;
>@@ -47,6 +54,7 @@ static const VMStateDescription vfio_container_vmstate = {
>     .post_load = vfio_container_post_load,
>     .needed = cpr_needed_for_reuse,
>     .fields = (VMStateField[]) {
>+        VMSTATE_UINT32(ioas_id, VFIOIOMMUFDContainer),
>         VMSTATE_END_OF_LIST()
>     }
> };
>diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
>index 046f601..c49a7e7 100644
>--- a/hw/vfio/iommufd.c
>+++ b/hw/vfio/iommufd.c
>@@ -122,6 +122,10 @@ static bool
>iommufd_cdev_connect_and_bind(VFIODevice *vbasedev, Error **errp)
>         goto err_kvm_device_add;
>     }
>
>+    if (vbasedev->cpr.reused) {
>+        goto skip_bind;
>+    }
>+
>     /* Bind device to iommufd */
>     bind.iommufd = iommufd->fd;
>     if (ioctl(vbasedev->fd, VFIO_DEVICE_BIND_IOMMUFD, &bind)) {
>@@ -133,6 +137,8 @@ static bool
>iommufd_cdev_connect_and_bind(VFIODevice *vbasedev, Error **errp)
>     vbasedev->devid = bind.out_devid;
>     trace_iommufd_cdev_connect_and_bind(bind.iommufd, vbasedev->name,
>                                         vbasedev->fd, vbasedev->devid);
>+
>+skip_bind:
>     return true;
> err_bind:
>     iommufd_cdev_kvm_device_del(vbasedev);
>@@ -580,6 +586,11 @@ static bool iommufd_cdev_attach(const char *name,
>VFIODevice *vbasedev,
>         }
>     }
>
>+    if (vbasedev->cpr.reused) {
>+        ioas_id = -1;           /* ioas_id will be received from vmstate */
>+        goto skip_ioas_alloc;
>+    }
>+
>     /* Need to allocate a new dedicated container */
>     if (!iommufd_backend_alloc_ioas(vbasedev->iommufd, &ioas_id, errp)) {
>         goto err_alloc_ioas;
>@@ -587,6 +598,7 @@ static bool iommufd_cdev_attach(const char *name,
>VFIODevice *vbasedev,
>
>     trace_iommufd_cdev_alloc_ioas(vbasedev->iommufd->fd, ioas_id);
>
>+skip_ioas_alloc:
>     container =
>VFIO_IOMMU_IOMMUFD(object_new(TYPE_VFIO_IOMMU_IOMMUFD));
>     container->be = vbasedev->iommufd;
>     container->ioas_id = ioas_id;
>@@ -605,6 +617,10 @@ static bool iommufd_cdev_attach(const char *name,
>VFIODevice *vbasedev,
>         goto err_discard_disable;
>     }
>
>+    if (vbasedev->cpr.reused) {
>+        goto skip_info;

I suspect this will break virtio-iommu, see virtio_iommu_set_iommu_device().
When virtio-iommu try to get host_iova_ranges, it's not ready until post load.

>+    }
>+
>     if (!iommufd_cdev_get_info_iova_range(container, ioas_id, &err)) {
>         error_append_hint(&err,
>                    "Fallback to default 64bit IOVA range and 4K page size\n");
>@@ -613,6 +629,7 @@ static bool iommufd_cdev_attach(const char *name,
>VFIODevice *vbasedev,
>         bcontainer->pgsizes = qemu_real_host_page_size();
>     }
>
>+skip_info:
>     if (!vfio_listener_register(bcontainer, errp)) {
>         goto err_listener_register;
>     }
>--
>1.8.3.1


Reply via email to