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>
master
Joao Martins 2023-03-07 12:54:48 +00:00 committed by Alex Williamson
parent b153402a89
commit e46883204c
4 changed files with 54 additions and 0 deletions

View File

@ -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();

View File

@ -634,6 +634,11 @@ int vfio_migration_probe(VFIODevice *vbasedev, Error **errp)
return ret;
}
ret = vfio_block_giommu_migration(errp);
if (ret) {
return ret;
}
trace_vfio_migration_probe(vbasedev->name);
return 0;

View File

@ -3185,6 +3185,7 @@ static void vfio_instance_finalize(Object *obj)
*/
vfio_put_device(vdev);
vfio_put_group(group);
vfio_unblock_giommu_migration();
}
static void vfio_exitfn(PCIDevice *pdev)

View File

@ -222,6 +222,8 @@ extern VFIOGroupList vfio_group_list;
bool vfio_mig_active(void);
int vfio_block_multiple_devices_migration(Error **errp);
void vfio_unblock_multiple_devices_migration(void);
int vfio_block_giommu_migration(Error **errp);
void vfio_unblock_giommu_migration(void);
int64_t vfio_mig_bytes_transferred(void);
#ifdef CONFIG_LINUX