RE: [PATCH v3 05/15] iommufd: File descriptor, context, kconfig and makefiles

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> From: Jason Gunthorpe <jgg@xxxxxxxxxx>
> Sent: Wednesday, October 26, 2022 2:12 AM
> 
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -10714,6 +10714,16 @@ F:	drivers/iommu/dma-iommu.h
>  F:	drivers/iommu/iova.c
>  F:	include/linux/iova.h
> 
> +IOMMU FD

remove the space, i.e. IOMMUFD

> +config IOMMUFD
> +	tristate "IOMMU Userspace API"
> +	select INTERVAL_TREE
> +	select INTERVAL_TREE_SPAN_ITER
> +	select IOMMU_API
> +	default n
> +	help
> +	  Provides /dev/iommu the user API to control the IOMMU subsystem
> as
> +	  it relates to managing IO page tables that point at user space
> memory.
> +
> +	  This would commonly be used in combination with VFIO.

remove this line

> +/**
> + * iommufd_put_object_keep_user() - Release part of the refcount on obj

what does 'part of the refcount' mean?

> + * @obj - Object to release
> + *
> + * Objects have two protections to ensure that userspace has a consistent
> + * experience with destruction. Normally objects are locked so that destroy
> will
> + * block while there are concurrent users, and wait for the object to be
> + * unlocked.
> + *
> + * However, destroy can also be blocked by holding users reference counts
> on the
> + * objects, in that case destroy will immediately return EBUSY and will not
> wait
> + * for reference counts to go to zero.
> + *
> + * This function switches from blocking userspace to returning EBUSY.

Not sure where "switch from... to..." comes from. Also this function alone
doesn't deal anything with EBUSY. Probably it is clearer that this interface
is used for long-term refcounting which the destroy path should favor to
not block as it did for transient refcounting in concurrent ioctl paths.

> + *
> + * It should be used in places where the users will be held beyond a single
> + * system call.

'users' or 'external drivers'? Do we ever allow userspace to hold the lock
of a kernel object for undefined time?

> +++ b/drivers/iommu/iommufd/main.c
> @@ -0,0 +1,345 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/* Copyright (C) 2021 Intel Corporation
> + * Copyright (c) 2021-2022, NVIDIA CORPORATION & AFFILIATES
> + *
> + * iommufd provides control over the IOMMU HW objects created by
> IOMMU kernel
> + * drivers. IOMMU HW objects revolve around IO page tables that map
> incoming DMA
> + * addresses (IOVA) to CPU addresses.

"to bus addresses".

> + *
> + * The API is divided into a general portion that is intended to work with any
> + * kernel IOMMU driver, and a device specific portion that  is intended to be
> + * used with a userspace HW driver paired with the specific kernel driver.
> This
> + * mechanism allows all the unique functionalities in individual IOMMUs to
> be
> + * exposed to userspace control.

there is no device specific portion in this series.

> +/*
> + * Allow concurrent access to the object. This should only be done once the
> + * system call that created the object is guaranteed to succeed.

an object is not always created by a system call, e.g. iommufd_access

> + */
> +void iommufd_object_finalize(struct iommufd_ctx *ictx,
> +			     struct iommufd_object *obj)
> +{
...

> +static int iommufd_destroy(struct iommufd_ucmd *ucmd)
> +{
> +	struct iommu_destroy *cmd = ucmd->cmd;
> +	struct iommufd_object *obj;
> +
> +	obj = iommufd_get_object(ucmd->ictx, cmd->id,
> IOMMUFD_OBJ_ANY);
> +	if (IS_ERR(obj))
> +		return PTR_ERR(obj);
> +	iommufd_put_object_keep_user(obj);
> +	if (!iommufd_object_destroy_user(ucmd->ictx, obj))
> +		return -EBUSY;

Add a comment that it implies a refcnt hold by external driver in a
long time so return error instead of blocking...

> +
> +static long iommufd_fops_ioctl(struct file *filp, unsigned int cmd,
> +			       unsigned long arg)
> +{
> +	struct iommufd_ucmd ucmd = {};
> +	struct iommufd_ioctl_op *op;
> +	union ucmd_buffer buf;
> +	unsigned int nr;
> +	int ret;
> +
> +	ucmd.ictx = filp->private_data;
> +	ucmd.ubuffer = (void __user *)arg;
> +	ret = get_user(ucmd.user_size, (u32 __user *)ucmd.ubuffer);
> +	if (ret)
> +		return ret;
> +
> +	nr = _IOC_NR(cmd);
> +	if (nr < IOMMUFD_CMD_BASE ||
> +	    (nr - IOMMUFD_CMD_BASE) >= ARRAY_SIZE(iommufd_ioctl_ops))
> +		return -ENOIOCTLCMD;

According to the description in iommufd.h:

	*  - ENOTTY: The IOCTL number itself is not supported at all

> +	op = &iommufd_ioctl_ops[nr - IOMMUFD_CMD_BASE];
> +	if (op->ioctl_num != cmd)
> +		return -ENOIOCTLCMD;
> +	if (ucmd.user_size < op->min_size)
> +		return -EOPNOTSUPP;

-EINVAL?

> +/**
> + * DOC: General ioctl format
> + *
> + * The ioctl mechanims follows a general format to allow for extensibility.

mechanism





[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux FS]     [Yosemite Forum]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux