Linux-ACPI Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH v3 00/10] ACPI/IORT: Support for IORT RMR node
@ 2021-04-20  8:27 Shameer Kolothum
  2021-04-20  8:27 ` [PATCH v3 01/10] ACPI/IORT: Add support for RMR node parsing Shameer Kolothum
                   ` (9 more replies)
  0 siblings, 10 replies; 24+ messages in thread
From: Shameer Kolothum @ 2021-04-20  8:27 UTC (permalink / raw)
  To: linux-arm-kernel, linux-acpi, iommu
  Cc: linuxarm, lorenzo.pieralisi, joro, robin.murphy, wanghuiqiang,
	guohanjun, steven.price, Sami.Mujawar, jon, eric.auger

Hi,

RFC v2 --> v3
 -Dropped RFC tag as the ACPICA header changes are now ready to be
  part of 5.13[0]. But this series still has a dependency on that patch.
 -Added IORT E.b related changes(node flags, _DSM function 5 checks for
  PCIe).
 -Changed RMR to stream id mapping from M:N to M:1 as per the spec and
  discussion here[1].
 -Last two patches add support for SMMUv2(Thanks to Jon Nettleton!) 

Sanity tested on a HiSilicon D06. Further testing and feedback is greatly
appreciated.

The whole series can be found here,
https://github.com/hisilicon/kernel-dev/tree/private-v5.12-rc8-rmr-v3

Thanks,
Shameer

[0] https://lore.kernel.org/linux-acpi/20210406213028.718796-22-erik.kaneda@intel.com/
[1] https://op-lists.linaro.org/pipermail/linaro-open-discussions/2021-April/000150.html

RFC v1 --> v2:
 - Added a generic interface for IOMMU drivers to retrieve all the 
   RMR info associated with a given IOMMU.
 - SMMUv3 driver gets the RMR list during probe() and installs
   bypass STEs for all the SIDs in the RMR list. This is to keep
   the ongoing traffic alive(if any) during SMMUv3 reset. This is
   based on the suggestions received for v1 to take care of the
   EFI framebuffer use case. Only sanity tested for now.
 - During the probe/attach device, SMMUv3 driver reserves any
   RMR region associated with the device such that there is a unity
   mapping for them in SMMU.
---    

From RFC v1:
-------------
The series adds support to IORT RMR nodes specified in IORT
Revision E -ARM DEN 0049E[0]. RMR nodes are used to describe memory
ranges that are used by endpoints and require a unity mapping
in SMMU.

We have faced issues with 3408iMR RAID controller cards which
fail to boot when SMMU is enabled. This is because these controllers
make use of host memory for various caching related purposes and when
SMMU is enabled the iMR firmware fails to access these memory regions
as there is no mapping for them. IORT RMR provides a way for UEFI to
describe and report these memory regions so that the kernel can make
a unity mapping for these in SMMU.

Tests:

With a UEFI, that reports the RMR for the dev,
....
[16F0h 5872   1]                         Type : 06
[16F1h 5873   2]                       Length : 007C
[16F3h 5875   1]                     Revision : 00
[1038h 0056   2]                     Reserved : 00000000
[1038h 0056   2]                   Identifier : 00000000
[16F8h 5880   4]                Mapping Count : 00000001
[16FCh 5884   4]               Mapping Offset : 00000040

[1700h 5888   4]    Number of RMR Descriptors : 00000002
[1704h 5892   4]        RMR Descriptor Offset : 00000018

[1708h 5896   8]          Base Address of RMR : 0000E6400000
[1710h 5904   8]                Length of RMR : 000000100000
[1718h 5912   4]                     Reserved : 00000000

[171Ch 5916   8]          Base Address of RMR : 0000000027B00000
[1724h 5924   8]                Length of RMR : 0000000000C00000
[172Ch 5932   4]                     Reserved : 00000000

[1730h 5936   4]                   Input base : 00000000
[1734h 5940   4]                     ID Count : 00000001
[1738h 5944   4]                  Output Base : 00000003
[173Ch 5948   4]             Output Reference : 00000064
[1740h 5952   4]        Flags (decoded below) : 00000001
                               Single Mapping : 1
...

Without the series the RAID controller initialization fails as
below,

...
[   12.631117] megaraid_sas 0000:03:00.0: FW supports sync cache        : Yes   
[   12.637360] megaraid_sas 0000:03:00.0: megasas_disable_intr_fusion is called outbound_intr_mask:0x40000009                                                   
[   18.776377] megaraid_sas 0000:03:00.0: Init cmd return status FAILED for SCSI host 0                                                                         
[   23.019383] megaraid_sas 0000:03:00.0: Waiting for FW to come to ready state 
[  106.684281] megaraid_sas 0000:03:00.0: FW in FAULT state, Fault code:0x10000 subcode:0x0 func:megasas_transition_to_ready                                    
[  106.695186] megaraid_sas 0000:03:00.0: System Register set:                  
[  106.889787] megaraid_sas 0000:03:00.0: Failed to transition controller to ready for scsi0.                                                                   
[  106.910475] megaraid_sas 0000:03:00.0: Failed from megasas_init_fw 6407      
estuary:/$

With the series, now the kernel has direct mapping for the dev as
below,

estuary:/$ cat /sys/kernel/iommu_groups/0/reserved_regions                      
0x0000000008000000 0x00000000080fffff msi                                       
0x0000000027b00000 0x00000000286fffff direct                                    
0x00000000e6400000 0x00000000e64fffff direct                                    
estuary:/$

....
[   12.254318] megaraid_sas 0000:03:00.0: megasas_disable_intr_fusion is called outbound_intr_mask:0x40000009                                                   
[   12.739089] megaraid_sas 0000:03:00.0: FW provided supportMaxExtLDs: 0      max_lds: 32                                                                      
[   12.746628] megaraid_sas 0000:03:00.0: controller type       : iMR(0MB)      
[   12.752694] megaraid_sas 0000:03:00.0: Online Controller Reset(OCR)  : Enabled                                                                               
[   12.759798] megaraid_sas 0000:03:00.0: Secure JBOD support   : Yes           
[   12.765778] megaraid_sas 0000:03:00.0: NVMe passthru support : Yes           
[   12.771931] megaraid_sas 0000:03:00.0: FW provided TM TaskAbort/Reset timeou: 6 secs/60 secs                                                                 
[   12.780503] megaraid_sas 0000:03:00.0: JBOD sequence map support     : Yes   
[   12.787000] megaraid_sas 0000:03:00.0: PCI Lane Margining support    : No    
[   12.819179] megaraid_sas 0000:03:00.0: NVME page size        : (4096)        
[   12.825672] megaraid_sas 0000:03:00.0: megasas_enable_intr_fusion is called outbound_intr_mask:0x40000000                                                    
[   12.835199] megaraid_sas 0000:03:00.0: INIT adapter done                     
[   12.873932] megaraid_sas 0000:03:00.0: pci id                : (0x1000)/(0x0017)/(0x19e5)/(0xd213)                                                           
[   12.881644] megaraid_sas 0000:03:00.0: unevenspan support    : no            
[   12.887451] megaraid_sas 0000:03:00.0: firmware crash dump   : no            
[   12.893344] megaraid_sas 0000:03:00.0: JBOD sequence map     : enabled       

RAID controller init is now success and can detect the drives
attached as well.


Jon Nettleton (2):
  iommu/arm-smmu: Get associated RMR info and install bypass SMR
  iommu/arm-smmu: Reserve any RMR regions associated with a dev

Shameer Kolothum (8):
  ACPI/IORT: Add support for RMR node parsing
  iommu/dma: Introduce generic helper to retrieve RMR info
  ACPI/IORT: Add a helper to retrieve RMR memory regions
  iommu/dma: Add a helper function to reserve RMRs for IOMMU drivers
  iommu/arm-smmu-v3: Introduce strtab init helper
  iommu/arm-smmu-v3: Add bypass flag to arm_smmu_write_strtab_ent()
  iommu/arm-smmu-v3: Get associated RMR info and install bypass STE
  iommu/arm-smmu-v3: Reserve any RMR regions associated with a dev

 drivers/acpi/arm64/iort.c                   | 144 +++++++++++++++++++-
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |  98 +++++++++++--
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h |   2 +
 drivers/iommu/arm/arm-smmu/arm-smmu.c       |  75 ++++++++++
 drivers/iommu/arm/arm-smmu/arm-smmu.h       |   2 +
 drivers/iommu/dma-iommu.c                   |  71 ++++++++++
 include/linux/acpi_iort.h                   |   7 +
 include/linux/dma-iommu.h                   |  15 ++
 include/linux/iommu.h                       |  19 +++
 9 files changed, 417 insertions(+), 16 deletions(-)

-- 
2.17.1


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v3 01/10] ACPI/IORT: Add support for RMR node parsing
  2021-04-20  8:27 [PATCH v3 00/10] ACPI/IORT: Support for IORT RMR node Shameer Kolothum
@ 2021-04-20  8:27 ` Shameer Kolothum
  2021-04-20  8:27 ` [PATCH v3 02/10] iommu/dma: Introduce generic helper to retrieve RMR info Shameer Kolothum
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 24+ messages in thread
From: Shameer Kolothum @ 2021-04-20  8:27 UTC (permalink / raw)
  To: linux-arm-kernel, linux-acpi, iommu
  Cc: linuxarm, lorenzo.pieralisi, joro, robin.murphy, wanghuiqiang,
	guohanjun, steven.price, Sami.Mujawar, jon, eric.auger

