Hi Yi, On 1/17/23 14:49, Yi Liu wrote: > This is preparation for adding vfio device cdev support. vfio device > cdev requires: > 1) a per device file memory to store the kvm pointer set by KVM. It will > be propagated to vfio_device:kvm after the device cdev file is bound > to an iommufd > 2) a mechanism to block device access through device cdev fd before it > is bound to an iommufd > > To address above requirements, this adds a per device file structure > named vfio_device_file. For now, it's only a wrapper of struct vfio_device > pointer. Other fields will be added to this per file structure in future > commits. > > Signed-off-by: Yi Liu <yi.l.liu@xxxxxxxxx> > --- > drivers/vfio/group.c | 13 +++++++++++-- > drivers/vfio/vfio.h | 6 ++++++ > drivers/vfio/vfio_main.c | 31 ++++++++++++++++++++++++++----- > 3 files changed, 43 insertions(+), 7 deletions(-) > > diff --git a/drivers/vfio/group.c b/drivers/vfio/group.c > index bb24b2f0271e..8fdb7e35b0a6 100644 > --- a/drivers/vfio/group.c > +++ b/drivers/vfio/group.c > @@ -186,19 +186,26 @@ void vfio_device_group_close(struct vfio_device *device) > > static struct file *vfio_device_open_file(struct vfio_device *device) > { > + struct vfio_device_file *df; > struct file *filep; > int ret; > > + df = vfio_allocate_device_file(device); > + if (IS_ERR(df)) { > + ret = PTR_ERR(df); > + goto err_out; > + } > + > ret = vfio_device_group_open(device); > if (ret) > - goto err_out; > + goto err_free; > > /* > * We can't use anon_inode_getfd() because we need to modify > * the f_mode flags directly to allow more than just ioctls > */ > filep = anon_inode_getfile("[vfio-device]", &vfio_device_fops, > - device, O_RDWR); > + df, O_RDWR); > if (IS_ERR(filep)) { > ret = PTR_ERR(filep); > goto err_close_device; > @@ -222,6 +229,8 @@ static struct file *vfio_device_open_file(struct vfio_device *device) > > err_close_device: > vfio_device_group_close(device); > +err_free: > + kfree(df); > err_out: > return ERR_PTR(ret); > } > diff --git a/drivers/vfio/vfio.h b/drivers/vfio/vfio.h > index f8219a438bfb..1091806bc89d 100644 > --- a/drivers/vfio/vfio.h > +++ b/drivers/vfio/vfio.h > @@ -16,12 +16,18 @@ struct iommu_group; > struct vfio_device; > struct vfio_container; > > +struct vfio_device_file { > + struct vfio_device *device; > +}; > + > void vfio_device_put_registration(struct vfio_device *device); > bool vfio_device_try_get_registration(struct vfio_device *device); > int vfio_device_open(struct vfio_device *device, > struct iommufd_ctx *iommufd, struct kvm *kvm); > void vfio_device_close(struct vfio_device *device, > struct iommufd_ctx *iommufd); > +struct vfio_device_file * > +vfio_allocate_device_file(struct vfio_device *device); > > extern const struct file_operations vfio_device_fops; > > diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c > index 5177bb061b17..ee54c9ae0af4 100644 > --- a/drivers/vfio/vfio_main.c > +++ b/drivers/vfio/vfio_main.c > @@ -344,6 +344,20 @@ static bool vfio_assert_device_open(struct vfio_device *device) > return !WARN_ON_ONCE(!READ_ONCE(device->open_count)); > } > > +struct vfio_device_file * > +vfio_allocate_device_file(struct vfio_device *device) > +{ > + struct vfio_device_file *df; > + > + df = kzalloc(sizeof(*df), GFP_KERNEL_ACCOUNT); > + if (!df) > + return ERR_PTR(-ENOMEM); > + > + df->device = device; > + > + return df; > +} > + > static int vfio_device_first_open(struct vfio_device *device, > struct iommufd_ctx *iommufd, struct kvm *kvm) > { > @@ -461,12 +475,15 @@ static inline void vfio_device_pm_runtime_put(struct vfio_device *device) > */ > static int vfio_device_fops_release(struct inode *inode, struct file *filep) > { > - struct vfio_device *device = filep->private_data; > + struct vfio_device_file *df = filep->private_data; > + struct vfio_device *device = df->device; > > vfio_device_group_close(device); > > vfio_device_put_registration(device); > > + kfree(df); > + > return 0; > } > > @@ -1031,7 +1048,8 @@ static int vfio_ioctl_device_feature(struct vfio_device *device, > static long vfio_device_fops_unl_ioctl(struct file *filep, > unsigned int cmd, unsigned long arg) > { > - struct vfio_device *device = filep->private_data; > + struct vfio_device_file *df = filep->private_data; > + struct vfio_device *device = df->device; > int ret; > > ret = vfio_device_pm_runtime_get(device); > @@ -1058,7 +1076,8 @@ static long vfio_device_fops_unl_ioctl(struct file *filep, > static ssize_t vfio_device_fops_read(struct file *filep, char __user *buf, > size_t count, loff_t *ppos) > { > - struct vfio_device *device = filep->private_data; > + struct vfio_device_file *df = filep->private_data; > + struct vfio_device *device = df->device; > > if (unlikely(!device->ops->read)) > return -EINVAL; > @@ -1070,7 +1089,8 @@ static ssize_t vfio_device_fops_write(struct file *filep, > const char __user *buf, > size_t count, loff_t *ppos) > { > - struct vfio_device *device = filep->private_data; > + struct vfio_device_file *df = filep->private_data; > + struct vfio_device *device = df->device; > > if (unlikely(!device->ops->write)) > return -EINVAL; > @@ -1080,7 +1100,8 @@ static ssize_t vfio_device_fops_write(struct file *filep, > > static int vfio_device_fops_mmap(struct file *filep, struct vm_area_struct *vma) > { > - struct vfio_device *device = filep->private_data; > + struct vfio_device_file *df = filep->private_data; > + struct vfio_device *device = df->device; > > if (unlikely(!device->ops->mmap)) > return -EINVAL; Reviewed-by: Eric Auger <eric.auger@xxxxxxxxxx> Thanks Eric