IOMMU Archive on lore.kernel.org
 help / color / Atom feed
From: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
To: linux-arm-kernel@lists.infradead.org
Cc: devicetree@vger.kernel.org, Marc Zyngier <maz@kernel.org>,
	Makarand Pawagi <makarand.pawagi@nxp.com>,
	linux-pci@vger.kernel.org,
	Catalin Marinas <catalin.marinas@arm.com>,
	Hanjun Guo <guohanjun@huawei.com>,
	"Rafael J. Wysocki" <rjw@rjwysocki.net>,
	Robin Murphy <robin.murphy@arm.com>,
	linux-acpi@vger.kernel.org, iommu@lists.linux-foundation.org,
	Rob Herring <robh+dt@kernel.org>,
	Sudeep Holla <sudeep.holla@arm.com>,
	Bjorn Helgaas <bhelgaas@google.com>,
	Will Deacon <will@kernel.org>,
	Diana Craciun <diana.craciun@oss.nxp.com>
Subject: [PATCH v2 05/12] ACPI/IORT: Add an input ID to acpi_dma_configure()
Date: Fri, 19 Jun 2020 09:20:06 +0100
Message-ID: <20200619082013.13661-6-lorenzo.pieralisi@arm.com> (raw)
In-Reply-To: <20200619082013.13661-1-lorenzo.pieralisi@arm.com>

Some HW devices are created as child devices of proprietary busses,
that have a bus specific policy defining how the child devices
wires representing the devices ID are translated into IOMMU and
IRQ controllers device IDs.

Current IORT code provides translations for:

- PCI devices, where the device ID is well identified at bus level
  as the requester ID (RID)
- Platform devices that are endpoint devices where the device ID is
  retrieved from the ACPI object IORT mappings (Named components single
  mappings). A platform device is represented in IORT as a named
  component node

For devices that are child devices of proprietary busses the IORT
firmware represents the bus node as a named component node in IORT
and it is up to that named component node to define in/out bus
specific ID translations for the bus child devices that are
allocated and created in a bus specific manner.

In order to make IORT ID translations available for proprietary
bus child devices, the current ACPI (and IORT) code must be
augmented to provide an additional ID parameter to acpi_dma_configure()
representing the child devices input ID. This ID is bus specific
and it is retrieved in bus specific code.

By adding an ID parameter to acpi_dma_configure(), the IORT
code can map the child device ID to an IOMMU stream ID through
the IORT named component representing the bus in/out ID mappings.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Hanjun Guo <guohanjun@huawei.com>
Cc: Sudeep Holla <sudeep.holla@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
---
 drivers/acpi/arm64/iort.c | 59 +++++++++++++++++++++++++++++----------
 drivers/acpi/scan.c       |  8 ++++--
 include/acpi/acpi_bus.h   |  9 ++++--
 include/linux/acpi.h      |  7 +++++
 include/linux/acpi_iort.h |  7 +++--
 5 files changed, 67 insertions(+), 23 deletions(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 421c6976ab81..ec782e4a0fe4 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -978,19 +978,54 @@ static void iort_named_component_init(struct device *dev,
 					   nc->node_flags);
 }
 
+static int iort_nc_iommu_map(struct device *dev, struct acpi_iort_node *node)
+{
+	struct acpi_iort_node *parent;
+	int err = -ENODEV, i = 0;
+	u32 streamid = 0;
+
+	do {
+
+		parent = iort_node_map_platform_id(node, &streamid,
+						   IORT_IOMMU_TYPE,
+						   i++);
+
+		if (parent)
+			err = iort_iommu_xlate(dev, parent, streamid);
+	} while (parent && !err);
+
+	return err;
+}
+
+static int iort_nc_iommu_map_id(struct device *dev,
+				struct acpi_iort_node *node,
+				const u32 *in_id)
+{
+	struct acpi_iort_node *parent;
+	u32 streamid;
+
+	parent = iort_node_map_id(node, *in_id, &streamid, IORT_IOMMU_TYPE);
+	if (parent)
+		return iort_iommu_xlate(dev, parent, streamid);
+
+	return -ENODEV;
+}
+
+
 /**
- * iort_iommu_configure - Set-up IOMMU configuration for a device.
+ * iort_iommu_configure_id - Set-up IOMMU configuration for a device.
  *
  * @dev: device to configure
+ * @id_in: optional input id const value pointer
  *
  * Returns: iommu_ops pointer on configuration success
  *          NULL on configuration failure
  */
