:: commit 37eddc6ddb13a1b8227cbccdd26388744b72e83a

Mintsuki <mintsuki@protonmail.com> — 2026-02-23 14:39

parents: 5c307663a6

sys/iommu: Fix VT-d disable order to TE, IRE, QIE

diff --git a/common/sys/iommu.c b/common/sys/iommu.c
index 6dd4e1a0..c9490409 100644
--- a/common/sys/iommu.c
+++ b/common/sys/iommu.c
@@ -32,30 +32,29 @@
 static void vtd_disable_unit(uintptr_t reg_base) {
     uint32_t sts = mmind(reg_base + VTD_GSTS_REG);
 
-    // Disable interrupt remapping first (IRE depends on QIE, so reverse
-    // the enable order: disable IRE before QIE)
-    if (sts & VTD_GSTS_IRES) {
-        uint32_t gcmd = (sts & VTD_GCMD_ONESHOT_MASK) & ~VTD_GSTS_IRES;
+    // Disable DMA translation first (most urgent: prevents stale lookups)
+    if (sts & VTD_GSTS_TES) {
+        uint32_t gcmd = (sts & VTD_GCMD_ONESHOT_MASK) & ~VTD_GSTS_TES;
         mmoutd(reg_base + VTD_GCMD_REG, gcmd);
 
         for (int i = 0; i < VTD_TIMEOUT; i++) {
             asm volatile ("pause");
             sts = mmind(reg_base + VTD_GSTS_REG);
-            if (!(sts & VTD_GSTS_IRES)) {
+            if (!(sts & VTD_GSTS_TES)) {
                 break;
             }
         }
     }
 
-    // Disable DMA translation
-    if (sts & VTD_GSTS_TES) {
-        uint32_t gcmd = (sts & VTD_GCMD_ONESHOT_MASK) & ~VTD_GSTS_TES;
+    // Disable interrupt remapping (depends on QIE, so disable before QIE)
+    if (sts & VTD_GSTS_IRES) {
+        uint32_t gcmd = (sts & VTD_GCMD_ONESHOT_MASK) & ~VTD_GSTS_IRES;
         mmoutd(reg_base + VTD_GCMD_REG, gcmd);
 
         for (int i = 0; i < VTD_TIMEOUT; i++) {
             asm volatile ("pause");
             sts = mmind(reg_base + VTD_GSTS_REG);
-            if (!(sts & VTD_GSTS_TES)) {
+            if (!(sts & VTD_GSTS_IRES)) {
                 break;
             }
         }
tab: 248 wrap: offon