Add support for parsing RMR node information from ACPI.
Find associated stream id and smmu node info from the
RMR node and populate a linked list with RMR memory
descriptors.

Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
---
 drivers/acpi/arm64/iort.c | 104 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 103 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 2494138a6905..bd96c5e3b36e 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -40,6 +40,19 @@ struct iort_fwnode {
 static LIST_HEAD(iort_fwnode_list);
 static DEFINE_SPINLOCK(iort_fwnode_lock);
 
+/*
+ * One entry for IORT RMR.
+ */
+struct iort_rmr_entry {
+	struct list_head list;
+	u32 sid;
+	struct acpi_iort_node *smmu;
+	struct acpi_iort_rmr_desc *rmr_desc;
+	u32 flags;
+};
+
+static LIST_HEAD(iort_rmr_list);         /* list of RMR regions from ACPI */
+
 /**
  * iort_set_fwnode() - Create iort_fwnode and use it to register
  *		       iommu data in the iort_fwnode_list
@@ -393,7 +406,8 @@ static struct acpi_iort_node *iort_node_get_id(struct acpi_iort_node *node,
 		if (node->type == ACPI_IORT_NODE_NAMED_COMPONENT ||
 		    node->type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX ||
 		    node->type == ACPI_IORT_NODE_SMMU_V3 ||
-		    node->type == ACPI_IORT_NODE_PMCG) {
+		    node->type == ACPI_IORT_NODE_PMCG ||
+		    node->type == ACPI_IORT_NODE_RMR) {
 			*id_out = map->output_base;
 			return parent;
 		}
@@ -1659,6 +1673,91 @@ static void __init iort_enable_acs(struct acpi_iort_node *iort_node)
 #else
 static inline void iort_enable_acs(struct acpi_iort_node *iort_node) { }
 #endif
+static int iort_rmr_desc_valid(struct acpi_iort_rmr_desc *desc, u32 count)
+{
+	int i, j;
+
+	for (i = 0; i < count; i++) {
+		u64 end, start = desc[i].base_address, length = desc[i].length;
+
+		if (!IS_ALIGNED(start, SZ_64K) || !IS_ALIGNED(length, SZ_64K))
+			return -EINVAL;
+
+		end = start + length - 1;
+
+		/* Check for address overlap */
+		for (j = i + 1; j < count; j++) {
+			u64 e_start = desc[j].base_address;
+			u64 e_end = e_start + desc[j].length - 1;
+
+			if (start <= e_end && end >= e_start)
+				return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+static int __init iort_parse_rmr(struct acpi_iort_node *iort_node)
+{
+	struct acpi_iort_node *smmu;
+	struct iort_rmr_entry *e;
+	struct acpi_iort_rmr *rmr;
+	struct acpi_iort_rmr_desc *rmr_desc;
+	u32 map_count = iort_node->mapping_count;
+	u32  sid;
+	int i, ret = 0;
+
+	if (iort_node->type != ACPI_IORT_NODE_RMR)
+		return 0;
+
+	if (!iort_node->mapping_offset || map_count != 1) {
+		pr_err(FW_BUG "Invalid ID mapping, skipping RMR node %p\n",
+		       iort_node);
+		return -EINVAL;
+	}
+
+	/* Retrieve associated smmu and stream id */
+	smmu = iort_node_get_id(iort_node, &sid, 0);
+	if (!smmu) {
+		pr_err(FW_BUG "Invalid SMMU reference, skipping RMR node %p\n",
+		       iort_node);
+		return -EINVAL;
+	}
+
+	/* Retrieve RMR data */
+	rmr = (struct acpi_iort_rmr *)iort_node->node_data;
+	if (!rmr->rmr_offset || !rmr->rmr_count) {
+		pr_err(FW_BUG "Invalid RMR descriptor array, skipping RMR node %p\n",
+		       iort_node);
+		return -EINVAL;
+	}
+
+	rmr_desc = ACPI_ADD_PTR(struct acpi_iort_rmr_desc, iort_node,
+				rmr->rmr_offset);
+
+	ret = iort_rmr_desc_valid(rmr_desc, rmr->rmr_count);
+	if (ret) {
+		pr_err(FW_BUG "Invalid RMR descriptor[%d] for node %p, skipping...\n",
+		       i, iort_node);
+		return ret;
+	}
+
+	for (i = 0; i < rmr->rmr_count; i++, rmr_desc++) {
+		e = kmalloc(sizeof(*e), GFP_KERNEL);
+		if (!e)
+			return -ENOMEM;
+
+		e->sid = sid;
+		e->smmu = smmu;
+		e->rmr_desc = rmr_desc;
+		e->flags = rmr->flags;
+
+		list_add_tail(&e->list, &iort_rmr_list);
+	}
+
+	return 0;
+}
 
 static void __init iort_init_platform_devices(void)
 {
@@ -1688,6 +1787,9 @@ static void __init iort_init_platform_devices(void)
 
 		iort_enable_acs(iort_node);
 
+		if (iort_table->revision == 3)
+			iort_parse_rmr(iort_node);
+
 		ops = iort_get_dev_cfg(iort_node);
 		if (ops) {
 			fwnode = acpi_alloc_fwnode_static();
-- 
2.17.1


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v3 02/10] iommu/dma: Introduce generic helper to retrieve RMR info
  2021-04-20  8:27 [PATCH v3 00/10] ACPI/IORT: Support for IORT RMR node Shameer Kolothum
  2021-04-20  8:27 ` [PATCH v3 01/10] ACPI/IORT: Add support for RMR node parsing Shameer Kolothum
@ 2021-04-20  8:27 ` Shameer Kolothum
  2021-04-20 12:04   ` kernel test robot
                     ` (2 more replies)
  2021-04-20  8:27 ` [PATCH v3 03/10] ACPI/IORT: Add a helper to retrieve RMR memory regions Shameer Kolothum
                   ` (7 subsequent siblings)
  9 siblings, 3 replies; 24+ messages in thread
From: Shameer Kolothum @ 2021-04-20  8:27 UTC (permalink / raw)
  To: linux-arm-kernel, linux-acpi, iommu
  Cc: linuxarm, lorenzo.pieralisi, joro, robin.murphy, wanghuiqiang,
	guohanjun, steven.price, Sami.Mujawar, jon, eric.auger

Reserved Memory Regions(RMR) associated with an IOMMU may be
described either through ACPI tables or DT in systems with
devices that require a unity mapping or bypass for those
regions in IOMMU drivers.

Introduce a generic interface so that IOMMU drivers can retrieve
and set up necessary mappings.

Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
---
 drivers/iommu/dma-iommu.c | 33 +++++++++++++++++++++++++++++++++
 include/linux/dma-iommu.h |  8 ++++++++
 include/linux/iommu.h     | 19 +++++++++++++++++++
 3 files changed, 60 insertions(+)

diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index af765c813cc8..86a1e48b1fe8 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -191,6 +191,39 @@ void iommu_dma_get_resv_regions(struct device *dev, struct list_head *list)
 }
 EXPORT_SYMBOL(iommu_dma_get_resv_regions);
 
+/**
+ * iommu_dma_get_rmrs - Retrieve Reserved Memory Regions(RMRs) associated
+ *                      with a given IOMMU
+ * @iommu_fwnode: fwnode associated with IOMMU
+ * @list: RMR list to be populated
+ *
+ */
+int iommu_dma_get_rmrs(struct fwnode_handle *iommu_fwnode,
+		       struct list_head *list)
+{
+	return 0;
+}
+EXPORT_SYMBOL(iommu_dma_get_rmrs);
+
+struct iommu_rmr *iommu_dma_alloc_rmr(u64 base, u64 length, u32 sid,
+				      u32 flags)
+{
+	struct iommu_rmr *rmr;
+
+	rmr = kzalloc(sizeof(*rmr), GFP_KERNEL);
+	if (!rmr)
+		return NULL;
+
+	INIT_LIST_HEAD(&rmr->list);
+	rmr->base_address = base;
+	rmr->length = length;
+	rmr->sid = sid;
+	rmr->flags = flags;
+
+	return rmr;
+}
+EXPORT_SYMBOL(iommu_dma_alloc_rmr);
+
 static int cookie_init_hw_msi_region(struct iommu_dma_cookie *cookie,
 		phys_addr_t start, phys_addr_t end)
 {
diff --git a/include/linux/dma-iommu.h b/include/linux/dma-iommu.h
index 706b68d1359b..beb84c4fe5b1 100644
--- a/include/linux/dma-iommu.h
+++ b/include/linux/dma-iommu.h
@@ -40,6 +40,9 @@ void iommu_dma_get_resv_regions(struct device *dev, struct list_head *list);
 void iommu_dma_free_cpu_cached_iovas(unsigned int cpu,
 		struct iommu_domain *domain);
 
+int iommu_dma_get_rmrs(struct fwnode_handle *iommu, struct list_head *list);
+struct iommu_rmr *iommu_dma_alloc_rmr(u64 base, u64 length, u32 sid, u32 flags);
+
 #else /* CONFIG_IOMMU_DMA */
 
 struct iommu_domain;
@@ -86,5 +89,10 @@ static inline void iommu_dma_free_cpu_cached_iovas(unsigned int cpu,
 {
 }
 
+int iommu_dma_get_rmrs(struct fwnode_handle *iommu, struct list_head *list);
+{
+	return 0;
+}
+
 #endif	/* CONFIG_IOMMU_DMA */
 #endif	/* __DMA_IOMMU_H */
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 5e7fe519430a..fb8820c40144 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -595,6 +595,25 @@ struct iommu_sva {
 	struct device			*dev;
 };
 
+/**
+ * struct iommu_rmr - Reserved Memory Region details per IOMMU
+ * @list: Linked list pointers to hold RMR region info
+ * @base_address: base address of Reserved Memory Region
+ * @length: length of memory region
+ * @sid: associated stream id
+ * @flags: flags that apply to the RMR node
+ */
+struct iommu_rmr {
+	struct list_head	list;
+	phys_addr_t		base_address;
+	u64			length;
+	u32			sid;
+	u32			flags;
+};
+
+/* RMR Remap permitted */
+#define IOMMU_RMR_REMAP_PERMITTED	(1 << 0)
+
 int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 		      const struct iommu_ops *ops);
 void iommu_fwspec_free(struct device *dev);
-- 
2.17.1


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v3 03/10] ACPI/IORT: Add a helper to retrieve RMR memory regions
  2021-04-20  8:27 [PATCH v3 00/10] ACPI/IORT: Support for IORT RMR node Shameer Kolothum
  2021-04-20  8:27 ` [PATCH v3 01/10] ACPI/IORT: Add support for RMR node parsing Shameer Kolothum
  2021-04-20  8:27 ` [PATCH v3 02/10] iommu/dma: Introduce generic helper to retrieve RMR info Shameer Kolothum
@ 2021-04-20  8:27 ` Shameer Kolothum
  2021-04-20  8:27 ` [PATCH v3 04/10] iommu/dma: Add a helper function to reserve RMRs for IOMMU drivers Shameer Kolothum
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 24+ messages in thread
From: Shameer Kolothum @ 2021-04-20  8:27 UTC (permalink / raw)
  To: linux-arm-kernel, linux-acpi, iommu
  Cc: linuxarm, lorenzo.pieralisi, joro, robin.murphy, wanghuiqiang,
	guohanjun, steven.price, Sami.Mujawar, jon, eric.auger

Add a helper function that retrieves RMR memory descriptors
associated with a given IOMMU. This will be used by IOMMU
drivers to setup necessary mappings.

Now that we have this, invoke this from the generic helper
interface.

Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
---
 drivers/acpi/arm64/iort.c | 40 +++++++++++++++++++++++++++++++++++++++
 drivers/iommu/dma-iommu.c |  3 +++
 include/linux/acpi_iort.h |  7 +++++++
 3 files changed, 50 insertions(+)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index bd96c5e3b36e..66e314b15692 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -12,6 +12,7 @@
 
 #include <linux/acpi_iort.h>
 #include <linux/bitfield.h>
+#include <linux/dma-iommu.h>
 #include <linux/iommu.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
@@ -837,6 +838,43 @@ static inline int iort_add_device_replay(struct device *dev)
 	return err;
 }
 
+/**
+ * iort_iommu_get_rmrs - Helper to retrieve RMR info associated with IOMMU
+ * @iommu: fwnode for the IOMMU
+ * @head: RMR list head to be populated
+ *
+ * Returns: 0 on success, <0 failure
+ */
+int iort_iommu_get_rmrs(struct fwnode_handle *iommu_fwnode,
+			struct list_head *head)
+{
+	struct iort_rmr_entry *e;
+	struct acpi_iort_node *iommu;
+
+	iommu = iort_get_iort_node(iommu_fwnode);
+	if (!iommu)
+		return 0;
+
+	list_for_each_entry(e, &iort_rmr_list, list) {
+		struct acpi_iort_rmr_desc *rmr_desc;
+		struct iommu_rmr *rmr;
+
+		if (e->smmu != iommu)
+			continue;
+
+		rmr_desc = e->rmr_desc;
+		rmr = iommu_dma_alloc_rmr(rmr_desc->base_address,
+					  rmr_desc->length, e->sid,
+					  e->flags);
+		if (!rmr)
+			return -ENOMEM;
+
+		list_add_tail(&rmr->list, head);
+	}
+
+	return 0;
+}
+
 /**
  * iort_iommu_msi_get_resv_regions - Reserved region driver helper
  * @dev: Device from iommu_get_resv_regions()
@@ -1107,6 +1145,8 @@ int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head)
 const struct iommu_ops *iort_iommu_configure_id(struct device *dev,
 						const u32 *input_id)
 { return NULL; }
+int iort_iommu_get_rmrs(struct fwnode_handle *fwnode, struct list_head *head)
+{ return 0; }
 #endif
 
 static int nc_dma_get_range(struct device *dev, u64 *size)
diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index 86a1e48b1fe8..a942cc04eee1 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -201,6 +201,9 @@ EXPORT_SYMBOL(iommu_dma_get_resv_regions);
 int iommu_dma_get_rmrs(struct fwnode_handle *iommu_fwnode,
 		       struct list_head *list)
 {
+	if (!is_of_node(iommu_fwnode))
+		return iort_iommu_get_rmrs(iommu_fwnode, list);
+
 	return 0;
 }
 EXPORT_SYMBOL(iommu_dma_get_rmrs);
diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
index 1a12baa58e40..e9f3bc2f4842 100644
--- a/include/linux/acpi_iort.h
+++ b/include/linux/acpi_iort.h
@@ -39,6 +39,8 @@ 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);
 phys_addr_t acpi_iort_dma_get_max_cpu_address(void);
+int iort_iommu_get_rmrs(struct fwnode_handle *iommu_fwnode,
+			struct list_head *list);
 #else
 static inline void acpi_iort_init(void) { }
 static inline u32 iort_msi_map_id(struct device *dev, u32 id)
@@ -59,6 +61,11 @@ int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head)
 
 static inline phys_addr_t acpi_iort_dma_get_max_cpu_address(void)
 { return PHYS_ADDR_MAX; }
+
+static inline
+int iort_iommu_get_rmrs(struct fwnode_handle *iommu_fwnode,
+			struct list_head *list)
+{ return 0; }
 #endif
 
 #endif /* __ACPI_IORT_H__ */
-- 
2.17.1


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v3 04/10] iommu/dma: Add a helper function to reserve RMRs for IOMMU drivers
  2021-04-20  8:27 [PATCH v3 00/10] ACPI/IORT: Support for IORT RMR node Shameer Kolothum
                   ` (2 preceding siblings ...)
  2021-04-20  8:27 ` [PATCH v3 03/10] ACPI/IORT: Add a helper to retrieve RMR memory regions Shameer Kolothum
