On 3/24/26 07:58, David Matlack wrote:
From: Vipin Sharma <[email protected]>

Enable userspace to retrieve preserved VFIO device files from VFIO after
a Live Update by implementing the retrieve() and finish() file handler
callbacks.

Use an anonymous inode when creating the file, since the retrieved
device file is not opened through any particular cdev inode, and the
cdev inode does not matter in practice.

do we have a list of struct file fields that do not matter?


For now the retrieved file is functionally equivalent a opening the
corresponding VFIO cdev file. Subsequent commits will leverage the
preserved state associated with the retrieved file to preserve bits of
the device across Live Update.

Signed-off-by: Vipin Sharma <[email protected]>
Co-developed-by: David Matlack <[email protected]>
Signed-off-by: David Matlack <[email protected]>
---
  drivers/vfio/device_cdev.c             | 59 ++++++++++++++++++++++----
  drivers/vfio/pci/vfio_pci_liveupdate.c | 52 ++++++++++++++++++++++-
  drivers/vfio/vfio_main.c               | 13 ++++++
  include/linux/vfio.h                   | 11 +++++
  4 files changed, 124 insertions(+), 11 deletions(-)

diff --git a/drivers/vfio/device_cdev.c b/drivers/vfio/device_cdev.c
index 8ceca24ac136..edf322315a41 100644
--- a/drivers/vfio/device_cdev.c
+++ b/drivers/vfio/device_cdev.c
@@ -2,6 +2,7 @@
  /*
   * Copyright (c) 2023 Intel Corporation.
   */
+#include <linux/anon_inodes.h>
  #include <linux/vfio.h>
  #include <linux/iommufd.h>
@@ -16,15 +17,10 @@ void vfio_init_device_cdev(struct vfio_device *device)
        device->cdev.owner = THIS_MODULE;
  }
-/*
- * device access via the fd opened by this function is blocked until
- * .open_device() is called successfully during BIND_IOMMUFD.
- */
-int vfio_device_fops_cdev_open(struct inode *inode, struct file *filep)
+static int vfio_device_cdev_open(struct vfio_device *device, struct file 
**filep)
  {
-       struct vfio_device *device = container_of(inode->i_cdev,
-                                                 struct vfio_device, cdev);
        struct vfio_device_file *df;
+       struct file *file = *filep;
        int ret;
/* Paired with the put in vfio_device_fops_release() */
@@ -37,22 +33,67 @@ int vfio_device_fops_cdev_open(struct inode *inode, struct 
file *filep)
                goto err_put_registration;
        }
- filep->private_data = df;
+       /*
+        * Simulate opening the character device using an anonymous inode. The
+        * returned file has the same properties as a cdev file (e.g. operations
+        * are blocked until BIND_IOMMUFD is called).
+        */
+       if (!file) {
+               file = anon_inode_getfile_fmode("[vfio-device-liveupdate]",
+                                               &vfio_device_fops, NULL,
+                                               O_RDWR, FMODE_PREAD | 
FMODE_PWRITE);
+
+               if (IS_ERR(file)) {
+                       ret = PTR_ERR(file);
+                       goto err_free_device_file;
+               }
+
+               *filep = file;
+       }
+
+       file->private_data = df;
/*
         * Use the pseudo fs inode on the device to link all mmaps
         * to the same address space, allowing us to unmap all vmas
         * associated to this device using unmap_mapping_range().
         */
-       filep->f_mapping = device->inode->i_mapping;
+       file->f_mapping = device->inode->i_mapping;

        return 0;
+err_free_device_file:
+       kvfree(df);

any reason to use kvfree()?

Regards,
Yi Liu

Reply via email to