]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 14 Dec 2013 00:25:43 +0000 (16:25 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 14 Dec 2013 00:25:43 +0000 (16:25 -0800)
added patches:
mips-dma-for-bmips5000-cores-flush-region-just-like-non-coherent-r10000.patch

queue-3.4/mips-dma-for-bmips5000-cores-flush-region-just-like-non-coherent-r10000.patch [new file with mode: 0644]
queue-3.4/series [new file with mode: 0644]

diff --git a/queue-3.4/mips-dma-for-bmips5000-cores-flush-region-just-like-non-coherent-r10000.patch b/queue-3.4/mips-dma-for-bmips5000-cores-flush-region-just-like-non-coherent-r10000.patch
new file mode 100644 (file)
index 0000000..e3bcf31
--- /dev/null
@@ -0,0 +1,86 @@
+From f86f55d3ad21b21b736bdeb29bee0f0937b77138 Mon Sep 17 00:00:00 2001
+From: Jim Quinlan <jim2101024@gmail.com>
+Date: Tue, 27 Aug 2013 16:57:51 -0400
+Subject: MIPS: DMA: For BMIPS5000 cores flush region just like non-coherent R10000
+
+From: Jim Quinlan <jim2101024@gmail.com>
+
+commit f86f55d3ad21b21b736bdeb29bee0f0937b77138 upstream.
+
+The BMIPS5000 (Zephyr) processor utilizes instruction speculation. A
+stale misprediction address in either the JTB or the CRS may trigger
+a prefetch inside a region that is currently being used by a DMA engine,
+which is not IO-coherent.  This prefetch will fetch a line into the
+scache, and that line will soon become stale (ie wrong) during/after the
+DMA.  Mayhem ensues.
+
+In dma-default.c, the r10000 is handled as a special case in the same way
+that we want to handle Zephyr.  So we generalize the exception cases into
+a function, and include Zephyr as one of the processors that needs this
+special care.
+
+Signed-off-by: Jim Quinlan <jim2101024@gmail.com>
+Cc: linux-mips@linux-mips.org
+Cc: cernekee@gmail.com
+Patchwork: https://patchwork.linux-mips.org/patch/5776/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Cc: John Ulvr <julvr@broadcom.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/mm/dma-default.c |   16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+--- a/arch/mips/mm/dma-default.c
++++ b/arch/mips/mm/dma-default.c
+@@ -30,16 +30,20 @@ static inline struct page *dma_addr_to_p
+ }
+ /*
++ * The affected CPUs below in 'cpu_needs_post_dma_flush()' can
++ * speculatively fill random cachelines with stale data at any time,
++ * requiring an extra flush post-DMA.
++ *
+  * Warning on the terminology - Linux calls an uncached area coherent;
+  * MIPS terminology calls memory areas with hardware maintained coherency
+  * coherent.
+  */
+-
+-static inline int cpu_is_noncoherent_r10000(struct device *dev)
++static inline int cpu_needs_post_dma_flush(struct device *dev)
+ {
+       return !plat_device_is_coherent(dev) &&
+              (current_cpu_type() == CPU_R10000 ||
+-             current_cpu_type() == CPU_R12000);
++              current_cpu_type() == CPU_R12000 ||
++              current_cpu_type() == CPU_BMIPS5000);
+ }
+ static gfp_t massage_gfp_flags(const struct device *dev, gfp_t gfp)
+@@ -209,7 +213,7 @@ static inline void __dma_sync(struct pag
+ static void mips_dma_unmap_page(struct device *dev, dma_addr_t dma_addr,
+       size_t size, enum dma_data_direction direction, struct dma_attrs *attrs)
+ {
+-      if (cpu_is_noncoherent_r10000(dev))
++      if (cpu_needs_post_dma_flush(dev))
+               __dma_sync(dma_addr_to_page(dev, dma_addr),
+                          dma_addr & ~PAGE_MASK, size, direction);
+@@ -260,7 +264,7 @@ static void mips_dma_unmap_sg(struct dev
+ static void mips_dma_sync_single_for_cpu(struct device *dev,
+       dma_addr_t dma_handle, size_t size, enum dma_data_direction direction)
+ {
+-      if (cpu_is_noncoherent_r10000(dev))
++      if (cpu_needs_post_dma_flush(dev))
+               __dma_sync(dma_addr_to_page(dev, dma_handle),
+                          dma_handle & ~PAGE_MASK, size, direction);
+ }
+@@ -281,7 +285,7 @@ static void mips_dma_sync_sg_for_cpu(str
+       /* Make sure that gcc doesn't leave the empty loop body.  */
+       for (i = 0; i < nelems; i++, sg++) {
+-              if (cpu_is_noncoherent_r10000(dev))
++              if (cpu_needs_post_dma_flush(dev))
+                       __dma_sync(sg_page(sg), sg->offset, sg->length,
+                                  direction);
+       }
diff --git a/queue-3.4/series b/queue-3.4/series
new file mode 100644 (file)
index 0000000..9248ef3
--- /dev/null
@@ -0,0 +1 @@
+mips-dma-for-bmips5000-cores-flush-region-just-like-non-coherent-r10000.patch