Skip to contentSkip to conversation

iommu/riscv: Add HPM support for RISC-V IOMMU

PATCH NAK Lv Zheng 8 participants 73 messages Jan 28 – Feb 27 2 messages not in the archive

Subsystems (6)
lore
Share & tools
lore

Lv Zheng

author
#0 lore raw

cover iommu/riscv: Add HPM support for RISC-V IOMMU

This patchset adds HPM support for RISC-V IOMMU. The HPM support can be found in recent announced SpacemiT SoCs (K3), where T100 (SpacemiT distributed IOMMU) is shipped.

The tested result can be found as follows:

 root@sdfirm:~# perf stat --timeout 5000 -a -e riscv_iommu_hpm_0/device-directory-walks,config1=0x20c0010000000000/ dmatest; sleep 1
 [  176.025295] event_source riscv_iommu_hpm_0: Setting event filter: 20c0010000000005, PID PSCID: 0x0, DID GSCID: 0xc0010, PV PSCV: 0x0, DV GSCV: 0x1, IDT: 0x0, DMASK: 0x0, Index: 0
 [  176.110211] dmatest: Started 1 threads using dma0chan0
 [  176.114933] dmatest: dma0chan0-copy0: summary 1 tests, 0 failures 394.94 iops 394 KB/s (0)

Performance counter stats for 'system wide':

                  3      riscv_iommu_hpm_0/device-directory-walks,config1=0x20c0010000000000/                                   
 
        0.081056000 seconds time elapsed
 root@sdfirm:~# perf stat --timeout 5000 -a -e riscv_iommu_hpm_0/first-stage-page-table-walks,config1=0x20c0010000000000/ dmatest; sleep 1
 [   68.050220] event_source riscv_iommu_hpm_0: Setting event filter: 20c0010000000007, PID PSCID: 0x0, DID GSCID: 0xc0010, PV PSCV: 0x0, DV GSCV: 0x1, IDT: 0x0, DMASK: 0x0, Index: 0
 [   68.152992] dmatest: Started 1 threads using dma0chan0
 [   68.158071] dmatest: dma0chan0-copy0: summary 1 tests, 0 failures 401.92 iops 401 KB/s (0)

Performance counter stats for 'system wide':

                  6      riscv_iommu_hpm_0/first-stage-page-table-walks,config1=0x20c0010000000000/                                   
 
        0.083192000 seconds time elapsed

Jingyu Li (3):
iommu/riscv: Enable IOMMU DMA mapping support iommu/riscv: Fix WSI mode IRQ number handling iommu/riscv: Add HPM support for performance monitoring

Lv Zheng (3):
spacemit/t100: Add vendor event support for RISC-V IOMMU HPM spacemit/t100: Add global filter support for RISC-V IOMMU HPM spacemit/t100: Add SpacemiT T100 IOATC HPM support

 .../bindings/iommu/riscv,iommu.yaml           |    6 +
 drivers/iommu/Kconfig                         |    2 +-
 drivers/iommu/riscv/Kconfig                   |    9 +
 drivers/iommu/riscv/Makefile                  |    1 +
 drivers/iommu/riscv/iommu-bits.h              |   19 +-
 drivers/iommu/riscv/iommu-hpm.c               | 1141 +++++++++++++++++
 drivers/iommu/riscv/iommu-pci.c               |   13 +-
 drivers/iommu/riscv/iommu-platform.c          |   12 +-
 drivers/iommu/riscv/iommu.c                   |   25 +-
 drivers/iommu/riscv/iommu.h                   |   44 +-
 10 files changed, 1259 insertions(+), 13 deletions(-)
 create mode 100644 drivers/iommu/riscv/iommu-hpm.c
Signature · 5 lines
2.43.0

This message and any attachment are confidential and may be privileged or otherwise protected from disclosure. If you are not an intended recipient of this message, please delete it and any attachment from your system and notify the sender immediately by reply e-mail. Unintended recipients should not use, copy, disclose or take any action based on this message or any information contained in this message. Emails cannot be guaranteed to be secure or error free as they can be intercepted, amended, lost or destroyed, and you should take full responsibility for security checking. 
 
本邮件及其任何附件具有保密性质,并可能受其他保护或不允许被披露给第三方。如阁下误收到本邮件,敬请立即以回复电子邮件的方式通知发件人,并将本邮件及其任何附件从阁下系统中予以删除。如阁下并非本邮件写明之收件人,敬请切勿使用、复制、披露本邮件或其任何内容,亦请切勿依本邮件或其任何内容而采取任何行动。电子邮件无法保证是一种安全和不会出现任何差错的通信方式,可能会被拦截、修改、丢失或损坏,收件人需自行负责做好安全检查。
author
#1 lore raw

PATCH 1/6 iommu/riscv: Enable IOMMU DMA mapping support

From: Jingyu Li <[email protected]>

This patch enables IOMMU DMA mapping support for RISC-V, so that DMACs can be tested with translation enabled.

Known Issue:
1. When CONFIG_IOMMU_DMA is enabled, current Linux RISC-V IOMMU is lack of PCIe support, causing riscv_iommu_fault:522 in dealing with NVMe PCIe devices.

---
 drivers/iommu/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iommu/Kconfig +1 -1
index f86262b11416..34d8a792339f 100644
@@ -151,7 +151,7 @@ config OF_IOMMU
 
 # IOMMU-agnostic DMA-mapping layer
 config IOMMU_DMA
-	def_bool ARM64 || X86 || S390
+	def_bool ARM64 || X86 || S390 || RISCV
 	select DMA_OPS_HELPERS
 	select IOMMU_API
 	select IOMMU_IOVA
Signature · 5 lines
2.43.0

This message and any attachment are confidential and may be privileged or otherwise protected from disclosure. If you are not an intended recipient of this message, please delete it and any attachment from your system and notify the sender immediately by reply e-mail. Unintended recipients should not use, copy, disclose or take any action based on this message or any information contained in this message. Emails cannot be guaranteed to be secure or error free as they can be intercepted, amended, lost or destroyed, and you should take full responsibility for security checking. 
 
本邮件及其任何附件具有保密性质,并可能受其他保护或不允许被披露给第三方。如阁下误收到本邮件,敬请立即以回复电子邮件的方式通知发件人,并将本邮件及其任何附件从阁下系统中予以删除。如阁下并非本邮件写明之收件人,敬请切勿使用、复制、披露本邮件或其任何内容,亦请切勿依本邮件或其任何内容而采取任何行动。电子邮件无法保证是一种安全和不会出现任何差错的通信方式,可能会被拦截、修改、丢失或损坏,收件人需自行负责做好安全检查。
author
#2 lore raw

PATCH 2/6 iommu/riscv: Fix WSI mode IRQ number handling

In reply to Lv Zheng

From: Jingyu Li <[email protected]>

In WSI mode, ICVEC doesn't exist, thus reading it returns 0, which causes IOMMU driver to fail to find IRQ numbers from device tree IRQ arrary. This patch fixes this issue by applying icvec indexes of WSI IRQs.

---
 drivers/iommu/riscv/iommu.c | 25 ++++++++++++++++++++-----
 1 file changed, 20 insertions(+), 5 deletions(-)
drivers/iommu/riscv/iommu.c +20 -5
index d9429097a2b5..26630979473b 100644
@@ -1593,11 +1593,26 @@ static int riscv_iommu_init_check(struct riscv_iommu_device *iommu)
 		       FIELD_PREP(RISCV_IOMMU_ICVEC_PMIV, 3 % iommu->irqs_count);
 	riscv_iommu_writeq(iommu, RISCV_IOMMU_REG_ICVEC, iommu->icvec);
 	iommu->icvec = riscv_iommu_readq(iommu, RISCV_IOMMU_REG_ICVEC);
-	if (max(max(FIELD_GET(RISCV_IOMMU_ICVEC_CIV, iommu->icvec),
-		    FIELD_GET(RISCV_IOMMU_ICVEC_FIV, iommu->icvec)),
-		max(FIELD_GET(RISCV_IOMMU_ICVEC_PIV, iommu->icvec),
-		    FIELD_GET(RISCV_IOMMU_ICVEC_PMIV, iommu->icvec))) >= iommu->irqs_count)
-		return -EINVAL;
+	/*
+	 * In WSI mode, ICVEC may read as zero. Only validate if using MSI.
+	 * Check if FCTL.WSI is set to determine interrupt mode.
+	 */
+	if (!(iommu->fctl & RISCV_IOMMU_FCTL_WSI)) {
+		if (max(max(FIELD_GET(RISCV_IOMMU_ICVEC_CIV, iommu->icvec),
+			    FIELD_GET(RISCV_IOMMU_ICVEC_FIV, iommu->icvec)),
+			max(FIELD_GET(RISCV_IOMMU_ICVEC_PIV, iommu->icvec),
+			    FIELD_GET(RISCV_IOMMU_ICVEC_PMIV, iommu->icvec))) >= iommu->irqs_count)
+			return -EINVAL;
+	} else {
+		/*
+		 * WSI mode: ICVEC is not used. Set to identity mapping for
+		 * riscv_iommu_queue_vec() to work correctly.
+		 */
+		iommu->icvec = FIELD_PREP(RISCV_IOMMU_ICVEC_CIV, 0) |
+			       FIELD_PREP(RISCV_IOMMU_ICVEC_FIV, 1) |
+			       FIELD_PREP(RISCV_IOMMU_ICVEC_PIV, 2) |
+			       FIELD_PREP(RISCV_IOMMU_ICVEC_PMIV, 3);
+	}
 
 	return 0;
 }
Signature · 5 lines
2.43.0

This message and any attachment are confidential and may be privileged or otherwise protected from disclosure. If you are not an intended recipient of this message, please delete it and any attachment from your system and notify the sender immediately by reply e-mail. Unintended recipients should not use, copy, disclose or take any action based on this message or any information contained in this message. Emails cannot be guaranteed to be secure or error free as they can be intercepted, amended, lost or destroyed, and you should take full responsibility for security checking. 
 
本邮件及其任何附件具有保密性质,并可能受其他保护或不允许被披露给第三方。如阁下误收到本邮件,敬请立即以回复电子邮件的方式通知发件人,并将本邮件及其任何附件从阁下系统中予以删除。如阁下并非本邮件写明之收件人,敬请切勿使用、复制、披露本邮件或其任何内容,亦请切勿依本邮件或其任何内容而采取任何行动。电子邮件无法保证是一种安全和不会出现任何差错的通信方式,可能会被拦截、修改、丢失或损坏,收件人需自行负责做好安全检查。
author
#3 lore raw

PATCH 3/6 iommu/riscv: Add HPM support for performance monitoring

In reply to Lv Zheng

From: Jingyu Li <[email protected]>

This patch introduces perf-based HPM driver for RISC-V IOMMU, enabling performance monitoring capabilities.

This patch uses COUNTER_MAX-1 as a static counter index of HPMCYCLES, and 0~COUNTER_MAX-2 as the dynamic counter indexes of other HPMEVENTS in order to correctly index into IOHPMEVT and IOHPMCTR registers that have already been defined in the iommu-bits.h. However the users treat 0 as the index of HPMCYCLES and 1~COUNTER_MAX-1 as the indexes of other HPMEVENTS, thus care should be taken in dealing with counter indexes between userspace and kernel space.

---
 drivers/iommu/riscv/Kconfig          |   9 +
 drivers/iommu/riscv/Makefile         |   1 +
 drivers/iommu/riscv/iommu-bits.h     |   5 +
 drivers/iommu/riscv/iommu-hpm.c      | 807 +++++++++++++++++++++++++++
 drivers/iommu/riscv/iommu-pci.c      |  13 +-
 drivers/iommu/riscv/iommu-platform.c |   8 +-
 drivers/iommu/riscv/iommu.h          |  41 ++
 7 files changed, 881 insertions(+), 3 deletions(-)
 create mode 100644 drivers/iommu/riscv/iommu-hpm.c
drivers/iommu/riscv/Kconfig +9 -0
index c071816f59a6..aa659b0f1682 100644
@@ -18,3 +18,12 @@ config RISCV_IOMMU_PCI
 	def_bool y if RISCV_IOMMU && PCI_MSI
 	help
 	  Support for the PCIe implementation of RISC-V IOMMU architecture.
+
+config RISCV_IOMMU_HPM
+	tristate "RISCV IOMMU HPM support"
+	depends on RISCV_IOMMU
+	help
+	  Support for RISC-V IOMMU HPM.
+
+	  Say 'y/m' to enable a driver that will attach to performance
+	  monitoring units and provide standard perf based interfaces.
drivers/iommu/riscv/Makefile +1 -0
index b5929f9f23e6..53db3ef62bdd 100644
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-y += iommu.o iommu-platform.o
 obj-$(CONFIG_RISCV_IOMMU_PCI) += iommu-pci.o
