Commit ad72907a authored by Will Deacon's avatar Will Deacon Committed by Russell King

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: default avatarWill Deacon <will.deacon@arm.com>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 8404663f
...@@ -118,7 +118,7 @@ extern int __get_user_4(void *); ...@@ -118,7 +118,7 @@ extern int __get_user_4(void *);
: "0" (__p), "r" (__l) \ : "0" (__p), "r" (__l) \
: __GUP_CLOBBER_##__s) : __GUP_CLOBBER_##__s)
#define get_user(x,p) \ #define __get_user_check(x,p) \
({ \ ({ \
unsigned long __limit = current_thread_info()->addr_limit - 1; \ unsigned long __limit = current_thread_info()->addr_limit - 1; \
register const typeof(*(p)) __user *__p asm("r0") = (p);\ register const typeof(*(p)) __user *__p asm("r0") = (p);\
...@@ -141,6 +141,12 @@ extern int __get_user_4(void *); ...@@ -141,6 +141,12 @@ extern int __get_user_4(void *);
__e; \ __e; \
}) })
#define get_user(x,p) \
({ \
might_fault(); \
__get_user_check(x,p); \
})
extern int __put_user_1(void *, unsigned int); extern int __put_user_1(void *, unsigned int);
extern int __put_user_2(void *, unsigned int); extern int __put_user_2(void *, unsigned int);
extern int __put_user_4(void *, unsigned int); extern int __put_user_4(void *, unsigned int);
...@@ -155,7 +161,7 @@ extern int __put_user_8(void *, unsigned long long); ...@@ -155,7 +161,7 @@ extern int __put_user_8(void *, unsigned long long);
: "0" (__p), "r" (__r2), "r" (__l) \ : "0" (__p), "r" (__r2), "r" (__l) \
: "ip", "lr", "cc") : "ip", "lr", "cc")
#define put_user(x,p) \ #define __put_user_check(x,p) \
({ \ ({ \
unsigned long __limit = current_thread_info()->addr_limit - 1; \ unsigned long __limit = current_thread_info()->addr_limit - 1; \
register const typeof(*(p)) __r2 asm("r2") = (x); \ register const typeof(*(p)) __r2 asm("r2") = (x); \
...@@ -180,6 +186,12 @@ extern int __put_user_8(void *, unsigned long long); ...@@ -180,6 +186,12 @@ extern int __put_user_8(void *, unsigned long long);
__e; \ __e; \
}) })
#define put_user(x,p) \
({ \
might_fault(); \
__put_user_check(x,p); \
})
#else /* CONFIG_MMU */ #else /* CONFIG_MMU */
/* /*
...@@ -233,6 +245,7 @@ do { \ ...@@ -233,6 +245,7 @@ do { \
unsigned long __gu_addr = (unsigned long)(ptr); \ unsigned long __gu_addr = (unsigned long)(ptr); \
unsigned long __gu_val; \ unsigned long __gu_val; \
__chk_user_ptr(ptr); \ __chk_user_ptr(ptr); \
might_fault(); \
switch (sizeof(*(ptr))) { \ switch (sizeof(*(ptr))) { \
case 1: __get_user_asm_byte(__gu_val,__gu_addr,err); break; \ case 1: __get_user_asm_byte(__gu_val,__gu_addr,err); break; \
case 2: __get_user_asm_half(__gu_val,__gu_addr,err); break; \ case 2: __get_user_asm_half(__gu_val,__gu_addr,err); break; \
...@@ -314,6 +327,7 @@ do { \ ...@@ -314,6 +327,7 @@ do { \
unsigned long __pu_addr = (unsigned long)(ptr); \ unsigned long __pu_addr = (unsigned long)(ptr); \
__typeof__(*(ptr)) __pu_val = (x); \ __typeof__(*(ptr)) __pu_val = (x); \
__chk_user_ptr(ptr); \ __chk_user_ptr(ptr); \
might_fault(); \
switch (sizeof(*(ptr))) { \ switch (sizeof(*(ptr))) { \
case 1: __put_user_asm_byte(__pu_val,__pu_addr,err); break; \ case 1: __put_user_asm_byte(__pu_val,__pu_addr,err); break; \
case 2: __put_user_asm_half(__pu_val,__pu_addr,err); break; \ case 2: __put_user_asm_half(__pu_val,__pu_addr,err); break; \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment