diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/asm-i386/uaccess.h | 33 | ||||
-rw-r--r-- | include/linux/uaccess.h | 22 |
2 files changed, 55 insertions, 0 deletions
diff --git a/include/asm-i386/uaccess.h b/include/asm-i386/uaccess.h index 1ec65523ea..82af28a943 100644 --- a/include/asm-i386/uaccess.h +++ b/include/asm-i386/uaccess.h | |||
@@ -390,6 +390,8 @@ unsigned long __must_check __copy_to_user_ll(void __user *to, | |||
390 | const void *from, unsigned long n); | 390 | const void *from, unsigned long n); |
391 | unsigned long __must_check __copy_from_user_ll(void *to, | 391 | unsigned long __must_check __copy_from_user_ll(void *to, |
392 | const void __user *from, unsigned long n); | 392 | const void __user *from, unsigned long n); |
393 | unsigned long __must_check __copy_from_user_ll_nocache(void *to, | ||
394 | const void __user *from, unsigned long n); | ||
393 | 395 | ||
394 | /* | 396 | /* |
395 | * Here we special-case 1, 2 and 4-byte copy_*_user invocations. On a fault | 397 | * Here we special-case 1, 2 and 4-byte copy_*_user invocations. On a fault |
@@ -478,12 +480,43 @@ __copy_from_user_inatomic(void *to, const void __user *from, unsigned long n) | |||
478 | return __copy_from_user_ll(to, from, n); | 480 | return __copy_from_user_ll(to, from, n); |
479 | } | 481 | } |
480 | 482 | ||
483 | #define ARCH_HAS_NOCACHE_UACCESS | ||
484 | |||
485 | static __always_inline unsigned long __copy_from_user_inatomic_nocache(void *to, | ||
486 | const void __user *from, unsigned long n) | ||
487 | { | ||
488 | if (__builtin_constant_p(n)) { | ||
489 | unsigned long ret; | ||
490 | |||
491 | switch (n) { | ||
492 | case 1: | ||
493 | __get_user_size(*(u8 *)to, from, 1, ret, 1); | ||
494 | return ret; | ||
495 | case 2: | ||
496 | __get_user_size(*(u16 *)to, from, 2, ret, 2); | ||
497 | return ret; | ||
498 | case 4: | ||
499 | __get_user_size(*(u32 *)to, from, 4, ret, 4); | ||
500 | return ret; | ||
501 | } | ||
502 | } | ||
503 | return __copy_from_user_ll_nocache(to, from, n); | ||
504 | } | ||
505 | |||
481 | static __always_inline unsigned long | 506 | static __always_inline unsigned long |
482 | __copy_from_user(void *to, const void __user *from, unsigned long n) | 507 | __copy_from_user(void *to, const void __user *from, unsigned long n) |
483 | { | 508 | { |
484 | might_sleep(); | 509 | might_sleep(); |
485 | return __copy_from_user_inatomic(to, from, n); | 510 | return __copy_from_user_inatomic(to, from, n); |
486 | } | 511 | } |
512 | |||
513 | static __always_inline unsigned long | ||
514 | __copy_from_user_nocache(void *to, const void __user *from, unsigned long n) | ||
515 | { | ||
516 | might_sleep(); | ||
517 | return __copy_from_user_inatomic_nocache(to, from, n); | ||
518 | } | ||
519 | |||
487 | unsigned long __must_check copy_to_user(void __user *to, | 520 | unsigned long __must_check copy_to_user(void __user *to, |
488 | const void *from, unsigned long n); | 521 | const void *from, unsigned long n); |
489 | unsigned long __must_check copy_from_user(void *to, | 522 | unsigned long __must_check copy_from_user(void *to, |
diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h new file mode 100644 index 0000000000..391e7ed1eb --- /dev/null +++ b/include/linux/uaccess.h | |||
@@ -0,0 +1,22 @@ | |||
1 | #ifndef __LINUX_UACCESS_H__ | ||
2 | #define __LINUX_UACCESS_H__ | ||
3 | |||
4 | #include <asm/uaccess.h> | ||
5 | |||
6 | #ifndef ARCH_HAS_NOCACHE_UACCESS | ||
7 | |||
8 | static inline unsigned long __copy_from_user_inatomic_nocache(void *to, | ||
9 | const void __user *from, unsigned long n) | ||
10 | { | ||
11 | return __copy_from_user_inatomic(to, from, n); | ||
12 | } | ||
13 | |||
14 | static inline unsigned long __copy_from_user_nocache(void *to, | ||
15 | const void __user *from, unsigned long n) | ||
16 | { | ||
17 | return __copy_from_user(to, from, n); | ||
18 | } | ||
19 | |||
20 | #endif /* ARCH_HAS_NOCACHE_UACCESS */ | ||
21 | |||
22 | #endif /* __LINUX_UACCESS_H__ */ | ||