diff options
author | Ram Muthiah <rammuthiah@google.com> | 2019-05-21 18:20:17 -0700 |
---|---|---|
committer | Amit Pundir <amit.pundir@linaro.org> | 2019-09-16 13:09:02 +0530 |
commit | 565677310f17f826c89df85c44b4c647e2f9bd9e (patch) | |
tree | 860387c25c51dfa8d8cbdd4bcffd5103b16d00e0 /arch | |
parent | 7e3fcd6fc7555f1be6d3b49597713fb45455a331 (diff) |
ANDROID: Four part revert of asm-goto usage [3/4]
Revert "Use __put_user_goto in __put_user_size() and unsafe_put_user()"
This reverts commit a959dc88f9c8900296ccf13e2f3e1cbc555a8917.
Bug: 120440614
Bug: 132629930
Change-Id: I07410ed2bc7552f16ec119fbc2001bb43ffef6f4
Signed-off-by: Ram Muthiah <rammuthiah@google.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/include/asm/uaccess.h | 57 |
1 files changed, 33 insertions, 24 deletions
diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h index c647784dd0c4..01e410fa97d9 100644 --- a/arch/x86/include/asm/uaccess.h +++ b/arch/x86/include/asm/uaccess.h @@ -184,14 +184,19 @@ __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL)) #ifdef CONFIG_X86_32 -#define __put_user_goto_u64(x, addr, label) \ - asm_volatile_goto("\n" \ - "1: movl %%eax,0(%1)\n" \ - "2: movl %%edx,4(%1)\n" \ - _ASM_EXTABLE_UA(1b, %l2) \ - _ASM_EXTABLE_UA(2b, %l2) \ - : : "A" (x), "r" (addr) \ - : : label) +#define __put_user_asm_u64(x, addr, err, errret) \ + asm volatile("\n" \ + "1: movl %%eax,0(%2)\n" \ + "2: movl %%edx,4(%2)\n" \ + "3:" \ + ".section .fixup,\"ax\"\n" \ + "4: movl %3,%0\n" \ + " jmp 3b\n" \ + ".previous\n" \ + _ASM_EXTABLE_UA(1b, 4b) \ + _ASM_EXTABLE_UA(2b, 4b) \ + : "=r" (err) \ + : "A" (x), "r" (addr), "i" (errret), "0" (err)) #define __put_user_asm_ex_u64(x, addr) \ asm volatile("\n" \ @@ -206,8 +211,8 @@ __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL)) asm volatile("call __put_user_8" : "=a" (__ret_pu) \ : "A" ((typeof(*(ptr)))(x)), "c" (ptr) : "ebx") #else -#define __put_user_goto_u64(x, ptr, label) \ - __put_user_goto(x, ptr, "q", "", "er", label) +#define __put_user_asm_u64(x, ptr, retval, errret) \ + __put_user_asm(x, ptr, retval, "q", "", "er", errret) #define __put_user_asm_ex_u64(x, addr) \ __put_user_asm_ex(x, addr, "q", "", "er") #define __put_user_x8(x, ptr, __ret_pu) __put_user_x(8, x, ptr, __ret_pu) @@ -268,21 +273,23 @@ extern void __put_user_8(void); __builtin_expect(__ret_pu, 0); \ }) -#define __put_user_size(x, ptr, size, label) \ +#define __put_user_size(x, ptr, size, retval, errret) \ do { \ + retval = 0; \ __chk_user_ptr(ptr); \ switch (size) { \ case 1: \ - __put_user_goto(x, ptr, "b", "b", "iq", label); \ + __put_user_asm(x, ptr, retval, "b", "b", "iq", errret); \ break; \ case 2: \ - __put_user_goto(x, ptr, "w", "w", "ir", label); \ + __put_user_asm(x, ptr, retval, "w", "w", "ir", errret); \ break; \ case 4: \ - __put_user_goto(x, ptr, "l", "k", "ir", label); \ + __put_user_asm(x, ptr, retval, "l", "k", "ir", errret); \ break; \ case 8: \ - __put_user_goto_u64((__typeof__(*ptr))(x), ptr, label); \ + __put_user_asm_u64((__typeof__(*ptr))(x), ptr, retval, \ + errret); \ break; \ default: \ __put_user_bad(); \ @@ -427,12 +434,9 @@ do { \ #define __put_user_nocheck(x, ptr, size) \ ({ \ - __label__ __pu_label; \ - int __pu_err = -EFAULT; \ + int __pu_err; \ __uaccess_begin(); \ - __put_user_size((x), (ptr), (size), __pu_label); \ - __pu_err = 0; \ -__pu_label: \ + __put_user_size((x), (ptr), (size), __pu_err, -EFAULT); \ __uaccess_end(); \ __builtin_expect(__pu_err, 0); \ }) @@ -716,11 +720,16 @@ static __must_check __always_inline bool user_access_begin(const void __user *pt #define user_access_begin(a,b) user_access_begin(a,b) #define user_access_end() __uaccess_end() -#define user_access_save() smap_save() -#define user_access_restore(x) smap_restore(x) +#define user_access_save() smap_save() +#define user_access_restore(x) smap_restore(x) -#define unsafe_put_user(x, ptr, label) \ - __put_user_size((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) +#define unsafe_put_user(x, ptr, err_label) \ +do { \ + int __pu_err; \ + __typeof__(*(ptr)) __pu_val = (x); \ + __put_user_size(__pu_val, (ptr), sizeof(*(ptr)), __pu_err, -EFAULT); \ + if (unlikely(__pu_err)) goto err_label; \ +} while (0) #define unsafe_get_user(x, ptr, err_label) \ do { \ |