x86/intel-iommu: properly ack edu interrupt
Writing zero to EDU_REG_INTR_RAISE doesn't clear the status, because
the value is ORed in. The edu spec says that to clear the interrupt,
regardless of using MSI or not, one should write the value of the
interrupt status register to the interrupt acknowledge register from
the interrupt handler.
Cc: Peter Xu <peterx@redhat.com>
Signed-off-by: Andrew Jones <drjones@redhat.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
diff --git a/lib/pci-edu.h b/lib/pci-edu.h
index 9fe32c6..44b4ba1 100644
--- a/lib/pci-edu.h
+++ b/lib/pci-edu.h
@@ -32,7 +32,9 @@
#define EDU_REG_ALIVE 0x4
#define EDU_REG_FACTORIAL 0x8
#define EDU_REG_STATUS 0x20
+#define EDU_REG_INTR_STATUS 0x24
#define EDU_REG_INTR_RAISE 0x60
+#define EDU_REG_INTR_ACK 0x64
#define EDU_REG_DMA_SRC 0x80
#define EDU_REG_DMA_DST 0x88
#define EDU_REG_DMA_COUNT 0x90
diff --git a/x86/intel-iommu.c b/x86/intel-iommu.c
index fa77914..d1fa420 100644
--- a/x86/intel-iommu.c
+++ b/x86/intel-iommu.c
@@ -67,6 +67,8 @@
{
edu_intr_recved = true;
eoi();
+ edu_reg_writel(&edu_dev, EDU_REG_INTR_ACK,
+ edu_reg_readl(&edu_dev, EDU_REG_INTR_STATUS));
}
static void vtd_test_ir(void)
@@ -120,9 +122,6 @@
while (!edu_intr_recved)
cpu_relax();
- /* Clear INTR bits */
- edu_reg_writel(dev, EDU_REG_INTR_RAISE, 0);
-
/* We are good as long as we reach here */
report(VTD_TEST_IR_MSI, edu_intr_recved == true);