diff options
-rw-r--r-- | arch/metag/include/asm/uaccess.h | 58 | ||||
-rw-r--r-- | arch/metag/lib/usercopy.c | 236 | ||||
-rw-r--r-- | arch/metag/mm/mmu-meta1.c | 1 |
3 files changed, 143 insertions, 152 deletions
diff --git a/arch/metag/include/asm/uaccess.h b/arch/metag/include/asm/uaccess.h index 5ebc2850690e..9c8fbf8fb5aa 100644 --- a/arch/metag/include/asm/uaccess.h +++ b/arch/metag/include/asm/uaccess.h | |||
@@ -24,24 +24,32 @@ | |||
24 | 24 | ||
25 | #define segment_eq(a, b) ((a).seg == (b).seg) | 25 | #define segment_eq(a, b) ((a).seg == (b).seg) |
26 | 26 | ||
27 | #define __kernel_ok (uaccess_kernel()) | ||
28 | /* | ||
29 | * Explicitly allow NULL pointers here. Parts of the kernel such | ||
30 | * as readv/writev use access_ok to validate pointers, but want | ||
31 | * to allow NULL pointers for various reasons. NULL pointers are | ||
32 | * safe to allow through because the first page is not mappable on | ||
33 | * Meta. | ||
34 | * | ||
35 | * We also wish to avoid letting user code access the system area | ||
36 | * and the kernel half of the address space. | ||
37 | */ | ||
38 | #define __user_bad(addr, size) (((addr) > 0 && (addr) < META_MEMORY_BASE) || \ | ||
39 | ((addr) > PAGE_OFFSET && \ | ||
40 | (addr) < LINCORE_BASE)) | ||
41 | |||
42 | static inline int __access_ok(unsigned long addr, unsigned long size) | 27 | static inline int __access_ok(unsigned long addr, unsigned long size) |
43 | { | 28 | { |
44 | return __kernel_ok || !__user_bad(addr, size); | 29 | /* |
30 | * Allow access to the user mapped memory area, but not the system area | ||
31 | * before it. The check extends to the top of the address space when | ||
32 | * kernel access is allowed (there's no real reason to user copy to the | ||
33 | * system area in any case). | ||
34 | */ | ||
35 | if (likely(addr >= META_MEMORY_BASE && addr < get_fs().seg && | ||
36 | size <= get_fs().seg - addr)) | ||
37 | return true; | ||
38 | /* | ||
39 | * Explicitly allow NULL pointers here. Parts of the kernel such | ||
40 | * as readv/writev use access_ok to validate pointers, but want | ||
41 | * to allow NULL pointers for various reasons. NULL pointers are | ||
42 | * safe to allow through because the first page is not mappable on | ||
43 | * Meta. | ||
44 | */ | ||
45 | if (!addr) | ||
46 | return true; | ||
47 | /* Allow access to core code memory area... */ | ||
48 | if (addr >= LINCORE_CODE_BASE && addr <= LINCORE_CODE_LIMIT && | ||
49 | size <= LINCORE_CODE_LIMIT + 1 - addr) | ||
50 | return true; | ||
51 | /* ... but no other areas. */ | ||
52 | return false; | ||
45 | } | 53 | } |
46 | 54 | ||
47 | #define access_ok(type, addr, size) __access_ok((unsigned long)(addr), \ | 55 | #define access_ok(type, addr, size) __access_ok((unsigned long)(addr), \ |
@@ -113,7 +121,8 @@ extern long __get_user_bad(void); | |||
113 | 121 | ||
114 | #define __get_user_nocheck(x, ptr, size) \ | 122 | #define __get_user_nocheck(x, ptr, size) \ |
115 | ({ \ | 123 | ({ \ |
116 | long __gu_err, __gu_val; \ | 124 | long __gu_err; \ |
125 | long long __gu_val; \ | ||
117 | __get_user_size(__gu_val, (ptr), (size), __gu_err); \ | 126 | __get_user_size(__gu_val, (ptr), (size), __gu_err); \ |
118 | (x) = (__force __typeof__(*(ptr)))__gu_val; \ | 127 | (x) = (__force __typeof__(*(ptr)))__gu_val; \ |
119 | __gu_err; \ | 128 | __gu_err; \ |
@@ -121,7 +130,8 @@ extern long __get_user_bad(void); | |||
121 | 130 | ||
122 | #define __get_user_check(x, ptr, size) \ | 131 | #define __get_user_check(x, ptr, size) \ |
123 | ({ \ | 132 | ({ \ |
124 | long __gu_err = -EFAULT, __gu_val = 0; \ | 133 | long __gu_err = -EFAULT; \ |
134 | long long __gu_val = 0; \ | ||
125 | const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \ | 135 | const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \ |
126 | if (access_ok(VERIFY_READ, __gu_addr, size)) \ | 136 | if (access_ok(VERIFY_READ, __gu_addr, size)) \ |
127 | __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \ | 137 | __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \ |
@@ -132,6 +142,7 @@ extern long __get_user_bad(void); | |||
132 | extern unsigned char __get_user_asm_b(const void __user *addr, long *err); | 142 | extern unsigned char __get_user_asm_b(const void __user *addr, long *err); |
133 | extern unsigned short __get_user_asm_w(const void __user *addr, long *err); | 143 | extern unsigned short __get_user_asm_w(const void __user *addr, long *err); |
134 | extern unsigned int __get_user_asm_d(const void __user *addr, long *err); | 144 | extern unsigned int __get_user_asm_d(const void __user *addr, long *err); |
145 | extern unsigned long long __get_user_asm_l(const void __user *addr, long *err); | ||
135 | 146 | ||
136 | #define __get_user_size(x, ptr, size, retval) \ | 147 | #define __get_user_size(x, ptr, size, retval) \ |
137 | do { \ | 148 | do { \ |
@@ -143,6 +154,8 @@ do { \ | |||
143 | x = __get_user_asm_w(ptr, &retval); break; \ | 154 | x = __get_user_asm_w(ptr, &retval); break; \ |
144 | case 4: \ | 155 | case 4: \ |
145 | x = __get_user_asm_d(ptr, &retval); break; \ | 156 | x = __get_user_asm_d(ptr, &retval); break; \ |
157 | case 8: \ | ||
158 | x = __get_user_asm_l(ptr, &retval); break; \ | ||
146 | default: \ | 159 | default: \ |
147 | (x) = __get_user_bad(); \ | 160 | (x) = __get_user_bad(); \ |
148 | } \ | 161 | } \ |
@@ -161,8 +174,13 @@ do { \ | |||
161 | extern long __must_check __strncpy_from_user(char *dst, const char __user *src, | 174 | extern long __must_check __strncpy_from_user(char *dst, const char __user *src, |
162 | long count); | 175 | long count); |
163 | 176 | ||
164 | #define strncpy_from_user(dst, src, count) __strncpy_from_user(dst, src, count) | 177 | static inline long |
165 | 178 | strncpy_from_user(char *dst, const char __user *src, long count) | |
179 | { | ||
180 | if (!access_ok(VERIFY_READ, src, 1)) | ||
181 | return -EFAULT; | ||
182 | return __strncpy_from_user(dst, src, count); | ||
183 | } | ||
166 | /* | 184 | /* |
167 | * Return the size of a string (including the ending 0) | 185 | * Return the size of a string (including the ending 0) |
168 | * | 186 | * |
diff --git a/arch/metag/lib/usercopy.c b/arch/metag/lib/usercopy.c index e8a4ea83cabb..c941abdb8f85 100644 --- a/arch/metag/lib/usercopy.c +++ b/arch/metag/lib/usercopy.c | |||
@@ -246,65 +246,47 @@ | |||
246 | #define __asm_copy_user_64bit_rapf_loop( \ | 246 | #define __asm_copy_user_64bit_rapf_loop( \ |
247 | to, from, ret, n, id, FIXUP) \ | 247 | to, from, ret, n, id, FIXUP) \ |
248 | asm volatile ( \ | 248 | asm volatile ( \ |
249 | ".balign 8\n" \ | 249 | ".balign 8\n" \ |
250 | "MOV RAPF, %1\n" \ | 250 | " MOV RAPF, %1\n" \ |
251 | "MSETL [A0StP++], D0Ar6, D0FrT, D0.5, D0.6, D0.7\n" \ | 251 | " MSETL [A0StP++], D0Ar6, D0FrT, D0.5, D0.6, D0.7\n" \ |
252 | "MOV D0Ar6, #0\n" \ | 252 | " MOV D0Ar6, #0\n" \ |
253 | "LSR D1Ar5, %3, #6\n" \ | 253 | " LSR D1Ar5, %3, #6\n" \ |
254 | "SUB TXRPT, D1Ar5, #2\n" \ | 254 | " SUB TXRPT, D1Ar5, #2\n" \ |
255 | "MOV RAPF, %1\n" \ | 255 | " MOV RAPF, %1\n" \ |
256 | "$Lloop"id":\n" \ | 256 | "$Lloop"id":\n" \ |
257 | "ADD RAPF, %1, #64\n" \ | 257 | " ADD RAPF, %1, #64\n" \ |
258 | "21:\n" \ | 258 | "21: MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ |
259 | "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ | 259 | "22: MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ |
260 | "22:\n" \ | 260 | "23: SUB %3, %3, #32\n" \ |
261 | "MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ | 261 | "24: MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ |
262 | "23:\n" \ | 262 | "25: MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ |
263 | "SUB %3, %3, #32\n" \ | 263 | "26: SUB %3, %3, #32\n" \ |
264 | "24:\n" \ | 264 | " DCACHE [%1+#-64], D0Ar6\n" \ |
265 | "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ | 265 | " BR $Lloop"id"\n" \ |
266 | "25:\n" \ | ||
267 | "MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ | ||
268 | "26:\n" \ | ||
269 | "SUB %3, %3, #32\n" \ | ||
270 | "DCACHE [%1+#-64], D0Ar6\n" \ | ||
271 | "BR $Lloop"id"\n" \ | ||
272 | \ | 266 | \ |
273 | "MOV RAPF, %1\n" \ | 267 | " MOV RAPF, %1\n" \ |
274 | "27:\n" \ | 268 | "27: MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ |
275 | "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ | 269 | "28: MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ |
276 | "28:\n" \ | 270 | "29: SUB %3, %3, #32\n" \ |
277 | "MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ | 271 | "30: MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ |
278 | "29:\n" \ | 272 | "31: MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ |
279 | "SUB %3, %3, #32\n" \ | 273 | "32: SETL [%0+#-8], D0.7, D1.7\n" \ |
280 | "30:\n" \ | 274 | " SUB %3, %3, #32\n" \ |
281 | "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ | 275 | "1: DCACHE [%1+#-64], D0Ar6\n" \ |
282 | "31:\n" \ | 276 | " GETL D0Ar6, D1Ar5, [A0StP+#-40]\n" \ |
283 | "MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ | 277 | " GETL D0FrT, D1RtP, [A0StP+#-32]\n" \ |
284 | "32:\n" \ | 278 | " GETL D0.5, D1.5, [A0StP+#-24]\n" \ |
285 | "SUB %0, %0, #8\n" \ | 279 | " GETL D0.6, D1.6, [A0StP+#-16]\n" \ |
286 | "33:\n" \ | 280 | " GETL D0.7, D1.7, [A0StP+#-8]\n" \ |
287 | "SETL [%0++], D0.7, D1.7\n" \ | 281 | " SUB A0StP, A0StP, #40\n" \ |
288 | "SUB %3, %3, #32\n" \ | ||
289 | "1:" \ | ||
290 | "DCACHE [%1+#-64], D0Ar6\n" \ | ||
291 | "GETL D0Ar6, D1Ar5, [A0StP+#-40]\n" \ | ||
292 | "GETL D0FrT, D1RtP, [A0StP+#-32]\n" \ | ||
293 | "GETL D0.5, D1.5, [A0StP+#-24]\n" \ | ||
294 | "GETL D0.6, D1.6, [A0StP+#-16]\n" \ | ||
295 | "GETL D0.7, D1.7, [A0StP+#-8]\n" \ | ||
296 | "SUB A0StP, A0StP, #40\n" \ | ||
297 | " .section .fixup,\"ax\"\n" \ | 282 | " .section .fixup,\"ax\"\n" \ |
298 | "4:\n" \ | 283 | "3: MOV D0Ar2, TXSTATUS\n" \ |
299 | " ADD %0, %0, #8\n" \ | ||
300 | "3:\n" \ | ||
301 | " MOV D0Ar2, TXSTATUS\n" \ | ||
302 | " MOV D1Ar1, TXSTATUS\n" \ | 284 | " MOV D1Ar1, TXSTATUS\n" \ |
303 | " AND D1Ar1, D1Ar1, #0xFFFFF8FF\n" \ | 285 | " AND D1Ar1, D1Ar1, #0xFFFFF8FF\n" \ |
304 | " MOV TXSTATUS, D1Ar1\n" \ | 286 | " MOV TXSTATUS, D1Ar1\n" \ |
305 | FIXUP \ | 287 | FIXUP \ |
306 | " MOVT D0Ar2,#HI(1b)\n" \ | 288 | " MOVT D0Ar2, #HI(1b)\n" \ |
307 | " JUMP D0Ar2,#LO(1b)\n" \ | 289 | " JUMP D0Ar2, #LO(1b)\n" \ |
308 | " .previous\n" \ | 290 | " .previous\n" \ |
309 | " .section __ex_table,\"a\"\n" \ | 291 | " .section __ex_table,\"a\"\n" \ |
310 | " .long 21b,3b\n" \ | 292 | " .long 21b,3b\n" \ |
@@ -319,7 +301,6 @@ | |||
319 | " .long 30b,3b\n" \ | 301 | " .long 30b,3b\n" \ |
320 | " .long 31b,3b\n" \ | 302 | " .long 31b,3b\n" \ |
321 | " .long 32b,3b\n" \ | 303 | " .long 32b,3b\n" \ |
322 | " .long 33b,4b\n" \ | ||
323 | " .previous\n" \ | 304 | " .previous\n" \ |
324 | : "=r" (to), "=r" (from), "=r" (ret), "=d" (n) \ | 305 | : "=r" (to), "=r" (from), "=r" (ret), "=d" (n) \ |
325 | : "0" (to), "1" (from), "2" (ret), "3" (n) \ | 306 | : "0" (to), "1" (from), "2" (ret), "3" (n) \ |
@@ -397,89 +378,59 @@ | |||
397 | #define __asm_copy_user_32bit_rapf_loop( \ | 378 | #define __asm_copy_user_32bit_rapf_loop( \ |
398 | to, from, ret, n, id, FIXUP) \ | 379 | to, from, ret, n, id, FIXUP) \ |
399 | asm volatile ( \ | 380 | asm volatile ( \ |
400 | ".balign 8\n" \ | 381 | ".balign 8\n" \ |
401 | "MOV RAPF, %1\n" \ | 382 | " MOV RAPF, %1\n" \ |
402 | "MSETL [A0StP++], D0Ar6, D0FrT, D0.5, D0.6, D0.7\n" \ | 383 | " MSETL [A0StP++], D0Ar6, D0FrT, D0.5, D0.6, D0.7\n" \ |
403 | "MOV D0Ar6, #0\n" \ | 384 | " MOV D0Ar6, #0\n" \ |
404 | "LSR D1Ar5, %3, #6\n" \ | 385 | " LSR D1Ar5, %3, #6\n" \ |
405 | "SUB TXRPT, D1Ar5, #2\n" \ | 386 | " SUB TXRPT, D1Ar5, #2\n" \ |
406 | "MOV RAPF, %1\n" \ | 387 | " MOV RAPF, %1\n" \ |
407 | "$Lloop"id":\n" \ | 388 | "$Lloop"id":\n" \ |
408 | "ADD RAPF, %1, #64\n" \ | 389 | " ADD RAPF, %1, #64\n" \ |
409 | "21:\n" \ | 390 | "21: MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ |
410 | "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ | 391 | "22: MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ |
411 | "22:\n" \ | 392 | "23: SUB %3, %3, #16\n" \ |
412 | "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ | 393 | "24: MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ |
413 | "23:\n" \ | 394 | "25: MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ |
414 | "SUB %3, %3, #16\n" \ | 395 | "26: SUB %3, %3, #16\n" \ |
415 | "24:\n" \ | 396 | "27: MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ |
416 | "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ | 397 | "28: MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ |
417 | "25:\n" \ | 398 | "29: SUB %3, %3, #16\n" \ |
418 | "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ | 399 | "30: MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ |
419 | "26:\n" \ | 400 | "31: MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ |
420 | "SUB %3, %3, #16\n" \ | 401 | "32: SUB %3, %3, #16\n" \ |
421 | "27:\n" \ | 402 | " DCACHE [%1+#-64], D0Ar6\n" \ |
422 | "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ | 403 | " BR $Lloop"id"\n" \ |
423 | "28:\n" \ | ||
424 | "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ | ||
425 | "29:\n" \ | ||
426 | "SUB %3, %3, #16\n" \ | ||
427 | "30:\n" \ | ||
428 | "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ | ||
429 | "31:\n" \ | ||
430 | "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ | ||
431 | "32:\n" \ | ||
432 | "SUB %3, %3, #16\n" \ | ||
433 | "DCACHE [%1+#-64], D0Ar6\n" \ | ||
434 | "BR $Lloop"id"\n" \ | ||
435 | \ | 404 | \ |
436 | "MOV RAPF, %1\n" \ | 405 | " MOV RAPF, %1\n" \ |
437 | "33:\n" \ | 406 | "33: MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ |
438 | "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ | 407 | "34: MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ |
439 | "34:\n" \ | 408 | "35: SUB %3, %3, #16\n" \ |
440 | "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ | 409 | "36: MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ |
441 | "35:\n" \ | 410 | "37: MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ |
442 | "SUB %3, %3, #16\n" \ | 411 | "38: SUB %3, %3, #16\n" \ |
443 | "36:\n" \ | 412 | "39: MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ |
444 | "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ | 413 | "40: MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ |
445 | "37:\n" \ | 414 | "41: SUB %3, %3, #16\n" \ |
446 | "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ | 415 | "42: MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ |
447 | "38:\n" \ | 416 | "43: MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ |
448 | "SUB %3, %3, #16\n" \ | 417 | "44: SETD [%0+#-4], D0.7\n" \ |
449 | "39:\n" \ | 418 | " SUB %3, %3, #16\n" \ |
450 | "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ | 419 | "1: DCACHE [%1+#-64], D0Ar6\n" \ |
451 | "40:\n" \ | 420 | " GETL D0Ar6, D1Ar5, [A0StP+#-40]\n" \ |
452 | "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ | 421 | " GETL D0FrT, D1RtP, [A0StP+#-32]\n" \ |
453 | "41:\n" \ | 422 | " GETL D0.5, D1.5, [A0StP+#-24]\n" \ |
454 | "SUB %3, %3, #16\n" \ | 423 | " GETL D0.6, D1.6, [A0StP+#-16]\n" \ |
455 | "42:\n" \ | 424 | " GETL D0.7, D1.7, [A0StP+#-8]\n" \ |
456 | "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ | 425 | " SUB A0StP, A0StP, #40\n" \ |
457 | "43:\n" \ | ||
458 | "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ | ||
459 | "44:\n" \ | ||
460 | "SUB %0, %0, #4\n" \ | ||
461 | "45:\n" \ | ||
462 | "SETD [%0++], D0.7\n" \ | ||
463 | "SUB %3, %3, #16\n" \ | ||
464 | "1:" \ | ||
465 | "DCACHE [%1+#-64], D0Ar6\n" \ | ||
466 | "GETL D0Ar6, D1Ar5, [A0StP+#-40]\n" \ | ||
467 | "GETL D0FrT, D1RtP, [A0StP+#-32]\n" \ | ||
468 | "GETL D0.5, D1.5, [A0StP+#-24]\n" \ | ||
469 | "GETL D0.6, D1.6, [A0StP+#-16]\n" \ | ||
470 | "GETL D0.7, D1.7, [A0StP+#-8]\n" \ | ||
471 | "SUB A0StP, A0StP, #40\n" \ | ||
472 | " .section .fixup,\"ax\"\n" \ | 426 | " .section .fixup,\"ax\"\n" \ |
473 | "4:\n" \ | 427 | "3: MOV D0Ar2, TXSTATUS\n" \ |
474 | " ADD %0, %0, #4\n" \ | ||
475 | "3:\n" \ | ||
476 | " MOV D0Ar2, TXSTATUS\n" \ | ||
477 | " MOV D1Ar1, TXSTATUS\n" \ | 428 | " MOV D1Ar1, TXSTATUS\n" \ |
478 | " AND D1Ar1, D1Ar1, #0xFFFFF8FF\n" \ | 429 | " AND D1Ar1, D1Ar1, #0xFFFFF8FF\n" \ |
479 | " MOV TXSTATUS, D1Ar1\n" \ | 430 | " MOV TXSTATUS, D1Ar1\n" \ |
480 | FIXUP \ | 431 | FIXUP \ |
481 | " MOVT D0Ar2,#HI(1b)\n" \ | 432 | " MOVT D0Ar2, #HI(1b)\n" \ |
482 | " JUMP D0Ar2,#LO(1b)\n" \ | 433 | " JUMP D0Ar2, #LO(1b)\n" \ |
483 | " .previous\n" \ | 434 | " .previous\n" \ |
484 | " .section __ex_table,\"a\"\n" \ | 435 | " .section __ex_table,\"a\"\n" \ |
485 | " .long 21b,3b\n" \ | 436 | " .long 21b,3b\n" \ |
@@ -506,7 +457,6 @@ | |||
506 | " .long 42b,3b\n" \ | 457 | " .long 42b,3b\n" \ |
507 | " .long 43b,3b\n" \ | 458 | " .long 43b,3b\n" \ |
508 | " .long 44b,3b\n" \ | 459 | " .long 44b,3b\n" \ |
509 | " .long 45b,4b\n" \ | ||
510 | " .previous\n" \ | 460 | " .previous\n" \ |
511 | : "=r" (to), "=r" (from), "=r" (ret), "=d" (n) \ | 461 | : "=r" (to), "=r" (from), "=r" (ret), "=d" (n) \ |
512 | : "0" (to), "1" (from), "2" (ret), "3" (n) \ | 462 | : "0" (to), "1" (from), "2" (ret), "3" (n) \ |
@@ -1094,6 +1044,30 @@ unsigned int __get_user_asm_d(const void __user *addr, long *err) | |||
1094 | } | 1044 | } |
1095 | EXPORT_SYMBOL(__get_user_asm_d); | 1045 | EXPORT_SYMBOL(__get_user_asm_d); |
1096 | 1046 | ||
1047 | unsigned long long __get_user_asm_l(const void __user *addr, long *err) | ||
1048 | { | ||
1049 | register unsigned long long x asm ("D0Re0") = 0; | ||
1050 | asm volatile ( | ||
1051 | " GETL %0,%t0,[%2]\n" | ||
1052 | "1:\n" | ||
1053 | " GETL %0,%t0,[%2]\n" | ||
1054 | "2:\n" | ||
1055 | " .section .fixup,\"ax\"\n" | ||
1056 | "3: MOV D0FrT,%3\n" | ||
1057 | " SETD [%1],D0FrT\n" | ||
1058 | " MOVT D0FrT,#HI(2b)\n" | ||
1059 | " JUMP D0FrT,#LO(2b)\n" | ||
1060 | " .previous\n" | ||
1061 | " .section __ex_table,\"a\"\n" | ||
1062 | " .long 1b,3b\n" | ||
1063 | " .previous\n" | ||
1064 | : "=r" (x) | ||
1065 | : "r" (err), "r" (addr), "P" (-EFAULT) | ||
1066 | : "D0FrT"); | ||
1067 | return x; | ||
1068 | } | ||
1069 | EXPORT_SYMBOL(__get_user_asm_l); | ||
1070 | |||
1097 | long __put_user_asm_b(unsigned int x, void __user *addr) | 1071 | long __put_user_asm_b(unsigned int x, void __user *addr) |
1098 | { | 1072 | { |
1099 | register unsigned int err asm ("D0Re0") = 0; | 1073 | register unsigned int err asm ("D0Re0") = 0; |
diff --git a/arch/metag/mm/mmu-meta1.c b/arch/metag/mm/mmu-meta1.c index 91f4255bcb5c..62ebab90924d 100644 --- a/arch/metag/mm/mmu-meta1.c +++ b/arch/metag/mm/mmu-meta1.c | |||
@@ -152,6 +152,5 @@ void __init mmu_init(unsigned long mem_end) | |||
152 | 152 | ||
153 | p_swapper_pg_dir++; | 153 | p_swapper_pg_dir++; |
154 | addr += PGDIR_SIZE; | 154 | addr += PGDIR_SIZE; |
155 | entry++; | ||
156 | } | 155 | } |
157 | } | 156 | } |