Hi Yi, On 4/1/23 17:18, Yi Liu wrote: > for counting the devices that are opened via the cdev path. This count > is increased and decreased by the cdev path. The group path checks it > to achieve exclusion with the cdev path. With this, only one path (group > path or cdev path) will claim DMA ownership. This avoids scenarios in > which devices within the same group may be opened via different paths. > > Reviewed-by: Kevin Tian <kevin.tian@xxxxxxxxx> > Reviewed-by: Jason Gunthorpe <jgg@xxxxxxxxxx> > Tested-by: Terrence Xu <terrence.xu@xxxxxxxxx> > Tested-by: Nicolin Chen <nicolinc@xxxxxxxxxx> > Tested-by: Matthew Rosato <mjrosato@xxxxxxxxxxxxx> > Tested-by: Yanting Jiang <yanting.jiang@xxxxxxxxx> > Signed-off-by: Yi Liu <yi.l.liu@xxxxxxxxx> Reviewed-by: Eric Auger <eric.auger@xxxxxxxxxx> Thanks Eric > --- > drivers/vfio/group.c | 33 +++++++++++++++++++++++++++++++++ > drivers/vfio/vfio.h | 3 +++ > 2 files changed, 36 insertions(+) > > diff --git a/drivers/vfio/group.c b/drivers/vfio/group.c > index 71f0a9a4016e..d55ce3ca44b7 100644 > --- a/drivers/vfio/group.c > +++ b/drivers/vfio/group.c > @@ -383,6 +383,33 @@ static long vfio_group_fops_unl_ioctl(struct file *filep, > } > } > > +int vfio_device_block_group(struct vfio_device *device) > +{ > + struct vfio_group *group = device->group; > + int ret = 0; > + > + mutex_lock(&group->group_lock); > + if (group->opened_file) { > + ret = -EBUSY; > + goto out_unlock; > + } > + > + group->cdev_device_open_cnt++; > + > +out_unlock: > + mutex_unlock(&group->group_lock); > + return ret; > +} > + > +void vfio_device_unblock_group(struct vfio_device *device) > +{ > + struct vfio_group *group = device->group; > + > + mutex_lock(&group->group_lock); > + group->cdev_device_open_cnt--; > + mutex_unlock(&group->group_lock); > +} > + > static int vfio_group_fops_open(struct inode *inode, struct file *filep) > { > struct vfio_group *group = > @@ -405,6 +432,11 @@ static int vfio_group_fops_open(struct inode *inode, struct file *filep) > goto out_unlock; > } > > + if (group->cdev_device_open_cnt) { > + ret = -EBUSY; > + goto out_unlock; > + } > + > /* > * Do we need multiple instances of the group open? Seems not. > */ > @@ -479,6 +511,7 @@ static void vfio_group_release(struct device *dev) > mutex_destroy(&group->device_lock); > mutex_destroy(&group->group_lock); > WARN_ON(group->iommu_group); > + WARN_ON(group->cdev_device_open_cnt); > ida_free(&vfio.group_ida, MINOR(group->dev.devt)); > kfree(group); > } > diff --git a/drivers/vfio/vfio.h b/drivers/vfio/vfio.h > index 854f2c97cb9a..b2f20b78a707 100644 > --- a/drivers/vfio/vfio.h > +++ b/drivers/vfio/vfio.h > @@ -83,8 +83,11 @@ struct vfio_group { > struct blocking_notifier_head notifier; > struct iommufd_ctx *iommufd; > spinlock_t kvm_ref_lock; > + unsigned int cdev_device_open_cnt; > }; > > +int vfio_device_block_group(struct vfio_device *device); > +void vfio_device_unblock_group(struct vfio_device *device); > int vfio_device_set_group(struct vfio_device *device, > enum vfio_group_type type); > void vfio_device_remove_group(struct vfio_device *device);