@ 2021-04-20  8:27 ` Shameer Kolothum
  2021-04-20 12:07   ` kernel test robot
  2021-04-20 13:32   ` kernel test robot
  2021-04-20  8:27 ` [PATCH v3 05/10] iommu/arm-smmu-v3: Introduce strtab init helper Shameer Kolothum
                   ` (5 subsequent siblings)
  9 siblings, 2 replies; 24+ messages in thread
From: Shameer Kolothum @ 2021-04-20  8:27 UTC (permalink / raw)
  To: linux-arm-kernel, linux-acpi, iommu
  Cc: linuxarm, lorenzo.pieralisi, joro, robin.murphy, wanghuiqiang,
	guohanjun, steven.price, Sami.Mujawar, jon, eric.auger

IOMMU drivers can use this to implement their .get_resv_regions callback
for any RMR address regions specific to a device.

As per ACPI IORT E.b spec, a check is added to make sure OS has preserved
the PCIe configuration done by boot firmware.

Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
---
 drivers/iommu/dma-iommu.c | 35 +++++++++++++++++++++++++++++++++++
 include/linux/dma-iommu.h |  7 +++++++
 2 files changed, 42 insertions(+)

diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index a942cc04eee1..c624000bf230 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -191,6 +191,41 @@ void iommu_dma_get_resv_regions(struct device *dev, struct list_head *list)
 }
 EXPORT_SYMBOL(iommu_dma_get_resv_regions);
 
+void iommu_dma_get_rmr_resv_regions(struct device *dev, struct iommu_rmr *rmr,
+				    struct list_head *list)
+{
+	int prot = IOMMU_READ | IOMMU_WRITE | IOMMU_NOEXEC | IOMMU_MMIO;
+	struct iommu_resv_region *region;
+	enum iommu_resv_type type;
+
+	/*
+	 * For ACPI, please make sure the OS has preserved the PCIe configuration
+	 * performed by the boot firmware(See IORT revision E.b).
+	 */
+	if (!is_of_node(dev_iommu_fwspec_get(dev)->iommu_fwnode) &&
+	    dev_is_pci(dev)) {
+		struct pci_dev *pdev = to_pci_dev(dev);
+		struct pci_host_bridge *host = pci_find_host_bridge(pdev->bus);
+
+		if (!host->preserve_config)
+			return;
+	}
+
+	if (rmr->flags & IOMMU_RMR_REMAP_PERMITTED)
+		type = IOMMU_RESV_DIRECT_RELAXABLE;
+	else
+		type = IOMMU_RESV_DIRECT;
+
+	region = iommu_alloc_resv_region(rmr->base_address,
+					 rmr->length, prot,
+					 type);
+	if (!region)
+		return;
+
+	list_add_tail(&region->list, list);
+}
+EXPORT_SYMBOL(iommu_dma_get_rmr_resv_regions);
+
 /**
  * iommu_dma_get_rmrs - Retrieve Reserved Memory Regions(RMRs) associated
  *                      with a given IOMMU
diff --git a/include/linux/dma-iommu.h b/include/linux/dma-iommu.h
index beb84c4fe5b1..dbad5073c9e0 100644
--- a/include/linux/dma-iommu.h
+++ b/include/linux/dma-iommu.h
@@ -40,6 +40,8 @@ void iommu_dma_get_resv_regions(struct device *dev, struct list_head *list);
 void iommu_dma_free_cpu_cached_iovas(unsigned int cpu,
 		struct iommu_domain *domain);
 
+void iommu_dma_get_rmr_resv_regions(struct device *dev, struct iommu_rmr *rmr,
+				    struct list_head *list);
 int iommu_dma_get_rmrs(struct fwnode_handle *iommu, struct list_head *list);
 struct iommu_rmr *iommu_dma_alloc_rmr(u64 base, u64 length, u32 sid, u32 flags);
 
@@ -89,6 +91,11 @@ static inline void iommu_dma_free_cpu_cached_iovas(unsigned int cpu,
 {
 }
 
+static void iommu_dma_get_rmr_resv_regions(struct device *dev, struct iommu_rmr *rmr,
+					   struct list_head *list)
+{
+}
+
 int iommu_dma_get_rmrs(struct fwnode_handle *iommu, struct list_head *list);
 {
 	return 0;
-- 
2.17.1


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v3 05/10] iommu/arm-smmu-v3: Introduce strtab init helper
  2021-04-20  8:27 [PATCH v3 00/10] ACPI/IORT: Support for IORT RMR node Shameer Kolothum
                   ` (3 preceding siblings ...)
  2021-04-20  8:27 ` [PATCH v3 04/10] iommu/dma: Add a helper function to reserve RMRs for IOMMU drivers Shameer Kolothum
@ 2021-04-20  8:27 ` Shameer Kolothum
  2021-04-20  8:27 ` [PATCH v3 06/10] iommu/arm-smmu-v3: Add bypass flag to arm_smmu_write_strtab_ent() Shameer Kolothum
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 24+ messages in thread
From: Shameer Kolothum @ 2021-04-20  8:27 UTC (permalink / raw)
  To: linux-arm-kernel, linux-acpi, iommu
  Cc: linuxarm, lorenzo.pieralisi, joro, robin.murphy, wanghuiqiang,
	guohanjun, steven.price, Sami.Mujawar, jon, eric.auger

Introduce a helper to check the sid range and to init the l2 strtab
entries(bypass). This will be useful when we have to initialize the
l2 strtab with bypass for RMR SIDs.

Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 26 ++++++++++++---------
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 8594b4a83043..29da3b681621 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2347,6 +2347,19 @@ static bool arm_smmu_sid_in_range(struct arm_smmu_device *smmu, u32 sid)
 
 static struct iommu_ops arm_smmu_ops;
 
+static int arm_smmu_init_sid_strtab(struct arm_smmu_device *smmu, u32 sid)
+{
+	/* Check the SIDs are in range of the SMMU and our stream table */
+	if (!arm_smmu_sid_in_range(smmu, sid))
+		return -ERANGE;
+
+	/* Ensure l2 strtab is initialised */
+	if (smmu->features & ARM_SMMU_FEAT_2_LVL_STRTAB)
+		return arm_smmu_init_l2_strtab(smmu, sid);
+
+	return 0;
+}
+
 static struct iommu_device *arm_smmu_probe_device(struct device *dev)
 {
 	int i, ret;
@@ -2375,21 +2388,12 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev)
 	INIT_LIST_HEAD(&master->bonds);
 	dev_iommu_priv_set(dev, master);
 
-	/* Check the SIDs are in range of the SMMU and our stream table */
 	for (i = 0; i < master->num_sids; i++) {
 		u32 sid = master->sids[i];
 
-		if (!arm_smmu_sid_in_range(smmu, sid)) {
-			ret = -ERANGE;
+		ret = arm_smmu_init_sid_strtab(smmu, sid);
+		if (ret)
 			goto err_free_master;
-		}
-
-		/* Ensure l2 strtab is initialised */
-		if (smmu->features & ARM_SMMU_FEAT_2_LVL_STRTAB) {
-			ret = arm_smmu_init_l2_strtab(smmu, sid);
-			if (ret)
-				goto err_free_master;
-		}
 	}
 
 	master->ssid_bits = min(smmu->ssid_bits, fwspec->num_pasid_bits);
-- 
2.17.1


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v3 06/10] iommu/arm-smmu-v3: Add bypass flag to arm_smmu_write_strtab_ent()
  2021-04-20  8:27 [PATCH v3 00/10] ACPI/IORT: Support for IORT RMR node Shameer Kolothum
                   ` (4 preceding siblings ...)
  2021-04-20  8:27 ` [PATCH v3 05/10] iommu/arm-smmu-v3: Introduce strtab init helper Shameer Kolothum
@ 2021-04-20  8:27 ` Shameer Kolothum
  2021-04-20  8:27 ` [PATCH v3 07/10] iommu/arm-smmu-v3: Get associated RMR info and install bypass STE Shameer Kolothum
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 24+ messages in thread
From: Shameer Kolothum @ 2021-04-20  8:27 UTC (permalink / raw)
  To: linux-arm-kernel, linux-acpi, iommu
  Cc: linuxarm, lorenzo.pieralisi, joro, robin.murphy, wanghuiqiang,
	guohanjun, steven.price, Sami.Mujawar, jon, eric.auger

By default, disable_bypass is set and any dev without an iommu domain
installs STE with CFG_ABORT during arm_smmu_init_bypass_stes(). Introduce
a "bypass" flag to arm_smmu_write_strtab_ent() so that we can force it to
install CFG_BYPASS STE for specific SIDs. This will be useful for RMR
related SIDs.

Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 29da3b681621..190285812182 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -1176,7 +1176,7 @@ static void arm_smmu_sync_ste_for_sid(struct arm_smmu_device *smmu, u32 sid)
 }
 
 static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,
-				      __le64 *dst)
+				      __le64 *dst, bool bypass)
 {
 	/*
 	 * This is hideously complicated, but we only really care about
@@ -1247,7 +1247,7 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,
 
 	/* Bypass/fault */
 	if (!smmu_domain || !(s1_cfg || s2_cfg)) {
-		if (!smmu_domain && disable_bypass)
+		if (!smmu_domain && disable_bypass && !bypass)
 			val |= FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_ABORT);
 		else
 			val |= FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_BYPASS);
@@ -1322,7 +1322,7 @@ static void arm_smmu_init_bypass_stes(__le64 *strtab, unsigned int nent)
 	unsigned int i;
 
 	for (i = 0; i < nent; ++i) {
-		arm_smmu_write_strtab_ent(NULL, -1, strtab);
+		arm_smmu_write_strtab_ent(NULL, -1, strtab, false);
 		strtab += STRTAB_STE_DWORDS;
 	}
 }
@@ -2076,7 +2076,7 @@ static void arm_smmu_install_ste_for_dev(struct arm_smmu_master *master)
 		if (j < i)
 			continue;
 
-		arm_smmu_write_strtab_ent(master, sid, step);
+		arm_smmu_write_strtab_ent(master, sid, step, false);
 	}
 }
 
-- 
2.17.1


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v3 07/10] iommu/arm-smmu-v3: Get associated RMR info and install bypass STE
  2021-04-20  8:27 [PATCH v3 00/10] ACPI/IORT: Support for IORT RMR node Shameer Kolothum
                   ` (5 preceding siblings ...)
  2021-04-20  8:27 ` [PATCH v3 06/10] iommu/arm-smmu-v3: Add bypass flag to arm_smmu_write_strtab_ent() Shameer Kolothum
@ 2021-04-20  8:27 ` Shameer Kolothum
  2021-04-20  8:27 ` [PATCH v3 08/10] iommu/arm-smmu-v3: Reserve any RMR regions associated with a dev Shameer Kolothum
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 24+ messages in thread
From: Shameer Kolothum @ 2021-04-20  8:27 UTC (permalink / raw)
  To: linux-arm-kernel, linux-acpi, iommu
  Cc: linuxarm, lorenzo.pieralisi, joro, robin.murphy, wanghuiqiang,
	guohanjun, steven.price, Sami.Mujawar, jon, eric.auger

Check if there is any RMR info associated with the devices behind
the SMMUv3 and if any, install bypass STEs for them. This is to
keep any ongoing traffic associated with these devices alive
when we enable/reset SMMUv3 during probe().

Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 35 +++++++++++++++++++++
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h |  2 ++
 2 files changed, 37 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 190285812182..14e9c7034c04 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -3530,6 +3530,37 @@ static void __iomem *arm_smmu_ioremap(struct device *dev, resource_size_t start,
 	return devm_ioremap_resource(dev, &res);
 }
 
+static void arm_smmu_rmr_install_bypass_ste(struct arm_smmu_device *smmu)
+{
+	struct iommu_rmr *e;
+	int ret;
+
+	/*
+	 * Since, we don't have a mechanism to differentiate the RMR
+	 * SIDs that has an ongoing live stream, install bypass STEs
+	 * for all the reported ones. 
+	 */
+	list_for_each_entry(e, &smmu->rmr_list, list) {
+		__le64 *step;
+
+		ret = arm_smmu_init_sid_strtab(smmu, e->sid);
+		if (ret) {
+			dev_err(smmu->dev, "RMR bypass(0x%x) failed\n",
+				e->sid);
+			continue;
+		}
+
+		step = arm_smmu_get_step_for_sid(smmu, e->sid);
+		arm_smmu_write_strtab_ent(NULL, e->sid, step, true);
+	}
+}
+
+static int arm_smmu_get_rmr(struct arm_smmu_device *smmu)
+{
+	INIT_LIST_HEAD(&smmu->rmr_list);
+	return iommu_dma_get_rmrs(dev_fwnode(smmu->dev), &smmu->rmr_list);
+}
+
 static int arm_smmu_device_probe(struct platform_device *pdev)
 {
 	int irq, ret;
@@ -3613,6 +3644,10 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
 	/* Record our private device structure */
 	platform_set_drvdata(pdev, smmu);
 
+	/* Check for RMRs and install bypass STEs if any */
+	if (!arm_smmu_get_rmr(smmu))
+		arm_smmu_rmr_install_bypass_ste(smmu);
+
 	/* Reset the device */
 	ret = arm_smmu_device_reset(smmu, bypass);
 	if (ret)
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index f985817c967a..e210fa81538a 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -639,6 +639,8 @@ struct arm_smmu_device {
 
 	/* IOMMU core code handle */
 	struct iommu_device		iommu;
+
+	struct list_head		rmr_list;
 };
 
 /* SMMU private data for each master */
-- 
2.17.1


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v3 08/10] iommu/arm-smmu-v3: Reserve any RMR regions associated with a dev
  2021-04-20  8:27 [PATCH v3 00/10] ACPI/IORT: Support for IORT RMR node Shameer Kolothum
                   ` (6 preceding siblings ...)
  2021-04-20  8:27 ` [PATCH v3 07/10] iommu/arm-smmu-v3: Get associated RMR info and install bypass STE Shameer Kolothum
@ 2021-04-20  8:27 ` Shameer Kolothum
  2021-05-07 10:01   ` Robin Murphy
  2021-04-20  8:27 ` [PATCH v3 09/10] iommu/arm-smmu: Get associated RMR info and install bypass SMR Shameer Kolothum
  2021-04-20  8:27 ` [PATCH v3 10/10] iommu/arm-smmu: Reserve any RMR regions associated with a dev Shameer Kolothum
  9 siblings, 1 reply; 24+ messages in thread
From: Shameer Kolothum @ 2021-04-20  8:27 UTC (permalink / raw)
  To: linux-arm-kernel, linux-acpi, iommu
  Cc: linuxarm, lorenzo.pieralisi, joro, robin.murphy, wanghuiqiang,
	guohanjun, steven.price, Sami.Mujawar, jon, eric.auger

Get RMR regions associated with a dev reserved so that there is
a unity mapping for them in SMMU.

Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 29 +++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 14e9c7034c04..8bacedf7bb34 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2531,6 +2531,34 @@ static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args)
 	return iommu_fwspec_add_ids(dev, args->args, 1);
 }
 
+static bool arm_smmu_dev_has_rmr(struct arm_smmu_master *master,
+				 struct iommu_rmr *e)
+{
+	int i;
+
+	for (i = 0; i < master->num_sids; i++) {
+		if (e->sid == master->sids[i])
+			return true;
+	}
+
+	return false;
+}
+
+static void arm_smmu_rmr_get_resv_regions(struct device *dev,
+					  struct list_head *head)
+{
+	struct arm_smmu_master *master = dev_iommu_priv_get(dev);
+	struct arm_smmu_device *smmu = master->smmu;
+	struct iommu_rmr *rmr;
+
+	list_for_each_entry(rmr, &smmu->rmr_list, list) {
+		if (!arm_smmu_dev_has_rmr(master, rmr))
+			continue;
+
+		iommu_dma_get_rmr_resv_regions(dev, rmr, head);
+	}
+}
+
 static void arm_smmu_get_resv_regions(struct device *dev,
 				      struct list_head *head)
 {
@@ -2545,6 +2573,7 @@ static void arm_smmu_get_resv_regions(struct device *dev,
 	list_add_tail(&region->list, head);
 
 	iommu_dma_get_resv_regions(dev, head);
+	arm_smmu_rmr_get_resv_regions(dev, head);
 }
 
 static bool arm_smmu_dev_has_feature(struct device *dev,
-- 
2.17.1


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v3 09/10] iommu/arm-smmu: Get associated RMR info and install bypass SMR
  2021-04-20  8:27 [PATCH v3 00/10] ACPI/IORT: Support for IORT RMR node Shameer Kolothum
                   ` (7 preceding siblings ...)
  2021-04-20  8:27 ` [PATCH v3 08/10] iommu/arm-smmu-v3: Reserve any RMR regions associated with a dev Shameer Kolothum
@ 2021-04-20  8:27 ` Shameer Kolothum
  2021-05-06 15:17   ` Steven Price
  2021-04-20  8:27 ` [PATCH v3 10/10] iommu/arm-smmu: Reserve any RMR regions associated with a dev Shameer Kolothum
  9 siblings, 1 reply; 24+ messages in thread
