diff options
Diffstat (limited to 'include/linux/uaccess.h')
-rw-r--r-- | include/linux/uaccess.h | 48 |
1 files changed, 35 insertions, 13 deletions
diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h index ecd3319dac33..ae572c138607 100644 --- a/include/linux/uaccess.h +++ b/include/linux/uaccess.h | |||
@@ -1,21 +1,30 @@ | |||
1 | #ifndef __LINUX_UACCESS_H__ | 1 | #ifndef __LINUX_UACCESS_H__ |
2 | #define __LINUX_UACCESS_H__ | 2 | #define __LINUX_UACCESS_H__ |
3 | 3 | ||
4 | #include <linux/preempt.h> | 4 | #include <linux/sched.h> |
5 | #include <asm/uaccess.h> | 5 | #include <asm/uaccess.h> |
6 | 6 | ||
7 | static __always_inline void pagefault_disabled_inc(void) | ||
8 | { | ||
9 | current->pagefault_disabled++; | ||
10 | } | ||
11 | |||
12 | static __always_inline void pagefault_disabled_dec(void) | ||
13 | { | ||
14 | current->pagefault_disabled--; | ||
15 | WARN_ON(current->pagefault_disabled < 0); | ||
16 | } | ||
17 | |||
7 | /* | 18 | /* |
8 | * These routines enable/disable the pagefault handler in that | 19 | * These routines enable/disable the pagefault handler. If disabled, it will |
9 | * it will not take any locks and go straight to the fixup table. | 20 | * not take any locks and go straight to the fixup table. |
10 | * | 21 | * |
11 | * They have great resemblance to the preempt_disable/enable calls | 22 | * User access methods will not sleep when called from a pagefault_disabled() |
12 | * and in fact they are identical; this is because currently there is | 23 | * environment. |
13 | * no other way to make the pagefault handlers do this. So we do | ||
14 | * disable preemption but we don't necessarily care about that. | ||
15 | */ | 24 | */ |
16 | static inline void pagefault_disable(void) | 25 | static inline void pagefault_disable(void) |
17 | { | 26 | { |
18 | preempt_count_inc(); | 27 | pagefault_disabled_inc(); |
19 | /* | 28 | /* |
20 | * make sure to have issued the store before a pagefault | 29 | * make sure to have issued the store before a pagefault |
21 | * can hit. | 30 | * can hit. |
@@ -25,18 +34,31 @@ static inline void pagefault_disable(void) | |||
25 | 34 | ||
26 | static inline void pagefault_enable(void) | 35 | static inline void pagefault_enable(void) |
27 | { | 36 | { |
28 | #ifndef CONFIG_PREEMPT | ||
29 | /* | 37 | /* |
30 | * make sure to issue those last loads/stores before enabling | 38 | * make sure to issue those last loads/stores before enabling |
31 | * the pagefault handler again. | 39 | * the pagefault handler again. |
32 | */ | 40 | */ |
33 | barrier(); | 41 | barrier(); |
34 | preempt_count_dec(); | 42 | pagefault_disabled_dec(); |
35 | #else | ||
36 | preempt_enable(); | ||
37 | #endif | ||
38 | } | 43 | } |
39 | 44 | ||
45 | /* | ||
46 | * Is the pagefault handler disabled? If so, user access methods will not sleep. | ||
47 | */ | ||
48 | #define pagefault_disabled() (current->pagefault_disabled != 0) | ||
49 | |||
50 | /* | ||
51 | * The pagefault handler is in general disabled by pagefault_disable() or | ||
52 | * when in irq context (via in_atomic()). | ||
53 | * | ||
54 | * This function should only be used by the fault handlers. Other users should | ||
55 | * stick to pagefault_disabled(). | ||
56 | * Please NEVER use preempt_disable() to disable the fault handler. With | ||
57 | * !CONFIG_PREEMPT_COUNT, this is like a NOP. So the handler won't be disabled. | ||
58 | * in_atomic() will report different values based on !CONFIG_PREEMPT_COUNT. | ||
59 | */ | ||
60 | #define faulthandler_disabled() (pagefault_disabled() || in_atomic()) | ||
61 | |||
40 | #ifndef ARCH_HAS_NOCACHE_UACCESS | 62 | #ifndef ARCH_HAS_NOCACHE_UACCESS |
41 | 63 | ||
42 | static inline unsigned long __copy_from_user_inatomic_nocache(void *to, | 64 | static inline unsigned long __copy_from_user_inatomic_nocache(void *to, |