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?

