So far, cpr-luo does not support preserving and retrieving VFIO resources
across a kexec reboot. In the future, this may be supported by treating
VFIO as a live-migratable device when applicable, that is, by saving and
loading VFIO and vendor-specific state across kexec, as mlx5_vfio_pci does.
In addition, the upstream linux kernel work is ongoing to preserve and
retrieve PCI, IOMMU, and VFIO state across kexec.

Block cpr-luo migration whenever a VFIO is involved, just like cpr-exec and
cpr-transfer.

(qemu) migrate_set_parameter mode cpr-luo
(qemu) migrate -d file:cpr-luo.state
Error: VFIO: cpr-luo is not supported

This does not affect the existing cpr-transfer and cpr-exec support.

Signed-off-by: Dongli Zhang <[email protected]>
---
 hw/vfio/cpr-iommufd.c      | 17 ++++++++++++++---
 hw/vfio/cpr-legacy.c       |  8 ++++++++
 include/hw/vfio/vfio-cpr.h |  1 +
 include/system/iommufd.h   |  1 +
 4 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/hw/vfio/cpr-iommufd.c b/hw/vfio/cpr-iommufd.c
index 6758c73b6b..803fc0cd51 100644
--- a/hw/vfio/cpr-iommufd.c
+++ b/hw/vfio/cpr-iommufd.c
@@ -157,10 +157,20 @@ bool vfio_iommufd_cpr_register_iommufd(IOMMUFDBackend 
*be, Error **errp)
 {
     Error **cpr_blocker = &be->cpr_blocker;
 
+    error_setg(&be->luo_blocker, "VFIO: cpr-luo is not supported");
+    if (migrate_add_blocker_modes(&be->luo_blocker,
+                                  BIT(MIG_MODE_CPR_LUO), errp) < 0) {
+        return false;
+    }
+
     if (!vfio_cpr_supported(be, cpr_blocker)) {
-        return migrate_add_blocker_modes(cpr_blocker,
-                    BIT(MIG_MODE_CPR_TRANSFER) | BIT(MIG_MODE_CPR_EXEC),
-                    errp) == 0;
+        if (migrate_add_blocker_modes(cpr_blocker,
+            BIT(MIG_MODE_CPR_TRANSFER) | BIT(MIG_MODE_CPR_EXEC), errp) < 0) {
+            migrate_del_blocker(&be->luo_blocker);
+            return false;
+        }
+
+        return true;
     }
 
     vmstate_register(NULL, -1, &iommufd_cpr_vmstate, be);
@@ -172,6 +182,7 @@ void vfio_iommufd_cpr_unregister_iommufd(IOMMUFDBackend *be)
 {
     vmstate_unregister(NULL, &iommufd_cpr_vmstate, be);
     migrate_del_blocker(&be->cpr_blocker);
+    migrate_del_blocker(&be->luo_blocker);
 }
 
 bool vfio_iommufd_cpr_register_container(VFIOIOMMUFDContainer *container,
diff --git a/hw/vfio/cpr-legacy.c b/hw/vfio/cpr-legacy.c
index 2d40d8baea..9160e95f27 100644
--- a/hw/vfio/cpr-legacy.c
+++ b/hw/vfio/cpr-legacy.c
@@ -171,6 +171,13 @@ bool 
vfio_legacy_cpr_register_container(VFIOLegacyContainer *container,
     VFIOContainer *bcontainer = VFIO_IOMMU(container);
     Error **cpr_blocker = &container->cpr.blocker;
 
+    error_setg(&container->cpr.luo_blocker,
+               "VFIO: cpr-luo is not supported");
+    if (migrate_add_blocker_modes(&container->cpr.luo_blocker,
+                                  BIT(MIG_MODE_CPR_LUO), errp) < 0) {
+        return false;
+    }
+
     migration_add_notifier_mode(&bcontainer->cpr_reboot_notifier,
                                 vfio_cpr_reboot_notifier,
                                 MIG_MODE_CPR_REBOOT);
@@ -199,6 +206,7 @@ void 
vfio_legacy_cpr_unregister_container(VFIOLegacyContainer *container)
     migrate_del_blocker(&container->cpr.blocker);
     vmstate_unregister(NULL, &vfio_container_vmstate, container);
     migration_remove_notifier(&container->cpr.transfer_notifier);
+    migrate_del_blocker(&container->cpr.luo_blocker);
 }
 
 /*
diff --git a/include/hw/vfio/vfio-cpr.h b/include/hw/vfio/vfio-cpr.h
index ecabe0c747..8d885fe404 100644
--- a/include/hw/vfio/vfio-cpr.h
+++ b/include/hw/vfio/vfio-cpr.h
@@ -26,6 +26,7 @@ typedef int (*dma_map_fn)(const struct VFIOContainer 
*bcontainer,
 
 typedef struct VFIOContainerCPR {
     Error *blocker;
+    Error *luo_blocker;
     bool vaddr_unmapped;
     NotifierWithReturn transfer_notifier;
     MemoryListener remap_listener;
diff --git a/include/system/iommufd.h b/include/system/iommufd.h
index 17bf1a3727..182a71df77 100644
--- a/include/system/iommufd.h
+++ b/include/system/iommufd.h
@@ -33,6 +33,7 @@ struct IOMMUFDBackend {
     int fd;            /* /dev/iommu file descriptor */
     bool owned;        /* is the /dev/iommu opened internally */
     Error *cpr_blocker;/* set if be does not support CPR */
+    Error *luo_blocker;
     uint32_t users;
 
     /*< public >*/
-- 
2.43.5


Reply via email to