From: Shameer Kolothum @ 2021-04-20  8:27 UTC (permalink / raw)
  To: linux-arm-kernel, linux-acpi, iommu
  Cc: linuxarm, lorenzo.pieralisi, joro, robin.murphy, wanghuiqiang,
	guohanjun, steven.price, Sami.Mujawar, jon, eric.auger

From: Jon Nettleton <jon@solid-run.com>

Check if there is any RMR info associated with the devices behind
the SMMU and if any, install bypass SMRs for them. This is to
keep any ongoing traffic associated with these devices alive
when we enable/reset SMMU during probe().

Signed-off-by: Jon Nettleton <jon@solid-run.com>
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
---
 drivers/iommu/arm/arm-smmu/arm-smmu.c | 42 +++++++++++++++++++++++++++
 drivers/iommu/arm/arm-smmu/arm-smmu.h |  2 ++
 2 files changed, 44 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index d8c6bfde6a61..4d2f91626d87 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -2102,6 +2102,43 @@ err_reset_platform_ops: __maybe_unused;
 	return err;
 }
 
+static void arm_smmu_rmr_install_bypass_smr(struct arm_smmu_device *smmu)
+{
+	struct iommu_rmr *e;
+	int i, cnt = 0;
+	u32 smr;
+
+	for (i = 0; i < smmu->num_mapping_groups; i++) {
+		smr = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_SMR(i));
+		if (!FIELD_GET(ARM_SMMU_SMR_VALID, smr))
+			continue;
+
+		list_for_each_entry(e, &smmu->rmr_list, list) {
+			if (FIELD_GET(ARM_SMMU_SMR_ID, smr) != e->sid)
+				continue;
+
+			smmu->smrs[i].id = FIELD_GET(ARM_SMMU_SMR_ID, smr);
+			smmu->smrs[i].mask = FIELD_GET(ARM_SMMU_SMR_MASK, smr);
+			smmu->smrs[i].valid = true;
+
+			smmu->s2crs[i].type = S2CR_TYPE_BYPASS;
+			smmu->s2crs[i].privcfg = S2CR_PRIVCFG_DEFAULT;
+			smmu->s2crs[i].cbndx = 0xff;
+
+			cnt++;
+		}
+	}
+
+	dev_notice(smmu->dev, "\tpreserved %d boot mapping%s\n", cnt,
+		   cnt == 1 ? "" : "s");
+}
+
+static int arm_smmu_get_rmr(struct arm_smmu_device *smmu)
+{
+	INIT_LIST_HEAD(&smmu->rmr_list);
+	return iommu_dma_get_rmrs(dev_fwnode(smmu->dev), &smmu->rmr_list);
+}
+
 static int arm_smmu_device_probe(struct platform_device *pdev)
 {
 	struct resource *res;
@@ -2231,6 +2268,11 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
 	}
 
 	platform_set_drvdata(pdev, smmu);
+
+	/* Check for RMRs and install bypass SMRs if any */
+	if (!arm_smmu_get_rmr(smmu))
+		arm_smmu_rmr_install_bypass_smr(smmu);
+
 	arm_smmu_device_reset(smmu);
 	arm_smmu_test_smr_masks(smmu);
 
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h b/drivers/iommu/arm/arm-smmu/arm-smmu.h
index d2a2d1bc58ba..ca9559eb8733 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.h
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h
@@ -326,6 +326,8 @@ struct arm_smmu_device {
 
 	/* IOMMU core code handle */
 	struct iommu_device		iommu;
+
+	struct list_head		rmr_list;
 };
 
 enum arm_smmu_context_fmt {
-- 
2.17.1


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v3 10/10] iommu/arm-smmu: Reserve any RMR regions associated with a dev
  2021-04-20  8:27 [PATCH v3 00/10] ACPI/IORT: Support for IORT RMR node Shameer Kolothum
                   ` (8 preceding siblings ...)
  2021-04-20  8:27 ` [PATCH v3 09/10] iommu/arm-smmu: Get associated RMR info and install bypass SMR Shameer Kolothum
@ 2021-04-20  8:27 ` Shameer Kolothum
  2021-04-20 14:18   ` kernel test robot
  9 siblings, 1 reply; 24+ messages in thread
From: Shameer Kolothum @ 2021-04-20  8:27 UTC (permalink / raw)
  To: linux-arm-kernel, linux-acpi, iommu
  Cc: linuxarm, lorenzo.pieralisi, joro, robin.murphy, wanghuiqiang,
	guohanjun, steven.price, Sami.Mujawar, jon, eric.auger

From: Jon Nettleton <jon@solid-run.com>

Get RMR regions associated with a dev reserved so that there is
a unity mapping for them in SMMU.

Signed-off-by: Jon Nettleton <jon@solid-run.com>
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
---
 drivers/iommu/arm/arm-smmu/arm-smmu.c | 33 +++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index 4d2f91626d87..8cbe8b98e8f0 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -1591,6 +1591,38 @@ static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args)
 	return iommu_fwspec_add_ids(dev, &fwid, 1);
 }
 
+static bool arm_smmu_dev_has_rmr(struct arm_smmu_master_cfg *cfg,
+				 struct iommu_fwspec *fwspec,
+				 struct iommu_rmr *e)
+{
+	struct arm_smmu_device *smmu = cfg->smmu;
+	struct arm_smmu_smr *smrs = smmu->smrs;
+	int i, idx;
+
+	for_each_cfg_sme(cfg, fwspec, i, idx) {
+		if (e->sid == smrs[idx].id)
+			return true;
+	}
+
+	return false;
+}
+
+static void arm_smmu_rmr_get_resv_regions(struct device *dev,
+					  struct list_head *head)
+{
+	struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev);
+	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+	struct arm_smmu_device *smmu = cfg->smmu;
+	struct iommu_rmr *rmr;
+
+	list_for_each_entry(rmr, &smmu->rmr_list, list) {
+		if (!arm_smmu_dev_has_rmr(cfg, fwspec, rmr))
+			continue;
+
+		iommu_dma_get_rmr_resv_regions(dev, rmr, head);
+	}
+}
+
 static void arm_smmu_get_resv_regions(struct device *dev,
 				      struct list_head *head)
 {
@@ -1605,6 +1637,7 @@ static void arm_smmu_get_resv_regions(struct device *dev,
 	list_add_tail(&region->list, head);
 
 	iommu_dma_get_resv_regions(dev, head);
+	arm_smmu_rmr_get_resv_regions(dev, head);
 }
 
 static int arm_smmu_def_domain_type(struct device *dev)
-- 
2.17.1


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v3 02/10] iommu/dma: Introduce generic helper to retrieve RMR info
  2021-04-20  8:27 ` [PATCH v3 02/10] iommu/dma: Introduce generic helper to retrieve RMR info Shameer Kolothum
@ 2021-04-20 12:04   ` kernel test robot
  2021-04-20 12:32   ` kernel test robot
  2021-04-20 12:59   ` kernel test robot
  2 siblings, 0 replies; 24+ messages in thread
From: kernel test robot @ 2021-04-20 12:04 UTC (permalink / raw)
  To: Shameer Kolothum, linux-arm-kernel, linux-acpi, iommu
  Cc: kbuild-all, linuxarm, lorenzo.pieralisi, joro, robin.murphy,
	wanghuiqiang, guohanjun, steven.price


[-- Attachment #1: Type: text/plain, Size: 2309 bytes --]

Hi Shameer,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on pm/linux-next]
[also build test WARNING on arm/for-next soc/for-next arm64/for-next/core linus/master v5.12-rc8]
[cannot apply to iommu/next xlnx/master next-20210420]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Shameer-Kolothum/ACPI-IORT-Support-for-IORT-RMR-node/20210420-173125
base:   https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git linux-next
config: arc-allyesconfig (attached as .config)
compiler: arceb-elf-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/c68d4ba37ecc2173a2dc418799e23a184685d681
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Shameer-Kolothum/ACPI-IORT-Support-for-IORT-RMR-node/20210420-173125
        git checkout c68d4ba37ecc2173a2dc418799e23a184685d681
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross W=1 ARCH=arc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   In file included from drivers/gpu/drm/exynos/exynos_drm_dma.c:7:
>> include/linux/dma-iommu.h:92:31: warning: 'struct fwnode_handle' declared inside parameter list will not be visible outside of this definition or declaration
      92 | int iommu_dma_get_rmrs(struct fwnode_handle *iommu, struct list_head *list);
         |                               ^~~~~~~~~~~~~
   include/linux/dma-iommu.h:93:1: error: expected identifier or '(' before '{' token
      93 | {
         | ^


vim +92 include/linux/dma-iommu.h

    91	
  > 92	int iommu_dma_get_rmrs(struct fwnode_handle *iommu, struct list_head *list);
    93	{
    94		return 0;
    95	}
    96	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 67483 bytes --]

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v3 04/10] iommu/dma: Add a helper function to reserve RMRs for IOMMU drivers
  2021-04-20  8:27 ` [PATCH v3 04/10] iommu/dma: Add a helper function to reserve RMRs for IOMMU drivers Shameer Kolothum
@ 2021-04-20 12:07   ` kernel test robot
  2021-04-20 13:32   ` kernel test robot
  1 sibling, 0 replies; 24+ messages in thread
From: kernel test robot @ 2021-04-20 12:07 UTC (permalink / raw)
  To: Shameer Kolothum, linux-arm-kernel, linux-acpi, iommu
  Cc: kbuild-all, linuxarm, lorenzo.pieralisi, joro, robin.murphy,
	wanghuiqiang, guohanjun, steven.price


[-- Attachment #1: Type: text/plain, Size: 2899 bytes --]

Hi Shameer,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on pm/linux-next]
[also build test WARNING on arm/for-next soc/for-next arm64/for-next/core linus/master v5.12-rc8]
[cannot apply to iommu/next xlnx/master next-20210420]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Shameer-Kolothum/ACPI-IORT-Support-for-IORT-RMR-node/20210420-173125
base:   https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git linux-next
config: m68k-randconfig-m031-20210420 (attached as .config)
compiler: m68k-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/2501962e423895e2e4f126ff5998b226f4803186
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Shameer-Kolothum/ACPI-IORT-Support-for-IORT-RMR-node/20210420-173125
        git checkout 2501962e423895e2e4f126ff5998b226f4803186
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross W=1 ARCH=m68k 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   In file included from drivers/iommu/rockchip-iommu.c:13:
>> include/linux/dma-iommu.h:94:71: warning: 'struct iommu_rmr' declared inside parameter list will not be visible outside of this definition or declaration
      94 | static void iommu_dma_get_rmr_resv_regions(struct device *dev, struct iommu_rmr *rmr,
         |                                                                       ^~~~~~~~~
   include/linux/dma-iommu.h:100:1: error: expected identifier or '(' before '{' token
     100 | {
         | ^
   In file included from drivers/iommu/rockchip-iommu.c:13:
   include/linux/dma-iommu.h:94:13: warning: 'iommu_dma_get_rmr_resv_regions' defined but not used [-Wunused-function]
      94 | static void iommu_dma_get_rmr_resv_regions(struct device *dev, struct iommu_rmr *rmr,
         |             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Kconfig warnings: (for reference only)
   WARNING: unmet direct dependencies detected for ADI_AXI_ADC
   Depends on IIO && HAS_IOMEM && OF
   Selected by
   - AD9467 && IIO && SPI


vim +94 include/linux/dma-iommu.h

    93	
  > 94	static void iommu_dma_get_rmr_resv_regions(struct device *dev, struct iommu_rmr *rmr,
    95						   struct list_head *list)
    96	{
    97	}
    98	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 25978 bytes --]

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v3 02/10] iommu/dma: Introduce generic helper to retrieve RMR info
  2021-04-20  8:27 ` [PATCH v3 02/10] iommu/dma: Introduce generic helper to retrieve RMR info Shameer Kolothum
  2021-04-20 12:04   ` kernel test robot
@ 2021-04-20 12:32   ` kernel test robot
  2021-04-20 12:59   ` kernel test robot
  2 siblings, 0 replies; 24+ messages in thread
From: kernel test robot @ 2021-04-20 12:32 UTC (permalink / raw)
  To: Shameer Kolothum, linux-arm-kernel, linux-acpi, iommu
  Cc: kbuild-all, clang-built-linux, linuxarm, lorenzo.pieralisi, joro,
	robin.murphy, wanghuiqiang, guohanjun, steven.price


[-- Attachment #1: Type: text/plain, Size: 2178 bytes --]

Hi Shameer,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on pm/linux-next]
[also build test ERROR on arm/for-next soc/for-next arm64/for-next/core linus/master v5.12-rc8]
[cannot apply to iommu/next xlnx/master next-20210420]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Shameer-Kolothum/ACPI-IORT-Support-for-IORT-RMR-node/20210420-173125
base:   https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git linux-next
config: arm-randconfig-r023-20210420 (attached as .config)
compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project ca8eef7e3da8f750d7c7aa004fe426d1d34787ea)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install arm cross compiling tool for clang build
        # apt-get install binutils-arm-linux-gnueabi
        # https://github.com/0day-ci/linux/commit/c68d4ba37ecc2173a2dc418799e23a184685d681
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Shameer-Kolothum/ACPI-IORT-Support-for-IORT-RMR-node/20210420-173125
        git checkout c68d4ba37ecc2173a2dc418799e23a184685d681
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 ARCH=arm 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   In file included from drivers/iommu/arm/arm-smmu/arm-smmu.c:24:
>> include/linux/dma-iommu.h:93:1: error: expected identifier or '('
   {
   ^
   1 error generated.


vim +93 include/linux/dma-iommu.h

    91	
    92	int iommu_dma_get_rmrs(struct fwnode_handle *iommu, struct list_head *list);
  > 93	{
    94		return 0;
    95	}
    96	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 25176 bytes --]

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v3 02/10] iommu/dma: Introduce generic helper to retrieve RMR info
  2021-04-20  8:27 ` [PATCH v3 02/10] iommu/dma: Introduce generic helper to retrieve RMR info Shameer Kolothum
  2021-04-20 12:04   ` kernel test robot
  2021-04-20 12:32   ` kernel test robot
