diff options
author | Catalin Marinas <catalin.marinas@arm.com> | 2009-10-06 20:57:09 +0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-10-07 16:12:59 +0400 |
commit | 32cfb1b16f2b68d2296536811cadfffe26a06c1b (patch) | |
tree | 6872f034656cc4ffb80ba51f9b29c35bb8da9f9e /arch/arm/mm/cache-v6.S | |
parent | cc1ad4a69667be885ac6036a315066854ef8c871 (diff) | |
download | linux-32cfb1b16f2b68d2296536811cadfffe26a06c1b.tar.xz |
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-v6.S')
-rw-r--r-- | arch/arm/mm/cache-v6.S | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/arch/arm/mm/cache-v6.S b/arch/arm/mm/cache-v6.S index 8f5c13f4c936..295e25dd6381 100644 --- a/arch/arm/mm/cache-v6.S +++ b/arch/arm/mm/cache-v6.S @@ -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 @@ -143,6 +146,19 @@ ENTRY(v6_coherent_user_range) 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) * * Ensure that the data held in the page kaddr is written back |