ARM: dma-mapping: avoid speculative prefetching fix
[pandora-kernel.git] / arch / arm / mm / cache-v7.S
index 07c4bc8..3953920 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 #include <asm/assembler.h>
+#include <asm/errno.h>
 #include <asm/unwind.h>
 
 #include "proc-macros.S"
@@ -54,9 +55,15 @@ loop1:
        and     r1, r1, #7                      @ mask of the bits for current cache only
        cmp     r1, #2                          @ see what cache we have at this level
        blt     skip                            @ skip if no cache, or just i-cache
+#ifdef CONFIG_PREEMPT
+       save_and_disable_irqs_notrace r9        @ make cssr&csidr read atomic
+#endif
        mcr     p15, 2, r10, c0, c0, 0          @ select current cache level in cssr
        isb                                     @ isb to sych the new cssr&csidr
        mrc     p15, 1, r1, c0, c0, 0           @ read the new csidr
+#ifdef CONFIG_PREEMPT
+       restore_irqs_notrace r9
+#endif
        and     r2, r1, #7                      @ extract the length of the cache lines
        add     r2, r2, #4                      @ add 4 (line length offset)
        ldr     r4, =0x3ff
@@ -192,7 +199,6 @@ ENTRY(v7_coherent_user_range)
        add     r12, r12, r2
        cmp     r12, r1
        blo     2b
-3:
        mov     r0, #0
        ALT_SMP(mcr     p15, 0, r0, c7, c1, 6)  @ invalidate BTB Inner Shareable
        ALT_UP(mcr      p15, 0, r0, c7, c5, 6)  @ invalidate BTB
@@ -202,13 +208,11 @@ ENTRY(v7_coherent_user_range)
 
 /*
  * Fault handling for the cache operation above. If the virtual address in r0
- * isn't mapped, just try the next page.
+ * isn't mapped, fail with -EFAULT.
  */
 9001:
-       mov     r12, r12, lsr #12
-       mov     r12, r12, lsl #12
-       add     r12, r12, #4096
-       b       3b
+       mov     r0, #-EFAULT
+       mov     pc, lr
  UNWIND(.fnend         )
 ENDPROC(v7_coherent_kern_range)
 ENDPROC(v7_coherent_user_range)
@@ -325,9 +329,10 @@ ENDPROC(v7_dma_flush_range)
  */
 ENTRY(v7_dma_map_area)
        add     r1, r1, r0
-       teq     r2, #DMA_FROM_DEVICE
-       beq     v7_dma_inv_range
-       b       v7_dma_clean_range
+       cmp     r2, #DMA_TO_DEVICE
+       beq     v7_dma_clean_range
+       bcs     v7_dma_inv_range
+       b       v7_dma_flush_range
 ENDPROC(v7_dma_map_area)
 
 /*
@@ -337,9 +342,6 @@ ENDPROC(v7_dma_map_area)
  *     - dir   - DMA direction
  */
 ENTRY(v7_dma_unmap_area)
-       add     r1, r1, r0
-       teq     r2, #DMA_TO_DEVICE
-       bne     v7_dma_inv_range
        mov     pc, lr
 ENDPROC(v7_dma_unmap_area)