-const struct iommu_ops *iort_iommu_configure(struct device *dev)
+const struct iommu_ops *iort_iommu_configure_id(struct device *dev,
+						const u32 *id_in)
 {
-	struct acpi_iort_node *node, *parent;
+	struct acpi_iort_node *node;
 	const struct iommu_ops *ops;
-	u32 streamid = 0;
 	int err = -ENODEV;
 
 	/*
@@ -1019,21 +1054,13 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)
 		if (fwspec && iort_pci_rc_supports_ats(node))
 			fwspec->flags |= IOMMU_FWSPEC_PCI_RC_ATS;
 	} else {
-		int i = 0;
-
 		node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
 				      iort_match_node_callback, dev);
 		if (!node)
 			return NULL;
 
-		do {
-			parent = iort_node_map_platform_id(node, &streamid,
-							   IORT_IOMMU_TYPE,
-							   i++);
-
-			if (parent)
-				err = iort_iommu_xlate(dev, parent, streamid);
-		} while (parent && !err);
+		err = id_in ? iort_nc_iommu_map_id(dev, node, id_in) :
+			      iort_nc_iommu_map(dev, node);
 
 		if (!err)
 			iort_named_component_init(dev, node);
@@ -1058,6 +1085,7 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)
 
 	return ops;
 }
+
 #else
 static inline const struct iommu_ops *iort_fwspec_iommu_ops(struct device *dev)
 { return NULL; }
@@ -1066,7 +1094,8 @@ static inline int iort_add_device_replay(const struct iommu_ops *ops,
 { return 0; }
 int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head)
 { return 0; }
-const struct iommu_ops *iort_iommu_configure(struct device *dev)
+const struct iommu_ops *iort_iommu_configure_id(struct device *dev,
+						const u32 *input_id)
 { return NULL; }
 #endif
 
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 8777faced51a..2142f1554761 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1457,8 +1457,10 @@ int acpi_dma_get_range(struct device *dev, u64 *dma_addr, u64 *offset,
  * acpi_dma_configure - Set-up DMA configuration for the device.
  * @dev: The pointer to the device
  * @attr: device dma attributes
+ * @input_id: input device id const value pointer
  */
-int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
+int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
+			  const u32 *input_id)
 {
 	const struct iommu_ops *iommu;
 	u64 dma_addr = 0, size = 0;
@@ -1470,7 +1472,7 @@ int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
 
 	iort_dma_setup(dev, &dma_addr, &size);
 
-	iommu = iort_iommu_configure(dev);
+	iommu = iort_iommu_configure_id(dev, input_id);
 	if (PTR_ERR(iommu) == -EPROBE_DEFER)
 		return -EPROBE_DEFER;
 
@@ -1479,7 +1481,7 @@ int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(acpi_dma_configure);
+EXPORT_SYMBOL_GPL(acpi_dma_configure_id);
 
 static void acpi_init_coherency(struct acpi_device *adev)
 {
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 5afb6ceb284f..a3abcc4b7d9f 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -588,8 +588,13 @@ bool acpi_dma_supported(struct acpi_device *adev);
 enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
 int acpi_dma_get_range(struct device *dev, u64 *dma_addr, u64 *offset,
 		       u64 *size);
-int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr);
-
+int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
+			   const u32 *input_id);
+static inline int acpi_dma_configure(struct device *dev,
+				     enum dev_dma_attr attr)
+{
+	return acpi_dma_configure_id(dev, attr, NULL);
+}
 struct acpi_device *acpi_find_child_device(struct acpi_device *parent,
 					   u64 address, bool check_children);
 int acpi_is_root_bridge(acpi_handle);
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index d661cd0ee64d..6d2c47489d90 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -905,6 +905,13 @@ static inline int acpi_dma_configure(struct device *dev,
 	return 0;
 }
 
+static inline int acpi_dma_configure_id(struct device *dev,
+					enum dev_dma_attr attr,
+					const u32 *input_id)
+{
+	return 0;
+}
+
 #define ACPI_PTR(_ptr)	(NULL)
 
 static inline void acpi_device_set_enumerated(struct acpi_device *adev)
diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
index e51425e083da..20a32120bb88 100644
--- a/include/linux/acpi_iort.h
+++ b/include/linux/acpi_iort.h
@@ -35,7 +35,8 @@ void acpi_configure_pmsi_domain(struct device *dev);
 int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id);
 /* IOMMU interface */
 void iort_dma_setup(struct device *dev, u64 *dma_addr, u64 *size);
-const struct iommu_ops *iort_iommu_configure(struct device *dev);
+const struct iommu_ops *iort_iommu_configure_id(struct device *dev,
+						const u32 *id_in);
 int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head);
 #else
 static inline void acpi_iort_init(void) { }
