Skip to content

Commit c6f4860

Browse files
jgunthorpeawilliam
authored andcommitted
vfio: Change struct vfio_group::opened from an atomic to bool
This is not a performance path, just use the group_rwsem to protect the value. Reviewed-by: Kevin Tian <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]> Tested-by: Nicolin Chen <[email protected]> Tested-by: Matthew Rosato <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alex Williamson <[email protected]>
1 parent be8d3ad commit c6f4860

File tree

1 file changed

+27
-19
lines changed

1 file changed

+27
-19
lines changed

drivers/vfio/vfio.c

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ struct vfio_group {
7373
struct mutex device_lock;
7474
struct list_head vfio_next;
7575
struct list_head container_next;
76-
atomic_t opened;
76+
bool opened;
7777
enum vfio_group_type type;
7878
unsigned int dev_counter;
7979
struct rw_semaphore group_rwsem;
@@ -1213,38 +1213,44 @@ static int vfio_group_fops_open(struct inode *inode, struct file *filep)
12131213
{
12141214
struct vfio_group *group =
12151215
container_of(inode->i_cdev, struct vfio_group, cdev);
1216-
int opened;
1216+
int ret;
12171217

1218-
/* users can be zero if this races with vfio_group_put() */
1219-
if (!refcount_inc_not_zero(&group->users))
1220-
return -ENODEV;
1218+
down_write(&group->group_rwsem);
12211219

1222-
if (group->type == VFIO_NO_IOMMU && !capable(CAP_SYS_RAWIO)) {
1223-
vfio_group_put(group);
1224-
return -EPERM;
1220+
/* users can be zero if this races with vfio_group_put() */
1221+
if (!refcount_inc_not_zero(&group->users)) {
1222+
ret = -ENODEV;
1223+
goto err_unlock;
12251224
}
12261225

1227-
/* Do we need multiple instances of the group open? Seems not. */
1228-
opened = atomic_cmpxchg(&group->opened, 0, 1);
1229-
if (opened) {
1230-
vfio_group_put(group);
1231-
return -EBUSY;
1226+
if (group->type == VFIO_NO_IOMMU && !capable(CAP_SYS_RAWIO)) {
1227+
ret = -EPERM;
1228+
goto err_put;
12321229
}
12331230

1234-
/* Is something still in use from a previous open? */
1235-
if (group->container) {
1236-
atomic_dec(&group->opened);
1237-
vfio_group_put(group);
1238-
return -EBUSY;
1231+
/*
1232+
* Do we need multiple instances of the group open? Seems not.
1233+
* Is something still in use from a previous open?
1234+
*/
1235+
if (group->opened || group->container) {
1236+
ret = -EBUSY;
1237+
goto err_put;
12391238
}
1239+
group->opened = true;
12401240

12411241
/* Warn if previous user didn't cleanup and re-init to drop them */
12421242
if (WARN_ON(group->notifier.head))
12431243
BLOCKING_INIT_NOTIFIER_HEAD(&group->notifier);
12441244

12451245
filep->private_data = group;
12461246

1247+
up_write(&group->group_rwsem);
12471248
return 0;
1249+
err_put:
1250+
vfio_group_put(group);
1251+
err_unlock:
1252+
up_write(&group->group_rwsem);
1253+
return ret;
12481254
}
12491255

12501256
static int vfio_group_fops_release(struct inode *inode, struct file *filep)
@@ -1255,7 +1261,9 @@ static int vfio_group_fops_release(struct inode *inode, struct file *filep)
12551261

12561262
vfio_group_try_dissolve_container(group);
12571263

1258-
atomic_dec(&group->opened);
1264+
down_write(&group->group_rwsem);
1265+
group->opened = false;
1266+
up_write(&group->group_rwsem);
12591267

12601268
vfio_group_put(group);
12611269

0 commit comments

Comments
 (0)