aboutsummaryrefslogtreecommitdiff
path: root/hw/vfio/common.c
diff options
context:
space:
mode:
authorJoao Martins <joao.m.martins@oracle.com>2023-03-07 12:54:48 +0000
committerAlex Williamson <alex.williamson@redhat.com>2023-03-07 10:21:22 -0700
commite46883204c384f992088f8c3ea713f7e1c2d5a6d (patch)
treee88ee1d09482d9107bdc21960013aa93fa04735d /hw/vfio/common.c
parentb153402a8941c2193e91ac50ed9720c7da6ee8db (diff)
vfio/migration: Block migration with vIOMMU
Migrating with vIOMMU will require either tracking maximum IOMMU supported address space (e.g. 39/48 address width on Intel) or range-track current mappings and dirty track the new ones post starting dirty tracking. This will be done as a separate series, so add a live migration blocker until that is fixed. Signed-off-by: Joao Martins <joao.m.martins@oracle.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/r/20230307125450.62409-14-joao.m.martins@oracle.com Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Diffstat (limited to 'hw/vfio/common.c')
-rw-r--r--hw/vfio/common.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 334c625858..539246e332 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -362,6 +362,7 @@ bool vfio_mig_active(void)
}
static Error *multiple_devices_migration_blocker;
+static Error *giommu_migration_blocker;
static unsigned int vfio_migratable_device_num(void)
{
@@ -413,6 +414,51 @@ void vfio_unblock_multiple_devices_migration(void)
multiple_devices_migration_blocker = NULL;
}
+static bool vfio_viommu_preset(void)
+{
+ VFIOAddressSpace *space;
+
+ QLIST_FOREACH(space, &vfio_address_spaces, list) {
+ if (space->as != &address_space_memory) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+int vfio_block_giommu_migration(Error **errp)
+{
+ int ret;
+
+ if (giommu_migration_blocker ||
+ !vfio_viommu_preset()) {
+ return 0;
+ }
+
+ error_setg(&giommu_migration_blocker,
+ "Migration is currently not supported with vIOMMU enabled");
+ ret = migrate_add_blocker(giommu_migration_blocker, errp);
+ if (ret < 0) {
+ error_free(giommu_migration_blocker);
+ giommu_migration_blocker = NULL;
+ }
+
+ return ret;
+}
+
+void vfio_unblock_giommu_migration(void)
+{
+ if (!giommu_migration_blocker ||
+ vfio_viommu_preset()) {
+ return;
+ }
+
+ migrate_del_blocker(giommu_migration_blocker);
+ error_free(giommu_migration_blocker);
+ giommu_migration_blocker = NULL;
+}
+
static void vfio_set_migration_error(int err)
{
MigrationState *ms = migrate_get_current();