aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorCatalin Marinas <catalin.marinas@arm.com>2010-09-13 11:03:21 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2010-11-04 11:44:31 -0400
commit247055aa21ffef1c49dd64710d5e94c2aee19b58 (patch)
treee9e026b96597d080de4c16bb88c17b0495c61904 /arch/arm
parentff8b16d7e15a8ba2a6086645614a483e048e3fbf (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.h13
-rw-r--r--arch/arm/include/asm/domain.h31
-rw-r--r--arch/arm/include/asm/futex.h9
-rw-r--r--arch/arm/include/asm/traps.h2
-rw-r--r--arch/arm/include/asm/uaccess.h16
-rw-r--r--arch/arm/kernel/entry-armv.S4
-rw-r--r--arch/arm/kernel/fiq.c5
-rw-r--r--arch/arm/kernel/traps.c14
-rw-r--r--arch/arm/lib/getuser.S13
-rw-r--r--arch/arm/lib/putuser.S29
-rw-r--r--arch/arm/lib/uaccess.S83
-rw-r--r--arch/arm/mm/Kconfig8
-rw-r--r--arch/arm/mm/mmu.c6
-rw-r--r--arch/arm/mm/proc-macros.S7
-rw-r--r--arch/arm/mm/proc-v7.S5
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()
2109999: 2119999:
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
2519999: 2529999:
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)
27extern void __init early_trap_init(void); 27extern void __init early_trap_init(void);
28extern void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame); 28extern void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame);
29 29
30extern 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
49static unsigned long no_fiq_insn; 50static unsigned long no_fiq_insn;
50 51
@@ -77,7 +78,11 @@ int show_fiq_list(struct seq_file *p, void *v)
77 78
78void set_fiq_handler(void *start, unsigned int length) 79void 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
38static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" }; 38static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" };
39 39
40void *vectors_page;
41
40#ifdef CONFIG_DEBUG_USER 42#ifdef CONFIG_DEBUG_USER
41unsigned int user_debug; 43unsigned int user_debug;
42 44
@@ -759,7 +761,11 @@ static void __init kuser_get_tls_init(unsigned long vectors)
759 761
760void __init early_trap_init(void) 762void __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
32ENTRY(__get_user_1) 33ENTRY(__get_user_1)
331: ldrbt r2, [r0] 341: T(ldrb) r2, [r0]
34 mov r0, #0 35 mov r0, #0
35 mov pc, lr 36 mov pc, lr
36ENDPROC(__get_user_1) 37ENDPROC(__get_user_1)
37 38
38ENTRY(__get_user_2) 39ENTRY(__get_user_2)
39#ifdef CONFIG_THUMB2_KERNEL 40#ifdef CONFIG_THUMB2_KERNEL
402: ldrbt r2, [r0] 412: T(ldrb) r2, [r0]
413: ldrbt r3, [r0, #1] 423: T(ldrb) r3, [r0, #1]
42#else 43#else
432: ldrbt r2, [r0], #1 442: T(ldrb) r2, [r0], #1
443: ldrbt r3, [r0] 453: 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)
53ENDPROC(__get_user_2) 54ENDPROC(__get_user_2)
54 55
55ENTRY(__get_user_4) 56ENTRY(__get_user_4)
564: ldrt r2, [r0] 574: T(ldr) r2, [r0]
57 mov r0, #0 58 mov r0, #0
58 mov pc, lr 59 mov pc, lr
59ENDPROC(__get_user_4) 60ENDPROC(__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
32ENTRY(__put_user_1) 33ENTRY(__put_user_1)
331: strbt r2, [r0] 341: T(strb) r2, [r0]
34 mov r0, #0 35 mov r0, #0
35 mov pc, lr 36 mov pc, lr
36ENDPROC(__put_user_1) 37ENDPROC(__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__
422: strbt r2, [r0] 432: T(strb) r2, [r0]
433: strbt ip, [r0, #1] 443: T(strb) ip, [r0, #1]
44#else 45#else
452: strbt ip, [r0] 462: T(strb) ip, [r0]
463: strbt r2, [r0, #1] 473: 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__
502: strbt r2, [r0], #1 512: T(strb) r2, [r0], #1
513: strbt ip, [r0] 523: T(strb) ip, [r0]
52#else 53#else
532: strbt ip, [r0], #1 542: T(strb) ip, [r0], #1
543: strbt r2, [r0] 553: 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)
59ENDPROC(__put_user_2) 60ENDPROC(__put_user_2)
60 61
61ENTRY(__put_user_4) 62ENTRY(__put_user_4)
624: strt r2, [r0] 634: T(str) r2, [r0]
63 mov r0, #0 64 mov r0, #0
64 mov pc, lr 65 mov pc, lr
65ENDPROC(__put_user_4) 66ENDPROC(__put_user_4)
66 67
67ENTRY(__put_user_8) 68ENTRY(__put_user_8)
68#ifdef CONFIG_THUMB2_KERNEL 69#ifdef CONFIG_THUMB2_KERNEL
695: strt r2, [r0] 705: T(str) r2, [r0]
706: strt r3, [r0, #4] 716: T(str) r3, [r0, #4]
71#else 72#else
725: strt r2, [r0], #4 735: T(str) r2, [r0], #4
736: strt r3, [r0] 746: 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
34USER( strbt r3, [r0], #1) @ May fault 35USER( T(strb) r3, [r0], #1) @ May fault
35 ldrgeb r3, [r1], #1 36 ldrgeb r3, [r1], #1
36USER( strgebt r3, [r0], #1) @ May fault 37USER( T(strgeb) r3, [r0], #1) @ May fault
37 ldrgtb r3, [r1], #1 38 ldrgtb r3, [r1], #1
38USER( strgtbt r3, [r0], #1) @ May fault 39USER( 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
61USER( strt r3, [r0], #4) @ May fault 62USER( 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
97USER( strbt r3, [r0], #1) @ May fault 98USER( T(strb) r3, [r0], #1) @ May fault
98 ldrgeb r3, [r1], #1 99 ldrgeb r3, [r1], #1
99USER( strgebt r3, [r0], #1) @ May fault 100USER( T(strgeb) r3, [r0], #1) @ May fault
100 ldrgtb r3, [r1], #1 101 ldrgtb r3, [r1], #1
101USER( strgtbt r3, [r0], #1) @ May fault 102USER( 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
122USER( strt r3, [r0], #4) @ May fault 123USER( 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
164USER( strbt r3, [r0], #1) @ May fault 165USER( T(strb) r3, [r0], #1) @ May fault
165 movge r3, r7, get_byte_2 166 movge r3, r7, get_byte_2
166USER( strgebt r3, [r0], #1) @ May fault 167USER( T(strgeb) r3, [r0], #1) @ May fault
167 movgt r3, r7, get_byte_3 168 movgt r3, r7, get_byte_3
168USER( strgtbt r3, [r0], #1) @ May fault 169USER( 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
177USER( strt r3, [r0], #4) @ May fault 178USER( 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
219USER( strbt r3, [r0], #1) @ May fault 220USER( T(strb) r3, [r0], #1) @ May fault
220 movge r3, r7, get_byte_3 221 movge r3, r7, get_byte_3
221USER( strgebt r3, [r0], #1) @ May fault 222USER( T(strgeb) r3, [r0], #1) @ May fault
222 ldrgtb r3, [r1], #0 223 ldrgtb r3, [r1], #0
223USER( strgtbt r3, [r0], #1) @ May fault 224USER( 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
232USER( strt r3, [r0], #4) @ May fault 233USER( 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
274USER( strbt r3, [r0], #1) @ May fault 275USER( T(strb) r3, [r0], #1) @ May fault
275 ldrgeb r3, [r1], #1 276 ldrgeb r3, [r1], #1
276USER( strgebt r3, [r0], #1) @ May fault 277USER( T(strgeb) r3, [r0], #1) @ May fault
277 ldrgtb r3, [r1], #0 278 ldrgtb r3, [r1], #0
278USER( strgtbt r3, [r0], #1) @ May fault 279USER( T(strgtb) r3, [r0], #1) @ May fault
279 b .Lc2u_finished 280 b .Lc2u_finished
280ENDPROC(__copy_to_user) 281ENDPROC(__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
297USER( ldrbt r3, [r1], #1) @ May fault 298USER( T(ldrb) r3, [r1], #1) @ May fault
298 strb r3, [r0], #1 299 strb r3, [r0], #1
299USER( ldrgebt r3, [r1], #1) @ May fault 300USER( T(ldrgeb) r3, [r1], #1) @ May fault
300 strgeb r3, [r0], #1 301 strgeb r3, [r0], #1
301USER( ldrgtbt r3, [r1], #1) @ May fault 302USER( 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
324USER( ldrt r3, [r1], #4) 325USER( 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
360USER( ldrbt r3, [r1], #1) @ May fault 361USER( T(ldrb) r3, [r1], #1) @ May fault
361 strb r3, [r0], #1 362 strb r3, [r0], #1
362USER( ldrgebt r3, [r1], #1) @ May fault 363USER( T(ldrgeb) r3, [r1], #1) @ May fault
363 strgeb r3, [r0], #1 364 strgeb r3, [r0], #1
364USER( ldrgtbt r3, [r1], #1) @ May fault 365USER( 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
377USER( ldrt r7, [r1], #4) @ May fault 378USER( 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
385USER( ldrt r7, [r1], #4) @ May fault 386USER( 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
420USER( ldrnet r7, [r1], #4) @ May fault 421USER( 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
440USER( ldrt r7, [r1], #4) @ May fault 441USER( 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
476USER( ldrnet r7, [r1], #4) @ May fault 477USER( 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
488USER( ldrgtbt r3, [r1], #0) @ May fault 489USER( 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
496USER( ldrt r7, [r1], #4) @ May fault 497USER( 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
531USER( ldrnet r7, [r1], #4) @ May fault 532USER( 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
541USER( ldrgebt r3, [r1], #1) @ May fault 542USER( T(ldrgeb) r3, [r1], #1) @ May fault
542 strgeb r3, [r0], #1 543 strgeb r3, [r0], #1
543USER( ldrgtbt r3, [r1], #1) @ May fault 544USER( 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
546ENDPROC(__copy_from_user) 547ENDPROC(__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
602config 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 *