summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcel Ziswiler <marcel.ziswiler@toradex.com>2018-09-27 18:38:43 +0200
committerMarcel Ziswiler <marcel.ziswiler@toradex.com>2018-09-27 18:38:43 +0200
commit929b34b825fd42d83d5cea66125966b99e429b1e (patch)
treebdba534b6fccdefb146ec9f8317c6dc06f4d4670
parent166cb6f4a4aff202d98914fe0c5530d26ce671a5 (diff)
Revert "ARM: uaccess: remove put_user() code duplication"
This reverts commit 166cb6f4a4aff202d98914fe0c5530d26ce671a5.
-rw-r--r--arch/arm/include/asm/uaccess.h106
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__( \