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: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-02 14:01 fangyu.yu [this message]
2026-09-03 4:45 ` [PATCH] ACPI: RIMT: Enable PCI ACS for root complexes mapped to an IOMMU Sunil V L
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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox