Commit 99641e09 authored by Peter Zijlstra's avatar Peter Zijlstra
Browse files

x86/uaccess: Remove .fixup usage



For the !CC_AS_ASM_GOTO_OUTPUT (aka. the legacy codepath), remove the
.fixup usage by employing both EX_TYPE_EFAULT_REG and EX_FLAG_CLEAR.
Like was already done for X86_32's version of __get_user_asm_u64() use
the "a" register for output, specifically so we can use CLEAR_AX.

Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: default avatarJosh Poimboeuf <jpoimboe@redhat.com>
Link: https://lore.kernel.org/r/20211110101325.485154848@infradead.org
parent 4c132d1d
Loading
Loading
Loading
Loading
+17 −22
Original line number Diff line number Diff line
@@ -351,24 +351,22 @@ do { \
		     "1:	movl %[lowbits],%%eax\n"		\
		     "2:	movl %[highbits],%%edx\n"		\
		     "3:\n"						\
		     ".section .fixup,\"ax\"\n"				\
		     "4:	mov %[efault],%[errout]\n"		\
		     "	xorl %%eax,%%eax\n"				\
		     "	xorl %%edx,%%edx\n"				\
		     "	jmp 3b\n"					\
		     ".previous\n"					\
		     _ASM_EXTABLE_UA(1b, 4b)				\
		     _ASM_EXTABLE_UA(2b, 4b)				\
		     _ASM_EXTABLE_TYPE_REG(1b, 3b, EX_TYPE_EFAULT_REG |	\
					   EX_FLAG_CLEAR_AX_DX,		\
					   %[errout])			\
		     _ASM_EXTABLE_TYPE_REG(2b, 3b, EX_TYPE_EFAULT_REG |	\
					   EX_FLAG_CLEAR_AX_DX,		\
					   %[errout])			\
		     : [errout] "=r" (retval),				\
		       [output] "=&A"(x)				\
		     : [lowbits] "m" (__m(__ptr)),			\
		       [highbits] "m" __m(((u32 __user *)(__ptr)) + 1),	\
		       [efault] "i" (-EFAULT), "0" (retval));		\
		       "0" (retval));					\
})

#else
#define __get_user_asm_u64(x, ptr, retval) \
	 __get_user_asm(x, ptr, retval, "q", "=r")
	 __get_user_asm(x, ptr, retval, "q")
#endif

#define __get_user_size(x, ptr, size, retval)				\
@@ -379,14 +377,14 @@ do { \
	__chk_user_ptr(ptr);						\
	switch (size) {							\
	case 1:								\
		__get_user_asm(x_u8__, ptr, retval, "b", "=q");		\
		__get_user_asm(x_u8__, ptr, retval, "b");		\
		(x) = x_u8__;						\
		break;							\
	case 2:								\
		__get_user_asm(x, ptr, retval, "w", "=r");		\
		__get_user_asm(x, ptr, retval, "w");			\
		break;							\
	case 4:								\
		__get_user_asm(x, ptr, retval, "l", "=r");		\
		__get_user_asm(x, ptr, retval, "l");			\
		break;							\
	case 8:								\
		__get_user_asm_u64(x, ptr, retval);			\
@@ -396,20 +394,17 @@ do { \
	}								\
} while (0)

#define __get_user_asm(x, addr, err, itype, ltype)			\
#define __get_user_asm(x, addr, err, itype)				\
	asm volatile("\n"						\
		     "1:	mov"itype" %[umem],%[output]\n"		\
		     "2:\n"						\
		     ".section .fixup,\"ax\"\n"				\
		     "3:	mov %[efault],%[errout]\n"		\
		     "	xorl %k[output],%k[output]\n"			\
		     "	jmp 2b\n"					\
		     ".previous\n"					\
		     _ASM_EXTABLE_UA(1b, 3b)				\
		     _ASM_EXTABLE_TYPE_REG(1b, 2b, EX_TYPE_EFAULT_REG | \
					   EX_FLAG_CLEAR_AX,		\
					   %[errout])			\
		     : [errout] "=r" (err),				\
		       [output] ltype(x)				\
		       [output] "=a" (x)				\
		     : [umem] "m" (__m(addr)),				\
		       [efault] "i" (-EFAULT), "0" (err))
		       "0" (err))

#endif // CONFIG_CC_HAS_ASM_GOTO_OUTPUT