aboutsummaryrefslogtreecommitdiff
path: root/hw/vfio/common.c
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2023-06-30 08:11:08 +0200
committerRichard Henderson <richard.henderson@linaro.org>2023-06-30 08:11:08 +0200
commit408015a97dbe48a9dde8c0d2526c9312691952e7 (patch)
treeb41b1a9349392da698def212ff60e19f7043f851 /hw/vfio/common.c
parentf7884164cbe3743c3bd2acc9daf877497fdb5fa3 (diff)
parent0cc889c8826cefa5b80110d31a62273b56aa1832 (diff)
Merge tag 'pull-vfio-20230630' of https://github.com/legoater/qemu into staging
vfio queue: * migration: New switchover ack to reduce downtime * VFIO migration pre-copy support * Removal of the VFIO migration experimental flag * Alternate offset for GPUDirect Cliques * Misc fixes # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCAAdFiEEoPZlSPBIlev+awtgUaNDx8/77KEFAmSeVHYACgkQUaNDx8/7 # 7KHeZw/+LRe9QQpx8hU//vKBvLet2QvI3WUaXGHiHbblbRT6HhiHjWHB2/8j6jji # QhAGJ6w9yoKODyY0kGpVFEnkmXOKyqwWssBheV219ntZs09pFGxZr/ldUhT22aBN # kH8mHU9BZ3J+zF/kKphpcIC1sPxVu/DlrtnJu5vDGuRAOu8+3kFV217JC1yGs1Vh # n+KOho8a8oP9qxtzfvQ9iZ4dpBOOKpE9vscS12wJAlen93AGB6esR7VaLxDjExRP # yL1pguQ8ZZ1gEXXbXO62djKo3IViobtD08KmCXTzQ6TVquLleJzqgjp+A0THnYAe # J9Rlja7LpsO9MYSxmRE9WcQccC+sAGn/t/ufB0tL8zR43FvfhbF5H0PzBBY0H7YA # JlzN+fgrKEEHJwMhXANNvSddhWCwvrkjNxo/80u3ySYMQR1Hav/tsXYBlk16e5nS # fmtrFGTwhsVdy1Q6ZqEOyTni1eiYt5stEQMZFODdUNj6b9FugSZ0BK+2WN/M0CzU # 6mKmJQgZAG/nBoRJm/XCO5OKQ6wm/4tm6F4HSH5EJ6mDT+DqETAk4GRUWTbYa2/G # yAAOlhTMu8Xc/NhMeJ7Z99dyq0SM8pi/XpVEIv7p9yBak8ix60iCWZtDE8vlDv3M # UfMVMTAvTS30kbS6FDN2Yyl6l8/ETdcwVIN4l02ipGzpMCtn9EQ= # =dKUj # -----END PGP SIGNATURE----- # gpg: Signature made Fri 30 Jun 2023 06:05:10 AM CEST # gpg: using RSA key A0F66548F04895EBFE6B0B6051A343C7CFFBECA1 # gpg: Good signature from "Cédric Le Goater <clg@kaod.org>" [undefined] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: A0F6 6548 F048 95EB FE6B 0B60 51A3 43C7 CFFB ECA1 * tag 'pull-vfio-20230630' of https://github.com/legoater/qemu: vfio/pci: Free leaked timer in vfio_realize error path vfio/pci: Fix a segfault in vfio_realize MAINTAINERS: Promote Cédric to VFIO co-maintainer vfio/migration: Make VFIO migration non-experimental vfio/migration: Reset bytes_transferred properly vfio/pci: Call vfio_prepare_kvm_msi_virq_batch() in MSI retry path hw/vfio/pci-quirks: Support alternate offset for GPUDirect Cliques vfio: Implement a common device info helper vfio/migration: Add support for switchover ack capability vfio/migration: Add VFIO migration pre-copy support vfio/migration: Store VFIO migration flags in VFIOMigration vfio/migration: Refactor vfio_save_block() to return saved data size tests: Add migration switchover ack capability test migration: Enable switchover ack capability migration: Implement switchover ack logic migration: Add switchover ack capability Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'hw/vfio/common.c')
-rw-r--r--hw/vfio/common.c68
1 files changed, 53 insertions, 15 deletions
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index fa8fd949b1..77e2ee0e5c 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -381,7 +381,7 @@ static unsigned int vfio_migratable_device_num(void)
return device_num;
}
-int vfio_block_multiple_devices_migration(Error **errp)
+int vfio_block_multiple_devices_migration(VFIODevice *vbasedev, Error **errp)
{
int ret;
@@ -390,6 +390,12 @@ int vfio_block_multiple_devices_migration(Error **errp)
return 0;
}
+ if (vbasedev->enable_migration == ON_OFF_AUTO_ON) {
+ error_setg(errp, "Migration is currently not supported with multiple "
+ "VFIO devices");
+ return -EINVAL;
+ }
+
error_setg(&multiple_devices_migration_blocker,
"Migration is currently not supported with multiple "
"VFIO devices");
@@ -427,7 +433,7 @@ static bool vfio_viommu_preset(void)
return false;
}
-int vfio_block_giommu_migration(Error **errp)
+int vfio_block_giommu_migration(VFIODevice *vbasedev, Error **errp)
{
int ret;
@@ -436,6 +442,12 @@ int vfio_block_giommu_migration(Error **errp)
return 0;
}
+ if (vbasedev->enable_migration == ON_OFF_AUTO_ON) {
+ error_setg(errp,
+ "Migration is currently not supported with vIOMMU enabled");
+ return -EINVAL;
+ }
+
error_setg(&giommu_migration_blocker,
"Migration is currently not supported with vIOMMU enabled");
ret = migrate_add_blocker(giommu_migration_blocker, errp);
@@ -492,7 +504,8 @@ static bool vfio_devices_all_dirty_tracking(VFIOContainer *container)
}
if (vbasedev->pre_copy_dirty_page_tracking == ON_OFF_AUTO_OFF &&
- migration->device_state == VFIO_DEVICE_STATE_RUNNING) {
+ (migration->device_state == VFIO_DEVICE_STATE_RUNNING ||
+ migration->device_state == VFIO_DEVICE_STATE_PRE_COPY)) {
return false;
}
}
@@ -537,7 +550,8 @@ static bool vfio_devices_all_running_and_mig_active(VFIOContainer *container)
return false;
}
- if (migration->device_state == VFIO_DEVICE_STATE_RUNNING) {
+ if (migration->device_state == VFIO_DEVICE_STATE_RUNNING ||
+ migration->device_state == VFIO_DEVICE_STATE_PRE_COPY) {
continue;
} else {
return false;
@@ -2844,11 +2858,35 @@ void vfio_put_group(VFIOGroup *group)
}
}
+struct vfio_device_info *vfio_get_device_info(int fd)
+{
+ struct vfio_device_info *info;
+ uint32_t argsz = sizeof(*info);
+
+ info = g_malloc0(argsz);
+
+retry:
+ info->argsz = argsz;
+
+ if (ioctl(fd, VFIO_DEVICE_GET_INFO, info)) {
+ g_free(info);
+ return NULL;
+ }
+
+ if (info->argsz > argsz) {
+ argsz = info->argsz;
+ info = g_realloc(info, argsz);
+ goto retry;
+ }
+
+ return info;
+}
+
int vfio_get_device(VFIOGroup *group, const char *name,
VFIODevice *vbasedev, Error **errp)
{
- struct vfio_device_info dev_info = { .argsz = sizeof(dev_info) };
- int ret, fd;
+ g_autofree struct vfio_device_info *info = NULL;
+ int fd;
fd = ioctl(group->fd, VFIO_GROUP_GET_DEVICE_FD, name);
if (fd < 0) {
@@ -2860,11 +2898,11 @@ int vfio_get_device(VFIOGroup *group, const char *name,
return fd;
}
- ret = ioctl(fd, VFIO_DEVICE_GET_INFO, &dev_info);
- if (ret) {
+ info = vfio_get_device_info(fd);
+ if (!info) {
error_setg_errno(errp, errno, "error getting device info");
close(fd);
- return ret;
+ return -1;
}
/*
@@ -2892,14 +2930,14 @@ int vfio_get_device(VFIOGroup *group, const char *name,
vbasedev->group = group;
QLIST_INSERT_HEAD(&group->device_list, vbasedev, next);
- vbasedev->num_irqs = dev_info.num_irqs;
- vbasedev->num_regions = dev_info.num_regions;
- vbasedev->flags = dev_info.flags;
+ vbasedev->num_irqs = info->num_irqs;
+ vbasedev->num_regions = info->num_regions;
+ vbasedev->flags = info->flags;
+
+ trace_vfio_get_device(name, info->flags, info->num_regions, info->num_irqs);
- trace_vfio_get_device(name, dev_info.flags, dev_info.num_regions,
- dev_info.num_irqs);
+ vbasedev->reset_works = !!(info->flags & VFIO_DEVICE_FLAGS_RESET);
- vbasedev->reset_works = !!(dev_info.flags & VFIO_DEVICE_FLAGS_RESET);
return 0;
}