@ 2021-04-20 12:59   ` kernel test robot
  2 siblings, 0 replies; 24+ messages in thread
From: kernel test robot @ 2021-04-20 12:59 UTC (permalink / raw)
  To: Shameer Kolothum, linux-arm-kernel, linux-acpi, iommu
  Cc: kbuild-all, clang-built-linux, linuxarm, lorenzo.pieralisi, joro,
	robin.murphy, wanghuiqiang, guohanjun, steven.price


[-- Attachment #1: Type: text/plain, Size: 2470 bytes --]

Hi Shameer,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on pm/linux-next]
[also build test WARNING on arm/for-next soc/for-next arm64/for-next/core linus/master v5.12-rc8]
[cannot apply to iommu/next xlnx/master next-20210420]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Shameer-Kolothum/ACPI-IORT-Support-for-IORT-RMR-node/20210420-173125
base:   https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git linux-next
config: x86_64-randconfig-a002-20210420 (attached as .config)
compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project ca8eef7e3da8f750d7c7aa004fe426d1d34787ea)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install x86_64 cross compiling tool for clang build
        # apt-get install binutils-x86-64-linux-gnu
        # https://github.com/0day-ci/linux/commit/c68d4ba37ecc2173a2dc418799e23a184685d681
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Shameer-Kolothum/ACPI-IORT-Support-for-IORT-RMR-node/20210420-173125
        git checkout c68d4ba37ecc2173a2dc418799e23a184685d681
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   In file included from drivers/iommu/arm/arm-smmu/qcom_iommu.c:13:
>> include/linux/dma-iommu.h:92:31: warning: declaration of 'struct fwnode_handle' will not be visible outside of this function [-Wvisibility]
   int iommu_dma_get_rmrs(struct fwnode_handle *iommu, struct list_head *list);
                                 ^
   include/linux/dma-iommu.h:93:1: error: expected identifier or '('
   {
   ^
   1 warning and 1 error generated.


vim +92 include/linux/dma-iommu.h

    91	
  > 92	int iommu_dma_get_rmrs(struct fwnode_handle *iommu, struct list_head *list);
    93	{
    94		return 0;
    95	}
    96	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 42003 bytes --]

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v3 04/10] iommu/dma: Add a helper function to reserve RMRs for IOMMU drivers
  2021-04-20  8:27 ` [PATCH v3 04/10] iommu/dma: Add a helper function to reserve RMRs for IOMMU drivers Shameer Kolothum
  2021-04-20 12:07   ` kernel test robot
@ 2021-04-20 13:32   ` kernel test robot
  1 sibling, 0 replies; 24+ messages in thread
From: kernel test robot @ 2021-04-20 13:32 UTC (permalink / raw)
  To: Shameer Kolothum, linux-arm-kernel, linux-acpi, iommu
  Cc: kbuild-all, clang-built-linux, linuxarm, lorenzo.pieralisi, joro,
	robin.murphy, wanghuiqiang, guohanjun, steven.price


[-- Attachment #1: Type: text/plain, Size: 2536 bytes --]

Hi Shameer,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on pm/linux-next]
[also build test WARNING on arm/for-next soc/for-next arm64/for-next/core linus/master v5.12-rc8]
[cannot apply to iommu/next xlnx/master next-20210420]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Shameer-Kolothum/ACPI-IORT-Support-for-IORT-RMR-node/20210420-173125
base:   https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git linux-next
config: arm-randconfig-r023-20210420 (attached as .config)
compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project ca8eef7e3da8f750d7c7aa004fe426d1d34787ea)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install arm cross compiling tool for clang build
        # apt-get install binutils-arm-linux-gnueabi
        # https://github.com/0day-ci/linux/commit/2501962e423895e2e4f126ff5998b226f4803186
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Shameer-Kolothum/ACPI-IORT-Support-for-IORT-RMR-node/20210420-173125
        git checkout 2501962e423895e2e4f126ff5998b226f4803186
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 ARCH=arm 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   In file included from drivers/iommu/arm/arm-smmu/arm-smmu.c:24:
>> include/linux/dma-iommu.h:94:71: warning: declaration of 'struct iommu_rmr' will not be visible outside of this function [-Wvisibility]
   static void iommu_dma_get_rmr_resv_regions(struct device *dev, struct iommu_rmr *rmr,
                                                                         ^
   include/linux/dma-iommu.h:100:1: error: expected identifier or '('
   {
   ^
   1 warning and 1 error generated.


vim +94 include/linux/dma-iommu.h

    93	
  > 94	static void iommu_dma_get_rmr_resv_regions(struct device *dev, struct iommu_rmr *rmr,
    95						   struct list_head *list)
    96	{
    97	}
    98	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 25176 bytes --]

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v3 10/10] iommu/arm-smmu: Reserve any RMR regions associated with a dev
  2021-04-20  8:27 ` [PATCH v3 10/10] iommu/arm-smmu: Reserve any RMR regions associated with a dev Shameer Kolothum
@ 2021-04-20 14:18   ` kernel test robot
  0 siblings, 0 replies; 24+ messages in thread
From: kernel test robot @ 2021-04-20 14:18 UTC (permalink / raw)
  To: Shameer Kolothum, linux-arm-kernel, linux-acpi, iommu
  Cc: kbuild-all, clang-built-linux, linuxarm, lorenzo.pieralisi, joro,
	robin.murphy, wanghuiqiang, guohanjun, steven.price


[-- Attachment #1: Type: text/plain, Size: 3516 bytes --]

Hi Shameer,

I love your patch! Yet something to improve:

[auto build test ERROR on pm/linux-next]
[also build test ERROR on arm/for-next soc/for-next arm64/for-next/core linus/master v5.12-rc8]
[cannot apply to iommu/next xlnx/master next-20210420]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Shameer-Kolothum/ACPI-IORT-Support-for-IORT-RMR-node/20210420-173125
base:   https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git linux-next
config: arm-randconfig-r023-20210420 (attached as .config)
compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project ca8eef7e3da8f750d7c7aa004fe426d1d34787ea)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install arm cross compiling tool for clang build
        # apt-get install binutils-arm-linux-gnueabi
        # https://github.com/0day-ci/linux/commit/ea2019c2969e4e8f6ec2b0dc2d492f0d05f36cd9
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Shameer-Kolothum/ACPI-IORT-Support-for-IORT-RMR-node/20210420-173125
        git checkout ea2019c2969e4e8f6ec2b0dc2d492f0d05f36cd9
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 ARCH=arm 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   In file included from drivers/iommu/arm/arm-smmu/arm-smmu.c:24:
   include/linux/dma-iommu.h:94:71: warning: declaration of 'struct iommu_rmr' will not be visible outside of this function [-Wvisibility]
   static void iommu_dma_get_rmr_resv_regions(struct device *dev, struct iommu_rmr *rmr,
                                                                         ^
   include/linux/dma-iommu.h:100:1: error: expected identifier or '('
   {
   ^
>> drivers/iommu/arm/arm-smmu/arm-smmu.c:1622:39: error: incompatible pointer types passing 'struct iommu_rmr *' to parameter of type 'struct iommu_rmr *' [-Werror,-Wincompatible-pointer-types]
                   iommu_dma_get_rmr_resv_regions(dev, rmr, head);
                                                       ^~~
   include/linux/dma-iommu.h:94:82: note: passing argument to parameter 'rmr' here
   static void iommu_dma_get_rmr_resv_regions(struct device *dev, struct iommu_rmr *rmr,
                                                                                    ^
   1 warning and 2 errors generated.


vim +1622 drivers/iommu/arm/arm-smmu/arm-smmu.c

  1609	
  1610	static void arm_smmu_rmr_get_resv_regions(struct device *dev,
  1611						  struct list_head *head)
  1612	{
  1613		struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev);
  1614		struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
  1615		struct arm_smmu_device *smmu = cfg->smmu;
  1616		struct iommu_rmr *rmr;
  1617	
  1618		list_for_each_entry(rmr, &smmu->rmr_list, list) {
  1619			if (!arm_smmu_dev_has_rmr(cfg, fwspec, rmr))
  1620				continue;
  1621	
> 1622			iommu_dma_get_rmr_resv_regions(dev, rmr, head);
  1623		}
  1624	}
  1625	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 25176 bytes --]

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v3 09/10] iommu/arm-smmu: Get associated RMR info and install bypass SMR
  2021-04-20  8:27 ` [PATCH v3 09/10] iommu/arm-smmu: Get associated RMR info and install bypass SMR Shameer Kolothum
@ 2021-05-06 15:17   ` Steven Price
  2021-05-07  9:52     ` Robin Murphy
  2021-05-10  8:40     ` Shameerali Kolothum Thodi
  0 siblings, 2 replies; 24+ messages in thread
From: Steven Price @ 2021-05-06 15:17 UTC (permalink / raw)
  To: Shameer Kolothum, linux-arm-kernel, linux-acpi, iommu
  Cc: linuxarm, lorenzo.pieralisi, joro, robin.murphy, wanghuiqiang,
	guohanjun, Sami.Mujawar, jon, eric.auger

On 20/04/2021 09:27, Shameer Kolothum wrote:
> From: Jon Nettleton <jon@solid-run.com>
> 
> Check if there is any RMR info associated with the devices behind
> the SMMU and if any, install bypass SMRs for them. This is to
> keep any ongoing traffic associated with these devices alive
> when we enable/reset SMMU during probe().
> 
> Signed-off-by: Jon Nettleton <jon@solid-run.com>
> Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
> ---
>   drivers/iommu/arm/arm-smmu/arm-smmu.c | 42 +++++++++++++++++++++++++++
>   drivers/iommu/arm/arm-smmu/arm-smmu.h |  2 ++
>   2 files changed, 44 insertions(+)
> 
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> index d8c6bfde6a61..4d2f91626d87 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> @@ -2102,6 +2102,43 @@ err_reset_platform_ops: __maybe_unused;
>   	return err;
>   }
>   
> +static void arm_smmu_rmr_install_bypass_smr(struct arm_smmu_device *smmu)
> +{
> +	struct iommu_rmr *e;
> +	int i, cnt = 0;
> +	u32 smr;
> +
> +	for (i = 0; i < smmu->num_mapping_groups; i++) {
> +		smr = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_SMR(i));
> +		if (!FIELD_GET(ARM_SMMU_SMR_VALID, smr))
> +			continue;
> +
> +		list_for_each_entry(e, &smmu->rmr_list, list) {
> +			if (FIELD_GET(ARM_SMMU_SMR_ID, smr) != e->sid)
> +				continue;
> +
> +			smmu->smrs[i].id = FIELD_GET(ARM_SMMU_SMR_ID, smr);
> +			smmu->smrs[i].mask = FIELD_GET(ARM_SMMU_SMR_MASK, smr);
> +			smmu->smrs[i].valid = true;
> +
> +			smmu->s2crs[i].type = S2CR_TYPE_BYPASS;
> +			smmu->s2crs[i].privcfg = S2CR_PRIVCFG_DEFAULT;
> +			smmu->s2crs[i].cbndx = 0xff;
> +
> +			cnt++;
> +		}
> +	}

If I understand this correctly - this is looking at the current
(hardware) configuration of the SMMU and attempting to preserve any
bypass SMRs. However from what I can tell it suffers from the following
two problems:

  (a) Only the ID of the SMR is being checked, not the MASK. So if the
firmware has setup an SMR matching a number of streams this will break.

  (b) The SMMU might not be enabled at all (CLIENTPD==1) or bypass
enabled for unmatched streams (USFCFG==0).

