From: fangyu.yu@linux.alibaba.com
To: sunilvl@oss.qualcomm.com, sunilvl@ventanamicro.com,
rafael@kernel.org, lenb@kernel.org, pjw@kernel.org,
palmer@dabbelt.com, aou@eecs.berkeley.edu, alex@ghiti.fr
Cc: fangyu.yu@linux.alibaba.com, guoren@kernel.org,
linux-acpi@vger.kernel.org, iommu@lists.linux.dev,
linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org
Subject: [PATCH] ACPI: RIMT: Enable PCI ACS for root complexes mapped to an IOMMU
Date: Wed, 2 Sep 2026 22:01:45 +0800 [thread overview]
Message-ID: <20260902140145.42094-1-fangyu.yu@linux.alibaba.com> (raw)
From: Fangyu Yu <fangyu.yu@linux.alibaba.com>
Mirror the ACPI IORT solution used on arm64 (see iort_enable_acs())
by scanning the RIMT table for PCIe root complex nodes during
riscv_acpi_rimt_init(), which runs before ACPI PCI enumeration. If a
root complex node's ID mapping points at an IOMMU node, call
pci_request_acs() immediately, so pci_acs_enable is already set by
the time any PCI device is scanned and pci_enable_acs() runs.
Only one call to pci_request_acs() is needed regardless of how many
root complexes are found, so track that with a static acs_enabled
flag, same as iort_enable_acs() does.
Signed-off-by: Fangyu Yu <fangyu.yu@linux.alibaba.com>
---
drivers/acpi/riscv/rimt.c | 56 +++++++++++++++++++++++++++++++++++++++
1 file changed, 56 insertions(+)
diff --git a/drivers/acpi/riscv/rimt.c b/drivers/acpi/riscv/rimt.c
index e4538fa6c2c8..f22e28c8211e 100644
--- a/drivers/acpi/riscv/rimt.c
+++ b/drivers/acpi/riscv/rimt.c
@@ -179,6 +179,42 @@ static struct acpi_rimt_node *rimt_scan_node(enum acpi_rimt_node_type type,
return NULL;
}
+#ifdef CONFIG_PCI
+static void __init rimt_enable_acs(struct acpi_rimt_node *rimt_node)
+{
+ static bool acs_enabled __initdata;
+ struct acpi_rimt_pcie_rc *pci_rc;
+ struct acpi_rimt_id_mapping *map;
+ struct acpi_rimt_node *parent;
+ int i;
+
+ if (acs_enabled || rimt_node->type != ACPI_RIMT_NODE_TYPE_PCIE_ROOT_COMPLEX)
+ return;
+
+ pci_rc = (struct acpi_rimt_pcie_rc *)rimt_node->node_data;
+ if (!pci_rc->id_mapping_offset || !pci_rc->num_id_mappings)
+ return;
+
+ map = ACPI_ADD_PTR(struct acpi_rimt_id_mapping, rimt_node,
+ pci_rc->id_mapping_offset);
+
+ for (i = 0; i < pci_rc->num_id_mappings; i++, map++) {
+ if (!map->dest_offset)
+ continue;
+
+ parent = ACPI_ADD_PTR(struct acpi_rimt_node, rimt_table,
+ map->dest_offset);
+ if (parent->type == ACPI_RIMT_NODE_TYPE_IOMMU) {
+ pci_request_acs();
+ acs_enabled = true;
+ return;
+ }
+ }
+}
+#else
+static inline void rimt_enable_acs(struct acpi_rimt_node *rimt_node) { }
+#endif
+
/*
* RISC-V supports IOMMU as a PCI device or a platform device.
* When it is a platform device, there should be a namespace device as
@@ -509,7 +545,10 @@ int rimt_iommu_configure_id(struct device *dev, const u32 *id_in)
void __init riscv_acpi_rimt_init(void)
{
+ struct acpi_rimt_node *rimt_node, *rimt_end;
+ struct acpi_table_rimt *rimt;
acpi_status status;
+ int i;
/* rimt_table will be used at runtime after the rimt init,
* so we don't need to call acpi_put_table() to release
@@ -525,4 +564,21 @@ void __init riscv_acpi_rimt_init(void)
return;
}
+
+ rimt = (struct acpi_table_rimt *)rimt_table;
+ rimt_node = ACPI_ADD_PTR(struct acpi_rimt_node, rimt,
+ rimt->node_offset);
+ rimt_end = ACPI_ADD_PTR(struct acpi_rimt_node, rimt_table,
+ rimt_table->length);
+
+ for (i = 0; i < rimt->num_nodes; i++) {
+ if (rimt_node >= rimt_end) {
+ pr_err("RIMT node pointer overflows, bad table\n");
+ return;
+ }
+
+ rimt_enable_acs(rimt_node);
+ rimt_node = ACPI_ADD_PTR(struct acpi_rimt_node, rimt_node,
+ rimt_node->length);
+ }
}
--
2.50.1
WARNING: multiple messages have this Message-ID (diff)
From: fangyu.yu@linux.alibaba.com
To: sunilvl@oss.qualcomm.com, sunilvl@ventanamicro.com,
rafael@kernel.org, lenb@kernel.org, pjw@kernel.org,
palmer@dabbelt.com, aou@eecs.berkeley.edu, alex@ghiti.fr
Cc: fangyu.yu@linux.alibaba.com, guoren@kernel.org,
linux-acpi@vger.kernel.org, iommu@lists.linux.dev,
linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org
Subject: [PATCH] ACPI: RIMT: Enable PCI ACS for root complexes mapped to an IOMMU
Date: Wed, 2 Sep 2026 22:01:45 +0800 [thread overview]
Message-ID: <20260902140145.42094-1-fangyu.yu@linux.alibaba.com> (raw)
From: Fangyu Yu <fangyu.yu@linux.alibaba.com>
Mirror the ACPI IORT solution used on arm64 (see iort_enable_acs())
by scanning the RIMT table for PCIe root complex nodes during
riscv_acpi_rimt_init(), which runs before ACPI PCI enumeration. If a
root complex node's ID mapping points at an IOMMU node, call
pci_request_acs() immediately, so pci_acs_enable is already set by
the time any PCI device is scanned and pci_enable_acs() runs.
Only one call to pci_request_acs() is needed regardless of how many
root complexes are found, so track that with a static acs_enabled
flag, same as iort_enable_acs() does.
Signed-off-by: Fangyu Yu <fangyu.yu@linux.alibaba.com>
---
drivers/acpi/riscv/rimt.c | 56 +++++++++++++++++++++++++++++++++++++++
1 file changed, 56 insertions(+)
diff --git a/drivers/acpi/riscv/rimt.c b/drivers/acpi/riscv/rimt.c
index e4538fa6c2c8..f22e28c8211e 100644
--- a/drivers/acpi/riscv/rimt.c
+++ b/drivers/acpi/riscv/rimt.c
@@ -179,6 +179,42 @@ static struct acpi_rimt_node *rimt_scan_node(enum acpi_rimt_node_type type,
return NULL;
}
+#ifdef CONFIG_PCI
+static void __init rimt_enable_acs(struct acpi_rimt_node *rimt_node)
+{
+ static bool acs_enabled __initdata;
+ struct acpi_rimt_pcie_rc *pci_rc;
+ struct acpi_rimt_id_mapping *map;
+ struct acpi_rimt_node *parent;
+ int i;
+
+ if (acs_enabled || rimt_node->type != ACPI_RIMT_NODE_TYPE_PCIE_ROOT_COMPLEX)
+ return;
+
+ pci_rc = (struct acpi_rimt_pcie_rc *)rimt_node->node_data;
+ if (!pci_rc->id_mapping_offset || !pci_rc->num_id_mappings)
+ return;
+
+ map = ACPI_ADD_PTR(struct acpi_rimt_id_mapping, rimt_node,
+ pci_rc->id_mapping_offset);
+
+ for (i = 0; i < pci_rc->num_id_mappings; i++, map++) {
+ if (!map->dest_offset)
+ continue;
+
+ parent = ACPI_ADD_PTR(struct acpi_rimt_node, rimt_table,
+ map->dest_offset);
+ if (parent->type == ACPI_RIMT_NODE_TYPE_IOMMU) {
+ pci_request_acs();
+ acs_enabled = true;
+ return;
+ }
+ }
+}
+#else
+static inline void rimt_enable_acs(struct acpi_rimt_node *rimt_node) { }
+#endif
+
/*
* RISC-V supports IOMMU as a PCI device or a platform device.
* When it is a platform device, there should be a namespace device as
@@ -509,7 +545,10 @@ int rimt_iommu_configure_id(struct device *dev, const u32 *id_in)
void __init riscv_acpi_rimt_init(void)
{
+ struct acpi_rimt_node *rimt_node, *rimt_end;
+ struct acpi_table_rimt *rimt;
acpi_status status;
+ int i;
/* rimt_table will be used at runtime after the rimt init,
* so we don't need to call acpi_put_table() to release
@@ -525,4 +564,21 @@ void __init riscv_acpi_rimt_init(void)
return;
}
+
+ rimt = (struct acpi_table_rimt *)rimt_table;
+ rimt_node = ACPI_ADD_PTR(struct acpi_rimt_node, rimt,
+ rimt->node_offset);
+ rimt_end = ACPI_ADD_PTR(struct acpi_rimt_node, rimt_table,
+ rimt_table->length);
+
+ for (i = 0; i < rimt->num_nodes; i++) {
+ if (rimt_node >= rimt_end) {
+ pr_err("RIMT node pointer overflows, bad table\n");
+ return;
+ }
+
+ rimt_enable_acs(rimt_node);
+ rimt_node = ACPI_ADD_PTR(struct acpi_rimt_node, rimt_node,
+ rimt_node->length);
+ }
}
--
2.50.1
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
next reply other threads:[~2026-09-02 14:02 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-02 14:01 fangyu.yu [this message]
2026-09-02 14:01 ` [PATCH] ACPI: RIMT: Enable PCI ACS for root complexes mapped to an IOMMU fangyu.yu
2026-09-03 4:45 ` Sunil V L
2026-09-03 4:45 ` Sunil V L
2026-09-03 7:44 ` fangyu.yu
2026-09-03 7:44 ` fangyu.yu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260902140145.42094-1-fangyu.yu@linux.alibaba.com \
--to=fangyu.yu@linux.alibaba.com \
--cc=alex@ghiti.fr \
--cc=aou@eecs.berkeley.edu \
--cc=guoren@kernel.org \
--cc=iommu@lists.linux.dev \
--cc=lenb@kernel.org \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=palmer@dabbelt.com \
--cc=pjw@kernel.org \
--cc=rafael@kernel.org \
--cc=sunilvl@oss.qualcomm.com \
--cc=sunilvl@ventanamicro.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.