Skip to content

Commit 805bb6c

Browse files
jgunthorpeawilliam
authored andcommitted
vfio: Split up vfio_group_get_device_fd()
The split follows the pairing with the destroy functions: - vfio_group_get_device_fd() destroyed by close() - vfio_device_open() destroyed by vfio_device_fops_release() - vfio_device_assign_container() destroyed by vfio_group_try_dissolve_container() The next patch will put a lock around vfio_device_assign_container(). 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 c6f4860 commit 805bb6c

File tree

1 file changed

+56
-23
lines changed

1 file changed

+56
-23
lines changed

drivers/vfio/vfio.c

Lines changed: 56 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,12 +1064,9 @@ static bool vfio_assert_device_open(struct vfio_device *device)
10641064
return !WARN_ON_ONCE(!READ_ONCE(device->open_count));
10651065
}
10661066

1067-
static int vfio_group_get_device_fd(struct vfio_group *group, char *buf)
1067+
static int vfio_device_assign_container(struct vfio_device *device)
10681068
{
1069-
struct vfio_device *device;
1070-
struct file *filep;
1071-
int fdno;
1072-
int ret = 0;
1069+
struct vfio_group *group = device->group;
10731070

10741071
if (0 == atomic_read(&group->container_users) ||
10751072
!group->container->iommu_driver)
@@ -1078,13 +1075,22 @@ static int vfio_group_get_device_fd(struct vfio_group *group, char *buf)
10781075
if (group->type == VFIO_NO_IOMMU && !capable(CAP_SYS_RAWIO))
10791076
return -EPERM;
10801077

1081-
device = vfio_device_get_from_name(group, buf);
1082-
if (IS_ERR(device))
1083-
return PTR_ERR(device);
1078+
atomic_inc(&group->container_users);
1079+
return 0;
1080+
}
1081+
1082+
static struct file *vfio_device_open(struct vfio_device *device)
1083+
{
1084+
struct file *filep;
1085+
int ret;
1086+
1087+
ret = vfio_device_assign_container(device);
1088+
if (ret)
1089+
return ERR_PTR(ret);
10841090

10851091
if (!try_module_get(device->dev->driver->owner)) {
10861092
ret = -ENODEV;
1087-
goto err_device_put;
1093+
goto err_unassign_container;
10881094
}
10891095

10901096
mutex_lock(&device->dev_set->lock);
@@ -1100,15 +1106,11 @@ static int vfio_group_get_device_fd(struct vfio_group *group, char *buf)
11001106
* We can't use anon_inode_getfd() because we need to modify
11011107
* the f_mode flags directly to allow more than just ioctls
11021108
*/
1103-
fdno = ret = get_unused_fd_flags(O_CLOEXEC);
1104-
if (ret < 0)
1105-
goto err_close_device;
1106-
11071109
filep = anon_inode_getfile("[vfio-device]", &vfio_device_fops,
11081110
device, O_RDWR);
11091111
if (IS_ERR(filep)) {
11101112
ret = PTR_ERR(filep);
1111-
goto err_fd;
1113+
goto err_close_device;
11121114
}
11131115

11141116
/*
@@ -1118,17 +1120,15 @@ static int vfio_group_get_device_fd(struct vfio_group *group, char *buf)
11181120
*/
11191121
filep->f_mode |= (FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE);
11201122

1121-
atomic_inc(&group->container_users);
1122-
1123-
fd_install(fdno, filep);
1124-
1125-
if (group->type == VFIO_NO_IOMMU)
1123+
if (device->group->type == VFIO_NO_IOMMU)
11261124
dev_warn(device->dev, "vfio-noiommu device opened by user "
11271125
"(%s:%d)\n", current->comm, task_pid_nr(current));
1128-
return fdno;
1126+
/*
1127+
* On success the ref of device is moved to the file and
1128+
* put in vfio_device_fops_release()
1129+
*/
1130+
return filep;
11291131

1130-
err_fd:
1131-
put_unused_fd(fdno);
11321132
err_close_device:
11331133
mutex_lock(&device->dev_set->lock);
11341134
if (device->open_count == 1 && device->ops->close_device)
@@ -1137,7 +1137,40 @@ static int vfio_group_get_device_fd(struct vfio_group *group, char *buf)
11371137
device->open_count--;
11381138
mutex_unlock(&device->dev_set->lock);
11391139
module_put(device->dev->driver->owner);
1140-
err_device_put:
1140+
err_unassign_container:
1141+
vfio_group_try_dissolve_container(device->group);
1142+
return ERR_PTR(ret);
1143+
}
1144+
1145+
static int vfio_group_get_device_fd(struct vfio_group *group, char *buf)
1146+
{
1147+
struct vfio_device *device;
1148+
struct file *filep;
1149+
int fdno;
1150+
int ret;
1151+
1152+
device = vfio_device_get_from_name(group, buf);
1153+
if (IS_ERR(device))
1154+
return PTR_ERR(device);
1155+
1156+
fdno = get_unused_fd_flags(O_CLOEXEC);
1157+
if (fdno < 0) {
1158+
ret = fdno;
1159+
goto err_put_device;
1160+
}
1161+
1162+
filep = vfio_device_open(device);
1163+
if (IS_ERR(filep)) {
1164+
ret = PTR_ERR(filep);
1165+
goto err_put_fdno;
1166+
}
1167+
1168+
fd_install(fdno, filep);
1169+
return fdno;
1170+
1171+
err_put_fdno:
1172+
put_unused_fd(fdno);
1173+
err_put_device:
11411174
vfio_device_put(device);
11421175
return ret;
11431176
}

0 commit comments

Comments
 (0)