ARM: uaccess: remove put_user() code duplication
Commit 9f73bd8bb445e0cbe4bcef6d4cfc788f1e184007 upstream. Remove the code duplication between put_user() and __put_user(). The code which selected the implementation based upon the pointer size, and declared the local variable to hold the value to be put are common to both implementations. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> Signed-off-by: Ard Biesheuvel <ardb@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
8e0a4c1012
commit
a6e65291d4
1 changed files with 49 additions and 57 deletions
|
@ -238,49 +238,23 @@ extern int __put_user_2(void *, unsigned int);
|
||||||
extern int __put_user_4(void *, unsigned int);
|
extern int __put_user_4(void *, unsigned int);
|
||||||
extern int __put_user_8(void *, unsigned long long);
|
extern int __put_user_8(void *, unsigned long long);
|
||||||
|
|
||||||
#define __put_user_x(__r2, __p, __e, __l, __s) \
|
#define __put_user_check(__pu_val, __ptr, __err, __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; \
|
unsigned long __limit = current_thread_info()->addr_limit - 1; \
|
||||||
const typeof(*(p)) __user *__tmp_p = (p); \
|
register typeof(__pu_val) __r2 asm("r2") = __pu_val; \
|
||||||
register const typeof(*(p)) __r2 asm("r2") = (x); \
|
register const void __user *__p asm("r0") = __ptr; \
|
||||||
register const typeof(*(p)) __user *__p asm("r0") = __tmp_p; \
|
|
||||||
register unsigned long __l asm("r1") = __limit; \
|
register unsigned long __l asm("r1") = __limit; \
|
||||||
register int __e asm("r0"); \
|
register int __e asm("r0"); \
|
||||||
unsigned int __ua_flags = uaccess_save_and_enable(); \
|
__asm__ __volatile__ ( \
|
||||||
switch (sizeof(*(__p))) { \
|
__asmeq("%0", "r0") __asmeq("%2", "r2") \
|
||||||
case 1: \
|
__asmeq("%3", "r1") \
|
||||||
__put_user_x(__r2, __p, __e, __l, 1); \
|
"bl __put_user_" #__s \
|
||||||
break; \
|
: "=&r" (__e) \
|
||||||
case 2: \
|
: "0" (__p), "r" (__r2), "r" (__l) \
|
||||||
__put_user_x(__r2, __p, __e, __l, 2); \
|
: "ip", "lr", "cc"); \
|
||||||
break; \
|
__err = __e; \
|
||||||
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 */
|
#else /* CONFIG_MMU */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -298,7 +272,7 @@ static inline void set_fs(mm_segment_t fs)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define get_user(x, p) __get_user(x, p)
|
#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 */
|
#endif /* CONFIG_MMU */
|
||||||
|
|
||||||
|
@ -389,36 +363,54 @@ do { \
|
||||||
#define __get_user_asm_word(x, addr, err) \
|
#define __get_user_asm_word(x, addr, err) \
|
||||||
__get_user_asm(x, addr, err, ldr)
|
__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) \
|
#define __put_user(x, ptr) \
|
||||||
({ \
|
({ \
|
||||||
long __pu_err = 0; \
|
long __pu_err = 0; \
|
||||||
__put_user_err((x), (ptr), __pu_err); \
|
__put_user_switch((x), (ptr), __pu_err, __put_user_nocheck); \
|
||||||
__pu_err; \
|
__pu_err; \
|
||||||
})
|
})
|
||||||
|
|
||||||
#define __put_user_error(x, ptr, 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; \
|
(void) 0; \
|
||||||
})
|
})
|
||||||
|
|
||||||
#define __put_user_err(x, ptr, err) \
|
#define __put_user_nocheck(x, __pu_ptr, __err, __size) \
|
||||||
do { \
|
do { \
|
||||||
unsigned long __pu_addr = (unsigned long)(ptr); \
|
unsigned long __pu_addr = (unsigned long)__pu_ptr; \
|
||||||
unsigned int __ua_flags; \
|
__put_user_nocheck_##__size(x, __pu_addr, __err); \
|
||||||
__typeof__(*(ptr)) __pu_val = (x); \
|
} while (0)
|
||||||
__chk_user_ptr(ptr); \
|
|
||||||
might_fault(); \
|
#define __put_user_nocheck_1 __put_user_asm_byte
|
||||||
__ua_flags = uaccess_save_and_enable(); \
|
#define __put_user_nocheck_2 __put_user_asm_half
|
||||||
switch (sizeof(*(ptr))) { \
|
#define __put_user_nocheck_4 __put_user_asm_word
|
||||||
case 1: __put_user_asm_byte(__pu_val, __pu_addr, err); break; \
|
#define __put_user_nocheck_8 __put_user_asm_dword
|
||||||
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) \
|
#define __put_user_asm(x, __pu_addr, err, instr) \
|
||||||
__asm__ __volatile__( \
|
__asm__ __volatile__( \
|
||||||
|
|
Loading…
Add table
Reference in a new issue