[PATCH 3/8] ACPI: LoongArch: Enable pci acs function if acpi iovt tables exist
From: Bibo Mao
Date: Wed Jun 17 2026 - 03:49:58 EST
IOMMU requires pci acs function enabled, so that all the DMA transaction
of pci device is routed to upper PCI bridge and IOMMU device.
Here scan IOMMU iovt table in function acpi_iovt_init(), which is
executed before PCI device sanning, and enable pci acs function if
iovt tables exist.
Signed-off-by: Bibo Mao <maobibo@xxxxxxxxxxx>
---
drivers/acpi/loongarch/iovt.c | 47 +++++++++++++++++++++++++++++++++++
include/acpi/actbl2.h | 3 +++
2 files changed, 50 insertions(+)
diff --git a/drivers/acpi/loongarch/iovt.c b/drivers/acpi/loongarch/iovt.c
index 793ed13a2cef..5e3d866796a9 100644
--- a/drivers/acpi/loongarch/iovt.c
+++ b/drivers/acpi/loongarch/iovt.c
@@ -1,7 +1,54 @@
// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/acpi.h>
+#include <linux/pci.h>
#include "init.h"
+#ifdef CONFIG_PCI
+static void __init iovt_enable_acs(struct acpi_iovt_iommu *iommu)
+{
+ static bool acs_enabled __initdata;
+
+ if (acs_enabled)
+ return;
+
+ /* IOMMU V1 only supports PCI device management */
+ if ((iommu->header.type == ACPI_IOVT_IOMMU_V1) ||
+ (iommu->flags & (ACPI_IOVT_PCI_DEVICE | ACPI_IOVT_MAGAGE_BY_SEGMENT))) {
+ pci_request_acs();
+ acs_enabled = true;
+ }
+}
+#else
+static inline void iovt_enable_acs(struct acpi_iovt_iommu *iommu) { }
+#endif
+
void __init acpi_iovt_init(void)
{
+ acpi_status status;
+ struct acpi_table_header *hdr;
+ struct acpi_table_iovt *iovt;
+ struct acpi_iovt_iommu *iommu;
+ int i;
+
+ status = acpi_get_table(ACPI_SIG_IOVT, 0, &hdr);
+ if (ACPI_FAILURE(status)) {
+ if (status != AE_NOT_FOUND) {
+ const char *msg = acpi_format_exception(status);
+
+ pr_err("Failed to get table, %s\n", msg);
+ }
+
+ return;
+ }
+
+ iovt = (struct acpi_table_iovt *)&hdr;
+ iommu = ACPI_ADD_PTR(struct acpi_iovt_iommu, iovt, iovt->iommu_offset);
+ for (i = 0; i < iovt->iommu_count; i++) {
+ iovt_enable_acs(iommu);
+
+ iommu = ACPI_ADD_PTR(struct acpi_iovt_iommu, iommu, iommu->header.length);
+ }
+
+ acpi_put_table(hdr);
}
diff --git a/include/acpi/actbl2.h b/include/acpi/actbl2.h
index baef525367b5..acc51a42c3ed 100644
--- a/include/acpi/actbl2.h
+++ b/include/acpi/actbl2.h
@@ -892,6 +892,9 @@ struct acpi_iovt_header {
/* Values for Type field above */
+#define ACPI_IOVT_PCI_DEVICE BIT(0)
+#define ACPI_IOVT_PXM_VALID BIT(1)
+#define ACPI_IOVT_MAGAGE_BY_SEGMENT BIT(2)
enum acpi_iovt_iommu_type {
ACPI_IOVT_IOMMU_V1 = 0x00,
ACPI_IOVT_IOMMU_RESERVED = 0x01 /* 1 and greater are reserved */
--
2.39.3