Certainly in my test setup case (b) applies and so this doesn't work.
Perhaps something like the below would work better? (It works in the
case of the SMMU not enabled - I've not tested case (a)).

Steve

----8<----
static void arm_smmu_rmr_install_bypass_smr(struct arm_smmu_device *smmu)
{
	struct iommu_rmr *e;
	int i, cnt = 0;
	u32 smr;
	u32 reg;

	reg = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_sCR0);

	if ((reg & ARM_SMMU_sCR0_USFCFG) && !(reg & ARM_SMMU_sCR0_CLIENTPD)) {
		/*
		 * SMMU is already enabled and disallowing bypass, so preserve
		 * the existing SMRs
		 */
		for (i = 0; i < smmu->num_mapping_groups; i++) {
			smr = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_SMR(i));
			if (!FIELD_GET(ARM_SMMU_SMR_VALID, smr))
				continue;
			smmu->smrs[i].id = FIELD_GET(ARM_SMMU_SMR_ID, smr);
			smmu->smrs[i].mask = FIELD_GET(ARM_SMMU_SMR_MASK, smr);
			smmu->smrs[i].valid = true;
		}
	}

	list_for_each_entry(e, &smmu->rmr_list, list) {
		u32 sid = e->sid;

		i = arm_smmu_find_sme(smmu, sid, ~0);
		if (i < 0)
			continue;
		if (smmu->s2crs[i].count == 0) {
			smmu->smrs[i].id = sid;
			smmu->smrs[i].mask = ~0;
			smmu->smrs[i].valid = true;
		}
		smmu->s2crs[i].count++;
		smmu->s2crs[i].type = S2CR_TYPE_BYPASS;
		smmu->s2crs[i].privcfg = S2CR_PRIVCFG_DEFAULT;
		smmu->s2crs[i].cbndx = 0xff;

		cnt++;
	}

	if ((reg & ARM_SMMU_sCR0_USFCFG) && !(reg & ARM_SMMU_sCR0_CLIENTPD)) {
		/* Remove the valid bit for unused SMRs */
		for (i = 0; i < smmu->num_mapping_groups; i++) {
			if (smmu->s2crs[i].count == 0)
				smmu->smrs[i].valid = false;
		}
	}

	dev_notice(smmu->dev, "\tpreserved %d boot mapping%s\n", cnt,
		   cnt == 1 ? "" : "s");
}

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v3 09/10] iommu/arm-smmu: Get associated RMR info and install bypass SMR
  2021-05-06 15:17   ` Steven Price
@ 2021-05-07  9:52     ` Robin Murphy
  2021-05-10  8:40     ` Shameerali Kolothum Thodi
  1 sibling, 0 replies; 24+ messages in thread
From: Robin Murphy @ 2021-05-07  9:52 UTC (permalink / raw)
  To: Steven Price, Shameer Kolothum, linux-arm-kernel, linux-acpi, iommu
  Cc: linuxarm, lorenzo.pieralisi, joro, wanghuiqiang, guohanjun,
	Sami.Mujawar, jon, eric.auger



On 2021-05-06 16:17, Steven Price wrote:
> On 20/04/2021 09:27, Shameer Kolothum wrote:
>> From: Jon Nettleton <jon@solid-run.com>
>>
>> Check if there is any RMR info associated with the devices behind
>> the SMMU and if any, install bypass SMRs for them. This is to
>> keep any ongoing traffic associated with these devices alive
>> when we enable/reset SMMU during probe().
>>
>> Signed-off-by: Jon Nettleton <jon@solid-run.com>
>> Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
>> ---
>>   drivers/iommu/arm/arm-smmu/arm-smmu.c | 42 +++++++++++++++++++++++++++
>>   drivers/iommu/arm/arm-smmu/arm-smmu.h |  2 ++
>>   2 files changed, 44 insertions(+)
>>
>> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c 
>> b/drivers/iommu/arm/arm-smmu/arm-smmu.c
>> index d8c6bfde6a61..4d2f91626d87 100644
>> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
>> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
>> @@ -2102,6 +2102,43 @@ err_reset_platform_ops: __maybe_unused;
>>       return err;
>>   }
>> +static void arm_smmu_rmr_install_bypass_smr(struct arm_smmu_device 
>> *smmu)
>> +{
>> +    struct iommu_rmr *e;
>> +    int i, cnt = 0;
>> +    u32 smr;
>> +
>> +    for (i = 0; i < smmu->num_mapping_groups; i++) {
>> +        smr = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_SMR(i));
>> +        if (!FIELD_GET(ARM_SMMU_SMR_VALID, smr))
>> +            continue;
>> +
>> +        list_for_each_entry(e, &smmu->rmr_list, list) {
>> +            if (FIELD_GET(ARM_SMMU_SMR_ID, smr) != e->sid)
>> +                continue;
>> +
>> +            smmu->smrs[i].id = FIELD_GET(ARM_SMMU_SMR_ID, smr);
>> +            smmu->smrs[i].mask = FIELD_GET(ARM_SMMU_SMR_MASK, smr);
>> +            smmu->smrs[i].valid = true;
>> +
>> +            smmu->s2crs[i].type = S2CR_TYPE_BYPASS;
>> +            smmu->s2crs[i].privcfg = S2CR_PRIVCFG_DEFAULT;
>> +            smmu->s2crs[i].cbndx = 0xff;
>> +
>> +            cnt++;
>> +        }
>> +    }
> 
> If I understand this correctly - this is looking at the current
> (hardware) configuration of the SMMU and attempting to preserve any
> bypass SMRs. However from what I can tell it suffers from the following
> two problems:
> 
>   (a) Only the ID of the SMR is being checked, not the MASK. So if the
> firmware has setup an SMR matching a number of streams this will break.
> 
>   (b) The SMMU might not be enabled at all (CLIENTPD==1) or bypass
> enabled for unmatched streams (USFCFG==0).

Yes, trying to infer anything from the current SMMU hardware state is 
bogus - consider what you might find left over after a kexec, for 
instance. The *only* way to detect the presence and applicability of 
RMRs is to look at the actual RMR nodes in the IORT.

Ignore what we let the Qualcomm ACPI bootloader hack do - that whole 
implementation is "special".

Robin.

> Certainly in my test setup case (b) applies and so this doesn't work.
> Perhaps something like the below would work better? (It works in the
> case of the SMMU not enabled - I've not tested case (a)).
> 
> Steve
> 
> ----8<----
> static void arm_smmu_rmr_install_bypass_smr(struct arm_smmu_device *smmu)
> {
>      struct iommu_rmr *e;
>      int i, cnt = 0;
>      u32 smr;
>      u32 reg;
> 
>      reg = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_sCR0);
> 
>      if ((reg & ARM_SMMU_sCR0_USFCFG) && !(reg & ARM_SMMU_sCR0_CLIENTPD)) {
>          /*
>           * SMMU is already enabled and disallowing bypass, so preserve
>           * the existing SMRs
>           */
>          for (i = 0; i < smmu->num_mapping_groups; i++) {
>              smr = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_SMR(i));
>              if (!FIELD_GET(ARM_SMMU_SMR_VALID, smr))
>                  continue;
>              smmu->smrs[i].id = FIELD_GET(ARM_SMMU_SMR_ID, smr);
>              smmu->smrs[i].mask = FIELD_GET(ARM_SMMU_SMR_MASK, smr);
>              smmu->smrs[i].valid = true;
>          }
>      }
> 
>      list_for_each_entry(e, &smmu->rmr_list, list) {
>          u32 sid = e->sid;
> 
>          i = arm_smmu_find_sme(smmu, sid, ~0);
>          if (i < 0)
>              continue;
>          if (smmu->s2crs[i].count == 0) {
>              smmu->smrs[i].id = sid;
>              smmu->smrs[i].mask = ~0;
>              smmu->smrs[i].valid = true;
>          }
>          smmu->s2crs[i].count++;
>          smmu->s2crs[i].type = S2CR_TYPE_BYPASS;
>          smmu->s2crs[i].privcfg = S2CR_PRIVCFG_DEFAULT;
>          smmu->s2crs[i].cbndx = 0xff;
> 
>          cnt++;
>      }
> 
>      if ((reg & ARM_SMMU_sCR0_USFCFG) && !(reg & ARM_SMMU_sCR0_CLIENTPD)) {
>          /* Remove the valid bit for unused SMRs */
>          for (i = 0; i < smmu->num_mapping_groups; i++) {
>              if (smmu->s2crs[i].count == 0)
>                  smmu->smrs[i].valid = false;
>          }
>      }
> 
>      dev_notice(smmu->dev, "\tpreserved %d boot mapping%s\n", cnt,
>             cnt == 1 ? "" : "s");
> }

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v3 08/10] iommu/arm-smmu-v3: Reserve any RMR regions associated with a dev
  2021-04-20  8:27 ` [PATCH v3 08/10] iommu/arm-smmu-v3: Reserve any RMR regions associated with a dev Shameer Kolothum
@ 2021-05-07 10:01   ` Robin Murphy
  2021-05-10  9:19     ` Shameerali Kolothum Thodi
  0 siblings, 1 reply; 24+ messages in thread
From: Robin Murphy @ 2021-05-07 10:01 UTC (permalink / raw)
  To: Shameer Kolothum, linux-arm-kernel, linux-acpi, iommu
  Cc: linuxarm, lorenzo.pieralisi, joro, wanghuiqiang, guohanjun,
	steven.price, Sami.Mujawar, jon, eric.auger

On 2021-04-20 09:27, Shameer Kolothum wrote:
> Get RMR regions associated with a dev reserved so that there is
> a unity mapping for them in SMMU.
> 
> Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
> ---
>   drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 29 +++++++++++++++++++++
>   1 file changed, 29 insertions(+)
> 
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> index 14e9c7034c04..8bacedf7bb34 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -2531,6 +2531,34 @@ static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args)
>   	return iommu_fwspec_add_ids(dev, args->args, 1);
>   }
>   
> +static bool arm_smmu_dev_has_rmr(struct arm_smmu_master *master,
> +				 struct iommu_rmr *e)
> +{
> +	int i;
> +
> +	for (i = 0; i < master->num_sids; i++) {
> +		if (e->sid == master->sids[i])
> +			return true;
> +	}
> +
> +	return false;
> +}
> +
> +static void arm_smmu_rmr_get_resv_regions(struct device *dev,
> +					  struct list_head *head)
> +{
> +	struct arm_smmu_master *master = dev_iommu_priv_get(dev);
> +	struct arm_smmu_device *smmu = master->smmu;
> +	struct iommu_rmr *rmr;
> +
> +	list_for_each_entry(rmr, &smmu->rmr_list, list) {
> +		if (!arm_smmu_dev_has_rmr(master, rmr))
> +			continue;
> +
> +		iommu_dma_get_rmr_resv_regions(dev, rmr, head);
> +	}
> +}
> +

TBH I wouldn't have thought we need a driver-specific hook for this, or 
is it too painful to correlate fwspec->iommu_fwnode back to the relevant 
IORT node generically?

Robin.

