58 lines
2.1 KiB
Diff
58 lines
2.1 KiB
Diff
|
# Commit 9eabb0735400e2b6059dfa3f0b47a426f61f570a
|
||
|
# Date 2013-07-02 08:50:41 +0200
|
||
|
# Author Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
|
||
|
# Committer Jan Beulich <jbeulich@suse.com>
|
||
|
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>
|
||
|
|
||
|
--- a/xen/drivers/passthrough/amd/iommu_init.c
|
||
|
+++ b/xen/drivers/passthrough/amd/iommu_init.c
|
||
|
@@ -636,6 +636,14 @@ static void iommu_check_event_log(struct
|
||
|
}
|
||
|
}
|
||
|
|
||
|
+ /*
|
||
|
+ * 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);
|
||
|
}
|
||
|
|
||
|
@@ -717,6 +725,14 @@ static void iommu_check_ppr_log(struct a
|
||
|
}
|
||
|
}
|
||
|
|
||
|
+ /*
|
||
|
+ * 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_PPR_LOG_INT_MASK )
|
||
|
+ tasklet_schedule(&amd_iommu_irq_tasklet);
|
||
|
+
|
||
|
spin_unlock_irqrestore(&iommu->lock, flags);
|
||
|
}
|
||
|
|