summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYishai Hadas <yishaih@nvidia.com>2026-03-17 18:17:49 +0200
committerAlex Williamson <alex@shazbot.org>2026-03-19 12:32:08 -0600
commit50ff3f404617c5d15832fec3711978104c4c9efd (patch)
tree3adf13e6508f71acc707308ae753bfbb785ae08b
parentd7140b5dde459048da52cfc0494228055f7e2fb8 (diff)
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 <yishaih@nvidia.com> Link: https://lore.kernel.org/r/20260317161753.18964-3-yishaih@nvidia.com Signed-off-by: Alex Williamson <alex@shazbot.org>
-rw-r--r--drivers/vfio/vfio_main.c21
-rw-r--r--include/linux/vfio.h1
2 files changed, 22 insertions, 0 deletions
diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c
index 742477546b15..8666f35fb3f0 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 e90859956514..7c1d33283e04 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 */