>-----Original Message-----
>From: Steve Sistare <steven.sist...@oracle.com>
>Subject: [PATCH V5 33/38] 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.
>
>Skip bind, and use the devid from CPR state.
>
>Skip allocation of, and attachment to, ioas_id. Recover ioas_id from CPR
>state, and use it to find a matching container, if any, before creating a
>new one.
>
>This reconstruction is not complete. hwpt_id is handled in a subsequent
>patch.
>
>Signed-off-by: Steve Sistare <steven.sist...@oracle.com>
>---
> hw/vfio/iommufd.c | 30 ++++++++++++++++++++++++++++--
> 1 file changed, 28 insertions(+), 2 deletions(-)
>
>diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
>index f0d57ea..a650517 100644
>--- a/hw/vfio/iommufd.c
>+++ b/hw/vfio/iommufd.c
>@@ -25,6 +25,7 @@
> #include "system/reset.h"
> #include "qemu/cutils.h"
> #include "qemu/chardev_open.h"
>+#include "migration/cpr.h"
> #include "pci.h"
> #include "vfio-iommufd.h"
> #include "vfio-helpers.h"
>@@ -121,6 +122,10 @@ static bool
>iommufd_cdev_connect_and_bind(VFIODevice *vbasedev, Error **errp)
> goto err_kvm_device_add;
> }
>
>+ if (cpr_is_incoming()) {
>+ goto skip_bind;
>+ }
>+
> /* Bind device to iommufd */
> bind.iommufd = iommufd->fd;
> if (ioctl(vbasedev->fd, VFIO_DEVICE_BIND_IOMMUFD, &bind)) {
>@@ -132,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:
I'm not sure if we should take above trace for CPR..
> return true;
> err_bind:
> iommufd_cdev_kvm_device_del(vbasedev);
>@@ -421,7 +428,9 @@ static bool iommufd_cdev_attach_container(VFIODevice
>*vbasedev,
> return iommufd_cdev_autodomains_get(vbasedev, container, errp);
> }
>
>- return !iommufd_cdev_attach_ioas_hwpt(vbasedev, container->ioas_id, errp);
>+ /* If CPR, we are already attached to ioas_id. */
>+ return cpr_is_incoming() ||
>+ !iommufd_cdev_attach_ioas_hwpt(vbasedev, container->ioas_id, errp);
> }
>
> static void iommufd_cdev_detach_container(VFIODevice *vbasedev,
>@@ -510,6 +519,7 @@ static bool iommufd_cdev_attach(const char *name,
>VFIODevice *vbasedev,
> VFIOAddressSpace *space;
> struct vfio_device_info dev_info = { .argsz = sizeof(dev_info) };
> int ret, devfd;
>+ bool res;
> uint32_t ioas_id;
> Error *err = NULL;
> const VFIOIOMMUClass *iommufd_vioc =
>@@ -540,7 +550,16 @@ static bool iommufd_cdev_attach(const char *name,
>VFIODevice *vbasedev,
> vbasedev->iommufd != container->be) {
> continue;
> }
>- if (!iommufd_cdev_attach_container(vbasedev, container, &err)) {
>+
>+ if (!cpr_is_incoming()) {
>+ res = iommufd_cdev_attach_container(vbasedev, container, &err);
>+ } else if (vbasedev->cpr.ioas_id == container->ioas_id) {
>+ res = true;
>+ } else {
>+ continue;
>+ }
>+
>+ if (!res) {
> const char *msg = error_get_pretty(err);
>
> trace_iommufd_cdev_fail_attach_existing_container(msg);
>@@ -557,6 +576,11 @@ static bool iommufd_cdev_attach(const char *name,
>VFIODevice *vbasedev,
> }
> }
>
>+ if (cpr_is_incoming()) {
>+ ioas_id = vbasedev->cpr.ioas_id;
>+ 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;
>@@ -564,10 +588,12 @@ static bool iommufd_cdev_attach(const char *name,
>VFIODevice *vbasedev,
>
> trace_iommufd_cdev_alloc_ioas(vbasedev->iommufd->fd, ioas_id);
>
>+skip_ioas_alloc:
Same here, others look good.
> container =
>VFIO_IOMMU_IOMMUFD(object_new(TYPE_VFIO_IOMMU_IOMMUFD));
> container->be = vbasedev->iommufd;
> container->ioas_id = ioas_id;
> QLIST_INIT(&container->hwpt_list);
>+ vbasedev->cpr.ioas_id = ioas_id;
>
> bcontainer = &container->bcontainer;
> vfio_address_space_insert(space, bcontainer);
>--
>1.8.3.1