The 4 patches in this series make the JMP_NOSPEC and CALL_NOSPEC macros used in the kernel consistent with what is generated by the compiler.
("x86,nospec: Simplify {JMP,CALL}_NOSPEC") was merged in v6.0 and the remaining 3 patches in this series were merged in v6.15. All 4 were included in kernels v5.15+ as prerequisites for the backport of the ITS mitigations [1].
None of these patches were included in the backport of the ITS mitigations to the 5.10 kernel [2]. They all apply cleanly and are applicable to the 5.10 kernel. Thus I see no reason that they weren't applied here, unless someone can correct me?
I am sending them for inclusion in the 5.10 kernel as this kernel is still actively maintained for these kind of vulnerability mitigations and as such having these patches will unify the handling of these cases with subsequent kernel versions easing code understanding and the ease of backports in the future.
[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... [2] https://lore.kernel.org/stable/20250617-its-5-10-v2-0-3e925a1512a1@linux.int...
Pawan Gupta (3): x86/speculation: Simplify and make CALL_NOSPEC consistent x86/speculation: Add a conditional CS prefix to CALL_NOSPEC x86/speculation: Remove the extra #ifdef around CALL_NOSPEC
Peter Zijlstra (1): x86,nospec: Simplify {JMP,CALL}_NOSPEC
arch/x86/include/asm/nospec-branch.h | 46 ++++++++++++++++++---------- 1 file changed, 30 insertions(+), 16 deletions(-)
From: Peter Zijlstra peterz@infradead.org
commit 09d09531a51a24635bc3331f56d92ee7092f5516 upstream.
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@infradead.org Signed-off-by: Suraj Jitindar Singh surajjs@amazon.com Cc: stable@vger.kernel.org # 5.10.x --- 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 ce5e6e70d2a4..3434e5ebd3c7 100644 --- a/arch/x86/include/asm/nospec-branch.h +++ b/arch/x86/include/asm/nospec-branch.h @@ -118,6 +118,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_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 @@ -125,19 +138,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
From: Pawan Gupta pawan.kumar.gupta@linux.intel.com
commit cfceff8526a426948b53445c02bcb98453c7330d upstream.
CALL_NOSPEC macro is used to generate Spectre-v2 mitigation friendly indirect branches. At compile time the macro defaults to indirect branch, and at runtime those can be patched to thunk based mitigations.
This approach is opposite of what is done for the rest of the kernel, where the compile time default is to replace indirect calls with retpoline thunk calls.
Make CALL_NOSPEC consistent with the rest of the kernel, default to retpoline thunk at compile time when CONFIG_MITIGATION_RETPOLINE is enabled.
Signed-off-by: Pawan Gupta pawan.kumar.gupta@linux.intel.com Signed-off-by: Ingo Molnar mingo@kernel.org Cc: Andrew Cooper <andrew.cooper3@citrix.com Cc: Linus Torvalds torvalds@linux-foundation.org Cc: Peter Zijlstra peterz@infradead.org Link: https://lore.kernel.org/r/20250228-call-nospec-v3-1-96599fed0f33@linux.intel... Signed-off-by: Suraj Jitindar Singh surajjs@amazon.com Cc: stable@vger.kernel.org # 5.10.x --- arch/x86/include/asm/nospec-branch.h | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-)
diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h index 3434e5ebd3c7..bb7dd09dc295 100644 --- a/arch/x86/include/asm/nospec-branch.h +++ b/arch/x86/include/asm/nospec-branch.h @@ -285,16 +285,11 @@ extern retpoline_thunk_t __x86_indirect_thunk_array[]; * Inline asm uses the %V modifier which is only in newer GCC * which is ensured when CONFIG_RETPOLINE is defined. */ -# define CALL_NOSPEC \ - ALTERNATIVE_2( \ - ANNOTATE_RETPOLINE_SAFE \ - "call *%[thunk_target]\n", \ - "call __x86_indirect_thunk_%V[thunk_target]\n", \ - X86_FEATURE_RETPOLINE, \ - "lfence;\n" \ - ANNOTATE_RETPOLINE_SAFE \ - "call *%[thunk_target]\n", \ - X86_FEATURE_RETPOLINE_LFENCE) +#ifdef CONFIG_RETPOLINE +#define CALL_NOSPEC "call __x86_indirect_thunk_%V[thunk_target]\n" +#else +#define CALL_NOSPEC "call *%[thunk_target]\n" +#endif
# define THUNK_TARGET(addr) [thunk_target] "r" (addr)
From: Pawan Gupta pawan.kumar.gupta@linux.intel.com
commit 052040e34c08428a5a388b85787e8531970c0c67 upstream.
Retpoline mitigation for spectre-v2 uses thunks for indirect branches. To support this mitigation compilers add a CS prefix with -mindirect-branch-cs-prefix. For an indirect branch in asm, this needs to be added manually.
CS prefix is already being added to indirect branches in asm files, but not in inline asm. Add CS prefix to CALL_NOSPEC for inline asm as well. There is no JMP_NOSPEC for inline asm.
Reported-by: Josh Poimboeuf jpoimboe@kernel.org Signed-off-by: Pawan Gupta pawan.kumar.gupta@linux.intel.com Signed-off-by: Ingo Molnar mingo@kernel.org Cc: Andrew Cooper <andrew.cooper3@citrix.com Cc: Linus Torvalds torvalds@linux-foundation.org Cc: Peter Zijlstra peterz@infradead.org Link: https://lore.kernel.org/r/20250228-call-nospec-v3-2-96599fed0f33@linux.intel... Signed-off-by: Suraj Jitindar Singh surajjs@amazon.com Cc: stable@vger.kernel.org # 5.10.x --- arch/x86/include/asm/nospec-branch.h | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h index bb7dd09dc295..2cade6749322 100644 --- a/arch/x86/include/asm/nospec-branch.h +++ b/arch/x86/include/asm/nospec-branch.h @@ -119,9 +119,8 @@ .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_retpolines(). + * Emits a conditional CS prefix that is compatible with + * -mindirect-branch-cs-prefix. */ .macro __CS_PREFIX reg:req .irp rs,r8,r9,r10,r11,r12,r13,r14,r15 @@ -281,12 +280,24 @@ extern retpoline_thunk_t __x86_indirect_thunk_array[];
#ifdef CONFIG_X86_64
+/* + * Emits a conditional CS prefix that is compatible with + * -mindirect-branch-cs-prefix. + */ +#define __CS_PREFIX(reg) \ + ".irp rs,r8,r9,r10,r11,r12,r13,r14,r15\n" \ + ".ifc \rs," reg "\n" \ + ".byte 0x2e\n" \ + ".endif\n" \ + ".endr\n" + /* * Inline asm uses the %V modifier which is only in newer GCC * which is ensured when CONFIG_RETPOLINE is defined. */ #ifdef CONFIG_RETPOLINE -#define CALL_NOSPEC "call __x86_indirect_thunk_%V[thunk_target]\n" +#define CALL_NOSPEC __CS_PREFIX("%V[thunk_target]") \ + "call __x86_indirect_thunk_%V[thunk_target]\n" #else #define CALL_NOSPEC "call *%[thunk_target]\n" #endif
From: Pawan Gupta pawan.kumar.gupta@linux.intel.com
commit c8c81458863ab686cda4fe1e603fccaae0f12460 upstream.
Commit:
010c4a461c1d ("x86/speculation: Simplify and make CALL_NOSPEC consistent")
added an #ifdef CONFIG_MITIGATION_RETPOLINE around the CALL_NOSPEC definition. This is not required as this code is already under a larger #ifdef.
Remove the extra #ifdef, no functional change.
vmlinux size remains same before and after this change:
CONFIG_MITIGATION_RETPOLINE=y: text data bss dec hex filename 25434752 7342290 2301212 35078254 217406e vmlinux.before 25434752 7342290 2301212 35078254 217406e vmlinux.after
# CONFIG_MITIGATION_RETPOLINE is not set: text data bss dec hex filename 22943094 6214994 1550152 30708240 1d49210 vmlinux.before 22943094 6214994 1550152 30708240 1d49210 vmlinux.after
Signed-off-by: Pawan Gupta pawan.kumar.gupta@linux.intel.com Signed-off-by: Ingo Molnar mingo@kernel.org Reviewed-by: Josh Poimboeuf jpoimboe@kernel.org Link: https://lore.kernel.org/r/20250320-call-nospec-extra-ifdef-v1-1-d9b084d24820... Signed-off-by: Suraj Jitindar Singh surajjs@amazon.com Cc: stable@vger.kernel.org # 5.10.x --- arch/x86/include/asm/nospec-branch.h | 4 ---- 1 file changed, 4 deletions(-)
diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h index 2cade6749322..9f84a00776e2 100644 --- a/arch/x86/include/asm/nospec-branch.h +++ b/arch/x86/include/asm/nospec-branch.h @@ -295,12 +295,8 @@ extern retpoline_thunk_t __x86_indirect_thunk_array[]; * Inline asm uses the %V modifier which is only in newer GCC * which is ensured when CONFIG_RETPOLINE is defined. */ -#ifdef CONFIG_RETPOLINE #define CALL_NOSPEC __CS_PREFIX("%V[thunk_target]") \ "call __x86_indirect_thunk_%V[thunk_target]\n" -#else -#define CALL_NOSPEC "call *%[thunk_target]\n" -#endif
# define THUNK_TARGET(addr) [thunk_target] "r" (addr)
On Wed, Sep 03, 2025 at 03:49:59PM -0700, Suraj Jitindar Singh wrote:
The 4 patches in this series make the JMP_NOSPEC and CALL_NOSPEC macros used in the kernel consistent with what is generated by the compiler.
("x86,nospec: Simplify {JMP,CALL}_NOSPEC") was merged in v6.0 and the remaining 3 patches in this series were merged in v6.15. All 4 were included in kernels v5.15+ as prerequisites for the backport of the ITS mitigations [1].
None of these patches were included in the backport of the ITS mitigations to the 5.10 kernel [2]. They all apply cleanly and are applicable to the 5.10 kernel. Thus I see no reason that they weren't applied here, unless someone can correct me?
Do they actually fix anything?
I am sending them for inclusion in the 5.10 kernel as this kernel is still actively maintained for these kind of vulnerability mitigations and as such having these patches will unify the handling of these cases with subsequent kernel versions easing code understanding and the ease of backports in the future.
Does this actually allow this to happen? I think there are a few speculation fixes that have not been backported to this kernel tree, so why not just make this as a part of that work instead? Just adding infastructure that doesn't do anything isn't usually a good idea.
thanks,
greg k-h
On Wed, Sep 03, 2025 at 03:49:59PM -0700, Suraj Jitindar Singh wrote:
The 4 patches in this series make the JMP_NOSPEC and CALL_NOSPEC macros used in the kernel consistent with what is generated by the compiler.
("x86,nospec: Simplify {JMP,CALL}_NOSPEC") was merged in v6.0 and the remaining 3 patches in this series were merged in v6.15. All 4 were included in kernels v5.15+ as prerequisites for the backport of the ITS mitigations [1].
None of these patches were included in the backport of the ITS mitigations to the 5.10 kernel [2]. They all apply cleanly and are applicable to the 5.10 kernel. Thus I see no reason that they weren't applied here, unless someone can correct me?
I am sending them for inclusion in the 5.10 kernel as this kernel is still actively maintained for these kind of vulnerability mitigations and as such having these patches will unify the handling of these cases with subsequent kernel versions easing code understanding and the ease of backports in the future.
Also, you only really have about 1 more year left for this kernel version, why not take the time to move any systems that are somehow still using this to a more modern kernel instead? What's preventing that from happening?
Running any x86 systems on this old kernel right now is probably not a good idea given the huge number of unfixed bugs in it...
thanks,
greg k-h
linux-stable-mirror@lists.linaro.org