diff options
author | Marcel Ziswiler <marcel.ziswiler@toradex.com> | 2018-09-27 18:38:43 +0200 |
---|---|---|
committer | Marcel Ziswiler <marcel.ziswiler@toradex.com> | 2018-09-27 18:38:43 +0200 |
commit | 929b34b825fd42d83d5cea66125966b99e429b1e (patch) | |
tree | bdba534b6fccdefb146ec9f8317c6dc06f4d4670 /arch/arm | |
parent | 166cb6f4a4aff202d98914fe0c5530d26ce671a5 (diff) |
Revert "ARM: uaccess: remove put_user() code duplication"
This reverts commit 166cb6f4a4aff202d98914fe0c5530d26ce671a5.
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/include/asm/uaccess.h | 106 |
1 files changed, 57 insertions, 49 deletions
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h index b0f9269bef1c..35c9db857ebe 100644 --- a/arch/arm/include/asm/uaccess.h +++ b/arch/arm/include/asm/uaccess.h @@ -238,23 +238,49 @@ 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_check(__pu_val, __ptr, __err, __s) \ +#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) \ ({ \ unsigned long __limit = current_thread_info()->addr_limit - 1; \ - register typeof(__pu_val) __r2 asm("r2") = __pu_val; \ - register const void __user *__p asm("r0") = __ptr; \ + 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 unsigned long __l asm("r1") = __limit; \ register int __e asm("r0"); \ - __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; \ + 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; \ }) +#define put_user(x, p) \ + ({ \ + might_fault(); \ + __put_user_check(x, p); \ + }) + #else /* CONFIG_MMU */ /* @@ -272,7 +298,7 @@ static inline void set_fs(mm_segment_t fs) } #define get_user(x, p) __get_user(x, p) -#define __put_user_check __put_user_nocheck +#define put_user(x, p) __put_user(x, p) #endif /* CONFIG_MMU */ @@ -363,54 +389,36 @@ 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_switch((x), (ptr), __pu_err, __put_user_nocheck); \ + __put_user_err((x), (ptr), __pu_err); \ __pu_err; \ }) #define __put_user_error(x, ptr, err) \ ({ \ - __put_user_switch((x), (ptr), (err), __put_user_nocheck); \ + __put_user_err((x), (ptr), err); \ (void) 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_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_asm(x, __pu_addr, err, instr) \ __asm__ __volatile__( \ |