Merge tag 'usercopy-v4.8' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux
[deliverable/linux.git] / arch / arm / include / asm / uaccess.h
index 7fb59199c6bbbebc03fafbff1c8083aa5892de91..a93c0f99acf7767c680158cf96acef87d1f0da51 100644 (file)
@@ -104,14 +104,6 @@ static inline void set_fs(mm_segment_t fs)
 
 #define segment_eq(a, b)       ((a) == (b))
 
-#define __addr_ok(addr) ({ \
-       unsigned long flag; \
-       __asm__("cmp %2, %0; movlo %0, #0" \
-               : "=&r" (flag) \
-               : "0" (current_thread_info()->addr_limit), "r" (addr) \
-               : "cc"); \
-       (flag == 0); })
-
 /* We use 33-bit arithmetic here... */
 #define __range_ok(addr, size) ({ \
        unsigned long flag, roksum; \
@@ -238,49 +230,23 @@ extern int __put_user_2(void *, unsigned int);
 extern int __put_user_4(void *, unsigned int);
 extern int __put_user_8(void *, unsigned long long);
 
-#define __put_user_x(__r2, __p, __e, __l, __s)                         \
-          __asm__ __volatile__ (                                       \
-               __asmeq("%0", "r0") __asmeq("%2", "r2")                 \
-               __asmeq("%3", "r1")                                     \
-               "bl     __put_user_" #__s                               \
-               : "=&r" (__e)                                           \
-               : "0" (__p), "r" (__r2), "r" (__l)                      \
-               : "ip", "lr", "cc")
-
-#define __put_user_check(x, p)                                         \
+#define __put_user_check(__pu_val, __ptr, __err, __s)                  \
        ({                                                              \
                unsigned long __limit = current_thread_info()->addr_limit - 1; \
-               const typeof(*(p)) __user *__tmp_p = (p);               \
-               register const typeof(*(p)) __r2 asm("r2") = (x);       \
-               register const typeof(*(p)) __user *__p asm("r0") = __tmp_p; \
+               register typeof(__pu_val) __r2 asm("r2") = __pu_val;    \
+               register const void __user *__p asm("r0") = __ptr;      \
                register unsigned long __l asm("r1") = __limit;         \
                register int __e asm("r0");                             \
-               unsigned int __ua_flags = uaccess_save_and_enable();    \
-               switch (sizeof(*(__p))) {                               \
-               case 1:                                                 \
-                       __put_user_x(__r2, __p, __e, __l, 1);           \
-                       break;                                          \
-               case 2:                                                 \
-                       __put_user_x(__r2, __p, __e, __l, 2);           \
-                       break;                                          \
-               case 4:                                                 \
-                       __put_user_x(__r2, __p, __e, __l, 4);           \
-                       break;                                          \
-               case 8:                                                 \
-                       __put_user_x(__r2, __p, __e, __l, 8);           \
-                       break;                                          \
-               default: __e = __put_user_bad(); break;                 \
-               }                                                       \
-               uaccess_restore(__ua_flags);                            \
-               __e;                                                    \
+               __asm__ __volatile__ (                                  \
+                       __asmeq("%0", "r0") __asmeq("%2", "r2")         \
+                       __asmeq("%3", "r1")                             \
+                       "bl     __put_user_" #__s                       \
+                       : "=&r" (__e)                                   \
+                       : "0" (__p), "r" (__r2), "r" (__l)              \
+                       : "ip", "lr", "cc");                            \
+               __err = __e;                                            \
        })
 
-#define put_user(x, p)                                                 \
-       ({                                                              \
-               might_fault();                                          \
-               __put_user_check(x, p);                                 \
-        })
-
 #else /* CONFIG_MMU */
 
 /*
@@ -298,7 +264,7 @@ static inline void set_fs(mm_segment_t fs)
 }
 
 #define get_user(x, p) __get_user(x, p)
-#define put_user(x, p) __put_user(x, p)
+#define __put_user_check __put_user_nocheck
 
 #endif /* CONFIG_MMU */
 
@@ -389,36 +355,54 @@ do {                                                                      \
 #define __get_user_asm_word(x, addr, err)                      \
        __get_user_asm(x, addr, err, ldr)
 
+
+#define __put_user_switch(x, ptr, __err, __fn)                         \
+       do {                                                            \
+               const __typeof__(*(ptr)) __user *__pu_ptr = (ptr);      \
+               __typeof__(*(ptr)) __pu_val = (x);                      \
+               unsigned int __ua_flags;                                \
+               might_fault();                                          \
+               __ua_flags = uaccess_save_and_enable();                 \
+               switch (sizeof(*(ptr))) {                               \
+               case 1: __fn(__pu_val, __pu_ptr, __err, 1); break;      \
+               case 2: __fn(__pu_val, __pu_ptr, __err, 2); break;      \
+               case 4: __fn(__pu_val, __pu_ptr, __err, 4); break;      \
+               case 8: __fn(__pu_val, __pu_ptr, __err, 8); break;      \
+               default: __err = __put_user_bad(); break;               \
+               }                                                       \
+               uaccess_restore(__ua_flags);                            \
+       } while (0)
+
+#define put_user(x, ptr)                                               \
+({                                                                     \
+       int __pu_err = 0;                                               \
+       __put_user_switch((x), (ptr), __pu_err, __put_user_check);      \
+       __pu_err;                                                       \
+})
+
 #define __put_user(x, ptr)                                             \
 ({                                                                     \
        long __pu_err = 0;                                              \
-       __put_user_err((x), (ptr), __pu_err);                           \
+       __put_user_switch((x), (ptr), __pu_err, __put_user_nocheck);    \
        __pu_err;                                                       \
 })
 
 #define __put_user_error(x, ptr, err)                                  \
 ({                                                                     \
-       __put_user_err((x), (ptr), err);                                \
+       __put_user_switch((x), (ptr), (err), __put_user_nocheck);       \
        (void) 0;                                                       \
 })
 
-#define __put_user_err(x, ptr, err)                                    \
-do {                                                                   \
-       unsigned long __pu_addr = (unsigned long)(ptr);                 \
-       unsigned int __ua_flags;                                        \
-       __typeof__(*(ptr)) __pu_val = (x);                              \
-       __chk_user_ptr(ptr);                                            \
-       might_fault();                                                  \
-       __ua_flags = uaccess_save_and_enable();                         \
-       switch (sizeof(*(ptr))) {                                       \
-       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 4: __put_user_asm_word(__pu_val, __pu_addr, err);  break;  \
-       case 8: __put_user_asm_dword(__pu_val, __pu_addr, err); break;  \
-       default: __put_user_bad();                                      \
-       }                                                               \
-       uaccess_restore(__ua_flags);                                    \
-} while (0)
+#define __put_user_nocheck(x, __pu_ptr, __err, __size)                 \
+       do {                                                            \
+               unsigned long __pu_addr = (unsigned long)__pu_ptr;      \
+               __put_user_nocheck_##__size(x, __pu_addr, __err);       \
+       } while (0)
+
+#define __put_user_nocheck_1 __put_user_asm_byte
+#define __put_user_nocheck_2 __put_user_asm_half
+#define __put_user_nocheck_4 __put_user_asm_word
+#define __put_user_nocheck_8 __put_user_asm_dword
 
 #define __put_user_asm(x, __pu_addr, err, instr)               \
        __asm__ __volatile__(                                   \
This page took 0.17419 seconds and 5 git commands to generate.