From: Yishai Hadas Date: Tue, 17 Mar 2026 16:17:49 +0000 (+0200) Subject: vfio: Add support for VFIO_DEVICE_FEATURE_MIG_PRECOPY_INFOv2 X-Git-Tag: v7.1-rc1~132^2~15 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=50ff3f404617c5d15832fec3711978104c4c9efd;p=thirdparty%2Fkernel%2Fstable.git vfio: Add support for VFIO_DEVICE_FEATURE_MIG_PRECOPY_INFOv2 Currently, existing VFIO_MIG_GET_PRECOPY_INFO implementations don't assign info.flags before copy_to_user(). Because they copy the struct in from userspace first, this effectively echoes userspace-provided flags back as output, preventing the field from being used to report new reliable data from the drivers. Add support for a new device feature named VFIO_DEVICE_FEATURE_MIG_PRECOPY_INFOv2. On SET, enables the v2 pre_copy_info behaviour, where the vfio_precopy_info.flags is a valid output field. Signed-off-by: Yishai Hadas Link: https://lore.kernel.org/r/20260317161753.18964-3-yishaih@nvidia.com Signed-off-by: Alex Williamson --- diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c index 742477546b15d..8666f35fb3f0d 100644 --- a/drivers/vfio/vfio_main.c +++ b/drivers/vfio/vfio_main.c @@ -553,6 +553,7 @@ static void vfio_df_device_last_close(struct vfio_device_file *df) vfio_df_iommufd_unbind(df); else vfio_device_group_unuse_iommu(device); + device->precopy_info_v2 = 0; module_put(device->dev->driver->owner); } @@ -964,6 +965,23 @@ vfio_ioctl_device_feature_migration_data_size(struct vfio_device *device, return 0; } +static int +vfio_ioctl_device_feature_migration_precopy_info_v2(struct vfio_device *device, + u32 flags, size_t argsz) +{ + int ret; + + if (!(device->migration_flags & VFIO_MIGRATION_PRE_COPY)) + return -EINVAL; + + ret = vfio_check_feature(flags, argsz, VFIO_DEVICE_FEATURE_SET, 0); + if (ret != 1) + return ret; + + device->precopy_info_v2 = 1; + return 0; +} + static int vfio_ioctl_device_feature_migration(struct vfio_device *device, u32 flags, void __user *arg, size_t argsz) @@ -1251,6 +1269,9 @@ static int vfio_ioctl_device_feature(struct vfio_device *device, return vfio_ioctl_device_feature_migration_data_size( device, feature.flags, arg->data, feature.argsz - minsz); + case VFIO_DEVICE_FEATURE_MIG_PRECOPY_INFOv2: + return vfio_ioctl_device_feature_migration_precopy_info_v2( + device, feature.flags, feature.argsz - minsz); default: if (unlikely(!device->ops->device_feature)) return -ENOTTY; diff --git a/include/linux/vfio.h b/include/linux/vfio.h index e90859956514a..7c1d33283e042 100644 --- a/include/linux/vfio.h +++ b/include/linux/vfio.h @@ -52,6 +52,7 @@ struct vfio_device { struct vfio_device_set *dev_set; struct list_head dev_set_list; unsigned int migration_flags; + u8 precopy_info_v2; struct kvm *kvm; /* Members below here are private, not for driver use */