linux-doc.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Nicolin Chen <nicolinc@nvidia.com>
To: <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>, <baolu.lu@linux.intel.com>
Subject: [PATCH v5 15/29] iommufd/driver: Add iommufd_hw_queue_depend/undepend() helpers
Date: Sat, 17 May 2025 20:21:32 -0700	[thread overview]
Message-ID: <8989f316a150a0eea15ce1e58abc311293d1692b.1747537752.git.nicolinc@nvidia.com> (raw)
In-Reply-To: <cover.1747537752.git.nicolinc@nvidia.com>

NVIDIA Virtual Command Queue is one of the iommufd users exposing vIOMMU
features to user space VMs. Its hardware has a strict rule when mapping
and unmapping multiple global CMDQVs to/from a VM-owned VINTF, requiring
mappings in ascending order and unmappings in descending order.

The tegra241-cmdqv driver can apply the rule for a mapping in the LVCMDQ
allocation handler. However, it can't do the same for an unmapping since
user space could start random destroy calls breaking the rule, while the
destroy op in the driver level can't reject a destroy call as it returns
void.

Add iommufd_hw_queue_depend/undepend for-driver helpers, allowing LVCMDQ
allocator to refcount_inc() a sibling LVCMDQ object and LVCMDQ destroyer
to refcount_dec(), so that iommufd core will help block a random destroy
call that breaks the rule.

This is a bit of compromise, because a driver might end up with abusing
the API that deadlocks the objects. So restrict the API to a dependency
between two driver-allocated objects of the same type, as iommufd would
unlikely build any core-level dependency in this case. And encourage to
use the macro version that currently supports the HW QUEUE objects only.

Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>
Reviewed-by: Pranjal Shrivastava <praan@google.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
 include/linux/iommufd.h        | 44 ++++++++++++++++++++++++++++++++++
 drivers/iommu/iommufd/driver.c | 28 ++++++++++++++++++++++
 2 files changed, 72 insertions(+)

