ef77e6880b
Use the newly added SYM_CODE_START_LOCAL* to annotate beginnings of all pseudo-functions (those ending with END until now) which do not have ".globl" annotation. This is needed to balance END for tools that generate debuginfo. Note that ENDs are switched to SYM_CODE_END too so that everybody can see the pairing. C-like functions (which handle frame ptr etc.) are not annotated here, hence SYM_CODE_* macros are used here, not SYM_FUNC_*. Note that the 32bit version of early_idt_handler_common already had ENDPROC -- switch that to SYM_CODE_END for the same reason as above (and to be the same as 64bit). While early_idt_handler_common is LOCAL, it's name is not prepended with ".L" as it happens to appear in call traces. bad_get_user*, and bad_put_user are now aligned, as they are separate functions. They do not mind to be aligned -- no need to be compact there. early_idt_handler_common is aligned now too, as it is after early_idt_handler_array, so as well no need to be compact there. verify_cpu is self-standing and included in other .S files, so align it too. The others have alignment preserved to what it used to be (using the _NOALIGN variant of macros). Signed-off-by: Jiri Slaby <jslaby@suse.cz> Signed-off-by: Borislav Petkov <bp@suse.de> Cc: Alexios Zavras <alexios.zavras@intel.com> Cc: Allison Randal <allison@lohutok.net> Cc: Andy Lutomirski <luto@kernel.org> Cc: Cao jin <caoj.fnst@cn.fujitsu.com> Cc: Enrico Weigelt <info@metux.net> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Josh Poimboeuf <jpoimboe@redhat.com> Cc: Juergen Gross <jgross@suse.com> Cc: linux-arch@vger.kernel.org Cc: Maran Wilson <maran.wilson@oracle.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: x86-ml <x86@kernel.org> Link: https://lkml.kernel.org/r/20191011115108.12392-6-jslaby@suse.cz
146 lines
3.2 KiB
ArmAsm
146 lines
3.2 KiB
ArmAsm
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/*
|
|
* __get_user functions.
|
|
*
|
|
* (C) Copyright 1998 Linus Torvalds
|
|
* (C) Copyright 2005 Andi Kleen
|
|
* (C) Copyright 2008 Glauber Costa
|
|
*
|
|
* These functions have a non-standard call interface
|
|
* to make them more efficient, especially as they
|
|
* return an error value in addition to the "real"
|
|
* return value.
|
|
*/
|
|
|
|
/*
|
|
* __get_user_X
|
|
*
|
|
* Inputs: %[r|e]ax contains the address.
|
|
*
|
|
* Outputs: %[r|e]ax is error code (0 or -EFAULT)
|
|
* %[r|e]dx contains zero-extended value
|
|
* %ecx contains the high half for 32-bit __get_user_8
|
|
*
|
|
*
|
|
* These functions should not modify any other registers,
|
|
* as they get called from within inline assembly.
|
|
*/
|
|
|
|
#include <linux/linkage.h>
|
|
#include <asm/page_types.h>
|
|
#include <asm/errno.h>
|
|
#include <asm/asm-offsets.h>
|
|
#include <asm/thread_info.h>
|
|
#include <asm/asm.h>
|
|
#include <asm/smap.h>
|
|
#include <asm/export.h>
|
|
|
|
.text
|
|
ENTRY(__get_user_1)
|
|
mov PER_CPU_VAR(current_task), %_ASM_DX
|
|
cmp TASK_addr_limit(%_ASM_DX),%_ASM_AX
|
|
jae bad_get_user
|
|
sbb %_ASM_DX, %_ASM_DX /* array_index_mask_nospec() */
|
|
and %_ASM_DX, %_ASM_AX
|
|
ASM_STAC
|
|
1: movzbl (%_ASM_AX),%edx
|
|
xor %eax,%eax
|
|
ASM_CLAC
|
|
ret
|
|
ENDPROC(__get_user_1)
|
|
EXPORT_SYMBOL(__get_user_1)
|
|
|
|
ENTRY(__get_user_2)
|
|
add $1,%_ASM_AX
|
|
jc bad_get_user
|
|
mov PER_CPU_VAR(current_task), %_ASM_DX
|
|
cmp TASK_addr_limit(%_ASM_DX),%_ASM_AX
|
|
jae bad_get_user
|
|
sbb %_ASM_DX, %_ASM_DX /* array_index_mask_nospec() */
|
|
and %_ASM_DX, %_ASM_AX
|
|
ASM_STAC
|
|
2: movzwl -1(%_ASM_AX),%edx
|
|
xor %eax,%eax
|
|
ASM_CLAC
|
|
ret
|
|
ENDPROC(__get_user_2)
|
|
EXPORT_SYMBOL(__get_user_2)
|
|
|
|
ENTRY(__get_user_4)
|
|
add $3,%_ASM_AX
|
|
jc bad_get_user
|
|
mov PER_CPU_VAR(current_task), %_ASM_DX
|
|
cmp TASK_addr_limit(%_ASM_DX),%_ASM_AX
|
|
jae bad_get_user
|
|
sbb %_ASM_DX, %_ASM_DX /* array_index_mask_nospec() */
|
|
and %_ASM_DX, %_ASM_AX
|
|
ASM_STAC
|
|
3: movl -3(%_ASM_AX),%edx
|
|
xor %eax,%eax
|
|
ASM_CLAC
|
|
ret
|
|
ENDPROC(__get_user_4)
|
|
EXPORT_SYMBOL(__get_user_4)
|
|
|
|
ENTRY(__get_user_8)
|
|
#ifdef CONFIG_X86_64
|
|
add $7,%_ASM_AX
|
|
jc bad_get_user
|
|
mov PER_CPU_VAR(current_task), %_ASM_DX
|
|
cmp TASK_addr_limit(%_ASM_DX),%_ASM_AX
|
|
jae bad_get_user
|
|
sbb %_ASM_DX, %_ASM_DX /* array_index_mask_nospec() */
|
|
and %_ASM_DX, %_ASM_AX
|
|
ASM_STAC
|
|
4: movq -7(%_ASM_AX),%rdx
|
|
xor %eax,%eax
|
|
ASM_CLAC
|
|
ret
|
|
#else
|
|
add $7,%_ASM_AX
|
|
jc bad_get_user_8
|
|
mov PER_CPU_VAR(current_task), %_ASM_DX
|
|
cmp TASK_addr_limit(%_ASM_DX),%_ASM_AX
|
|
jae bad_get_user_8
|
|
sbb %_ASM_DX, %_ASM_DX /* array_index_mask_nospec() */
|
|
and %_ASM_DX, %_ASM_AX
|
|
ASM_STAC
|
|
4: movl -7(%_ASM_AX),%edx
|
|
5: movl -3(%_ASM_AX),%ecx
|
|
xor %eax,%eax
|
|
ASM_CLAC
|
|
ret
|
|
#endif
|
|
ENDPROC(__get_user_8)
|
|
EXPORT_SYMBOL(__get_user_8)
|
|
|
|
|
|
SYM_CODE_START_LOCAL(.Lbad_get_user_clac)
|
|
ASM_CLAC
|
|
bad_get_user:
|
|
xor %edx,%edx
|
|
mov $(-EFAULT),%_ASM_AX
|
|
ret
|
|
SYM_CODE_END(.Lbad_get_user_clac)
|
|
|
|
#ifdef CONFIG_X86_32
|
|
SYM_CODE_START_LOCAL(.Lbad_get_user_8_clac)
|
|
ASM_CLAC
|
|
bad_get_user_8:
|
|
xor %edx,%edx
|
|
xor %ecx,%ecx
|
|
mov $(-EFAULT),%_ASM_AX
|
|
ret
|
|
SYM_CODE_END(.Lbad_get_user_8_clac)
|
|
#endif
|
|
|
|
_ASM_EXTABLE_UA(1b, .Lbad_get_user_clac)
|
|
_ASM_EXTABLE_UA(2b, .Lbad_get_user_clac)
|
|
_ASM_EXTABLE_UA(3b, .Lbad_get_user_clac)
|
|
#ifdef CONFIG_X86_64
|
|
_ASM_EXTABLE_UA(4b, .Lbad_get_user_clac)
|
|
#else
|
|
_ASM_EXTABLE_UA(4b, .Lbad_get_user_8_clac)
|
|
_ASM_EXTABLE_UA(5b, .Lbad_get_user_8_clac)
|
|
#endif
|