aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorWill Deacon <will.deacon@arm.com>2012-09-07 13:24:10 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2012-09-09 12:28:48 -0400
commitad72907acd2943304c292ae36960bb66e6dc23c9 (patch)
treed9f09ddcb8c4bc8d5a3885c89bc28942bd2e33bd /arch/arm
parent8404663f81d212918ff85f493649a7991209fa04 (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.h18
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
144extern int __put_user_1(void *, unsigned int); 150extern int __put_user_1(void *, unsigned int);
145extern int __put_user_2(void *, unsigned int); 151extern int __put_user_2(void *, unsigned int);
146extern int __put_user_4(void *, unsigned int); 152extern 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; \