linux-tegra.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Baolu Lu <baolu.lu@linux.intel.com>
To: Nicolin Chen <nicolinc@nvidia.com>,
	jgg@nvidia.com, kevin.tian@intel.com, corbet@lwn.net,
	will@kernel.org
Cc: bagasdotme@gmail.com, robin.murphy@arm.com, joro@8bytes.org,
	thierry.reding@gmail.com, vdumpa@nvidia.com,
	jonathanh@nvidia.com, shuah@kernel.org, jsnitsel@redhat.com,
	nathan@kernel.org, peterz@infradead.org, yi.l.liu@intel.com,
	mshavit@google.com, praan@google.com, zhangzekun11@huawei.com,
	iommu@lists.linux.dev, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-tegra@vger.kernel.org, linux-kselftest@vger.kernel.org,
	patches@lists.linux.dev, mochs@nvidia.com,
	alok.a.tiwari@oracle.com, vasant.hegde@amd.com,
	dwmw2@infradead.org
Subject: Re: [PATCH v6 10/25] iommufd/viommu: Add IOMMUFD_CMD_HW_QUEUE_ALLOC ioctl
Date: Mon, 16 Jun 2025 14:12:04 +0800	[thread overview]
Message-ID: <1ab8030b-8d2f-4ebe-a280-6d0e4e1d17c7@linux.intel.com> (raw)
In-Reply-To: <7dfb002613f224f57a069d27e7bf2b306b0a5ba0.1749884998.git.nicolinc@nvidia.com>

On 6/14/25 15:14, Nicolin Chen wrote:
> Introduce a new IOMMUFD_CMD_HW_QUEUE_ALLOC ioctl for user space to allocate
> a HW QUEUE object for a vIOMMU specific HW-accelerated queue, e.g.:
>   - NVIDIA's Virtual Command Queue
>   - AMD vIOMMU's Command Buffer, Event Log Buffers, and PPR Log Buffers
> 
> Since this is introduced with NVIDIA's VCMDQs that access the guest memory
> in the physical address space, add an iommufd_hw_queue_alloc_phys() helper
> that will create an access object to the queue memory in the IOAS, to avoid
> the mappings of the guest memory from being unmapped, during the life cycle
> of the HW queue object.
> 
> Reviewed-by: Pranjal Shrivastava<praan@google.com>
> Reviewed-by: Kevin Tian<kevin.tian@intel.com>
> Signed-off-by: Nicolin Chen<nicolinc@nvidia.com>
> ---
>   drivers/iommu/iommufd/iommufd_private.h |   2 +
>   include/linux/iommufd.h                 |   1 +
>   include/uapi/linux/iommufd.h            |  33 +++++
>   drivers/iommu/iommufd/main.c            |   6 +
>   drivers/iommu/iommufd/viommu.c          | 184 ++++++++++++++++++++++++
>   5 files changed, 226 insertions(+)
> 

[...]

