Index | Thread | Search

From:
hshoexer <hshoexer@yerbouti.franken.de>
Subject:
acpidmar(4): Apply DTE settings
To:
tech@openbsd.org
Date:
Tue, 7 Apr 2026 15:57:32 +0200

Download raw body.

Thread
  • hshoexer:

    acpidmar(4): Apply DTE settings

Hi,

this is a follow-up on my previous diff [1]:  When setting an AMD-Vi
DTE entry, apply the previously recorded settings.

Thoughts? Comments? ok?

Take care,
HJ.

----------------------------------------------------------------------------
commit f7320935063f51fa36c2a3b8b2902a1d36a770d1
Author: Hans-Joerg Hoexer <hshoexer@genua.de>
Date:   Wed Mar 25 12:48:25 2026 +0100

    acpidmar(4): When mapping a device apply DTE settings

diff --git a/sys/dev/acpi/acpidmar.c b/sys/dev/acpi/acpidmar.c
index 41aa8502bb3..6fc7ad99306 100644
--- a/sys/dev/acpi/acpidmar.c
+++ b/sys/dev/acpi/acpidmar.c
@@ -2552,6 +2552,29 @@ void
 	return dom;
 }
 
+void
+domain_apply_dteset(struct ivhd_dte *dte, struct domain *dom)
+{
+	struct ivhd_dteset *dteset;
+
+	if ((dteset = dom->dteset) == NULL || dteset->dte == 0)
+		return;
+
+	if (dteset->dte & IVHD_LINT1PASS)
+		dte_set_lint1pass(dte);
+	if (dteset->dte & IVHD_LINT0PASS)
+		dte_set_lint0pass(dte);
+	if ((dteset->dte >> IVHD_SYSMGT_SHIFT) & IVHD_SYSMGT_MASK)
+		dte_set_sysmgt(dte, (dteset->dte >> IVHD_SYSMGT_SHIFT) &
+		    IVHD_SYSMGT_MASK);
+	if (dteset->dte & IVHD_NMIPASS)
+		dte_set_nmipass(dte);
+	if (dteset->dte & IVHD_EINTPASS)
+		dte_set_eintpass(dte);
+	if (dteset->dte & IVHD_INITPASS)
+		dte_set_initpass(dte);
+}
+
 void
 domain_map_device(struct domain *dom, int sid)
 {
@@ -2571,6 +2594,7 @@ domain_map_device(struct domain *dom, int sid)
 		if (!dte->dw0) {
 			/* Setup Device Table Entry: bus.devfn */
 			DPRINTF(1, "@@@ PCI Attach: %.4x[%s] %.4x\n", sid, dmar_bdf(sid), dom->did);
+			domain_apply_dteset(dte, dom);
 			dte_set_host_page_table_root_ptr(dte, dom->ptep);
 			dte_set_domain(dte, dom->did);
 			dte_set_mode(dte, 3);  /* Set 3 level PTE */
diff --git a/sys/dev/acpi/acpireg.h b/sys/dev/acpi/acpireg.h
index 9e9653c7dfc..70380c561c8 100644
--- a/sys/dev/acpi/acpireg.h
+++ b/sys/dev/acpi/acpireg.h
@@ -622,6 +622,14 @@ union acpi_ivhd_entry {
 		uint8_t		type;
 		uint16_t	resvd;
 		uint8_t		data;
+#define IVHD_LINT1PASS			(1L << 7)
+#define IVHD_LINT0PASS			(1L << 6)
+#define IVHD_SYSMGT_SHIFT		4
+#define IVHD_SYSMGT_MASK		0x3
+#define IVHD_DTERESVD			(1L << 3)
+#define IVHD_NMIPASS			(1L << 2)
+#define IVHD_EINTPASS			(1L << 1)
+#define IVHD_INITPASS			(1L << 0)
 	} __packed all;
 	struct {
 		uint8_t		type;
diff --git a/sys/dev/acpi/amd_iommu.h b/sys/dev/acpi/amd_iommu.h
index 9a071552e78..7fd312a5f6d 100644
--- a/sys/dev/acpi/amd_iommu.h
+++ b/sys/dev/acpi/amd_iommu.h
@@ -177,10 +177,21 @@ struct ivhd_dte {
 #define DTE_IV			(1L << 0)			/* dw3 */
 #define DTE_SE			(1L << 1)
 #define DTE_SA			(1L << 2)
-#define DTE_INTTABLEN_SHIFT	1
+#define DTE_SYSMGT_SHIFT	8
+#define DTE_SYSMGT_MASK		0x3
+
+#define DTE_INTTABLEN_SHIFT	1				/* dw4 */
 #define DTE_INTTABLEN_MASK	0xF
 #define DTE_IRTP_MASK		0x000FFFFFFFFFFFC0LL
 
+#define DTE_INITPASS		(1L << 24)			/* dw5 */
+#define DTE_EINTPASS		(1L << 25)
+#define DTE_NMIPASS		(1L << 26)
+#define DTE_INTCTL_SHIFT	28
+#define DTE_INTCTL_MASK		0x3
+#define DTE_LINT0PASS		(1L << 30)
+#define DTE_LINT1PASS		(1L << 31)
+
 #define PTE_LVL5                48
 #define PTE_LVL4                39
 #define PTE_LVL3                30
@@ -261,6 +272,13 @@ dte_set_mode(struct ivhd_dte *dte, int mode)
 	iommu_rmw32(&dte->dw0, DTE_LEVEL_MASK, DTE_LEVEL_SHIFT, mode);
 }
 
+/* Set System Management Message Enable */
+static inline void
+dte_set_sysmgt(struct ivhd_dte *dte, int mode)
+{
+	iommu_rmw32(&dte->dw3, DTE_SYSMGT_MASK, DTE_SYSMGT_SHIFT, mode);
+}
+
 static inline void
 dte_set_tv(struct ivhd_dte *dte)
 {
@@ -283,6 +301,41 @@ dte_is_valid(struct ivhd_dte *dte)
 	return (dte->dw0 & DTE_V);
 }
 
+/* Set Lint1Pass */
+static inline void
+dte_set_lint1pass(struct ivhd_dte *dte)
+{
+	dte->dw5 |= DTE_LINT1PASS;
+}
+
+/* Set Lint0Pass */
+static inline void
+dte_set_lint0pass(struct ivhd_dte *dte)
+{
+	dte->dw5 |= DTE_LINT0PASS;
+}
+
+/* Set NMIPass */
+static inline void
+dte_set_nmipass(struct ivhd_dte *dte)
+{
+	dte->dw5 |= DTE_NMIPASS;
+}
+
+/* Set EIntPass */
+static inline void
+dte_set_eintpass(struct ivhd_dte *dte)
+{
+	dte->dw5 |= DTE_EINTPASS;
+}
+
+/* Set InitPass */
+static inline void
+dte_set_initpass(struct ivhd_dte *dte)
+{
+	dte->dw5 |= DTE_INITPASS;
+}
+
 /*=========================================
  * COMMAND
  *=========================================*/