On 6/10/2026 2:13 AM, Dongli Zhang wrote:
When QEMU records an AMD-Vi event-log entry for an IO page fault, it
sets the event interrupt status bit and injects the event interrupt.

Linux kernel prior to commit 2379f3485239 ("iommu/amd: Refactor IOMMU
interrupt handling logic for Event, PPR, and GA logs") clears the status
register with a combined mask AMD_IOMMU_INT_MASK when handling any IOMMU
interrupt. That mask includes the
GA log interrupt (MMIO_STATUS_GALOG_INT_MASK) and
overflow (MMIO_STATUS_GALOG_OVERFLOW_MASK) bits, even when the interrupt
being handled is only an event-log interrupt.

QEMU does not produce GA log entries or set GA log status. However, the
emulated status register still accepts guest writes to the GA log status
bits as normal writes. As a result, a guest status clear write that
includes those bits can latch a spurious GA log overflow. The guest then
observes GA log status that QEMU did not generate and repeatedly
restarts the GA log.

The below guest dmesg logs are from v6.4 Linux kernel.

[   57.818224] virtio-pci 0000:01:00.0: AMD-Vi: Event logged [IO_PAGE_FAULT 
domain=0x0000 address=0xc0000000 flags=0x0009]
[   57.821130] virtio-pci 0000:01:00.0: AMD-Vi: Event logged [IO_PAGE_FAULT 
domain=0x0000 address=0xc0000000 flags=0x0009]
[   57.824003] AMD-Vi: IOMMU GA Log overflow
[   57.825099] AMD-Vi: IOMMU GA Log restarting
[   57.826338] AMD-Vi: IOMMU GA Log overflow
[   57.827425] AMD-Vi: IOMMU GA Log restarting
[   57.828657] AMD-Vi: IOMMU GA Log overflow
[   57.829758] AMD-Vi: IOMMU GA Log restarting
[   57.830986] AMD-Vi: IOMMU GA Log overflow
[   57.832063] AMD-Vi: IOMMU GA Log restarting

Mainline Linux commit 2379f3485239 ("iommu/amd: Refactor IOMMU interrupt
handling logic for Event, PPR, and GA logs") avoids triggering this by
chance by clearing only the status bits for the log being handled. However,
older guests still use the combined clear mask.

Add the GA log interrupt and overflow bits to the AMDVI_MMIO_STATUS
w1cmask so guest writes cannot create unsupported GA log status. This
does not implement GA log production. It only prevents guest status clear
writes from creating GA log status that QEMU did not generate to
emulated IO page fault for guest Linux kernel.

Signed-off-by: Dongli Zhang <[email protected]>
---
  hw/i386/amd_iommu.c | 4 +++-
  hw/i386/amd_iommu.h | 2 ++
  2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c
index ca9d79bb51..996c154a3f 100644
--- a/hw/i386/amd_iommu.c
+++ b/hw/i386/amd_iommu.c
@@ -2414,7 +2414,9 @@ static void amdvi_init(AMDVIState *s)
      amdvi_set_quad(s, AMDVI_MMIO_EXT_FEATURES,
                     amdvi_extended_feature_register(s),
                     0xffffffffffffffef, 0);

Not related to this patch, but we have another cleanup opportunity here
All the extended feature bits are read only, the value 0xffffffffffffffef does not make sense. We can have it as.. #define AMDVI_MMIO_EXTENDED_FEATURE_RO_MASK (~0ULL)
-    amdvi_set_quad(s, AMDVI_MMIO_STATUS, 0, 0x98, 0x67);
+    amdvi_set_quad(s, AMDVI_MMIO_STATUS, 0, 0x98,
+                   0x67 | AMDVI_MMIO_STATUS_GALOG_OVF |
+                   AMDVI_MMIO_STATUS_GALOG_INT);
  }

The 0x98 and 0x67 looks ambiguous. I was planning to clean this
code by defining macro for every field in the IOMMU status
register and using them like..

#define AMDVI_MMIO_STATUS_RO_MASK (..)   #OR of Read only fields
#define AMDVI_MMIO_STATUS_W1C_MASK (..)   #OR or the write-1-to-clear fields

Since you are touching this code, it would be great if you can
clean it up a little bit more.

Thanks
Sairaj

  static void amdvi_pci_realize(PCIDevice *pdev, Error **errp)
diff --git a/hw/i386/amd_iommu.h b/hw/i386/amd_iommu.h
index 302ccca512..0b2e8d207b 100644
--- a/hw/i386/amd_iommu.h
+++ b/hw/i386/amd_iommu.h
@@ -113,6 +113,8 @@
  #define AMDVI_MMIO_STATUS_COMP_INT    (1 << 2)
  #define AMDVI_MMIO_STATUS_EVENT_INT   (1 << 1)
  #define AMDVI_MMIO_STATUS_EVT_OVF     (1 << 0)
+#define AMDVI_MMIO_STATUS_GALOG_OVF   (1 << 9)
+#define AMDVI_MMIO_STATUS_GALOG_INT   (1 << 10)
#define AMDVI_CMDBUF_ID_BYTE 0x07
  #define AMDVI_CMDBUF_ID_RSHIFT            4


Reply via email to