On Thu, 29 Jan 2026 21:24:55 +0000
David Matlack <[email protected]> wrote:

> 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.
> 
> Signed-off-by: David Matlack <[email protected]>
> ---
>  drivers/vfio/device_cdev.c |  4 ++++
>  drivers/vfio/group.c       |  9 +++++++++
>  include/linux/vfio.h       | 18 ++++++++++++++++++
>  3 files changed, 31 insertions(+)
> 
> diff --git a/drivers/vfio/device_cdev.c b/drivers/vfio/device_cdev.c
> index 935f84a35875..355447e2add3 100644
> --- a/drivers/vfio/device_cdev.c
> +++ b/drivers/vfio/device_cdev.c
> @@ -57,6 +57,10 @@ int vfio_device_fops_cdev_open(struct inode *inode, struct 
> file *filep)
>       struct vfio_device *device = container_of(inode->i_cdev,
>                                                 struct vfio_device, cdev);
>  
> +     /* Device file must be retrieved via LIVEUPDATE_SESSION_RETRIEVE_FD */
> +     if (vfio_liveupdate_incoming_is_preserved(device))
> +             return -EBUSY;
> +
>       return __vfio_device_fops_cdev_open(device, filep);
>  }
>  
> diff --git a/drivers/vfio/group.c b/drivers/vfio/group.c
> index d47ffada6912..63fc4d656215 100644
> --- a/drivers/vfio/group.c
> +++ b/drivers/vfio/group.c
> @@ -311,6 +311,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;

Is this an EPERM issue then?

> +     }
> +
>       fd = FD_ADD(O_CLOEXEC, vfio_device_open_file(device));
>       if (fd < 0)
>               vfio_device_put_registration(device);
> diff --git a/include/linux/vfio.h b/include/linux/vfio.h
> index dc592dc00f89..0921847b18b5 100644
> --- a/include/linux/vfio.h
> +++ b/include/linux/vfio.h
> @@ -16,6 +16,7 @@
>  #include <linux/cdev.h>
>  #include <uapi/linux/vfio.h>
>  #include <linux/iova_bitmap.h>
> +#include <linux/pci.h>
>  
>  struct kvm;
>  struct iommufd_ctx;
> @@ -431,4 +432,21 @@ static inline int __vfio_device_fops_cdev_open(struct 
> vfio_device *device,
>  
>  struct vfio_device *vfio_find_device(const void *data, device_match_t match);
>  
> +#ifdef CONFIG_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

Why does this need to be in the public header versus
drivers/vfio/vfio.h?

Reply via email to