在 2026/5/11 16:47, Vipin Sharma 写道:
From: David Matlack <[email protected]>

Enforce that files for incoming (preserved by previous kernel) VFIO
devices are retrieved via LIVEUPDATE_SESSION_RETRIEVE_FD rather than by
opening the corresponding VFIO character device or via
VFIO_GROUP_GET_DEVICE_FD.

Both of these methods would result in VFIO initializing the device
without access to the preserved state of the device passed by the
previous kernel.

Reviewed-by: Pranjal Shrivastava <[email protected]>
Signed-off-by: David Matlack <[email protected]>
Co-developed-by: Vipin Sharma <[email protected]>
Signed-off-by: Vipin Sharma <[email protected]>
---
  drivers/vfio/device_cdev.c             |  8 ++++++++
  drivers/vfio/group.c                   |  9 +++++++++
  drivers/vfio/pci/vfio_pci_liveupdate.c |  6 ++++++
  drivers/vfio/vfio.h                    | 18 ++++++++++++++++++
  4 files changed, 41 insertions(+)

diff --git a/drivers/vfio/device_cdev.c b/drivers/vfio/device_cdev.c
index 1ab07ccaf3ab..4df0495941c6 100644
--- a/drivers/vfio/device_cdev.c
+++ b/drivers/vfio/device_cdev.c
@@ -49,6 +49,14 @@ static int vfio_device_cdev_open(struct vfio_device *device, 
struct file **filep
                }
*filep = file;
+       } else if (vfio_liveupdate_incoming_is_preserved(device)) {
+               /*
+                * Since it is live update preserved device, it must be
+                * retrieved via LIVEUPDATE_SESSION_RETRIEVE_FD instead of
+                * opening /dev/vfio/devices/vfioX.
+                */
+               ret = -EBUSY;
+               goto err_free_device_file;

When vfio_liveupdate_incoming_is_preserved(device) returns true, vfio_device_put_registration(device) is not called in this path.

Is vfio_device_put_registration(device) instead invoked from the err_free_device_file error handling path?

Zhu Yanjun

        }
file->private_data = df;
diff --git a/drivers/vfio/group.c b/drivers/vfio/group.c
index b2299e5bc6df..62b4eaabc829 100644
--- a/drivers/vfio/group.c
+++ b/drivers/vfio/group.c
@@ -316,6 +316,15 @@ static int vfio_group_ioctl_get_device_fd(struct 
vfio_group *group,
        if (IS_ERR(device))
                return PTR_ERR(device);
+ /*
+        * This device was preserved across a Live Update. Accessing it via
+        * VFIO_GROUP_GET_DEVICE_FD is not allowed.
+        */
+       if (vfio_liveupdate_incoming_is_preserved(device)) {
+               vfio_device_put_registration(device);
+               return -EBUSY;
+       }
+
        fd = FD_ADD(O_CLOEXEC, vfio_device_open_file(device));
        if (fd < 0)
                vfio_device_put_registration(device);
diff --git a/drivers/vfio/pci/vfio_pci_liveupdate.c 
b/drivers/vfio/pci/vfio_pci_liveupdate.c
index 11c3bc8a8dcd..731a3e34085f 100644
--- a/drivers/vfio/pci/vfio_pci_liveupdate.c
+++ b/drivers/vfio/pci/vfio_pci_liveupdate.c
@@ -47,6 +47,12 @@
   *   ...
   *   ioctl(session_fd, LIVEUPDATE_SESSION_FINISH, ...);
   *
+ * .. note::
+ *    After kexec, if a device was preserved by the previous kernel, attempting
+ *    to open a new file for the device via its character device
+ *    (``/dev/vfio/devices/X``) or via ``VFIO_GROUP_GET_DEVICE_FD`` will fail
+ *    with ``-EBUSY``.
+ *
   * Restrictions
   * ============
   *
diff --git a/drivers/vfio/vfio.h b/drivers/vfio/vfio.h
index 0854f3fa1a22..5269fe021ee3 100644
--- a/drivers/vfio/vfio.h
+++ b/drivers/vfio/vfio.h
@@ -11,6 +11,7 @@
  #include <linux/cdev.h>
  #include <linux/module.h>
  #include <linux/vfio.h>
+#include <linux/pci.h>
struct iommufd_ctx;
  struct iommu_group;
@@ -461,4 +462,21 @@ static inline void vfio_device_debugfs_init(struct 
vfio_device *vdev) { }
  static inline void vfio_device_debugfs_exit(struct vfio_device *vdev) { }
  #endif /* CONFIG_VFIO_DEBUGFS */
+#ifdef CONFIG_PCI_LIVEUPDATE
+static inline bool vfio_liveupdate_incoming_is_preserved(struct vfio_device 
*device)
+{
+       struct device *d = device->dev;
+
+       if (dev_is_pci(d))
+               return to_pci_dev(d)->liveupdate_incoming;
+
+       return false;
+}
+#else
+static inline bool vfio_liveupdate_incoming_is_preserved(struct vfio_device 
*device)
+{
+       return false;
+}
+#endif /* CONFIG_PCI_LIVEUPDATE */
+
  #endif

--
Best Regards,
Yanjun.Zhu


Reply via email to