diff options
author | Jason Gunthorpe <jgg@nvidia.com> | 2022-09-22 21:20:21 +0200 |
---|---|---|
committer | Alex Williamson <alex.williamson@redhat.com> | 2022-09-22 23:46:06 +0200 |
commit | 03e650f6611563c0ccbd0d769d5748fd10d8ee8e (patch) | |
tree | 4fafa9164c0a4961dc75261d6fc098ac833f9bbb /drivers/vfio/vfio_main.c | |
parent | vfio: Rename __vfio_group_unset_container() (diff) | |
download | linux-03e650f6611563c0ccbd0d769d5748fd10d8ee8e.tar.xz linux-03e650f6611563c0ccbd0d769d5748fd10d8ee8e.zip |
vfio: Split the container logic into vfio_container_attach_group()
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.
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Link: https://lore.kernel.org/r/3-v3-297af71838d2+b9-vfio_container_split_jgg@nvidia.com
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Diffstat (limited to 'drivers/vfio/vfio_main.c')
-rw-r--r-- | drivers/vfio/vfio_main.c | 78 |
1 files changed, 48 insertions, 30 deletions
diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c index 3d8813125358..879c5d27c712 100644 --- a/drivers/vfio/vfio_main.c +++ b/drivers/vfio/vfio_main.c @@ -1097,40 +1097,29 @@ out_unlock: return ret; } -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_container *container, + struct vfio_group *group) +{ + 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); @@ -1142,7 +1131,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; } @@ -1170,9 +1159,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(container, group); + goto out_unlock; + } + +out_unlock: up_write(&group->group_rwsem); -out_fdput: fdput(f); return ret; } |