Commit 6f240ee6 authored by Yi Liu's avatar Yi Liu Committed by Alex Williamson
Browse files

vfio-iommufd: Split bind/attach into two steps

parent 6086efe7
Loading
Loading
Loading
Loading
+13 −4
Original line number Diff line number Diff line
@@ -207,9 +207,13 @@ static int vfio_df_group_open(struct vfio_device_file *df)
	}

	ret = vfio_df_open(df);
	if (ret) {
		df->iommufd = NULL;
	if (ret)
		goto out_put_kvm;

	if (df->iommufd && device->open_count == 1) {
		ret = vfio_iommufd_compat_attach_ioas(device, df->iommufd);
		if (ret)
			goto out_close_device;
	}

	/*
@@ -218,12 +222,17 @@ static int vfio_df_group_open(struct vfio_device_file *df)
	 */
	smp_store_release(&df->access_granted, true);

	mutex_unlock(&device->dev_set->lock);
	mutex_unlock(&device->group->group_lock);
	return 0;

out_close_device:
	vfio_df_close(df);
out_put_kvm:
	df->iommufd = NULL;
	if (device->open_count == 0)
		vfio_device_put_kvm(device);

	mutex_unlock(&device->dev_set->lock);

out_unlock:
	mutex_unlock(&device->group->group_lock);
	return ret;
+17 −18
Original line number Diff line number Diff line
@@ -20,33 +20,32 @@ bool vfio_iommufd_device_has_compat_ioas(struct vfio_device *vdev,

int vfio_iommufd_bind(struct vfio_device *vdev, struct iommufd_ctx *ictx)
{
	u32 ioas_id;
	u32 device_id;
	int ret;

	lockdep_assert_held(&vdev->dev_set->lock);

	ret = vdev->ops->bind_iommufd(vdev, ictx, &device_id);
	if (ret)
		return ret;
	/* The legacy path has no way to return the device id */
	return vdev->ops->bind_iommufd(vdev, ictx, &device_id);
}

	ret = iommufd_vfio_compat_ioas_get_id(ictx, &ioas_id);
	if (ret)
		goto err_unbind;
	ret = vdev->ops->attach_ioas(vdev, &ioas_id);
	if (ret)
		goto err_unbind;
int vfio_iommufd_compat_attach_ioas(struct vfio_device *vdev,
				    struct iommufd_ctx *ictx)
{
	u32 ioas_id;
	int ret;

	/*
	 * The legacy path has no way to return the device id or the selected
	 * pt_id
	 */
	lockdep_assert_held(&vdev->dev_set->lock);

	/* compat noiommu does not need to do ioas attach */
	if (vfio_device_is_noiommu(vdev))
		return 0;

err_unbind:
	if (vdev->ops->unbind_iommufd)
		vdev->ops->unbind_iommufd(vdev);
	ret = iommufd_vfio_compat_ioas_get_id(ictx, &ioas_id);
	if (ret)
		return ret;

	/* The legacy path has no way to return the selected pt_id */
	return vdev->ops->attach_ioas(vdev, &ioas_id);
}

void vfio_iommufd_unbind(struct vfio_device *vdev)
+9 −0
Original line number Diff line number Diff line
@@ -238,6 +238,8 @@ bool vfio_iommufd_device_has_compat_ioas(struct vfio_device *vdev,
					 struct iommufd_ctx *ictx);
int vfio_iommufd_bind(struct vfio_device *device, struct iommufd_ctx *ictx);
void vfio_iommufd_unbind(struct vfio_device *device);
int vfio_iommufd_compat_attach_ioas(struct vfio_device *device,
				    struct iommufd_ctx *ictx);
#else
static inline bool
vfio_iommufd_device_has_compat_ioas(struct vfio_device *vdev,
@@ -255,6 +257,13 @@ static inline int vfio_iommufd_bind(struct vfio_device *device,
static inline void vfio_iommufd_unbind(struct vfio_device *device)
{
}

static inline int
vfio_iommufd_compat_attach_ioas(struct vfio_device *device,
				struct iommufd_ctx *ictx)
{
	return -EOPNOTSUPP;
}
#endif

#if IS_ENABLED(CONFIG_VFIO_VIRQFD)