> diff --git a/drivers/iommu/iommufd/viommu.c b/drivers/iommu/iommufd/viommu.c
> index 28ea5d026222..506479ece826 100644
> --- a/drivers/iommu/iommufd/viommu.c
> +++ b/drivers/iommu/iommufd/viommu.c
> @@ -201,3 +201,187 @@ int iommufd_vdevice_alloc_ioctl(struct iommufd_ucmd *ucmd)
>   	iommufd_put_object(ucmd->ictx, &viommu->obj);
>   	return rc;
>   }
> +
> +static void iommufd_hw_queue_destroy_access(struct iommufd_ctx *ictx,
> +					    struct iommufd_access *access,
> +					    u64 base_iova, size_t length)
> +{
> +	iommufd_access_unpin_pages(access, base_iova, length);
> +	iommufd_access_detach_internal(access);
> +	iommufd_access_destroy_internal(ictx, access);
> +}
> +
> +void iommufd_hw_queue_destroy(struct iommufd_object *obj)
> +{
> +	struct iommufd_hw_queue *hw_queue =
> +		container_of(obj, struct iommufd_hw_queue, obj);
> +	struct iommufd_viommu *viommu = hw_queue->viommu;
> +
> +	if (hw_queue->destroy)
> +		hw_queue->destroy(hw_queue);
> +	if (hw_queue->access)
> +		iommufd_hw_queue_destroy_access(viommu->ictx, hw_queue->access,
> +						hw_queue->base_addr,
> +						hw_queue->length);
> +	refcount_dec(&viommu->obj.users);
> +}
> +
> +/*
> + * When the HW accesses the guest queue via physical addresses, the underlying
> + * physical pages of the guest queue must be contiguous. Also, for the security
> + * concern that IOMMUFD_CMD_IOAS_UNMAP could potentially remove the mappings of
> + * the guest queue from the nesting parent iopt while the HW is still accessing
> + * the guest queue memory physically, such a HW queue must require an access to
> + * pin the underlying pages and prevent that from happening.
> + */
> +static struct iommufd_access *
> +iommufd_hw_queue_alloc_phys(struct iommu_hw_queue_alloc *cmd,
> +			    struct iommufd_viommu *viommu, phys_addr_t *base_pa)
> +{
> +	struct iommufd_access *access;
> +	struct page **pages;
> +	int max_npages, i;
> +	u64 offset;
> +	int rc;
> +
> +	offset =
> +		cmd->nesting_parent_iova - PAGE_ALIGN(cmd->nesting_parent_iova);
> +	max_npages = DIV_ROUND_UP(offset + cmd->length, PAGE_SIZE);
> +
> +	/*
> +	 * FIXME allocation may fail when sizeof(*pages) * max_npages is
> +	 * larger than PAGE_SIZE. This might need a new API returning a
> +	 * bio_vec or something more efficient.
> +	 */
> +	pages = kcalloc(max_npages, sizeof(*pages), GFP_KERNEL);
> +	if (!pages)
> +		return ERR_PTR(-ENOMEM);
> +
> +	access = iommufd_access_create_internal(viommu->ictx);
> +	if (IS_ERR(access)) {
> +		rc = PTR_ERR(access);
> +		goto out_free;
> +	}
> +
> +	rc = iommufd_access_attach_internal(access, viommu->hwpt->ioas);
> +	if (rc)
> +		goto out_destroy;
> +
> +	rc = iommufd_access_pin_pages(access, cmd->nesting_parent_iova,
> +				      cmd->length, pages, 0);
> +	if (rc)
> +		goto out_detach;
> +
> +	/* Validate if the underlying physical pages are contiguous */
> +	for (i = 1; i < max_npages; i++) {
> +		if (page_to_pfn(pages[i]) == page_to_pfn(pages[i - 1]) + 1)
> +			continue;
> +		rc = -EFAULT;
> +		goto out_unpin;
> +	}
> +
> +	*base_pa = page_to_pfn(pages[0]) << PAGE_SHIFT;
> +	kfree(pages);
> +	return access;
> +
> +out_unpin:
> +	iommufd_access_unpin_pages(access, cmd->nesting_parent_iova,
> +				   cmd->length);
> +out_detach:
> +	iommufd_access_detach_internal(access);
> +out_destroy:
> +	iommufd_access_destroy_internal(viommu->ictx, access);
> +out_free:
> +	kfree(pages);
> +	return ERR_PTR(rc);
> +}
> +
> +int iommufd_hw_queue_alloc_ioctl(struct iommufd_ucmd *ucmd)
> +{
> +	struct iommu_hw_queue_alloc *cmd = ucmd->cmd;
> +	struct iommufd_hw_queue *hw_queue;
> +	struct iommufd_viommu *viommu;
> +	struct iommufd_access *access;
> +	size_t hw_queue_size;
> +	phys_addr_t base_pa;
> +	u64 last;
> +	int rc;
> +
> +	if (cmd->flags || cmd->type == IOMMU_HW_QUEUE_TYPE_DEFAULT)
> +		return -EOPNOTSUPP;
> +	if (!cmd->length)
> +		return -EINVAL;
> +	if (check_add_overflow(cmd->nesting_parent_iova, cmd->length - 1,
> +			       &last))
> +		return -EOVERFLOW;
> +
> +	viommu = iommufd_get_viommu(ucmd, cmd->viommu_id);
> +	if (IS_ERR(viommu))
> +		return PTR_ERR(viommu);
> +
> +	if (!viommu->ops || !viommu->ops->get_hw_queue_size ||
> +	    !viommu->ops->hw_queue_init_phys) {
> +		rc = -EOPNOTSUPP;
> +		goto out_put_viommu;
> +	}
> +
> +	/*
> +	 * FIXME once ops->hw_queue_init is introduced, a WARN_ON_ONCE will be
> +	 * required, if hw_queue_init and hw_queue_init_phys both exist, since
> +	 * they should be mutually exclusive
> +	 */
> +
> +	hw_queue_size = viommu->ops->get_hw_queue_size(viommu, cmd->type);
> +	if (!hw_queue_size) {
> +		rc = -EOPNOTSUPP;
> +		goto out_put_viommu;
> +	}
> +
> +	/*
> +	 * It is a driver bug for providing a hw_queue_size smaller than the
> +	 * core HW queue structure size
> +	 */
> +	if (WARN_ON_ONCE(hw_queue_size < sizeof(*hw_queue))) {
> +		rc = -EOPNOTSUPP;
> +		goto out_put_viommu;
> +	}
> +
> +	/*
> +	 * FIXME once ops->hw_queue_init is introduced, this should check "if
> +	 * ops->hw_queue_init_phys". And "access" should be initialized to NULL.
> +	 */

I just don't follow here. Up until now, only viommu->ops->
hw_queue_init_phys has been added, which means the current code only
supports hardware queues that access guest memory using physical
addresses. The access object is not needed for the other type of
hardware queue that uses guest IOVA.

So, why not just abort here if ops->hw_queue_init_phys is not supported
by the IOMMU driver? Leave other logics to the patches that introduce
ops->hw_queue_init? I guess that would make this patch more readible.

> +	access = iommufd_hw_queue_alloc_phys(cmd, viommu, &base_pa);
> +	if (IS_ERR(access)) {
> +		rc = PTR_ERR(access);
> +		goto out_put_viommu;
> +	}

Thanks,
baolu

  reply	other threads:[~2025-06-16  6:13 UTC|newest]

Thread overview: 77+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-06-14  7:14 [PATCH v6 00/25] iommufd: Add vIOMMU infrastructure (Part-4 HW QUEUE) Nicolin Chen
2025-06-14  7:14 ` [PATCH v6 01/25] iommu: Add iommu_copy_struct_to_user helper Nicolin Chen
2025-06-14  7:14 ` [PATCH v6 02/25] iommu: Pass in a driver-level user data structure to viommu_init op Nicolin Chen
2025-06-14  7:14 ` [PATCH v6 03/25] iommufd/viommu: Allow driver-specific user data for a vIOMMU object Nicolin Chen
2025-06-14  7:14 ` [PATCH v6 04/25] iommufd/selftest: Support user_data in mock_viommu_alloc Nicolin Chen
2025-06-14  7:14 ` [PATCH v6 05/25] iommufd/selftest: Add coverage for viommu data Nicolin Chen
2025-06-14  7:14 ` [PATCH v6 06/25] iommufd/access: Allow access->ops to be NULL for internal use Nicolin Chen
2025-06-16  6:25   ` Baolu Lu
2025-06-16 13:33   ` Jason Gunthorpe
2025-06-17  2:21     ` Nicolin Chen
2025-06-19  9:14       ` Pranjal Shrivastava
2025-06-25  3:38   ` Tian, Kevin
2025-06-25 16:37     ` Nicolin Chen
2025-06-25 17:33       ` Nicolin Chen
2025-06-14  7:14 ` [PATCH v6 07/25] iommufd/access: Add internal APIs for HW queue to use Nicolin Chen
2025-06-16 13:37   ` Jason Gunthorpe
2025-06-17  2:25     ` Nicolin Chen
2025-06-17  4:23       ` Baolu Lu
2025-06-17 11:55         ` Jason Gunthorpe
2025-06-19  9:49       ` Pranjal Shrivastava
2025-06-19  9:42   ` Pranjal Shrivastava
2025-06-14  7:14 ` [PATCH v6 08/25] iommufd/viommu: Add driver-defined vDEVICE support Nicolin Chen
2025-06-16  6:26   ` Baolu Lu
2025-06-19 10:26   ` Pranjal Shrivastava
2025-06-19 11:44     ` Jason Gunthorpe
2025-06-21  4:51       ` Nicolin Chen
2025-06-14  7:14 ` [PATCH v6 09/25] iommufd/viommu: Introduce IOMMUFD_OBJ_HW_QUEUE and its related struct Nicolin Chen
2025-06-16 13:47   ` Jason Gunthorpe
2025-06-17  2:29     ` Nicolin Chen
2025-06-14  7:14 ` [PATCH v6 10/25] iommufd/viommu: Add IOMMUFD_CMD_HW_QUEUE_ALLOC ioctl Nicolin Chen
2025-06-16  6:12   ` Baolu Lu [this message]
2025-06-16  6:47     ` Nicolin Chen
2025-06-16  6:54       ` Baolu Lu
2025-06-16  7:04         ` Nicolin Chen
2025-06-16  7:09           ` Baolu Lu
2025-06-25  3:43       ` Tian, Kevin
2025-06-25 16:06         ` Nicolin Chen
2025-06-16  7:11   ` Baolu Lu
2025-06-16 13:58   ` Jason Gunthorpe
2025-06-25  3:45   ` Tian, Kevin
2025-06-25 23:06     ` Nicolin Chen
2025-06-14  7:14 ` [PATCH v6 11/25] iommufd/driver: Add iommufd_hw_queue_depend/undepend() helpers Nicolin Chen
2025-06-16 14:06   ` Jason Gunthorpe
2025-06-14  7:14 ` [PATCH v6 12/25] iommufd/selftest: Add coverage for IOMMUFD_CMD_HW_QUEUE_ALLOC Nicolin Chen
2025-06-14  7:14 ` [PATCH v6 13/25] iommufd: Add mmap interface Nicolin Chen
2025-06-16 11:33   ` Baolu Lu
2025-06-16 14:13   ` Jason Gunthorpe
2025-06-17  2:37     ` Nicolin Chen
2025-06-17 11:55       ` Jason Gunthorpe
2025-06-25 21:18     ` Nicolin Chen
2025-06-19 11:15   ` Pranjal Shrivastava
2025-06-14  7:14 ` [PATCH v6 14/25] iommufd/selftest: Add coverage for the new " Nicolin Chen
2025-06-14  7:14 ` [PATCH v6 15/25] Documentation: userspace-api: iommufd: Update HW QUEUE Nicolin Chen
2025-06-16 11:34   ` Baolu Lu
2025-06-14  7:14 ` [PATCH v6 16/25] iommu: Allow an input type in hw_info op Nicolin Chen
2025-06-16 11:53   ` Baolu Lu
2025-06-14  7:14 ` [PATCH v6 17/25] iommufd: Allow an input data_type via iommu_hw_info Nicolin Chen
2025-06-16 11:54   ` Baolu Lu
2025-06-16 14:14   ` Jason Gunthorpe
2025-06-14  7:14 ` [PATCH v6 18/25] iommufd/selftest: Update hw_info coverage for an input data_type Nicolin Chen
2025-06-14  7:14 ` [PATCH v6 19/25] iommu/arm-smmu-v3-iommufd: Add vsmmu_size/type and vsmmu_init impl ops Nicolin Chen
2025-06-16 14:19   ` Jason Gunthorpe
2025-06-14  7:14 ` [PATCH v6 20/25] iommu/arm-smmu-v3-iommufd: Add hw_info to impl_ops Nicolin Chen
2025-06-16 14:20   ` Jason Gunthorpe
2025-06-19 11:47   ` Pranjal Shrivastava
2025-06-19 18:53     ` Jason Gunthorpe
2025-06-20  3:32       ` Pranjal Shrivastava
2025-06-21  5:36         ` Nicolin Chen
2025-06-23 15:13           ` Pranjal Shrivastava
2025-06-14  7:14 ` [PATCH v6 21/25] iommu/tegra241-cmdqv: Use request_threaded_irq Nicolin Chen
2025-06-14  7:14 ` [PATCH v6 22/25] iommu/tegra241-cmdqv: Simplify deinit flow in tegra241_cmdqv_remove_vintf() Nicolin Chen
2025-06-14  7:14 ` [PATCH v6 23/25] iommu/tegra241-cmdqv: Do not statically map LVCMDQs Nicolin Chen
2025-06-16 15:44   ` Jason Gunthorpe
2025-06-14  7:14 ` [PATCH v6 24/25] iommu/tegra241-cmdqv: Add user-space use support Nicolin Chen
2025-06-16 16:03   ` Jason Gunthorpe
2025-06-26 18:51   ` Nicolin Chen
2025-06-14  7:14 ` [PATCH v6 25/25] iommu/tegra241-cmdqv: Add IOMMU_VEVENTQ_TYPE_TEGRA241_CMDQV support Nicolin Chen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1ab8030b-8d2f-4ebe-a280-6d0e4e1d17c7@linux.intel.com \
    --to=baolu.lu@linux.intel.com \
    --cc=alok.a.tiwari@oracle.com \
    --cc=bagasdotme@gmail.com \
    --cc=corbet@lwn.net \
    --cc=dwmw2@infradead.org \
    --cc=iommu@lists.linux.dev \
    --cc=jgg@nvidia.com \
    --cc=jonathanh@nvidia.com \
    --cc=joro@8bytes.org \
    --cc=jsnitsel@redhat.com \
    --cc=kevin.tian@intel.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=linux-tegra@vger.kernel.org \
    --cc=mochs@nvidia.com \
    --cc=mshavit@google.com \
    --cc=nathan@kernel.org \
    --cc=nicolinc@nvidia.com \
    --cc=patches@lists.linux.dev \
    --cc=peterz@infradead.org \
    --cc=praan@google.com \
    --cc=robin.murphy@arm.com \
    --cc=shuah@kernel.org \
    --cc=thierry.reding@gmail.com \
    --cc=vasant.hegde@amd.com \
    --cc=vdumpa@nvidia.com \
    --cc=will@kernel.org \
    --cc=yi.l.liu@intel.com \
    --cc=zhangzekun11@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).