diff options
author | Catalin Marinas <catalin.marinas@arm.com> | 2009-10-06 17:57:09 +0100 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-10-07 13:12:59 +0100 |
commit | 32cfb1b16f2b68d2296536811cadfffe26a06c1b (patch) | |
tree | 6872f034656cc4ffb80ba51f9b29c35bb8da9f9e /arch/arm/mm/cache-v7.S | |
parent | cc1ad4a69667be885ac6036a315066854ef8c871 (diff) | |
download | op-kernel-dev-32cfb1b16f2b68d2296536811cadfffe26a06c1b.zip op-kernel-dev-32cfb1b16f2b68d2296536811cadfffe26a06c1b.tar.gz |
ARM: 5746/1: Handle possible translation errors in ARMv6/v7 coherent_user_range
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>
Diffstat (limited to 'arch/arm/mm/cache-v7.S')
-rw-r--r-- | arch/arm/mm/cache-v7.S | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S index bda0ec3..e1bd975 100644 --- a/arch/arm/mm/cache-v7.S +++ b/arch/arm/mm/cache-v7.S @@ -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) |