diff options
author | Will Deacon <will.deacon@arm.com> | 2012-09-07 13:24:10 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2012-09-09 12:28:48 -0400 |
commit | ad72907acd2943304c292ae36960bb66e6dc23c9 (patch) | |
tree | d9f09ddcb8c4bc8d5a3885c89bc28942bd2e33bd /arch/arm | |
parent | 8404663f81d212918ff85f493649a7991209fa04 (diff) |
ARM: 7528/1: uaccess: annotate [__]{get,put}_user functions with might_fault()
The user access functions may generate a fault, resulting in invocation
of a handler that may sleep.
This patch annotates the accessors with might_fault() so that we print a
warning if they are invoked from atomic context and help lockdep keep
track of mmap_sem.
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/include/asm/uaccess.h | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h index 6f83ad6e4d3d..77bd79f2ffdb 100644 --- a/arch/arm/include/asm/uaccess.h +++ b/arch/arm/include/asm/uaccess.h | |||
@@ -118,7 +118,7 @@ extern int __get_user_4(void *); | |||
118 | : "0" (__p), "r" (__l) \ | 118 | : "0" (__p), "r" (__l) \ |
119 | : __GUP_CLOBBER_##__s) | 119 | : __GUP_CLOBBER_##__s) |
120 | 120 | ||
121 | #define get_user(x,p) \ | 121 | #define __get_user_check(x,p) \ |
122 | ({ \ | 122 | ({ \ |
123 | unsigned long __limit = current_thread_info()->addr_limit - 1; \ | 123 | unsigned long __limit = current_thread_info()->addr_limit - 1; \ |
124 | register const typeof(*(p)) __user *__p asm("r0") = (p);\ | 124 | register const typeof(*(p)) __user *__p asm("r0") = (p);\ |
@@ -141,6 +141,12 @@ extern int __get_user_4(void *); | |||
141 | __e; \ | 141 | __e; \ |
142 | }) | 142 | }) |
143 | 143 | ||
144 | #define get_user(x,p) \ | ||
145 | ({ \ | ||
146 | might_fault(); \ | ||
147 | __get_user_check(x,p); \ | ||
148 | }) | ||
149 | |||
144 | extern int __put_user_1(void *, unsigned int); | 150 | extern int __put_user_1(void *, unsigned int); |
145 | extern int __put_user_2(void *, unsigned int); | 151 | extern int __put_user_2(void *, unsigned int); |
146 | extern int __put_user_4(void *, unsigned int); | 152 | extern int __put_user_4(void *, unsigned int); |
@@ -155,7 +161,7 @@ extern int __put_user_8(void *, unsigned long long); | |||
155 | : "0" (__p), "r" (__r2), "r" (__l) \ | 161 | : "0" (__p), "r" (__r2), "r" (__l) \ |
156 | : "ip", "lr", "cc") | 162 | : "ip", "lr", "cc") |
157 | 163 | ||
158 | #define put_user(x,p) \ | 164 | #define __put_user_check(x,p) \ |
159 | ({ \ | 165 | ({ \ |
160 | unsigned long __limit = current_thread_info()->addr_limit - 1; \ | 166 | unsigned long __limit = current_thread_info()->addr_limit - 1; \ |
161 | register const typeof(*(p)) __r2 asm("r2") = (x); \ | 167 | register const typeof(*(p)) __r2 asm("r2") = (x); \ |
@@ -180,6 +186,12 @@ extern int __put_user_8(void *, unsigned long long); | |||
180 | __e; \ | 186 | __e; \ |
181 | }) | 187 | }) |
182 | 188 | ||
189 | #define put_user(x,p) \ | ||
190 | ({ \ | ||
191 | might_fault(); \ | ||
192 | __put_user_check(x,p); \ | ||
193 | }) | ||
194 | |||
183 | #else /* CONFIG_MMU */ | 195 | #else /* CONFIG_MMU */ |
184 | 196 | ||
185 | /* | 197 | /* |
@@ -233,6 +245,7 @@ do { \ | |||
233 | unsigned long __gu_addr = (unsigned long)(ptr); \ | 245 | unsigned long __gu_addr = (unsigned long)(ptr); \ |
234 | unsigned long __gu_val; \ | 246 | unsigned long __gu_val; \ |
235 | __chk_user_ptr(ptr); \ | 247 | __chk_user_ptr(ptr); \ |
248 | might_fault(); \ | ||
236 | switch (sizeof(*(ptr))) { \ | 249 | switch (sizeof(*(ptr))) { \ |
237 | case 1: __get_user_asm_byte(__gu_val,__gu_addr,err); break; \ | 250 | case 1: __get_user_asm_byte(__gu_val,__gu_addr,err); break; \ |
238 | case 2: __get_user_asm_half(__gu_val,__gu_addr,err); break; \ | 251 | case 2: __get_user_asm_half(__gu_val,__gu_addr,err); break; \ |
@@ -314,6 +327,7 @@ do { \ | |||
314 | unsigned long __pu_addr = (unsigned long)(ptr); \ | 327 | unsigned long __pu_addr = (unsigned long)(ptr); \ |
315 | __typeof__(*(ptr)) __pu_val = (x); \ | 328 | __typeof__(*(ptr)) __pu_val = (x); \ |
316 | __chk_user_ptr(ptr); \ | 329 | __chk_user_ptr(ptr); \ |
330 | might_fault(); \ | ||
317 | switch (sizeof(*(ptr))) { \ | 331 | switch (sizeof(*(ptr))) { \ |
318 | case 1: __put_user_asm_byte(__pu_val,__pu_addr,err); break; \ | 332 | case 1: __put_user_asm_byte(__pu_val,__pu_addr,err); break; \ |
319 | case 2: __put_user_asm_half(__pu_val,__pu_addr,err); break; \ | 333 | case 2: __put_user_asm_half(__pu_val,__pu_addr,err); break; \ |