The RETPOLINE_AMD name is unfortunate since it isn't necessarily AMD only, in fact Hygon also uses it. Furthermore it will likely be sufficient for some Intel processors. Therefore rename the thing to RETPOLINE_LFENCE to better describe what it is. Add the spectre_v2=retpoline,lfence option as an alias to spectre_v2=retpoline,amd to preserve existing setups. However, the output of /sys/devices/system/cpu/vulnerabilities/spectre_v2 will be changed. [ bp: Fix typos, massage. ] Co-developed-by: Josh Poimboeuf <jpoimboe@redhat.com> Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Signed-off-by: Borislav Petkov <bp@suse.de> Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
69 lines
1.7 KiB
ArmAsm
69 lines
1.7 KiB
ArmAsm
/* SPDX-License-Identifier: GPL-2.0 */
|
|
|
|
#include <linux/stringify.h>
|
|
#include <linux/linkage.h>
|
|
#include <asm/dwarf2.h>
|
|
#include <asm/cpufeatures.h>
|
|
#include <asm/alternative.h>
|
|
#include <asm/export.h>
|
|
#include <asm/nospec-branch.h>
|
|
#include <asm/unwind_hints.h>
|
|
#include <asm/frame.h>
|
|
|
|
.section .text.__x86.indirect_thunk
|
|
|
|
.macro RETPOLINE reg
|
|
ANNOTATE_INTRA_FUNCTION_CALL
|
|
call .Ldo_rop_\@
|
|
.Lspec_trap_\@:
|
|
UNWIND_HINT_EMPTY
|
|
pause
|
|
lfence
|
|
jmp .Lspec_trap_\@
|
|
.Ldo_rop_\@:
|
|
mov %\reg, (%_ASM_SP)
|
|
UNWIND_HINT_FUNC
|
|
RET
|
|
.endm
|
|
|
|
.macro THUNK reg
|
|
|
|
.align RETPOLINE_THUNK_SIZE
|
|
SYM_INNER_LABEL(__x86_indirect_thunk_\reg, SYM_L_GLOBAL)
|
|
UNWIND_HINT_EMPTY
|
|
|
|
ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; jmp *%\reg), \
|
|
__stringify(RETPOLINE \reg), X86_FEATURE_RETPOLINE, \
|
|
__stringify(lfence; ANNOTATE_RETPOLINE_SAFE; jmp *%\reg; int3), X86_FEATURE_RETPOLINE_LFENCE
|
|
|
|
.endm
|
|
|
|
/*
|
|
* Despite being an assembler file we can't just use .irp here
|
|
* because __KSYM_DEPS__ only uses the C preprocessor and would
|
|
* only see one instance of "__x86_indirect_thunk_\reg" rather
|
|
* than one per register with the correct names. So we do it
|
|
* the simple and nasty way...
|
|
*
|
|
* Worse, you can only have a single EXPORT_SYMBOL per line,
|
|
* and CPP can't insert newlines, so we have to repeat everything
|
|
* at least twice.
|
|
*/
|
|
|
|
#define __EXPORT_THUNK(sym) _ASM_NOKPROBE(sym); EXPORT_SYMBOL(sym)
|
|
#define EXPORT_THUNK(reg) __EXPORT_THUNK(__x86_indirect_thunk_ ## reg)
|
|
|
|
.align RETPOLINE_THUNK_SIZE
|
|
SYM_CODE_START(__x86_indirect_thunk_array)
|
|
|
|
#define GEN(reg) THUNK reg
|
|
#include <asm/GEN-for-each-reg.h>
|
|
#undef GEN
|
|
|
|
.align RETPOLINE_THUNK_SIZE
|
|
SYM_CODE_END(__x86_indirect_thunk_array)
|
|
|
|
#define GEN(reg) EXPORT_THUNK(reg)
|
|
#include <asm/GEN-for-each-reg.h>
|
|
#undef GEN
|