+obj-$(CONFIG_RISCV_IOMMU_HPM) += iommu-hpm.o
drivers/iommu/riscv/iommu-bits.h +5 -0
index 98daf0e1a306..f5f00386a11c 100644
@@ -207,6 +207,7 @@ enum riscv_iommu_ddtp_modes {
 /* 5.22 Performance monitoring event counters (31 * 64bits) */
 #define RISCV_IOMMU_REG_IOHPMCTR_BASE	0x0068
 #define RISCV_IOMMU_REG_IOHPMCTR(_n)	(RISCV_IOMMU_REG_IOHPMCTR_BASE + ((_n) * 0x8))
+#define RISCV_IOMMU_IOHPMEVENT_COUNTER	GENMASK_ULL(63, 0)
 
 /* 5.23 Performance monitoring event selectors (31 * 64bits) */
 #define RISCV_IOMMU_REG_IOHPMEVT_BASE	0x0160
@@ -222,6 +223,9 @@ enum riscv_iommu_ddtp_modes {
 
 /* Number of defined performance-monitoring event selectors */
 #define RISCV_IOMMU_IOHPMEVT_CNT	31
+/* Cycles counter is statically indexed as the last counter */
+#define RISCV_IOMMU_HPMCOUNTER_CYCLES	RISCV_IOMMU_IOHPMEVT_CNT
+#define RISCV_IOMMU_HPMCOUNTER_MAX	(RISCV_IOMMU_IOHPMEVT_CNT + 1)
 
 /**
  * enum riscv_iommu_hpmevent_id - Performance-monitoring event identifier
@@ -249,6 +253,7 @@ enum riscv_iommu_hpmevent_id {
 	RISCV_IOMMU_HPMEVENT_G_WALKS    = 8,
 	RISCV_IOMMU_HPMEVENT_MAX        = 9
 };
+#define RISCV_IOMMU_HPMEVENT_CYCLES	RISCV_IOMMU_HPMEVENT_INVALID
 
 /* 5.24 Translation request IOVA (64bits) */
 #define RISCV_IOMMU_REG_TR_REQ_IOVA     0x0258
drivers/iommu/riscv/iommu-hpm.c new file +807 -0

807 lines not on this page · raw message

drivers/iommu/riscv/iommu-pci.c +11 -2
index d82d2b00904c..71407aecbf92 100644
@@ -34,6 +34,8 @@ static int riscv_iommu_pci_probe(struct pci_dev *pdev, const struct pci_device_i
 {
 	struct device *dev = &pdev->dev;
 	struct riscv_iommu_device *iommu;
+	phys_addr_t reg_phys;
+	resource_size_t reg_size;
 	int rc, vec;
 
 	rc = pcim_enable_device(pdev);
@@ -43,7 +45,9 @@ static int riscv_iommu_pci_probe(struct pci_dev *pdev, const struct pci_device_i
 	if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM))
 		return -ENODEV;
 
-	if (pci_resource_len(pdev, 0) < RISCV_IOMMU_REG_SIZE)
+	reg_phys = pci_resource_start(pdev, 0);
+	reg_size = pci_resource_len(pdev, 0);
+	if (reg_size < RISCV_IOMMU_REG_SIZE)
 		return -ENODEV;
 
 	rc = pcim_iomap_regions(pdev, BIT(0), pci_name(pdev));
@@ -56,6 +60,8 @@ static int riscv_iommu_pci_probe(struct pci_dev *pdev, const struct pci_device_i
 
 	iommu->dev = dev;
 	iommu->reg = pcim_iomap_table(pdev)[0];
+	iommu->reg_phys = reg_phys;
+	iommu->reg_size = reg_size;
 
 	pci_set_master(pdev);
 	dev_set_drvdata(dev, iommu);
@@ -91,7 +97,10 @@ static int riscv_iommu_pci_probe(struct pci_dev *pdev, const struct pci_device_i
 		riscv_iommu_writel(iommu, RISCV_IOMMU_REG_FCTL, iommu->fctl);
 	}
 
-	return riscv_iommu_init(iommu);
+	rc = riscv_iommu_init(iommu);
+	if (rc)
+		return rc;
+	return riscv_iommu_add_hpm(iommu);
 }
 
 static void riscv_iommu_pci_remove(struct pci_dev *pdev)
drivers/iommu/riscv/iommu-platform.c +7 -1
index 83a28c83f991..684bc267ac30 100644
@@ -62,6 +62,9 @@ static int riscv_iommu_platform_probe(struct platform_device *pdev)
 		return dev_err_probe(dev, PTR_ERR(iommu->reg),
 				     "could not map register region\n");
 
+	iommu->reg_phys = res->start;
+	iommu->reg_size = resource_size(res);
+
 	dev_set_drvdata(dev, iommu);
 
 	/* Check device reported capabilities / features. */
@@ -134,7 +137,10 @@ static int riscv_iommu_platform_probe(struct platform_device *pdev)
 		return dev_err_probe(dev, -ENODEV, "invalid IGS\n");
 	}
 
-	return riscv_iommu_init(iommu);
+	ret = riscv_iommu_init(iommu);
+	if (ret)
+		return ret;
+	return riscv_iommu_add_hpm(iommu);
 };
 
 static void riscv_iommu_platform_remove(struct platform_device *pdev)
drivers/iommu/riscv/iommu.h +41 -0

71 lines not on this page · raw message

Signature · 5 lines
2.43.0

This message and any attachment are confidential and may be privileged or otherwise protected from disclosure. If you are not an intended recipient of this message, please delete it and any attachment from your system and notify the sender immediately by reply e-mail. Unintended recipients should not use, copy, disclose or take any action based on this message or any information contained in this message. Emails cannot be guaranteed to be secure or error free as they can be intercepted, amended, lost or destroyed, and you should take full responsibility for security checking. 
 
本邮件及其任何附件具有保密性质,并可能受其他保护或不允许被披露给第三方。如阁下误收到本邮件,敬请立即以回复电子邮件的方式通知发件人,并将本邮件及其任何附件从阁下系统中予以删除。如阁下并非本邮件写明之收件人,敬请切勿使用、复制、披露本邮件或其任何内容,亦请切勿依本邮件或其任何内容而采取任何行动。电子邮件无法保证是一种安全和不会出现任何差错的通信方式,可能会被拦截、修改、丢失或损坏,收件人需自行负责做好安全检查。
author
#4 lore raw

PATCH 4/6 spacemit/t100: Add vendor event support for RISC-V IOMMU HPM

In reply to Lv Zheng

This patch adds mechanism to allow vendor events to be registered via device tree. This is useful to support SpacemiT T100 IOMMU where the maximum 128 event IDs should be supported by T100 IOATS.

---
 .../bindings/iommu/riscv,iommu.yaml           |  4 +
 drivers/iommu/riscv/iommu-bits.h              |  2 +-
 drivers/iommu/riscv/iommu-hpm.c               | 92 ++++++++++++++++++-
 3 files changed, 96 insertions(+), 2 deletions(-)
Documentation/devicetree/bindings/iommu/riscv,iommu.yaml +4 -0
index d4838c3b3741..b69109362b20 100644
@@ -68,6 +68,10 @@ properties:
   power-domains:
     maxItems: 1
 
+  vendor-hpm-events:
+    minItems: 1
+    maxItems: 120
+
 required:
   - compatible
   - reg
drivers/iommu/riscv/iommu-bits.h +1 -1
index f5f00386a11c..d85f2ae898dd 100644
@@ -251,7 +251,7 @@ enum riscv_iommu_hpmevent_id {
 	RISCV_IOMMU_HPMEVENT_PD_WALK    = 6,
 	RISCV_IOMMU_HPMEVENT_S_VS_WALKS = 7,
 	RISCV_IOMMU_HPMEVENT_G_WALKS    = 8,
-	RISCV_IOMMU_HPMEVENT_MAX        = 9
+	RISCV_IOMMU_HPMEVENT_MAX        = 128
 };
 #define RISCV_IOMMU_HPMEVENT_CYCLES	RISCV_IOMMU_HPMEVENT_INVALID
 
drivers/iommu/riscv/iommu-hpm.c +91 -1

111 lines not on this page · raw message

Signature · 5 lines
2.43.0

This message and any attachment are confidential and may be privileged or otherwise protected from disclosure. If you are not an intended recipient of this message, please delete it and any attachment from your system and notify the sender immediately by reply e-mail. Unintended recipients should not use, copy, disclose or take any action based on this message or any information contained in this message. Emails cannot be guaranteed to be secure or error free as they can be intercepted, amended, lost or destroyed, and you should take full responsibility for security checking. 
 
本邮件及其任何附件具有保密性质,并可能受其他保护或不允许被披露给第三方。如阁下误收到本邮件,敬请立即以回复电子邮件的方式通知发件人,并将本邮件及其任何附件从阁下系统中予以删除。如阁下并非本邮件写明之收件人,敬请切勿使用、复制、披露本邮件或其任何内容,亦请切勿依本邮件或其任何内容而采取任何行动。电子邮件无法保证是一种安全和不会出现任何差错的通信方式,可能会被拦截、修改、丢失或损坏,收件人需自行负责做好安全检查。
#5 lore raw

Re: [PATCH 4/6] spacemit/t100: Add vendor event support for RISC-V IOMMU HPM

Quoted 8 lines · Lv Zheng

This patch adds mechanism to allow vendor events to be registered via device tree. This is useful to support SpacemiT T100 IOMMU where the maximum 128 event IDs should be supported by T100 IOATS.

---
 .../bindings/iommu/riscv,iommu.yaml           |  4 +

Please run scripts/checkpatch.pl on the patches and fix reported warnings. After that, run also 'scripts/checkpatch.pl --strict' on the patches and (probably) fix more warnings. Some warnings can be ignored, especially from --strict run, but the code here looks like it needs a fix. Feel free to get in touch if the warning is not clear.

Please use scripts/get_maintainers.pl to get a list of necessary people and lists to CC (and consider --no-git-fallback argument, so you will not CC people just because they made one commit years ago). It might happen, that command when run on an older kernel, gives you outdated entries. Therefore please be sure you base your patches on recent Linux kernel.

Tools like b4 or scripts/get_maintainer.pl provide you proper list of people, so fix your workflow. Tools might also fail if you work on some ancient tree (don't, instead use mainline) or work on fork of kernel (don't, instead use mainline). Just use b4 and everything should be fine, although remember about b4 prep --auto-to-cc if you added new patches to the patchset.

Anyway, the property is NAK - does not follow any standard rules. Read docs in kernel about bindings and some DTS beginners talks/slides.

Best regards,
Krzysztof

author
#6 lore raw

Re: [PATCH 4/6] spacemit/t100: Add vendor event support for RISC-V IOMMU HPM

Hi,

Quoted 29 lines

From: "Krzysztof Kozlowski"<[email protected]>
Date:  Wed, Jan 28, 2026, 15:46
Subject:  Re: [PATCH 4/6] spacemit/t100: Add vendor event support for RISC-V IOMMU HPM
To: "Lv Zheng"<[email protected]>, "Robin Murphy"<[email protected]>, "Tomasz Jeznach"<[email protected]>
Cc: "Jingyu Li"<[email protected]>, "Zhijian Chen"<[email protected]>, <[email protected]>

Quoted 8 lines · Lv Zheng

This patch adds mechanism to allow vendor events to be registered via device tree. This is useful to support SpacemiT T100 IOMMU where the maximum 128 event IDs should be supported by T100 IOATS.

---
 .../bindings/iommu/riscv,iommu.yaml           |  4 +


Please run scripts/checkpatch.pl on the patches and fix reported warnings. After that, run also 'scripts/checkpatch.pl --strict' on the patches and (probably) fix more warnings. Some warnings can be ignored, especially from --strict run, but the code here looks like it needs a fix. Feel free to get in touch if the warning is not clear.

Please use scripts/get_maintainers.pl to get a list of necessary people and lists to CC (and consider --no-git-fallback argument, so you will not CC people just because they made one commit years ago). It might happen, that command when run on an older kernel, gives you outdated entries. Therefore please be sure you base your patches on recent Linux kernel.

Tools like b4 or scripts/get_maintainer.pl provide you proper list of

Quoted 8 lines

people, so fix your workflow. Tools might also fail if you work on some ancient tree (don't, instead use mainline) or work on fork of kernel (don't, instead use mainline). Just use b4 and everything should be fine, although remember about b4 prep --auto-to-cc if you added new patches to the patchset.

Anyway, the property is NAK - does not follow any standard rules. Read docs in kernel about bindings and some DTS beginners talks/slides.

Sure, thanks for the kind reply. Will rework and submit again.

Best regards
Lv

Quoted 3 lines

Best regards,
Krzysztof

This message and any attachment are confidential and may be privileged or otherwise protected from disclosure. If you are not an intended recipient of this message, please delete it and any attachment from your system and notify the sender immediately by reply e-mail. Unintended recipients should not use, copy, disclose or take any action based on this message or any information contained in this message. Emails cannot be guaranteed to be secure or error free as they can be intercepted, amended, lost or destroyed, and you should take full responsibility for security checking.

本邮件及其任何附件具有保密性质,并可能受其他保护或不允许被披露给第三方。如阁下误收到本邮件,敬请立即以回复电子邮件的方式通知发件人,并将本邮件及其任何附件从阁下系统中予以删除。如阁下并非本邮件写明之收件人,敬请切勿使用、复制、披露本邮件或其任何内容,亦请切勿依本邮件或其任何内容而采取任何行动。电子邮件无法保证是一种安全和不会出现任何差错的通信方式,可能会被拦截、修改、丢失或损坏,收件人需自行负责做好安全检查。

author
#7 lore raw

PATCH 5/6 spacemit/t100: Add global filter support for RISC-V IOMMU HPM

In reply to Lv Zheng

This patch introduces global filter support for RISC-V IOMMU HPM. The global filter can be seen in SpacemiT T100 which only supports single filter to be applied to all event counters. This silicon design can save the number of the event bus signals.

---
 .../bindings/iommu/riscv,iommu.yaml           |  2 +
 drivers/iommu/riscv/iommu-hpm.c               | 93 +++++++++++++++++--
 drivers/iommu/riscv/iommu.h                   |  1 +
 3 files changed, 89 insertions(+), 7 deletions(-)
Documentation/devicetree/bindings/iommu/riscv,iommu.yaml +2 -0
index b69109362b20..ec5b84ff5afb 100644
@@ -72,6 +72,8 @@ properties:
     minItems: 1
     maxItems: 120
 
+  global-filter: true
+
 required:
   - compatible
   - reg
drivers/iommu/riscv/iommu-hpm.c +86 -7

161 lines not on this page · raw message

drivers/iommu/riscv/iommu.h +1 -0
index c84391342977..bafcdc7ff356 100644
@@ -41,6 +41,7 @@ struct riscv_iommu_hpm {
 	int irq;
 	int on_cpu;
 	struct hlist_node node;
+	bool global_filter;
 	/*
 	 * Layout of events:
 	 * 0       -> HPMCYCLES
Signature · 5 lines
2.43.0

This message and any attachment are confidential and may be privileged or otherwise protected from disclosure. If you are not an intended recipient of this message, please delete it and any attachment from your system and notify the sender immediately by reply e-mail. Unintended recipients should not use, copy, disclose or take any action based on this message or any information contained in this message. Emails cannot be guaranteed to be secure or error free as they can be intercepted, amended, lost or destroyed, and you should take full responsibility for security checking. 
 
本邮件及其任何附件具有保密性质,并可能受其他保护或不允许被披露给第三方。如阁下误收到本邮件,敬请立即以回复电子邮件的方式通知发件人,并将本邮件及其任何附件从阁下系统中予以删除。如阁下并非本邮件写明之收件人,敬请切勿使用、复制、披露本邮件或其任何内容,亦请切勿依本邮件或其任何内容而采取任何行动。电子邮件无法保证是一种安全和不会出现任何差错的通信方式,可能会被拦截、修改、丢失或损坏,收件人需自行负责做好安全检查。
#8 lore raw

Re: [PATCH 5/6] spacemit/t100: Add global filter support for RISC-V IOMMU HPM

Quoted 1 line · Lv Zheng

This patch introduces global filter support for RISC-V IOMMU HPM. The

Please do not use "This commit/patch/change", but imperative mood. See longer explanation here:
https://elixir.bootlin.com/linux/v6.16/source/Documentation/process/submitting-patches.rst#L94

Quoted 17 lines

global filter can be seen in SpacemiT T100 which only supports single filter to be applied to all event counters. This silicon design can save the number of the event bus signals.

---
 .../bindings/iommu/riscv,iommu.yaml           |  2 +
 drivers/iommu/riscv/iommu-hpm.c               | 93 +++++++++++++++++--
 drivers/iommu/riscv/iommu.h                   |  1 +
 3 files changed, 89 insertions(+), 7 deletions(-)
Documentation/devicetree/bindings/iommu/riscv,iommu.yaml +0 -0
index b69109362b20..ec5b84ff5afb 100644

Documentation/devicetree/bindings/iommu/riscv,iommu.yaml properties: · line 75

Quoted 4 lines
Documentation/devicetree/bindings/iommu/riscv,iommu.yaml +1 -0
@@ -72,6 +72,8 @@ properties:
     minItems: 1
     maxItems: 120
 
+  global-filter: true

NAK, absolutely pointless and wrong code. I am not providing you full review because you did not bother to follow basic steps required from you, so essentially you waste our time.

Please run scripts/checkpatch.pl on the patches and fix reported warnings. After that, run also 'scripts/checkpatch.pl --strict' on the patches and (probably) fix more warnings. Some warnings can be ignored, especially from --strict run, but the code here looks like it needs a fix. Feel free to get in touch if the warning is not clear.

Please use scripts/get_maintainers.pl to get a list of necessary people and lists to CC (and consider --no-git-fallback argument, so you will not CC people just because they made one commit years ago). It might happen, that command when run on an older kernel, gives you outdated entries. Therefore please be sure you base your patches on recent Linux kernel.

Tools like b4 or scripts/get_maintainer.pl provide you proper list of people, so fix your workflow. Tools might also fail if you work on some ancient tree (don't, instead use mainline) or work on fork of kernel (don't, instead use mainline). Just use b4 and everything should be fine, although remember about b4 prep --auto-to-cc if you added new patches to the patchset.

Best regards,
Krzysztof

author
#9 lore raw

Re: [PATCH 5/6] spacemit/t100: Add global filter support for RISC-V IOMMU HPM

Hi,

Quoted 35 lines

From: "Krzysztof Kozlowski"<[email protected]>
Date:  Wed, Jan 28, 2026, 15:47
Subject:  Re: [PATCH 5/6] spacemit/t100: Add global filter support for RISC-V IOMMU HPM
To: "Lv Zheng"<[email protected]>, "Robin Murphy"<[email protected]>, "Tomasz Jeznach"<[email protected]>
Cc: "Jingyu Li"<[email protected]>, "Zhijian Chen"<[email protected]>, <[email protected]>

Quoted 1 line · Lv Zheng

This patch introduces global filter support for RISC-V IOMMU HPM. The


Please do not use "This commit/patch/change", but imperative mood. See longer explanation here:
https://elixir.bootlin.com/linux/v6.16/source/Documentation/process/submitting-patches.rst#L94

Quoted 17 lines

global filter can be seen in SpacemiT T100 which only supports single filter to be applied to all event counters. This silicon design can save the number of the event bus signals.

---
 .../bindings/iommu/riscv,iommu.yaml           |  2 + drivers/iommu/riscv/iommu-hpm.c               | 93 +++++++++++++++++-- drivers/iommu/riscv/iommu.h                   |  1 +

 3 files changed, 89 insertions(+), 7 deletions(-)

Documentation/devicetree/bindings/iommu/riscv,iommu.yaml +0 -0
index b69109362b20..ec5b84ff5afb 100644
@@ -72,6 +72,8 @@ properties:
Quoted 4 lines

     minItems: 1
     maxItems: 120

+  global-filter: true


NAK, absolutely pointless and wrong code. I am not providing you full

Quoted 8 lines

review because you did not bother to follow basic steps required from you, so essentially you waste our time.

Please run scripts/checkpatch.pl on the patches and fix reported warnings. After that, run also 'scripts/checkpatch.pl --strict' on the patches and (probably) fix more warnings. Some warnings can be ignored, especially from --strict run, but the code here looks like it needs a fix. Feel free to get in touch if the warning is not clear.

Thanks for the reminder.

I've been away from the community for too long time, and this is my first time submitting driver patches with DT updates required. Sorry for the basic mistakes.

Will re-work and submit again. My appologies.

Quoted 5 lines

Please use scripts/get_maintainers.pl to get a list of necessary people and lists to CC (and consider --no-git-fallback argument, so you will not CC people just because they made one commit years ago). It might happen, that command when run on an older kernel, gives you outdated entries. Therefore please be sure you base your patches on recent Linux

Quoted 8 lines

kernel.

Tools like b4 or scripts/get_maintainer.pl provide you proper list of people, so fix your workflow. Tools might also fail if you work on some ancient tree (don't, instead use mainline) or work on fork of kernel (don't, instead use mainline). Just use b4 and everything should be fine, although remember about b4 prep --auto-to-cc if you added new patches to the patchset.

Sure. Will loop to Will and Joerg in and probably with perf community included for acknowledgement.

Best regards
Lv

Quoted 5 lines



Best regards,
Krzysztof

This message and any attachment are confidential and may be privileged or otherwise protected from disclosure. If you are not an intended recipient of this message, please delete it and any attachment from your system and notify the sender immediately by reply e-mail. Unintended recipients should not use, copy, disclose or take any action based on this message or any information contained in this message. Emails cannot be guaranteed to be secure or error free as they can be intercepted, amended, lost or destroyed, and you should take full responsibility for security checking.

本邮件及其任何附件具有保密性质,并可能受其他保护或不允许被披露给第三方。如阁下误收到本邮件,敬请立即以回复电子邮件的方式通知发件人,并将本邮件及其任何附件从阁下系统中予以删除。如阁下并非本邮件写明之收件人,敬请切勿使用、复制、披露本邮件或其任何内容,亦请切勿依本邮件或其任何内容而采取任何行动。电子邮件无法保证是一种安全和不会出现任何差错的通信方式,可能会被拦截、修改、丢失或损坏,收件人需自行负责做好安全检查。

author
#10 lore raw

PATCH 6/6 spacemit/t100: Add SpacemiT T100 IOATC HPM support

In reply to Lv Zheng

This patch adds IOATC discovery and HPM support for SpacemiT T100.

SpacemiT T100 supports distributed architecture which allows IOTLBs to be cached in adjacent to the DMA masters. Such IOTLBs controllers are called as IOATC, this patch adds distributed HPM support for IOATCs.

---
 drivers/iommu/riscv/iommu-bits.h     |  12 ++
 drivers/iommu/riscv/iommu-hpm.c      | 173 ++++++++++++++++++++++++++-
 drivers/iommu/riscv/iommu-platform.c |   4 +-
 drivers/iommu/riscv/iommu.h          |   2 +-
 4 files changed, 184 insertions(+), 7 deletions(-)
drivers/iommu/riscv/iommu-bits.h +12 -0
index d85f2ae898dd..b62869c906be 100644
@@ -283,6 +283,18 @@ enum riscv_iommu_hpmevent_id {
 #define RISCV_IOMMU_ICVEC_PMIV		GENMASK_ULL(11, 8)
 #define RISCV_IOMMU_ICVEC_PIV		GENMASK_ULL(15, 12)
 
+/* 5.28 Distributed translation interface status register (dtisr0-3) (4 * 32-bits) */
+#define RISCV_IOMMU_REG_DTISR_BASE	0x02B0
+#define RISCV_IOMMU_REG_DTISR(_n)	(RISCV_IOMMU_REG_DTISR_BASE + ((_n) * 0x04))
+#define RISCV_IOMMU_DTI_STS_SHIFT(_n)	(((_n) % 16) * 2)
+#define RISCV_IOMMU_DTI_STS_MASK(_n)	(0x3 << RISCV_IOMMU_DTI_STS_SHIFT(_n))
+#define RISCV_IOMMU_DTI_STS_NONE	0x0
+#define RISCV_IOMMU_DTI_STS_TBU_IOATC	0x1
+
+#define MAX_RISCV_IOMMU_IOATC		64
+#define RISCV_IOMMU_IOATC_BASE(_base, _idx) \
+	((void __iomem *)((u8 __iomem *)(_base) + ((_idx) + 1) * RISCV_IOMMU_REG_SIZE))
+
 /* 5.28 MSI Configuration table (32 * 64bits) */
 #define RISCV_IOMMU_REG_MSI_CFG_TBL	0x0300
 #define RISCV_IOMMU_REG_MSI_CFG_TBL_ADDR(_n) \
drivers/iommu/riscv/iommu-hpm.c +169 -4

228 lines not on this page · raw message

drivers/iommu/riscv/iommu-platform.c +2 -2
index 684bc267ac30..ca8de9ec5266 100644
@@ -75,8 +75,8 @@ static int riscv_iommu_platform_probe(struct platform_device *pdev)
 	if (iommu->irqs_count <= 0)
 		return dev_err_probe(dev, -ENODEV,
 				     "no IRQ resources provided\n");
-	if (iommu->irqs_count > RISCV_IOMMU_INTR_COUNT)
-		iommu->irqs_count = RISCV_IOMMU_INTR_COUNT;
+	if (iommu->irqs_count > RISCV_IOMMU_INTR_COUNT + MAX_RISCV_IOMMU_IOATC)
+		iommu->irqs_count = RISCV_IOMMU_INTR_COUNT + MAX_RISCV_IOMMU_IOATC;
 
 	igs = FIELD_GET(RISCV_IOMMU_CAPABILITIES_IGS, iommu->caps);
 	switch (igs) {
drivers/iommu/riscv/iommu.h +1 -1
index bafcdc7ff356..ba80de1bd19c 100644
@@ -75,7 +75,7 @@ struct riscv_iommu_device {
 	u32 fctl;
 
 	/* available interrupt numbers, MSI or WSI */
-	unsigned int irqs[RISCV_IOMMU_INTR_COUNT];
+	unsigned int irqs[RISCV_IOMMU_INTR_COUNT + MAX_RISCV_IOMMU_IOATC];
 	unsigned int irqs_count;
 	unsigned int icvec;
 
Signature · 5 lines
2.43.0

This message and any attachment are confidential and may be privileged or otherwise protected from disclosure. If you are not an intended recipient of this message, please delete it and any attachment from your system and notify the sender immediately by reply e-mail. Unintended recipients should not use, copy, disclose or take any action based on this message or any information contained in this message. Emails cannot be guaranteed to be secure or error free as they can be intercepted, amended, lost or destroyed, and you should take full responsibility for security checking. 
 
本邮件及其任何附件具有保密性质,并可能受其他保护或不允许被披露给第三方。如阁下误收到本邮件,敬请立即以回复电子邮件的方式通知发件人,并将本邮件及其任何附件从阁下系统中予以删除。如阁下并非本邮件写明之收件人,敬请切勿使用、复制、披露本邮件或其任何内容,亦请切勿依本邮件或其任何内容而采取任何行动。电子邮件无法保证是一种安全和不会出现任何差错的通信方式,可能会被拦截、修改、丢失或损坏,收件人需自行负责做好安全检查。
author
#11 lore raw

cover iommu/riscv: Add HPM support for RISC-V IOMMU

In reply to Lv Zheng

Includes HPM support for RISC-V IOMMU. The HPM hardware mechnism can be found in the recent announced SpacemiT SoCs (K3, V100), where T100 (SpacemiT distributed IOMMU) is shipped.

The tested result can be found as follows:

 root@sdfirm:~# perf stat --timeout 5000 -a -e riscv_iommu_hpm_0/device_dir_walks,config1=0x20c0010000000000/ dmatest; sleep 1
 [  176.110211] dmatest: Started 1 threads using dma0chan0
 [  176.114933] dmatest: dma0chan0-copy0: summary 1 tests, 0 failures 394.94 iops 394 KB/s (0)

Performance counter stats for 'system wide':

                  3      riscv_iommu_hpm_0/device_dir_walks,config1=0x20c0010000000000/                                   
 
        0.081056000 seconds time elapsed
 root@sdfirm:~# perf stat --timeout 5000 -a -e riscv_iommu_hpm_0/s_stage_walks,config1=0x20c0010000000000/ dmatest; sleep 1
 [   68.152992] dmatest: Started 1 threads using dma0chan0
 [   68.158071] dmatest: dma0chan0-copy0: summary 1 tests, 0 failures 401.92 iops 401 KB/s (0)

Performance counter stats for 'system wide':

                  6      riscv_iommu_hpm_0/s_stage_walks,config1=0x20c0010000000000/                                   
 
        0.083192000 seconds time elapsed

Jingyu Li (3):
iommu/riscv: Enable IOMMU DMA mapping support iommu/riscv: Fix WSI mode IRQ number handling iommu/riscv: Add HPM support for performance monitoring

Lv Zheng (4):
dt-bindings: iommu: Add spacemit/t100 features spacemit/t100: Add vendor event support for RISC-V IOMMU HPM spacemit/t100: Add global filter support for RISC-V IOMMU HPM spacemit/t100: Add SpacemiT T100 IOATC HPM support

 .../bindings/iommu/riscv,iommu.yaml           |   60 +-
 drivers/iommu/Kconfig                         |    2 +-
 drivers/iommu/riscv/Kconfig                   |    9 +
 drivers/iommu/riscv/Makefile                  |    1 +
 drivers/iommu/riscv/iommu-bits.h              |   20 +-
 drivers/iommu/riscv/iommu-hpm.c               | 1135 +++++++++++++++++
 drivers/iommu/riscv/iommu-pci.c               |   13 +-
 drivers/iommu/riscv/iommu-platform.c          |   12 +-
 drivers/iommu/riscv/iommu.c                   |   25 +-
 drivers/iommu/riscv/iommu.h                   |   45 +-
 10 files changed, 1308 insertions(+), 14 deletions(-)
 create mode 100644 drivers/iommu/riscv/iommu-hpm.c
Signature · 5 lines
2.43.0

This message and any attachment are confidential and may be privileged or otherwise protected from disclosure. If you are not an intended recipient of this message, please delete it and any attachment from your system and notify the sender immediately by reply e-mail. Unintended recipients should not use, copy, disclose or take any action based on this message or any information contained in this message. Emails cannot be guaranteed to be secure or error free as they can be intercepted, amended, lost or destroyed, and you should take full responsibility for security checking. 
 
本邮件及其任何附件具有保密性质,并可能受其他保护或不允许被披露给第三方。如阁下误收到本邮件,敬请立即以回复电子邮件的方式通知发件人,并将本邮件及其任何附件从阁下系统中予以删除。如阁下并非本邮件写明之收件人,敬请切勿使用、复制、披露本邮件或其任何内容,亦请切勿依本邮件或其任何内容而采取任何行动。电子邮件无法保证是一种安全和不会出现任何差错的通信方式,可能会被拦截、修改、丢失或损坏,收件人需自行负责做好安全检查。
author
#12 lore raw

PATCH 1/7 iommu/riscv: Enable IOMMU DMA mapping support

From: Jingyu Li <[email protected]>

Enables IOMMU DMA mapping support for RISC-V, so that DMACs can be tested with translation enabled.

Known Issue:
1. When CONFIG_IOMMU_DMA is enabled, current Linux RISC-V IOMMU is lack of PCIe support, causing riscv_iommu_fault:522 in dealing with NVMe PCIe devices.

---
 drivers/iommu/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iommu/Kconfig +1 -1
index f86262b11416..34d8a792339f 100644
@@ -151,7 +151,7 @@ config OF_IOMMU
 
 # IOMMU-agnostic DMA-mapping layer
 config IOMMU_DMA
-	def_bool ARM64 || X86 || S390
+	def_bool ARM64 || X86 || S390 || RISCV
 	select DMA_OPS_HELPERS
 	select IOMMU_API
 	select IOMMU_IOVA
Signature · 5 lines
2.43.0

This message and any attachment are confidential and may be privileged or otherwise protected from disclosure. If you are not an intended recipient of this message, please delete it and any attachment from your system and notify the sender immediately by reply e-mail. Unintended recipients should not use, copy, disclose or take any action based on this message or any information contained in this message. Emails cannot be guaranteed to be secure or error free as they can be intercepted, amended, lost or destroyed, and you should take full responsibility for security checking. 
 
本邮件及其任何附件具有保密性质,并可能受其他保护或不允许被披露给第三方。如阁下误收到本邮件,敬请立即以回复电子邮件的方式通知发件人,并将本邮件及其任何附件从阁下系统中予以删除。如阁下并非本邮件写明之收件人,敬请切勿使用、复制、披露本邮件或其任何内容,亦请切勿依本邮件或其任何内容而采取任何行动。电子邮件无法保证是一种安全和不会出现任何差错的通信方式,可能会被拦截、修改、丢失或损坏,收件人需自行负责做好安全检查。
author
#13 lore raw

PATCH 2/7 iommu/riscv: Fix WSI mode IRQ number handling

In reply to Lv Zheng

From: Jingyu Li <[email protected]>

In WSI mode, ICVEC doesn't exist, thus reading it returns 0, which causes IOMMU driver to fail to find IRQ numbers from device tree IRQ arrary. The issue is fixed by applying icvec indexes of WSI IRQs.

---
 drivers/iommu/riscv/iommu.c | 25 ++++++++++++++++++++-----
 1 file changed, 20 insertions(+), 5 deletions(-)
drivers/iommu/riscv/iommu.c +20 -5
index d9429097a2b5..26630979473b 100644
@@ -1593,11 +1593,26 @@ static int riscv_iommu_init_check(struct riscv_iommu_device *iommu)
 		       FIELD_PREP(RISCV_IOMMU_ICVEC_PMIV, 3 % iommu->irqs_count);
 	riscv_iommu_writeq(iommu, RISCV_IOMMU_REG_ICVEC, iommu->icvec);
 	iommu->icvec = riscv_iommu_readq(iommu, RISCV_IOMMU_REG_ICVEC);
-	if (max(max(FIELD_GET(RISCV_IOMMU_ICVEC_CIV, iommu->icvec),
-		    FIELD_GET(RISCV_IOMMU_ICVEC_FIV, iommu->icvec)),
-		max(FIELD_GET(RISCV_IOMMU_ICVEC_PIV, iommu->icvec),
-		    FIELD_GET(RISCV_IOMMU_ICVEC_PMIV, iommu->icvec))) >= iommu->irqs_count)
-		return -EINVAL;
+	/*
+	 * In WSI mode, ICVEC may read as zero. Only validate if using MSI.
+	 * Check if FCTL.WSI is set to determine interrupt mode.
+	 */
+	if (!(iommu->fctl & RISCV_IOMMU_FCTL_WSI)) {
+		if (max(max(FIELD_GET(RISCV_IOMMU_ICVEC_CIV, iommu->icvec),
+			    FIELD_GET(RISCV_IOMMU_ICVEC_FIV, iommu->icvec)),
+			max(FIELD_GET(RISCV_IOMMU_ICVEC_PIV, iommu->icvec),
+			    FIELD_GET(RISCV_IOMMU_ICVEC_PMIV, iommu->icvec))) >= iommu->irqs_count)
+			return -EINVAL;
+	} else {
+		/*
+		 * WSI mode: ICVEC is not used. Set to identity mapping for
+		 * riscv_iommu_queue_vec() to work correctly.
+		 */
+		iommu->icvec = FIELD_PREP(RISCV_IOMMU_ICVEC_CIV, 0) |
+			       FIELD_PREP(RISCV_IOMMU_ICVEC_FIV, 1) |
+			       FIELD_PREP(RISCV_IOMMU_ICVEC_PIV, 2) |
+			       FIELD_PREP(RISCV_IOMMU_ICVEC_PMIV, 3);
+	}
 
 	return 0;
 }
Signature · 5 lines
2.43.0

This message and any attachment are confidential and may be privileged or otherwise protected from disclosure. If you are not an intended recipient of this message, please delete it and any attachment from your system and notify the sender immediately by reply e-mail. Unintended recipients should not use, copy, disclose or take any action based on this message or any information contained in this message. Emails cannot be guaranteed to be secure or error free as they can be intercepted, amended, lost or destroyed, and you should take full responsibility for security checking. 
 
本邮件及其任何附件具有保密性质,并可能受其他保护或不允许被披露给第三方。如阁下误收到本邮件,敬请立即以回复电子邮件的方式通知发件人,并将本邮件及其任何附件从阁下系统中予以删除。如阁下并非本邮件写明之收件人,敬请切勿使用、复制、披露本邮件或其任何内容,亦请切勿依本邮件或其任何内容而采取任何行动。电子邮件无法保证是一种安全和不会出现任何差错的通信方式,可能会被拦截、修改、丢失或损坏,收件人需自行负责做好安全检查。
author
#14 lore raw

PATCH 3/7 iommu/riscv: Add HPM support for performance monitoring

In reply to Lv Zheng

From: Jingyu Li <[email protected]>

Introduces perf-based HPM driver for RISC-V IOMMU, enabling performance monitoring capabilities.

Note that the RISC-V IOMMU HPM module uses COUNTER_MAX-1 as a static counter index of HPMCYCLES, and 0~COUNTER_MAX-2 as the dynamic counter indexes of other HPMEVENTS in order to correctly index into IOHPMEVT and IOHPMCTR registers that have already been defined in the iommu-bits.h. However the users treat 0 as the index of HPMCYCLES and 1~COUNTER_MAX-1 as the indexes of other HPMEVENTS, thus care should be taken in dealing with counter indexes between userspace and kernel space.

---
 drivers/iommu/riscv/Kconfig          |   9 +
 drivers/iommu/riscv/Makefile         |   1 +
 drivers/iommu/riscv/iommu-bits.h     |   6 +
 drivers/iommu/riscv/iommu-hpm.c      | 799 +++++++++++++++++++++++++++
 drivers/iommu/riscv/iommu-pci.c      |  13 +-
 drivers/iommu/riscv/iommu-platform.c |   8 +-
 drivers/iommu/riscv/iommu.h          |  42 ++
 7 files changed, 875 insertions(+), 3 deletions(-)
 create mode 100644 drivers/iommu/riscv/iommu-hpm.c
drivers/iommu/riscv/Kconfig +9 -0
index c071816f59a6..2d06a1ef11c9 100644
@@ -18,3 +18,12 @@ config RISCV_IOMMU_PCI
 	def_bool y if RISCV_IOMMU && PCI_MSI
 	help
 	  Support for the PCIe implementation of RISC-V IOMMU architecture.
+
+config RISCV_IOMMU_HPM
+	tristate "RISCV IOMMU HPM support"
+	depends on RISCV_IOMMU
+	help
+	  Provides support for the RISC-V IOMMU Hardware Performance Monitor
+	  (HPM), which provide monitoring of transactions passing through the
+	  IOMMU and allow the resulting information to be filtered based on
+	  the device/process ID of the corresponding master.
drivers/iommu/riscv/Makefile +1 -0
index b5929f9f23e6..53db3ef62bdd 100644
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-y += iommu.o iommu-platform.o
 obj-$(CONFIG_RISCV_IOMMU_PCI) += iommu-pci.o
+obj-$(CONFIG_RISCV_IOMMU_HPM) += iommu-hpm.o
drivers/iommu/riscv/iommu-bits.h +6 -0
index 98daf0e1a306..cc6bea064d8f 100644
@@ -207,6 +207,7 @@ enum riscv_iommu_ddtp_modes {
 /* 5.22 Performance monitoring event counters (31 * 64bits) */
 #define RISCV_IOMMU_REG_IOHPMCTR_BASE	0x0068
 #define RISCV_IOMMU_REG_IOHPMCTR(_n)	(RISCV_IOMMU_REG_IOHPMCTR_BASE + ((_n) * 0x8))
+#define RISCV_IOMMU_IOHPMEVENT_COUNTER	GENMASK_ULL(63, 0)
 
 /* 5.23 Performance monitoring event selectors (31 * 64bits) */
 #define RISCV_IOMMU_REG_IOHPMEVT_BASE	0x0160
@@ -222,6 +223,9 @@ enum riscv_iommu_ddtp_modes {
 
 /* Number of defined performance-monitoring event selectors */
 #define RISCV_IOMMU_IOHPMEVT_CNT	31
+/* Cycles counter is statically indexed as the last counter */
+#define RISCV_IOMMU_HPMCOUNTER_CYCLES	RISCV_IOMMU_IOHPMEVT_CNT
+#define RISCV_IOMMU_HPMCOUNTER_MAX	(RISCV_IOMMU_IOHPMEVT_CNT + 1)
 
 /**
  * enum riscv_iommu_hpmevent_id - Performance-monitoring event identifier
@@ -250,6 +254,8 @@ enum riscv_iommu_hpmevent_id {
 	RISCV_IOMMU_HPMEVENT_MAX        = 9
 };
 
+#define RISCV_IOMMU_HPMEVENT_CYCLES	RISCV_IOMMU_HPMEVENT_INVALID
+
 /* 5.24 Translation request IOVA (64bits) */
 #define RISCV_IOMMU_REG_TR_REQ_IOVA     0x0258
 #define RISCV_IOMMU_TR_REQ_IOVA_VPN	GENMASK_ULL(63, 12)
drivers/iommu/riscv/iommu-hpm.c new file +799 -0

799 lines not on this page · raw message

drivers/iommu/riscv/iommu-pci.c +11 -2
index d82d2b00904c..71407aecbf92 100644
@@ -34,6 +34,8 @@ static int riscv_iommu_pci_probe(struct pci_dev *pdev, const struct pci_device_i
 {
 	struct device *dev = &pdev->dev;
 	struct riscv_iommu_device *iommu;
+	phys_addr_t reg_phys;
+	resource_size_t reg_size;
 	int rc, vec;
 
 	rc = pcim_enable_device(pdev);
@@ -43,7 +45,9 @@ static int riscv_iommu_pci_probe(struct pci_dev *pdev, const struct pci_device_i
 	if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM))
 		return -ENODEV;
 
-	if (pci_resource_len(pdev, 0) < RISCV_IOMMU_REG_SIZE)
+	reg_phys = pci_resource_start(pdev, 0);
+	reg_size = pci_resource_len(pdev, 0);
+	if (reg_size < RISCV_IOMMU_REG_SIZE)
 		return -ENODEV;
 
 	rc = pcim_iomap_regions(pdev, BIT(0), pci_name(pdev));
@@ -56,6 +60,8 @@ static int riscv_iommu_pci_probe(struct pci_dev *pdev, const struct pci_device_i
 
 	iommu->dev = dev;
 	iommu->reg = pcim_iomap_table(pdev)[0];
+	iommu->reg_phys = reg_phys;
+	iommu->reg_size = reg_size;
 
 	pci_set_master(pdev);
 	dev_set_drvdata(dev, iommu);
@@ -91,7 +97,10 @@ static int riscv_iommu_pci_probe(struct pci_dev *pdev, const struct pci_device_i
 		riscv_iommu_writel(iommu, RISCV_IOMMU_REG_FCTL, iommu->fctl);
 	}
 
-	return riscv_iommu_init(iommu);
+	rc = riscv_iommu_init(iommu);
+	if (rc)
+		return rc;
+	return riscv_iommu_add_hpm(iommu);
 }
 
 static void riscv_iommu_pci_remove(struct pci_dev *pdev)
drivers/iommu/riscv/iommu-platform.c +7 -1
index 83a28c83f991..684bc267ac30 100644
@@ -62,6 +62,9 @@ static int riscv_iommu_platform_probe(struct platform_device *pdev)
 		return dev_err_probe(dev, PTR_ERR(iommu->reg),
 				     "could not map register region\n");
 
+	iommu->reg_phys = res->start;
+	iommu->reg_size = resource_size(res);
+
 	dev_set_drvdata(dev, iommu);
 
 	/* Check device reported capabilities / features. */
@@ -134,7 +137,10 @@ static int riscv_iommu_platform_probe(struct platform_device *pdev)
 		return dev_err_probe(dev, -ENODEV, "invalid IGS\n");
 	}
 
-	return riscv_iommu_init(iommu);
+	ret = riscv_iommu_init(iommu);
+	if (ret)
+		return ret;
+	return riscv_iommu_add_hpm(iommu);
 };
 
 static void riscv_iommu_platform_remove(struct platform_device *pdev)
drivers/iommu/riscv/iommu.h +42 -0

72 lines not on this page · raw message

Signature · 5 lines
2.43.0

This message and any attachment are confidential and may be privileged or otherwise protected from disclosure. If you are not an intended recipient of this message, please delete it and any attachment from your system and notify the sender immediately by reply e-mail. Unintended recipients should not use, copy, disclose or take any action based on this message or any information contained in this message. Emails cannot be guaranteed to be secure or error free as they can be intercepted, amended, lost or destroyed, and you should take full responsibility for security checking. 
 
本邮件及其任何附件具有保密性质,并可能受其他保护或不允许被披露给第三方。如阁下误收到本邮件,敬请立即以回复电子邮件的方式通知发件人,并将本邮件及其任何附件从阁下系统中予以删除。如阁下并非本邮件写明之收件人,敬请切勿使用、复制、披露本邮件或其任何内容,亦请切勿依本邮件或其任何内容而采取任何行动。电子邮件无法保证是一种安全和不会出现任何差错的通信方式,可能会被拦截、修改、丢失或损坏,收件人需自行负责做好安全检查。
author
#15 lore raw

PATCH 4/7 dt-bindings: iommu: Add spacemit/t100 features

In reply to Lv Zheng

Adds device tree bindings for SpacemiT T100 specific features.

vendor-hpm-events: Allow vendor events to be customized in the device
tree.
global-filter: The feature saves silicon area by reducing filters to
one and use it as a global filter across all events. This usually is sufficient for real applications.

---
 .../bindings/iommu/riscv,iommu.yaml           | 60 ++++++++++++++++++-
 1 file changed, 59 insertions(+), 1 deletion(-)
Documentation/devicetree/bindings/iommu/riscv,iommu.yaml +59 -1
index d4838c3b3741..0378eef1f34e 100644
@@ -57,17 +57,42 @@ properties:
 
   interrupts:
     minItems: 1
-    maxItems: 4
+    maxItems: 68
     description:
       Wired interrupt vectors available for RISC-V IOMMU to notify the
       RISC-V HARTS. The cause to interrupt vector is software defined
       using IVEC IOMMU register.
+      Normally the number of interrupt vectors available is 4 for IOATS
+      civ/fiv/pmiv/piv interrupts. But for SpacemiT distributed IOMMU,
+      the number of interrupt vectors includes IOATC pmiv wired
+      interrupts and the maximum number of IOATCs can be up to 64.
+
+  interrupt-names:
+    minItems: 1
+    maxItems: 68
 
   msi-parent: true
 
   power-domains:
     maxItems: 1
 
+  vendor-hpm-events:
+    minItems: 1
+    maxItems: 120
+    description:
+      Each item defines a vendor specific event using the format of
+      "eventId[:eventName]", where the eventId is an integer filling the
+      eventID field of the iohpmevt register and the eventName is an
+      optional string used as the annotation of the event instead of the
+      default name "eventId".
+    $ref: /schemas/types.yaml#/definitions/string-array
+
+  global-filter:
+    type: boolean
+    description:
+      Indicate the filters programmed across iohpmevt registers are wired
+      together in hardware as a global filter applied to all HPM events.
+
 required:
   - compatible
   - reg
@@ -145,3 +170,36 @@ examples:
             };
         };
     };
+
+  - |+
+    /* Example 5 (SpacemiT distributed IOMMU) */
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    iommu4: iommu@1bccd000 {
+        compatible = "qemu,riscv-iommu", "riscv,iommu";
+        reg = <0x1bccd000 0x1000>;
+        interrupts = <58 IRQ_TYPE_LEVEL_HIGH>, <58 IRQ_TYPE_LEVEL_HIGH>,
+                     <58 IRQ_TYPE_LEVEL_HIGH>, <58 IRQ_TYPE_LEVEL_HIGH>,
+                     <62 IRQ_TYPE_LEVEL_HIGH>, <63 IRQ_TYPE_LEVEL_HIGH>;
+        interrupt-names = "civ", "fiv", "ioats-pmiv", "piv",
+                          "ioatc0-pmiv", "ioatc1-pmiv";
+        interrupt-parent = <&saplic>;
+        #iommu-cells = <0x01>;
+        /* SpacemiT T100 features */
+        global-filter;
+        vendor-hpm-events = "0x10:pri_page_reqs",
+                            "0x11:ptw_cache_reqs",
+                            "0x12:dtw_cache_reqs",
+                            "0x15:all_trans_reqs",
+                            "0x20:dtw_cache_lkps",
+                            "0x28:s1l0_ptw_cache_lkps",
+                            "0x2A:s1l1_ptw_cache_lkps",
+                            "0x2C:s1l2_ptw_cache_lkps",
+                            "0x2E:s1l3_ptw_cache_lkps",
+                            "0x30:s2l0_ptw_cache_lkps",
+                            "0x32:s2l1_ptw_cache_lkps",
+                            "0x34:s2l2_ptw_cache_lkps",
+                            "0x36:s2l3_ptw_cache_lkps",
+                            "0x38:mtlb_lkps",
+                            "0x3A:utlb_lkps";
+    };
Signature · 5 lines
2.43.0

This message and any attachment are confidential and may be privileged or otherwise protected from disclosure. If you are not an intended recipient of this message, please delete it and any attachment from your system and notify the sender immediately by reply e-mail. Unintended recipients should not use, copy, disclose or take any action based on this message or any information contained in this message. Emails cannot be guaranteed to be secure or error free as they can be intercepted, amended, lost or destroyed, and you should take full responsibility for security checking. 
 
本邮件及其任何附件具有保密性质,并可能受其他保护或不允许被披露给第三方。如阁下误收到本邮件,敬请立即以回复电子邮件的方式通知发件人,并将本邮件及其任何附件从阁下系统中予以删除。如阁下并非本邮件写明之收件人,敬请切勿使用、复制、披露本邮件或其任何内容,亦请切勿依本邮件或其任何内容而采取任何行动。电子邮件无法保证是一种安全和不会出现任何差错的通信方式,可能会被拦截、修改、丢失或损坏,收件人需自行负责做好安全检查。
#16 lore raw

Re: [PATCH v1.1 4/7] dt-bindings: iommu: Add spacemit/t100 features

Quoted 7 lines · Lv Zheng

Adds device tree bindings for SpacemiT T100 specific features.

vendor-hpm-events: Allow vendor events to be customized in the device
tree.
global-filter: The feature saves silicon area by reducing filters to
one and use it as a global filter across all events. This usually is sufficient for real applications.

Why can these not be determined from a device specific compatible?

Quoted 14 lines
---
 .../bindings/iommu/riscv,iommu.yaml           | 60 ++++++++++++++++++-
 1 file changed, 59 insertions(+), 1 deletion(-)
Documentation/devicetree/bindings/iommu/riscv,iommu.yaml +0 -0
index d4838c3b3741..0378eef1f34e 100644
@@ -57,17 +57,42 @@ properties:
 
   interrupts:
     minItems: 1

Documentation/devicetree/bindings/iommu/riscv,iommu.yaml properties: · line 68

Quoted 10 lines
Documentation/devicetree/bindings/iommu/riscv,iommu.yaml +5 -1
-    maxItems: 4
+    maxItems: 68
     description:
       Wired interrupt vectors available for RISC-V IOMMU to notify the
       RISC-V HARTS. The cause to interrupt vector is software defined
       using IVEC IOMMU register.
+      Normally the number of interrupt vectors available is 4 for IOATS
+      civ/fiv/pmiv/piv interrupts. But for SpacemiT distributed IOMMU,
+      the number of interrupt vectors includes IOATC pmiv wired
+      interrupts and the maximum number of IOATCs can be up to 64.

The extension to 68 should only be permitted for a soc-specific compatible.

Quoted 31 lines
Documentation/devicetree/bindings/iommu/riscv,iommu.yaml +21 -0
+
+  interrupt-names:
+    minItems: 1
+    maxItems: 68
 
   msi-parent: true
 
   power-domains:
     maxItems: 1
 
+  vendor-hpm-events:
+    minItems: 1
+    maxItems: 120
+    description:
+      Each item defines a vendor specific event using the format of
+      "eventId[:eventName]", where the eventId is an integer filling the
+      eventID field of the iohpmevt register and the eventName is an
+      optional string used as the annotation of the event instead of the
+      default name "eventId".
+    $ref: /schemas/types.yaml#/definitions/string-array
+
+  global-filter:
+    type: boolean
+    description:
+      Indicate the filters programmed across iohpmevt registers are wired
+      together in hardware as a global filter applied to all HPM events.
+
 required:
   - compatible
   - reg

Documentation/devicetree/bindings/iommu/riscv,iommu.yaml examples: · line 179

Quoted 10 lines
Documentation/devicetree/bindings/iommu/riscv,iommu.yaml +7 -0
@@ -145,3 +170,36 @@ examples:
             };
         };
     };
