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);