Commit c0d498a1 authored by Nicolin Chen's avatar Nicolin Chen Committed by Jason Gunthorpe
Browse files

iommufd: Introduce iommufd_object_alloc_ucmd helper

An object allocator needs to call either iommufd_object_finalize() upon a
success or iommufd_object_abort_and_destroy() upon an error code.

To reduce duplication, store a new_obj in the struct iommufd_ucmd and call
iommufd_object_finalize/iommufd_object_abort_and_destroy() accordingly in
the main function.

Similar to iommufd_object_alloc() and __iommufd_object_alloc(), add a pair
of helpers: __iommufd_object_alloc_ucmd() and iommufd_object_alloc_ucmd().

Link: https://patch.msgid.link/r/e7206d4227844887cc8dbf0cc7b0242580fafd9d.1749882255.git.nicolinc@nvidia.com


Suggested-by: default avatarJason Gunthorpe <jgg@nvidia.com>
Reviewed-by: default avatarKevin Tian <kevin.tian@intel.com>
Reviewed-by: default avatarJason Gunthorpe <jgg@nvidia.com>
Signed-off-by: default avatarNicolin Chen <nicolinc@nvidia.com>
Reviewed-by: default avatarLu Baolu <baolu.lu@linux.intel.com>
Acked-by: default avatarPranjal Shrivastava <praan@google.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
parent 17a93473
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
@@ -135,6 +135,7 @@ struct iommufd_ucmd {
	void __user *ubuffer;
	u32 user_size;
	void *cmd;
	struct iommufd_object *new_obj;
};

int iommufd_vfio_ioctl(struct iommufd_ctx *ictx, unsigned int cmd,
@@ -230,6 +231,11 @@ iommufd_object_put_and_try_destroy(struct iommufd_ctx *ictx,
	iommufd_object_remove(ictx, obj, obj->id, 0);
}

/*
 * Callers of these normal object allocators must call iommufd_object_finalize()
 * to finalize the object, or call iommufd_object_abort_and_destroy() to revert
 * the allocation.
 */
struct iommufd_object *_iommufd_object_alloc(struct iommufd_ctx *ictx,
					     size_t size,
					     enum iommufd_object_type type);
@@ -246,6 +252,26 @@ struct iommufd_object *_iommufd_object_alloc(struct iommufd_ctx *ictx,
#define iommufd_object_alloc(ictx, ptr, type) \
	__iommufd_object_alloc(ictx, ptr, type, obj)

/*
 * Callers of these _ucmd allocators should not call iommufd_object_finalize()
 * or iommufd_object_abort_and_destroy(), as the core automatically does that.
 */
struct iommufd_object *
_iommufd_object_alloc_ucmd(struct iommufd_ucmd *ucmd, size_t size,
			   enum iommufd_object_type type);

#define __iommufd_object_alloc_ucmd(ucmd, ptr, type, obj)                      \
	container_of(_iommufd_object_alloc_ucmd(                               \
			     ucmd,                                             \
			     sizeof(*(ptr)) + BUILD_BUG_ON_ZERO(               \
						      offsetof(typeof(*(ptr)), \
							       obj) != 0),     \
			     type),                                            \
		     typeof(*(ptr)), obj)

#define iommufd_object_alloc_ucmd(ucmd, ptr, type) \
	__iommufd_object_alloc_ucmd(ucmd, ptr, type, obj)

/*
 * The IO Address Space (IOAS) pagetable is a virtual page table backed by the
 * io_pagetable object. It is a user controlled mapping of IOVA -> PFNs. The
+25 −0
Original line number Diff line number Diff line
@@ -61,6 +61,24 @@ struct iommufd_object *_iommufd_object_alloc(struct iommufd_ctx *ictx,
	return ERR_PTR(rc);
}

struct iommufd_object *_iommufd_object_alloc_ucmd(struct iommufd_ucmd *ucmd,
						  size_t size,
						  enum iommufd_object_type type)
{
	struct iommufd_object *new_obj;

	/* Something is coded wrong if this is hit */
	if (WARN_ON(ucmd->new_obj))
		return ERR_PTR(-EBUSY);

	new_obj = _iommufd_object_alloc(ucmd->ictx, size, type);
	if (IS_ERR(new_obj))
		return new_obj;

	ucmd->new_obj = new_obj;
	return new_obj;
}

/*
 * Allow concurrent access to the object.
 *
@@ -448,6 +466,13 @@ static long iommufd_fops_ioctl(struct file *filp, unsigned int cmd,
	if (ret)
		return ret;
	ret = op->execute(&ucmd);

	if (ucmd.new_obj) {
		if (ret)
			iommufd_object_abort_and_destroy(ictx, ucmd.new_obj);
		else
			iommufd_object_finalize(ictx, ucmd.new_obj);
	}
	return ret;
}