Block CPR if the container has any mdevs (mediated devices). CPR is not supported for legacy containers and mdevs. It will be supported for iommufd containers with mdevs in a future patch.
Signed-off-by: Steve Sistare <steven.sist...@oracle.com> --- hw/vfio/pci.c | 10 ++++++++++ include/hw/vfio/vfio-common.h | 1 + include/hw/vfio/vfio-container-base.h | 2 ++ 3 files changed, 13 insertions(+) diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index b5e7592..872b07c 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -3100,6 +3100,13 @@ static void vfio_realize(PCIDevice *pdev, Error **errp) is_mdev = subsys && (strcmp(subsys, "/sys/bus/mdev") == 0); free(subsys); + vbasedev->is_mdev = is_mdev; + if (is_mdev && !vbasedev->bcontainer->n_mdev++) { + error_setg(&vbasedev->bcontainer->cpr_mdev_blocker, + "CPR does not support vfio mdev"); + migrate_add_blocker_modes(&vbasedev->bcontainer->cpr_mdev_blocker, + &error_fatal, MIG_MODE_CPR_EXEC, -1); + } trace_vfio_mdev(vbasedev->name, is_mdev); if (vbasedev->ram_block_discard_allowed && !is_mdev) { @@ -3387,6 +3394,9 @@ static void vfio_exitfn(PCIDevice *pdev) vfio_teardown_msi(vdev); vfio_pci_disable_rp_atomics(vdev); vfio_bars_exit(vdev); + if (vbasedev->is_mdev && !--vbasedev->bcontainer->n_mdev) { + migrate_del_blocker(&vbasedev->bcontainer->cpr_mdev_blocker); + } vfio_migration_exit(vbasedev); pci_device_unset_iommu_device(pdev); } diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h index 8aa02d4..342c40f 100644 --- a/include/hw/vfio/vfio-common.h +++ b/include/hw/vfio/vfio-common.h @@ -133,6 +133,7 @@ typedef struct VFIODevice { OnOffAuto pre_copy_dirty_page_tracking; bool dirty_pages_supported; bool dirty_tracking; + bool is_mdev; HostIOMMUDevice *hiod; int devid; IOMMUFDBackend *iommufd; diff --git a/include/hw/vfio/vfio-container-base.h b/include/hw/vfio/vfio-container-base.h index f8b7b26..e29cbb8 100644 --- a/include/hw/vfio/vfio-container-base.h +++ b/include/hw/vfio/vfio-container-base.h @@ -45,6 +45,7 @@ typedef struct VFIOContainerBase { uint64_t max_dirty_bitmap_size; unsigned long pgsizes; unsigned int dma_max_mappings; + unsigned int n_mdev; bool dirty_pages_supported; QLIST_HEAD(, VFIOGuestIOMMU) giommu_list; QLIST_HEAD(, VFIORamDiscardListener) vrdl_list; @@ -54,6 +55,7 @@ typedef struct VFIOContainerBase { NotifierWithReturn cpr_reboot_notifier; NotifierWithReturn cpr_exec_notifier; Error *cpr_blocker; + Error *cpr_mdev_blocker; } VFIOContainerBase; typedef struct VFIOGuestIOMMU { -- 1.8.3.1