aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/include/asm/uaccess.h4
-rw-r--r--arch/arm/kernel/process.c33
-rw-r--r--arch/arm/kernel/swp_emulate.c6
-rw-r--r--arch/arm/lib/uaccess_with_memcpy.c29
-rw-r--r--arch/arm/mm/context.c38
-rw-r--r--arch/arm/mm/init.c92
-rw-r--r--arch/arm/mm/proc-v7.S4
7 files changed, 138 insertions, 68 deletions
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index 8cc85a4ebec2..35c9db857ebe 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -510,10 +510,14 @@ __copy_to_user_std(void __user *to, const void *from, unsigned long n);
510static inline unsigned long __must_check 510static inline unsigned long __must_check
511__copy_to_user(void __user *to, const void *from, unsigned long n) 511__copy_to_user(void __user *to, const void *from, unsigned long n)
512{ 512{
513#ifndef CONFIG_UACCESS_WITH_MEMCPY
513 unsigned int __ua_flags = uaccess_save_and_enable(); 514 unsigned int __ua_flags = uaccess_save_and_enable();
514 n = arm_copy_to_user(to, from, n); 515 n = arm_copy_to_user(to, from, n);
515 uaccess_restore(__ua_flags); 516 uaccess_restore(__ua_flags);
516 return n; 517 return n;
518#else
519 return arm_copy_to_user(to, from, n);
520#endif
517} 521}
518 522
519extern unsigned long __must_check 523extern unsigned long __must_check
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 7a7c4cea5523..4adfb46e3ee9 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -95,6 +95,22 @@ void __show_regs(struct pt_regs *regs)
95{ 95{
96 unsigned long flags; 96 unsigned long flags;
97 char buf[64]; 97 char buf[64];
98#ifndef CONFIG_CPU_V7M
99 unsigned int domain;
100#ifdef CONFIG_CPU_SW_DOMAIN_PAN
101 /*
102 * Get the domain register for the parent context. In user
103 * mode, we don't save the DACR, so lets use what it should
104 * be. For other modes, we place it after the pt_regs struct.
105 */
106 if (user_mode(regs))
107 domain = DACR_UACCESS_ENABLE;
108 else
109 domain = *(unsigned int *)(regs + 1);
110#else
111 domain = get_domain();
112#endif
113#endif
98 114
99 show_regs_print_info(KERN_DEFAULT); 115 show_regs_print_info(KERN_DEFAULT);
100 116
@@ -123,21 +139,8 @@ void __show_regs(struct pt_regs *regs)
123 139
124#ifndef CONFIG_CPU_V7M 140#ifndef CONFIG_CPU_V7M
125 { 141 {
126 unsigned int domain = get_domain();
127 const char *segment; 142 const char *segment;
128 143
129#ifdef CONFIG_CPU_SW_DOMAIN_PAN
130 /*
131 * Get the domain register for the parent context. In user
132 * mode, we don't save the DACR, so lets use what it should
133 * be. For other modes, we place it after the pt_regs struct.
134 */
135 if (user_mode(regs))
136 domain = DACR_UACCESS_ENABLE;
137 else
138 domain = *(unsigned int *)(regs + 1);
139#endif
140
141 if ((domain & domain_mask(DOMAIN_USER)) == 144 if ((domain & domain_mask(DOMAIN_USER)) ==
142 domain_val(DOMAIN_USER, DOMAIN_NOACCESS)) 145 domain_val(DOMAIN_USER, DOMAIN_NOACCESS))
143 segment = "none"; 146 segment = "none";
@@ -163,11 +166,11 @@ void __show_regs(struct pt_regs *regs)
163 buf[0] = '\0'; 166 buf[0] = '\0';
164#ifdef CONFIG_CPU_CP15_MMU 167#ifdef CONFIG_CPU_CP15_MMU
165 { 168 {
166 unsigned int transbase, dac = get_domain(); 169 unsigned int transbase;
167 asm("mrc p15, 0, %0, c2, c0\n\t" 170 asm("mrc p15, 0, %0, c2, c0\n\t"
168 : "=r" (transbase)); 171 : "=r" (transbase));
169 snprintf(buf, sizeof(buf), " Table: %08x DAC: %08x", 172 snprintf(buf, sizeof(buf), " Table: %08x DAC: %08x",
170 transbase, dac); 173 transbase, domain);
171 } 174 }
172#endif 175#endif
173 asm("mrc p15, 0, %0, c1, c0\n" : "=r" (ctrl)); 176 asm("mrc p15, 0, %0, c1, c0\n" : "=r" (ctrl));
diff --git a/arch/arm/kernel/swp_emulate.c b/arch/arm/kernel/swp_emulate.c
index 5b26e7efa9ea..c3fe769d7558 100644
--- a/arch/arm/kernel/swp_emulate.c
+++ b/arch/arm/kernel/swp_emulate.c
@@ -36,10 +36,10 @@
36 */ 36 */
37#define __user_swpX_asm(data, addr, res, temp, B) \ 37#define __user_swpX_asm(data, addr, res, temp, B) \
38 __asm__ __volatile__( \ 38 __asm__ __volatile__( \
39 " mov %2, %1\n" \ 39 "0: ldrex"B" %2, [%3]\n" \
40 "0: ldrex"B" %1, [%3]\n" \ 40 "1: strex"B" %0, %1, [%3]\n" \
41 "1: strex"B" %0, %2, [%3]\n" \
42 " cmp %0, #0\n" \ 41 " cmp %0, #0\n" \
42 " moveq %1, %2\n" \
43 " movne %0, %4\n" \ 43 " movne %0, %4\n" \
44 "2:\n" \ 44 "2:\n" \
45 " .section .text.fixup,\"ax\"\n" \ 45 " .section .text.fixup,\"ax\"\n" \
diff --git a/arch/arm/lib/uaccess_with_memcpy.c b/arch/arm/lib/uaccess_with_memcpy.c
index d72b90905132..588bbc288396 100644
--- a/arch/arm/lib/uaccess_with_memcpy.c
+++ b/arch/arm/lib/uaccess_with_memcpy.c
@@ -88,6 +88,7 @@ pin_page_for_write(const void __user *_addr, pte_t **ptep, spinlock_t **ptlp)
88static unsigned long noinline 88static unsigned long noinline
89__copy_to_user_memcpy(void __user *to, const void *from, unsigned long n) 89__copy_to_user_memcpy(void __user *to, const void *from, unsigned long n)
90{ 90{
91 unsigned long ua_flags;
91 int atomic; 92 int atomic;
92 93
93 if (unlikely(segment_eq(get_fs(), KERNEL_DS))) { 94 if (unlikely(segment_eq(get_fs(), KERNEL_DS))) {
@@ -118,7 +119,9 @@ __copy_to_user_memcpy(void __user *to, const void *from, unsigned long n)
118 if (tocopy > n) 119 if (tocopy > n)
119 tocopy = n; 120 tocopy = n;
120 121
122 ua_flags = uaccess_save_and_enable();
121 memcpy((void *)to, from, tocopy); 123 memcpy((void *)to, from, tocopy);
124 uaccess_restore(ua_flags);
122 to += tocopy; 125 to += tocopy;
123 from += tocopy; 126 from += tocopy;
124 n -= tocopy; 127 n -= tocopy;
@@ -145,14 +148,21 @@ arm_copy_to_user(void __user *to, const void *from, unsigned long n)
145 * With frame pointer disabled, tail call optimization kicks in 148 * With frame pointer disabled, tail call optimization kicks in
146 * as well making this test almost invisible. 149 * as well making this test almost invisible.
147 */ 150 */
148 if (n < 64) 151 if (n < 64) {
149 return __copy_to_user_std(to, from, n); 152 unsigned long ua_flags = uaccess_save_and_enable();
150 return __copy_to_user_memcpy(to, from, n); 153 n = __copy_to_user_std(to, from, n);
154 uaccess_restore(ua_flags);
155 } else {
156 n = __copy_to_user_memcpy(to, from, n);
157 }
158 return n;
151} 159}
152 160
153static unsigned long noinline 161static unsigned long noinline
154__clear_user_memset(void __user *addr, unsigned long n) 162__clear_user_memset(void __user *addr, unsigned long n)
155{ 163{
164 unsigned long ua_flags;
165
156 if (unlikely(segment_eq(get_fs(), KERNEL_DS))) { 166 if (unlikely(segment_eq(get_fs(), KERNEL_DS))) {
157 memset((void *)addr, 0, n); 167 memset((void *)addr, 0, n);
158 return 0; 168 return 0;
@@ -175,7 +185,9 @@ __clear_user_memset(void __user *addr, unsigned long n)
175 if (tocopy > n) 185 if (tocopy > n)
176 tocopy = n; 186 tocopy = n;
177 187
188 ua_flags = uaccess_save_and_enable();
178 memset((void *)addr, 0, tocopy); 189 memset((void *)addr, 0, tocopy);
190 uaccess_restore(ua_flags);
179 addr += tocopy; 191 addr += tocopy;
180 n -= tocopy; 192 n -= tocopy;
181 193
@@ -193,9 +205,14 @@ out:
193unsigned long arm_clear_user(void __user *addr, unsigned long n) 205unsigned long arm_clear_user(void __user *addr, unsigned long n)
194{ 206{
195 /* See rational for this in __copy_to_user() above. */ 207 /* See rational for this in __copy_to_user() above. */
196 if (n < 64) 208 if (n < 64) {
197 return __clear_user_std(addr, n); 209 unsigned long ua_flags = uaccess_save_and_enable();
198 return __clear_user_memset(addr, n); 210 n = __clear_user_std(addr, n);
211 uaccess_restore(ua_flags);
212 } else {
213 n = __clear_user_memset(addr, n);
214 }
215 return n;
199} 216}
200 217
201#if 0 218#if 0
diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c
index 845769e41332..c8c8b9ed02e0 100644
--- a/arch/arm/mm/context.c
+++ b/