diff --git a/include/linux/iommufd.h b/include/linux/iommufd.h
index 923c66ccc15a..a89797307379 100644
--- a/include/linux/iommufd.h
+++ b/include/linux/iommufd.h
@@ -272,6 +272,10 @@ struct iommufd_object *_iommufd_object_alloc(struct iommufd_ctx *ictx,
 struct iommufd_object *
 _iommufd_object_alloc_ucmd(struct iommufd_ucmd *ucmd, size_t size,
 			   enum iommufd_object_type type);
+int _iommufd_object_depend(struct iommufd_object *obj_dependent,
+			   struct iommufd_object *obj_depended);
+void _iommufd_object_undepend(struct iommufd_object *obj_dependent,
+			      struct iommufd_object *obj_depended);
 struct device *iommufd_viommu_find_dev(struct iommufd_viommu *viommu,
 				       unsigned long vdev_id);
 int iommufd_viommu_get_vdev_id(struct iommufd_viommu *viommu,
@@ -294,6 +298,18 @@ _iommufd_object_alloc_ucmd(struct iommufd_ucmd *ucmd, size_t size,
 	return ERR_PTR(-EOPNOTSUPP);
 }
 
+static inline int _iommufd_object_depend(struct iommufd_object *obj_dependent,
+					 struct iommufd_object *obj_depended)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline void
+_iommufd_object_undepend(struct iommufd_object *obj_dependent,
+			 struct iommufd_object *obj_depended)
+{
+}
+
 static inline struct device *
 iommufd_viommu_find_dev(struct iommufd_viommu *viommu, unsigned long vdev_id)
 {
@@ -359,4 +375,32 @@ static inline int iommufd_viommu_report_event(struct iommufd_viommu *viommu,
 		}                                                              \
 		ret;                                                           \
 	})
+
+/*
+ * Helpers for IOMMU driver to build/destroy a dependency between two sibling
+ * structures created by one of the allocators above
+ */
+#define iommufd_hw_queue_depend(dependent, depended, member)                   \
+	({                                                                     \
+		int ret = -EINVAL;                                             \
+									       \
+		static_assert(__same_type(struct iommufd_hw_queue,             \
+					  dependent->member));                 \
+		static_assert(__same_type(typeof(*dependent), *depended));     \
+		if (!WARN_ON_ONCE(dependent->member.ictx !=                    \
+				  depended->member.ictx))                      \
+			ret = _iommufd_object_depend(&dependent->member.obj,   \
+						     &depended->member.obj);   \
+		ret;                                                           \
+	})
+
+#define iommufd_hw_queue_undepend(dependent, depended, member)                 \
+	({                                                                     \
+		static_assert(__same_type(struct iommufd_hw_queue,             \
+					  dependent->member));                 \
+		static_assert(__same_type(typeof(*dependent), *depended));     \
+		WARN_ON_ONCE(dependent->member.ictx != depended->member.ictx); \
+		_iommufd_object_undepend(&dependent->member.obj,               \
+					 &depended->member.obj);               \
+	})
 #endif
diff --git a/drivers/iommu/iommufd/driver.c b/drivers/iommu/iommufd/driver.c
index 28dec9e09720..529968126f85 100644
--- a/drivers/iommu/iommufd/driver.c
+++ b/drivers/iommu/iommufd/driver.c
@@ -54,6 +54,34 @@ struct iommufd_object *_iommufd_object_alloc_ucmd(struct iommufd_ucmd *ucmd,
 }
 EXPORT_SYMBOL_NS_GPL(_iommufd_object_alloc_ucmd, "IOMMUFD");
 
+/* Driver should use a per-structure helper in include/linux/iommufd.h */
+int _iommufd_object_depend(struct iommufd_object *obj_dependent,
+			   struct iommufd_object *obj_depended)
+{
+	/* Reject self dependency that dead locks */
+	if (obj_dependent == obj_depended)
+		return -EINVAL;
+	/* Only support dependency between two objects of the same type */
+	if (obj_dependent->type != obj_depended->type)
+		return -EINVAL;
+
+	refcount_inc(&obj_depended->users);
+	return 0;
+}
+EXPORT_SYMBOL_NS_GPL(_iommufd_object_depend, "IOMMUFD");
+
+/* Driver should use a per-structure helper in include/linux/iommufd.h */
+void _iommufd_object_undepend(struct iommufd_object *obj_dependent,
+			      struct iommufd_object *obj_depended)
+{
+	if (WARN_ON_ONCE(obj_dependent == obj_depended ||
+			 obj_dependent->type != obj_depended->type))
+		return;
+
+	refcount_dec(&obj_depended->users);
+}
+EXPORT_SYMBOL_NS_GPL(_iommufd_object_undepend, "IOMMUFD");
+
 /* Caller should xa_lock(&viommu->vdevs) to protect the return value */
 struct device *iommufd_viommu_find_dev(struct iommufd_viommu *viommu,
 				       unsigned long vdev_id)
-- 
2.43.0


  parent reply	other threads:[~2025-05-18  3:22 UTC|newest]

Thread overview: 79+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-05-18  3:21 [PATCH v5 00/29] iommufd: Add vIOMMU infrastructure (Part-4 HW QUEUE) Nicolin Chen
2025-05-18  3:21 ` [PATCH v5 01/29] iommufd: Apply obvious cosmetic fixes Nicolin Chen
2025-05-23  7:43   ` Tian, Kevin
2025-05-28 16:55   ` Jason Gunthorpe
2025-05-18  3:21 ` [PATCH v5 02/29] iommufd: Introduce iommufd_object_alloc_ucmd helper Nicolin Chen
2025-05-23  7:46   ` Tian, Kevin
2025-05-23 21:17     ` Nicolin Chen
2025-05-28 16:56   ` Jason Gunthorpe
2025-05-18  3:21 ` [PATCH v5 03/29] iommu: Apply the new " Nicolin Chen
2025-05-23  7:49   ` Tian, Kevin
2025-05-23 21:34     ` Nicolin Chen
2025-05-28  8:11       ` Tian, Kevin
2025-05-28 16:57   ` Jason Gunthorpe
2025-05-18  3:21 ` [PATCH v5 04/29] iommu: Add iommu_copy_struct_to_user helper Nicolin Chen
2025-05-18  3:21 ` [PATCH v5 05/29] iommu: Pass in a driver-level user data structure to viommu_alloc op Nicolin Chen
2025-05-18  3:21 ` [PATCH v5 06/29] iommufd/viommu: Allow driver-specific user data for a vIOMMU object Nicolin Chen
2025-05-18  3:21 ` [PATCH v5 07/29] iommufd/selftest: Support user_data in mock_viommu_alloc Nicolin Chen
2025-05-18  3:21 ` [PATCH v5 08/29] iommufd/selftest: Add coverage for viommu data Nicolin Chen
2025-05-18  3:21 ` [PATCH v5 09/29] iommufd: Do not unmap an owned iopt_area Nicolin Chen
2025-05-23  7:53   ` Tian, Kevin
2025-05-23 21:38     ` Nicolin Chen
2025-05-24  3:30   ` Nicolin Chen
2025-05-28 17:08   ` Jason Gunthorpe
2025-05-28 18:07     ` Nicolin Chen
2025-06-05  4:30     ` Nicolin Chen
2025-05-18  3:21 ` [PATCH v5 10/29] iommufd: Abstract iopt_pin_pages and iopt_unpin_pages helpers Nicolin Chen
2025-05-28 17:17   ` Jason Gunthorpe
2025-06-05  4:11     ` Nicolin Chen
2025-06-05 15:16       ` Jason Gunthorpe
2025-06-05 17:04         ` Nicolin Chen
2025-06-05 19:40           ` Jason Gunthorpe
2025-06-06  4:46             ` Nicolin Chen
2025-05-18  3:21 ` [PATCH v5 11/29] iommufd/driver: Let iommufd_viommu_alloc helper save ictx to viommu->ictx Nicolin Chen
2025-05-18  3:21 ` [PATCH v5 12/29] iommufd/viommu: Add driver-allocated vDEVICE support Nicolin Chen
2025-05-18  3:21 ` [PATCH v5 13/29] iommufd/viommu: Introduce IOMMUFD_OBJ_HW_QUEUE and its related struct Nicolin Chen
2025-05-23  7:55   ` Tian, Kevin
2025-05-23 21:45     ` Nicolin Chen
2025-05-28  8:12       ` Tian, Kevin
2025-05-28 18:01         ` Nicolin Chen
2025-05-30 16:07   ` Jason Gunthorpe
2025-05-30 16:33     ` Nicolin Chen
2025-05-18  3:21 ` [PATCH v5 14/29] iommufd/viommu: Add IOMMUFD_CMD_HW_QUEUE_ALLOC ioctl Nicolin Chen
2025-05-23  8:00   ` Tian, Kevin
2025-05-24  0:30     ` Nicolin Chen
2025-05-30 16:14   ` Jason Gunthorpe
2025-05-30 17:38     ` Nicolin Chen
2025-05-30 17:40       ` Jason Gunthorpe
2025-05-30 18:23         ` Nicolin Chen
2025-05-30 18:25           ` Jason Gunthorpe
2025-05-30 18:39             ` Nicolin Chen
2025-06-03  5:41     ` Nicolin Chen
2025-06-03 12:24       ` Jason Gunthorpe
2025-05-18  3:21 ` Nicolin Chen [this message]
2025-05-18  3:21 ` [PATCH v5 16/29] iommufd/selftest: Add coverage for IOMMUFD_CMD_HW_QUEUE_ALLOC Nicolin Chen
2025-05-18  3:21 ` [PATCH v5 17/29] iommufd: Add mmap interface Nicolin Chen
2025-05-30 16:29   ` Jason Gunthorpe
2025-05-30 16:59     ` Nicolin Chen
2025-05-30 17:12       ` Jason Gunthorpe
2025-05-18  3:21 ` [PATCH v5 18/29] iommufd/selftest: Add coverage for the new " Nicolin Chen
2025-05-18  3:21 ` [PATCH v5 19/29] Documentation: userspace-api: iommufd: Update HW QUEUE Nicolin Chen
2025-05-18  3:21 ` [PATCH v5 20/29] iommu: Allow an input type in hw_info op Nicolin Chen
2025-05-23  8:04   ` Tian, Kevin
2025-05-30 16:52   ` Jason Gunthorpe
2025-05-18  3:21 ` [PATCH v5 21/29] iommufd: Allow an input data_type via iommu_hw_info Nicolin Chen
2025-05-23  8:06   ` Tian, Kevin
2025-05-30 16:52   ` Jason Gunthorpe
2025-05-30 17:11     ` Nicolin Chen
2025-05-18  3:21 ` [PATCH v5 22/29] iommufd/selftest: Update hw_info coverage for an input data_type Nicolin Chen
2025-05-18  3:21 ` [PATCH v5 23/29] iommu/arm-smmu-v3-iommufd: Add vsmmu_alloc impl op Nicolin Chen
2025-05-18  3:21 ` [PATCH v5 24/29] iommu/arm-smmu-v3-iommufd: Add hw_info to impl_ops Nicolin Chen
2025-05-30 16:57   ` Jason Gunthorpe
2025-05-18  3:21 ` [PATCH v5 25/29] iommu/tegra241-cmdqv: Use request_threaded_irq Nicolin Chen
2025-05-18  3:21 ` [PATCH v5 26/29] iommu/tegra241-cmdqv: Simplify deinit flow in tegra241_cmdqv_remove_vintf() Nicolin Chen
2025-05-18  3:21 ` [PATCH v5 27/29] iommu/tegra241-cmdqv: Do not statically map LVCMDQs Nicolin Chen
2025-05-18  3:21 ` [PATCH v5 28/29] iommu/tegra241-cmdqv: Add user-space use support Nicolin Chen
2025-05-30 17:10   ` Jason Gunthorpe
2025-05-30 17:19     ` Nicolin Chen
2025-05-18  3:21 ` [PATCH v5 29/29] iommu/tegra241-cmdqv: Add IOMMU_VEVENTQ_TYPE_TEGRA241_CMDQV support Nicolin Chen
2025-05-30 17:09   ` Jason Gunthorpe

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=8989f316a150a0eea15ce1e58abc311293d1692b.1747537752.git.nicolinc@nvidia.com \
    --to=nicolinc@nvidia.com \
    --cc=alok.a.tiwari@oracle.com \
    --cc=bagasdotme@gmail.com \
    --cc=baolu.lu@linux.intel.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=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).