+
+  - |+
+    /* Example 5 (SpacemiT distributed IOMMU) */
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    iommu4: iommu@1bccd000 {
+        compatible = "qemu,riscv-iommu", "riscv,iommu";

You cannot use the qemu compatible for your device, you must use a specific one for the spacemit k3.

Also, why is your version "v1.1"? That should just be "v1", and your next version "v2" etc.

pw-bot: changes-requested

Cheers,
Conor.

Quoted 32 lines
Documentation/devicetree/bindings/iommu/riscv,iommu.yaml +26 -0
+        reg = <0x1bccd000 0x1000>;
+        interrupts = <58 IRQ_TYPE_LEVEL_HIGH>, <58 IRQ_TYPE_LEVEL_HIGH>,
+                     <58 IRQ_TYPE_LEVEL_HIGH>, <58 IRQ_TYPE_LEVEL_HIGH>,
+                     <62 IRQ_TYPE_LEVEL_HIGH>, <63 IRQ_TYPE_LEVEL_HIGH>;
+        interrupt-names = "civ", "fiv", "ioats-pmiv", "piv",
+                          "ioatc0-pmiv", "ioatc1-pmiv";
+        interrupt-parent = <&saplic>;
+        #iommu-cells = <0x01>;
+        /* SpacemiT T100 features */
+        global-filter;
+        vendor-hpm-events = "0x10:pri_page_reqs",
+                            "0x11:ptw_cache_reqs",
+                            "0x12:dtw_cache_reqs",
+                            "0x15:all_trans_reqs",
+                            "0x20:dtw_cache_lkps",
+                            "0x28:s1l0_ptw_cache_lkps",
+                            "0x2A:s1l1_ptw_cache_lkps",
+                            "0x2C:s1l2_ptw_cache_lkps",
+                            "0x2E:s1l3_ptw_cache_lkps",
+                            "0x30:s2l0_ptw_cache_lkps",
+                            "0x32:s2l1_ptw_cache_lkps",
+                            "0x34:s2l2_ptw_cache_lkps",
+                            "0x36:s2l3_ptw_cache_lkps",
+                            "0x38:mtlb_lkps",
+                            "0x3A:utlb_lkps";
+    };
Signature · 5 lines
2.43.0

This message and any attachment are confidential and may be privileged or otherwise protected from disclosure. If you are not an intended recipient of this message, please delete it and any attachment from your system and notify the sender immediately by reply e-mail. Unintended recipients should not use, copy, disclose or take any action based on this message or any information contained in this message. Emails cannot be guaranteed to be secure or error free as they can be intercepted, amended, lost or destroyed, and you should take full responsibility for security checking. 
 
本邮件及其任何附件具有保密性质,并可能受其他保护或不允许被披露给第三方。如阁下误收到本邮件,敬请立即以回复电子邮件的方式通知发件人,并将本邮件及其任何附件从阁下系统中予以删除。如阁下并非本邮件写明之收件人,敬请切勿使用、复制、披露本邮件或其任何内容,亦请切勿依本邮件或其任何内容而采取任何行动。电子邮件无法保证是一种安全和不会出现任何差错的通信方式,可能会被拦截、修改、丢失或损坏,收件人需自行负责做好安全检查。
author
#17 lore raw

Re: [PATCH v1.1 4/7] dt-bindings: iommu: Add spacemit/t100 features

Quoted 13 lines

From: "Conor Dooley"<[email protected]>
Date:  Thu, Jan 29, 2026, 18:08
Subject:  Re: [PATCH v1.1 4/7] dt-bindings: iommu: Add spacemit/t100 features
To: "Lv Zheng"<[email protected]>
Cc: "Tomasz Jeznach"<[email protected]>, "Joerg Roedel"<[email protected]>, "Will Deacon"<[email protected]>, "Robin Murphy"<[email protected]>, "Rob Herring"<[email protected]>, "Krzysztof Kozlowski"<[email protected]>, "Conor Dooley"<[email protected]>, "Paul Walmsley"<[email protected]>, "Palmer Dabbelt"<[email protected]>, "Albert Ou"<[email protected]>, "Alexandre Ghiti"<[email protected]>, "Jingyu Li"<[email protected]>, "Zhijian Chen"<[email protected]>, <[email protected]>, <[email protected]>, <[email protected]>, <[email protected]>, <[email protected]>

Quoted 7 lines · Lv Zheng

Adds device tree bindings for SpacemiT T100 specific features.
vendor-hpm-events: Allow vendor events to be customized in the device tree.
global-filter: The feature saves silicon area by reducing filters to one and use it as a global filter across all events. This usually is sufficient for real applications.

Quoted 2 lines


Why can these not be determined from a device specific compatible?

The specification only defines less than 10 standard event types while the real silicons should have implemented many other event types based on their micro-architecture. I tried to provide a common mechanism for all vendor specific event types across different vendors.

It is similar for the global filter, the global filter mechanism actually complies to the IOMMU specification, users can alter the iohpmevt registers as is what is specified in the IOMMU specification. It only provides slight application difference between the final effection. Thus this could also be a non-device specific option.

Quoted 20 lines

Quoted 19 lines

---
 .../bindings/iommu/riscv,iommu.yaml           | 60 ++++++++++++++++++-

 1 file changed, 59 insertions(+), 1 deletion(-)

Documentation/devicetree/bindings/iommu/riscv,iommu.yaml +0 -0
index d4838c3b3741..0378eef1f34e 100644
@@ -57,17 +57,42 @@ properties:


   interrupts:
     minItems: 1
-    maxItems: 4
+    maxItems: 68
     description:
       Wired interrupt vectors available for RISC-V IOMMU to notify the RISC-V HARTS. The cause to interrupt vector is software defined

Quoted 8 lines
Quoted 5 lines

       using IVEC IOMMU register.
+      Normally the number of interrupt vectors available is 4 for IOATS
+      civ/fiv/pmiv/piv interrupts. But for SpacemiT distributed IOMMU,
+      the number of interrupt vectors includes IOATC pmiv wired
+      interrupts and the maximum number of IOATCs can be up to 64.


The extension to 68 should only be permitted for a soc-specific compatible.

Sure.

Quoted 37 lines

Quoted 36 lines

+
+  interrupt-names:
+    minItems: 1
+    maxItems: 68

   msi-parent: true

   power-domains:
     maxItems: 1

+  vendor-hpm-events:
+    minItems: 1
+    maxItems: 120
+    description:
+      Each item defines a vendor specific event using the format of
+      "eventId[:eventName]", where the eventId is an integer filling the
+      eventID field of the iohpmevt register and the eventName is an
+      optional string used as the annotation of the event instead of the
+      default name "eventId".
+    $ref: /schemas/types.yaml#/definitions/string-array

Documentation/devicetree/bindings/iommu/riscv,iommu.yaml +7 -0
+
+  global-filter:
+    type: boolean
+    description:
+      Indicate the filters programmed across iohpmevt registers are wired
+      together in hardware as a global filter applied to all HPM events.
+

 required:
   - compatible
   - reg

Documentation/devicetree/bindings/iommu/riscv,iommu.yaml +2 -0
@@ -145,3 +170,36 @@ examples:
              };
          };
      };
+
+  - |+
Quoted 8 lines

Documentation/devicetree/bindings/iommu/riscv,iommu.yaml examples: · line 179

Quoted 5 lines
Documentation/devicetree/bindings/iommu/riscv,iommu.yaml +5 -0
+    /* Example 5 (SpacemiT distributed IOMMU) */
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    iommu4: iommu@1bccd000 {
+        compatible = "qemu,riscv-iommu", "riscv,iommu";


You cannot use the qemu compatible for your device, you must use a specific one for the spacemit k3.

Sure.

Quoted 3 lines


Also, why is your version "v1.1"? That should just be "v1", and your next version "v2" etc.

I'm still using an old fashioned upstream rule, thanks for the reminder.

Quoted 2 lines


pw-bot: changes-requested

OK. Will send a revised patchset later.

Cheers,
Lv

Quoted 33 lines


Cheers,
Conor.

Quoted 29 lines
Documentation/devicetree/bindings/iommu/riscv,iommu.yaml +26 -0
+        reg = <0x1bccd000 0x1000>;
+        interrupts = <58 IRQ_TYPE_LEVEL_HIGH>, <58 IRQ_TYPE_LEVEL_HIGH>,
+                     <58 IRQ_TYPE_LEVEL_HIGH>, <58 IRQ_TYPE_LEVEL_HIGH>,
+                     <62 IRQ_TYPE_LEVEL_HIGH>, <63 IRQ_TYPE_LEVEL_HIGH>;
+        interrupt-names = "civ", "fiv", "ioats-pmiv", "piv",
+                          "ioatc0-pmiv", "ioatc1-pmiv";
+        interrupt-parent = <&saplic>;
+        #iommu-cells = <0x01>;
+        /* SpacemiT T100 features */
+        global-filter;
+        vendor-hpm-events = "0x10:pri_page_reqs",
+                            "0x11:ptw_cache_reqs",
+                            "0x12:dtw_cache_reqs",
+                            "0x15:all_trans_reqs",
+                            "0x20:dtw_cache_lkps",
+                            "0x28:s1l0_ptw_cache_lkps",
+                            "0x2A:s1l1_ptw_cache_lkps",
+                            "0x2C:s1l2_ptw_cache_lkps",
+                            "0x2E:s1l3_ptw_cache_lkps",
+                            "0x30:s2l0_ptw_cache_lkps",
+                            "0x32:s2l1_ptw_cache_lkps",
+                            "0x34:s2l2_ptw_cache_lkps",
+                            "0x36:s2l3_ptw_cache_lkps",
+                            "0x38:mtlb_lkps",
+                            "0x3A:utlb_lkps";
+    };

--
2.43.0

This message and any attachment are confidential and may be privileged or otherwise protected from disclosure. If you are not an intended recipient of this message, please delete it and any attachment from your system and notify the sender immediately by reply e-mail. Unintended recipients should not use, copy, disclose or take any action based on this message or any information contained in this message. Emails cannot be guaranteed to be secure or error free as they can be intercepted, amended, lost or destroyed, and you should take full responsibility for security checking.

本邮件及其任何附件具有保密性质,并可能受其他保护或不允许被披露给第三方。如阁下误收到本邮件,敬请立即以回复电子邮件的方式通知发件人,并将本邮件及其任何附件从阁下系统中予以删除。如阁下并非本邮件写明之收件人,敬请切勿使用、复制、披露本邮件或其任何内容,亦请切勿依本邮件或其任何内容而采取任何行动。电子邮件无法保证是一种安全和不会出现任何差错的通信方式,可能会被拦截、修改、丢失或损坏,收件人需自行负责做好安全检查。

#18 lore raw

Re: [PATCH v1.1 4/7] dt-bindings: iommu: Add spacemit/t100 features

Quoted 13 lines · 郑律
Quoted 13 lines

From: "Conor Dooley"<[email protected]>
Date:  Thu, Jan 29, 2026, 18:08
Subject:  Re: [PATCH v1.1 4/7] dt-bindings: iommu: Add spacemit/t100 features
To: "Lv Zheng"<[email protected]>
Cc: "Tomasz Jeznach"<[email protected]>, "Joerg Roedel"<[email protected]>, "Will Deacon"<[email protected]>, "Robin Murphy"<[email protected]>, "Rob Herring"<[email protected]>, "Krzysztof Kozlowski"<[email protected]>, "Conor Dooley"<[email protected]>, "Paul Walmsley"<[email protected]>, "Palmer Dabbelt"<[email protected]>, "Albert Ou"<[email protected]>, "Alexandre Ghiti"<[email protected]>, "Jingyu Li"<[email protected]>, "Zhijian Chen"<[email protected]>, <[email protected]>, <[email protected]>, <[email protected]>, <[email protected]>, <[email protected]>

Quoted 7 lines · Lv Zheng

Adds device tree bindings for SpacemiT T100 specific features.
vendor-hpm-events: Allow vendor events to be customized in the device tree.
global-filter: The feature saves silicon area by reducing filters to one and use it as a global filter across all events. This usually is sufficient for real applications.

Quoted 7 lines
Quoted 2 lines


Why can these not be determined from a device specific compatible?

The specification only defines less than 10 standard event types while the real silicons should have implemented many other event types based on their micro-architecture. I tried to provide a common mechanism for all vendor specific event types across different vendors.

Given that the variance is based on uarch, it sounds like it can be determined from the compatible.

Quoted 5 lines

It is similar for the global filter, the global filter mechanism actually complies to the IOMMU specification, users can alter the iohpmevt registers as is what is specified in the IOMMU specification. It only provides slight application difference between the final effection. Thus this could also be a non-device specific option.

What is a "user" in this context? Given you're talking about reducing silicon area, it sounds like this will be set in stone for each SoC, and therefore can be determined by compatible. If other devices do this, they can also determine it from their compatible.

Properties for things that can be determined based on compatible are generally not permitted, so you'll need to provide a compelling rationale. Common mechanism isn't one, since determining based on compatible would be a common mechanism based on match data that people can tack onto for their devices.

reviewer
#19 lore raw

Re: [PATCH v1.1 4/7] dt-bindings: iommu: Add spacemit/t100 features

Quoted 36 lines · Conor Dooley
Quoted 14 lines · 郑律
Quoted 14 lines

From: "Conor Dooley"<[email protected]>
Date:  Thu, Jan 29, 2026, 18:08
Subject:  Re: [PATCH v1.1 4/7] dt-bindings: iommu: Add spacemit/t100 features
To: "Lv Zheng"<[email protected]>
Cc: "Tomasz Jeznach"<[email protected]>, "Joerg Roedel"<[email protected]>, "Will Deacon"<[email protected]>, "Robin Murphy"<[email protected]>, "Rob Herring"<[email protected]>, "Krzysztof Kozlowski"<[email protected]>, "Conor Dooley"<[email protected]>, "Paul Walmsley"<[email protected]>, "Palmer Dabbelt"<[email protected]>, "Albert Ou"<[email protected]>, "Alexandre Ghiti"<[email protected]>, "Jingyu Li"<[email protected]>, "Zhijian Chen"<[email protected]>, <[email protected]>, <[email protected]>, <[email protected]>, <[email protected]>, <[email protected]>

Quoted 7 lines · Lv Zheng

Adds device tree bindings for SpacemiT T100 specific features.

vendor-hpm-events: Allow vendor events to be customized in the device
                   tree.
global-filter: The feature saves silicon area by reducing filters to
               one and use it as a global filter across all events. This usually is sufficient for real applications.

Quoted 6 lines
Quoted 1 line

Why can these not be determined from a device specific compatible?

The specification only defines less than 10 standard event types while the real silicons should have implemented many other event types based on their micro-architecture. I tried to provide a common mechanism for all vendor specific event types across different vendors.

Given that the variance is based on uarch, it sounds like it can be determined from the compatible.

Quoted 5 lines

It is similar for the global filter, the global filter mechanism actually complies to the IOMMU specification, users can alter the iohpmevt registers as is what is specified in the IOMMU specification. It only provides slight application difference between the final effection. Thus this could also be a non-device specific option.

What is a "user" in this context? Given you're talking about reducing silicon area, it sounds like this will be set in stone for each SoC, and therefore can be determined by compatible. If other devices do this, they can also determine it from their compatible.

Quoted 5 lines

Properties for things that can be determined based on compatible are generally not permitted, so you'll need to provide a compelling rationale. Common mechanism isn't one, since determining based on compatible would be a common mechanism based on match data that people can tack onto for their devices.

Also, reinventing jevents via devicetree is pretty grim anyway - the PMU can simply expose an "identifier" attribute that uniquely identifies the vendor implementation, and perf tooling can match that to a set of event definitions in userspace, with the added bonus that jevents can also encode meaningful descriptions, metrics and suchlike. There doesn't *need* to be a sysfs alias for every possible event. I see the RISC-V CPU PMUs are already on-board with this approach - note the "Unit"/"Compat" matching for system/uncore PMUs is a little different from the mapfile used for CPUs, but see other architectures for examples.

Thanks,
Robin.

author
#20 lore raw

Re: [PATCH v1.1 4/7] dt-bindings: iommu: Add spacemit/t100 features

Quoted 47 lines

From: "Robin Murphy"<[email protected]>
Date:  Fri, Jan 30, 2026, 01:06
Subject:  Re: [PATCH v1.1 4/7] dt-bindings: iommu: Add spacemit/t100 features
To: "Conor Dooley"<[email protected]>, "郑律"<[email protected]>
Cc: "Tomasz Jeznach"<[email protected]>, "Joerg Roedel"<[email protected]>, "Will Deacon"<[email protected]>, "Rob Herring"<[email protected]>, "Krzysztof Kozlowski"<[email protected]>, "Conor Dooley"<[email protected]>, "Paul Walmsley"<[email protected]>, "Palmer Dabbelt"<[email protected]>, "Albert Ou"<[email protected]>, "Alexandre Ghiti"<[email protected]>, "Jingyu Li"<[email protected]>, "iommu"<[email protected]>, "linux-perf-users"<[email protected]>, "linux-riscv"<[email protected]>, "spacemit"<[email protected]>, "devicetree"<[email protected]>

Quoted 30 lines · Conor Dooley
Quoted 13 lines · 郑律
Quoted 13 lines

From: "Conor Dooley"<[email protected]>
Date:  Thu, Jan 29, 2026, 18:08
Subject:  Re: [PATCH v1.1 4/7] dt-bindings: iommu: Add spacemit/t100 features
To: "Lv Zheng"<[email protected]>
Cc: "Tomasz Jeznach"<[email protected]>, "Joerg Roedel"<[email protected]>, "Will Deacon"<[email protected]>, "Robin Murphy"<[email protected]>, "Rob Herring"<[email protected]>, "Krzysztof Kozlowski"<[email protected]>, "Conor Dooley"<[email protected]>, "Paul Walmsley"<[email protected]>, "Palmer Dabbelt"<[email protected]>, "Albert Ou"<[email protected]>, "Alexandre Ghiti"<[email protected]>, "Jingyu Li"<[email protected]>, "Zhijian Chen"<[email protected]>, <[email protected]>, <[email protected]>, <[email protected]>, <[email protected]>, <[email protected]>

Quoted 7 lines · Lv Zheng

Adds device tree bindings for SpacemiT T100 specific features.
vendor-hpm-events: Allow vendor events to be customized in the device tree.
global-filter: The feature saves silicon area by reducing filters to one and use it as a global filter across all events. This usually is sufficient for real applications.

Quoted 7 lines
Quoted 2 lines


Why can these not be determined from a device specific compatible?

The specification only defines less than 10 standard event types while the real silicons should have implemented many other event types based on their micro-architecture. I tried to provide a common mechanism for all vendor specific event types across different vendors.


Given that the variance is based on uarch, it sounds like it can be determined from the compatible.

Quoted 5 lines

It is similar for the global filter, the global filter mechanism actually complies to the IOMMU specification, users can alter the iohpmevt registers as is what is specified in the IOMMU specification. It only provides slight application difference between the final effection. Thus this could also be a non-device specific option.

Quoted 11 lines


What is a "user" in this context? Given you're talking about reducing silicon area, it sounds like this will be set in stone for each SoC, and therefore can be determined by compatible. If other devices do this, they can also determine it from their compatible.

Properties for things that can be determined based on compatible are generally not permitted, so you'll need to provide a compelling rationale. Common mechanism isn't one, since determining based on compatible would be a common mechanism based on match data that people can tack onto for their devices.

Quoted 10 lines


Also, reinventing jevents via devicetree is pretty grim anyway - the PMU can simply expose an "identifier" attribute that uniquely identifies the vendor implementation, and perf tooling can match that to a set of event definitions in userspace, with the added bonus that jevents can also encode meaningful descriptions, metrics and suchlike. There doesn't *need* to be a sysfs alias for every possible event. I see the RISC-V CPU PMUs are already on-board with this approach - note the "Unit"/"Compat" matching for system/uncore PMUs is a little different from the mapfile used for CPUs, but see other architectures for examples.

Thanks for the idea. It sounds great and I'll give it a try.

Best regards,
Lv

Quoted 3 lines


Thanks,
Robin.

This message and any attachment are confidential and may be privileged or otherwise protected from disclosure. If you are not an intended recipient of this message, please delete it and any attachment from your system and notify the sender immediately by reply e-mail. Unintended recipients should not use, copy, disclose or take any action based on this message or any information contained in this message. Emails cannot be guaranteed to be secure or error free as they can be intercepted, amended, lost or destroyed, and you should take full responsibility for security checking.

本邮件及其任何附件具有保密性质,并可能受其他保护或不允许被披露给第三方。如阁下误收到本邮件,敬请立即以回复电子邮件的方式通知发件人,并将本邮件及其任何附件从阁下系统中予以删除。如阁下并非本邮件写明之收件人,敬请切勿使用、复制、披露本邮件或其任何内容,亦请切勿依本邮件或其任何内容而采取任何行动。电子邮件无法保证是一种安全和不会出现任何差错的通信方式,可能会被拦截、修改、丢失或损坏,收件人需自行负责做好安全检查。

author
#21 lore raw

Re: [PATCH v1.1 4/7] dt-bindings: iommu: Add spacemit/t100 features

In reply to Conor Dooley
Quoted 21 lines

From: "Conor Dooley"<[email protected]>
Date:  Fri, Jan 30, 2026, 00:42
Subject:  Re: [PATCH v1.1 4/7] dt-bindings: iommu: Add spacemit/t100 features
To: "郑律"<[email protected]>
Cc: "Tomasz Jeznach"<[email protected]>, "Joerg Roedel"<[email protected]>, "Will Deacon"<[email protected]>, "Robin Murphy"<[email protected]>, "Rob Herring"<[email protected]>, "Krzysztof Kozlowski"<[email protected]>, "Conor Dooley"<[email protected]>, "Paul Walmsley"<[email protected]>, "Palmer Dabbelt"<[email protected]>, "Albert Ou"<[email protected]>, "Alexandre Ghiti"<[email protected]>, "Jingyu Li"<[email protected]>, "iommu"<[email protected]>, "linux-perf-users"<[email protected]>, "linux-riscv"<[email protected]>, "spacemit"<[email protected]>, "devicetree"<[email protected]>

Quoted 15 lines · 郑律
Quoted 15 lines

From: "Conor Dooley"<[email protected]>
Date:  Thu, Jan 29, 2026, 18:08
Subject:  Re: [PATCH v1.1 4/7] dt-bindings: iommu: Add spacemit/t100 features
To: "Lv Zheng"<[email protected]>
Cc: "Tomasz Jeznach"<[email protected]>, "Joerg Roedel"<[email protected]>, "Will Deacon"<[email protected]>, "Robin Murphy"<[email protected]>, "Rob Herring"<[email protected]>, "Krzysztof Kozlowski"<[email protected]>, "Conor Dooley"<[email protected]>, "Paul Walmsley"<[email protected]>, "Palmer Dabbelt"<[email protected]>, "Albert Ou"<[email protected]>, "Alexandre Ghiti"<[email protected]>, "Jingyu Li"<[email protected]>, "Zhijian Chen"<[email protected]>, <[email protected]>, <[email protected]>, <[email protected]>, <[email protected]>, <[email protected]>

Quoted 7 lines · Lv Zheng

Adds device tree bindings for SpacemiT T100 specific features.
vendor-hpm-events: Allow vendor events to be customized in the device tree.
global-filter: The feature saves silicon area by reducing filters to one and use it as a global filter across all events. This usually is sufficient for real applications.


Why can these not be determined from a device specific compatible?

Quoted 8 lines
Quoted 5 lines


The specification only defines less than 10 standard event types while the real silicons should have implemented many other event types based on their micro-architecture. I tried to provide a common mechanism for all vendor specific event types across different vendors.


Given that the variance is based on uarch, it sounds like it can be determined from the compatible.

I'll give Robin's suggestion a try.

Quoted 5 lines
Quoted 5 lines

It is similar for the global filter, the global filter mechanism actually complies to the IOMMU specification, users can alter the iohpmevt registers as is what is specified in the IOMMU specification. It only provides slight application difference between the final effection. Thus this could also be a non-device specific option.

Quoted 11 lines


What is a "user" in this context? Given you're talking about reducing silicon area, it sounds like this will be set in stone for each SoC, and therefore can be determined by compatible. If other devices do this, they can also determine it from their compatible.

Properties for things that can be determined based on compatible are generally not permitted, so you'll need to provide a compelling rationale. Common mechanism isn't one, since determining based on compatible would be a common mechanism based on match data that people can tack onto for their devices.

I see. This sounds like a reasonable rule of DT attributes. I'll do similar stuffs based on compatible.

Thanks and best regards,
Lv

This message and any attachment are confidential and may be privileged or otherwise protected from disclosure. If you are not an intended recipient of this message, please delete it and any attachment from your system and notify the sender immediately by reply e-mail. Unintended recipients should not use, copy, disclose or take any action based on this message or any information contained in this message. Emails cannot be guaranteed to be secure or error free as they can be intercepted, amended, lost or destroyed, and you should take full responsibility for security checking.

本邮件及其任何附件具有保密性质,并可能受其他保护或不允许被披露给第三方。如阁下误收到本邮件,敬请立即以回复电子邮件的方式通知发件人,并将本邮件及其任何附件从阁下系统中予以删除。如阁下并非本邮件写明之收件人,敬请切勿使用、复制、披露本邮件或其任何内容,亦请切勿依本邮件或其任何内容而采取任何行动。电子邮件无法保证是一种安全和不会出现任何差错的通信方式,可能会被拦截、修改、丢失或损坏,收件人需自行负责做好安全检查。

author
#22 lore raw

PATCH 5/7 spacemit/t100: Add vendor event support for RISC-V IOMMU HPM

In reply to Lv Zheng

Adds mechanism to allow vendor events to be registered via device tree. This is useful to support SpacemiT T100 IOMMU where the maximum 128 event IDs should be supported by T100 IOATS.

---
 drivers/iommu/riscv/iommu-bits.h |  2 +-
 drivers/iommu/riscv/iommu-hpm.c  | 94 +++++++++++++++++++++++++++++++-
 2 files changed, 94 insertions(+), 2 deletions(-)
drivers/iommu/riscv/iommu-bits.h +1 -1
index cc6bea064d8f..f1fbf3cc6ba5 100644
@@ -251,7 +251,7 @@ enum riscv_iommu_hpmevent_id {
 	RISCV_IOMMU_HPMEVENT_PD_WALK    = 6,
 	RISCV_IOMMU_HPMEVENT_S_VS_WALKS = 7,
 	RISCV_IOMMU_HPMEVENT_G_WALKS    = 8,
-	RISCV_IOMMU_HPMEVENT_MAX        = 9
+	RISCV_IOMMU_HPMEVENT_MAX        = 128
 };
 
 #define RISCV_IOMMU_HPMEVENT_CYCLES	RISCV_IOMMU_HPMEVENT_INVALID
drivers/iommu/riscv/iommu-hpm.c +93 -1

113 lines not on this page · raw message

Signature · 5 lines
2.43.0

This message and any attachment are confidential and may be privileged or otherwise protected from disclosure. If you are not an intended recipient of this message, please delete it and any attachment from your system and notify the sender immediately by reply e-mail. Unintended recipients should not use, copy, disclose or take any action based on this message or any information contained in this message. Emails cannot be guaranteed to be secure or error free as they can be intercepted, amended, lost or destroyed, and you should take full responsibility for security checking. 
 
本邮件及其任何附件具有保密性质,并可能受其他保护或不允许被披露给第三方。如阁下误收到本邮件,敬请立即以回复电子邮件的方式通知发件人,并将本邮件及其任何附件从阁下系统中予以删除。如阁下并非本邮件写明之收件人,敬请切勿使用、复制、披露本邮件或其任何内容,亦请切勿依本邮件或其任何内容而采取任何行动。电子邮件无法保证是一种安全和不会出现任何差错的通信方式,可能会被拦截、修改、丢失或损坏,收件人需自行负责做好安全检查。
author
#23 lore raw

PATCH 6/7 spacemit/t100: Add global filter support for RISC-V IOMMU HPM

In reply to Lv Zheng

Introduces global filter support for RISC-V IOMMU HPM. The global filter can be seen in SpacemiT T100 which only supports single filter to be applied to all event counters. This silicon design can save the number of the event bus signals.

---
 drivers/iommu/riscv/iommu-hpm.c | 93 ++++++++++++++++++++++++++++++---
 drivers/iommu/riscv/iommu.h     |  1 +
 2 files changed, 87 insertions(+), 7 deletions(-)
drivers/iommu/riscv/iommu-hpm.c +86 -7
index b01d72dd056f..23e1afc262ea 100644
@@ -134,6 +134,49 @@ static inline void riscv_iommu_hpm_interrupt_clear(struct riscv_iommu_hpm *hpm)
 	riscv_iommu_hpm_writel(hpm, RISCV_IOMMU_REG_IPSR, RISCV_IOMMU_IPSR_PMIP);
 }
 
+static bool riscv_iommu_hpm_check_global_filter(struct perf_event *curr,
+						struct perf_event *new)
+{
+	u32 curr_pid_pscid, curr_did_gscid, curr_pv_pscv;
+	u32 curr_dv_gscv, curr_idt, curr_dmask;
+	u32 new_pid_pscid, new_did_gscid, new_pv_pscv;
+	u32 new_dv_gscv, new_idt, new_dmask;
+
+	curr_pid_pscid = get_filter_pid_pscid(curr);
+	curr_did_gscid = get_filter_did_gscid(curr);
+	curr_pv_pscv = get_filter_pv_pscv(curr);
+	curr_dv_gscv = get_filter_dv_gscv(curr);
+	curr_idt = get_filter_idt(curr);
+	curr_dmask = get_filter_dmask(curr);
+
+	new_pid_pscid = get_filter_pid_pscid(new);
+	new_did_gscid = get_filter_did_gscid(new);
+	new_pv_pscv = get_filter_pv_pscv(new);
+	new_dv_gscv = get_filter_dv_gscv(new);
+	new_idt = get_filter_idt(new);
+	new_dmask = get_filter_dmask(new);
+
+	return (curr_pid_pscid == new_pid_pscid &&
+		curr_did_gscid == new_did_gscid &&
+		curr_pv_pscv == new_pv_pscv &&
+		curr_dv_gscv == new_dv_gscv &&
+		curr_idt == new_idt &&
+		curr_dmask == new_dmask);
+}
+
+static bool riscv_iommu_hpm_events_compatible(struct perf_event *curr,
+					      struct perf_event *new)
+{
+	if (new->pmu != curr->pmu)
+		return false;
+
+	if (to_iommu_hpm(new->pmu)->global_filter &&
+	    !riscv_iommu_hpm_check_global_filter(curr, new))
+		return false;
+
+	return true;
+}
+
 static void riscv_iommu_hpm_event_update(struct perf_event *event)
 {
 	struct hw_perf_event *hwc = &event->hw;
@@ -246,9 +289,10 @@ static void riscv_iommu_hpm_set_event_filter(struct perf_event *event, int idx,
 			       RISCV_IOMMU_REG_IOHPMEVT(idx), event_cfg);
 }
 