@@ -48,8 +49,8 @@ static inline void acpi_configure_pmsi_domain(struct device *dev) { }
 /* IOMMU interface */
 static inline void iort_dma_setup(struct device *dev, u64 *dma_addr,
 				  u64 *size) { }
-static inline const struct iommu_ops *iort_iommu_configure(
-				      struct device *dev)
+static inline const struct iommu_ops *iort_iommu_configure_id(
+				      struct device *dev, const u32 *id_in)
 { return NULL; }
 static inline
 int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head)
-- 
2.26.1

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

  parent reply index

Thread overview: 82+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-21 12:59 [PATCH 00/12] ACPI/OF: Upgrade MSI/IOMMU ID mapping APIs Lorenzo Pieralisi
2020-05-21 12:59 ` [PATCH 01/12] ACPI/IORT: Make iort_match_node_callback walk the ACPI namespace for NC Lorenzo Pieralisi
2020-05-21 12:59 ` [PATCH 02/12] ACPI/IORT: Make iort_get_device_domain IRQ domain agnostic Lorenzo Pieralisi
2020-05-21 19:56   ` Bjorn Helgaas
2020-05-21 12:59 ` [PATCH 03/12] ACPI/IORT: Make iort_msi_map_rid() PCI agnostic Lorenzo Pieralisi
2020-05-21 13:00 ` [PATCH 04/12] ACPI/IORT: Remove useless PCI bus walk Lorenzo Pieralisi
2020-05-21 13:00 ` [PATCH 05/12] ACPI/IORT: Add an input ID to acpi_dma_configure() Lorenzo Pieralisi
2020-05-21 13:00 ` [PATCH 06/12] of/iommu: Make of_map_rid() PCI agnostic Lorenzo Pieralisi
2020-05-21 22:47   ` Rob Herring
2020-06-04 14:27     ` Lorenzo Pieralisi
2020-05-21 13:00 ` [PATCH 07/12] of/device: Add input id to of_dma_configure() Lorenzo Pieralisi
2020-05-21 23:02   ` Rob Herring
2020-06-04 14:49     ` Lorenzo Pieralisi
2020-05-21 13:00 ` [PATCH 08/12] of/irq: make of_msi_map_get_device_domain() bus agnostic Lorenzo Pieralisi
2020-05-21 19:57   ` Bjorn Helgaas
2020-05-21 13:00 ` [PATCH 09/12] dt-bindings: arm: fsl: Add msi-map device-tree binding for fsl-mc bus Lorenzo Pieralisi
2020-05-21 23:10   ` Rob Herring
2020-05-22  9:42     ` Robin Murphy
2020-05-22  9:57       ` Diana Craciun OSS
2020-05-22 14:08         ` Rob Herring
2020-05-22 14:34           ` Robin Murphy
2020-05-22 14:02       ` Rob Herring
2020-05-22 15:38         ` Laurentiu Tudor
2020-05-21 13:00 ` [PATCH 10/12] of/irq: Make of_msi_map_rid() PCI bus agnostic Lorenzo Pieralisi
2020-05-21 23:17   ` Rob Herring
2020-06-04 15:08     ` Lorenzo Pieralisi
2020-05-21 13:00 ` [PATCH 11/12] bus/fsl-mc: Refactor the MSI domain creation in the DPRC driver Lorenzo Pieralisi
2020-05-21 13:00 ` [PATCH 12/12] bus: fsl-mc: Add ACPI support for fsl-mc Lorenzo Pieralisi
2020-05-21 15:03   ` Laurentiu Tudor
2020-05-22  5:32     ` Makarand Pawagi
2020-05-22  9:53       ` Lorenzo Pieralisi
2020-06-19  8:20 ` [PATCH v2 00/12] ACPI/OF: Upgrade MSI/IOMMU ID mapping APIs Lorenzo Pieralisi
2020-06-19  8:20   ` [PATCH v2 01/12] ACPI/IORT: Make iort_match_node_callback walk the ACPI namespace for NC Lorenzo Pieralisi
2020-06-29  4:24     ` Hanjun Guo
2020-06-29  9:05       ` Lorenzo Pieralisi
2020-06-30  3:06         ` Hanjun Guo
2020-06-30 10:24           ` Lorenzo Pieralisi
2020-06-30 13:04             ` Hanjun Guo
2020-07-01 16:12               ` Robin Murphy
2020-07-02  8:22                 ` Hanjun Guo
2020-07-09  9:21                   ` Lorenzo Pieralisi
2020-07-09 12:48                     ` Hanjun Guo
2020-08-18  0:49                   ` Hanjun Guo
2020-06-19  8:20   ` [PATCH v2 02/12] ACPI/IORT: Make iort_get_device_domain IRQ domain agnostic Lorenzo Pieralisi
2020-06-19  8:20   ` [PATCH v2 03/12] ACPI/IORT: Make iort_msi_map_rid() PCI agnostic Lorenzo Pieralisi
2020-07-15  9:15     ` Lorenzo Pieralisi
2020-07-21 14:59     ` Bjorn Helgaas
2020-07-27  6:06       ` [EXT] " Makarand Pawagi
2020-06-19  8:20   ` [PATCH v2 04/12] ACPI/IORT: Remove useless PCI bus walk Lorenzo Pieralisi
2020-06-19  8:20   ` Lorenzo Pieralisi [this message]
2020-07-09  9:35     ` [PATCH v2 05/12] ACPI/IORT: Add an input ID to acpi_dma_configure() Lorenzo Pieralisi
2020-07-15  9:13       ` Lorenzo Pieralisi
2020-07-28 12:48         ` Lorenzo Pieralisi
2020-07-28 13:00           ` Rafael J. Wysocki
2020-06-19  8:20   ` [PATCH v2 06/12] of/iommu: Make of_map_rid() PCI agnostic Lorenzo Pieralisi
2020-06-22 13:26     ` Joerg Roedel
2020-07-13 23:57     ` Rob Herring
2020-06-19  8:20   ` [PATCH v2 07/12] of/device: Add input id to of_dma_configure() Lorenzo Pieralisi
2020-06-30 21:50     ` Rob Herring
2020-06-19  8:20   ` [PATCH v2 08/12] dt-bindings: arm: fsl: Add msi-map device-tree binding for fsl-mc bus Lorenzo Pieralisi
2020-06-30 21:55     ` Rob Herring
2020-06-19  8:20   ` [PATCH v2 09/12] of/irq: make of_msi_map_get_device_domain() bus agnostic Lorenzo Pieralisi
2020-06-30 21:50     ` Rob Herring
2020-06-19  8:20   ` [PATCH v2 10/12] of/irq: Make of_msi_map_rid() PCI " Lorenzo Pieralisi
2020-06-30 21:56     ` Rob Herring
2020-06-19  8:20   ` [PATCH v2 11/12] bus/fsl-mc: Refactor the MSI domain creation in the DPRC driver Lorenzo Pieralisi
2020-07-15 13:05     ` Marc Zyngier
2020-06-19  8:20   ` [PATCH v2 12/12] bus: fsl-mc: Add ACPI support for fsl-mc Lorenzo Pieralisi
2020-07-01 16:55     ` Laurentiu Tudor
2020-07-09  9:19       ` Lorenzo Pieralisi
2020-07-09  9:26         ` [EXT] " Makarand Pawagi
2020-07-09 10:14           ` Laurentiu Tudor
2020-07-09 10:37             ` Makarand Pawagi
2020-07-09 10:39               ` Laurentiu Tudor
2020-07-09 10:47               ` Diana Craciun OSS
2020-07-09 10:52                 ` Makarand Pawagi
2020-07-15 10:06                   ` Lorenzo Pieralisi
2020-07-16  3:23                     ` Makarand Pawagi
2020-07-16  7:57                       ` Marc Zyngier
2020-07-20 16:54   ` [PATCH v2 00/12] ACPI/OF: Upgrade MSI/IOMMU ID mapping APIs Lorenzo Pieralisi
2020-07-21  4:28     ` [EXT] " Makarand Pawagi
2020-07-28 17:01   ` Catalin Marinas

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=20200619082013.13661-6-lorenzo.pieralisi@arm.com \
    --to=lorenzo.pieralisi@arm.com \
    --cc=bhelgaas@google.com \
    --cc=catalin.marinas@arm.com \
    --cc=devicetree@vger.kernel.org \
    --cc=diana.craciun@oss.nxp.com \
    --cc=guohanjun@huawei.com \
    --cc=iommu@lists.linux-foundation.org \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=makarand.pawagi@nxp.com \
    --cc=maz@kernel.org \
    --cc=rjw@rjwysocki.net \
    --cc=robh+dt@kernel.org \
    --cc=robin.murphy@arm.com \
    --cc=sudeep.holla@arm.com \
    --cc=will@kernel.org \
    /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

IOMMU Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-iommu/0 linux-iommu/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-iommu linux-iommu/ https://lore.kernel.org/linux-iommu \
		iommu@lists.linux-foundation.org
	public-inbox-index linux-iommu

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.linux-foundation.lists.iommu


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git