Re: [RFC][PATCH] x86,nospec: Simplify {JMP,CALL}_NOSPEC

From: Peter Zijlstra
Date: Tue Jul 19 2022 - 17:33:34 EST


On Tue, Jul 19, 2022 at 11:23:07PM +0200, Peter Zijlstra wrote:
> Subject: x86,nospec: Simplify {JMP,CALL}_NOSPEC
>
> Have {JMP,CALL}_NOSPEC generate the same code GCC does for indirect
> calls and rely on the objtool retpoline patching infrastructure.
>
> There's no reason these should be alternatives while the vast bulk of
> compiler generated retpolines are not.
>
> Signed-off-by: Peter Zijlstra (Intel) <peterz@xxxxxxxxxxxxx>
> ---
> arch/x86/include/asm/nospec-branch.h | 24 ++++++++++++++++++------
> 1 file changed, 18 insertions(+), 6 deletions(-)
>
> diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h
> index 10a3bfc1eb23..7bb319d2932c 100644
> --- a/arch/x86/include/asm/nospec-branch.h
> +++ b/arch/x86/include/asm/nospec-branch.h
> @@ -93,6 +93,19 @@
> #endif
> .endm
>
> +/*
> + * Equivalent to -mindirect-branch-cs-prefix; emit the 5 byte jmp/call
> + * to the retpoline thunk with a CS prefix when the register requires
> + * a RAX prefix byte to encode. Also see apply_alternatives().

Obviously I meant: apply_retpolines() ...

> + */
> +.macro __CS_PREFIX reg:req
> + .irp rs,r8,r9,r10,r11,r12,r13,r14,r15
> + .ifc \reg,\rs
> + .byte 0x2e
> + .endif
> + .endr
> +.endm
> +
> /*
> * JMP_NOSPEC and CALL_NOSPEC macros can be used instead of a simple
> * indirect jmp/call which may be susceptible to the Spectre variant 2
> @@ -100,19 +113,18 @@
> */
> .macro JMP_NOSPEC reg:req
> #ifdef CONFIG_RETPOLINE
> - ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; jmp *%\reg), \
> - __stringify(jmp __x86_indirect_thunk_\reg), X86_FEATURE_RETPOLINE, \
> - __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; jmp *%\reg), X86_FEATURE_RETPOLINE_LFENCE
> + __CS_PREFIX \reg
> + jmp __x86_indirect_thunk_\reg
> #else
> jmp *%\reg
> + int3
> #endif
> .endm
>
> .macro CALL_NOSPEC reg:req
> #ifdef CONFIG_RETPOLINE
> - ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; call *%\reg), \
> - __stringify(call __x86_indirect_thunk_\reg), X86_FEATURE_RETPOLINE, \
> - __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; call *%\reg), X86_FEATURE_RETPOLINE_LFENCE
> + __CS_PREFIX \reg
> + call __x86_indirect_thunk_\reg
> #else
> call *%\reg
> #endif