-static void riscv_iommu_hpm_apply_event_filter(struct riscv_iommu_hpm *iommu_hpm,
-					       struct perf_event *event, int idx)
+static int riscv_iommu_hpm_apply_event_filter(struct riscv_iommu_hpm *iommu_hpm,
+					      struct perf_event *event, int idx)
 {
+	unsigned int cur_idx, num_ctrs = iommu_hpm->num_counters;
 	u32 pid_pscid, did_gscid, pv_pscv, dv_gscv, idt, dmask;
 
 	pid_pscid = get_filter_pid_pscid(event);
@@ -258,14 +302,36 @@ static void riscv_iommu_hpm_apply_event_filter(struct riscv_iommu_hpm *iommu_hpm
 	idt = get_filter_idt(event);
 	dmask = get_filter_dmask(event);
 
+	if (iommu_hpm->global_filter) {
+		cur_idx = find_first_bit(iommu_hpm->used_counters, num_ctrs - 1);
+		if (cur_idx == num_ctrs - 1) {
+			/* First event, set the global filter */
+			riscv_iommu_hpm_set_event_filter(event, 0, pid_pscid,
+							 did_gscid,
+							 pv_pscv, dv_gscv, idt, dmask);
+		} else {
+			/* Check if the new event's filter is compatible with
+			 * the global filter
+			 */
+			if (!riscv_iommu_hpm_check_global_filter(iommu_hpm->events[cur_idx + 1],
+								 event)) {
+				dev_dbg(iommu_hpm->pmu.dev,
+					"HPM: Filter incompatible with global filter\n");
+				return -EAGAIN;
+			}
+		}
+		return 0;
+	}
+
 	riscv_iommu_hpm_set_event_filter(event, idx, pid_pscid, did_gscid,
 					 pv_pscv, dv_gscv, idt, dmask);
+	return 0;
 }
 
 static int riscv_iommu_hpm_get_event_idx(struct riscv_iommu_hpm *iommu_hpm,
 					 struct perf_event *event)
 {
-	int idx;
+	int idx, err;
 	unsigned int num_ctrs = iommu_hpm->num_counters;
 	u16 event_id = get_event(event);
 
@@ -287,7 +353,10 @@ static int riscv_iommu_hpm_get_event_idx(struct riscv_iommu_hpm *iommu_hpm,
 		return -EAGAIN;
 	}
 
-	riscv_iommu_hpm_apply_event_filter(iommu_hpm, event, idx);
+	err = riscv_iommu_hpm_apply_event_filter(iommu_hpm, event, idx);
+	if (err)
+		return err;
+
 	set_bit(idx, iommu_hpm->used_counters);
 
 	return idx;
@@ -363,6 +432,8 @@ static int riscv_iommu_hpm_event_init(struct perf_event *event)
 	}
 
 	if (!is_software_event(event->group_leader)) {
+		if (!riscv_iommu_hpm_events_compatible(event->group_leader, event))
+			return -EINVAL;
 		if (++group_num_events > iommu_hpm->num_counters)
 			return -EINVAL;
 	}
@@ -370,6 +441,8 @@ static int riscv_iommu_hpm_event_init(struct perf_event *event)
 	for_each_sibling_event(sibling, event->group_leader) {
 		if (is_software_event(sibling))
 			continue;
+		if (!riscv_iommu_hpm_events_compatible(sibling, event))
+			return -EINVAL;
 		if (++group_num_events > iommu_hpm->num_counters)
 			return -EINVAL;
 	}
@@ -685,6 +758,7 @@ static void riscv_iommu_hpm_remove(void *data)
 static int riscv_iommu_hpm_register_unit(struct riscv_iommu_device *iommu,
 					 struct riscv_iommu_hpm *iommu_hpm,
 					 u32 offset, int irq,
+					 bool global_filter,
 					 const struct attribute_group **attr_groups,
 					 const char *prefix, int index)
 {
@@ -709,6 +783,8 @@ static int riscv_iommu_hpm_register_unit(struct riscv_iommu_device *iommu,
 	iommu_hpm->base = base;
 	bitmap_zero(iommu_hpm->used_counters, RISCV_IOMMU_HPMCOUNTER_MAX);
 	bitmap_zero(iommu_hpm->supported_events, RISCV_IOMMU_HPMEVENT_MAX);
+	iommu_hpm->global_filter = of_property_read_bool(dev->of_node,
+							 "global-filter");
 
 	riscv_iommu_hpm_writel(iommu_hpm,
 			       RISCV_IOMMU_REG_IOCOUNTINH, 0xFFFFFFFF);
@@ -775,8 +851,10 @@ static int riscv_iommu_hpm_register_unit(struct riscv_iommu_device *iommu,
 	if (err)
 		goto err_cpuhp;
 
-	dev_info(dev, "HPM: Registered %s (%d counters, IRQ %d)\n",
-		 pmu_name, iommu_hpm->num_counters, iommu_hpm->irq);
+	dev_info(dev, "HPM: Registered %s (%d counters, IRQ %d, %s filter)\n",
+		 pmu_name, iommu_hpm->num_counters,
+		 iommu_hpm->irq,
+		 iommu_hpm->global_filter ? "global" : "per-counter");
 	return 0;
 
 err_cpuhp:
@@ -845,7 +923,8 @@ int riscv_iommu_add_hpm(struct riscv_iommu_device *iommu)
 	if (rc < 0)
 		return rc;
 
-	rc = riscv_iommu_hpm_register_unit(iommu, &iommu->hpm, 0, irq,
+	rc = riscv_iommu_hpm_register_unit(iommu, &iommu->hpm,
+					   0, irq, true,
 					   riscv_iommu_hpm_attr_grps,
 					   "riscv_iommu_hpm", -1);
 	if (rc < 0)
drivers/iommu/riscv/iommu.h +1 -0
index 0ad9f5cad4de..5ebf4e85962e 100644
@@ -41,6 +41,7 @@ struct riscv_iommu_hpm {
 	int irq;
 	int on_cpu;
 	struct hlist_node node;
+	bool global_filter;
 	/*
 	 * Layout of events:
 	 * 0       -> HPMCYCLES
Signature · 5 lines
2.43.0

This message and any attachment are confidential and may be privileged or otherwise protected from disclosure. If you are not an intended recipient of this message, please delete it and any attachment from your system and notify the sender immediately by reply e-mail. Unintended recipients should not use, copy, disclose or take any action based on this message or any information contained in this message. Emails cannot be guaranteed to be secure or error free as they can be intercepted, amended, lost or destroyed, and you should take full responsibility for security checking. 
 
本邮件及其任何附件具有保密性质,并可能受其他保护或不允许被披露给第三方。如阁下误收到本邮件,敬请立即以回复电子邮件的方式通知发件人,并将本邮件及其任何附件从阁下系统中予以删除。如阁下并非本邮件写明之收件人,敬请切勿使用、复制、披露本邮件或其任何内容,亦请切勿依本邮件或其任何内容而采取任何行动。电子邮件无法保证是一种安全和不会出现任何差错的通信方式,可能会被拦截、修改、丢失或损坏,收件人需自行负责做好安全检查。
author
#24 lore raw

PATCH 7/7 spacemit/t100: Add SpacemiT T100 IOATC HPM support

In reply to Lv Zheng

Adds IOATC discovery and HPM support for SpacemiT T100.

SpacemiT T100 supports distributed architecture which allows IOTLBs to be cached in adjacent to the DMA masters. Such IOTLBs controllers are called as IOATC, this patch adds distributed HPM support for IOATCs.

---
 drivers/iommu/riscv/iommu-bits.h     |  12 ++
 drivers/iommu/riscv/iommu-hpm.c      | 173 ++++++++++++++++++++++++++-
 drivers/iommu/riscv/iommu-platform.c |   4 +-
 drivers/iommu/riscv/iommu.h          |   2 +-
 4 files changed, 184 insertions(+), 7 deletions(-)
drivers/iommu/riscv/iommu-bits.h +12 -0
index f1fbf3cc6ba5..4dae9f378169 100644
@@ -284,6 +284,18 @@ enum riscv_iommu_hpmevent_id {
 #define RISCV_IOMMU_ICVEC_PMIV		GENMASK_ULL(11, 8)
 #define RISCV_IOMMU_ICVEC_PIV		GENMASK_ULL(15, 12)
 
+/* 5.28 Distributed translation interface status register (dtisr0-3) (4 * 32-bits) */
+#define RISCV_IOMMU_REG_DTISR_BASE	0x02B0
+#define RISCV_IOMMU_REG_DTISR(_n)	(RISCV_IOMMU_REG_DTISR_BASE + ((_n) * 0x04))
+#define RISCV_IOMMU_DTI_STS_SHIFT(_n)	(((_n) % 16) * 2)
+#define RISCV_IOMMU_DTI_STS_MASK(_n)	(0x3 << RISCV_IOMMU_DTI_STS_SHIFT(_n))
+#define RISCV_IOMMU_DTI_STS_NONE	0x0
+#define RISCV_IOMMU_DTI_STS_TBU_IOATC	0x1
+
+#define MAX_RISCV_IOMMU_IOATC		64
+#define RISCV_IOMMU_IOATC_BASE(_base, _idx) \
+	((void __iomem *)((u8 __iomem *)(_base) + ((_idx) + 1) * RISCV_IOMMU_REG_SIZE))
+
 /* 5.28 MSI Configuration table (32 * 64bits) */
 #define RISCV_IOMMU_REG_MSI_CFG_TBL	0x0300
 #define RISCV_IOMMU_REG_MSI_CFG_TBL_ADDR(_n) \
drivers/iommu/riscv/iommu-hpm.c +169 -4

228 lines not on this page · raw message

drivers/iommu/riscv/iommu-platform.c +2 -2
index 684bc267ac30..ca8de9ec5266 100644
@@ -75,8 +75,8 @@ static int riscv_iommu_platform_probe(struct platform_device *pdev)
 	if (iommu->irqs_count <= 0)
 		return dev_err_probe(dev, -ENODEV,
 				     "no IRQ resources provided\n");
-	if (iommu->irqs_count > RISCV_IOMMU_INTR_COUNT)
-		iommu->irqs_count = RISCV_IOMMU_INTR_COUNT;
+	if (iommu->irqs_count > RISCV_IOMMU_INTR_COUNT + MAX_RISCV_IOMMU_IOATC)
+		iommu->irqs_count = RISCV_IOMMU_INTR_COUNT + MAX_RISCV_IOMMU_IOATC;
 
 	igs = FIELD_GET(RISCV_IOMMU_CAPABILITIES_IGS, iommu->caps);
 	switch (igs) {
drivers/iommu/riscv/iommu.h +1 -1
index 5ebf4e85962e..b1905e54bd0b 100644
@@ -75,7 +75,7 @@ struct riscv_iommu_device {
 	u32 fctl;
 
 	/* available interrupt numbers, MSI or WSI */
-	unsigned int irqs[RISCV_IOMMU_INTR_COUNT];
+	unsigned int irqs[RISCV_IOMMU_INTR_COUNT + MAX_RISCV_IOMMU_IOATC];
 	unsigned int irqs_count;
 	unsigned int icvec;
 
Signature · 5 lines
2.43.0

This message and any attachment are confidential and may be privileged or otherwise protected from disclosure. If you are not an intended recipient of this message, please delete it and any attachment from your system and notify the sender immediately by reply e-mail. Unintended recipients should not use, copy, disclose or take any action based on this message or any information contained in this message. Emails cannot be guaranteed to be secure or error free as they can be intercepted, amended, lost or destroyed, and you should take full responsibility for security checking. 
 
本邮件及其任何附件具有保密性质,并可能受其他保护或不允许被披露给第三方。如阁下误收到本邮件,敬请立即以回复电子邮件的方式通知发件人,并将本邮件及其任何附件从阁下系统中予以删除。如阁下并非本邮件写明之收件人,敬请切勿使用、复制、披露本邮件或其任何内容,亦请切勿依本邮件或其任何内容而采取任何行动。电子邮件无法保证是一种安全和不会出现任何差错的通信方式,可能会被拦截、修改、丢失或损坏,收件人需自行负责做好安全检查。
#25 lore raw
In reply to Lv Zheng
Quoted 5 lines · Lv Zheng

Includes HPM support for RISC-V IOMMU. The HPM hardware mechnism can be found in the recent announced SpacemiT SoCs (K3, V100), where T100 (SpacemiT distributed IOMMU) is shipped.

The tested result can be found as follows:

What is v1.1 in this patch? Why aren't you following standard process which allows us to make review easier (try yourself with b4 diff)?

Best regards,
Krzysztof

#26 lore raw

v3 cover iommu/riscv: Add HPM support for RISC-V IOMMU

In reply to Lv Zheng

Includes HPM support for RISC-V IOMMU. The HPM hardware mechanism can be found in the recent announced SpacemiT SoCs (K3, V100), where T100 (SpacemiT distributed IOMMU) is shipped.

Revisions:
v1
Initial release.
v2 (sent as v1.1)
Split and cleanup DT-bindings.
v3
Refactor using vendor specific compatible.

The tested result can be found as follows:

 root@sdfirm:~# perf stat --timeout 5000 -a -e spacemit_ioats_hpm_00/dd_walk,config1=0x20c0010000000000/ dmatest; sleep 1
 [  145.630224] dmatest: Started 1 threads using dma0chan0
 [  145.644896] dmatest: dma0chan0-copy0: summary 1 tests, 0 failures 123.60 iops 123 KB/s (0)

Performance counter stats for 'system wide':

                  3      spacemit_ioats_hpm_00/dd_walk,config1=0x20c0010000000000/                                      

        0.193108000 seconds time elapsed
 root@sdfirm:~# echo dma0chan1 > /sys/module/dmatest/parameters/channel 
 [  327.001820] dmatest: Added 1 threads using dma0chan1
 root@sdfirm:~# perf stat --timeout 5000 -a -e spacemit_ioats_hpm_00/s_walk,config1=0x20c0011000000000/ dmatest; sleep 1
 [  484.037180] dmatest: Started 1 threads using dma0chan1
 [  484.048832] dmatest: dma0chan1-copy0: summary 1 tests, 0 failures 172.11 iops 172 KB/s (0)

Performance counter stats for 'system wide':

                  6      spacemit_ioats_hpm_00/s_walk,config1=0x20c0011000000000/                                      

        0.191970000 seconds time elapsed
 root@sdfirm:~# perf stat --timeout 5000 -a -e spacemit_ioatc_hpm_0003/tlb_mis,config1=0x20c0011000000000/ dmatest; sleep 1
 [  546.332494] dmatest: No channels configured, continue with any
 [  546.363062] dmatest: Added 1 threads using dma0chan1
 [  546.377994] dmatest: Started 1 threads using dma0chan1
 [  546.388376] dmatest: dma0chan1-copy0: summary 1 tests, 0 failures 213.94 iops 213 KB/s (0)

Performance counter stats for 'system wide':

                  3      spacemit_ioatc_hpm_0003/tlb_mis,config1=0x20c0011000000000/                                      

        0.225062000 seconds time elapsed

Jingyu Li (3):
iommu/riscv: Enable IOMMU DMA mapping support iommu/riscv: Fix WSI mode IRQ number handling iommu/riscv: Add HPM support for performance monitoring

Lv Zheng (5):
dt-bindings: iommu: Add spacemit/t100 features riscv/iommu: Add vendor event support for RISC-V IOMMU HPM spacemit/t100: Add global filter awareness for RISC-V IOMMU HPM spacemit/t100: Add SpacemiT T100 IOATC HPM support
perf vendor events riscv:: Add support for spacemit,riscv-iommu HPM
aliasing

 .../bindings/iommu/riscv,iommu.yaml           |   37 +
 MAINTAINERS                                   |    3 +
 drivers/iommu/Kconfig                         |    2 +-
 drivers/iommu/riscv/Kconfig                   |    9 +
 drivers/iommu/riscv/Makefile                  |    1 +
 drivers/iommu/riscv/iommu-bits.h              |   18 +
 drivers/iommu/riscv/iommu-hpm.c               | 1122 +++++++++++++++++
 drivers/iommu/riscv/iommu-pci.c               |   13 +-
 drivers/iommu/riscv/iommu-platform.c          |   12 +-
 drivers/iommu/riscv/iommu.c                   |   25 +-
 drivers/iommu/riscv/iommu.h                   |   46 +-
 .../arch/riscv/spacemit/iommu/sys/ioatc.json  |   30 +
 .../arch/riscv/spacemit/iommu/sys/ioats.json  |  163 +++
 13 files changed, 1469 insertions(+), 12 deletions(-)
 create mode 100644 drivers/iommu/riscv/iommu-hpm.c
 create mode 100644 tools/perf/pmu-events/arch/riscv/spacemit/iommu/sys/ioatc.json
 create mode 100644 tools/perf/pmu-events/arch/riscv/spacemit/iommu/sys/ioats.json
Signature · 1 line
2.43.0
#27 lore raw
Quoted 4 lines · Lv Zheng

Includes HPM support for RISC-V IOMMU. The HPM hardware mechanism can be found in the recent announced SpacemiT SoCs (K3, V100), where T100 (SpacemiT distributed IOMMU) is shipped.

Quoted 8 lines

Revisions:
v1
Initial release.
v2 (sent as v1.1)
Split and cleanup DT-bindings.
v3
Refactor using vendor specific compatible.

Do not attach (thread) your patchsets to some other threads (unrelated or older versions). This buries them deep in the mailbox and might interfere with applying entire sets. See also:
https://elixir.bootlin.com/linux/v6.16-rc2/source/Documentation/process/submitting-patches.rst#L830

Best regards,
Krzysztof

#28 lore raw
Quoted 15 lines · Krzysztof Kozlowski
Quoted 4 lines · Lv Zheng

Includes HPM support for RISC-V IOMMU. The HPM hardware mechanism can be found in the recent announced SpacemiT SoCs (K3, V100), where T100 (SpacemiT distributed IOMMU) is shipped.

Quoted 8 lines

Revisions:
v1
Initial release.
v2 (sent as v1.1)
Split and cleanup DT-bindings.
v3
Refactor using vendor specific compatible.

Quoted 4 lines

Do not attach (thread) your patchsets to some other threads (unrelated or older versions). This buries them deep in the mailbox and might interfere with applying entire sets. See also:
https://elixir.bootlin.com/linux/v6.16-rc2/source/Documentation/process/submitting-patches.rst#L830

Got it.
I'm still using an old fashioned upstream way to collect all revisions into one thread. Will align to the preferred style.

Thanks,
Lv

Quoted 4 lines

Best regards,
Krzysztof

#29 lore raw

Hi Lv,

Quoted 16 lines · Lv Zheng
Quoted 15 lines · Krzysztof Kozlowski
Quoted 12 lines · Lv Zheng

Includes HPM support for RISC-V IOMMU. The HPM hardware mechanism can be found in the recent announced SpacemiT SoCs (K3, V100), where T100 (SpacemiT distributed IOMMU) is shipped.

Revisions:
v1
Initial release.
v2 (sent as v1.1)
Split and cleanup DT-bindings.
v3
Refactor using vendor specific compatible.

Quoted 9 lines
Quoted 4 lines

Do not attach (thread) your patchsets to some other threads (unrelated or older versions). This buries them deep in the mailbox and might interfere with applying entire sets. See also:
https://elixir.bootlin.com/linux/v6.16-rc2/source/Documentation/process/submitting-patches.rst#L830

Got it.
I'm still using an old fashioned upstream way to collect all revisions into one thread. Will align to the preferred style.

Using b4 will automate this procedure, you can also take a look at Konstantin's articles, and the b4 doc
https://people.kernel.org/monsieuricon/sending-a-kernel-patch-with-b4-part-1
https://b4.docs.kernel.org/en/latest/

Quoted 10 lines

Thanks,
Lv

Quoted 4 lines

Best regards,
Krzysztof

Signature · 1 line
Yixun Lan (dlan)
#30 lore raw
Quoted 24 lines · Yixun Lan

Hi Lv,

Quoted 21 lines · Lv Zheng
Quoted 19 lines · Krzysztof Kozlowski
Quoted 4 lines · Lv Zheng

Includes HPM support for RISC-V IOMMU. The HPM hardware mechanism can be found in the recent announced SpacemiT SoCs (K3, V100), where T100 (SpacemiT distributed IOMMU) is shipped.

Quoted 8 lines

Revisions:
v1
Initial release.
v2 (sent as v1.1)
Split and cleanup DT-bindings.
v3
Refactor using vendor specific compatible.

Do not attach (thread) your patchsets to some other threads (unrelated or older versions). This buries them deep in the mailbox and might interfere with applying entire sets. See also:
https://elixir.bootlin.com/linux/v6.16-rc2/source/Documentation/process/submitting-patches.rst#L830

Quoted 8 lines
Quoted 4 lines

Got it.
I'm still using an old fashioned upstream way to collect all revisions into one thread. Will align to the preferred style.

Using b4 will automate this procedure, you can also take a look at Konstantin's articles, and the b4 doc
https://people.kernel.org/monsieuricon/sending-a-kernel-patch-with-b4-part-1
https://b4.docs.kernel.org/en/latest/

Yes, we've tried b4, it really can automate this process a lot.

Thanks,
Lv

Quoted 5 lines
Quoted 5 lines

Thanks,
Lv

Quoted 1 line
Quoted 7 lines
Quoted 6 lines
Quoted 3 lines

Best regards,
Krzysztof

_______________________________________________
linux-riscv mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-riscv

A message that is not in the archive (sent off-list or not yet received): [email protected]

#32 lore raw

PATCH v3 1/8 iommu/riscv: Enable IOMMU DMA mapping support

From: Jingyu Li <[email protected]>

Enables IOMMU DMA mapping support for RISC-V, so that DMACs can be tested with translation enabled.

Known Possible Issue:
1. When CONFIG_IOMMU_DMA is enabled, on the tested Linux, RISC-V IOMMU is lack of PCIe support, causing riscv_iommu_fault:522 in dealing with NVMe PCIe devices.

---
 drivers/iommu/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iommu/Kconfig +1 -1
index f86262b11416..34d8a792339f 100644
@@ -151,7 +151,7 @@ config OF_IOMMU
 
 # IOMMU-agnostic DMA-mapping layer
 config IOMMU_DMA
-	def_bool ARM64 || X86 || S390
+	def_bool ARM64 || X86 || S390 || RISCV
 	select DMA_OPS_HELPERS
 	select IOMMU_API
 	select IOMMU_IOVA
Signature · 1 line
2.43.0
#33 lore raw

PATCH v3 2/8 iommu/riscv: Fix WSI mode IRQ number handling

In reply to a message not in the archive

From: Jingyu Li <[email protected]>

In WSI mode, ICVEC doesn't exist, thus reading it returns 0, which causes IOMMU driver to fail to find IRQ numbers from device tree IRQ arrary. The issue is fixed by applying icvec indexes of WSI IRQs.

---
 drivers/iommu/riscv/iommu.c | 25 ++++++++++++++++++++-----
 1 file changed, 20 insertions(+), 5 deletions(-)
drivers/iommu/riscv/iommu.c +20 -5
index d9429097a2b5..26630979473b 100644
@@ -1593,11 +1593,26 @@ static int riscv_iommu_init_check(struct riscv_iommu_device *iommu)
 		       FIELD_PREP(RISCV_IOMMU_ICVEC_PMIV, 3 % iommu->irqs_count);
 	riscv_iommu_writeq(iommu, RISCV_IOMMU_REG_ICVEC, iommu->icvec);
 	iommu->icvec = riscv_iommu_readq(iommu, RISCV_IOMMU_REG_ICVEC);
-	if (max(max(FIELD_GET(RISCV_IOMMU_ICVEC_CIV, iommu->icvec),
-		    FIELD_GET(RISCV_IOMMU_ICVEC_FIV, iommu->icvec)),
-		max(FIELD_GET(RISCV_IOMMU_ICVEC_PIV, iommu->icvec),
-		    FIELD_GET(RISCV_IOMMU_ICVEC_PMIV, iommu->icvec))) >= iommu->irqs_count)
-		return -EINVAL;
+	/*
+	 * In WSI mode, ICVEC may read as zero. Only validate if using MSI.
+	 * Check if FCTL.WSI is set to determine interrupt mode.
+	 */
+	if (!(iommu->fctl & RISCV_IOMMU_FCTL_WSI)) {
+		if (max(max(FIELD_GET(RISCV_IOMMU_ICVEC_CIV, iommu->icvec),
+			    FIELD_GET(RISCV_IOMMU_ICVEC_FIV, iommu->icvec)),
+			max(FIELD_GET(RISCV_IOMMU_ICVEC_PIV, iommu->icvec),
+			    FIELD_GET(RISCV_IOMMU_ICVEC_PMIV, iommu->icvec))) >= iommu->irqs_count)
+			return -EINVAL;
+	} else {
+		/*
+		 * WSI mode: ICVEC is not used. Set to identity mapping for
+		 * riscv_iommu_queue_vec() to work correctly.
+		 */
+		iommu->icvec = FIELD_PREP(RISCV_IOMMU_ICVEC_CIV, 0) |
+			       FIELD_PREP(RISCV_IOMMU_ICVEC_FIV, 1) |
+			       FIELD_PREP(RISCV_IOMMU_ICVEC_PIV, 2) |
+			       FIELD_PREP(RISCV_IOMMU_ICVEC_PMIV, 3);
+	}
 
 	return 0;
 }
Signature · 1 line
2.43.0
#34 lore raw

Re: [PATCH v3 2/8] iommu/riscv: Fix WSI mode IRQ number handling

Quoted 5 lines · Lv Zheng

From: Jingyu Li <[email protected]>

In WSI mode, ICVEC doesn't exist, thus reading it returns 0, which causes IOMMU driver to fail to find IRQ numbers from device tree IRQ arrary. The issue is fixed by applying icvec indexes of WSI IRQs.

ICVEC always exists, however it may be hardwired to zero when an implementation only supports a single vector. But, that has nothing to do with whether wired interrupts or MSIs are used.

If ICVEC on this IOMMU is always reading as zero, even when 0xf is written to it first, then it should be interpreted as there only being a single vector (or that the IOMMU's ICVEC is broken, if the number of sources is known to be more).

Quoted 15 lines
---
 drivers/iommu/riscv/iommu.c | 25 ++++++++++++++++++++-----
 1 file changed, 20 insertions(+), 5 deletions(-)
drivers/iommu/riscv/iommu.c +0 -0
index d9429097a2b5..26630979473b 100644
@@ -1593,11 +1593,26 @@ static int riscv_iommu_init_check(struct riscv_iommu_device *iommu)
 		       FIELD_PREP(RISCV_IOMMU_ICVEC_PMIV, 3 % iommu->irqs_count);
 	riscv_iommu_writeq(iommu, RISCV_IOMMU_REG_ICVEC, iommu->icvec);
 	iommu->icvec = riscv_iommu_readq(iommu, RISCV_IOMMU_REG_ICVEC);

drivers/iommu/riscv/iommu.c static int riscv_iommu_init_check(struct riscv_iommu_device *iommu) · line 1600

Quoted 10 lines
drivers/iommu/riscv/iommu.c +5 -5
-	if (max(max(FIELD_GET(RISCV_IOMMU_ICVEC_CIV, iommu->icvec),
-		    FIELD_GET(RISCV_IOMMU_ICVEC_FIV, iommu->icvec)),
-		max(FIELD_GET(RISCV_IOMMU_ICVEC_PIV, iommu->icvec),
-		    FIELD_GET(RISCV_IOMMU_ICVEC_PMIV, iommu->icvec))) >= iommu->irqs_count)
-		return -EINVAL;
+	/*
+	 * In WSI mode, ICVEC may read as zero. Only validate if using MSI.
+	 * Check if FCTL.WSI is set to determine interrupt mode.
+	 */
+	if (!(iommu->fctl & RISCV_IOMMU_FCTL_WSI)) {

The behavior of ICVEC does not depend on FCTL.WSI

Quoted 4 lines
drivers/iommu/riscv/iommu.c +4 -0
+		if (max(max(FIELD_GET(RISCV_IOMMU_ICVEC_CIV, iommu->icvec),
+			    FIELD_GET(RISCV_IOMMU_ICVEC_FIV, iommu->icvec)),
+			max(FIELD_GET(RISCV_IOMMU_ICVEC_PIV, iommu->icvec),
+			    FIELD_GET(RISCV_IOMMU_ICVEC_PMIV, iommu->icvec))) >= iommu->irqs_count)

drivers/iommu/riscv/iommu.c static int riscv_iommu_init_check(struct riscv_iommu_device *iommu) · line 1614

Quoted 10 lines
drivers/iommu/riscv/iommu.c +10 -0
+			return -EINVAL;
+	} else {
+		/*
+		 * WSI mode: ICVEC is not used. Set to identity mapping for
+		 * riscv_iommu_queue_vec() to work correctly.
+		 */
+		iommu->icvec = FIELD_PREP(RISCV_IOMMU_ICVEC_CIV, 0) |
+			       FIELD_PREP(RISCV_IOMMU_ICVEC_FIV, 1) |
+			       FIELD_PREP(RISCV_IOMMU_ICVEC_PIV, 2) |
+			       FIELD_PREP(RISCV_IOMMU_ICVEC_PMIV, 3);

It's certainly not correct to set iommu->icvec to anything that can't be written to the IOMMU's WARL ICVEC fields and read back again.

Thanks,
drew

#35 lore raw

Re: [PATCH v3 2/8] iommu/riscv: Fix WSI mode IRQ number handling

Quoted 53 lines · Andrew Jones
Quoted 5 lines · Lv Zheng

From: Jingyu Li <[email protected]>

In WSI mode, ICVEC doesn't exist, thus reading it returns 0, which causes IOMMU driver to fail to find IRQ numbers from device tree IRQ arrary. The issue is fixed by applying icvec indexes of WSI IRQs.

ICVEC always exists, however it may be hardwired to zero when an implementation only supports a single vector. But, that has nothing to do with whether wired interrupts or MSIs are used.

If ICVEC on this IOMMU is always reading as zero, even when 0xf is written to it first, then it should be interpreted as there only being a single vector (or that the IOMMU's ICVEC is broken, if the number of sources is known to be more).

Quoted 15 lines
---
  drivers/iommu/riscv/iommu.c | 25 ++++++++++++++++++++-----
  1 file changed, 20 insertions(+), 5 deletions(-)
drivers/iommu/riscv/iommu.c +0 -0
index d9429097a2b5..26630979473b 100644
@@ -1593,11 +1593,26 @@ static int riscv_iommu_init_check(struct riscv_iommu_device *iommu)
  		       FIELD_PREP(RISCV_IOMMU_ICVEC_PMIV, 3 % iommu->irqs_count);
  	riscv_iommu_writeq(iommu, RISCV_IOMMU_REG_ICVEC, iommu->icvec);
  	iommu->icvec = riscv_iommu_readq(iommu, RISCV_IOMMU_REG_ICVEC);

drivers/iommu/riscv/iommu.c static int riscv_iommu_init_check(struct riscv_iommu_device *iommu) · line 1600

Quoted 10 lines
drivers/iommu/riscv/iommu.c +5 -5
-	if (max(max(FIELD_GET(RISCV_IOMMU_ICVEC_CIV, iommu->icvec),
-		    FIELD_GET(RISCV_IOMMU_ICVEC_FIV, iommu->icvec)),
-		max(FIELD_GET(RISCV_IOMMU_ICVEC_PIV, iommu->icvec),
-		    FIELD_GET(RISCV_IOMMU_ICVEC_PMIV, iommu->icvec))) >= iommu->irqs_count)
-		return -EINVAL;
+	/*
+	 * In WSI mode, ICVEC may read as zero. Only validate if using MSI.
+	 * Check if FCTL.WSI is set to determine interrupt mode.
+	 */
+	if (!(iommu->fctl & RISCV_IOMMU_FCTL_WSI)) {

The behavior of ICVEC does not depend on FCTL.WSI

Quoted 9 lines
drivers/iommu/riscv/iommu.c +9 -0
+		if (max(max(FIELD_GET(RISCV_IOMMU_ICVEC_CIV, iommu->icvec),
+			    FIELD_GET(RISCV_IOMMU_ICVEC_FIV, iommu->icvec)),
+			max(FIELD_GET(RISCV_IOMMU_ICVEC_PIV, iommu->icvec),
+			    FIELD_GET(RISCV_IOMMU_ICVEC_PMIV, iommu->icvec))) >= iommu->irqs_count)
+			return -EINVAL;
+	} else {
+		/*
+		 * WSI mode: ICVEC is not used. Set to identity mapping for
+		 * riscv_iommu_queue_vec() to work correctly.
Quoted 8 lines

drivers/iommu/riscv/iommu.c static int riscv_iommu_init_check(struct riscv_iommu_device *iommu) · line 1614

Quoted 5 lines
drivers/iommu/riscv/iommu.c +5 -0
+		 */
+		iommu->icvec = FIELD_PREP(RISCV_IOMMU_ICVEC_CIV, 0) |
+			       FIELD_PREP(RISCV_IOMMU_ICVEC_FIV, 1) |
+			       FIELD_PREP(RISCV_IOMMU_ICVEC_PIV, 2) |
+			       FIELD_PREP(RISCV_IOMMU_ICVEC_PMIV, 3);

It's certainly not correct to set iommu->icvec to anything that can't be written to the IOMMU's WARL ICVEC fields and read back again.

Indeed.
It looks I can keep icvec returned for WSI and keeps the write-and-read check logic only for MSI.

Thanks,
Lv

Quoted 4 lines

Thanks,
drew

#36 lore raw

Re: [PATCH v3 2/8] iommu/riscv: Fix WSI mode IRQ number handling

Quoted 2 lines · Lv Zheng
Quoted 1 line · Andrew Jones

On Wed, Feb 04, 2026 at 05:08:52PM +0800, Lv Zheng wrote:

...

Quoted 39 lines
Quoted 30 lines
Quoted 8 lines
drivers/iommu/riscv/iommu.c +0 -0
index d9429097a2b5..26630979473b 100644
@@ -1593,11 +1593,26 @@ static int riscv_iommu_init_check(struct riscv_iommu_device *iommu)
  		       FIELD_PREP(RISCV_IOMMU_ICVEC_PMIV, 3 % iommu->irqs_count);
  	riscv_iommu_writeq(iommu, RISCV_IOMMU_REG_ICVEC, iommu->icvec);
  	iommu->icvec = riscv_iommu_readq(iommu, RISCV_IOMMU_REG_ICVEC);

drivers/iommu/riscv/iommu.c static int riscv_iommu_init_check(struct riscv_iommu_device *iommu) · line 1600

Quoted 10 lines
drivers/iommu/riscv/iommu.c +5 -5
-	if (max(max(FIELD_GET(RISCV_IOMMU_ICVEC_CIV, iommu->icvec),
-		    FIELD_GET(RISCV_IOMMU_ICVEC_FIV, iommu->icvec)),
-		max(FIELD_GET(RISCV_IOMMU_ICVEC_PIV, iommu->icvec),
-		    FIELD_GET(RISCV_IOMMU_ICVEC_PMIV, iommu->icvec))) >= iommu->irqs_count)
-		return -EINVAL;
+	/*
+	 * In WSI mode, ICVEC may read as zero. Only validate if using MSI.
+	 * Check if FCTL.WSI is set to determine interrupt mode.
+	 */
+	if (!(iommu->fctl & RISCV_IOMMU_FCTL_WSI)) {

The behavior of ICVEC does not depend on FCTL.WSI

Quoted 9 lines
drivers/iommu/riscv/iommu.c +9 -0
+		if (max(max(FIELD_GET(RISCV_IOMMU_ICVEC_CIV, iommu->icvec),
+			    FIELD_GET(RISCV_IOMMU_ICVEC_FIV, iommu->icvec)),
+			max(FIELD_GET(RISCV_IOMMU_ICVEC_PIV, iommu->icvec),
+			    FIELD_GET(RISCV_IOMMU_ICVEC_PMIV, iommu->icvec))) >= iommu->irqs_count)
+			return -EINVAL;
+	} else {
+		/*
+		 * WSI mode: ICVEC is not used. Set to identity mapping for
+		 * riscv_iommu_queue_vec() to work correctly.
Quoted 8 lines

drivers/iommu/riscv/iommu.c static int riscv_iommu_init_check(struct riscv_iommu_device *iommu) · line 1614

Quoted 5 lines
drivers/iommu/riscv/iommu.c +5 -0
+		 */
+		iommu->icvec = FIELD_PREP(RISCV_IOMMU_ICVEC_CIV, 0) |
+			       FIELD_PREP(RISCV_IOMMU_ICVEC_FIV, 1) |
+			       FIELD_PREP(RISCV_IOMMU_ICVEC_PIV, 2) |
+			       FIELD_PREP(RISCV_IOMMU_ICVEC_PMIV, 3);

It's certainly not correct to set iommu->icvec to anything that can't be written to the IOMMU's WARL ICVEC fields and read back again.

Quoted 4 lines

Indeed.
It looks I can keep icvec returned for WSI and keeps the write-and-read check logic only for MSI.

You shouldn't need to touch this code at all. I don't see anything to fix wrt the spec. As I said, if iommu->irqs_count is known to be greater than one but you're getting zero back from ICVEC even after writing 0xffff to it first, then ICVEC on your IOMMU is broken. Once you've confirmed that, then the best you can do is add some workaround for your specific IOMMU here.

Thanks,
drew

#37 lore raw

Re: [PATCH v3 2/8] iommu/riscv: Fix WSI mode IRQ number handling

Quoted 55 lines · Andrew Jones
Quoted 2 lines · Lv Zheng
Quoted 1 line · Andrew Jones

On Wed, Feb 04, 2026 at 05:08:52PM +0800, Lv Zheng wrote:

...

Quoted 39 lines
Quoted 30 lines
Quoted 8 lines
drivers/iommu/riscv/iommu.c +0 -0
index d9429097a2b5..26630979473b 100644
@@ -1593,11 +1593,26 @@ static int riscv_iommu_init_check(struct riscv_iommu_device *iommu)
   		       FIELD_PREP(RISCV_IOMMU_ICVEC_PMIV, 3 % iommu->irqs_count);
   	riscv_iommu_writeq(iommu, RISCV_IOMMU_REG_ICVEC, iommu->icvec);
   	iommu->icvec = riscv_iommu_readq(iommu, RISCV_IOMMU_REG_ICVEC);

drivers/iommu/riscv/iommu.c static int riscv_iommu_init_check(struct riscv_iommu_device *iommu) · line 1600

Quoted 10 lines
drivers/iommu/riscv/iommu.c +5 -5
-	if (max(max(FIELD_GET(RISCV_IOMMU_ICVEC_CIV, iommu->icvec),
-		    FIELD_GET(RISCV_IOMMU_ICVEC_FIV, iommu->icvec)),
-		max(FIELD_GET(RISCV_IOMMU_ICVEC_PIV, iommu->icvec),
-		    FIELD_GET(RISCV_IOMMU_ICVEC_PMIV, iommu->icvec))) >= iommu->irqs_count)
-		return -EINVAL;
+	/*
+	 * In WSI mode, ICVEC may read as zero. Only validate if using MSI.
+	 * Check if FCTL.WSI is set to determine interrupt mode.
+	 */
+	if (!(iommu->fctl & RISCV_IOMMU_FCTL_WSI)) {

The behavior of ICVEC does not depend on FCTL.WSI

Quoted 9 lines
drivers/iommu/riscv/iommu.c +9 -0
+		if (max(max(FIELD_GET(RISCV_IOMMU_ICVEC_CIV, iommu->icvec),
+			    FIELD_GET(RISCV_IOMMU_ICVEC_FIV, iommu->icvec)),
+			max(FIELD_GET(RISCV_IOMMU_ICVEC_PIV, iommu->icvec),
+			    FIELD_GET(RISCV_IOMMU_ICVEC_PMIV, iommu->icvec))) >= iommu->irqs_count)
+			return -EINVAL;
+	} else {
+		/*
+		 * WSI mode: ICVEC is not used. Set to identity mapping for
+		 * riscv_iommu_queue_vec() to work correctly.
Quoted 8 lines

drivers/iommu/riscv/iommu.c static int riscv_iommu_init_check(struct riscv_iommu_device *iommu) · line 1614

Quoted 5 lines
drivers/iommu/riscv/iommu.c +5 -0
+		 */
+		iommu->icvec = FIELD_PREP(RISCV_IOMMU_ICVEC_CIV, 0) |
+			       FIELD_PREP(RISCV_IOMMU_ICVEC_FIV, 1) |
+			       FIELD_PREP(RISCV_IOMMU_ICVEC_PIV, 2) |
+			       FIELD_PREP(RISCV_IOMMU_ICVEC_PMIV, 3);

It's certainly not correct to set iommu->icvec to anything that can't be written to the IOMMU's WARL ICVEC fields and read back again.

Quoted 4 lines

Indeed.
It looks I can keep icvec returned for WSI and keeps the write-and-read check logic only for MSI.

You shouldn't need to touch this code at all. I don't see anything to fix wrt the spec. As I said, if iommu->irqs_count is known to be greater than one but you're getting zero back from ICVEC even after writing 0xffff to it first, then ICVEC on your IOMMU is broken. Once you've confirmed that, then the best you can do is add some workaround for your specific IOMMU here.

Quoted 3 lines

Thanks,
drew

This patch is an approach trying to give PMIV a standalone wired IRQ# which is required by pre-silicon spacemit T100 RTLs when it is configured to report both MSI/WSI caps. However there is no such real product on the market, I just drop it it in the next version.

Thanks,
Lv

#38 lore raw

PATCH v3 3/8 iommu/riscv: Add HPM support for performance monitoring

In reply to a message not in the archive

From: Jingyu Li <[email protected]>

Introduces perf-based HPM driver for RISC-V IOMMU, enabling performance monitoring capabilities.

Note that the RISC-V IOMMU HPM module uses COUNTER_MAX-1 as a static counter index of HPMCYCLES, and 0~COUNTER_MAX-2 as the dynamic counter indexes of other HPMEVENTS in order to correctly index into IOHPMEVT and IOHPMCTR registers that have already been defined in the iommu-bits.h. However the users treat 0 as the index of HPMCYCLES and 1~COUNTER_MAX-1 as the indexes of other HPMEVENTS, thus care should be taken in dealing with counter indexes between userspace and kernel space.

---
 drivers/iommu/riscv/Kconfig          |   9 +
 drivers/iommu/riscv/Makefile         |   1 +
 drivers/iommu/riscv/iommu-bits.h     |   6 +
 drivers/iommu/riscv/iommu-hpm.c      | 843 +++++++++++++++++++++++++++
 drivers/iommu/riscv/iommu-pci.c      |  13 +-
 drivers/iommu/riscv/iommu-platform.c |   8 +-
 drivers/iommu/riscv/iommu.h          |  42 ++
 7 files changed, 919 insertions(+), 3 deletions(-)
 create mode 100644 drivers/iommu/riscv/iommu-hpm.c
drivers/iommu/riscv/Kconfig +9 -0
index c071816f59a6..2d06a1ef11c9 100644
@@ -18,3 +18,12 @@ config RISCV_IOMMU_PCI
 	def_bool y if RISCV_IOMMU && PCI_MSI
 	help
 	  Support for the PCIe implementation of RISC-V IOMMU architecture.
+
+config RISCV_IOMMU_HPM
+	tristate "RISCV IOMMU HPM support"
+	depends on RISCV_IOMMU
+	help
+	  Provides support for the RISC-V IOMMU Hardware Performance Monitor
+	  (HPM), which provide monitoring of transactions passing through the
+	  IOMMU and allow the resulting information to be filtered based on
+	  the device/process ID of the corresponding master.
drivers/iommu/riscv/Makefile +1 -0
index b5929f9f23e6..53db3ef62bdd 100644
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-y += iommu.o iommu-platform.o
 obj-$(CONFIG_RISCV_IOMMU_PCI) += iommu-pci.o
+obj-$(CONFIG_RISCV_IOMMU_HPM) += iommu-hpm.o
drivers/iommu/riscv/iommu-bits.h +6 -0
index 98daf0e1a306..cc6bea064d8f 100644
@@ -207,6 +207,7 @@ enum riscv_iommu_ddtp_modes {
 /* 5.22 Performance monitoring event counters (31 * 64bits) */
 #define RISCV_IOMMU_REG_IOHPMCTR_BASE	0x0068
 #define RISCV_IOMMU_REG_IOHPMCTR(_n)	(RISCV_IOMMU_REG_IOHPMCTR_BASE + ((_n) * 0x8))
+#define RISCV_IOMMU_IOHPMEVENT_COUNTER	GENMASK_ULL(63, 0)
 
 /* 5.23 Performance monitoring event selectors (31 * 64bits) */
 #define RISCV_IOMMU_REG_IOHPMEVT_BASE	0x0160
@@ -222,6 +223,9 @@ enum riscv_iommu_ddtp_modes {
 
 /* Number of defined performance-monitoring event selectors */
 #define RISCV_IOMMU_IOHPMEVT_CNT	31
+/* Cycles counter is statically indexed as the last counter */
+#define RISCV_IOMMU_HPMCOUNTER_CYCLES	RISCV_IOMMU_IOHPMEVT_CNT
+#define RISCV_IOMMU_HPMCOUNTER_MAX	(RISCV_IOMMU_IOHPMEVT_CNT + 1)
 
 /**
  * enum riscv_iommu_hpmevent_id - Performance-monitoring event identifier
@@ -250,6 +254,8 @@ enum riscv_iommu_hpmevent_id {
 	RISCV_IOMMU_HPMEVENT_MAX        = 9
 };
 
+#define RISCV_IOMMU_HPMEVENT_CYCLES	RISCV_IOMMU_HPMEVENT_INVALID
+
 /* 5.24 Translation request IOVA (64bits) */
 #define RISCV_IOMMU_REG_TR_REQ_IOVA     0x0258
 #define RISCV_IOMMU_TR_REQ_IOVA_VPN	GENMASK_ULL(63, 12)
drivers/iommu/riscv/iommu-hpm.c new file +843 -0

843 lines not on this page · raw message

drivers/iommu/riscv/iommu-pci.c +11 -2
index d82d2b00904c..71407aecbf92 100644
@@ -34,6 +34,8 @@ static int riscv_iommu_pci_probe(struct pci_dev *pdev, const struct pci_device_i
 {
 	struct device *dev = &pdev->dev;
 	struct riscv_iommu_device *iommu;
+	phys_addr_t reg_phys;
+	resource_size_t reg_size;
 	int rc, vec;
 
 	rc = pcim_enable_device(pdev);
@@ -43,7 +45,9 @@ static int riscv_iommu_pci_probe(struct pci_dev *pdev, const struct pci_device_i
 	if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM))
 		return -ENODEV;
 
-	if (pci_resource_len(pdev, 0) < RISCV_IOMMU_REG_SIZE)
+	reg_phys = pci_resource_start(pdev, 0);
+	reg_size = pci_resource_len(pdev, 0);
+	if (reg_size < RISCV_IOMMU_REG_SIZE)
 		return -ENODEV;
 
 	rc = pcim_iomap_regions(pdev, BIT(0), pci_name(pdev));
@@ -56,6 +60,8 @@ static int riscv_iommu_pci_probe(struct pci_dev *pdev, const struct pci_device_i
 
 	iommu->dev = dev;
 	iommu->reg = pcim_iomap_table(pdev)[0];
+	iommu->reg_phys = reg_phys;
+	iommu->reg_size = reg_size;
 
 	pci_set_master(pdev);
 	dev_set_drvdata(dev, iommu);
@@ -91,7 +97,10 @@ static int riscv_iommu_pci_probe(struct pci_dev *pdev, const struct pci_device_i
 		riscv_iommu_writel(iommu, RISCV_IOMMU_REG_FCTL, iommu->fctl);
 	}
 
-	return riscv_iommu_init(iommu);
+	rc = riscv_iommu_init(iommu);
+	if (rc)
+		return rc;
+	return riscv_iommu_add_hpm(iommu);
 }
 
 static void riscv_iommu_pci_remove(struct pci_dev *pdev)
drivers/iommu/riscv/iommu-platform.c +7 -1
index 83a28c83f991..684bc267ac30 100644
@@ -62,6 +62,9 @@ static int riscv_iommu_platform_probe(struct platform_device *pdev)
 		return dev_err_probe(dev, PTR_ERR(iommu->reg),
 				     "could not map register region\n");
 
+	iommu->reg_phys = res->start;
+	iommu->reg_size = resource_size(res);
+
 	dev_set_drvdata(dev, iommu);
 
 	/* Check device reported capabilities / features. */
@@ -134,7 +137,10 @@ static int riscv_iommu_platform_probe(struct platform_device *pdev)
 		return dev_err_probe(dev, -ENODEV, "invalid IGS\n");
 	}
 
-	return riscv_iommu_init(iommu);
+	ret = riscv_iommu_init(iommu);
+	if (ret)
+		return ret;
+	return riscv_iommu_add_hpm(iommu);
 };
 
 static void riscv_iommu_platform_remove(struct platform_device *pdev)
drivers/iommu/riscv/iommu.h +42 -0

72 lines not on this page · raw message

Signature · 1 line
2.43.0
#39 lore raw

Re: [PATCH v3 3/8] iommu/riscv: Add HPM support for performance monitoring

How does this relate to

https://lore.kernel.org/all/[email protected]/

From a quick skim it looks like there's plenty of overlap.

Thanks,
drew

Quoted 27 lines · Lv Zheng

From: Jingyu Li <[email protected]>

Introduces perf-based HPM driver for RISC-V IOMMU, enabling performance monitoring capabilities.

Note that the RISC-V IOMMU HPM module uses COUNTER_MAX-1 as a static counter index of HPMCYCLES, and 0~COUNTER_MAX-2 as the dynamic counter indexes of other HPMEVENTS in order to correctly index into IOHPMEVT and IOHPMCTR registers that have already been defined in the iommu-bits.h. However the users treat 0 as the index of HPMCYCLES and 1~COUNTER_MAX-1 as the indexes of other HPMEVENTS, thus care should be taken in dealing with counter indexes between userspace and kernel space.

---
 drivers/iommu/riscv/Kconfig          |   9 +
 drivers/iommu/riscv/Makefile         |   1 +
 drivers/iommu/riscv/iommu-bits.h     |   6 +
 drivers/iommu/riscv/iommu-hpm.c      | 843 +++++++++++++++++++++++++++
 drivers/iommu/riscv/iommu-pci.c      |  13 +-
 drivers/iommu/riscv/iommu-platform.c |   8 +-
 drivers/iommu/riscv/iommu.h          |  42 ++
 7 files changed, 919 insertions(+), 3 deletions(-)
 create mode 100644 drivers/iommu/riscv/iommu-hpm.c
#40 lore raw

Re: [PATCH v3 3/8] iommu/riscv: Add HPM support for performance monitoring

Quoted 10 lines · Andrew Jones

How does this relate to

https://lore.kernel.org/all/[email protected]/

From a quick skim it looks like there's plenty of overlap.

Thanks,
drew

Hi all,

Thanks Andrew for bringing me here, and sorry for the long delay on the IOMMU PMU driver series.

I’m currently working on the next version to incorporate the feedback from my earlier series. The main goals are to decouple the IOMMU perf driver from the IOMMU driver itself, and to make it easier to add custom events.
The implementation is almost done, but I’m still working on binding a name between the PMU driver with the IOMMU driver on PCIe and ACPI cases. This part is related to how custom events should be added. That said, I’m thinking that I could submit the current implementation first, and then send a separate patch series later to handle the custom event support.

Also, I’d like to mention that Yaxing has a similar implementation. We had some discussion about this last month.
https://lore.kernel.org/linux-iommu/[email protected]/

I think I should be able to submit this next week.

Thanks,

Quoted 29 lines · Lv Zheng
Quoted 27 lines

From: Jingyu Li <[email protected]>

Introduces perf-based HPM driver for RISC-V IOMMU, enabling performance monitoring capabilities.

Note that the RISC-V IOMMU HPM module uses COUNTER_MAX-1 as a static counter index of HPMCYCLES, and 0~COUNTER_MAX-2 as the dynamic counter indexes of other HPMEVENTS in order to correctly index into IOHPMEVT and IOHPMCTR registers that have already been defined in the iommu-bits.h. However the users treat 0 as the index of HPMCYCLES and 1~COUNTER_MAX-1 as the indexes of other HPMEVENTS, thus care should be taken in dealing with counter indexes between userspace and kernel space.

---
 drivers/iommu/riscv/Kconfig          |   9 +
 drivers/iommu/riscv/Makefile         |   1 +
 drivers/iommu/riscv/iommu-bits.h     |   6 +
 drivers/iommu/riscv/iommu-hpm.c      | 843 +++++++++++++++++++++++++++
 drivers/iommu/riscv/iommu-pci.c      |  13 +-
 drivers/iommu/riscv/iommu-platform.c |   8 +-
 drivers/iommu/riscv/iommu.h          |  42 ++
 7 files changed, 919 insertions(+), 3 deletions(-)
 create mode 100644 drivers/iommu/riscv/iommu-hpm.c
#41 lore raw

Re: [PATCH v3 3/8] iommu/riscv: Add HPM support for performance monitoring

In reply to Andrew Jones
Quoted 5 lines · Andrew Jones

How does this relate to

https://lore.kernel.org/all/[email protected]/

From a quick skim it looks like there's plenty of overlap.

We developed the driver in 2024 and demonstrated it in China summit. We didn't notice that a patch is on-going now in the community.

Now it looks our approach solved more issues, and we'll check and update if there are any community concerns still not addressed in this patchset.

We can add Reviewed-by/Tested-by and Signed-off-by of Zong Li to this patch if he wishes.

Thanks,
Lv

Quoted 34 lines

Thanks,
drew

Quoted 27 lines · Lv Zheng

From: Jingyu Li <[email protected]>

Introduces perf-based HPM driver for RISC-V IOMMU, enabling performance monitoring capabilities.

Note that the RISC-V IOMMU HPM module uses COUNTER_MAX-1 as a static counter index of HPMCYCLES, and 0~COUNTER_MAX-2 as the dynamic counter indexes of other HPMEVENTS in order to correctly index into IOHPMEVT and IOHPMCTR registers that have already been defined in the iommu-bits.h. However the users treat 0 as the index of HPMCYCLES and 1~COUNTER_MAX-1 as the indexes of other HPMEVENTS, thus care should be taken in dealing with counter indexes between userspace and kernel space.

---
  drivers/iommu/riscv/Kconfig          |   9 +
  drivers/iommu/riscv/Makefile         |   1 +
  drivers/iommu/riscv/iommu-bits.h     |   6 +
  drivers/iommu/riscv/iommu-hpm.c      | 843 +++++++++++++++++++++++++++
  drivers/iommu/riscv/iommu-pci.c      |  13 +-
  drivers/iommu/riscv/iommu-platform.c |   8 +-
  drivers/iommu/riscv/iommu.h          |  42 ++
  7 files changed, 919 insertions(+), 3 deletions(-)

create mode 100644 drivers/iommu/riscv/iommu-hpm.c

#42 lore raw

Re: [PATCH v3 3/8] iommu/riscv: Add HPM support for performance monitoring

Quoted 11 lines · Lv Zheng
Quoted 5 lines · Andrew Jones

How does this relate to

https://lore.kernel.org/all/[email protected]/

From a quick skim it looks like there's plenty of overlap.

We developed the driver in 2024 and demonstrated it in China summit. We didn't notice that a patch is on-going now in the community.

Quoted 9 lines

Now it looks our approach solved more issues, and we'll check and update if there are any community concerns still not addressed in this patchset.

We can add Reviewed-by/Tested-by and Signed-off-by of Zong Li to this patch if he wishes.

Thanks,
Lv

Perhaps I can first post my next revision to the mailing list (hope it won't waste the community resource), so that you could have a chance to review it and see whether that version is architecturally closer to what the community is looking for, while also addressing your issue. If you also feel that my next revision meets your needs, perhaps you could append your additional implementations on top of it.

Of course, if the community would prefer to go your version, I’m perfectly fine with that as well.

Quoted 35 lines
Quoted 34 lines

Thanks,
drew

Quoted 27 lines · Lv Zheng

From: Jingyu Li <[email protected]>

Introduces perf-based HPM driver for RISC-V IOMMU, enabling performance monitoring capabilities.

Note that the RISC-V IOMMU HPM module uses COUNTER_MAX-1 as a static counter index of HPMCYCLES, and 0~COUNTER_MAX-2 as the dynamic counter indexes of other HPMEVENTS in order to correctly index into IOHPMEVT and IOHPMCTR registers that have already been defined in the iommu-bits.h. However the users treat 0 as the index of HPMCYCLES and 1~COUNTER_MAX-1 as the indexes of other HPMEVENTS, thus care should be taken in dealing with counter indexes between userspace and kernel space.

---
  drivers/iommu/riscv/Kconfig          |   9 +
  drivers/iommu/riscv/Makefile         |   1 +
  drivers/iommu/riscv/iommu-bits.h     |   6 +
  drivers/iommu/riscv/iommu-hpm.c      | 843 +++++++++++++++++++++++++++
  drivers/iommu/riscv/iommu-pci.c      |  13 +-
  drivers/iommu/riscv/iommu-platform.c |   8 +-
  drivers/iommu/riscv/iommu.h          |  42 ++
  7 files changed, 919 insertions(+), 3 deletions(-)

create mode 100644 drivers/iommu/riscv/iommu-hpm.c

#43 lore raw

Re: [PATCH v3 3/8] iommu/riscv: Add HPM support for performance monitoring

Quoted 22 lines · Zong Li
Quoted 11 lines · Lv Zheng
Quoted 5 lines · Andrew Jones

How does this relate to

https://lore.kernel.org/all/[email protected]/

From a quick skim it looks like there's plenty of overlap.

We developed the driver in 2024 and demonstrated it in China summit. We didn't notice that a patch is on-going now in the community.

Quoted 9 lines

Now it looks our approach solved more issues, and we'll check and update if there are any community concerns still not addressed in this patchset.

We can add Reviewed-by/Tested-by and Signed-off-by of Zong Li to this patch if he wishes.

Thanks,
Lv

Quoted 7 lines

Perhaps I can first post my next revision to the mailing list (hope it won't waste the community resource), so that you could have a chance to review it and see whether that version is architecturally closer to what the community is looking for, while also addressing your issue. If you also feel that my next revision meets your needs, perhaps you could append your additional implementations on top of it.

It seems we all composed the RISC-V iommu HPM support by referencing drivers/perf/arm_smmuv3_pmu.

Robin's comments should all be addressed IMHO.

Quoted 2 lines

Of course, if the community would prefer to go your version, I’m perfectly fine with that as well.

OK. If we send a next version, we will add your SOB and please help to review and test.

Thanks in advance,
Lv

Quoted 37 lines
Quoted 36 lines
Quoted 35 lines

Thanks,
drew

Quoted 27 lines · Lv Zheng

From: Jingyu Li <[email protected]>

Introduces perf-based HPM driver for RISC-V IOMMU, enabling performance monitoring capabilities.

Note that the RISC-V IOMMU HPM module uses COUNTER_MAX-1 as a static counter index of HPMCYCLES, and 0~COUNTER_MAX-2 as the dynamic counter indexes of other HPMEVENTS in order to correctly index into IOHPMEVT and IOHPMCTR registers that have already been defined in the iommu-bits.h. However the users treat 0 as the index of HPMCYCLES and 1~COUNTER_MAX-1 as the indexes of other HPMEVENTS, thus care should be taken in dealing with counter indexes between userspace and kernel space.

---
   drivers/iommu/riscv/Kconfig          |   9 +
   drivers/iommu/riscv/Makefile         |   1 +
   drivers/iommu/riscv/iommu-bits.h     |   6 +
   drivers/iommu/riscv/iommu-hpm.c      | 843 +++++++++++++++++++++++++++
   drivers/iommu/riscv/iommu-pci.c      |  13 +-
   drivers/iommu/riscv/iommu-platform.c |   8 +-
   drivers/iommu/riscv/iommu.h          |  42 ++
   7 files changed, 919 insertions(+), 3 deletions(-)

create mode 100644 drivers/iommu/riscv/iommu-hpm.c

#44 lore raw

Re: [PATCH v3 3/8] iommu/riscv: Add HPM support for performance monitoring

Quoted 34 lines · Lv Zheng
Quoted 22 lines · Zong Li
Quoted 11 lines · Lv Zheng
Quoted 5 lines · Andrew Jones

How does this relate to

https://lore.kernel.org/all/[email protected]/

From a quick skim it looks like there's plenty of overlap.

We developed the driver in 2024 and demonstrated it in China summit. We didn't notice that a patch is on-going now in the community.

Quoted 9 lines

Now it looks our approach solved more issues, and we'll check and update if there are any community concerns still not addressed in this patchset.

We can add Reviewed-by/Tested-by and Signed-off-by of Zong Li to this patch if he wishes.

Thanks,
Lv

Quoted 7 lines

Perhaps I can first post my next revision to the mailing list (hope it won't waste the community resource), so that you could have a chance to review it and see whether that version is architecturally closer to what the community is looking for, while also addressing your issue. If you also feel that my next revision meets your needs, perhaps you could append your additional implementations on top of it.

It seems we all composed the RISC-V iommu HPM support by referencing drivers/perf/arm_smmuv3_pmu.

Quoted 7 lines

Robin's comments should all be addressed IMHO.

Quoted 2 lines

Of course, if the community would prefer to go your version, I’m perfectly fine with that as well.

OK. If we send a next version, we will add your SOB and please help to review and test.

Zong Li's SOB should only be on the patches he authored. Don't put anybody's SOB on patches they haven't been involved in. See Documentation/process/submitting-patches.rst
"""
The Signed-off-by: tag indicates that the signer was involved in the development of the patch, or that he/she was in the patch's delivery path. """

Since Zong Li's patches were already on the list then your series should at least discuss them in the cover letter, explaining why you've opted not to adopt them. But, most likely some of the patches can be adopted, so those should be extracted from Zong Li's work (with authorship preserved) and based upon in order to respect that prior work.

Thanks,
drew

#45 lore raw

Re: [PATCH v3 3/8] iommu/riscv: Add HPM support for performance monitoring

Quoted 51 lines · Andrew Jones
Quoted 34 lines · Lv Zheng
Quoted 22 lines · Zong Li
Quoted 11 lines · Lv Zheng
Quoted 5 lines · Andrew Jones

How does this relate to

https://lore.kernel.org/all/[email protected]/

From a quick skim it looks like there's plenty of overlap.

We developed the driver in 2024 and demonstrated it in China summit. We didn't notice that a patch is on-going now in the community.

Quoted 9 lines

Now it looks our approach solved more issues, and we'll check and update if there are any community concerns still not addressed in this patchset.

We can add Reviewed-by/Tested-by and Signed-off-by of Zong Li to this patch if he wishes.

Thanks,
Lv

Quoted 7 lines

Perhaps I can first post my next revision to the mailing list (hope it won't waste the community resource), so that you could have a chance to review it and see whether that version is architecturally closer to what the community is looking for, while also addressing your issue. If you also feel that my next revision meets your needs, perhaps you could append your additional implementations on top of it.

It seems we all composed the RISC-V iommu HPM support by referencing drivers/perf/arm_smmuv3_pmu.

Quoted 7 lines

Robin's comments should all be addressed IMHO.

Quoted 2 lines

Of course, if the community would prefer to go your version, I’m perfectly fine with that as well.

OK. If we send a next version, we will add your SOB and please help to review and test.

Zong Li's SOB should only be on the patches he authored. Don't put anybody's SOB on patches they haven't been involved in. See Documentation/process/submitting-patches.rst
"""
The Signed-off-by: tag indicates that the signer was involved in the development of the patch, or that he/she was in the patch's delivery path. """

Quoted 5 lines

Since Zong Li's patches were already on the list then your serieswould> at least discuss them in the cover letter, explaining why you've opted not to adopt them. But, most likely some of the patches can be adopted,
so those should be extracted from Zong Li's work (with authorship
preserved) and based upon in order to respect that prior work.

You can see we have contacted each other in community, and decided to cooperate in this way to honor his contribution. But final decision is left for the community to decide:

From Zong Li:

Quoted 2 lines
Quoted 2 lines

Of course, if the community would prefer to go your version, I’m perfectly fine with that as well.

We respect all contributions, We'll add the link in cover letter to the follow-up revisions, let me know if anything else should be done to the new revisions.

--------------------------------------------------------------------

And let me describe in details to compare the functionalities and addressed comments between what is provided by Joey and by Zong:

https://lore.kernel.org/all/[email protected]/

There is no missing functionalities between the two approaches, I also checked the original Robin's comments, let me describe them in details:

1. The following comments require a split CYCLES implementation:

comment 1:

Quoted 3 lines
Quoted 3 lines

Why not use an extra config bit to encode cycles events completely independently of the regular eventID space? Or even just use 0 since by definition that cannot overlap a valid eventID?

comment 2:

Quoted 2 lines
Quoted 2 lines

It's also horribly confusing to use GENMASK for something which is not actually a mask at all.

comment 3:

Quoted 11 lines
Quoted 11 lines

Hmm, from experience I would expect these variables to be number-of-counters related, but I guess there must be some special cleverness going on since that number-of-counters looking RISCV_IOMMU_HPM_COUNTER_NUM definition is conspicuously not used, so it must be significant that these are instead related to the number of...

[ goes off to search code... ]

...event selectors? But with a magic +1 for reasons so obvious they clearly don't need explaining.

comment 4:

Quoted 2 lines
Quoted 2 lines

One of those conditions is literally impossible, the other should already be avoided by construction.

comment 5:

Quoted 5 lines
Quoted 5 lines

I don't think you need this - as best I can tell, you never initialise a counter without also (re)enabling the interrupt (which is logical), so since "value" for the cycle counter should always implicitly have OF=0 anyway, it should work to just write it like the other counters.

comment 6:

Quoted 3 lines
Quoted 3 lines

Is RISCV_IOMMU_IOHPMCTR_COUNTER honestly useful? Or is it actively hurting readability by obfuscating that we are in fact just using the full 64-bit value in all those places?

comment 7:

Quoted 1 line
Quoted 1 line

And that's a very creative way to spell "if (idx == 0)".

comment 8:

Quoted 2 lines
Quoted 2 lines

(and as above, I think you can make this a no-op for the cycle counter)

These comments require a software architecture change to handle CYCLES in a neat way. CYCLES is split and handled in the clean way in iommu-hpm.

2. The following comments require an uncore non-sampling mechanism:

comment 1:

Quoted 2 lines
Quoted 2 lines

You also need a "cpumask" attribute to tell userspace this is a system/uncore PMU.

comment 2:

Quoted 3 lines
Quoted 3 lines

None of this is relevant or necessary. This is not a CPU PMU, so it can't support sampling because it doesn't have a meaningful context to sample.

comment 3:

Quoted 2 lines
Quoted 2 lines

You first need to validate that the event is for this PMU at all, and return -ENOENT if not.

comment 4:

Quoted 5 lines
Quoted 5 lines

As above, you can't support sampling events anyway, so you should reject them with -EINVAL.

You also need to validate event groups to ensure they don't contain more events than could ever be scheduled at once.

comment 5:

Quoted 4 lines
Quoted 4 lines

This will never do anything, since even if we could ever get here, it would not be at a time when there are any active events. Unregistering an in-use PMU does not end well (hence why standalone PMU drivers need to use suppress_bind_attrs)...

Here, Joey does check PMU type, does not include sampling event stuffs, and cpuhp is handled in a fine grained locking way. And since locking is handled correctly, it's safe to keep iommu-hpm as tristate. The new approach requires more system software architecture techniques.

3. The following comments require a IRQ handling improvement:

comment 1:

Quoted 3 lines
Quoted 3 lines

TBH I'd be inclined to just leave out all the dead cleanup code if the PMU driver is tied to the IOMMU driver and can never realistically be removed.

comment 2:

Quoted 3 lines
Quoted 3 lines

Surely this should only touch the counter(s) that overflowed and have been handled? It might be cleaner to keep that within the IRQ handler itself.

comment 3:

Quoted 1 line
Quoted 1 line

This needs to start all active counters together, not one-by-one.

comment 4:

Quoted 5 lines
Quoted 5 lines

This does nothing, since set_event has just implicitly written OF=0.

...unless, that is, the user was mischievous and also set bit 63 in event->attr.config, since you never sanitised the input ;)

comment 5:

Quoted 6 lines
Quoted 6 lines

What do these regs represent? If you look at the perf_event_open ABI, you'll see that events can target various combinations of CPU and/or pid, but there is no encoding for "whichever CPU takes the IOMMU PMU interrupt". Thus whatever you get here is more than likely not what the user asked for, and this is why non-CPU PMUs cannot reasonably support sampling ;)

comment 6:

Quoted 3 lines
Quoted 3 lines

You still need to handle counter rollover for all events, otherwise they can start losing counts and rapidly turn to nonsense. Admittedly it's largely theoretical with full 64-bit counters, but still...

comment 7:

Quoted 7 lines
Quoted 7 lines

Hmm, shared interrupts are tricky for PMUs, since perf requires any IRQ handler touching a PMU is running on pmu->cpu, so you have to be very careful about maintaining affinity and not letting anyone else change it behind your back.

The other thing is that if it really is shared, at this point you could now be in riscv_iommu_pmu_handle_irq() dereferencing NULL.

comment 8:

Quoted 6 lines
Quoted 6 lines

In general it's not a great idea to register an IRQ handler before the data passed to that handler is initialised. What is pointed to by (&iommu->pmu)->reg + RISCV_IOMMU_REG_IOCOUNTOVF if the IRQ fires right now (and/or if CONFIG_DEBUG_SHIRQ ever gets fixed)? ;)

(OK, it's not *literally* NULL, but hey...)

Here OVF interrupt is handled as a standalone threaded per-cpu shared IRQ in iommu-hpm.c and iocountinh register is not used as OVF interrupt is always enabled and overflows is stored to software counters. The new approach passed testings.

4. Other programming style fixes, they are all not in this patch.

comment 1:

Quoted 1 line
Quoted 1 line

sysfs_emit()

No such problem here.

comment 2:

Quoted 3 lines
Quoted 3 lines

Might be worth leaving a comment just in case anyone does try to enable this for 32-bit that the io-64-nonatomic readq() isn't enough to work properly here.

Not addressed in v3 and v4. And probably not necessary.

comment 3:

Quoted 2 lines
Quoted 2 lines

That's a wonderfully expensive way to spell
"pmu->events[idx]->hw.config"...

No such problem here, get_event() is used.

comment 4:

Quoted 9 lines
Quoted 9 lines

Initially this looks weird - why bother storing constants in memory if they're constant? - but I see the spec implies they are not necessarily fixed, and we can only actually assume at least one counter at least 32 bits wide, so I guess this is really more of a placeholder? Is there a well-defined way we're supposed to be able to discover these, like some more ID register fields somewhere, or writing all 1s to various registers to see what sticks, or is it liable to be a mess of just having to know what each implementation has by matching DT compatibles and/or PCI IDs?

Here WARL registers are handled in RISC-V programming style.

comment 5:

Quoted 3 lines
Quoted 3 lines

The new thing is that you can now set pmu.parent to the IOMMU device so their relationship is clear in sysfs, rather than having to play tricks with the PMU name.

Not addressed here but addressed in v4.

IMO, the Joey's approach addressed issue 1, 2 and 3, which does require more software architecture changes. Her contribution and authorship might also be honored.

--------------------------------------------------------------------

Am I missing something in the above list? Robin might help to confirm if the new approach has addressed all his comments.

Thanks and best regards,
Lv

Quoted 3 lines

Thanks,
drew

#46 lore raw

Re: [PATCH v3 3/8] iommu/riscv: Add HPM support for performance monitoring

Quoted 1 line · Lv Zheng

On 2/5/2026 11:23 PM, Andrew Jones wrote:

...

Quoted 11 lines
Quoted 1 line

Since Zong Li's patches were already on the list then your serieswould> at

least discuss them in the cover letter, explaining why you've opted

Quoted 4 lines

not to adopt them. But, most likely some of the patches can be adopted, so those should be extracted from Zong Li's work (with authorship preserved) and based upon in order to respect that prior work.

You can see we have contacted each other in community, and decided to cooperate in this way to honor his contribution. But final decision is left for the community to decide:

Quoted 7 lines

From Zong Li:

Quoted 2 lines
Quoted 2 lines

Of course, if the community would prefer to go your version, I’m perfectly fine with that as well.

We respect all contributions, We'll add the link in cover letter to the follow-up revisions, let me know if anything else should be done to the new revisions.

Just do all the communication before posting, allowing that communication to be summarized in the cover letter and in any appropriate commit messages so reviewers know what's going on. Also don't forget to CC anybody previously involved to ensure they have a chance to chime in.

Quoted 10 lines

--------------------------------------------------------------------

And let me describe in details to compare the functionalities and addressed comments between what is provided by Joey and by Zong:

https://lore.kernel.org/all/[email protected]/

There is no missing functionalities between the two approaches, I also checked the original Robin's comments, let me describe them in details:

My concern wasn't whether or not Robin's comments were addressed in this posting (that's important, but not what I'm talking about). My concern was that Zong Li's work wasn't addressed in any way, so appeared to be a chance for duplicated efforts. Indeed his reply [1] indicates exactly that and even that there is a third patch series being worked independently. Please work out who and what patches are going to be the focus going forward and describe that decision in the cover letter for the next revision. And please don't forget to CC Zong Li and Yaxing Guo.

[1] https://lore.kernel.org/all/CANXhq0oi9nE7ffLGsz5j8GnC1UDTD-4bE4cantRjW2fXHYrjHA@mail.gmail.com/

Thanks,
drew

#47 lore raw

Re: [PATCH v3 3/8] iommu/riscv: Add HPM support for performance monitoring

Quoted 49 lines · Andrew Jones
Quoted 1 line · Lv Zheng

On 2/5/2026 11:23 PM, Andrew Jones wrote:

...

Quoted 11 lines
Quoted 1 line

Since Zong Li's patches were already on the list then your serieswould> at

least discuss them in the cover letter, explaining why you've opted

Quoted 4 lines

not to adopt them. But, most likely some of the patches can be adopted, so those should be extracted from Zong Li's work (with authorship preserved) and based upon in order to respect that prior work.

You can see we have contacted each other in community, and decided to cooperate in this way to honor his contribution. But final decision is left for the community to decide:

Quoted 7 lines

From Zong Li:

Quoted 2 lines
Quoted 2 lines

Of course, if the community would prefer to go your version, I’m perfectly fine with that as well.

We respect all contributions, We'll add the link in cover letter to the follow-up revisions, let me know if anything else should be done to the new revisions.

Just do all the communication before posting, allowing that communication to be summarized in the cover letter and in any appropriate commit messages so reviewers know what's going on. Also don't forget to CC anybody previously involved to ensure they have a chance to chime in.

Quoted 10 lines

--------------------------------------------------------------------

And let me describe in details to compare the functionalities and addressed comments between what is provided by Joey and by Zong:

https://lore.kernel.org/all/[email protected]/

There is no missing functionalities between the two approaches, I also checked the original Robin's comments, let me describe them in details:

My concern wasn't whether or not Robin's comments were addressed in this posting (that's important, but not what I'm talking about). My concern was that Zong Li's work wasn't addressed in any way, so appeared to be a chance for duplicated efforts. Indeed his reply [1] indicates exactly that and even that there is a third patch series being worked independently. Please work out who and what patches are going to be the focus going forward and describe that decision in the cover letter for the next revision. And please don't forget to CC Zong Li and Yaxing Guo.

Quoted 2 lines

[1] https://lore.kernel.org/all/CANXhq0oi9nE7ffLGsz5j8GnC1UDTD-4bE4cantRjW2fXHYrjHA@mail.gmail.com/

First of all, I apologize for the delay of the PMU series and any inconvenience it may have caused. I also really appreciate Andrew for pointing out the upstream culture and consensus.

My next version (v3 series) is expected to be sent out in the next couple of days. It will pick up all the suggestions and feedback from the previous versions. Apart from that, the main structural change is that the PMU driver has been moved under drivers/perf/, which is something that has been mentioned repeatedly by several people.

To allow everyone to review the major changes in the next version as soon as possible, the custom event support will be split into a separate series. Its overall idea will be similar to a typical platform driver, where vendor-specific PMU events are defined through driver data. More details will be described in the v3 cover letter.

Additionally, since I did not follow up the patches from Lv Zheng, Jingyu Li, or Yaxing, it is very possible that my v3 series may miss some important features or fixes from their work. If that is the case, I apologize, I was not aware that those patches had been posted to the mailing list, which is also why I did not respond to their v1 patch series in a timely manner. Therefore, I would really appreciate it if everyone could help review the v3 series and point out any additional fixes or feature support that I may have missed.

I also really appreciate everyone for always helping to bring us together and keep the discussions aligned.
Thanks

Quoted 2 lines

Thanks,
drew

#48 lore raw

PATCH v3 4/8 dt-bindings: iommu: Add spacemit/t100 features

In reply to a message not in the archive

Adds device tree bindings for SpacemiT T100 specific features by introducing spacemit,100 compatible. T100 contains distributed IOATCs, each of which exposes pmiv interrupt.

---
 .../bindings/iommu/riscv,iommu.yaml           | 37 +++++++++++++++++++
 1 file changed, 37 insertions(+)
Documentation/devicetree/bindings/iommu/riscv,iommu.yaml +37 -0
index d4838c3b3741..2da3456e7402 100644
@@ -32,6 +32,12 @@ properties:
   # should be specified along with 'reg' property providing MMIO location.
   compatible:
     oneOf:
+      - description: SpacemiT distributed IOMMUs
+        items:
+          - enum:
+              - spacemit,t100
+          - const: spacemit,riscv-iommu
+          - const: riscv,iommu
       - items:
           - enum:
               - qemu,riscv-iommu
@@ -75,6 +81,23 @@ required:
 
 additionalProperties: false
 
+select: false
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: spacemit,riscv-iommu
+    then:
+      properties:
+        interrupts:
+          maxItems: 68
+          description:
+            SpacemiT distributed IOMMU includes additional interrupts for
+            IOATCs. Each IOATC exposes pmiv wired vector as standalone
+            interrupt and the maximum number of IOATCs can be up to 64.
+
 examples:
   - |+
     /* Example 1 (IOMMU device with wired interrupts) */
@@ -145,3 +168,17 @@ examples:
             };
         };
     };
+
+  - |+
+    /* Example 5 (SpacemiT distributed IOMMU) */
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    iommu4: iommu@1bccd000 {
+        compatible = "spacemit,t100", "spacemit,riscv-iommu", "riscv,iommu";
+        reg = <0x1bccd000 0x1000>;
+        interrupts = <58 IRQ_TYPE_LEVEL_HIGH>, <58 IRQ_TYPE_LEVEL_HIGH>,
+                     <58 IRQ_TYPE_LEVEL_HIGH>, <58 IRQ_TYPE_LEVEL_HIGH>,
+                     <62 IRQ_TYPE_LEVEL_HIGH>, <63 IRQ_TYPE_LEVEL_HIGH>;
+        interrupt-parent = <&saplic>;
+        #iommu-cells = <0x01>;
+    };
Signature · 1 line
2.43.0
#49 lore raw

Re: [PATCH v3 4/8] dt-bindings: iommu: Add spacemit/t100 features

Quoted 15 lines · Lv Zheng

Adds device tree bindings for SpacemiT T100 specific features by introducing spacemit,100 compatible. T100 contains distributed IOATCs, each of which exposes pmiv interrupt.

---
 .../bindings/iommu/riscv,iommu.yaml           | 37 +++++++++++++++++++
 1 file changed, 37 insertions(+)
Documentation/devicetree/bindings/iommu/riscv,iommu.yaml +0 -0
index d4838c3b3741..2da3456e7402 100644

Documentation/devicetree/bindings/iommu/riscv,iommu.yaml properties: · line 39

Quoted 8 lines
Documentation/devicetree/bindings/iommu/riscv,iommu.yaml +5 -0
@@ -32,6 +32,12 @@ properties:
   # should be specified along with 'reg' property providing MMIO location.
   compatible:
     oneOf:
+      - description: SpacemiT distributed IOMMUs
+        items:
+          - enum:
+              - spacemit,t100
+          - const: spacemit,riscv-iommu

What actually is the t100? Is it an SoC or is it the name of the core complex IP that spacemit is using in multiple SoCs?

Documentation/devicetree/bindings/iommu/riscv,iommu.yaml required: · line 84

Quoted 9 lines
Documentation/devicetree/bindings/iommu/riscv,iommu.yaml +2 -0
+          - const: riscv,iommu
       - items:
           - enum:
               - qemu,riscv-iommu
@@ -75,6 +81,23 @@ required:
 
 additionalProperties: false
 
+select: false

Why is this here? It just breaks the whole binding.
pw-bot: changes-requested

Documentation/devicetree/bindings/iommu/riscv,iommu.yaml required: · line 95

Quoted 11 lines
Documentation/devicetree/bindings/iommu/riscv,iommu.yaml +11 -0
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: spacemit,riscv-iommu
+    then:
+      properties:
+        interrupts:
+          maxItems: 68

This isn't right. You would need to make the interrupts property itself have maxItems: 68, then add an else to this conditional that has
maxItems: 4. What you've done just doesn't work, and if you removed the "select: false: you'd see.

Quoted 9 lines
Documentation/devicetree/bindings/iommu/riscv,iommu.yaml +5 -0
+          description:
+            SpacemiT distributed IOMMU includes additional interrupts for
+            IOATCs. Each IOATC exposes pmiv wired vector as standalone
+            interrupt and the maximum number of IOATCs can be up to 64.
+
 examples:
   - |+
     /* Example 1 (IOMMU device with wired interrupts) */

Documentation/devicetree/bindings/iommu/riscv,iommu.yaml examples: · line 176

Quoted 9 lines
Documentation/devicetree/bindings/iommu/riscv,iommu.yaml +6 -0
@@ -145,3 +168,17 @@ examples:
             };
         };
     };
+
+  - |+
+    /* Example 5 (SpacemiT distributed IOMMU) */
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    iommu4: iommu@1bccd000 {

Remove the iommu4 label, there's no references to it.

Cheers,
Conor.

Quoted 11 lines
Documentation/devicetree/bindings/iommu/riscv,iommu.yaml +8 -0
+        compatible = "spacemit,t100", "spacemit,riscv-iommu", "riscv,iommu";
+        reg = <0x1bccd000 0x1000>;
+        interrupts = <58 IRQ_TYPE_LEVEL_HIGH>, <58 IRQ_TYPE_LEVEL_HIGH>,
+                     <58 IRQ_TYPE_LEVEL_HIGH>, <58 IRQ_TYPE_LEVEL_HIGH>,
+                     <62 IRQ_TYPE_LEVEL_HIGH>, <63 IRQ_TYPE_LEVEL_HIGH>;
+        interrupt-parent = <&saplic>;
+        #iommu-cells = <0x01>;
+    };
Signature · 1 line
2.43.0
#50 lore raw

Re: [PATCH v3 4/8] dt-bindings: iommu: Add spacemit/t100 features

Quoted 11 lines · Conor Dooley
Quoted 10 lines · Lv Zheng

Adds device tree bindings for SpacemiT T100 specific features by introducing spacemit,100 compatible. T100 contains distributed IOATCs, each of which exposes pmiv interrupt.

---
  .../bindings/iommu/riscv,iommu.yaml           | 37 +++++++++++++++++++
  1 file changed, 37 insertions(+)
Quoted 16 lines

Documentation/devicetree/bindings/iommu/riscv,iommu.yaml properties: · line 39

Quoted 13 lines
Documentation/devicetree/bindings/iommu/riscv,iommu.yaml +5 -0
index d4838c3b3741..2da3456e7402 100644
@@ -32,6 +32,12 @@ properties:
    # should be specified along with 'reg' property providing MMIO location.
    compatible:
      oneOf:
+      - description: SpacemiT distributed IOMMUs
+        items:
+          - enum:
+              - spacemit,t100
+          - const: spacemit,riscv-iommu

What actually is the t100? Is it an SoC or is it the name of the core complex IP that spacemit is using in multiple SoCs?

T100 is the name of the IOMMU IP developed by SpacemiT, announced in RISC-V 2024 China Summit:
https://www.bilibili.com/video/BV1DNtCeiEBk/
It's world first server SPEC IOMMU in RISC-V, supports IOTLB placed in adjacent to the DMA masters and supports PCIe ATS and PRI. You can find it shipped in the recent publicly purchasable SoC SpacemiT K3.

Quoted 7 lines
Quoted 7 lines
Documentation/devicetree/bindings/iommu/riscv,iommu.yaml +1 -0
+          - const: riscv,iommu
        - items:
            - enum:
                - qemu,riscv-iommu
@@ -75,6 +81,23 @@ required:
 
Quoted 6 lines

Documentation/devicetree/bindings/iommu/riscv,iommu.yaml required: · line 84

Quoted 3 lines
Documentation/devicetree/bindings/iommu/riscv,iommu.yaml +1 -0
  additionalProperties: false
 
+select: false

Why is this here? It just breaks the whole binding.
pw-bot: changes-requested

OK.

Quoted 17 lines

Documentation/devicetree/bindings/iommu/riscv,iommu.yaml required: · line 95

Quoted 12 lines
Documentation/devicetree/bindings/iommu/riscv,iommu.yaml +11 -0
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: spacemit,riscv-iommu
+    then:
+      properties:
+        interrupts:
+          maxItems: 68

This isn't right. You would need to make the interrupts property itself have maxItems: 68, then add an else to this conditional that has
maxItems: 4. What you've done just doesn't work, and if you removed the "select: false: you'd see.

Indeed, thanks for pointing this out.
Will dig deeper to correct this.

Quoted 13 lines
Quoted 13 lines
Documentation/devicetree/bindings/iommu/riscv,iommu.yaml +5 -0
+          description:
+            SpacemiT distributed IOMMU includes additional interrupts for
+            IOATCs. Each IOATC exposes pmiv wired vector as standalone
+            interrupt and the maximum number of IOATCs can be up to 64.
+
  examples:
    - |+
      /* Example 1 (IOMMU device with wired interrupts) */
@@ -145,3 +168,17 @@ examples:
              };
          };
      };
Quoted 8 lines

Documentation/devicetree/bindings/iommu/riscv,iommu.yaml examples: · line 176

Quoted 6 lines
Documentation/devicetree/bindings/iommu/riscv,iommu.yaml +6 -0
+
+  - |+
+    /* Example 5 (SpacemiT distributed IOMMU) */
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    iommu4: iommu@1bccd000 {

Remove the iommu4 label, there's no references to it.

Sure.

Cheers,
Lv

Quoted 15 lines

Cheers,
Conor.

Quoted 11 lines
Documentation/devicetree/bindings/iommu/riscv,iommu.yaml +8 -0
+        compatible = "spacemit,t100", "spacemit,riscv-iommu", "riscv,iommu";
+        reg = <0x1bccd000 0x1000>;
+        interrupts = <58 IRQ_TYPE_LEVEL_HIGH>, <58 IRQ_TYPE_LEVEL_HIGH>,
+                     <58 IRQ_TYPE_LEVEL_HIGH>, <58 IRQ_TYPE_LEVEL_HIGH>,
+                     <62 IRQ_TYPE_LEVEL_HIGH>, <63 IRQ_TYPE_LEVEL_HIGH>;
+        interrupt-parent = <&saplic>;
+        #iommu-cells = <0x01>;
+    };
Signature · 1 line
2.43.0
#51 lore raw

Re: [PATCH v3 4/8] dt-bindings: iommu: Add spacemit/t100 features

Quoted 29 lines · Lv Zheng
Quoted 11 lines · Conor Dooley
Quoted 10 lines · Lv Zheng

Adds device tree bindings for SpacemiT T100 specific features by introducing spacemit,100 compatible. T100 contains distributed IOATCs, each of which exposes pmiv interrupt.

---
  .../bindings/iommu/riscv,iommu.yaml           | 37 +++++++++++++++++++
  1 file changed, 37 insertions(+)
Quoted 16 lines

Documentation/devicetree/bindings/iommu/riscv,iommu.yaml properties: · line 39

Quoted 13 lines
Documentation/devicetree/bindings/iommu/riscv,iommu.yaml +5 -0
index d4838c3b3741..2da3456e7402 100644
@@ -32,6 +32,12 @@ properties:
    # should be specified along with 'reg' property providing MMIO location.
    compatible:
      oneOf:
+      - description: SpacemiT distributed IOMMUs
+        items:
+          - enum:
+              - spacemit,t100
+          - const: spacemit,riscv-iommu

What actually is the t100? Is it an SoC or is it the name of the core complex IP that spacemit is using in multiple SoCs?

Quoted 6 lines

T100 is the name of the IOMMU IP developed by SpacemiT, announced in RISC-V 2024 China Summit:
https://www.bilibili.com/video/BV1DNtCeiEBk/
It's world first server SPEC IOMMU in RISC-V, supports IOTLB placed in adjacent to the DMA masters and supports PCIe ATS and PRI.
You can find it shipped in the recent publicly purchasable SoC SpacemiT K3.

Right, then what you need here is something like:

items:
- enum:
- spacemit,k3-iommu
- spacemit,t100-iommu
- riscv,iommu

Driver can then match on spacemit,t100-iommu - but you need to have soc-specific compatibles.
I'm not convinced that riscv,iommu is suitable here though, does the driver work on your platform without the portions of code that are added by this series and enabled by your new compatible? If not, the I don't think the riscv,iommu fallback should be here.

Additionally, please stop sending new versions so frequently and in response to earlier submissions. I have a v4 in my inbox while we are still discussing v3.

Cheers,
Conor.

#52 lore raw

Re: [PATCH v3 4/8] dt-bindings: iommu: Add spacemit/t100 features

Quoted 52 lines · Conor Dooley
Quoted 29 lines · Lv Zheng
Quoted 11 lines · Conor Dooley
Quoted 10 lines · Lv Zheng

Adds device tree bindings for SpacemiT T100 specific features by introducing spacemit,100 compatible. T100 contains distributed IOATCs, each of which exposes pmiv interrupt.

---
   .../bindings/iommu/riscv,iommu.yaml           | 37 +++++++++++++++++++
   1 file changed, 37 insertions(+)
Quoted 16 lines

Documentation/devicetree/bindings/iommu/riscv,iommu.yaml properties: · line 39

Quoted 13 lines
Documentation/devicetree/bindings/iommu/riscv,iommu.yaml +5 -0
index d4838c3b3741..2da3456e7402 100644
@@ -32,6 +32,12 @@ properties:
     # should be specified along with 'reg' property providing MMIO location.
     compatible:
       oneOf:
+      - description: SpacemiT distributed IOMMUs
+        items:
+          - enum:
+              - spacemit,t100
+          - const: spacemit,riscv-iommu

What actually is the t100? Is it an SoC or is it the name of the core complex IP that spacemit is using in multiple SoCs?

Quoted 6 lines

T100 is the name of the IOMMU IP developed by SpacemiT, announced in RISC-V 2024 China Summit:
https://www.bilibili.com/video/BV1DNtCeiEBk/
It's world first server SPEC IOMMU in RISC-V, supports IOTLB placed in adjacent to the DMA masters and supports PCIe ATS and PRI.
You can find it shipped in the recent publicly purchasable SoC SpacemiT K3.

Right, then what you need here is something like:

items:
- enum:
- spacemit,k3-iommu
- spacemit,t100-iommu
- riscv,iommu

Driver can then match on spacemit,t100-iommu - but you need to have soc-specific compatibles.
I'm not convinced that riscv,iommu is suitable here though, does the driver work on your platform without the portions of code that are added by this series and enabled by your new compatible? If not, the I don't think the riscv,iommu fallback should be here.

Quoted 3 lines

Additionally, please stop sending new versions so frequently and in response to earlier submissions. I have a v4 in my inbox while we are still discussing v3.

SpacemiT provides RISC-V IOMMU implementation, T100 is the first generation of the this IP product line, we have plan to develop T200, T300, etc., with more features introduced to be adoptive to new RISC-V IOMMU specifications.
Besides, T100 is not only shipped in K3, but also shipped in V100 and the follow-up SoCs, like Kn, Vn00, they will likely use the same synthesis result of T100 RTLs.

From SpacemiT's point of view, we need a common sense of this IP series for something like IOATCs, that's why spacemit,riscv-iommu (this is same like qemu,riscv-iommu) is introduced. And a common sense of T100 for all SoCs shipped T100 (like global filters, vendor events and etc.,).

IMO, the current compatible is proper to reflect these concerns. What do you think?

Cheers,
Lv

Quoted 3 lines

Cheers,
Conor.

#53 lore raw

Re: [PATCH v3 4/8] dt-bindings: iommu: Add spacemit/t100 features

Quoted 65 lines · Lv Zheng
Quoted 52 lines · Conor Dooley
Quoted 29 lines · Lv Zheng
Quoted 11 lines · Conor Dooley
Quoted 10 lines · Lv Zheng

Adds device tree bindings for SpacemiT T100 specific features by introducing spacemit,100 compatible. T100 contains distributed IOATCs, each of which exposes pmiv interrupt.

---
   .../bindings/iommu/riscv,iommu.yaml           | 37 +++++++++++++++++++
   1 file changed, 37 insertions(+)
Quoted 16 lines

Documentation/devicetree/bindings/iommu/riscv,iommu.yaml properties: · line 39

Quoted 13 lines
Documentation/devicetree/bindings/iommu/riscv,iommu.yaml +5 -0
index d4838c3b3741..2da3456e7402 100644
@@ -32,6 +32,12 @@ properties:
     # should be specified along with 'reg' property providing MMIO location.
     compatible:
       oneOf:
+      - description: SpacemiT distributed IOMMUs
+        items:
+          - enum:
+              - spacemit,t100
+          - const: spacemit,riscv-iommu

What actually is the t100? Is it an SoC or is it the name of the core complex IP that spacemit is using in multiple SoCs?

Quoted 6 lines

T100 is the name of the IOMMU IP developed by SpacemiT, announced in RISC-V 2024 China Summit:
https://www.bilibili.com/video/BV1DNtCeiEBk/
It's world first server SPEC IOMMU in RISC-V, supports IOTLB placed in adjacent to the DMA masters and supports PCIe ATS and PRI.
You can find it shipped in the recent publicly purchasable SoC SpacemiT K3.

Right, then what you need here is something like:

items:
- enum:
- spacemit,k3-iommu
- spacemit,t100-iommu
- riscv,iommu

Driver can then match on spacemit,t100-iommu - but you need to have soc-specific compatibles.
I'm not convinced that riscv,iommu is suitable here though, does the driver work on your platform without the portions of code that are added by this series and enabled by your new compatible? If not, the I don't think the riscv,iommu fallback should be here.

Quoted 3 lines

Additionally, please stop sending new versions so frequently and in response to earlier submissions. I have a v4 in my inbox while we are still discussing v3.

SpacemiT provides RISC-V IOMMU implementation, T100 is the first generation of the this IP product line, we have plan to develop T200, T300, etc., with more features introduced to be adoptive to new RISC-V IOMMU specifications.
Besides, T100 is not only shipped in K3, but also shipped in V100 and the follow-up SoCs, like Kn, Vn00, they will likely use the same synthesis result of T100 RTLs.

Quoted 3 lines

From SpacemiT's point of view, we need a common sense of this IP series for something like IOATCs, that's why spacemit,riscv-iommu (this is same like qemu,riscv-iommu) is introduced. And a common sense

No, it's not the same as qemu,riscv-iommu. That exists to avoid riscv,iommu being allowed in isolation and as a "SoC"/integration specific compatible. The driver matches against riscv,iommu not qemu,riscv-iommu and has no qemu,riscv-iommu specific behaviours. It is akin to having spacemit,k3-iommu.

Quoted 5 lines

of T100 for all SoCs shipped T100 (like global filters, vendor events and etc.,).

IMO, the current compatible is proper to reflect these concerns. What do you think?

I pretty much already told you what I think, that you need SoC-specific compatibles for SoCs that integrate this IP and that the you should drop the spacemit,riscv-iommu compatible. The spacemit,riscv-iommu compatible doesn't provide any additional value over spacemit,t100-iommu, and has the downside of maybe being confusing in the future if spacemit produces a iommu that doesn't have the IOATC behaviour.

Also, I don't see an answer to my question about whether the hardware will work without the driver changes this series introduces and enables with the new compatible?

Cheers,
Conor.

#54 lore raw

Re: [PATCH v3 4/8] dt-bindings: iommu: Add spacemit/t100 features

Quoted 70 lines · Conor Dooley
Quoted 65 lines · Lv Zheng
Quoted 52 lines · Conor Dooley
Quoted 29 lines · Lv Zheng
Quoted 11 lines · Conor Dooley
Quoted 10 lines · Lv Zheng

Adds device tree bindings for SpacemiT T100 specific features by introducing spacemit,100 compatible. T100 contains distributed IOATCs, each of which exposes pmiv interrupt.

---
    .../bindings/iommu/riscv,iommu.yaml           | 37 +++++++++++++++++++
    1 file changed, 37 insertions(+)
Quoted 16 lines

Documentation/devicetree/bindings/iommu/riscv,iommu.yaml properties: · line 39

Quoted 13 lines
Documentation/devicetree/bindings/iommu/riscv,iommu.yaml +5 -0
index d4838c3b3741..2da3456e7402 100644
@@ -32,6 +32,12 @@ properties:
      # should be specified along with 'reg' property providing MMIO location.
      compatible:
        oneOf:
+      - description: SpacemiT distributed IOMMUs
+        items:
+          - enum:
+              - spacemit,t100
+          - const: spacemit,riscv-iommu

What actually is the t100? Is it an SoC or is it the name of the core complex IP that spacemit is using in multiple SoCs?

Quoted 6 lines

T100 is the name of the IOMMU IP developed by SpacemiT, announced in RISC-V 2024 China Summit:
https://www.bilibili.com/video/BV1DNtCeiEBk/
It's world first server SPEC IOMMU in RISC-V, supports IOTLB placed in adjacent to the DMA masters and supports PCIe ATS and PRI.
You can find it shipped in the recent publicly purchasable SoC SpacemiT K3.

Right, then what you need here is something like:

items:
- enum:
- spacemit,k3-iommu
- spacemit,t100-iommu
- riscv,iommu

Driver can then match on spacemit,t100-iommu - but you need to have soc-specific compatibles.
I'm not convinced that riscv,iommu is suitable here though, does the driver work on your platform without the portions of code that are added by this series and enabled by your new compatible? If not, the I don't think the riscv,iommu fallback should be here.

Quoted 3 lines

Additionally, please stop sending new versions so frequently and in response to earlier submissions. I have a v4 in my inbox while we are still discussing v3.

SpacemiT provides RISC-V IOMMU implementation, T100 is the first generation of the this IP product line, we have plan to develop T200, T300, etc., with more features introduced to be adoptive to new RISC-V IOMMU specifications.
Besides, T100 is not only shipped in K3, but also shipped in V100 and the follow-up SoCs, like Kn, Vn00, they will likely use the same synthesis result of T100 RTLs.

Quoted 3 lines

From SpacemiT's point of view, we need a common sense of this IP
series for something like IOATCs, that's why spacemit,riscv-iommu (this is same like qemu,riscv-iommu) is introduced. And a common sense

Quoted 5 lines

No, it's not the same as qemu,riscv-iommu. That exists to avoid riscv,iommu being allowed in isolation and as a "SoC"/integration specific compatible. The driver matches against riscv,iommu not qemu,riscv-iommu and has no qemu,riscv-iommu specific behaviours. It is akin to having spacemit,k3-iommu.

Got it.

Quoted 7 lines
Quoted 6 lines

of T100 for all SoCs shipped T100 (like global filters, vendor events and etc.,).

IMO, the current compatible is proper to reflect these concerns. What do you think?

Quoted 6 lines

I pretty much already told you what I think, that you need SoC-specific compatibles for SoCs that integrate this IP and that the you should drop the spacemit,riscv-iommu compatible. The spacemit,riscv-iommu compatible doesn't provide any additional value over spacemit,t100-iommu, and has the downside of maybe being confusing in the future if spacemit produces a iommu that doesn't have the IOATC behaviour.

Sounds reasonable. Thanks.

Quoted 4 lines

Also, I don't see an answer to my question about whether the hardware will work without the driver changes this series introduces and enables with the new compatible?

Basically, T100 is riscv,iommu compatible, its IOATS part should be able to work using standard HPM events with standard riscv,iommu HPM compatible driver. People can now test the real hardware of spacemit T100 on K3.
https://canonical.com/blog/spacemit-announces-availability-of-ubuntu-on-k3-k1-series
I'll try to ask our product team to find third party testers, and if any, adds Cc(s) in the next revision.

Without the awareness of this compatible, hardware will face the following problems:

Handled in this series:
1. No vendor event matches
2. No global filter awareness
3. No IOATC enumeration
That's the basic support introduced in this series to enable some basic features of T100 that we couldn't find in the upstream.

And there are other features not handled in this series:
4. No identities matching vendors
5. No awareness of only PMIV working as WSI, others (CIV/FIV/PIV) are configurable as MSI to make IOATS/IOATC PMIV behaves same and more suitable for kernel performance sampling.
6. And many other SpacemiT specific features people can find the discussions in the IOMMU spec community that is not limited to HPM, ex., RISC-V DMA64 compliance, QEMU old style MSI-PTE support, etc.
7. ACPI support for spacemit,v100-iommu.
8. PCIe ATS/PRI support for spacemit,k3-iommu/spacemit,v100-iommu.
9. etc.

Cheers,
Lv

Quoted 3 lines

Cheers,
Conor.

#55 lore raw

Re: [PATCH v3 4/8] dt-bindings: iommu: Add spacemit/t100 features

Quoted 9 lines · Lv Zheng
Quoted 5 lines

Also, I don't see an answer to my question about whether the hardware will work without the driver changes this series introduces and enables with the new compatible?

Basically, T100 is riscv,iommu compatible, its IOATS part should be able to work using standard HPM events with standard riscv,iommu HPM compatible driver.

That's fine, that's all I wanted to know. The riscv,iommu compatible can stay :)

#56 lore raw

PATCH v3 5/8 riscv/iommu: Add vendor event support for RISC-V IOMMU HPM

In reply to a message not in the archive

Adds mechanism to allow vendor events to be registered via userspace jevents. By default, vendor event identifier matches "riscv,iommu", and the events are registered as "riscv_iommu_hpm" events.

---
 drivers/iommu/riscv/iommu-hpm.c | 63 +++++++++++++++++++++++++++++++++
 drivers/iommu/riscv/iommu.h     |  1 +
 2 files changed, 64 insertions(+)
drivers/iommu/riscv/iommu-hpm.c +63 -0
index f1b265634e51..e140cf59c408 100644
@@ -447,6 +447,30 @@ static const struct attribute_group riscv_iommu_hpm_cpumask_group = {
 	.attrs = riscv_iommu_hpm_cpumask_attrs,
 };
 
+static ssize_t riscv_iommu_hpm_identifier_show(struct device *dev,
+					       struct device_attribute *attr,
+					       char *buf)
+{
+	struct riscv_iommu_hpm *iommu_hpm = to_iommu_hpm(dev_get_drvdata(dev));
+
+	if (!iommu_hpm->identifier)
+		return 0;
+
+	return sysfs_emit(buf, "%s\n", iommu_hpm->identifier);
+}
+
+static struct device_attribute riscv_iommu_hpm_identifier_attr =
+	__ATTR(identifier, 0444, riscv_iommu_hpm_identifier_show, NULL);
+
+static struct attribute *riscv_iommu_hpm_identifier_attrs[] = {
+	&riscv_iommu_hpm_identifier_attr.attr,
+	NULL
+};
+
+static const struct attribute_group riscv_iommu_hpm_identifier_group = {
+	.attrs = riscv_iommu_hpm_identifier_attrs,
+};
+
 #define IOMMU_HPM_EVENT_ATTR(name, config)		\
 	PMU_EVENT_ATTR_ID(name, riscv_iommu_hpm_event_show, config)
 
@@ -522,6 +546,7 @@ static const struct attribute_group *riscv_iommu_hpm_attr_grps[] = {
 	&riscv_iommu_hpm_cpumask_group,
 	&riscv_iommu_hpm_events_group,
 	&riscv_iommu_hpm_format_group,
+	&riscv_iommu_hpm_identifier_group,
 	NULL
 };
 
@@ -624,6 +649,36 @@ static void riscv_iommu_hpm_reset(struct riscv_iommu_hpm *iommu_hpm)
 	riscv_iommu_hpm_interrupt_clear(iommu_hpm);
 }
 
+static bool riscv_iommu_hpm_is_identifier_compat(const char *compat)
+{
+	return !strcmp(compat, "riscv,iommu");
+}
+
+static const char *riscv_iommu_hpm_get_identifier(struct device *dev)
+{
+	struct device_node *np = dev->of_node;
+	const char *compat;
+	int count, i;
+
+	if (!np)
+		return NULL;
+
+	count = of_property_count_strings(np, "compatible");
+	if (count <= 0)
+		return NULL;
+
+	for (i = 0; i < count; i++) {
+		if (of_property_read_string_index(np, "compatible",
+						  i, &compat))
+			continue;
+
+		if (riscv_iommu_hpm_is_identifier_compat(compat))
+			return devm_kstrdup(dev, compat, GFP_KERNEL);
+	}
+
+	return NULL;
+}
+
 static void riscv_iommu_hpm_set_standard_events(struct riscv_iommu_hpm *iommu_hpm)
 {
 	/* Cycles counter is always supported */
@@ -650,6 +705,7 @@ static void riscv_iommu_hpm_remove(void *data)
 static int riscv_iommu_hpm_register_unit(struct riscv_iommu_device *iommu,
 					 struct riscv_iommu_hpm *iommu_hpm,
 					 u32 offset, int irq,
+					 const char *identifier,
 					 const struct attribute_group **attr_groups,
 					 const char *prefix)
 {
@@ -663,6 +719,7 @@ static int riscv_iommu_hpm_register_unit(struct riscv_iommu_device *iommu,
 	unique_id = atomic_fetch_inc(&riscv_iommu_hpm_ids);
 	memset(iommu_hpm, 0, sizeof(*iommu_hpm));
 	iommu_hpm->iommu = iommu;
+	iommu_hpm->identifier = identifier;
 
 	if (offset + RISCV_IOMMU_REG_SIZE <= iommu->reg_size)
 		base = iommu->reg + offset;
@@ -791,6 +848,7 @@ static void riscv_iommu_hpm_exit(void)
 int riscv_iommu_add_hpm(struct riscv_iommu_device *iommu)
 {
 	struct device *dev = iommu->dev;
+	const char *identifier;
 	int irq, rc;
 
 	if (!FIELD_GET(RISCV_IOMMU_CAPABILITIES_HPM, iommu->caps)) {
@@ -809,7 +867,12 @@ int riscv_iommu_add_hpm(struct riscv_iommu_device *iommu)
 	if (rc < 0)
 		return rc;
 
+	identifier = riscv_iommu_hpm_get_identifier(dev);
+	if (identifier)
+		dev_info(dev, "HPM: Vendor identifier: %s\n", identifier);
+
 	rc = riscv_iommu_hpm_register_unit(iommu, &iommu->hpm, 0, irq,
+					   identifier,
 					   riscv_iommu_hpm_attr_grps,
 					   "riscv_iommu_hpm");
 	if (rc < 0)
drivers/iommu/riscv/iommu.h +1 -0
index 0ad9f5cad4de..d3c11abef5cf 100644
@@ -41,6 +41,7 @@ struct riscv_iommu_hpm {
 	int irq;
 	int on_cpu;
 	struct hlist_node node;
+	const char *identifier;
 	/*
 	 * Layout of events:
 	 * 0       -> HPMCYCLES
Signature · 1 line
2.43.0
#57 lore raw

PATCH v3 6/8 spacemit/t100: Add global filter awareness for RISC-V IOMMU HPM

In reply to a message not in the archive

Introduces global filter support for RISC-V IOMMU HPM. The global filter can be seen in SpacemiT T100 which only supports single filter to be applied to all event counters.

Drivers can program filters in each iohpmevt registers as normal in such a silicon design, however the underlying hardware filters are wired together as a global filter applying to all iohpmevt(s). Since the mechanism is compatible with standard iohpmevt in programming interface, only adds sanity checks to allow it to be configured with "global" awareness to inform users a filter incompatiblity.

---
 drivers/iommu/riscv/iommu-hpm.c | 68 ++++++++++++++++++++++++++++++---
 drivers/iommu/riscv/iommu.h     |  1 +
 2 files changed, 63 insertions(+), 6 deletions(-)
drivers/iommu/riscv/iommu-hpm.c +62 -6
index e140cf59c408..4a739cb0887c 100644
@@ -134,6 +134,30 @@ static inline void riscv_iommu_hpm_interrupt_clear(struct riscv_iommu_hpm *hpm)
 	riscv_iommu_hpm_writel(hpm, RISCV_IOMMU_REG_IPSR, RISCV_IOMMU_IPSR_PMIP);
 }
 
+static bool riscv_iommu_hpm_check_global_filter(struct perf_event *curr,
+						struct perf_event *new)
+{
+	return get_filter_pid_pscid(curr) == get_filter_pid_pscid(new) &&
+	       get_filter_did_gscid(curr) == get_filter_did_gscid(new) &&
+	       get_filter_pv_pscv(curr) == get_filter_pv_pscv(new) &&
+	       get_filter_dv_gscv(curr) == get_filter_dv_gscv(new) &&
+	       get_filter_idt(curr) == get_filter_idt(new) &&
+	       get_filter_dmask(curr) == get_filter_dmask(new);
+}
+
+static bool riscv_iommu_hpm_events_compatible(struct perf_event *curr,
+					      struct perf_event *new)
+{
+	if (new->pmu != curr->pmu)
+		return false;
+
+	if (to_iommu_hpm(new->pmu)->global_filter &&
+	    !riscv_iommu_hpm_check_global_filter(curr, new))
+		return false;
+
+	return true;
+}
+
 /**
  * riscv_iommu_hpm_event_update() - Update and return RISC-V IOMMU HPM
  *                                  event counters
@@ -268,9 +292,10 @@ static void riscv_iommu_hpm_set_event_filter(struct perf_event *event, int idx,
 			       RISCV_IOMMU_REG_IOHPMEVT(idx), event_cfg);
 }
 
-static void riscv_iommu_hpm_apply_event_filter(struct riscv_iommu_hpm *iommu_hpm,
-					       struct perf_event *event, int idx)
+static int riscv_iommu_hpm_apply_event_filter(struct riscv_iommu_hpm *iommu_hpm,
+					      struct perf_event *event, int idx)
 {
+	unsigned int cur_idx, num_ctrs = iommu_hpm->num_counters;
 	u32 pid_pscid, did_gscid, pv_pscv, dv_gscv, idt, dmask;
 
 	pid_pscid = get_filter_pid_pscid(event);
@@ -280,14 +305,36 @@ static void riscv_iommu_hpm_apply_event_filter(struct riscv_iommu_hpm *iommu_hpm
 	idt = get_filter_idt(event);
 	dmask = get_filter_dmask(event);
 
+	if (iommu_hpm->global_filter) {
+		cur_idx = find_first_bit(iommu_hpm->used_counters, num_ctrs - 1);
+		if (cur_idx == num_ctrs - 1) {
+			/* First event, set the global filter */
+			riscv_iommu_hpm_set_event_filter(event, 0, pid_pscid,
+							 did_gscid,
+							 pv_pscv, dv_gscv, idt, dmask);
+		} else {
+			/* Check if the new event's filter is compatible with
+			 * the global filter
+			 */
+			if (!riscv_iommu_hpm_check_global_filter(iommu_hpm->events[cur_idx + 1],
+								 event)) {
+				dev_dbg(iommu_hpm->pmu.dev,
+					"HPM: Filter incompatible with global filter\n");
+				return -EAGAIN;
+			}
+		}
+		return 0;
+	}
+
 	riscv_iommu_hpm_set_event_filter(event, idx, pid_pscid, did_gscid,
 					 pv_pscv, dv_gscv, idt, dmask);
+	return 0;
 }
 
 static int riscv_iommu_hpm_get_event_idx(struct riscv_iommu_hpm *iommu_hpm,
 					 struct perf_event *event)
 {
-	int idx;
+	int idx, err;
 	unsigned int num_ctrs = iommu_hpm->num_counters;
 	u16 event_id = get_event(event);
 
@@ -309,7 +356,9 @@ static int riscv_iommu_hpm_get_event_idx(struct riscv_iommu_hpm *iommu_hpm,
 		return -EAGAIN;
 	}
 
-	riscv_iommu_hpm_apply_event_filter(iommu_hpm, event, idx);
+	err = riscv_iommu_hpm_apply_event_filter(iommu_hpm, event, idx);
+	if (err)
+		return err;
 	set_bit(idx, iommu_hpm->used_counters);
 
 	return idx;
@@ -409,6 +458,8 @@ static int riscv_iommu_hpm_event_init(struct perf_event *event)
 	}
 
 	if (!is_software_event(event->group_leader)) {
+		if (!riscv_iommu_hpm_events_compatible(event->group_leader, event))
+			return -EINVAL;
 		if (++group_num_events > iommu_hpm->num_counters)
 			return -EINVAL;
 	}
@@ -416,6 +467,8 @@ static int riscv_iommu_hpm_event_init(struct perf_event *event)
 	for_each_sibling_event(sibling, event->group_leader) {
 		if (is_software_event(sibling))
 			continue;
+		if (!riscv_iommu_hpm_events_compatible(sibling, event))
+			return -EINVAL;
 		if (++group_num_events > iommu_hpm->num_counters)
 			return -EINVAL;
 	}
@@ -733,6 +786,8 @@ static int riscv_iommu_hpm_register_unit(struct riscv_iommu_device *iommu,
 	bitmap_zero(iommu_hpm->used_counters, RISCV_IOMMU_HPMCOUNTER_MAX);
 	bitmap_zero(iommu_hpm->supported_events, RISCV_IOMMU_HPMEVENT_MAX);
 
+	iommu_hpm->global_filter = of_device_is_compatible(dev->of_node,
+							   "spacemit,t100");
 	riscv_iommu_hpm_writel(iommu_hpm,
 			       RISCV_IOMMU_REG_IOCOUNTINH, 0xFFFFFFFF);
 	val = riscv_iommu_hpm_readl(iommu_hpm,
@@ -796,8 +851,9 @@ static int riscv_iommu_hpm_register_unit(struct riscv_iommu_device *iommu,
 	if (err)
 		goto err_cpuhp;
 
-	dev_info(dev, "HPM: Registered %s (%d counters, IRQ %d)\n",
-		 pmu_name, iommu_hpm->num_counters, iommu_hpm->irq);
+	dev_info(dev, "HPM: Registered %s (%d counters, IRQ %d, %s filter)\n",
+		 pmu_name, iommu_hpm->num_counters, iommu_hpm->irq,
+		 iommu_hpm->global_filter ? "global" : "per-counter");
 	return 0;
 
 err_cpuhp:
drivers/iommu/riscv/iommu.h +1 -0
index d3c11abef5cf..80e96fd7e164 100644
@@ -42,6 +42,7 @@ struct riscv_iommu_hpm {
 	int on_cpu;
 	struct hlist_node node;
 	const char *identifier;
+	bool global_filter;
 	/*
 	 * Layout of events:
 	 * 0       -> HPMCYCLES
Signature · 1 line
2.43.0
#58 lore raw

PATCH v3 7/8 spacemit/t100: Add SpacemiT T100 IOATC HPM support

In reply to a message not in the archive

Adds IOATC discovery and HPM support for SpacemiT T100.

SpacemiT T100 supports distributed architecture which allows IOTLBs to be cached in adjacent to the DMA masters. Such IOTLB controllers are called as IOATCs. Adds distributed HPM support for IOATCs.

---
 drivers/iommu/riscv/iommu-bits.h     |  12 ++
 drivers/iommu/riscv/iommu-hpm.c      | 178 +++++++++++++++++++++++++--
 drivers/iommu/riscv/iommu-platform.c |   4 +-
 drivers/iommu/riscv/iommu.h          |   2 +-
 4 files changed, 184 insertions(+), 12 deletions(-)
drivers/iommu/riscv/iommu-bits.h +12 -0
index cc6bea064d8f..dcf95a99c1d1 100644
@@ -284,6 +284,18 @@ enum riscv_iommu_hpmevent_id {
 #define RISCV_IOMMU_ICVEC_PMIV		GENMASK_ULL(11, 8)
 #define RISCV_IOMMU_ICVEC_PIV		GENMASK_ULL(15, 12)
 
+/* 5.28 Distributed translation interface status register (dtisr0-3) (4 * 32-bits) */
+#define RISCV_IOMMU_REG_DTISR_BASE	0x02B0
+#define RISCV_IOMMU_REG_DTISR(_n)	(RISCV_IOMMU_REG_DTISR_BASE + ((_n) * 0x04))
+#define RISCV_IOMMU_DTI_STS_SHIFT(_n)	(((_n) % 16) * 2)
+#define RISCV_IOMMU_DTI_STS_MASK(_n)	(0x3 << RISCV_IOMMU_DTI_STS_SHIFT(_n))
+#define RISCV_IOMMU_DTI_STS_NONE	0x0
+#define RISCV_IOMMU_DTI_STS_IOATC	0x1
+
+#define MAX_RISCV_IOMMU_IOATC		64
+#define RISCV_IOMMU_IOATC_BASE(_base, _idx) \
+	((void __iomem *)((u8 __iomem *)(_base) + ((_idx) + 1) * RISCV_IOMMU_REG_SIZE))
+
 /* 5.28 MSI Configuration table (32 * 64bits) */
 #define RISCV_IOMMU_REG_MSI_CFG_TBL	0x0300
 #define RISCV_IOMMU_REG_MSI_CFG_TBL_ADDR(_n) \
drivers/iommu/riscv/iommu-hpm.c +169 -9

235 lines not on this page · raw message

drivers/iommu/riscv/iommu-platform.c +2 -2
index 684bc267ac30..ca8de9ec5266 100644
@@ -75,8 +75,8 @@ static int riscv_iommu_platform_probe(struct platform_device *pdev)
 	if (iommu->irqs_count <= 0)
 		return dev_err_probe(dev, -ENODEV,
 				     "no IRQ resources provided\n");
-	if (iommu->irqs_count > RISCV_IOMMU_INTR_COUNT)
-		iommu->irqs_count = RISCV_IOMMU_INTR_COUNT;
+	if (iommu->irqs_count > RISCV_IOMMU_INTR_COUNT + MAX_RISCV_IOMMU_IOATC)
+		iommu->irqs_count = RISCV_IOMMU_INTR_COUNT + MAX_RISCV_IOMMU_IOATC;
 
 	igs = FIELD_GET(RISCV_IOMMU_CAPABILITIES_IGS, iommu->caps);
 	switch (igs) {
drivers/iommu/riscv/iommu.h +1 -1
index 80e96fd7e164..c2f008d86d63 100644
@@ -76,7 +76,7 @@ struct riscv_iommu_device {
 	u32 fctl;
 
 	/* available interrupt numbers, MSI or WSI */
-	unsigned int irqs[RISCV_IOMMU_INTR_COUNT];
+	unsigned int irqs[RISCV_IOMMU_INTR_COUNT + MAX_RISCV_IOMMU_IOATC];
 	unsigned int irqs_count;
 	unsigned int icvec;
 
Signature · 1 line
2.43.0
#59 lore raw

PATCH v3 8/8 perf vendor events riscv:: Add support for spacemit,riscv-iommu HPM aliasing

In reply to a message not in the archive

Add JSON HPM event aliases for SpacemiT distributed IOMMU (T100) which is general and compatible for all SpacemiT RISC-V SoCs.

---
 MAINTAINERS                                   |   3 +
 .../arch/riscv/spacemit/iommu/sys/ioatc.json  |  30 ++++
 .../arch/riscv/spacemit/iommu/sys/ioats.json  | 163 ++++++++++++++++++
 3 files changed, 196 insertions(+)
 create mode 100644 tools/perf/pmu-events/arch/riscv/spacemit/iommu/sys/ioatc.json
 create mode 100644 tools/perf/pmu-events/arch/riscv/spacemit/iommu/sys/ioats.json
MAINTAINERS +3 -0
index 7c50701b6001..4d91f99aa742 100644
@@ -22459,12 +22459,15 @@ K:	riscv
 
 RISC-V IOMMU
 M:	Tomasz Jeznach <[email protected]>
+M:	Lv Zheng <[email protected]>
+M:	Jingyu Li <[email protected]>
 L:	[email protected]
 L:	[email protected]
 S:	Maintained
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/iommu/linux.git
 F:	Documentation/devicetree/bindings/iommu/riscv,iommu.yaml
 F:	drivers/iommu/riscv/
+F:	tools/perf/pmu-events/arch/riscv/spacemit/iommu/
 
 RISC-V MICROCHIP SUPPORT
 M:	Conor Dooley <[email protected]>
tools/perf/pmu-events/arch/riscv/spacemit/iommu/sys/ioatc.json new file +30 -0
new file mode 100644
index 000000000000..a16610ba2274
@@ -0,0 +1,30 @@
+[
+  {
+    "EventName": "mtlb_lkp",
+    "EventCode": "0x38",
+    "BriefDescription": "IOATC main TLB (MTLB) lookups",
+    "Unit": "spacemit_ioatc_hpm",
+    "Compat": "spacemit,riscv-iommu"
+  },
+  {
+    "EventName": "mtlb_mis",
+    "EventCode": "0x39",
+    "BriefDescription": "IOATC main TLB (MTLB) misses",
+    "Unit": "spacemit_ioatc_hpm",
+    "Compat": "spacemit,riscv-iommu"
+  },
+  {
+    "EventName": "utlb_lkp",
+    "EventCode": "0x3A",
+    "BriefDescription": "IOATC micro TLB (uTLB) lookups",
+    "Unit": "spacemit_ioatc_hpm",
+    "Compat": "spacemit,riscv-iommu"
+  },
+  {
+    "EventName": "utlb_mis",
+    "EventCode": "0x3B",
+    "BriefDescription": "IOATC micro TLB (uTLB) misses",
+    "Unit": "spacemit_ioatc_hpm",
+    "Compat": "spacemit,riscv-iommu"
+  }
+]
tools/perf/pmu-events/arch/riscv/spacemit/iommu/sys/ioats.json new file +163 -0

163 lines not on this page · raw message

Signature · 1 line
2.43.0
#60 lore raw

Re: [PATCH v3 8/8] perf vendor events riscv:: Add support for spacemit,riscv-iommu HPM aliasing

Quoted 18 lines · Lv Zheng

Add JSON HPM event aliases for SpacemiT distributed IOMMU (T100) which is general and compatible for all SpacemiT RISC-V SoCs.

---
 MAINTAINERS                                   |   3 +
 .../arch/riscv/spacemit/iommu/sys/ioatc.json  |  30 ++++
 .../arch/riscv/spacemit/iommu/sys/ioats.json  | 163 ++++++++++++++++++
 3 files changed, 196 insertions(+)
 create mode 100644 tools/perf/pmu-events/arch/riscv/spacemit/iommu/sys/ioatc.json
 create mode 100644 tools/perf/pmu-events/arch/riscv/spacemit/iommu/sys/ioats.json
MAINTAINERS +0 -0
index 7c50701b6001..4d91f99aa742 100644

MAINTAINERS K: riscv · line 22463

Quoted 5 lines
MAINTAINERS +2 -0
@@ -22459,12 +22459,15 @@ K:	riscv
 
 RISC-V IOMMU
 M:	Tomasz Jeznach <[email protected]>
+M:	Lv Zheng <[email protected]>
+M:	Jingyu Li <[email protected]>

To be frank, this looks misguided, or at least premature, to me, given the state of the patchset.

Quoted 7 lines
MAINTAINERS +1 -0
 L:	[email protected]
 L:	[email protected]
 S:	Maintained
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/iommu/linux.git
 F:	Documentation/devicetree/bindings/iommu/riscv,iommu.yaml
 F:	drivers/iommu/riscv/
+F:	tools/perf/pmu-events/arch/riscv/spacemit/iommu/
#61 lore raw

Re: [PATCH v3 8/8] perf vendor events riscv:: Add support for spacemit,riscv-iommu HPM aliasing

Quoted 20 lines · Conor Dooley
Quoted 19 lines · Lv Zheng

Add JSON HPM event aliases for SpacemiT distributed IOMMU (T100) which is general and compatible for all SpacemiT RISC-V SoCs.

---
  MAINTAINERS                                   |   3 +
  .../arch/riscv/spacemit/iommu/sys/ioatc.json  |  30 ++++
  .../arch/riscv/spacemit/iommu/sys/ioats.json  | 163 ++++++++++++++++++
  3 files changed, 196 insertions(+)

create mode 100644 tools/perf/pmu-events/arch/riscv/spacemit/iommu/sys/ioatc.json create mode 100644 tools/perf/pmu-events/arch/riscv/spacemit/iommu/sys/ioats.json

MAINTAINERS +0 -0
index 7c50701b6001..4d91f99aa742 100644
@@ -22459,12 +22459,15 @@ K:	riscv
 
Quoted 7 lines

MAINTAINERS K: riscv · line 22463

Quoted 4 lines
MAINTAINERS +2 -0
  RISC-V IOMMU
  M:	Tomasz Jeznach <[email protected]>
+M:	Lv Zheng <[email protected]>
+M:	Jingyu Li <[email protected]>

To be frank, this looks misguided, or at least premature, to me, given the state of the patchset.

Should this be a big deal?
I've been working as kernel maintainers for 5 years (you can find me in git log using Lv Zheng <[email protected]>) and given the fact that I'm also the silicon designer of SpacemiT T100, played an active role in IOMMU spec community, I'm ready to help the community by reviewing RISC-V IOMMU related changes. Joey is responsible for SpacemiT RISC-V linux kernel support. We have chances to test RISC-V linux kernel supports very early using pre-silicon real hardware here in a silicon team to help the community.
Any suggestions?

Quoted 8 lines

MAINTAINERS K: riscv · line 22470

Quoted 8 lines
MAINTAINERS +1 -0
  L:	[email protected]
  L:	[email protected]
  S:	Maintained
  T:	git git://git.kernel.org/pub/scm/linux/kernel/git/iommu/linux.git
  F:	Documentation/devicetree/bindings/iommu/riscv,iommu.yaml
  F:	drivers/iommu/riscv/
+F:	tools/perf/pmu-events/arch/riscv/spacemit/iommu/

checkpatch.pl complains missing files and given the reason above, I didn't create a "Supported" part of RISC-V IOMMU HPM.

Best regards,
Lv

#62 lore raw

v4 cover iommu/riscv: Add HPM support for RISC-V IOMMU

In reply to Lv Zheng

Includes HPM support for RISC-V IOMMU. The HPM hardware mechanism can be found in the recent announced SpacemiT SoCs (K3, V100), where T100 (SpacemiT distributed IOMMU) is shipped.

Revisions:
v1
Initial release.
v2 (sent as v1.1)
Split and cleanup DT-bindings.
v3
1. Refactor using vendor specific compatible.
2. Implement vendor events with a userspace identifier.
v4
1. Drop ICVEC check which is not that usful as WSI device tree can use only 1 vector for IOATS CIV/FIV/PIV/PMIV.
2. Solve DT binding check of "interrupts/maxItems" attribute.
3. Address Robin's comments for an old revision sent by "Zong Li":

    https://lore.kernel.org/all/[email protected]/

4. Limit IOATC enumeration by referencing spacemit,riscv-iommu.

The tested result can be found as follows:

 root@sdfirm:~# perf stat --timeout 5000 -a -e spacemit_ioats_hpm_00/dd_walk,config1=0x20c0010000000000/ dmatest; sleep 1
 [  145.630224] dmatest: Started 1 threads using dma0chan0
 [  145.644896] dmatest: dma0chan0-copy0: summary 1 tests, 0 failures 123.60 iops 123 KB/s (0)

Performance counter stats for 'system wide':

                  3      spacemit_ioats_hpm_00/dd_walk,config1=0x20c0010000000000/                                      

        0.193108000 seconds time elapsed
 root@sdfirm:~# echo dma0chan1 > /sys/module/dmatest/parameters/channel 
 [  327.001820] dmatest: Added 1 threads using dma0chan1
 root@sdfirm:~# perf stat --timeout 5000 -a -e spacemit_ioats_hpm_00/s_walk,config1=0x20c0011000000000/ dmatest; sleep 1
 [  484.037180] dmatest: Started 1 threads using dma0chan1
 [  484.048832] dmatest: dma0chan1-copy0: summary 1 tests, 0 failures 172.11 iops 172 KB/s (0)

Performance counter stats for 'system wide':

                  6      spacemit_ioats_hpm_00/s_walk,config1=0x20c0011000000000/                                      

        0.191970000 seconds time elapsed
 root@sdfirm:~# perf stat --timeout 5000 -a -e spacemit_ioatc_hpm_0003/tlb_mis,config1=0x20c0011000000000/ dmatest; sleep 1
 [  546.332494] dmatest: No channels configured, continue with any
 [  546.363062] dmatest: Added 1 threads using dma0chan1
 [  546.377994] dmatest: Started 1 threads using dma0chan1
 [  546.388376] dmatest: dma0chan1-copy0: summary 1 tests, 0 failures 213.94 iops 213 KB/s (0)

Performance counter stats for 'system wide':

                  3      spacemit_ioatc_hpm_0003/tlb_mis,config1=0x20c0011000000000/                                      

        0.225062000 seconds time elapsed

Jingyu Li (2):
iommu/riscv: Enable IOMMU DMA mapping support iommu/riscv: Add HPM support for performance monitoring

Lv Zheng (5):
dt-bindings: iommu: Add spacemit/t100 features iommu/riscv: Add vendor event support for RISC-V IOMMU HPM spacemit/t100: Add global filter awareness for RISC-V IOMMU HPM spacemit/t100: Add SpacemiT T100 IOATC HPM support
perf vendor events riscv:: Add support for spacemit,riscv-iommu HPM
aliasing

 .../bindings/iommu/riscv,iommu.yaml           |   53 +-
 MAINTAINERS                                   |    3 +
 drivers/iommu/Kconfig                         |    2 +-
 drivers/iommu/riscv/Kconfig                   |    9 +
 drivers/iommu/riscv/Makefile                  |    1 +
 drivers/iommu/riscv/iommu-bits.h              |   18 +
 drivers/iommu/riscv/iommu-hpm.c               | 1123 +++++++++++++++++
 drivers/iommu/riscv/iommu-pci.c               |   13 +-
 drivers/iommu/riscv/iommu-platform.c          |   12 +-
 drivers/iommu/riscv/iommu.h                   |   46 +-
 .../arch/riscv/spacemit/iommu/sys/ioatc.json  |   30 +
 .../arch/riscv/spacemit/iommu/sys/ioats.json  |  163 +++
 12 files changed, 1464 insertions(+), 9 deletions(-)
 create mode 100644 drivers/iommu/riscv/iommu-hpm.c
 create mode 100644 tools/perf/pmu-events/arch/riscv/spacemit/iommu/sys/ioatc.json
 create mode 100644 tools/perf/pmu-events/arch/riscv/spacemit/iommu/sys/ioats.json
Signature · 1 line
2.43.0
#63 lore raw
Quoted 4 lines · Lv Zheng

Includes HPM support for RISC-V IOMMU. The HPM hardware mechanism can be found in the recent announced SpacemiT SoCs (K3, V100), where T100 (SpacemiT distributed IOMMU) is shipped.

Quoted 9 lines

Revisions:
v1
Initial release.
v2 (sent as v1.1)
Split and cleanup DT-bindings.
v3
1. Refactor using vendor specific compatible.
2. Implement vendor events with a userspace identifier.
v4

And now also v4 is in the same thread? This is total mess!

How tools are supposed to handle this?

Best regards,
Krzysztof

#64 lore raw
Quoted 15 lines · Krzysztof Kozlowski
Quoted 4 lines · Lv Zheng

Includes HPM support for RISC-V IOMMU. The HPM hardware mechanism can be found in the recent announced SpacemiT SoCs (K3, V100), where T100 (SpacemiT distributed IOMMU) is shipped.

Quoted 9 lines

Revisions:
v1
Initial release.
v2 (sent as v1.1)
Split and cleanup DT-bindings.
v3
1. Refactor using vendor specific compatible.
2. Implement vendor events with a userspace identifier.
v4

Quoted 3 lines

And now also v4 is in the same thread? This is total mess!

How tools are supposed to handle this?

I'm using the tools I was using several years ago.

It's able to handle revisions using one single thread if a "msgid" is provided via its command line:

# Prepare --in-reply-to argument of git-format-patch if [ "x$1" != "x" -a "x$1" != "xnone" ]; then
echo "Found Message-Id: <$msgid>." GFPFLAGS="$GFPFLAGS --in-reply-to=$msgid"
fi

And I have a configuration file in my $HOME collecting all patchsets' first msgid:

if [ "x$require_msgid" = "xno" ]; then
fatal "Invalid Message-Id: $1 shouldn't be specified
for v${MAJOR}.${MINOR}."

        fi
        msgid=`cat $MSGIDS | grep $1 | cut -f2`
        if [ "x$msgid" = "x" ]; then
                fatal "Invalid Message-Id: cannot find $1 in $MSGIDS."
        fi

That's the old fashion I was doing upstream related work, as some online tools was able to update patchsets automatically if the thread top matched and then showed the new revision up in their web portal.

Will stop using such single thread style as what you suggested.

Thanks,
Lv

Quoted 4 lines

Best regards,
Krzysztof

A message that is not in the archive (sent off-list or not yet received): [email protected]

#66 lore raw

PATCH v4 1/7 iommu/riscv: Enable IOMMU DMA mapping support

From: Jingyu Li <[email protected]>

Enables IOMMU DMA mapping support for RISC-V, so that DMACs can be tested with translation enabled.

Known Possible Issue:
1. When CONFIG_IOMMU_DMA is enabled, on the tested Linux, RISC-V IOMMU is lack of PCIe support, causing riscv_iommu_fault:522 in dealing with NVMe PCIe devices.

---
 drivers/iommu/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iommu/Kconfig +1 -1
index f86262b11416..34d8a792339f 100644
@@ -151,7 +151,7 @@ config OF_IOMMU
 
 # IOMMU-agnostic DMA-mapping layer
 config IOMMU_DMA
-	def_bool ARM64 || X86 || S390
+	def_bool ARM64 || X86 || S390 || RISCV
 	select DMA_OPS_HELPERS
 	select IOMMU_API
 	select IOMMU_IOVA
Signature · 1 line
2.43.0
#67 lore raw

PATCH v4 2/7 iommu/riscv: Add HPM support for performance monitoring

In reply to a message not in the archive

From: Jingyu Li <[email protected]>

Introduces perf-based HPM driver for RISC-V IOMMU, enabling performance monitoring capabilities.

Note that the RISC-V IOMMU HPM module uses COUNTER_MAX-1 as a static counter index of HPMCYCLES, and 0~COUNTER_MAX-2 as the dynamic counter indexes of other HPMEVENTS in order to correctly index into IOHPMEVT and IOHPMCTR registers that have already been defined in the iommu-bits.h. However the users treat 0 as the index of HPMCYCLES and 1~COUNTER_MAX-1 as the indexes of other HPMEVENTS, thus care should be taken in dealing with counter indexes between userspace and kernel space.

Also addresses community comments in the revision sent by "Zong Li".

---
 drivers/iommu/riscv/Kconfig          |   9 +
 drivers/iommu/riscv/Makefile         |   1 +
 drivers/iommu/riscv/iommu-bits.h     |   6 +
 drivers/iommu/riscv/iommu-hpm.c      | 840 +++++++++++++++++++++++++++
 drivers/iommu/riscv/iommu-pci.c      |  13 +-
 drivers/iommu/riscv/iommu-platform.c |   8 +-
 drivers/iommu/riscv/iommu.h          |  42 ++
 7 files changed, 916 insertions(+), 3 deletions(-)
 create mode 100644 drivers/iommu/riscv/iommu-hpm.c
drivers/iommu/riscv/Kconfig +9 -0
index c071816f59a6..2d06a1ef11c9 100644
@@ -18,3 +18,12 @@ config RISCV_IOMMU_PCI
 	def_bool y if RISCV_IOMMU && PCI_MSI
 	help
 	  Support for the PCIe implementation of RISC-V IOMMU architecture.
+
+config RISCV_IOMMU_HPM
+	tristate "RISCV IOMMU HPM support"
+	depends on RISCV_IOMMU
+	help
+	  Provides support for the RISC-V IOMMU Hardware Performance Monitor
+	  (HPM), which provide monitoring of transactions passing through the
+	  IOMMU and allow the resulting information to be filtered based on
+	  the device/process ID of the corresponding master.
drivers/iommu/riscv/Makefile +1 -0
index b5929f9f23e6..53db3ef62bdd 100644
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-y += iommu.o iommu-platform.o
 obj-$(CONFIG_RISCV_IOMMU_PCI) += iommu-pci.o
+obj-$(CONFIG_RISCV_IOMMU_HPM) += iommu-hpm.o
drivers/iommu/riscv/iommu-bits.h +6 -0
index 98daf0e1a306..cc6bea064d8f 100644
@@ -207,6 +207,7 @@ enum riscv_iommu_ddtp_modes {
 /* 5.22 Performance monitoring event counters (31 * 64bits) */
 #define RISCV_IOMMU_REG_IOHPMCTR_BASE	0x0068
 #define RISCV_IOMMU_REG_IOHPMCTR(_n)	(RISCV_IOMMU_REG_IOHPMCTR_BASE + ((_n) * 0x8))
+#define RISCV_IOMMU_IOHPMEVENT_COUNTER	GENMASK_ULL(63, 0)
 
 /* 5.23 Performance monitoring event selectors (31 * 64bits) */
 #define RISCV_IOMMU_REG_IOHPMEVT_BASE	0x0160
@@ -222,6 +223,9 @@ enum riscv_iommu_ddtp_modes {
 
 /* Number of defined performance-monitoring event selectors */
 #define RISCV_IOMMU_IOHPMEVT_CNT	31
+/* Cycles counter is statically indexed as the last counter */
+#define RISCV_IOMMU_HPMCOUNTER_CYCLES	RISCV_IOMMU_IOHPMEVT_CNT
+#define RISCV_IOMMU_HPMCOUNTER_MAX	(RISCV_IOMMU_IOHPMEVT_CNT + 1)
 
 /**
  * enum riscv_iommu_hpmevent_id - Performance-monitoring event identifier
@@ -250,6 +254,8 @@ enum riscv_iommu_hpmevent_id {
 	RISCV_IOMMU_HPMEVENT_MAX        = 9
 };
 
+#define RISCV_IOMMU_HPMEVENT_CYCLES	RISCV_IOMMU_HPMEVENT_INVALID
+
 /* 5.24 Translation request IOVA (64bits) */
 #define RISCV_IOMMU_REG_TR_REQ_IOVA     0x0258
 #define RISCV_IOMMU_TR_REQ_IOVA_VPN	GENMASK_ULL(63, 12)
drivers/iommu/riscv/iommu-hpm.c new file +840 -0

840 lines not on this page · raw message

drivers/iommu/riscv/iommu-pci.c +11 -2
index d82d2b00904c..71407aecbf92 100644
@@ -34,6 +34,8 @@ static int riscv_iommu_pci_probe(struct pci_dev *pdev, const struct pci_device_i
 {
 	struct device *dev = &pdev->dev;
 	struct riscv_iommu_device *iommu;
+	phys_addr_t reg_phys;
+	resource_size_t reg_size;
 	int rc, vec;
 
 	rc = pcim_enable_device(pdev);
@@ -43,7 +45,9 @@ static int riscv_iommu_pci_probe(struct pci_dev *pdev, const struct pci_device_i
 	if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM))
 		return -ENODEV;
 
-	if (pci_resource_len(pdev, 0) < RISCV_IOMMU_REG_SIZE)
+	reg_phys = pci_resource_start(pdev, 0);
+	reg_size = pci_resource_len(pdev, 0);
+	if (reg_size < RISCV_IOMMU_REG_SIZE)
 		return -ENODEV;
 
 	rc = pcim_iomap_regions(pdev, BIT(0), pci_name(pdev));
@@ -56,6 +60,8 @@ static int riscv_iommu_pci_probe(struct pci_dev *pdev, const struct pci_device_i
 
 	iommu->dev = dev;
 	iommu->reg = pcim_iomap_table(pdev)[0];
+	iommu->reg_phys = reg_phys;
+	iommu->reg_size = reg_size;
 
 	pci_set_master(pdev);
 	dev_set_drvdata(dev, iommu);
@@ -91,7 +97,10 @@ static int riscv_iommu_pci_probe(struct pci_dev *pdev, const struct pci_device_i
 		riscv_iommu_writel(iommu, RISCV_IOMMU_REG_FCTL, iommu->fctl);
 	}
 
-	return riscv_iommu_init(iommu);
+	rc = riscv_iommu_init(iommu);
+	if (rc)
+		return rc;
+	return riscv_iommu_add_hpm(iommu);
 }
 
 static void riscv_iommu_pci_remove(struct pci_dev *pdev)
drivers/iommu/riscv/iommu-platform.c +7 -1
index 83a28c83f991..684bc267ac30 100644
@@ -62,6 +62,9 @@ static int riscv_iommu_platform_probe(struct platform_device *pdev)
 		return dev_err_probe(dev, PTR_ERR(iommu->reg),
 				     "could not map register region\n");
 
+	iommu->reg_phys = res->start;
+	iommu->reg_size = resource_size(res);
+
 	dev_set_drvdata(dev, iommu);
 
 	/* Check device reported capabilities / features. */
@@ -134,7 +137,10 @@ static int riscv_iommu_platform_probe(struct platform_device *pdev)
 		return dev_err_probe(dev, -ENODEV, "invalid IGS\n");
 	}
 
-	return riscv_iommu_init(iommu);
+	ret = riscv_iommu_init(iommu);
+	if (ret)
+		return ret;
+	return riscv_iommu_add_hpm(iommu);
 };
 
 static void riscv_iommu_platform_remove(struct platform_device *pdev)
drivers/iommu/riscv/iommu.h +42 -0

72 lines not on this page · raw message

Signature · 1 line
2.43.0
#68 lore raw

PATCH v4 3/7 dt-bindings: iommu: Add spacemit/t100 features

In reply to a message not in the archive

Adds device tree bindings for SpacemiT T100 specific features by introducing spacemit,100 compatible. T100 contains distributed IOATCs, each of which exposes pmiv interrupt.

---
 .../bindings/iommu/riscv,iommu.yaml           | 53 ++++++++++++++++++-
 1 file changed, 51 insertions(+), 2 deletions(-)
Documentation/devicetree/bindings/iommu/riscv,iommu.yaml +51 -2
index d4838c3b3741..67d226a1a90d 100644
@@ -32,6 +32,12 @@ properties:
   # should be specified along with 'reg' property providing MMIO location.
   compatible:
     oneOf:
+      - description: SpacemiT distributed IOMMUs
+        items:
+          - enum:
+              - spacemit,t100
+          - const: spacemit,riscv-iommu
+          - const: riscv,iommu
       - items:
           - enum:
               - qemu,riscv-iommu
@@ -57,11 +63,21 @@ properties:
 
   interrupts:
     minItems: 1
-    maxItems: 4
+    maxItems: 68
     description:
       Wired interrupt vectors available for RISC-V IOMMU to notify the
       RISC-V HARTS. The cause to interrupt vector is software defined
-      using IVEC IOMMU register.
+      using ICVEC IOMMU register. For WSI only mode, the number of the
+      interrupt vectors should be 1 while for MSI possible mode, the
+      maximum of the interrupt vectors should be 4 with the cause indexed
+      as "CIV=0, FIV=1, PIV=2, PMIV=3".
+      SpacemiT distributed IOMMU includes additional interrupts for
+      IOATCs. Each IOATC exposes PMIV wired vector as standalone
+      interrupt and the maximum number of IOATCs can be up to 64. Thus for
+      WSI only mode, the maximum number of the interrupt vectors should be
+      65 while for MSI possible mode, the maximum number of the interrupt
+      vectors should be 68 with the cause indexed as "IOATS CIV=0,
+      IOATS FIV=1, IOATS PIV=2, IOATS PMIV=3, IOATC0..n PMIV=4..4+n".
 
   msi-parent: true
 
@@ -75,6 +91,18 @@ required:
 
 additionalProperties: false
 
+allOf:
+  - if:
+      properties:
+        compatible:
+          not:
+            contains:
+              const: spacemit,riscv-iommu
+    then:
+      properties:
+        interrupts:
+          maxItems: 4
+
 examples:
   - |+
     /* Example 1 (IOMMU device with wired interrupts) */
@@ -145,3 +173,24 @@ examples:
             };
         };
     };
+
+  - |+
+    /* Example 5 (SpacemiT distributed IOMMU) */
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    iommu4: iommu@1bccd000 {
+        compatible = "spacemit,t100", "spacemit,riscv-iommu", "riscv,iommu";
+        reg = <0x1bccd000 0x1000>;
+        interrupts = <58 IRQ_TYPE_LEVEL_HIGH>,
+                     <62 IRQ_TYPE_LEVEL_HIGH>, <63 IRQ_TYPE_LEVEL_HIGH>,
+                     <62 IRQ_TYPE_LEVEL_HIGH>, <63 IRQ_TYPE_LEVEL_HIGH>;
+        interrupt-parent = <&saplic>;
+        #iommu-cells = <0x01>;
+    };
+
+    /* Device with four IOMMU device IDs */
+    master2 {
+        #iommu-cells = <1>;
+        iommus = <&iommu4 0xc0010>, <&iommu4 0xc0011>,
+                 <&iommu4 0xc0012>, <&iommu4 0xc0013>;
+    };
Signature · 7 lines
2.43.0


_______________________________________________
linux-riscv mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-riscv
#69 lore raw

Re: [PATCH v4 3/7] dt-bindings: iommu: Add spacemit/t100 features

Quoted 6 lines · Lv Zheng

Adds device tree bindings for SpacemiT T100 specific features by introducing spacemit,100 compatible. T100 contains distributed IOATCs, each of which exposes pmiv interrupt.

Please wait until discussion has finished on prior versions before sending more. The merge window opens next week, so there's absolutely no rush with this series, there's weeks before anything could happen with it.

#70 lore raw

Re: [PATCH v4 3/7] dt-bindings: iommu: Add spacemit/t100 features

Quoted 5 lines · Conor Dooley
Quoted 4 lines · Lv Zheng

Adds device tree bindings for SpacemiT T100 specific features by introducing spacemit,100 compatible. T100 contains distributed IOATCs, each of which exposes pmiv interrupt.

Quoted 7 lines
Quoted 2 lines

Please wait until discussion has finished on prior versions before sending more. The merge window opens next week, so there's absolutely no rush with this series, there's weeks before anything could happen with it.

Sure, thanks for the help.

Cheers,
Lv

#71 lore raw

PATCH v4 4/7 iommu/riscv: Add vendor event support for RISC-V IOMMU HPM

In reply to a message not in the archive

Adds mechanism to allow vendor events to be registered via userspace jevents. By default, vendor event identifier matches "riscv,iommu", and the events are registered as "riscv_iommu_hpm" events.

---
 drivers/iommu/riscv/iommu-hpm.c | 63 +++++++++++++++++++++++++++++++++
 drivers/iommu/riscv/iommu.h     |  1 +
 2 files changed, 64 insertions(+)
drivers/iommu/riscv/iommu-hpm.c +63 -0
index fe51f60c0c75..4615c4b161a0 100644
@@ -443,6 +443,30 @@ static const struct attribute_group riscv_iommu_hpm_cpumask_group = {
 	.attrs = riscv_iommu_hpm_cpumask_attrs,
 };
 
+static ssize_t riscv_iommu_hpm_identifier_show(struct device *dev,
+					       struct device_attribute *attr,
+					       char *buf)
+{
+	struct riscv_iommu_hpm *iommu_hpm = to_iommu_hpm(dev_get_drvdata(dev));
+
+	if (!iommu_hpm->identifier)
+		return 0;
+
+	return sysfs_emit(buf, "%s\n", iommu_hpm->identifier);
+}
+
+static struct device_attribute riscv_iommu_hpm_identifier_attr =
+	__ATTR(identifier, 0444, riscv_iommu_hpm_identifier_show, NULL);
+
+static struct attribute *riscv_iommu_hpm_identifier_attrs[] = {
+	&riscv_iommu_hpm_identifier_attr.attr,
+	NULL
+};
+
+static const struct attribute_group riscv_iommu_hpm_identifier_group = {
+	.attrs = riscv_iommu_hpm_identifier_attrs,
+};
+
 #define IOMMU_HPM_EVENT_ATTR(name, config)		\
 	PMU_EVENT_ATTR_ID(name, riscv_iommu_hpm_event_show, config)
 
@@ -518,6 +542,7 @@ static const struct attribute_group *riscv_iommu_hpm_attr_grps[] = {
 	&riscv_iommu_hpm_cpumask_group,
 	&riscv_iommu_hpm_events_group,
 	&riscv_iommu_hpm_format_group,
+	&riscv_iommu_hpm_identifier_group,
 	NULL
 };
 
@@ -620,6 +645,36 @@ static void riscv_iommu_hpm_reset(struct riscv_iommu_hpm *iommu_hpm)
 	riscv_iommu_hpm_interrupt_clear(iommu_hpm);
 }
 
+static bool riscv_iommu_hpm_is_identifier_compat(const char *compat)
+{
+	return !strcmp(compat, "riscv,iommu");
+}
+
+static const char *riscv_iommu_hpm_get_identifier(struct device *dev)
+{
+	struct device_node *np = dev->of_node;
+	const char *compat;
+	int count, i;
+
+	if (!np)
+		return NULL;
+
+	count = of_property_count_strings(np, "compatible");
+	if (count <= 0)
+		return NULL;
+
+	for (i = 0; i < count; i++) {
+		if (of_property_read_string_index(np, "compatible",
+						  i, &compat))
+			continue;
+
+		if (riscv_iommu_hpm_is_identifier_compat(compat))
+			return devm_kstrdup(dev, compat, GFP_KERNEL);
+	}
+
+	return NULL;
+}
+
 static void riscv_iommu_hpm_set_standard_events(struct riscv_iommu_hpm *iommu_hpm)
 {
 	/* Cycles counter is always supported */
@@ -646,6 +701,7 @@ static void riscv_iommu_hpm_remove(void *data)
 static int riscv_iommu_hpm_register_unit(struct riscv_iommu_device *iommu,
 					 struct riscv_iommu_hpm *iommu_hpm,
 					 u32 offset, int irq,
+					 const char *identifier,
 					 const struct attribute_group **attr_groups,
 					 const char *prefix)
 {
@@ -659,6 +715,7 @@ static int riscv_iommu_hpm_register_unit(struct riscv_iommu_device *iommu,
 	unique_id = atomic_fetch_inc(&riscv_iommu_hpm_ids);
 	memset(iommu_hpm, 0, sizeof(*iommu_hpm));
 	iommu_hpm->iommu = iommu;
+	iommu_hpm->identifier = identifier;
 
 	if (offset + RISCV_IOMMU_REG_SIZE <= iommu->reg_size)
 		base = iommu->reg + offset;
@@ -788,6 +845,7 @@ static void riscv_iommu_hpm_exit(void)
 int riscv_iommu_add_hpm(struct riscv_iommu_device *iommu)
 {
 	struct device *dev = iommu->dev;
+	const char *identifier;
 	int irq, rc;
 
 	if (!FIELD_GET(RISCV_IOMMU_CAPABILITIES_HPM, iommu->caps)) {
@@ -806,7 +864,12 @@ int riscv_iommu_add_hpm(struct riscv_iommu_device *iommu)
 	if (rc < 0)
 		return rc;
 
+	identifier = riscv_iommu_hpm_get_identifier(dev);
+	if (identifier)
+		dev_info(dev, "HPM: Vendor identifier: %s\n", identifier);
+
 	rc = riscv_iommu_hpm_register_unit(iommu, &iommu->hpm, 0, irq,
+					   identifier,
 					   riscv_iommu_hpm_attr_grps,
 					   "riscv_iommu_hpm");
 	if (rc < 0)
drivers/iommu/riscv/iommu.h +1 -0
index 0ad9f5cad4de..d3c11abef5cf 100644
@@ -41,6 +41,7 @@ struct riscv_iommu_hpm {
 	int irq;
 	int on_cpu;
 	struct hlist_node node;
+	const char *identifier;
 	/*
 	 * Layout of events:
 	 * 0       -> HPMCYCLES
Signature · 1 line
2.43.0
#72 lore raw

PATCH v4 5/7 spacemit/t100: Add global filter awareness for RISC-V IOMMU HPM

In reply to a message not in the archive

Introduces global filter support for RISC-V IOMMU HPM. The global filter can be seen in SpacemiT T100 which only supports single filter to be applied to all event counters.

Drivers can program filters in each iohpmevt registers as normal in such a silicon design, however the underlying hardware filters are wired together as a global filter applying to all iohpmevt(s). Since the mechanism is compatible with standard iohpmevt in programming interface, only adds sanity checks to allow it to be configured with "global" awareness to inform users a filter incompatiblity.

---
 drivers/iommu/riscv/iommu-hpm.c | 68 ++++++++++++++++++++++++++++++---
 drivers/iommu/riscv/iommu.h     |  1 +
 2 files changed, 63 insertions(+), 6 deletions(-)
drivers/iommu/riscv/iommu-hpm.c +62 -6
index 4615c4b161a0..6860714fb61e 100644
@@ -134,6 +134,30 @@ static inline void riscv_iommu_hpm_interrupt_clear(struct riscv_iommu_hpm *hpm)
 	riscv_iommu_hpm_writel(hpm, RISCV_IOMMU_REG_IPSR, RISCV_IOMMU_IPSR_PMIP);
 }
 
+static bool riscv_iommu_hpm_check_global_filter(struct perf_event *curr,
+						struct perf_event *new)
+{
+	return get_filter_pid_pscid(curr) == get_filter_pid_pscid(new) &&
+	       get_filter_did_gscid(curr) == get_filter_did_gscid(new) &&
+	       get_filter_pv_pscv(curr) == get_filter_pv_pscv(new) &&
+	       get_filter_dv_gscv(curr) == get_filter_dv_gscv(new) &&
+	       get_filter_idt(curr) == get_filter_idt(new) &&
+	       get_filter_dmask(curr) == get_filter_dmask(new);
+}
+
+static bool riscv_iommu_hpm_events_compatible(struct perf_event *curr,
+					      struct perf_event *new)
+{
+	if (new->pmu != curr->pmu)
+		return false;
+
+	if (to_iommu_hpm(new->pmu)->global_filter &&
+	    !riscv_iommu_hpm_check_global_filter(curr, new))
+		return false;
+
+	return true;
+}
+
 /**
  * riscv_iommu_hpm_event_update() - Update and return RISC-V IOMMU HPM
  *                                  event counters
@@ -268,9 +292,10 @@ static void riscv_iommu_hpm_set_event_filter(struct perf_event *event, int idx,
 			       RISCV_IOMMU_REG_IOHPMEVT(idx), event_cfg);
 }
 
-static void riscv_iommu_hpm_apply_event_filter(struct riscv_iommu_hpm *iommu_hpm,
-					       struct perf_event *event, int idx)
+static int riscv_iommu_hpm_apply_event_filter(struct riscv_iommu_hpm *iommu_hpm,
+					      struct perf_event *event, int idx)
 {
+	unsigned int cur_idx, num_ctrs = iommu_hpm->num_counters;
 	u32 pid_pscid, did_gscid, pv_pscv, dv_gscv, idt, dmask;
 
 	pid_pscid = get_filter_pid_pscid(event);
@@ -280,14 +305,36 @@ static void riscv_iommu_hpm_apply_event_filter(struct riscv_iommu_hpm *iommu_hpm
 	idt = get_filter_idt(event);
 	dmask = get_filter_dmask(event);
 
+	if (iommu_hpm->global_filter) {
+		cur_idx = find_first_bit(iommu_hpm->used_counters, num_ctrs - 1);
+		if (cur_idx == num_ctrs - 1) {
+			/* First event, set the global filter */
+			riscv_iommu_hpm_set_event_filter(event, 0, pid_pscid,
+							 did_gscid,
+							 pv_pscv, dv_gscv, idt, dmask);
+		} else {
+			/* Check if the new event's filter is compatible with
+			 * the global filter
+			 */
+			if (!riscv_iommu_hpm_check_global_filter(iommu_hpm->events[cur_idx + 1],
+								 event)) {
+				dev_dbg(iommu_hpm->pmu.dev,
+					"HPM: Filter incompatible with global filter\n");
+				return -EAGAIN;
+			}
+		}
+		return 0;
+	}
+
 	riscv_iommu_hpm_set_event_filter(event, idx, pid_pscid, did_gscid,
 					 pv_pscv, dv_gscv, idt, dmask);
+	return 0;
 }
 
 static int riscv_iommu_hpm_get_event_idx(struct riscv_iommu_hpm *iommu_hpm,
 					 struct perf_event *event)
 {
-	int idx;
+	int idx, err;
 	unsigned int num_ctrs = iommu_hpm->num_counters;
 	u16 event_id = get_event(event);
 
@@ -309,7 +356,9 @@ static int riscv_iommu_hpm_get_event_idx(struct riscv_iommu_hpm *iommu_hpm,
 		return -EAGAIN;
 	}
 
-	riscv_iommu_hpm_apply_event_filter(iommu_hpm, event, idx);
+	err = riscv_iommu_hpm_apply_event_filter(iommu_hpm, event, idx);
+	if (err)
+		return err;
 	set_bit(idx, iommu_hpm->used_counters);
 
 	return idx;
@@ -405,6 +454,8 @@ static int riscv_iommu_hpm_event_init(struct perf_event *event)
 	}
 
 	if (!is_software_event(event->group_leader)) {
+		if (!riscv_iommu_hpm_events_compatible(event->group_leader, event))
+			return -EINVAL;
 		if (++group_num_events > iommu_hpm->num_counters)
 			return -EINVAL;
 	}
@@ -412,6 +463,8 @@ static int riscv_iommu_hpm_event_init(struct perf_event *event)
 	for_each_sibling_event(sibling, event->group_leader) {
 		if (is_software_event(sibling))
 			continue;
+		if (!riscv_iommu_hpm_events_compatible(sibling, event))
+			return -EINVAL;
 		if (++group_num_events > iommu_hpm->num_counters)
 			return -EINVAL;
 	}
@@ -729,6 +782,8 @@ static int riscv_iommu_hpm_register_unit(struct riscv_iommu_device *iommu,
 	bitmap_zero(iommu_hpm->used_counters, RISCV_IOMMU_HPMCOUNTER_MAX);
 	bitmap_zero(iommu_hpm->supported_events, RISCV_IOMMU_HPMEVENT_MAX);
 
+	iommu_hpm->global_filter = of_device_is_compatible(dev->of_node,
+							   "spacemit,t100");
 	riscv_iommu_hpm_writel(iommu_hpm,
 			       RISCV_IOMMU_REG_IOCOUNTINH, 0xFFFFFFFF);
 	val = riscv_iommu_hpm_readl(iommu_hpm,
@@ -793,8 +848,9 @@ static int riscv_iommu_hpm_register_unit(struct riscv_iommu_device *iommu,
 	if (err)
 		goto err_cpuhp;
 
-	dev_info(dev, "HPM: Registered %s (%d counters, IRQ %d)\n",
-		 pmu_name, iommu_hpm->num_counters, iommu_hpm->irq);
+	dev_info(dev, "HPM: Registered %s (%d counters, IRQ %d, %s filter)\n",
+		 pmu_name, iommu_hpm->num_counters, iommu_hpm->irq,
+		 iommu_hpm->global_filter ? "global" : "per-counter");
 	return 0;
 
 err_cpuhp:
drivers/iommu/riscv/iommu.h +1 -0
index d3c11abef5cf..80e96fd7e164 100644
@@ -42,6 +42,7 @@ struct riscv_iommu_hpm {
 	int on_cpu;
 	struct hlist_node node;
 	const char *identifier;
+	bool global_filter;
 	/*
 	 * Layout of events:
 	 * 0       -> HPMCYCLES
Signature · 1 line
2.43.0
#73 lore raw

PATCH v4 6/7 spacemit/t100: Add SpacemiT T100 IOATC HPM support

In reply to a message not in the archive

Adds IOATC discovery and HPM support for SpacemiT T100.

SpacemiT T100 supports distributed architecture which allows IOTLBs to be cached in adjacent to the DMA masters. Such IOTLB controllers are called as IOATCs. Adds distributed HPM support for IOATCs.

---
 drivers/iommu/riscv/iommu-bits.h     |  12 ++
 drivers/iommu/riscv/iommu-hpm.c      | 182 +++++++++++++++++++++++++--
 drivers/iommu/riscv/iommu-platform.c |   4 +-
 drivers/iommu/riscv/iommu.h          |   2 +-
 4 files changed, 188 insertions(+), 12 deletions(-)
drivers/iommu/riscv/iommu-bits.h +12 -0
index cc6bea064d8f..dcf95a99c1d1 100644
@@ -284,6 +284,18 @@ enum riscv_iommu_hpmevent_id {
 #define RISCV_IOMMU_ICVEC_PMIV		GENMASK_ULL(11, 8)
 #define RISCV_IOMMU_ICVEC_PIV		GENMASK_ULL(15, 12)
 
+/* 5.28 Distributed translation interface status register (dtisr0-3) (4 * 32-bits) */
+#define RISCV_IOMMU_REG_DTISR_BASE	0x02B0
+#define RISCV_IOMMU_REG_DTISR(_n)	(RISCV_IOMMU_REG_DTISR_BASE + ((_n) * 0x04))
+#define RISCV_IOMMU_DTI_STS_SHIFT(_n)	(((_n) % 16) * 2)
+#define RISCV_IOMMU_DTI_STS_MASK(_n)	(0x3 << RISCV_IOMMU_DTI_STS_SHIFT(_n))
+#define RISCV_IOMMU_DTI_STS_NONE	0x0
+#define RISCV_IOMMU_DTI_STS_IOATC	0x1
+
+#define MAX_RISCV_IOMMU_IOATC		64
+#define RISCV_IOMMU_IOATC_BASE(_base, _idx) \
+	((void __iomem *)((u8 __iomem *)(_base) + ((_idx) + 1) * RISCV_IOMMU_REG_SIZE))
+
 /* 5.28 MSI Configuration table (32 * 64bits) */
 #define RISCV_IOMMU_REG_MSI_CFG_TBL	0x0300
 #define RISCV_IOMMU_REG_MSI_CFG_TBL_ADDR(_n) \
drivers/iommu/riscv/iommu-hpm.c +173 -9

239 lines not on this page · raw message

drivers/iommu/riscv/iommu-platform.c +2 -2
index 684bc267ac30..ca8de9ec5266 100644
@@ -75,8 +75,8 @@ static int riscv_iommu_platform_probe(struct platform_device *pdev)
 	if (iommu->irqs_count <= 0)
 		return dev_err_probe(dev, -ENODEV,
 				     "no IRQ resources provided\n");
-	if (iommu->irqs_count > RISCV_IOMMU_INTR_COUNT)
-		iommu->irqs_count = RISCV_IOMMU_INTR_COUNT;
+	if (iommu->irqs_count > RISCV_IOMMU_INTR_COUNT + MAX_RISCV_IOMMU_IOATC)
+		iommu->irqs_count = RISCV_IOMMU_INTR_COUNT + MAX_RISCV_IOMMU_IOATC;
 
 	igs = FIELD_GET(RISCV_IOMMU_CAPABILITIES_IGS, iommu->caps);
 	switch (igs) {
drivers/iommu/riscv/iommu.h +1 -1
index 80e96fd7e164..c2f008d86d63 100644
@@ -76,7 +76,7 @@ struct riscv_iommu_device {
 	u32 fctl;
 
 	/* available interrupt numbers, MSI or WSI */
-	unsigned int irqs[RISCV_IOMMU_INTR_COUNT];
+	unsigned int irqs[RISCV_IOMMU_INTR_COUNT + MAX_RISCV_IOMMU_IOATC];
 	unsigned int irqs_count;
 	unsigned int icvec;
 
Signature · 1 line
2.43.0
#74 lore raw

PATCH v4 7/7 perf vendor events riscv:: Add support for spacemit,riscv-iommu HPM aliasing

In reply to a message not in the archive

Add JSON HPM event aliases for SpacemiT distributed IOMMU (T100) which is general and compatible for all SpacemiT RISC-V SoCs.

---
 MAINTAINERS                                   |   3 +
 .../arch/riscv/spacemit/iommu/sys/ioatc.json  |  30 ++++
 .../arch/riscv/spacemit/iommu/sys/ioats.json  | 163 ++++++++++++++++++
 3 files changed, 196 insertions(+)
 create mode 100644 tools/perf/pmu-events/arch/riscv/spacemit/iommu/sys/ioatc.json
 create mode 100644 tools/perf/pmu-events/arch/riscv/spacemit/iommu/sys/ioats.json
MAINTAINERS +3 -0
index 7c50701b6001..4d91f99aa742 100644
@@ -22459,12 +22459,15 @@ K:	riscv
 
 RISC-V IOMMU
 M:	Tomasz Jeznach <[email protected]>
+M:	Lv Zheng <[email protected]>
+M:	Jingyu Li <[email protected]>
 L:	[email protected]
 L:	[email protected]
 S:	Maintained
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/iommu/linux.git
 F:	Documentation/devicetree/bindings/iommu/riscv,iommu.yaml
 F:	drivers/iommu/riscv/
+F:	tools/perf/pmu-events/arch/riscv/spacemit/iommu/
 
 RISC-V MICROCHIP SUPPORT
 M:	Conor Dooley <[email protected]>
tools/perf/pmu-events/arch/riscv/spacemit/iommu/sys/ioatc.json new file +30 -0
new file mode 100644
index 000000000000..a16610ba2274
@@ -0,0 +1,30 @@
+[
+  {
+    "EventName": "mtlb_lkp",
+    "EventCode": "0x38",
+    "BriefDescription": "IOATC main TLB (MTLB) lookups",
+    "Unit": "spacemit_ioatc_hpm",
+    "Compat": "spacemit,riscv-iommu"
+  },
+  {
+    "EventName": "mtlb_mis",
+    "EventCode": "0x39",
+    "BriefDescription": "IOATC main TLB (MTLB) misses",
+    "Unit": "spacemit_ioatc_hpm",
+    "Compat": "spacemit,riscv-iommu"
+  },
+  {
+    "EventName": "utlb_lkp",
+    "EventCode": "0x3A",
+    "BriefDescription": "IOATC micro TLB (uTLB) lookups",
+    "Unit": "spacemit_ioatc_hpm",
+    "Compat": "spacemit,riscv-iommu"
+  },
+  {
+    "EventName": "utlb_mis",
+    "EventCode": "0x3B",
+    "BriefDescription": "IOATC micro TLB (uTLB) misses",
+    "Unit": "spacemit_ioatc_hpm",
+    "Compat": "spacemit,riscv-iommu"
+  }
+]
tools/perf/pmu-events/arch/riscv/spacemit/iommu/sys/ioats.json new file +163 -0

163 lines not on this page · raw message

Signature · 1 line
2.43.0