ARM: 5746/1: Handle possible translation errors in ARMv6/v7 coherent_user_range
authorCatalin Marinas <catalin.marinas@arm.com>
Tue, 6 Oct 2009 16:57:09 +0000 (17:57 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Wed, 7 Oct 2009 12:12:59 +0000 (13:12 +0100)
This is needed because applications using the sys_cacheflush system call
can pass a memory range which isn't mapped yet even though the
corresponding vma is valid. The patch also adds unwinding annotations
for correct backtraces from the coherent_user_range() functions.

Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
arch/arm/mm/cache-v6.S
arch/arm/mm/cache-v7.S

index 8f5c13f4c93614abbcc37315b8c7a3fbb987d38b..295e25dd6381f69da0eaf59c8e9da1854434ddd8 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 #include <asm/assembler.h>
+#include <asm/unwind.h>
 
 #include "proc-macros.S"
 
@@ -121,11 +122,13 @@ ENTRY(v6_coherent_kern_range)
  *     - the Icache does not read data from the write buffer
  */
 ENTRY(v6_coherent_user_range)
-
+ UNWIND(.fnstart               )
 #ifdef HARVARD_CACHE
        bic     r0, r0, #CACHE_LINE_SIZE - 1
-1:     mcr     p15, 0, r0, c7, c10, 1          @ clean D line
+1:
+ USER( mcr     p15, 0, r0, c7, c10, 1  )       @ clean D line
        add     r0, r0, #CACHE_LINE_SIZE
+2:
        cmp     r0, r1
        blo     1b
 #endif
@@ -142,6 +145,19 @@ ENTRY(v6_coherent_user_range)
 #endif
        mov     pc, lr
 
+/*
+ * Fault handling for the cache operation above. If the virtual address in r0
+ * isn't mapped, just try the next page.
+ */
+9001:
+       mov     r0, r0, lsr #12
+       mov     r0, r0, lsl #12
+       add     r0, r0, #4096
+       b       2b
+ UNWIND(.fnend         )
+ENDPROC(v6_coherent_user_range)
+ENDPROC(v6_coherent_kern_range)
+
 /*
  *     v6_flush_kern_dcache_page(kaddr)
  *
index bda0ec31a4e2c9d2f06e856396a65d09082ad9d0..e1bd9759617f16cce4d8b59c738e340afa22b2e2 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 #include <asm/assembler.h>
+#include <asm/unwind.h>
 
 #include "proc-macros.S"
 
@@ -153,13 +154,16 @@ ENTRY(v7_coherent_kern_range)
  *     - the Icache does not read data from the write buffer
  */
 ENTRY(v7_coherent_user_range)
+ UNWIND(.fnstart               )
        dcache_line_size r2, r3
        sub     r3, r2, #1
        bic     r0, r0, r3
-1:     mcr     p15, 0, r0, c7, c11, 1          @ clean D line to the point of unification
+1:
+ USER( mcr     p15, 0, r0, c7, c11, 1  )       @ clean D line to the point of unification
        dsb
      mcr     p15, 0, r0, c7, c5, 1           @ invalidate I line
USER( mcr     p15, 0, r0, c7, c5, 1   )       @ invalidate I line
        add     r0, r0, r2
+2:
        cmp     r0, r1
        blo     1b
        mov     r0, #0
@@ -167,6 +171,17 @@ ENTRY(v7_coherent_user_range)
        dsb
        isb
        mov     pc, lr
+
+/*
+ * Fault handling for the cache operation above. If the virtual address in r0
+ * isn't mapped, just try the next page.
+ */
+9001:
+       mov     r0, r0, lsr #12
+       mov     r0, r0, lsl #12
+       add     r0, r0, #4096
+       b       2b
+ UNWIND(.fnend         )
 ENDPROC(v7_coherent_kern_range)
 ENDPROC(v7_coherent_user_range)