Commit 03e650f6 authored by Jason Gunthorpe's avatar Jason Gunthorpe Committed by Alex Williamson
Browse files

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: default avatarKevin Tian <kevin.tian@intel.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
Link: https://lore.kernel.org/r/3-v3-297af71838d2+b9-vfio_container_split_jgg@nvidia.com


Signed-off-by: default avatarAlex Williamson <alex.williamson@redhat.com>
parent 429a781c
Loading
Loading
Loading
Loading
+48 −30
Original line number Diff line number Diff line
@@ -1097,40 +1097,29 @@ static int vfio_group_ioctl_unset_container(struct vfio_group *group)
	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;
}