lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <b1ad7bee26fc87c1b73ac18d2284ad2e10b4b4d5.1762235099.git.charan.kalla@oss.qualcomm.com>
Date: Tue,  4 Nov 2025 14:21:05 +0530
From: Charan Teja Kalla <charan.kalla@....qualcomm.com>
To: robin.murphy@....com, will@...nel.org, joro@...tes.org, robh@...nel.org,
        dmitry.baryshkov@....qualcomm.com, konrad.dybcio@....qualcomm.com,
        bjorn.andersson@....qualcomm.com, bod@...nel.org, conor+dt@...nel.org,
        krzk+dt@...nel.org, saravanak@...gle.com,
        prakash.gupta@....qualcomm.com, vikash.garodia@....qualcomm.com
Cc: iommu@...ts.linux.dev, linux-kernel@...r.kernel.org,
        devicetree@...r.kernel.org,
        Charan Teja Kalla <charan.kalla@....qualcomm.com>
Subject: [PATCH 6/6] of: use correct iommu-map parsing logic from of_iommu layer

Use of_map_id_or_funcid() that takes #iommu-cells into account, while
keeping the compatibility with the existing DTs, which assume single
argument. A callback function is used to get the of_phandle arguments,
that contains iommu controller and its cells, and is called into the
vendor specific driver through of_iommu_xlate().

When 'args_count' passed in of_phandle_args is '1', it is expected that
of_map_id_or_funcid() fills the translated id into the of_phandle
arguments which then called into of_iommu_xlate().

When 'args_count' > 1, as it is complex to establish a defined relation
between the input id and output, of_iommu layer handles through the
below relation:
For platform devices, 'rid' defined in the iommu-map tuple indicates a
function, through a bit position, which is compared against passed input
'id' that represents a bitmap of functions represented by the device.

For others, 'rid' is compared against the input 'id' as an integer value.

When matched, of_iommu_xlate() is used to call into vendor specific
iommu driver.

Signed-off-by: Charan Teja Kalla <charan.kalla@....qualcomm.com>
---
 drivers/iommu/of_iommu.c | 59 +++++++++++++++++++++++++++++++++-------
 drivers/of/base.c        |  4 +--
 include/linux/of.h       | 15 ++++++++++
 3 files changed, 66 insertions(+), 12 deletions(-)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 6b989a62def2..9575e37ad844 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -16,6 +16,7 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/fsl/mc.h>
+#include <linux/platform_device.h>
 
 #include "iommu-priv.h"
 
@@ -41,22 +42,60 @@ static int of_iommu_xlate(struct device *dev,
 	return ret;
 }
 
+/**
+ * of_iommu_map_xlate - Translate IOMMU mapping and release node reference.
+ *
+ * @id: bitmap for function id parsing(platform devices) or base id.
+ * @id_base: checked against @id
+ * @arg: Device to configure.
+ * @iommu_spec: IOMMU specifier from device tree.
+ *
+ * Wrapper function that calls of_iommu_xlate() to configure the IOMMU
+ * mapping for a device, then releases the device tree node reference.
+ * This is used as a callback function for of_map_id_or_funcid().
+ *
+ * When the cell_count > 1, the relation between input id(@id) and the
+ * output specifier is complex to define, like linear case when cell_count = 1,
+ * Handle such cases where linear relation can't be established between
+ * the @id and the output with the below relation:
+ * a) For platform devices, @id_base represents the function id, which is
+ * compared against the input @id, all maintained in bitmap relation.
+ * b) For other devices, it performs exact ID matching.
+ *
+ * Return: 0 on success, -EAGAIN if ID doesn't match
+ * and standard negative error code on failure.
+ */
+static int of_iommu_map_xlate(u32 id, u32 id_base,
+			void *arg, struct of_phandle_args *iommu_spec)
+{
+	struct device *dev = arg;
+	int ret;
+
+	if (iommu_spec->args_count > 1) {
+		if (dev_is_platform(dev)) {     /* case a. */
+			if (!(BIT(id_base - 1) & id))
+				return -EAGAIN;
+		} else if (id_base != id) {     /* case b. */
+			return -EAGAIN;
+		}
+
+	}
+
+	ret = of_iommu_xlate(dev, iommu_spec);
+	of_node_put(iommu_spec->np);
+	return ret;
+}
+
 static int of_iommu_configure_dev_id(struct device_node *master_np,
 				     struct device *dev,
 				     const u32 *id)
 {
 	struct of_phandle_args iommu_spec = { .args_count = 1 };
-	int err;
 
-	err = of_map_id(master_np, *id, "iommu-map",
-			 "iommu-map-mask", &iommu_spec.np,
-			 iommu_spec.args);
-	if (err)
-		return err;
-
-	err = of_iommu_xlate(dev, &iommu_spec);
-	of_node_put(iommu_spec.np);
-	return err;
+	return of_map_id_or_funcid(master_np, *id, "iommu-map",
+			"iommu-map-mask", &iommu_spec.np,
+			 iommu_spec.args, dev, &iommu_spec,
+			 of_iommu_map_xlate);
 }
 
 static int of_iommu_configure_dev(struct device_node *master_np,
diff --git a/drivers/of/base.c b/drivers/of/base.c
index cd221c003dd5..b5554c0b0bc5 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -2181,7 +2181,7 @@ static int of_map_id_cell_count(const __be32 *map, const char *map_name,
  * @id: input id that is given for translation.
  * @arg: argument passed to the @fn.
  * @pargs: filled by the contents of @map and pass to the @fn.
- * @fn: Callback function that operated on @dev and @fn.
+ * @fn: Callback function that operates on @arg.
  *
  * The function populates the phandle args structure with the node and
  * specifier cells, then invokes the callback function. The callback is
@@ -2233,7 +2233,7 @@ static int of_map_id_untranslated(const __be32 *map, u32 cell_count, u32 id,
  *
  * Return: 0 on success or a standard error code on failure.
  */
-static int of_map_id_or_funcid(const struct device_node *np, u32 id,
+int of_map_id_or_funcid(const struct device_node *np, u32 id,
 		const char *map_name, const char *map_mask_name,
 		struct device_node **target, u32 *id_out,
 		void *arg, struct of_phandle_args *pargs,
diff --git a/include/linux/of.h b/include/linux/of.h
index f8d976205ff4..7935ff5ac09e 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -410,6 +410,12 @@ extern int of_phandle_iterator_args(struct of_phandle_iterator *it,
 extern int of_alias_get_id(const struct device_node *np, const char *stem);
 extern int of_alias_get_highest_id(const char *stem);
 
+extern int of_map_id_or_funcid(const struct device_node *np, u32 id,
+	       const char *map_name, const char *map_mask_name,
+	       struct device_node **target, u32 *id_out,
+	       void *arg, struct of_phandle_args *pargs,
+	       of_map_id_cb fn);
+
 bool of_machine_compatible_match(const char *const *compats);
 
 /**
@@ -909,6 +915,15 @@ static inline int of_map_id(const struct device_node *np, u32 id,
 	return -EINVAL;
 }
 
+static inline int of_map_id_or_funcid(const struct device_node *np, u32 id,
+	       const char *map_name, const char *map_mask_name,
+	       struct device_node **target, u32 *id_out,
+	       void *arg, struct of_phandle_args *pargs,
+	       of_map_id_cb fn)
+{
+	return -EINVAL;
+}
+
 static inline phys_addr_t of_dma_get_max_cpu_address(struct device_node *np)
 {
 	return PHYS_ADDR_MAX;
-- 
2.34.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