>   static void arm_smmu_get_resv_regions(struct device *dev,
>   				      struct list_head *head)
>   {
> @@ -2545,6 +2573,7 @@ static void arm_smmu_get_resv_regions(struct device *dev,
>   	list_add_tail(&region->list, head);
>   
>   	iommu_dma_get_resv_regions(dev, head);
> +	arm_smmu_rmr_get_resv_regions(dev, head);
>   }
>   
>   static bool arm_smmu_dev_has_feature(struct device *dev,
> 

^ permalink raw reply	[flat|nested] 24+ messages in thread

* RE: [PATCH v3 09/10] iommu/arm-smmu: Get associated RMR info and install bypass SMR
  2021-05-06 15:17   ` Steven Price
  2021-05-07  9:52     ` Robin Murphy
@ 2021-05-10  8:40     ` Shameerali Kolothum Thodi
  2021-05-10 11:51       ` Jon Nettleton
  1 sibling, 1 reply; 24+ messages in thread
From: Shameerali Kolothum Thodi @ 2021-05-10  8:40 UTC (permalink / raw)
  To: Steven Price, linux-arm-kernel, linux-acpi, iommu, jon
  Cc: Linuxarm, lorenzo.pieralisi, joro, robin.murphy, wanghuiqiang,
	Guohanjun (Hanjun Guo),
	Sami.Mujawar, eric.auger



> -----Original Message-----
> From: Steven Price [mailto:steven.price@arm.com]
> Sent: 06 May 2021 16:17
> To: Shameerali Kolothum Thodi <shameerali.kolothum.thodi@huawei.com>;
> linux-arm-kernel@lists.infradead.org; linux-acpi@vger.kernel.org;
> iommu@lists.linux-foundation.org
> Cc: Linuxarm <linuxarm@huawei.com>; lorenzo.pieralisi@arm.com;
> joro@8bytes.org; robin.murphy@arm.com; wanghuiqiang
> <wanghuiqiang@huawei.com>; Guohanjun (Hanjun Guo)
> <guohanjun@huawei.com>; Sami.Mujawar@arm.com; jon@solid-run.com;
> eric.auger@redhat.com
> Subject: Re: [PATCH v3 09/10] iommu/arm-smmu: Get associated RMR info
> and install bypass SMR
> 
> On 20/04/2021 09:27, Shameer Kolothum wrote:
> > From: Jon Nettleton <jon@solid-run.com>
> >
> > Check if there is any RMR info associated with the devices behind
> > the SMMU and if any, install bypass SMRs for them. This is to
> > keep any ongoing traffic associated with these devices alive
> > when we enable/reset SMMU during probe().
> >
> > Signed-off-by: Jon Nettleton <jon@solid-run.com>
> > Signed-off-by: Shameer Kolothum
> <shameerali.kolothum.thodi@huawei.com>
> > ---
> >   drivers/iommu/arm/arm-smmu/arm-smmu.c | 42
> +++++++++++++++++++++++++++
> >   drivers/iommu/arm/arm-smmu/arm-smmu.h |  2 ++
> >   2 files changed, 44 insertions(+)
> >
> > diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c
> b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> > index d8c6bfde6a61..4d2f91626d87 100644
> > --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
> > +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> > @@ -2102,6 +2102,43 @@ err_reset_platform_ops: __maybe_unused;
> >   	return err;
> >   }
> >
> > +static void arm_smmu_rmr_install_bypass_smr(struct arm_smmu_device
> *smmu)
> > +{
> > +	struct iommu_rmr *e;
> > +	int i, cnt = 0;
> > +	u32 smr;
> > +
> > +	for (i = 0; i < smmu->num_mapping_groups; i++) {
> > +		smr = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_SMR(i));
> > +		if (!FIELD_GET(ARM_SMMU_SMR_VALID, smr))
> > +			continue;
> > +
> > +		list_for_each_entry(e, &smmu->rmr_list, list) {
> > +			if (FIELD_GET(ARM_SMMU_SMR_ID, smr) != e->sid)
> > +				continue;
> > +
> > +			smmu->smrs[i].id = FIELD_GET(ARM_SMMU_SMR_ID, smr);
> > +			smmu->smrs[i].mask = FIELD_GET(ARM_SMMU_SMR_MASK,
> smr);
> > +			smmu->smrs[i].valid = true;
> > +
> > +			smmu->s2crs[i].type = S2CR_TYPE_BYPASS;
> > +			smmu->s2crs[i].privcfg = S2CR_PRIVCFG_DEFAULT;
> > +			smmu->s2crs[i].cbndx = 0xff;
> > +
> > +			cnt++;
> > +		}
> > +	}
> 
> If I understand this correctly - this is looking at the current
> (hardware) configuration of the SMMU and attempting to preserve any
> bypass SMRs. However from what I can tell it suffers from the following
> two problems:
> 
>   (a) Only the ID of the SMR is being checked, not the MASK. So if the
> firmware has setup an SMR matching a number of streams this will break.
> 
>   (b) The SMMU might not be enabled at all (CLIENTPD==1) or bypass
> enabled for unmatched streams (USFCFG==0).
> 
> Certainly in my test setup case (b) applies and so this doesn't work.
> Perhaps something like the below would work better? (It works in the
> case of the SMMU not enabled - I've not tested case (a)).

Thanks Steve for taking a look and testing this on SMMUv2. My knowledge
on SMMUv2 is limited an don't have a setup to verify this. After reading
the code, agree that the current implementation addresses the hardware
configuration only and breaks all the scenarios explained above.

I will include the below snippet in next respin if that works.

Hi Jon,

Could you please take a look and see the below changes works for
you too?

Thanks,
Shameer

> ----8<----
> static void arm_smmu_rmr_install_bypass_smr(struct arm_smmu_device
> *smmu)
> {
> 	struct iommu_rmr *e;
> 	int i, cnt = 0;
> 	u32 smr;
> 	u32 reg;
> 
> 	reg = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_sCR0);
> 
> 	if ((reg & ARM_SMMU_sCR0_USFCFG) && !(reg &
> ARM_SMMU_sCR0_CLIENTPD)) {
> 		/*
> 		 * SMMU is already enabled and disallowing bypass, so preserve
> 		 * the existing SMRs
> 		 */
> 		for (i = 0; i < smmu->num_mapping_groups; i++) {
> 			smr = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_SMR(i));
> 			if (!FIELD_GET(ARM_SMMU_SMR_VALID, smr))
> 				continue;
> 			smmu->smrs[i].id = FIELD_GET(ARM_SMMU_SMR_ID, smr);
> 			smmu->smrs[i].mask = FIELD_GET(ARM_SMMU_SMR_MASK,
> smr);
> 			smmu->smrs[i].valid = true;
> 		}
> 	}
> 
> 	list_for_each_entry(e, &smmu->rmr_list, list) {
> 		u32 sid = e->sid;
> 
> 		i = arm_smmu_find_sme(smmu, sid, ~0);
> 		if (i < 0)
> 			continue;
> 		if (smmu->s2crs[i].count == 0) {
> 			smmu->smrs[i].id = sid;
> 			smmu->smrs[i].mask = ~0;
> 			smmu->smrs[i].valid = true;
> 		}
> 		smmu->s2crs[i].count++;
> 		smmu->s2crs[i].type = S2CR_TYPE_BYPASS;
> 		smmu->s2crs[i].privcfg = S2CR_PRIVCFG_DEFAULT;
> 		smmu->s2crs[i].cbndx = 0xff;
> 
> 		cnt++;
> 	}
> 
> 	if ((reg & ARM_SMMU_sCR0_USFCFG) && !(reg &
> ARM_SMMU_sCR0_CLIENTPD)) {
> 		/* Remove the valid bit for unused SMRs */
> 		for (i = 0; i < smmu->num_mapping_groups; i++) {
> 			if (smmu->s2crs[i].count == 0)
> 				smmu->smrs[i].valid = false;
> 		}
> 	}
> 
> 	dev_notice(smmu->dev, "\tpreserved %d boot mapping%s\n", cnt,
> 		   cnt == 1 ? "" : "s");
> }

^ permalink raw reply	[flat|nested] 24+ messages in thread

* RE: [PATCH v3 08/10] iommu/arm-smmu-v3: Reserve any RMR regions associated with a dev
  2021-05-07 10:01   ` Robin Murphy
@ 2021-05-10  9:19     ` Shameerali Kolothum Thodi
  2021-05-10 14:22       ` Robin Murphy
  0 siblings, 1 reply; 24+ messages in thread
From: Shameerali Kolothum Thodi @ 2021-05-10  9:19 UTC (permalink / raw)
  To: Robin Murphy, linux-arm-kernel, linux-acpi, iommu
  Cc: Linuxarm, lorenzo.pieralisi, joro, wanghuiqiang,
	Guohanjun (Hanjun Guo),
	steven.price, Sami.Mujawar, jon, eric.auger

Hi Robin,

> -----Original Message-----
> From: Robin Murphy [mailto:robin.murphy@arm.com]
> Sent: 07 May 2021 11:02
> To: Shameerali Kolothum Thodi <shameerali.kolothum.thodi@huawei.com>;
> linux-arm-kernel@lists.infradead.org; linux-acpi@vger.kernel.org;
> iommu@lists.linux-foundation.org
> Cc: Linuxarm <linuxarm@huawei.com>; lorenzo.pieralisi@arm.com;
> joro@8bytes.org; wanghuiqiang <wanghuiqiang@huawei.com>; Guohanjun
> (Hanjun Guo) <guohanjun@huawei.com>; steven.price@arm.com;
> Sami.Mujawar@arm.com; jon@solid-run.com; eric.auger@redhat.com
> Subject: Re: [PATCH v3 08/10] iommu/arm-smmu-v3: Reserve any RMR regions
> associated with a dev
> 
> On 2021-04-20 09:27, Shameer Kolothum wrote:
> > Get RMR regions associated with a dev reserved so that there is
> > a unity mapping for them in SMMU.
> >
> > Signed-off-by: Shameer Kolothum
> <shameerali.kolothum.thodi@huawei.com>
> > ---
> >   drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 29
> +++++++++++++++++++++
> >   1 file changed, 29 insertions(+)
> >
> > diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> > index 14e9c7034c04..8bacedf7bb34 100644
> > --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> > +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> > @@ -2531,6 +2531,34 @@ static int arm_smmu_of_xlate(struct device *dev,
> struct of_phandle_args *args)
> >   	return iommu_fwspec_add_ids(dev, args->args, 1);
> >   }
> >
> > +static bool arm_smmu_dev_has_rmr(struct arm_smmu_master *master,
> > +				 struct iommu_rmr *e)
> > +{
> > +	int i;
> > +
> > +	for (i = 0; i < master->num_sids; i++) {
> > +		if (e->sid == master->sids[i])
> > +			return true;
> > +	}
> > +
> > +	return false;
> > +}
> > +
> > +static void arm_smmu_rmr_get_resv_regions(struct device *dev,
> > +					  struct list_head *head)
> > +{
> > +	struct arm_smmu_master *master = dev_iommu_priv_get(dev);
> > +	struct arm_smmu_device *smmu = master->smmu;
> > +	struct iommu_rmr *rmr;
> > +
> > +	list_for_each_entry(rmr, &smmu->rmr_list, list) {
> > +		if (!arm_smmu_dev_has_rmr(master, rmr))
> > +			continue;
> > +
> > +		iommu_dma_get_rmr_resv_regions(dev, rmr, head);
> > +	}
> > +}
> > +
> 
> TBH I wouldn't have thought we need a driver-specific hook for this, or
> is it too painful to correlate fwspec->iommu_fwnode back to the relevant
> IORT node generically?

From a quick look, I think I could get rid of the above with something like below,

------8<----
+static bool iommu_dma_dev_has_rmr(struct iommu_fwspec *fwspec,
+                                 struct iommu_rmr *e)
+{
+       int i;
+
+       for (i = 0; i < fwspec->num_ids; i++) {
+                if (e->sid == fwspec->ids[i])
+                        return true;
+        }
+
+        return false;
+}
+
+
+void iommu_dma_get_rmr_resv_regions(struct device *dev, struct list_head *list)
+{
+       struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+       struct list_head rmr_list;
+       struct iommu_rmr *rmr;
+
+       INIT_LIST_HEAD(&rmr_list);
+       if (iommu_dma_get_rmrs(fwspec->iommu_fwnode, &rmr_list))
+               return;
        ...
+       list_for_each_entry(rmr, &rmr_list, list) {
+     
+       if (!iommu_dma_dev_has_rmr(fwspec, rmr)
+           continue;
+          ... 
+               region = iommu_alloc_resv_region(rmr->base_address,
+                                                rmr->length, prot,
+                                                type);
         ...
+       }
+}
 /**
  * iommu_dma_get_resv_regions - Reserved region driver helper
  * @dev: Device from iommu_get_resv_regions()
@@ -188,10 +242,11 @@ void iommu_dma_get_resv_regions(struct device *dev, struct list_head *list)
        if (!is_of_node(dev_iommu_fwspec_get(dev)->iommu_fwnode))
                iort_iommu_msi_get_resv_regions(dev, list);
 
+       iommu_dma_get_rmr_resv_regions(dev, list);
 }

----8<----

But looking at the SMMUv2 code, the fwspec->ids is MASK:SID, so I am not
sure the RMR sid can be compared directly to fwspec->ids above. Right? Or
is there a better way here?

Thanks,
Shameer


> 
> >   static void arm_smmu_get_resv_regions(struct device *dev,
> >   				      struct list_head *head)
> >   {
> > @@ -2545,6 +2573,7 @@ static void arm_smmu_get_resv_regions(struct
> device *dev,
> >   	list_add_tail(&region->list, head);
> >
> >   	iommu_dma_get_resv_regions(dev, head);
> > +	arm_smmu_rmr_get_resv_regions(dev, head);
> >   }
> >
> >   static bool arm_smmu_dev_has_feature(struct device *dev,
> >

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v3 09/10] iommu/arm-smmu: Get associated RMR info and install bypass SMR
  2021-05-10  8:40     ` Shameerali Kolothum Thodi
