aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSuravee Suthikulpanit <suravee.suthikulpanit@amd.com>2013-07-11 15:10:23 +0200
committerJan Beulich <jbeulich@suse.com>2013-07-11 15:10:23 +0200
commit625adff3a665e0edcce6fc96b269379263f4ff6d (patch)
tree16fdccaaf336e9b26a3acbcb5d2356bd37b2636d
parent0d57d46c71ded043c14b39660c7eeddb96c650a9 (diff)
downloadxen-625adff3a665e0edcce6fc96b269379263f4ff6d.tar.gz
xen-625adff3a665e0edcce6fc96b269379263f4ff6d.tar.bz2
xen-625adff3a665e0edcce6fc96b269379263f4ff6d.zip
iommu/amd: Workaround for erratum 787
The IOMMU interrupt handling in bottom half must clear the PPR log interrupt and event log interrupt bits to re-enable the interrupt. This is done by writing 1 to the memory mapped register to clear the bit. Due to hardware bug, if the driver tries to clear this bit while the IOMMU hardware also setting this bit, the conflict will result with the bit being set. If the interrupt handling code does not make sure to clear this bit, subsequent changes in the event/PPR logs will no longer generating interrupts, and would result if buffer overflow. After clearing the bits, the driver must read back the register to verify. Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com> Adjust to apply on top of heavily modified patch 1. Adjust flow to get away with a single readl() in each instance of the status register checks. Signed-off-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Tim Deegan <tim@xen.org> Acked-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com> master commit: 9eabb0735400e2b6059dfa3f0b47a426f61f570a master date: 2013-07-02 08:50:41 +0200
-rw-r--r--xen/drivers/passthrough/amd/iommu_init.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/xen/drivers/passthrough/amd/iommu_init.c b/xen/drivers/passthrough/amd/iommu_init.c
index b87b61301c..d105e35c3c 100644
--- a/xen/drivers/passthrough/amd/iommu_init.c
+++ b/xen/drivers/passthrough/amd/iommu_init.c
@@ -593,6 +593,14 @@ static void do_amd_iommu_irq(unsigned long data)
}
}
+ /*
+ * Workaround for erratum787:
+ * Re-check to make sure the bit has been cleared.
+ */
+ entry = readl(iommu->mmio_base + IOMMU_STATUS_MMIO_OFFSET);
+ if ( entry & IOMMU_STATUS_EVENT_LOG_INT_MASK )
+ tasklet_schedule(&amd_iommu_irq_tasklet);
+
spin_unlock_irqrestore(&iommu->lock, flags);
}
}