This splits up the ioctl of vfio_group_ioctl_set_container() so it determines the type of file then invokes a type specific attachment function. Future patches will add iommufd to this function as an alternative type. A following patch will move the vfio_container functions to their own .c file. Signed-off-by: Jason Gunthorpe <jgg@xxxxxxxxxx> --- drivers/vfio/vfio_main.c | 78 ++++++++++++++++++++++++---------------- 1 file changed, 48 insertions(+), 30 deletions(-) diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c index e145c87f208f3a..1108ba53fe5c28 100644 --- a/drivers/vfio/vfio_main.c +++ b/drivers/vfio/vfio_main.c @@ -981,40 +981,29 @@ static int vfio_group_ioctl_unset_container(struct vfio_group *group) return 0; } -static int vfio_group_ioctl_set_container(struct vfio_group *group, - int __user *arg) +static struct vfio_container *vfio_container_from_file(struct file *file) { - struct fd f; struct vfio_container *container; - struct vfio_iommu_driver *driver; - int container_fd; - int ret = 0; - - if (group->type == VFIO_NO_IOMMU && !capable(CAP_SYS_RAWIO)) - return -EPERM; - - if (get_user(container_fd, arg)) - return -EFAULT; - if (container_fd < 0) - return -EINVAL; - f = fdget(container_fd); - if (!f.file) - return -EBADF; /* Sanity check, is this really our fd? */ - if (f.file->f_op != &vfio_fops) { - ret = -EINVAL; - goto out_fdput; - } - container = f.file->private_data; + if (file->f_op != &vfio_fops) + return NULL; + + container = file->private_data; WARN_ON(!container); /* fget ensures we don't race vfio_release */ + return container; +} - down_write(&group->group_rwsem); +static int vfio_container_attach_group(struct vfio_group *group, + struct vfio_container *container) +{ + struct vfio_iommu_driver *driver; + int ret = 0; - if (group->container || WARN_ON(group->container_users)) { - ret = -EINVAL; - goto out_unlock_group; - } + lockdep_assert_held_write(&group->group_rwsem); + + if (group->type == VFIO_NO_IOMMU && !capable(CAP_SYS_RAWIO)) + return -EPERM; down_write(&container->group_lock); @@ -1026,7 +1015,7 @@ static int vfio_group_ioctl_set_container(struct vfio_group *group, } if (group->type == VFIO_IOMMU) { - ret = iommu_group_claim_dma_owner(group->iommu_group, f.file); + ret = iommu_group_claim_dma_owner(group->iommu_group, group); if (ret) goto out_unlock_container; } @@ -1054,9 +1043,38 @@ static int vfio_group_ioctl_set_container(struct vfio_group *group, out_unlock_container: up_write(&container->group_lock); -out_unlock_group: + return ret; +} + +static int vfio_group_ioctl_set_container(struct vfio_group *group, + int __user *arg) +{ + struct vfio_container *container; + struct fd f; + int ret; + int fd; + + if (get_user(fd, arg)) + return -EFAULT; + + f = fdget(fd); + if (!f.file) + return -EBADF; + + down_write(&group->group_rwsem); + if (group->container || WARN_ON(group->container_users)) { + ret = -EINVAL; + goto out_unlock; + } + container = vfio_container_from_file(f.file); + ret = -EINVAL; + if (container) { + ret = vfio_container_attach_group(group, container); + goto out_unlock; + } + +out_unlock: up_write(&group->group_rwsem); -out_fdput: fdput(f); return ret; } -- 2.37.2