@ 2021-05-10 11:51       ` Jon Nettleton
  0 siblings, 0 replies; 24+ messages in thread
From: Jon Nettleton @ 2021-05-10 11:51 UTC (permalink / raw)
  To: Shameerali Kolothum Thodi
  Cc: Steven Price, linux-arm-kernel, linux-acpi, iommu, Linuxarm,
	lorenzo.pieralisi, joro, robin.murphy, wanghuiqiang,
	Guohanjun (Hanjun Guo),
	Sami.Mujawar, eric.auger

On Mon, May 10, 2021 at 10:40 AM Shameerali Kolothum Thodi
<shameerali.kolothum.thodi@huawei.com> wrote:
>
>
>
> > -----Original Message-----
> > From: Steven Price [mailto:steven.price@arm.com]
> > Sent: 06 May 2021 16:17
> > To: Shameerali Kolothum Thodi <shameerali.kolothum.thodi@huawei.com>;
> > linux-arm-kernel@lists.infradead.org; linux-acpi@vger.kernel.org;
> > iommu@lists.linux-foundation.org
> > Cc: Linuxarm <linuxarm@huawei.com>; lorenzo.pieralisi@arm.com;
> > joro@8bytes.org; robin.murphy@arm.com; wanghuiqiang
> > <wanghuiqiang@huawei.com>; Guohanjun (Hanjun Guo)
> > <guohanjun@huawei.com>; Sami.Mujawar@arm.com; jon@solid-run.com;
> > eric.auger@redhat.com
> > Subject: Re: [PATCH v3 09/10] iommu/arm-smmu: Get associated RMR info
> > and install bypass SMR
> >
> > On 20/04/2021 09:27, Shameer Kolothum wrote:
> > > From: Jon Nettleton <jon@solid-run.com>
> > >
> > > Check if there is any RMR info associated with the devices behind
> > > the SMMU and if any, install bypass SMRs for them. This is to
> > > keep any ongoing traffic associated with these devices alive
> > > when we enable/reset SMMU during probe().
> > >
> > > Signed-off-by: Jon Nettleton <jon@solid-run.com>
> > > Signed-off-by: Shameer Kolothum
> > <shameerali.kolothum.thodi@huawei.com>
> > > ---
> > >   drivers/iommu/arm/arm-smmu/arm-smmu.c | 42
> > +++++++++++++++++++++++++++
> > >   drivers/iommu/arm/arm-smmu/arm-smmu.h |  2 ++
> > >   2 files changed, 44 insertions(+)
> > >
> > > diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c
> > b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> > > index d8c6bfde6a61..4d2f91626d87 100644
> > > --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
> > > +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> > > @@ -2102,6 +2102,43 @@ err_reset_platform_ops: __maybe_unused;
> > >     return err;
> > >   }
> > >
> > > +static void arm_smmu_rmr_install_bypass_smr(struct arm_smmu_device
> > *smmu)
> > > +{
> > > +   struct iommu_rmr *e;
> > > +   int i, cnt = 0;
> > > +   u32 smr;
> > > +
> > > +   for (i = 0; i < smmu->num_mapping_groups; i++) {
> > > +           smr = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_SMR(i));
> > > +           if (!FIELD_GET(ARM_SMMU_SMR_VALID, smr))
> > > +                   continue;
> > > +
> > > +           list_for_each_entry(e, &smmu->rmr_list, list) {
> > > +                   if (FIELD_GET(ARM_SMMU_SMR_ID, smr) != e->sid)
> > > +                           continue;
> > > +
> > > +                   smmu->smrs[i].id = FIELD_GET(ARM_SMMU_SMR_ID, smr);
> > > +                   smmu->smrs[i].mask = FIELD_GET(ARM_SMMU_SMR_MASK,
> > smr);
> > > +                   smmu->smrs[i].valid = true;
> > > +
> > > +                   smmu->s2crs[i].type = S2CR_TYPE_BYPASS;
> > > +                   smmu->s2crs[i].privcfg = S2CR_PRIVCFG_DEFAULT;
> > > +                   smmu->s2crs[i].cbndx = 0xff;
> > > +
> > > +                   cnt++;
> > > +           }
> > > +   }
> >
> > If I understand this correctly - this is looking at the current
> > (hardware) configuration of the SMMU and attempting to preserve any
> > bypass SMRs. However from what I can tell it suffers from the following
> > two problems:
> >
> >   (a) Only the ID of the SMR is being checked, not the MASK. So if the
> > firmware has setup an SMR matching a number of streams this will break.
> >
> >   (b) The SMMU might not be enabled at all (CLIENTPD==1) or bypass
> > enabled for unmatched streams (USFCFG==0).
> >
> > Certainly in my test setup case (b) applies and so this doesn't work.
> > Perhaps something like the below would work better? (It works in the
> > case of the SMMU not enabled - I've not tested case (a)).
>
> Thanks Steve for taking a look and testing this on SMMUv2. My knowledge
> on SMMUv2 is limited an don't have a setup to verify this. After reading
> the code, agree that the current implementation addresses the hardware
> configuration only and breaks all the scenarios explained above.
>
> I will include the below snippet in next respin if that works.
>
> Hi Jon,
>
> Could you please take a look and see the below changes works for
> you too?

My original code was derived from a solution that was proposed for
device-tree booted systems.  I will review and test the changes and
then report back.

-Jon


>
> Thanks,
> Shameer
>
> > ----8<----
> > static void arm_smmu_rmr_install_bypass_smr(struct arm_smmu_device
> > *smmu)
> > {
> >       struct iommu_rmr *e;
> >       int i, cnt = 0;
> >       u32 smr;
> >       u32 reg;
> >
> >       reg = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_sCR0);
> >
> >       if ((reg & ARM_SMMU_sCR0_USFCFG) && !(reg &
> > ARM_SMMU_sCR0_CLIENTPD)) {
> >               /*
> >                * SMMU is already enabled and disallowing bypass, so preserve
> >                * the existing SMRs
> >                */
> >               for (i = 0; i < smmu->num_mapping_groups; i++) {
> >                       smr = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_SMR(i));
> >                       if (!FIELD_GET(ARM_SMMU_SMR_VALID, smr))
> >                               continue;
> >                       smmu->smrs[i].id = FIELD_GET(ARM_SMMU_SMR_ID, smr);
> >                       smmu->smrs[i].mask = FIELD_GET(ARM_SMMU_SMR_MASK,
> > smr);
> >                       smmu->smrs[i].valid = true;
> >               }
> >       }
> >
> >       list_for_each_entry(e, &smmu->rmr_list, list) {
> >               u32 sid = e->sid;
> >
> >               i = arm_smmu_find_sme(smmu, sid, ~0);
> >               if (i < 0)
> >                       continue;
> >               if (smmu->s2crs[i].count == 0) {
> >                       smmu->smrs[i].id = sid;
> >                       smmu->smrs[i].mask = ~0;
> >                       smmu->smrs[i].valid = true;
> >               }
> >               smmu->s2crs[i].count++;
> >               smmu->s2crs[i].type = S2CR_TYPE_BYPASS;
> >               smmu->s2crs[i].privcfg = S2CR_PRIVCFG_DEFAULT;
> >               smmu->s2crs[i].cbndx = 0xff;
> >
> >               cnt++;
> >       }
> >
> >       if ((reg & ARM_SMMU_sCR0_USFCFG) && !(reg &
> > ARM_SMMU_sCR0_CLIENTPD)) {
> >               /* Remove the valid bit for unused SMRs */
> >               for (i = 0; i < smmu->num_mapping_groups; i++) {
> >                       if (smmu->s2crs[i].count == 0)
> >                               smmu->smrs[i].valid = false;
> >               }
> >       }
> >
> >       dev_notice(smmu->dev, "\tpreserved %d boot mapping%s\n", cnt,
> >                  cnt == 1 ? "" : "s");
> > }

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v3 08/10] iommu/arm-smmu-v3: Reserve any RMR regions associated with a dev
  2021-05-10  9:19     ` Shameerali Kolothum Thodi
@ 2021-05-10 14:22       ` Robin Murphy
  0 siblings, 0 replies; 24+ messages in thread
From: Robin Murphy @ 2021-05-10 14:22 UTC (permalink / raw)
  To: Shameerali Kolothum Thodi, linux-arm-kernel, linux-acpi, iommu
  Cc: Linuxarm, lorenzo.pieralisi, joro, wanghuiqiang,
	Guohanjun (Hanjun Guo),
	steven.price, Sami.Mujawar, jon, eric.auger

On 2021-05-10 10:19, Shameerali Kolothum Thodi wrote:
> Hi Robin,
> 
>> -----Original Message-----
>> From: Robin Murphy [mailto:robin.murphy@arm.com]
>> Sent: 07 May 2021 11:02
>> To: Shameerali Kolothum Thodi <shameerali.kolothum.thodi@huawei.com>;
>> linux-arm-kernel@lists.infradead.org; linux-acpi@vger.kernel.org;
>> iommu@lists.linux-foundation.org
>> Cc: Linuxarm <linuxarm@huawei.com>; lorenzo.pieralisi@arm.com;
>> joro@8bytes.org; wanghuiqiang <wanghuiqiang@huawei.com>; Guohanjun
>> (Hanjun Guo) <guohanjun@huawei.com>; steven.price@arm.com;
>> Sami.Mujawar@arm.com; jon@solid-run.com; eric.auger@redhat.com
>> Subject: Re: [PATCH v3 08/10] iommu/arm-smmu-v3: Reserve any RMR regions
>> associated with a dev
>>
>> On 2021-04-20 09:27, Shameer Kolothum wrote:
>>> Get RMR regions associated with a dev reserved so that there is
>>> a unity mapping for them in SMMU.
>>>
>>> Signed-off-by: Shameer Kolothum
>> <shameerali.kolothum.thodi@huawei.com>
>>> ---
>>>    drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 29
>> +++++++++++++++++++++
>>>    1 file changed, 29 insertions(+)
>>>
>>> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>> b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>>> index 14e9c7034c04..8bacedf7bb34 100644
>>> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>>> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>>> @@ -2531,6 +2531,34 @@ static int arm_smmu_of_xlate(struct device *dev,
>> struct of_phandle_args *args)
>>>    	return iommu_fwspec_add_ids(dev, args->args, 1);
>>>    }
>>>
>>> +static bool arm_smmu_dev_has_rmr(struct arm_smmu_master *master,
>>> +				 struct iommu_rmr *e)
>>> +{
>>> +	int i;
>>> +
>>> +	for (i = 0; i < master->num_sids; i++) {
>>> +		if (e->sid == master->sids[i])
>>> +			return true;
>>> +	}
>>> +
>>> +	return false;
>>> +}
>>> +
>>> +static void arm_smmu_rmr_get_resv_regions(struct device *dev,
>>> +					  struct list_head *head)
>>> +{
>>> +	struct arm_smmu_master *master = dev_iommu_priv_get(dev);
>>> +	struct arm_smmu_device *smmu = master->smmu;
>>> +	struct iommu_rmr *rmr;
>>> +
>>> +	list_for_each_entry(rmr, &smmu->rmr_list, list) {
>>> +		if (!arm_smmu_dev_has_rmr(master, rmr))
>>> +			continue;
>>> +
>>> +		iommu_dma_get_rmr_resv_regions(dev, rmr, head);
>>> +	}
>>> +}
>>> +
>>
>> TBH I wouldn't have thought we need a driver-specific hook for this, or
>> is it too painful to correlate fwspec->iommu_fwnode back to the relevant
>> IORT node generically?
> 
>  From a quick look, I think I could get rid of the above with something like below,
> 
> ------8<----
> +static bool iommu_dma_dev_has_rmr(struct iommu_fwspec *fwspec,
> +                                 struct iommu_rmr *e)
> +{
> +       int i;
> +
> +       for (i = 0; i < fwspec->num_ids; i++) {
> +                if (e->sid == fwspec->ids[i])
> +                        return true;
> +        }
> +
> +        return false;
> +}
> +
> +
> +void iommu_dma_get_rmr_resv_regions(struct device *dev, struct list_head *list)
> +{
> +       struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
> +       struct list_head rmr_list;
> +       struct iommu_rmr *rmr;
> +
> +       INIT_LIST_HEAD(&rmr_list);
> +       if (iommu_dma_get_rmrs(fwspec->iommu_fwnode, &rmr_list))
> +               return;
>          ...
> +       list_for_each_entry(rmr, &rmr_list, list) {
> +
> +       if (!iommu_dma_dev_has_rmr(fwspec, rmr)
> +           continue;
> +          ...
> +               region = iommu_alloc_resv_region(rmr->base_address,
> +                                                rmr->length, prot,
> +                                                type);
>           ...
> +       }
> +}
>   /**
>    * iommu_dma_get_resv_regions - Reserved region driver helper
>    * @dev: Device from iommu_get_resv_regions()
> @@ -188,10 +242,11 @@ void iommu_dma_get_resv_regions(struct device *dev, struct list_head *list)
>          if (!is_of_node(dev_iommu_fwspec_get(dev)->iommu_fwnode))
>                  iort_iommu_msi_get_resv_regions(dev, list);
>   
> +       iommu_dma_get_rmr_resv_regions(dev, list);
>   }
> 
> ----8<----
> 
> But looking at the SMMUv2 code, the fwspec->ids is MASK:SID, so I am not
> sure the RMR sid can be compared directly to fwspec->ids above. Right? Or
> is there a better way here?

Ah, but consider how the IDs got there in the first place ;)

A mask will never be set on ACPI systems, since IORT (intentionally) 
only caters for straightforward mappings rather than arbitrary 
complexity, so the assumption of fwspec ID == SID is already baked in by 
virtue of arm_smmu_iort_xlate(). The IORT code is free to assume its own 
behaviour!

Robin.

> 
> Thanks,
> Shameer
> 
> 
>>
>>>    static void arm_smmu_get_resv_regions(struct device *dev,
>>>    				      struct list_head *head)
>>>    {
>>> @@ -2545,6 +2573,7 @@ static void arm_smmu_get_resv_regions(struct
>> device *dev,
>>>    	list_add_tail(&region->list, head);
>>>
>>>    	iommu_dma_get_resv_regions(dev, head);
>>> +	arm_smmu_rmr_get_resv_regions(dev, head);
>>>    }
>>>
>>>    static bool arm_smmu_dev_has_feature(struct device *dev,
>>>

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, back to index

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-20  8:27 [PATCH v3 00/10] ACPI/IORT: Support for IORT RMR node Shameer Kolothum
2021-04-20  8:27 ` [PATCH v3 01/10] ACPI/IORT: Add support for RMR node parsing Shameer Kolothum
2021-04-20  8:27 ` [PATCH v3 02/10] iommu/dma: Introduce generic helper to retrieve RMR info Shameer Kolothum
2021-04-20 12:04   ` kernel test robot
2021-04-20 12:32   ` kernel test robot
2021-04-20 12:59   ` kernel test robot
2021-04-20  8:27 ` [PATCH v3 03/10] ACPI/IORT: Add a helper to retrieve RMR memory regions Shameer Kolothum
2021-04-20  8:27 ` [PATCH v3 04/10] iommu/dma: Add a helper function to reserve RMRs for IOMMU drivers Shameer Kolothum
2021-04-20 12:07   ` kernel test robot
2021-04-20 13:32   ` kernel test robot
2021-04-20  8:27 ` [PATCH v3 05/10] iommu/arm-smmu-v3: Introduce strtab init helper Shameer Kolothum
2021-04-20  8:27 ` [PATCH v3 06/10] iommu/arm-smmu-v3: Add bypass flag to arm_smmu_write_strtab_ent() Shameer Kolothum
2021-04-20  8:27 ` [PATCH v3 07/10] iommu/arm-smmu-v3: Get associated RMR info and install bypass STE Shameer Kolothum
2021-04-20  8:27 ` [PATCH v3 08/10] iommu/arm-smmu-v3: Reserve any RMR regions associated with a dev Shameer Kolothum
2021-05-07 10:01   ` Robin Murphy
2021-05-10  9:19     ` Shameerali Kolothum Thodi
2021-05-10 14:22       ` Robin Murphy
2021-04-20  8:27 ` [PATCH v3 09/10] iommu/arm-smmu: Get associated RMR info and install bypass SMR Shameer Kolothum
2021-05-06 15:17   ` Steven Price
2021-05-07  9:52     ` Robin Murphy
2021-05-10  8:40     ` Shameerali Kolothum Thodi
2021-05-10 11:51       ` Jon Nettleton
2021-04-20  8:27 ` [PATCH v3 10/10] iommu/arm-smmu: Reserve any RMR regions associated with a dev Shameer Kolothum
2021-04-20 14:18   ` kernel test robot

Linux-ACPI Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-acpi/0 linux-acpi/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-acpi linux-acpi/ https://lore.kernel.org/linux-acpi \
		linux-acpi@vger.kernel.org
	public-inbox-index linux-acpi

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-acpi


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