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>
This commit is contained in:
Родитель
cc1ad4a696
Коммит
32cfb1b16f
|
@ -12,6 +12,7 @@
|
||||||
#include <linux/linkage.h>
|
#include <linux/linkage.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <asm/assembler.h>
|
#include <asm/assembler.h>
|
||||||
|
#include <asm/unwind.h>
|
||||||
|
|
||||||
#include "proc-macros.S"
|
#include "proc-macros.S"
|
||||||
|
|
||||||
|
@ -121,11 +122,13 @@ ENTRY(v6_coherent_kern_range)
|
||||||
* - the Icache does not read data from the write buffer
|
* - the Icache does not read data from the write buffer
|
||||||
*/
|
*/
|
||||||
ENTRY(v6_coherent_user_range)
|
ENTRY(v6_coherent_user_range)
|
||||||
|
UNWIND(.fnstart )
|
||||||
#ifdef HARVARD_CACHE
|
#ifdef HARVARD_CACHE
|
||||||
bic r0, r0, #CACHE_LINE_SIZE - 1
|
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
|
add r0, r0, #CACHE_LINE_SIZE
|
||||||
|
2:
|
||||||
cmp r0, r1
|
cmp r0, r1
|
||||||
blo 1b
|
blo 1b
|
||||||
#endif
|
#endif
|
||||||
|
@ -142,6 +145,19 @@ ENTRY(v6_coherent_user_range)
|
||||||
#endif
|
#endif
|
||||||
mov pc, lr
|
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)
|
* v6_flush_kern_dcache_page(kaddr)
|
||||||
*
|
*
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <linux/linkage.h>
|
#include <linux/linkage.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <asm/assembler.h>
|
#include <asm/assembler.h>
|
||||||
|
#include <asm/unwind.h>
|
||||||
|
|
||||||
#include "proc-macros.S"
|
#include "proc-macros.S"
|
||||||
|
|
||||||
|
@ -153,13 +154,16 @@ ENTRY(v7_coherent_kern_range)
|
||||||
* - the Icache does not read data from the write buffer
|
* - the Icache does not read data from the write buffer
|
||||||
*/
|
*/
|
||||||
ENTRY(v7_coherent_user_range)
|
ENTRY(v7_coherent_user_range)
|
||||||
|
UNWIND(.fnstart )
|
||||||
dcache_line_size r2, r3
|
dcache_line_size r2, r3
|
||||||
sub r3, r2, #1
|
sub r3, r2, #1
|
||||||
bic r0, r0, r3
|
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
|
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
|
add r0, r0, r2
|
||||||
|
2:
|
||||||
cmp r0, r1
|
cmp r0, r1
|
||||||
blo 1b
|
blo 1b
|
||||||
mov r0, #0
|
mov r0, #0
|
||||||
|
@ -167,6 +171,17 @@ ENTRY(v7_coherent_user_range)
|
||||||
dsb
|
dsb
|
||||||
isb
|
isb
|
||||||
mov pc, lr
|
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_kern_range)
|
||||||
ENDPROC(v7_coherent_user_range)
|
ENDPROC(v7_coherent_user_range)
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче