diff options
author | Catalin Marinas <catalin.marinas@arm.com> | 2010-09-13 11:03:21 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-11-04 11:44:31 -0400 |
commit | 247055aa21ffef1c49dd64710d5e94c2aee19b58 (patch) | |
tree | e9e026b96597d080de4c16bb88c17b0495c61904 /arch/arm | |
parent | ff8b16d7e15a8ba2a6086645614a483e048e3fbf (diff) |
ARM: 6384/1: Remove the domain switching on ARMv6k/v7 CPUs
This patch removes the domain switching functionality via the set_fs and
__switch_to functions on cores that have a TLS register.
Currently, the ioremap and vmalloc areas share the same level 1 page
tables and therefore have the same domain (DOMAIN_KERNEL). When the
kernel domain is modified from Client to Manager (via the __set_fs or in
the __switch_to function), the XN (eXecute Never) bit is overridden and
newer CPUs can speculatively prefetch the ioremap'ed memory.
Linux performs the kernel domain switching to allow user-specific
functions (copy_to/from_user, get/put_user etc.) to access kernel
memory. In order for these functions to work with the kernel domain set
to Client, the patch modifies the LDRT/STRT and related instructions to
the LDR/STR ones.
The user pages access rights are also modified for kernel read-only
access rather than read/write so that the copy-on-write mechanism still
works. CPU_USE_DOMAINS gets disabled only if the hardware has a TLS register
(CPU_32v6K is defined) since writing the TLS value to the high vectors page
isn't possible.
The user addresses passed to the kernel are checked by the access_ok()
function so that they do not point to the kernel space.
Tested-by: Anton Vorontsov <cbouatmailru@gmail.com>
Cc: Tony Lindgren <tony@atomide.com>
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')
-rw-r--r-- | arch/arm/include/asm/assembler.h | 13 | ||||
-rw-r--r-- | arch/arm/include/asm/domain.h | 31 | ||||
-rw-r--r-- | arch/arm/include/asm/futex.h | 9 | ||||
-rw-r--r-- | arch/arm/include/asm/traps.h | 2 | ||||
-rw-r--r-- | arch/arm/include/asm/uaccess.h | 16 | ||||
-rw-r--r-- | arch/arm/kernel/entry-armv.S | 4 | ||||
-rw-r--r-- | arch/arm/kernel/fiq.c | 5 | ||||
-rw-r--r-- | arch/arm/kernel/traps.c | 14 | ||||
-rw-r--r-- | arch/arm/lib/getuser.S | 13 | ||||
-rw-r--r-- | arch/arm/lib/putuser.S | 29 | ||||
-rw-r--r-- | arch/arm/lib/uaccess.S | 83 | ||||
-rw-r--r-- | arch/arm/mm/Kconfig | 8 | ||||
-rw-r--r-- | arch/arm/mm/mmu.c | 6 | ||||
-rw-r--r-- | arch/arm/mm/proc-macros.S | 7 | ||||
-rw-r--r-- | arch/arm/mm/proc-v7.S | 5 |
15 files changed, 153 insertions, 92 deletions
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h index 062b58c029ab..4e84d09c9c1b 100644 --- a/arch/arm/include/asm/assembler.h +++ b/arch/arm/include/asm/assembler.h | |||
@@ -18,6 +18,7 @@ | |||
18 | #endif | 18 | #endif |
19 | 19 | ||
20 | #include <asm/ptrace.h> | 20 | #include <asm/ptrace.h> |
21 | #include <asm/domain.h> | ||
21 | 22 | ||
22 | /* | 23 | /* |
23 | * Endian independent macros for shifting bytes within registers. | 24 | * Endian independent macros for shifting bytes within registers. |
@@ -206,12 +207,12 @@ | |||
206 | */ | 207 | */ |
207 | #ifdef CONFIG_THUMB2_KERNEL | 208 | #ifdef CONFIG_THUMB2_KERNEL |
208 | 209 | ||
209 | .macro usraccoff, instr, reg, ptr, inc, off, cond, abort | 210 | .macro usraccoff, instr, reg, ptr, inc, off, cond, abort, t=T() |
210 | 9999: | 211 | 9999: |
211 | .if \inc == 1 | 212 | .if \inc == 1 |
212 | \instr\cond\()bt \reg, [\ptr, #\off] | 213 | \instr\cond\()b\()\t\().w \reg, [\ptr, #\off] |
213 | .elseif \inc == 4 | 214 | .elseif \inc == 4 |
214 | \instr\cond\()t \reg, [\ptr, #\off] | 215 | \instr\cond\()\t\().w \reg, [\ptr, #\off] |
215 | .else | 216 | .else |
216 | .error "Unsupported inc macro argument" | 217 | .error "Unsupported inc macro argument" |
217 | .endif | 218 | .endif |
@@ -246,13 +247,13 @@ | |||
246 | 247 | ||
247 | #else /* !CONFIG_THUMB2_KERNEL */ | 248 | #else /* !CONFIG_THUMB2_KERNEL */ |
248 | 249 | ||
249 | .macro usracc, instr, reg, ptr, inc, cond, rept, abort | 250 | .macro usracc, instr, reg, ptr, inc, cond, rept, abort, t=T() |
250 | .rept \rept | 251 | .rept \rept |
251 | 9999: | 252 | 9999: |
252 | .if \inc == 1 | 253 | .if \inc == 1 |
253 | \instr\cond\()bt \reg, [\ptr], #\inc | 254 | \instr\cond\()b\()\t \reg, [\ptr], #\inc |
254 | .elseif \inc == 4 | 255 | .elseif \inc == 4 |
255 | \instr\cond\()t \reg, [\ptr], #\inc | 256 | \instr\cond\()\t \reg, [\ptr], #\inc |
256 | .else | 257 | .else |
257 | .error "Unsupported inc macro argument" | 258 | .error "Unsupported inc macro argument" |
258 | .endif | 259 | .endif |
diff --git a/arch/arm/include/asm/domain.h b/arch/arm/include/asm/domain.h index cc7ef4080711..af18ceaacf5d 100644 --- a/arch/arm/include/asm/domain.h +++ b/arch/arm/include/asm/domain.h | |||
@@ -45,13 +45,17 @@ | |||
45 | */ | 45 | */ |
46 | #define DOMAIN_NOACCESS 0 | 46 | #define DOMAIN_NOACCESS 0 |
47 | #define DOMAIN_CLIENT 1 | 47 | #define DOMAIN_CLIENT 1 |
48 | #ifdef CONFIG_CPU_USE_DOMAINS | ||
48 | #define DOMAIN_MANAGER 3 | 49 | #define DOMAIN_MANAGER 3 |
50 | #else | ||
51 | #define DOMAIN_MANAGER 1 | ||
52 | #endif | ||
49 | 53 | ||
50 | #define domain_val(dom,type) ((type) << (2*(dom))) | 54 | #define domain_val(dom,type) ((type) << (2*(dom))) |
51 | 55 | ||
52 | #ifndef __ASSEMBLY__ | 56 | #ifndef __ASSEMBLY__ |
53 | 57 | ||
54 | #ifdef CONFIG_MMU | 58 | #ifdef CONFIG_CPU_USE_DOMAINS |
55 | #define set_domain(x) \ | 59 | #define set_domain(x) \ |
56 | do { \ | 60 | do { \ |
57 | __asm__ __volatile__( \ | 61 | __asm__ __volatile__( \ |
@@ -74,5 +78,28 @@ | |||
74 | #define modify_domain(dom,type) do { } while (0) | 78 | #define modify_domain(dom,type) do { } while (0) |
75 | #endif | 79 | #endif |
76 | 80 | ||
81 | /* | ||
82 | * Generate the T (user) versions of the LDR/STR and related | ||
83 | * instructions (inline assembly) | ||
84 | */ | ||
85 | #ifdef CONFIG_CPU_USE_DOMAINS | ||
86 | #define T(instr) #instr "t" | ||
87 | #else | ||
88 | #define T(instr) #instr | ||
77 | #endif | 89 | #endif |
78 | #endif /* !__ASSEMBLY__ */ | 90 | |
91 | #else /* __ASSEMBLY__ */ | ||
92 | |||
93 | /* | ||
94 | * Generate the T (user) versions of the LDR/STR and related | ||
95 | * instructions | ||
96 | */ | ||
97 | #ifdef CONFIG_CPU_USE_DOMAINS | ||
98 | #define T(instr) instr ## t | ||
99 | #else | ||
100 | #define T(instr) instr | ||
101 | #endif | ||
102 | |||
103 | #endif /* __ASSEMBLY__ */ | ||
104 | |||
105 | #endif /* !__ASM_PROC_DOMAIN_H */ | ||
diff --git a/arch/arm/include/asm/futex.h b/arch/arm/include/asm/futex.h index 540a044153a5..b33fe7065b38 100644 --- a/arch/arm/include/asm/futex.h +++ b/arch/arm/include/asm/futex.h | |||
@@ -13,12 +13,13 @@ | |||
13 | #include <linux/preempt.h> | 13 | #include <linux/preempt.h> |
14 | #include <linux/uaccess.h> | 14 | #include <linux/uaccess.h> |
15 | #include <asm/errno.h> | 15 | #include <asm/errno.h> |
16 | #include <asm/domain.h> | ||
16 | 17 | ||
17 | #define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \ | 18 | #define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \ |
18 | __asm__ __volatile__( \ | 19 | __asm__ __volatile__( \ |
19 | "1: ldrt %1, [%2]\n" \ | 20 | "1: " T(ldr) " %1, [%2]\n" \ |
20 | " " insn "\n" \ | 21 | " " insn "\n" \ |
21 | "2: strt %0, [%2]\n" \ | 22 | "2: " T(str) " %0, [%2]\n" \ |
22 | " mov %0, #0\n" \ | 23 | " mov %0, #0\n" \ |
23 | "3:\n" \ | 24 | "3:\n" \ |
24 | " .pushsection __ex_table,\"a\"\n" \ | 25 | " .pushsection __ex_table,\"a\"\n" \ |
@@ -97,10 +98,10 @@ futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval) | |||
97 | pagefault_disable(); /* implies preempt_disable() */ | 98 | pagefault_disable(); /* implies preempt_disable() */ |
98 | 99 | ||
99 | __asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n" | 100 | __asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n" |
100 | "1: ldrt %0, [%3]\n" | 101 | "1: " T(ldr) " %0, [%3]\n" |
101 | " teq %0, %1\n" | 102 | " teq %0, %1\n" |
102 | " it eq @ explicit IT needed for the 2b label\n" | 103 | " it eq @ explicit IT needed for the 2b label\n" |
103 | "2: streqt %2, [%3]\n" | 104 | "2: " T(streq) " %2, [%3]\n" |
104 | "3:\n" | 105 | "3:\n" |
105 | " .pushsection __ex_table,\"a\"\n" | 106 | " .pushsection __ex_table,\"a\"\n" |
106 | " .align 3\n" | 107 | " .align 3\n" |
diff --git a/arch/arm/include/asm/traps.h b/arch/arm/include/asm/traps.h index 491960bf4260..af5d5d1388c6 100644 --- a/arch/arm/include/asm/traps.h +++ b/arch/arm/include/asm/traps.h | |||
@@ -27,4 +27,6 @@ static inline int in_exception_text(unsigned long ptr) | |||
27 | extern void __init early_trap_init(void); | 27 | extern void __init early_trap_init(void); |
28 | extern void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame); | 28 | extern void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame); |
29 | 29 | ||
30 | extern void *vectors_page; | ||
31 | |||
30 | #endif | 32 | #endif |
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h index 33e4a48fe103..b293616a1a1a 100644 --- a/arch/arm/include/asm/uaccess.h +++ b/arch/arm/include/asm/uaccess.h | |||
@@ -227,7 +227,7 @@ do { \ | |||
227 | 227 | ||
228 | #define __get_user_asm_byte(x,addr,err) \ | 228 | #define __get_user_asm_byte(x,addr,err) \ |
229 | __asm__ __volatile__( \ | 229 | __asm__ __volatile__( \ |
230 | "1: ldrbt %1,[%2]\n" \ | 230 | "1: " T(ldrb) " %1,[%2],#0\n" \ |
231 | "2:\n" \ | 231 | "2:\n" \ |
232 | " .pushsection .fixup,\"ax\"\n" \ | 232 | " .pushsection .fixup,\"ax\"\n" \ |
233 | " .align 2\n" \ | 233 | " .align 2\n" \ |
@@ -263,7 +263,7 @@ do { \ | |||
263 | 263 | ||
264 | #define __get_user_asm_word(x,addr,err) \ | 264 | #define __get_user_asm_word(x,addr,err) \ |
265 | __asm__ __volatile__( \ | 265 | __asm__ __volatile__( \ |
266 | "1: ldrt %1,[%2]\n" \ | 266 | "1: " T(ldr) " %1,[%2],#0\n" \ |
267 | "2:\n" \ | 267 | "2:\n" \ |
268 | " .pushsection .fixup,\"ax\"\n" \ | 268 | " .pushsection .fixup,\"ax\"\n" \ |
269 | " .align 2\n" \ | 269 | " .align 2\n" \ |
@@ -308,7 +308,7 @@ do { \ | |||
308 | 308 | ||
309 | #define __put_user_asm_byte(x,__pu_addr,err) \ | 309 | #define __put_user_asm_byte(x,__pu_addr,err) \ |
310 | __asm__ __volatile__( \ | 310 | __asm__ __volatile__( \ |
311 | "1: strbt %1,[%2]\n" \ | 311 | "1: " T(strb) " %1,[%2],#0\n" \ |
312 | "2:\n" \ | 312 | "2:\n" \ |
313 | " .pushsection .fixup,\"ax\"\n" \ | 313 | " .pushsection .fixup,\"ax\"\n" \ |
314 | " .align 2\n" \ | 314 | " .align 2\n" \ |
@@ -341,7 +341,7 @@ do { \ | |||
341 | 341 | ||
342 | #define __put_user_asm_word(x,__pu_addr,err) \ | 342 | #define __put_user_asm_word(x,__pu_addr,err) \ |
343 | __asm__ __volatile__( \ | 343 | __asm__ __volatile__( \ |
344 | "1: strt %1,[%2]\n" \ | 344 | "1: " T(str) " %1,[%2],#0\n" \ |
345 | "2:\n" \ | 345 | "2:\n" \ |
346 | " .pushsection .fixup,\"ax\"\n" \ | 346 | " .pushsection .fixup,\"ax\"\n" \ |
347 | " .align 2\n" \ | 347 | " .align 2\n" \ |
@@ -366,10 +366,10 @@ do { \ | |||
366 | 366 | ||
367 | #define __put_user_asm_dword(x,__pu_addr,err) \ | 367 | #define __put_user_asm_dword(x,__pu_addr,err) \ |
368 | __asm__ __volatile__( \ | 368 | __asm__ __volatile__( \ |
369 | ARM( "1: strt " __reg_oper1 ", [%1], #4\n" ) \ | 369 | ARM( "1: " T(str) " " __reg_oper1 ", [%1], #4\n" ) \ |
370 | ARM( "2: strt " __reg_oper0 ", [%1]\n" ) \ | 370 | ARM( "2: " T(str) " " __reg_oper0 ", [%1]\n" ) \ |
371 | THUMB( "1: strt " __reg_oper1 ", [%1]\n" ) \ | 371 | THUMB( "1: " T(str) " " __reg_oper1 ", [%1]\n" ) \ |
372 | THUMB( "2: strt " __reg_oper0 ", [%1, #4]\n" ) \ | 372 | THUMB( "2: " T(str) " " __reg_oper0 ", [%1, #4]\n" ) \ |
373 | "3:\n" \ | 373 | "3:\n" \ |
374 | " .pushsection .fixup,\"ax\"\n" \ | 374 | " .pushsection .fixup,\"ax\"\n" \ |
375 | " .align 2\n" \ | 375 | " .align 2\n" \ |
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index c09e3573c5de..35f3f20d6731 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S | |||
@@ -735,7 +735,7 @@ ENTRY(__switch_to) | |||
735 | THUMB( stmia ip!, {r4 - sl, fp} ) @ Store most regs on stack | 735 | THUMB( stmia ip!, {r4 - sl, fp} ) @ Store most regs on stack |
736 | THUMB( str sp, [ip], #4 ) | 736 | THUMB( str sp, [ip], #4 ) |
737 | THUMB( str lr, [ip], #4 ) | 737 | THUMB( str lr, [ip], #4 ) |
738 | #ifdef CONFIG_MMU | 738 | #ifdef CONFIG_CPU_USE_DOMAINS |
739 | ldr r6, [r2, #TI_CPU_DOMAIN] | 739 | ldr r6, [r2, #TI_CPU_DOMAIN] |
740 | #endif | 740 | #endif |
741 | set_tls r3, r4, r5 | 741 | set_tls r3, r4, r5 |
@@ -744,7 +744,7 @@ ENTRY(__switch_to) | |||
744 | ldr r8, =__stack_chk_guard | 744 | ldr r8, =__stack_chk_guard |
745 | ldr r7, [r7, #TSK_STACK_CANARY] | 745 | ldr r7, [r7, #TSK_STACK_CANARY] |
746 | #endif | 746 | #endif |
747 | #ifdef CONFIG_MMU | 747 | #ifdef CONFIG_CPU_USE_DOMAINS |
748 | mcr p15, 0, r6, c3, c0, 0 @ Set domain register | 748 | mcr p15, 0, r6, c3, c0, 0 @ Set domain register |
749 | #endif | 749 | #endif |
750 | mov r5, r0 | 750 | mov r5, r0 |
diff --git a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c index 6ff7919613d7..d601ef297eb6 100644 --- a/arch/arm/kernel/fiq.c +++ b/arch/arm/kernel/fiq.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include <asm/fiq.h> | 45 | #include <asm/fiq.h> |
46 | #include <asm/irq.h> | 46 | #include <asm/irq.h> |
47 | #include <asm/system.h> | 47 | #include <asm/system.h> |
48 | #include <asm/traps.h> | ||
48 | 49 | ||
49 | static unsigned long no_fiq_insn; | 50 | static unsigned long no_fiq_insn; |
50 | 51 | ||
@@ -77,7 +78,11 @@ int show_fiq_list(struct seq_file *p, void *v) | |||
77 | 78 | ||
78 | void set_fiq_handler(void *start, unsigned int length) | 79 | void set_fiq_handler(void *start, unsigned int length) |
79 | { | 80 | { |
81 | #if defined(CONFIG_CPU_USE_DOMAINS) | ||
80 | memcpy((void *)0xffff001c, start, length); | 82 | memcpy((void *)0xffff001c, start, length); |
83 | #else | ||
84 | memcpy(vectors_page + 0x1c, start, length); | ||
85 | #endif | ||
81 | flush_icache_range(0xffff001c, 0xffff001c + length); | 86 | flush_icache_range(0xffff001c, 0xffff001c + length); |
82 | if (!vectors_high()) | 87 | if (!vectors_high()) |
83 | flush_icache_range(0x1c, 0x1c + length); | 88 | flush_icache_range(0x1c, 0x1c + length); |
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index cda78d59aa31..87abca018054 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c | |||
@@ -37,6 +37,8 @@ | |||
37 | 37 | ||
38 | static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" }; | 38 | static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" }; |
39 | 39 | ||
40 | void *vectors_page; | ||
41 | |||
40 | #ifdef CONFIG_DEBUG_USER | 42 | #ifdef CONFIG_DEBUG_USER |
41 | unsigned int user_debug; | 43 | unsigned int user_debug; |
42 | 44 | ||
@@ -759,7 +761,11 @@ static void __init kuser_get_tls_init(unsigned long vectors) | |||
759 | 761 | ||
760 | void __init early_trap_init(void) | 762 | void __init early_trap_init(void) |
761 | { | 763 | { |
764 | #if defined(CONFIG_CPU_USE_DOMAINS) | ||
762 | unsigned long vectors = CONFIG_VECTORS_BASE; | 765 | unsigned long vectors = CONFIG_VECTORS_BASE; |
766 | #else | ||
767 | unsigned long vectors = (unsigned long)vectors_page; | ||
768 | #endif | ||
763 | extern char __stubs_start[], __stubs_end[]; | 769 | extern char __stubs_start[], __stubs_end[]; |
764 | extern char __vectors_start[], __vectors_end[]; | 770 | extern char __vectors_start[], __vectors_end[]; |
765 | extern char __kuser_helper_start[], __kuser_helper_end[]; | 771 | extern char __kuser_helper_start[], __kuser_helper_end[]; |
@@ -783,10 +789,10 @@ void __init early_trap_init(void) | |||
783 | * Copy signal return handlers into the vector page, and | 789 | * Copy signal return handlers into the vector page, and |
784 | * set sigreturn to be a pointer to these. | 790 | * set sigreturn to be a pointer to these. |
785 | */ | 791 | */ |
786 | memcpy((void *)KERN_SIGRETURN_CODE, sigreturn_codes, | 792 | memcpy((void *)(vectors + KERN_SIGRETURN_CODE - CONFIG_VECTORS_BASE), |
787 | sizeof(sigreturn_codes)); | 793 | sigreturn_codes, sizeof(sigreturn_codes)); |
788 | memcpy((void *)KERN_RESTART_CODE, syscall_restart_code, | 794 | memcpy((void *)(vectors + KERN_RESTART_CODE - CONFIG_VECTORS_BASE), |
789 | sizeof(syscall_restart_code)); | 795 | syscall_restart_code, sizeof(syscall_restart_code)); |
790 | 796 | ||
791 | flush_icache_range(vectors, vectors + PAGE_SIZE); | 797 | flush_icache_range(vectors, vectors + PAGE_SIZE); |
792 | modify_domain(DOMAIN_USER, DOMAIN_CLIENT); | 798 | modify_domain(DOMAIN_USER, DOMAIN_CLIENT); |
diff --git a/arch/arm/lib/getuser.S b/arch/arm/lib/getuser.S index b1631a7dbe75..1b049cd7a49a 100644 --- a/arch/arm/lib/getuser.S +++ b/arch/arm/lib/getuser.S | |||
@@ -28,20 +28,21 @@ | |||
28 | */ | 28 | */ |
29 | #include <linux/linkage.h> | 29 | #include <linux/linkage.h> |
30 | #include <asm/errno.h> | 30 | #include <asm/errno.h> |
31 | #include <asm/domain.h> | ||
31 | 32 | ||
32 | ENTRY(__get_user_1) | 33 | ENTRY(__get_user_1) |
33 | 1: ldrbt r2, [r0] | 34 | 1: T(ldrb) r2, [r0] |
34 | mov r0, #0 | 35 | mov r0, #0 |
35 | mov pc, lr | 36 | mov pc, lr |
36 | ENDPROC(__get_user_1) | 37 | ENDPROC(__get_user_1) |
37 | 38 | ||
38 | ENTRY(__get_user_2) | 39 | ENTRY(__get_user_2) |
39 | #ifdef CONFIG_THUMB2_KERNEL | 40 | #ifdef CONFIG_THUMB2_KERNEL |
40 | 2: ldrbt r2, [r0] | 41 | 2: T(ldrb) r2, [r0] |
41 | 3: ldrbt r3, [r0, #1] | 42 | 3: T(ldrb) r3, [r0, #1] |
42 | #else | 43 | #else |
43 | 2: ldrbt r2, [r0], #1 | 44 | 2: T(ldrb) r2, [r0], #1 |
44 | 3: ldrbt r3, [r0] | 45 | 3: T(ldrb) r3, [r0] |
45 | #endif | 46 | #endif |
46 | #ifndef __ARMEB__ | 47 | #ifndef __ARMEB__ |
47 | orr r2, r2, r3, lsl #8 | 48 | orr r2, r2, r3, lsl #8 |
@@ -53,7 +54,7 @@ ENTRY(__get_user_2) | |||
53 | ENDPROC(__get_user_2) | 54 | ENDPROC(__get_user_2) |
54 | 55 | ||
55 | ENTRY(__get_user_4) | 56 | ENTRY(__get_user_4) |
56 | 4: ldrt r2, [r0] | 57 | 4: T(ldr) r2, [r0] |
57 | mov r0, #0 | 58 | mov r0, #0 |
58 | mov pc, lr | 59 | mov pc, lr |
59 | ENDPROC(__get_user_4) | 60 | ENDPROC(__get_user_4) |
diff --git a/arch/arm/lib/putuser.S b/arch/arm/lib/putuser.S index 5a01a23c6c06..c023fc11e86c 100644 --- a/arch/arm/lib/putuser.S +++ b/arch/arm/lib/putuser.S | |||
@@ -28,9 +28,10 @@ | |||
28 | */ | 28 | */ |
29 | #include <linux/linkage.h> | 29 | #include <linux/linkage.h> |
30 | #include <asm/errno.h> | 30 | #include <asm/errno.h> |
31 | #include <asm/domain.h> | ||
31 | 32 | ||
32 | ENTRY(__put_user_1) | 33 | ENTRY(__put_user_1) |
33 | 1: strbt r2, [r0] | 34 | 1: T(strb) r2, [r0] |
34 | mov r0, #0 | 35 | mov r0, #0 |
35 | mov pc, lr | 36 | mov pc, lr |
36 | ENDPROC(__put_user_1) | 37 | ENDPROC(__put_user_1) |
@@ -39,19 +40,19 @@ ENTRY(__put_user_2) | |||
39 | mov ip, r2, lsr #8 | 40 | mov ip, r2, lsr #8 |
40 | #ifdef CONFIG_THUMB2_KERNEL | 41 | #ifdef CONFIG_THUMB2_KERNEL |
41 | #ifndef __ARMEB__ | 42 | #ifndef __ARMEB__ |
42 | 2: strbt r2, [r0] | 43 | 2: T(strb) r2, [r0] |
43 | 3: strbt ip, [r0, #1] | 44 | 3: T(strb) ip, [r0, #1] |
44 | #else | 45 | #else |
45 | 2: strbt ip, [r0] | 46 | 2: T(strb) ip, [r0] |
46 | 3: strbt r2, [r0, #1] | 47 | 3: T(strb) r2, [r0, #1] |
47 | #endif | 48 | #endif |
48 | #else /* !CONFIG_THUMB2_KERNEL */ | 49 | #else /* !CONFIG_THUMB2_KERNEL */ |
49 | #ifndef __ARMEB__ | 50 | #ifndef __ARMEB__ |
50 | 2: strbt r2, [r0], #1 | 51 | 2: T(strb) r2, [r0], #1 |
51 | 3: strbt ip, [r0] | 52 | 3: T(strb) ip, [r0] |
52 | #else | 53 | #else |
53 | 2: strbt ip, [r0], #1 | 54 | 2: T(strb) ip, [r0], #1 |
54 | 3: strbt r2, [r0] | 55 | 3: T(strb) r2, [r0] |
55 | #endif | 56 | #endif |
56 | #endif /* CONFIG_THUMB2_KERNEL */ | 57 | #endif /* CONFIG_THUMB2_KERNEL */ |
57 | mov r0, #0 | 58 | mov r0, #0 |
@@ -59,18 +60,18 @@ ENTRY(__put_user_2) | |||
59 | ENDPROC(__put_user_2) | 60 | ENDPROC(__put_user_2) |
60 | 61 | ||
61 | ENTRY(__put_user_4) | 62 | ENTRY(__put_user_4) |
62 | 4: strt r2, [r0] | 63 | 4: T(str) r2, [r0] |
63 | mov r0, #0 | 64 | mov r0, #0 |
64 | mov pc, lr | 65 | mov pc, lr |
65 | ENDPROC(__put_user_4) | 66 | ENDPROC(__put_user_4) |
66 | 67 | ||
67 | ENTRY(__put_user_8) | 68 | ENTRY(__put_user_8) |
68 | #ifdef CONFIG_THUMB2_KERNEL | 69 | #ifdef CONFIG_THUMB2_KERNEL |
69 | 5: strt r2, [r0] | 70 | 5: T(str) r2, [r0] |
70 | 6: strt r3, [r0, #4] | 71 | 6: T(str) r3, [r0, #4] |
71 | #else | 72 | #else |
72 | 5: strt r2, [r0], #4 | 73 | 5: T(str) r2, [r0], #4 |
73 | 6: strt r3, [r0] | 74 | 6: T(str) r3, [r0] |
74 | #endif | 75 | #endif |
75 | mov r0, #0 | 76 | mov r0, #0 |
76 | mov pc, lr | 77 | mov pc, lr |
diff --git a/arch/arm/lib/uaccess.S b/arch/arm/lib/uaccess.S index fee9f6f88adb..d0ece2aeb70d 100644 --- a/arch/arm/lib/uaccess.S +++ b/arch/arm/lib/uaccess.S | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/linkage.h> | 14 | #include <linux/linkage.h> |
15 | #include <asm/assembler.h> | 15 | #include <asm/assembler.h> |
16 | #include <asm/errno.h> | 16 | #include <asm/errno.h> |
17 | #include <asm/domain.h> | ||
17 | 18 | ||
18 | .text | 19 | .text |
19 | 20 | ||
@@ -31,11 +32,11 @@ | |||
31 | rsb ip, ip, #4 | 32 | rsb ip, ip, #4 |
32 | cmp ip, #2 | 33 | cmp ip, #2 |
33 | ldrb r3, [r1], #1 | 34 | ldrb r3, [r1], #1 |
34 | USER( strbt r3, [r0], #1) @ May fault | 35 | USER( T(strb) r3, [r0], #1) @ May fault |
35 | ldrgeb r3, [r1], #1 | 36 | ldrgeb r3, [r1], #1 |
36 | USER( strgebt r3, [r0], #1) @ May fault | 37 | USER( T(strgeb) r3, [r0], #1) @ May fault |
37 | ldrgtb r3, [r1], #1 | 38 | ldrgtb r3, [r1], #1 |
38 | USER( strgtbt r3, [r0], #1) @ May fault | 39 | USER( T(strgtb) r3, [r0], #1) @ May fault |
39 | sub r2, r2, ip | 40 | sub r2, r2, ip |
40 | b .Lc2u_dest_aligned | 41 | b .Lc2u_dest_aligned |
41 | 42 | ||
@@ -58,7 +59,7 @@ ENTRY(__copy_to_user) | |||
58 | addmi ip, r2, #4 | 59 | addmi ip, r2, #4 |
59 | bmi .Lc2u_0nowords | 60 | bmi .Lc2u_0nowords |
60 | ldr r3, [r1], #4 | 61 | ldr r3, [r1], #4 |
61 | USER( strt r3, [r0], #4) @ May fault | 62 | USER( T(str) r3, [r0], #4) @ May fault |
62 | mov ip, r0, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction | 63 | mov ip, r0, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction |
63 | rsb ip, ip, #0 | 64 | rsb ip, ip, #0 |
64 | movs ip, ip, lsr #32 - PAGE_SHIFT | 65 | movs ip, ip, lsr #32 - PAGE_SHIFT |
@@ -87,18 +88,18 @@ USER( strt r3, [r0], #4) @ May fault | |||
87 | stmneia r0!, {r3 - r4} @ Shouldnt fault | 88 | stmneia r0!, {r3 - r4} @ Shouldnt fault |
88 | tst ip, #4 | 89 | tst ip, #4 |
89 | ldrne r3, [r1], #4 | 90 | ldrne r3, [r1], #4 |
90 | strnet r3, [r0], #4 @ Shouldnt fault | 91 | T(strne) r3, [r0], #4 @ Shouldnt fault |
91 | ands ip, ip, #3 | 92 | ands ip, ip, #3 |
92 | beq .Lc2u_0fupi | 93 | beq .Lc2u_0fupi |
93 | .Lc2u_0nowords: teq ip, #0 | 94 | .Lc2u_0nowords: teq ip, #0 |
94 | beq .Lc2u_finished | 95 | beq .Lc2u_finished |
95 | .Lc2u_nowords: cmp ip, #2 | 96 | .Lc2u_nowords: cmp ip, #2 |
96 | ldrb r3, [r1], #1 | 97 | ldrb r3, [r1], #1 |
97 | USER( strbt r3, [r0], #1) @ May fault | 98 | USER( T(strb) r3, [r0], #1) @ May fault |
98 | ldrgeb r3, [r1], #1 | 99 | ldrgeb r3, [r1], #1 |
99 | USER( strgebt r3, [r0], #1) @ May fault | 100 | USER( T(strgeb) r3, [r0], #1) @ May fault |
100 | ldrgtb r3, [r1], #1 | 101 | ldrgtb r3, [r1], #1 |
101 | USER( strgtbt r3, [r0], #1) @ May fault | 102 | USER( T(strgtb) r3, [r0], #1) @ May fault |
102 | b .Lc2u_finished | 103 | b .Lc2u_finished |
103 | 104 | ||
104 | .Lc2u_not_enough: | 105 | .Lc2u_not_enough: |
@@ -119,7 +120,7 @@ USER( strgtbt r3, [r0], #1) @ May fault | |||
119 | mov r3, r7, pull #8 | 120 | mov r3, r7, pull #8 |
120 | ldr r7, [r1], #4 | 121 | ldr r7, [r1], #4 |
121 | orr r3, r3, r7, push #24 | 122 | orr r3, r3, r7, push #24 |
122 | USER( strt r3, [r0], #4) @ May fault | 123 | USER( T(str) r3, [r0], #4) @ May fault |
123 | mov ip, r0, lsl #32 - PAGE_SHIFT | 124 | mov ip, r0, lsl #32 - PAGE_SHIFT |
124 | rsb ip, ip, #0 | 125 | rsb ip, ip, #0 |
125 | movs ip, ip, lsr #32 - PAGE_SHIFT | 126 | movs ip, ip, lsr #32 - PAGE_SHIFT |
@@ -154,18 +155,18 @@ USER( strt r3, [r0], #4) @ May fault | |||
154 | movne r3, r7, pull #8 | 155 | movne r3, r7, pull #8 |
155 | ldrne r7, [r1], #4 | 156 | ldrne r7, [r1], #4 |
156 | orrne r3, r3, r7, push #24 | 157 | orrne r3, r3, r7, push #24 |
157 | strnet r3, [r0], #4 @ Shouldnt fault | 158 | T(strne) r3, [r0], #4 @ Shouldnt fault |
158 | ands ip, ip, #3 | 159 | ands ip, ip, #3 |
159 | beq .Lc2u_1fupi | 160 | beq .Lc2u_1fupi |
160 | .Lc2u_1nowords: mov r3, r7, get_byte_1 | 161 | .Lc2u_1nowords: mov r3, r7, get_byte_1 |
161 | teq ip, #0 | 162 | teq ip, #0 |
162 | beq .Lc2u_finished | 163 | beq .Lc2u_finished |
163 | cmp ip, #2 | 164 | cmp ip, #2 |
164 | USER( strbt r3, [r0], #1) @ May fault | 165 | USER( T(strb) r3, [r0], #1) @ May fault |
165 | movge r3, r7, get_byte_2 | 166 | movge r3, r7, get_byte_2 |
166 | USER( strgebt r3, [r0], #1) @ May fault | 167 | USER( T(strgeb) r3, [r0], #1) @ May fault |
167 | movgt r3, r7, get_byte_3 | 168 | movgt r3, r7, get_byte_3 |
168 | USER( strgtbt r3, [r0], #1) @ May fault | 169 | USER( T(strgtb) r3, [r0], #1) @ May fault |
169 | b .Lc2u_finished | 170 | b .Lc2u_finished |
170 | 171 | ||
171 | .Lc2u_2fupi: subs r2, r2, #4 | 172 | .Lc2u_2fupi: subs r2, r2, #4 |
@@ -174,7 +175,7 @@ USER( strgtbt r3, [r0], #1) @ May fault | |||
174 | mov r3, r7, pull #16 | 175 | mov r3, r7, pull #16 |
175 | ldr r7, [r1], #4 | 176 | ldr r7, [r1], #4 |
176 | orr r3, r3, r7, push #16 | 177 | orr r3, r3, r7, push #16 |
177 | USER( strt r3, [r0], #4) @ May fault | 178 | USER( T(str) r3, [r0], #4) @ May fault |
178 | mov ip, r0, lsl #32 - PAGE_SHIFT | 179 | mov ip, r0, lsl #32 - PAGE_SHIFT |
179 | rsb ip, ip, #0 | 180 | rsb ip, ip, #0 |
180 | movs ip, ip, lsr #32 - PAGE_SHIFT | 181 | movs ip, ip, lsr #32 - PAGE_SHIFT |
@@ -209,18 +210,18 @@ USER( strt r3, [r0], #4) @ May fault | |||
209 | movne r3, r7, pull #16 | 210 | movne r3, r7, pull #16 |
210 | ldrne r7, [r1], #4 | 211 | ldrne r7, [r1], #4 |
211 | orrne r3, r3, r7, push #16 | 212 | orrne r3, r3, r7, push #16 |
212 | strnet r3, [r0], #4 @ Shouldnt fault | 213 | T(strne) r3, [r0], #4 @ Shouldnt fault |
213 | ands ip, ip, #3 | 214 | ands ip, ip, #3 |
214 | beq .Lc2u_2fupi | 215 | beq .Lc2u_2fupi |
215 | .Lc2u_2nowords: mov r3, r7, get_byte_2 | 216 | .Lc2u_2nowords: mov r3, r7, get_byte_2 |
216 | teq ip, #0 | 217 | teq ip, #0 |
217 | beq .Lc2u_finished | 218 | beq .Lc2u_finished |
218 | cmp ip, #2 | 219 | cmp ip, #2 |
219 | USER( strbt r3, [r0], #1) @ May fault | 220 | USER( T(strb) r3, [r0], #1) @ May fault |
220 | movge r3, r7, get_byte_3 | 221 | movge r3, r7, get_byte_3 |
221 | USER( strgebt r3, [r0], #1) @ May fault | 222 | USER( T(strgeb) r3, [r0], #1) @ May fault |
222 | ldrgtb r3, [r1], #0 | 223 | ldrgtb r3, [r1], #0 |
223 | USER( strgtbt r3, [r0], #1) @ May fault | 224 | USER( T(strgtb) r3, [r0], #1) @ May fault |
224 | b .Lc2u_finished | 225 | b .Lc2u_finished |
225 | 226 | ||
226 | .Lc2u_3fupi: subs r2, r2, #4 | 227 | .Lc2u_3fupi: subs r2, r2, #4 |
@@ -229,7 +230,7 @@ USER( strgtbt r3, [r0], #1) @ May fault | |||
229 | mov r3, r7, pull #24 | 230 | mov r3, r7, pull #24 |
230 | ldr r7, [r1], #4 | 231 | ldr r7, [r1], #4 |
231 | orr r3, r3, r7, push #8 | 232 | orr r3, r3, r7, push #8 |
232 | USER( strt r3, [r0], #4) @ May fault | 233 | USER( T(str) r3, [r0], #4) @ May fault |
233 | mov ip, r0, lsl #32 - PAGE_SHIFT | 234 | mov ip, r0, lsl #32 - PAGE_SHIFT |
234 | rsb ip, ip, #0 | 235 | rsb ip, ip, #0 |
235 | movs ip, ip, lsr #32 - PAGE_SHIFT | 236 | movs ip, ip, lsr #32 - PAGE_SHIFT |
@@ -264,18 +265,18 @@ USER( strt r3, [r0], #4) @ May fault | |||
264 | movne r3, r7, pull #24 | 265 | movne r3, r7, pull #24 |
265 | ldrne r7, [r1], #4 | 266 | ldrne r7, [r1], #4 |
266 | orrne r3, r3, r7, push #8 | 267 | orrne r3, r3, r7, push #8 |
267 | strnet r3, [r0], #4 @ Shouldnt fault | 268 | T(strne) r3, [r0], #4 @ Shouldnt fault |
268 | ands ip, ip, #3 | 269 | ands ip, ip, #3 |
269 | beq .Lc2u_3fupi | 270 | beq .Lc2u_3fupi |
270 | .Lc2u_3nowords: mov r3, r7, get_byte_3 | 271 | .Lc2u_3nowords: mov r3, r7, get_byte_3 |
271 | teq ip, #0 | 272 | teq ip, #0 |
272 | beq .Lc2u_finished | 273 | beq .Lc2u_finished |
273 | cmp ip, #2 | 274 | cmp ip, #2 |
274 | USER( strbt r3, [r0], #1) @ May fault | 275 | USER( T(strb) r3, [r0], #1) @ May fault |
275 | ldrgeb r3, [r1], #1 | 276 | ldrgeb r3, [r1], #1 |
276 | USER( strgebt r3, [r0], #1) @ May fault | 277 | USER( T(strgeb) r3, [r0], #1) @ May fault |
277 | ldrgtb r3, [r1], #0 | 278 | ldrgtb r3, [r1], #0 |
278 | USER( strgtbt r3, [r0], #1) @ May fault | 279 | USER( T(strgtb) r3, [r0], #1) @ May fault |
279 | b .Lc2u_finished | 280 | b .Lc2u_finished |
280 | ENDPROC(__copy_to_user) | 281 | ENDPROC(__copy_to_user) |
281 | 282 | ||
@@ -294,11 +295,11 @@ ENDPROC(__copy_to_user) | |||
294 | .Lcfu_dest_not_aligned: | 295 | .Lcfu_dest_not_aligned: |
295 | rsb ip, ip, #4 | 296 | rsb ip, ip, #4 |
296 | cmp ip, #2 | 297 | cmp ip, #2 |
297 | USER( ldrbt r3, [r1], #1) @ May fault | 298 | USER( T(ldrb) r3, [r1], #1) @ May fault |
298 | strb r3, [r0], #1 | 299 | strb r3, [r0], #1 |
299 | USER( ldrgebt r3, [r1], #1) @ May fault | 300 | USER( T(ldrgeb) r3, [r1], #1) @ May fault |
300 | strgeb r3, [r0], #1 | 301 | strgeb r3, [r0], #1 |
301 | USER( ldrgtbt r3, [r1], #1) @ May fault | 302 | USER( T(ldrgtb) r3, [r1], #1) @ May fault |
302 | strgtb r3, [r0], #1 | 303 | strgtb r3, [r0], #1 |
303 | sub r2, r2, ip | 304 | sub r2, r2, ip |
304 | b .Lcfu_dest_aligned | 305 | b .Lcfu_dest_aligned |
@@ -321,7 +322,7 @@ ENTRY(__copy_from_user) | |||
321 | .Lcfu_0fupi: subs r2, r2, #4 | 322 | .Lcfu_0fupi: subs r2, r2, #4 |
322 | addmi ip, r2, #4 | 323 | addmi ip, r2, #4 |
323 | bmi .Lcfu_0nowords | 324 | bmi .Lcfu_0nowords |
324 | USER( ldrt r3, [r1], #4) | 325 | USER( T(ldr) r3, [r1], #4) |
325 | str r3, [r0], #4 | 326 | str r3, [r0], #4 |
326 | mov ip, r1, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction | 327 | mov ip, r1, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction |
327 | rsb ip, ip, #0 | 328 | rsb ip, ip, #0 |
@@ -350,18 +351,18 @@ USER( ldrt r3, [r1], #4) | |||
350 | ldmneia r1!, {r3 - r4} @ Shouldnt fault | 351 | ldmneia r1!, {r3 - r4} @ Shouldnt fault |
351 | stmneia r0!, {r3 - r4} | 352 | stmneia r0!, {r3 - r4} |
352 | tst ip, #4 | 353 | tst ip, #4 |
353 | ldrnet r3, [r1], #4 @ Shouldnt fault | 354 | T(ldrne) r3, [r1], #4 @ Shouldnt fault |
354 | strne r3, [r0], #4 | 355 | strne r3, [r0], #4 |
355 | ands ip, ip, #3 | 356 | ands ip, ip, #3 |
356 | beq .Lcfu_0fupi | 357 | beq .Lcfu_0fupi |
357 | .Lcfu_0nowords: teq ip, #0 | 358 | .Lcfu_0nowords: teq ip, #0 |
358 | beq .Lcfu_finished | 359 | beq .Lcfu_finished |
359 | .Lcfu_nowords: cmp ip, #2 | 360 | .Lcfu_nowords: cmp ip, #2 |
360 | USER( ldrbt r3, [r1], #1) @ May fault | 361 | USER( T(ldrb) r3, [r1], #1) @ May fault |
361 | strb r3, [r0], #1 | 362 | strb r3, [r0], #1 |
362 | USER( ldrgebt r3, [r1], #1) @ May fault | 363 | USER( T(ldrgeb) r3, [r1], #1) @ May fault |
363 | strgeb r3, [r0], #1 | 364 | strgeb r3, [r0], #1 |
364 | USER( ldrgtbt r3, [r1], #1) @ May fault | 365 | USER( T(ldrgtb) r3, [r1], #1) @ May fault |
365 | strgtb r3, [r0], #1 | 366 | strgtb r3, [r0], #1 |
366 | b .Lcfu_finished | 367 | b .Lcfu_finished |
367 | 368 | ||
@@ -374,7 +375,7 @@ USER( ldrgtbt r3, [r1], #1) @ May fault | |||
374 | 375 | ||
375 | .Lcfu_src_not_aligned: | 376 | .Lcfu_src_not_aligned: |
376 | bic r1, r1, #3 | 377 | bic r1, r1, #3 |
377 | USER( ldrt r7, [r1], #4) @ May fault | 378 | USER( T(ldr) r7, [r1], #4) @ May fault |
378 | cmp ip, #2 | 379 | cmp ip, #2 |
379 | bgt .Lcfu_3fupi | 380 | bgt .Lcfu_3fupi |
380 | beq .Lcfu_2fupi | 381 | beq .Lcfu_2fupi |
@@ -382,7 +383,7 @@ USER( ldrt r7, [r1], #4) @ May fault | |||
382 | addmi ip, r2, #4 | 383 | addmi ip, r2, #4 |
383 | bmi .Lcfu_1nowords | 384 | bmi .Lcfu_1nowords |
384 | mov r3, r7, pull #8 | 385 | mov r3, r7, pull #8 |
385 | USER( ldrt r7, [r1], #4) @ May fault | 386 | USER( T(ldr) r7, [r1], #4) @ May fault |
386 | orr r3, r3, r7, push #24 | 387 | orr r3, r3, r7, push #24 |
387 | str r3, [r0], #4 | 388 | str r3, [r0], #4 |
388 | mov ip, r1, lsl #32 - PAGE_SHIFT | 389 | mov ip, r1, lsl #32 - PAGE_SHIFT |
@@ -417,7 +418,7 @@ USER( ldrt r7, [r1], #4) @ May fault | |||
417 | stmneia r0!, {r3 - r4} | 418 | stmneia r0!, {r3 - r4} |
418 | tst ip, #4 | 419 | tst ip, #4 |
419 | movne r3, r7, pull #8 | 420 | movne r3, r7, pull #8 |
420 | USER( ldrnet r7, [r1], #4) @ May fault | 421 | USER( T(ldrne) r7, [r1], #4) @ May fault |
421 | orrne r3, r3, r7, push #24 | 422 | orrne r3, r3, r7, push #24 |
422 | strne r3, [r0], #4 | 423 | strne r3, [r0], #4 |
423 | ands ip, ip, #3 | 424 | ands ip, ip, #3 |
@@ -437,7 +438,7 @@ USER( ldrnet r7, [r1], #4) @ May fault | |||
437 | addmi ip, r2, #4 | 438 | addmi ip, r2, #4 |
438 | bmi .Lcfu_2nowords | 439 | bmi .Lcfu_2nowords |
439 | mov r3, r7, pull #16 | 440 | mov r3, r7, pull #16 |
440 | USER( ldrt r7, [r1], #4) @ May fault | 441 | USER( T(ldr) r7, [r1], #4) @ May fault |
441 | orr r3, r3, r7, push #16 | 442 | orr r3, r3, r7, push #16 |
442 | str r3, [r0], #4 | 443 | str r3, [r0], #4 |
443 | mov ip, r1, lsl #32 - PAGE_SHIFT | 444 | mov ip, r1, lsl #32 - PAGE_SHIFT |
@@ -473,7 +474,7 @@ USER( ldrt r7, [r1], #4) @ May fault | |||
473 | stmneia r0!, {r3 - r4} | 474 | stmneia r0!, {r3 - r4} |
474 | tst ip, #4 | 475 | tst ip, #4 |
475 | movne r3, r7, pull #16 | 476 | movne r3, r7, pull #16 |
476 | USER( ldrnet r7, [r1], #4) @ May fault | 477 | USER( T(ldrne) r7, [r1], #4) @ May fault |
477 | orrne r3, r3, r7, push #16 | 478 | orrne r3, r3, r7, push #16 |
478 | strne r3, [r0], #4 | 479 | strne r3, [r0], #4 |
479 | ands ip, ip, #3 | 480 | ands ip, ip, #3 |
@@ -485,7 +486,7 @@ USER( ldrnet r7, [r1], #4) @ May fault | |||
485 | strb r3, [r0], #1 | 486 | strb r3, [r0], #1 |
486 | movge r3, r7, get_byte_3 | 487 | movge r3, r7, get_byte_3 |
487 | strgeb r3, [r0], #1 | 488 | strgeb r3, [r0], #1 |
488 | USER( ldrgtbt r3, [r1], #0) @ May fault | 489 | USER( T(ldrgtb) r3, [r1], #0) @ May fault |
489 | strgtb r3, [r0], #1 | 490 | strgtb r3, [r0], #1 |
490 | b .Lcfu_finished | 491 | b .Lcfu_finished |
491 | 492 | ||
@@ -493,7 +494,7 @@ USER( ldrgtbt r3, [r1], #0) @ May fault | |||
493 | addmi ip, r2, #4 | 494 | addmi ip, r2, #4 |
494 | bmi .Lcfu_3nowords | 495 | bmi .Lcfu_3nowords |
495 | mov r3, r7, pull #24 | 496 | mov r3, r7, pull #24 |
496 | USER( ldrt r7, [r1], #4) @ May fault | 497 | USER( T(ldr) r7, [r1], #4) @ May fault |
497 | orr r3, r3, r7, push #8 | 498 | orr r3, r3, r7, push #8 |
498 | str r3, [r0], #4 | 499 | str r3, [r0], #4 |
499 | mov ip, r1, lsl #32 - PAGE_SHIFT | 500 | mov ip, r1, lsl #32 - PAGE_SHIFT |
@@ -528,7 +529,7 @@ USER( ldrt r7, [r1], #4) @ May fault | |||
528 | stmneia r0!, {r3 - r4} | 529 | stmneia r0!, {r3 - r4} |
529 | tst ip, #4 | 530 | tst ip, #4 |
530 | movne r3, r7, pull #24 | 531 | movne r3, r7, pull #24 |
531 | USER( ldrnet r7, [r1], #4) @ May fault | 532 | USER( T(ldrne) r7, [r1], #4) @ May fault |
532 | orrne r3, r3, r7, push #8 | 533 | orrne r3, r3, r7, push #8 |
533 | strne r3, [r0], #4 | 534 | strne r3, [r0], #4 |
534 | ands ip, ip, #3 | 535 | ands ip, ip, #3 |
@@ -538,9 +539,9 @@ USER( ldrnet r7, [r1], #4) @ May fault | |||
538 | beq .Lcfu_finished | 539 | beq .Lcfu_finished |
539 | cmp ip, #2 | 540 | cmp ip, #2 |
540 | strb r3, [r0], #1 | 541 | strb r3, [r0], #1 |
541 | USER( ldrgebt r3, [r1], #1) @ May fault | 542 | USER( T(ldrgeb) r3, [r1], #1) @ May fault |
542 | strgeb r3, [r0], #1 | 543 | strgeb r3, [r0], #1 |
543 | USER( ldrgtbt r3, [r1], #1) @ May fault | 544 | USER( T(ldrgtb) r3, [r1], #1) @ May fault |
544 | strgtb r3, [r0], #1 | 545 | strgtb r3, [r0], #1 |
545 | b .Lcfu_finished | 546 | b .Lcfu_finished |
546 | ENDPROC(__copy_from_user) | 547 | ENDPROC(__copy_from_user) |
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 4414a01e1e8a..6d05f79a8cd2 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig | |||
@@ -599,6 +599,14 @@ config CPU_CP15_MPU | |||
599 | help | 599 | help |
600 | Processor has the CP15 register, which has MPU related registers. | 600 | Processor has the CP15 register, which has MPU related registers. |
601 | 601 | ||
602 | config CPU_USE_DOMAINS | ||
603 | bool | ||
604 | depends on MMU | ||
605 | default y if !CPU_32v6K | ||
606 | help | ||
607 | This option enables or disables the use of domain switching | ||
608 | via the set_fs() function. | ||
609 | |||
602 | # | 610 | # |
603 | # CPU supports 36-bit I/O | 611 | # CPU supports 36-bit I/O |
604 | # | 612 | # |
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 72ad3e1f56cf..79c01f540cbe 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <asm/smp_plat.h> | 24 | #include <asm/smp_plat.h> |
25 | #include <asm/tlb.h> | 25 | #include <asm/tlb.h> |
26 | #include <asm/highmem.h> | 26 | #include <asm/highmem.h> |
27 | #include <asm/traps.h> | ||
27 | 28 | ||
28 | #include <asm/mach/arch.h> | 29 | #include <asm/mach/arch.h> |
29 | #include <asm/mach/map.h> | 30 | #include <asm/mach/map.h> |
@@ -914,12 +915,11 @@ static void __init devicemaps_init(struct machine_desc *mdesc) | |||
914 | { | 915 | { |
915 | struct map_desc map; | 916 | struct map_desc map; |
916 | unsigned long addr; | 917 | unsigned long addr; |
917 | void *vectors; | ||
918 | 918 | ||
919 | /* | 919 | /* |
920 | * Allocate the vector page early. | 920 | * Allocate the vector page early. |
921 | */ | 921 | */ |
922 | vectors = early_alloc(PAGE_SIZE); | 922 | vectors_page = early_alloc(PAGE_SIZE); |
923 | 923 | ||
924 | for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE) | 924 | for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE) |
925 | pmd_clear(pmd_off_k(addr)); | 925 | pmd_clear(pmd_off_k(addr)); |
@@ -959,7 +959,7 @@ static void __init devicemaps_init(struct machine_desc *mdesc) | |||
959 | * location (0xffff0000). If we aren't using high-vectors, also | 959 | * location (0xffff0000). If we aren't using high-vectors, also |
960 | * create a mapping at the low-vectors virtual address. | 960 | * create a mapping at the low-vectors virtual address. |
961 | */ | 961 | */ |
962 | map.pfn = __phys_to_pfn(virt_to_phys(vectors)); | 962 | map.pfn = __phys_to_pfn(virt_to_phys(vectors_page)); |
963 | map.virtual = 0xffff0000; | 963 | map.virtual = 0xffff0000; |
964 | map.length = PAGE_SIZE; | 964 | map.length = PAGE_SIZE; |
965 | map.type = MT_HIGH_VECTORS; | 965 | map.type = MT_HIGH_VECTORS; |
diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S index 7d63beaf9745..337f10256cd6 100644 --- a/arch/arm/mm/proc-macros.S +++ b/arch/arm/mm/proc-macros.S | |||
@@ -99,6 +99,10 @@ | |||
99 | * 110x 0 1 0 r/w r/o | 99 | * 110x 0 1 0 r/w r/o |
100 | * 11x0 0 1 0 r/w r/o | 100 | * 11x0 0 1 0 r/w r/o |
101 | * 1111 0 1 1 r/w r/w | 101 | * 1111 0 1 1 r/w r/w |
102 | * | ||
103 | * If !CONFIG_CPU_USE_DOMAINS, the following permissions are changed: | ||
104 | * 110x 1 1 1 r/o r/o | ||
105 | * 11x0 1 1 1 r/o r/o | ||
102 | */ | 106 | */ |
103 | .macro armv6_mt_table pfx | 107 | .macro armv6_mt_table pfx |
104 | \pfx\()_mt_table: | 108 | \pfx\()_mt_table: |
@@ -138,8 +142,11 @@ | |||
138 | 142 | ||
139 | tst r1, #L_PTE_USER | 143 | tst r1, #L_PTE_USER |
140 | orrne r3, r3, #PTE_EXT_AP1 | 144 | orrne r3, r3, #PTE_EXT_AP1 |
145 | #ifdef CONFIG_CPU_USE_DOMAINS | ||
146 | @ allow kernel read/write access to read-only user pages | ||
141 | tstne r3, #PTE_EXT_APX | 147 | tstne r3, #PTE_EXT_APX |
142 | bicne r3, r3, #PTE_EXT_APX | PTE_EXT_AP0 | 148 | bicne r3, r3, #PTE_EXT_APX | PTE_EXT_AP0 |
149 | #endif | ||
143 | 150 | ||
144 | tst r1, #L_PTE_EXEC | 151 | tst r1, #L_PTE_EXEC |
145 | orreq r3, r3, #PTE_EXT_XN | 152 | orreq r3, r3, #PTE_EXT_XN |
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index 53cbe2225153..cfc11afab1fb 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S | |||
@@ -148,8 +148,11 @@ ENTRY(cpu_v7_set_pte_ext) | |||
148 | 148 | ||
149 | tst r1, #L_PTE_USER | 149 | tst r1, #L_PTE_USER |
150 | orrne r3, r3, #PTE_EXT_AP1 | 150 | orrne r3, r3, #PTE_EXT_AP1 |
151 | #ifdef CONFIG_CPU_USE_DOMAINS | ||
152 | @ allow kernel read/write access to read-only user pages | ||
151 | tstne r3, #PTE_EXT_APX | 153 | tstne r3, #PTE_EXT_APX |
152 | bicne r3, r3, #PTE_EXT_APX | PTE_EXT_AP0 | 154 | bicne r3, r3, #PTE_EXT_APX | PTE_EXT_AP0 |
155 | #endif | ||
153 | 156 | ||
154 | tst r1, #L_PTE_EXEC | 157 | tst r1, #L_PTE_EXEC |
155 | orreq r3, r3, #PTE_EXT_XN | 158 | orreq r3, r3, #PTE_EXT_XN |
@@ -273,8 +276,6 @@ __v7_setup: | |||
273 | ALT_SMP(orr r4, r4, #TTB_FLAGS_SMP) | 276 | ALT_SMP(orr r4, r4, #TTB_FLAGS_SMP) |
274 | ALT_UP(orr r4, r4, #TTB_FLAGS_UP) | 277 | ALT_UP(orr r4, r4, #TTB_FLAGS_UP) |
275 | mcr p15, 0, r4, c2, c0, 1 @ load TTB1 | 278 | mcr p15, 0, r4, c2, c0, 1 @ load TTB1 |
276 | mov r10, #0x1f @ domains 0, 1 = manager | ||
277 | mcr p15, 0, r10, c3, c0, 0 @ load domain access register | ||
278 | /* | 279 | /* |
279 | * Memory region attributes with SCTLR.TRE=1 | 280 | * Memory region attributes with SCTLR.TRE=1 |
280 | * | 281 | * |