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

iommufd/fault: Add an iommufd_fault_init() helper

The infrastructure of a fault object will be shared with a new vEVENTQ
object in a following change. Add an iommufd_fault_init helper and an
INIT_EVENTQ_FOPS marco for a vEVENTQ allocator to use too.

Reorder the iommufd_ctx_get and refcount_inc, to keep them symmetrical
with the iommufd_fault_fops_release().

Since the new vEVENTQ doesn't need "response" and its "mutex", so keep
the xa_init_flags and mutex_init in their original locations.

Link: https://patch.msgid.link/r/a9522c521909baeb1bd843950b2490478f3d06e0.1741719725.git.nicolinc@nvidia.com


Reviewed-by: default avatarKevin Tian <kevin.tian@intel.com>
Reviewed-by: default avatarLu Baolu <baolu.lu@linux.intel.com>
Reviewed-by: default avatarJason Gunthorpe <jgg@nvidia.com>
Signed-off-by: default avatarNicolin Chen <nicolinc@nvidia.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
parent dbf00d7d
Loading
Loading
Loading
Loading
+42 −28
Original line number Diff line number Diff line
@@ -280,20 +280,49 @@ static int iommufd_fault_fops_release(struct inode *inode, struct file *filep)
	return 0;
}

static const struct file_operations iommufd_fault_fops = {
	.owner		= THIS_MODULE,
	.open		= nonseekable_open,
	.read		= iommufd_fault_fops_read,
	.write		= iommufd_fault_fops_write,
	.poll		= iommufd_fault_fops_poll,
	.release	= iommufd_fault_fops_release,
};
#define INIT_FAULT_FOPS(read_op, write_op)                                     \
	((const struct file_operations){                                       \
		.owner = THIS_MODULE,                                          \
		.open = nonseekable_open,                                      \
		.read = read_op,                                               \
		.write = write_op,                                             \
		.poll = iommufd_fault_fops_poll,                               \
		.release = iommufd_fault_fops_release,                         \
	})

static int iommufd_fault_init(struct iommufd_fault *fault, char *name,
			      struct iommufd_ctx *ictx,
			      const struct file_operations *fops)
{
	struct file *filep;
	int fdno;

	spin_lock_init(&fault->lock);
	INIT_LIST_HEAD(&fault->deliver);
	init_waitqueue_head(&fault->wait_queue);

	filep = anon_inode_getfile(name, fops, fault, O_RDWR);
	if (IS_ERR(filep))
		return PTR_ERR(filep);

	fault->ictx = ictx;
	iommufd_ctx_get(fault->ictx);
	fault->filep = filep;
	refcount_inc(&fault->obj.users);

	fdno = get_unused_fd_flags(O_CLOEXEC);
	if (fdno < 0)
		fput(filep);
	return fdno;
}

static const struct file_operations iommufd_fault_fops =
	INIT_FAULT_FOPS(iommufd_fault_fops_read, iommufd_fault_fops_write);

int iommufd_fault_alloc(struct iommufd_ucmd *ucmd)
{
	struct iommu_fault_alloc *cmd = ucmd->cmd;
	struct iommufd_fault *fault;
	struct file *filep;
	int fdno;
	int rc;

@@ -304,28 +333,14 @@ int iommufd_fault_alloc(struct iommufd_ucmd *ucmd)
	if (IS_ERR(fault))
		return PTR_ERR(fault);

	fault->ictx = ucmd->ictx;
	INIT_LIST_HEAD(&fault->deliver);
	xa_init_flags(&fault->response, XA_FLAGS_ALLOC1);
	mutex_init(&fault->mutex);
	spin_lock_init(&fault->lock);
	init_waitqueue_head(&fault->wait_queue);

	filep = anon_inode_getfile("[iommufd-pgfault]", &iommufd_fault_fops,
				   fault, O_RDWR);
	if (IS_ERR(filep)) {
		rc = PTR_ERR(filep);
		goto out_abort;
	}

	refcount_inc(&fault->obj.users);
	iommufd_ctx_get(fault->ictx);
	fault->filep = filep;

	fdno = get_unused_fd_flags(O_CLOEXEC);
	fdno = iommufd_fault_init(fault, "[iommufd-pgfault]", ucmd->ictx,
				  &iommufd_fault_fops);
	if (fdno < 0) {
		rc = fdno;
		goto out_fput;
		goto out_abort;
	}

	cmd->out_fault_id = fault->obj.id;
@@ -341,8 +356,7 @@ int iommufd_fault_alloc(struct iommufd_ucmd *ucmd)
	return 0;
out_put_fdno:
	put_unused_fd(fdno);
out_fput:
	fput(filep);
	fput(fault->filep);
out_abort:
	iommufd_object_abort_and_destroy(ucmd->ictx, &fault->obj);