]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
vfio: Add support for VFIO_DEVICE_FEATURE_MIG_PRECOPY_INFOv2
authorYishai Hadas <yishaih@nvidia.com>
Tue, 17 Mar 2026 16:17:49 +0000 (18:17 +0200)
committerAlex Williamson <alex@shazbot.org>
Thu, 19 Mar 2026 18:32:08 +0000 (12:32 -0600)
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 <yishaih@nvidia.com>
Link: https://lore.kernel.org/r/20260317161753.18964-3-yishaih@nvidia.com
Signed-off-by: Alex Williamson <alex@shazbot.org>
drivers/vfio/vfio_main.c
include/linux/vfio.h

index 742477546b15d4dbaf9ebcfb2e67627db71521e0..8666f35fb3f0dbbed14eb39389f3741472bd1e38 100644 (file)
@@ -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;
index e90859956514a1718e08d503b7a3d37def603da9..7c1d33283e042bc226671f4ef031119f73c22eb5 100644 (file)
@@ -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 */