diff options
Diffstat (limited to 'include/asm-mips/uaccess.h')
-rw-r--r-- | include/asm-mips/uaccess.h | 65 |
1 files changed, 58 insertions, 7 deletions
diff --git a/include/asm-mips/uaccess.h b/include/asm-mips/uaccess.h index 1cdd4eeb2f73..c62c20e7b5c6 100644 --- a/include/asm-mips/uaccess.h +++ b/include/asm-mips/uaccess.h | |||
@@ -265,12 +265,14 @@ do { \ | |||
265 | */ | 265 | */ |
266 | #define __get_user_asm_ll32(val, addr) \ | 266 | #define __get_user_asm_ll32(val, addr) \ |
267 | { \ | 267 | { \ |
268 | unsigned long long __gu_tmp; \ | 268 | union { \ |
269 | unsigned long long l; \ | ||
270 | __typeof__(*(addr)) t; \ | ||
271 | } __gu_tmp; \ | ||
269 | \ | 272 | \ |
270 | __asm__ __volatile__( \ | 273 | __asm__ __volatile__( \ |
271 | "1: lw %1, (%3) \n" \ | 274 | "1: lw %1, (%3) \n" \ |
272 | "2: lw %D1, 4(%3) \n" \ | 275 | "2: lw %D1, 4(%3) \n" \ |
273 | " move %0, $0 \n" \ | ||
274 | "3: .section .fixup,\"ax\" \n" \ | 276 | "3: .section .fixup,\"ax\" \n" \ |
275 | "4: li %0, %4 \n" \ | 277 | "4: li %0, %4 \n" \ |
276 | " move %1, $0 \n" \ | 278 | " move %1, $0 \n" \ |
@@ -281,9 +283,10 @@ do { \ | |||
281 | " " __UA_ADDR " 1b, 4b \n" \ | 283 | " " __UA_ADDR " 1b, 4b \n" \ |
282 | " " __UA_ADDR " 2b, 4b \n" \ | 284 | " " __UA_ADDR " 2b, 4b \n" \ |
283 | " .previous \n" \ | 285 | " .previous \n" \ |
284 | : "=r" (__gu_err), "=&r" (__gu_tmp) \ | 286 | : "=r" (__gu_err), "=&r" (__gu_tmp.l) \ |
285 | : "0" (0), "r" (addr), "i" (-EFAULT)); \ | 287 | : "0" (0), "r" (addr), "i" (-EFAULT)); \ |
286 | (val) = (__typeof__(*(addr))) __gu_tmp; \ | 288 | \ |
289 | (val) = __gu_tmp.t; \ | ||
287 | } | 290 | } |
288 | 291 | ||
289 | /* | 292 | /* |
@@ -432,8 +435,32 @@ extern size_t __copy_user(void *__to, const void *__from, size_t __n); | |||
432 | __cu_len; \ | 435 | __cu_len; \ |
433 | }) | 436 | }) |
434 | 437 | ||
435 | #define __copy_to_user_inatomic __copy_to_user | 438 | #define __copy_to_user_inatomic(to,from,n) \ |
436 | #define __copy_from_user_inatomic __copy_from_user | 439 | ({ \ |
440 | void __user *__cu_to; \ | ||
441 | const void *__cu_from; \ | ||
442 | long __cu_len; \ | ||
443 | \ | ||
444 | __cu_to = (to); \ | ||
445 | __cu_from = (from); \ | ||
446 | __cu_len = (n); \ | ||
447 | __cu_len = __invoke_copy_to_user(__cu_to, __cu_from, __cu_len); \ | ||
448 | __cu_len; \ | ||
449 | }) | ||
450 | |||
451 | #define __copy_from_user_inatomic(to,from,n) \ | ||
452 | ({ \ | ||
453 | void *__cu_to; \ | ||
454 | const void __user *__cu_from; \ | ||
455 | long __cu_len; \ | ||
456 | \ | ||
457 | __cu_to = (to); \ | ||
458 | __cu_from = (from); \ | ||
459 | __cu_len = (n); \ | ||
460 | __cu_len = __invoke_copy_from_user_inatomic(__cu_to, __cu_from, \ | ||
461 | __cu_len); \ | ||
462 | __cu_len; \ | ||
463 | }) | ||
437 | 464 | ||
438 | /* | 465 | /* |
439 | * copy_to_user: - Copy a block of data into user space. | 466 | * copy_to_user: - Copy a block of data into user space. |
@@ -487,8 +514,32 @@ extern size_t __copy_user(void *__to, const void *__from, size_t __n); | |||
487 | __cu_len_r; \ | 514 | __cu_len_r; \ |
488 | }) | 515 | }) |
489 | 516 | ||
517 | #define __invoke_copy_from_user_inatomic(to,from,n) \ | ||
518 | ({ \ | ||
519 | register void *__cu_to_r __asm__ ("$4"); \ | ||
520 | register const void __user *__cu_from_r __asm__ ("$5"); \ | ||
521 | register long __cu_len_r __asm__ ("$6"); \ | ||
522 | \ | ||
523 | __cu_to_r = (to); \ | ||
524 | __cu_from_r = (from); \ | ||
525 | __cu_len_r = (n); \ | ||
526 | __asm__ __volatile__( \ | ||
527 | ".set\tnoreorder\n\t" \ | ||
528 | __MODULE_JAL(__copy_user_inatomic) \ | ||
529 | ".set\tnoat\n\t" \ | ||
530 | __UA_ADDU "\t$1, %1, %2\n\t" \ | ||
531 | ".set\tat\n\t" \ | ||
532 | ".set\treorder" \ | ||
533 | : "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r) \ | ||
534 | : \ | ||
535 | : "$8", "$9", "$10", "$11", "$12", "$15", "$24", "$31", \ | ||
536 | "memory"); \ | ||
537 | __cu_len_r; \ | ||
538 | }) | ||
539 | |||
490 | /* | 540 | /* |
491 | * __copy_from_user: - Copy a block of data from user space, with less checking. * @to: Destination address, in kernel space. | 541 | * __copy_from_user: - Copy a block of data from user space, with less checking. |
542 | * @to: Destination address, in kernel space. | ||
492 | * @from: Source address, in user space. | 543 | * @from: Source address, in user space. |
493 | * @n: Number of bytes to copy. | 544 | * @n: Number of bytes to copy. |
494 | * | 545 | * |