aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2006-09-13 22:12:52 +1000
committerPaul Mackerras <paulus@samba.org>2006-09-13 22:12:52 +1000
commiteeac5c142b8687e35780b11b54b4c2f95b1a2436 (patch)
treec0df8f3f5b154d41a63bff1a4e49f2bf5172b079
parent[POWERPC] Fix MMIO ops to provide expected barrier behaviour (diff)
downloadlinux-dev-eeac5c142b8687e35780b11b54b4c2f95b1a2436.tar.xz
linux-dev-eeac5c142b8687e35780b11b54b4c2f95b1a2436.zip
[POWERPC] Fix G5 DART (IOMMU) race causing occasional data corruption
It seems that the occasional data corruption observed with the tg3 driver wasn't due to missing barriers after all, but rather seems to be due to the DART (= IOMMU) in the U4 northbridge reading stale IOMMU table entries from memory due to a race. This fixes it by making the CPU read the entry back from memory before using it. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r--arch/powerpc/sysdev/dart_iommu.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c
index e32fadde1f77..03b4477dd7f0 100644
--- a/arch/powerpc/sysdev/dart_iommu.c
+++ b/arch/powerpc/sysdev/dart_iommu.c
@@ -139,6 +139,7 @@ wait_more:
static void dart_flush(struct iommu_table *tbl)
{
+ mb();
if (dart_dirty) {
dart_tlb_invalidate_all();
dart_dirty = 0;
@@ -172,9 +173,13 @@ static void dart_build(struct iommu_table *tbl, long index,
uaddr += DART_PAGE_SIZE;
}
+ /* make sure all updates have reached memory */
+ mb();
+ in_be32((unsigned __iomem *)dp);
+ mb();
+
if (dart_is_u4) {
rpn = index;
- mb(); /* make sure all updates have reached memory */
while (npages--)
dart_tlb_invalidate_one(rpn++);
} else {