Skip to content

Commit

Permalink
vfio: Add cdev_device_open_cnt to vfio_group
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
yiliu1765 authored and awilliam committed Jul 25, 2023
1 parent 82d93f5 commit 270bf4c
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 0 deletions.
33 changes: 33 additions & 0 deletions drivers/vfio/group.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand All @@ -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.
*/
Expand Down Expand Up @@ -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);
}
Expand Down
3 changes: 3 additions & 0 deletions drivers/vfio/vfio.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,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);
Expand Down

0 comments on commit 270bf4c

Please sign in to comment.