diff options
author | Alexey Kardashevskiy <aik@ozlabs.ru> | 2016-02-17 18:26:31 +1100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-02-25 12:01:19 -0800 |
commit | 602acfedc981eb887289f11f1a7565e6f48c710d (patch) | |
tree | 3cb29f002adab15813f4ba82f14e7300de79e782 | |
parent | b5311270caba5392a83ed918e11a16e71b3b1e44 (diff) | |
download | linux-stable-602acfedc981eb887289f11f1a7565e6f48c710d.tar.gz linux-stable-602acfedc981eb887289f11f1a7565e6f48c710d.tar.bz2 linux-stable-602acfedc981eb887289f11f1a7565e6f48c710d.zip |
powerpc/ioda: Set "read" permission when "write" is set
commit 6ecad912a0073c768db1491c27ca55ad2d0ee68f upstream.
Quite often drivers set only "write" permission assuming that this
includes "read" permission as well and this works on plenty of
platforms. However IODA2 is strict about this and produces an EEH when
"read" permission is not set and reading happens.
This adds a workaround in the IODA code to always add the "read" bit
when the "write" bit is set.
Fixes: 10b35b2b7485 ("powerpc/powernv: Do not set "read" flag if direction==DMA_NONE")
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Tested-by: Douglas Miller <dougmill@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | arch/powerpc/platforms/powernv/pci.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index c97c76f9ad84..ad8c3f4a5e0b 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c @@ -601,6 +601,9 @@ int pnv_tce_build(struct iommu_table *tbl, long index, long npages, u64 rpn = __pa(uaddr) >> tbl->it_page_shift; long i; + if (proto_tce & TCE_PCI_WRITE) + proto_tce |= TCE_PCI_READ; + for (i = 0; i < npages; i++) { unsigned long newtce = proto_tce | ((rpn + i) << tbl->it_page_shift); @@ -622,6 +625,9 @@ int pnv_tce_xchg(struct iommu_table *tbl, long index, BUG_ON(*hpa & ~IOMMU_PAGE_MASK(tbl)); + if (newtce & TCE_PCI_WRITE) + newtce |= TCE_PCI_READ; + oldtce = xchg(pnv_tce(tbl, idx), cpu_to_be64(newtce)); *hpa = be64_to_cpu(oldtce) & ~(TCE_PCI_READ | TCE_PCI_WRITE); *direction = iommu_tce_direction(oldtce); |