aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCatalin Marinas <catalin.marinas@arm.com>2012-09-05 15:01:25 +0100
committerCatalin Marinas <catalin.marinas@arm.com>2012-09-05 16:19:07 +0100
commit8b1990649bd260a080e2a39f8d53b952a35b89b2 (patch)
tree32ee61e0964913251adb59e95b6ed0797504f61b
parent43fa556c59f470bdda6d131c0ec9b914ed60c181 (diff)
downloadlinux-aarch64-8b1990649bd260a080e2a39f8d53b952a35b89b2.tar.gz
fixup! arm64: Only use the inline asm for get_user/put_user
Further simplify the get_user/put_user macros (similar to the generic code but with get_user setting the value to 0 in case of failure). Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
-rw-r--r--arch/arm64/include/asm/uaccess.h50
1 files changed, 20 insertions, 30 deletions
diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h
index 328ac944957..cdc1666e47f 100644
--- a/arch/arm64/include/asm/uaccess.h
+++ b/arch/arm64/include/asm/uaccess.h
@@ -115,7 +115,7 @@ static inline void set_fs(mm_segment_t fs)
"2:\n" \
" .section .fixup, \"ax\"\n" \
" .align 2\n" \
- "3: mov %0, %3\n" \
+ "3: mov %w0, %3\n" \
" mov %1, #0\n" \
" b 2b\n" \
" .previous\n" \
@@ -131,16 +131,16 @@ do { \
__chk_user_ptr(ptr); \
switch (sizeof(*(ptr))) { \
case 1: \
- __get_user_asm("ldrb", "%w", (x), (ptr), err); \
+ __get_user_asm("ldrb", "%w", (x), (ptr), (err)); \
break; \
case 2: \
- __get_user_asm("ldrh", "%w", (x), (ptr), err); \
+ __get_user_asm("ldrh", "%w", (x), (ptr), (err)); \
break; \
case 4: \
- __get_user_asm("ldr", "%w", (x), (ptr), err); \
+ __get_user_asm("ldr", "%w", (x), (ptr), (err)); \
break; \
case 8: \
- __get_user_asm("ldr", "%", (x), (ptr), err); \
+ __get_user_asm("ldr", "%", (x), (ptr), (err)); \
break; \
default: \
BUILD_BUG(); \
@@ -149,7 +149,7 @@ do { \
#define __get_user(x, ptr) \
({ \
- long __gu_err = 0; \
+ int __gu_err = 0; \
__get_user_err((x), (ptr), __gu_err); \
__gu_err; \
})
@@ -164,24 +164,19 @@ do { \
#define get_user(x, ptr) \
({ \
- long __gu_err = 0; \
- unsigned long __gu_val = 0; \
might_sleep(); \
- if (access_ok(VERIFY_READ, (ptr), sizeof(*ptr))) \
- __get_user_err(__gu_val, (ptr), __gu_err); \
- else \
- __gu_err = -EFAULT; \
- (x) = (__typeof__(*(ptr)))__gu_val; \
- __gu_err; \
+ access_ok(VERIFY_READ, (ptr), sizeof(*(ptr))) ? \
+ __get_user((x), (ptr)) : \
+ ((x) = 0, -EFAULT); \
})
-#define __put_user_asm(instr, reg, x, __pu_addr, err) \
+#define __put_user_asm(instr, reg, x, addr, err) \
asm volatile( \
"1: " instr " " reg "1, [%2]\n" \
"2:\n" \
" .section .fixup,\"ax\"\n" \
" .align 2\n" \
- "3: mov %0, %3\n" \
+ "3: mov %w0, %3\n" \
" b 2b\n" \
" .previous\n" \
" .section __ex_table,\"a\"\n" \
@@ -189,25 +184,23 @@ do { \
" .quad 1b, 3b\n" \
" .previous" \
: "+r" (err) \
- : "r" (x), "r" (__pu_addr), "i" (-EFAULT))
+ : "r" (x), "r" (addr), "i" (-EFAULT))
#define __put_user_err(x, ptr, err) \
do { \
- unsigned long __pu_addr = (unsigned long)(ptr); \
- __typeof__(*(ptr)) __pu_val = (x); \
__chk_user_ptr(ptr); \
switch (sizeof(*(ptr))) { \
case 1: \
- __put_user_asm("strb", "%w", __pu_val, __pu_addr, err); \
+ __put_user_asm("strb", "%w", (x), (ptr), (err)); \
break; \
case 2: \
- __put_user_asm("strh", "%w", __pu_val, __pu_addr, err); \
+ __put_user_asm("strh", "%w", (x), (ptr), (err)); \
break; \
case 4: \
- __put_user_asm("str", "%w", __pu_val, __pu_addr, err); \
+ __put_user_asm("str", "%w", (x), (ptr), (err)); \
break; \
case 8: \
- __put_user_asm("str", "%", __pu_val, __pu_addr, err); \
+ __put_user_asm("str", "%", (x), (ptr), (err)); \
break; \
default: \
BUILD_BUG(); \
@@ -216,7 +209,7 @@ do { \
#define __put_user(x, ptr) \
({ \
- long __pu_err = 0; \
+ int __pu_err = 0; \
__put_user_err((x), (ptr), __pu_err); \
__pu_err; \
})
@@ -231,13 +224,10 @@ do { \
#define put_user(x, ptr) \
({ \
- long __gu_err = 0; \
might_sleep(); \
- if (access_ok(VERIFY_WRITE, (ptr), sizeof(*ptr))) \
- __put_user_err((x), (ptr), __gu_err); \
- else \
- __gu_err = -EFAULT; \
- __gu_err; \
+ access_ok(VERIFY_WRITE, (ptr), sizeof(*(ptr))) ? \
+ __put_user((x), (ptr)) : \
+ -EFAULT; \
})
extern unsigned long __must_check __copy_from_user(void *to, const void __user *from, unsigned long n);