Skip to content

Commit 270bf4c

Browse files
yiliu1765awilliam
authored andcommitted
vfio: Add cdev_device_open_cnt to vfio_group
This is 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 <[email protected]> Reviewed-by: Jason Gunthorpe <[email protected]> Reviewed-by: Eric Auger <[email protected]> Tested-by: Terrence Xu <[email protected]> Tested-by: Nicolin Chen <[email protected]> Tested-by: Matthew Rosato <[email protected]> Tested-by: Yanting Jiang <[email protected]> Tested-by: Shameer Kolothum <[email protected]> Tested-by: Zhenzhong Duan <[email protected]> Signed-off-by: Yi Liu <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alex Williamson <[email protected]>
1 parent 82d93f5 commit 270bf4c

File tree

2 files changed

+36
-0
lines changed

2 files changed

+36
-0
lines changed

drivers/vfio/group.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,33 @@ static long vfio_group_fops_unl_ioctl(struct file *filep,
383383
}
384384
}
385385

386+
int vfio_device_block_group(struct vfio_device *device)
387+
{
388+
struct vfio_group *group = device->group;
389+
int ret = 0;
390+
391+
mutex_lock(&group->group_lock);
392+
if (group->opened_file) {
393+
ret = -EBUSY;
394+
goto out_unlock;
395+
}
396+
397+
group->cdev_device_open_cnt++;
398+
399+
out_unlock:
400+
mutex_unlock(&group->group_lock);
401+
return ret;
402+
}
403+
404+
void vfio_device_unblock_group(struct vfio_device *device)
405+
{
406+
struct vfio_group *group = device->group;
407+
408+
mutex_lock(&group->group_lock);
409+
group->cdev_device_open_cnt--;
410+
mutex_unlock(&group->group_lock);
411+
}
412+
386413
static int vfio_group_fops_open(struct inode *inode, struct file *filep)
387414
{
388415
struct vfio_group *group =
@@ -405,6 +432,11 @@ static int vfio_group_fops_open(struct inode *inode, struct file *filep)
405432
goto out_unlock;
406433
}
407434

435+
if (group->cdev_device_open_cnt) {
436+
ret = -EBUSY;
437+
goto out_unlock;
438+
}
439+
408440
/*
409441
* Do we need multiple instances of the group open? Seems not.
410442
*/
@@ -479,6 +511,7 @@ static void vfio_group_release(struct device *dev)
479511
mutex_destroy(&group->device_lock);
480512
mutex_destroy(&group->group_lock);
481513
WARN_ON(group->iommu_group);
514+
WARN_ON(group->cdev_device_open_cnt);
482515
ida_free(&vfio.group_ida, MINOR(group->dev.devt));
483516
kfree(group);
484517
}

drivers/vfio/vfio.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,11 @@ struct vfio_group {
8484
struct blocking_notifier_head notifier;
8585
struct iommufd_ctx *iommufd;
8686
spinlock_t kvm_ref_lock;
87+
unsigned int cdev_device_open_cnt;
8788
};
8889

90+
int vfio_device_block_group(struct vfio_device *device);
91+
void vfio_device_unblock_group(struct vfio_device *device);
8992
int vfio_device_set_group(struct vfio_device *device,
9093
enum vfio_group_type type);
9194
void vfio_device_remove_group(struct vfio_device *device);

0 commit comments

Comments
 (0)