Skip to content

Commit f43b987

Browse files
Peter Zijlstrasuryasaimadhu
Peter Zijlstra
authored andcommitted
x86/retbleed: Add fine grained Kconfig knobs
Do fine-grained Kconfig for all the various retbleed parts. NOTE: if your compiler doesn't support return thunks this will silently 'upgrade' your mitigation to IBPB, you might not like this. Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Signed-off-by: Borislav Petkov <[email protected]>
1 parent 26aae8c commit f43b987

19 files changed

+178
-69
lines changed

arch/x86/Kconfig

+85-26
Original file line numberDiff line numberDiff line change
@@ -462,32 +462,6 @@ config GOLDFISH
462462
def_bool y
463463
depends on X86_GOLDFISH
464464

465-
config RETPOLINE
466-
bool "Avoid speculative indirect branches in kernel"
467-
select OBJTOOL if HAVE_OBJTOOL
468-
default y
469-
help
470-
Compile kernel with the retpoline compiler options to guard against
471-
kernel-to-user data leaks by avoiding speculative indirect
472-
branches. Requires a compiler with -mindirect-branch=thunk-extern
473-
support for full protection. The kernel may run slower.
474-
475-
config CC_HAS_SLS
476-
def_bool $(cc-option,-mharden-sls=all)
477-
478-
config CC_HAS_RETURN_THUNK
479-
def_bool $(cc-option,-mfunction-return=thunk-extern)
480-
481-
config SLS
482-
bool "Mitigate Straight-Line-Speculation"
483-
depends on CC_HAS_SLS && X86_64
484-
select OBJTOOL if HAVE_OBJTOOL
485-
default n
486-
help
487-
Compile the kernel with straight-line-speculation options to guard
488-
against straight line speculation. The kernel image might be slightly
489-
larger.
490-
491465
config X86_CPU_RESCTRL
492466
bool "x86 CPU resource control support"
493467
depends on X86 && (CPU_SUP_INTEL || CPU_SUP_AMD)
@@ -2456,6 +2430,91 @@ source "kernel/livepatch/Kconfig"
24562430

24572431
endmenu
24582432

2433+
config CC_HAS_SLS
2434+
def_bool $(cc-option,-mharden-sls=all)
2435+
2436+
config CC_HAS_RETURN_THUNK
2437+
def_bool $(cc-option,-mfunction-return=thunk-extern)
2438+
2439+
menuconfig SPECULATION_MITIGATIONS
2440+
bool "Mitigations for speculative execution vulnerabilities"
2441+
default y
2442+
help
2443+
Say Y here to enable options which enable mitigations for
2444+
speculative execution hardware vulnerabilities.
2445+
2446+
If you say N, all mitigations will be disabled. You really
2447+
should know what you are doing to say so.
2448+
2449+
if SPECULATION_MITIGATIONS
2450+
2451+
config PAGE_TABLE_ISOLATION
2452+
bool "Remove the kernel mapping in user mode"
2453+
default y
2454+
depends on (X86_64 || X86_PAE)
2455+
help
2456+
This feature reduces the number of hardware side channels by
2457+
ensuring that the majority of kernel addresses are not mapped
2458+
into userspace.
2459+
2460+
See Documentation/x86/pti.rst for more details.
2461+
2462+
config RETPOLINE
2463+
bool "Avoid speculative indirect branches in kernel"
2464+
select OBJTOOL if HAVE_OBJTOOL
2465+
default y
2466+
help
2467+
Compile kernel with the retpoline compiler options to guard against
2468+
kernel-to-user data leaks by avoiding speculative indirect
2469+
branches. Requires a compiler with -mindirect-branch=thunk-extern
2470+
support for full protection. The kernel may run slower.
2471+
2472+
config RETHUNK
2473+
bool "Enable return-thunks"
2474+
depends on RETPOLINE && CC_HAS_RETURN_THUNK
2475+
select OBJTOOL if HAVE_OBJTOOL
2476+
default y
2477+
help
2478+
Compile the kernel with the return-thunks compiler option to guard
2479+
against kernel-to-user data leaks by avoiding return speculation.
2480+
Requires a compiler with -mfunction-return=thunk-extern
2481+
support for full protection. The kernel may run slower.
2482+
2483+
config CPU_UNRET_ENTRY
2484+
bool "Enable UNRET on kernel entry"
2485+
depends on CPU_SUP_AMD && RETHUNK
2486+
default y
2487+
help
2488+
Compile the kernel with support for the retbleed=unret mitigation.
2489+
2490+
config CPU_IBPB_ENTRY
2491+
bool "Enable IBPB on kernel entry"
2492+
depends on CPU_SUP_AMD
2493+
default y
2494+
help
2495+
Compile the kernel with support for the retbleed=ibpb mitigation.
2496+
2497+
config CPU_IBRS_ENTRY
2498+
bool "Enable IBRS on kernel entry"
2499+
depends on CPU_SUP_INTEL
2500+
default y
2501+
help
2502+
Compile the kernel with support for the spectre_v2=ibrs mitigation.
2503+
This mitigates both spectre_v2 and retbleed at great cost to
2504+
performance.
2505+
2506+
config SLS
2507+
bool "Mitigate Straight-Line-Speculation"
2508+
depends on CC_HAS_SLS && X86_64
2509+
select OBJTOOL if HAVE_OBJTOOL
2510+
default n
2511+
help
2512+
Compile the kernel with straight-line-speculation options to guard
2513+
against straight line speculation. The kernel image might be slightly
2514+
larger.
2515+
2516+
endif
2517+
24592518
config ARCH_HAS_ADD_PAGES
24602519
def_bool y
24612520
depends on ARCH_ENABLE_MEMORY_HOTPLUG

arch/x86/Makefile

+6-2
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,18 @@ endif
1515
ifdef CONFIG_CC_IS_GCC
1616
RETPOLINE_CFLAGS := $(call cc-option,-mindirect-branch=thunk-extern -mindirect-branch-register)
1717
RETPOLINE_CFLAGS += $(call cc-option,-mindirect-branch-cs-prefix)
18-
RETPOLINE_CFLAGS += $(call cc-option,-mfunction-return=thunk-extern)
1918
RETPOLINE_VDSO_CFLAGS := $(call cc-option,-mindirect-branch=thunk-inline -mindirect-branch-register)
2019
endif
2120
ifdef CONFIG_CC_IS_CLANG
2221
RETPOLINE_CFLAGS := -mretpoline-external-thunk
2322
RETPOLINE_VDSO_CFLAGS := -mretpoline
24-
RETPOLINE_CFLAGS += $(call cc-option,-mfunction-return=thunk-extern)
2523
endif
24+
25+
ifdef CONFIG_RETHUNK
26+
RETHUNK_CFLAGS := -mfunction-return=thunk-extern
27+
RETPOLINE_CFLAGS += $(RETHUNK_CFLAGS)
28+
endif
29+
2630
export RETPOLINE_CFLAGS
2731
export RETPOLINE_VDSO_CFLAGS
2832

arch/x86/entry/calling.h

+4
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@ For 32-bit we have the following conventions - kernel is built with
297297
* Assumes x86_spec_ctrl_{base,current} to have SPEC_CTRL_IBRS set.
298298
*/
299299
.macro IBRS_ENTER save_reg
300+
#ifdef CONFIG_CPU_IBRS_ENTRY
300301
ALTERNATIVE "jmp .Lend_\@", "", X86_FEATURE_KERNEL_IBRS
301302
movl $MSR_IA32_SPEC_CTRL, %ecx
302303

@@ -317,13 +318,15 @@ For 32-bit we have the following conventions - kernel is built with
317318
shr $32, %rdx
318319
wrmsr
319320
.Lend_\@:
321+
#endif
320322
.endm
321323

322324
/*
323325
* Similar to IBRS_ENTER, requires KERNEL GS,CR3 and clobbers (AX, CX, DX)
324326
* regs. Must be called after the last RET.
325327
*/
326328
.macro IBRS_EXIT save_reg
329+
#ifdef CONFIG_CPU_IBRS_ENTRY
327330
ALTERNATIVE "jmp .Lend_\@", "", X86_FEATURE_KERNEL_IBRS
328331
movl $MSR_IA32_SPEC_CTRL, %ecx
329332

@@ -338,6 +341,7 @@ For 32-bit we have the following conventions - kernel is built with
338341
shr $32, %rdx
339342
wrmsr
340343
.Lend_\@:
344+
#endif
341345
.endm
342346

343347
/*

arch/x86/include/asm/disabled-features.h

+14-4
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,19 @@
5454
# define DISABLE_RETPOLINE 0
5555
#else
5656
# define DISABLE_RETPOLINE ((1 << (X86_FEATURE_RETPOLINE & 31)) | \
57-
(1 << (X86_FEATURE_RETPOLINE_LFENCE & 31)) | \
58-
(1 << (X86_FEATURE_RETHUNK & 31)) | \
59-
(1 << (X86_FEATURE_UNRET & 31)))
57+
(1 << (X86_FEATURE_RETPOLINE_LFENCE & 31)))
58+
#endif
59+
60+
#ifdef CONFIG_RETHUNK
61+
# define DISABLE_RETHUNK 0
62+
#else
63+
# define DISABLE_RETHUNK (1 << (X86_FEATURE_RETHUNK & 31))
64+
#endif
65+
66+
#ifdef CONFIG_CPU_UNRET_ENTRY
67+
# define DISABLE_UNRET 0
68+
#else
69+
# define DISABLE_UNRET (1 << (X86_FEATURE_UNRET & 31))
6070
#endif
6171

6272
#ifdef CONFIG_INTEL_IOMMU_SVM
@@ -91,7 +101,7 @@
91101
#define DISABLED_MASK8 (DISABLE_TDX_GUEST)
92102
#define DISABLED_MASK9 (DISABLE_SGX)
93103
#define DISABLED_MASK10 0
94-
#define DISABLED_MASK11 (DISABLE_RETPOLINE)
104+
#define DISABLED_MASK11 (DISABLE_RETPOLINE|DISABLE_RETHUNK|DISABLE_UNRET)
95105
#define DISABLED_MASK12 0
96106
#define DISABLED_MASK13 0
97107
#define DISABLED_MASK14 0

arch/x86/include/asm/linkage.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
#define __ALIGN_STR __stringify(__ALIGN)
2020
#endif
2121

22-
#if defined(CONFIG_RETPOLINE) && !defined(__DISABLE_EXPORTS) && !defined(BUILD_VDSO)
22+
#if defined(CONFIG_RETHUNK) && !defined(__DISABLE_EXPORTS) && !defined(BUILD_VDSO)
2323
#define RET jmp __x86_return_thunk
2424
#else /* CONFIG_RETPOLINE */
2525
#ifdef CONFIG_SLS
@@ -31,7 +31,7 @@
3131

3232
#else /* __ASSEMBLY__ */
3333

34-
#if defined(CONFIG_RETPOLINE) && !defined(__DISABLE_EXPORTS) && !defined(BUILD_VDSO)
34+
#if defined(CONFIG_RETHUNK) && !defined(__DISABLE_EXPORTS) && !defined(BUILD_VDSO)
3535
#define ASM_RET "jmp __x86_return_thunk\n\t"
3636
#else /* CONFIG_RETPOLINE */
3737
#ifdef CONFIG_SLS

arch/x86/include/asm/nospec-branch.h

+8-2
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,12 @@
127127
.Lskip_rsb_\@:
128128
.endm
129129

130+
#ifdef CONFIG_CPU_UNRET_ENTRY
131+
#define CALL_ZEN_UNTRAIN_RET "call zen_untrain_ret"
132+
#else
133+
#define CALL_ZEN_UNTRAIN_RET ""
134+
#endif
135+
130136
/*
131137
* Mitigate RETBleed for AMD/Hygon Zen uarch. Requires KERNEL CR3 because the
132138
* return thunk isn't mapped into the userspace tables (then again, AMD
@@ -139,10 +145,10 @@
139145
* where we have a stack but before any RET instruction.
140146
*/
141147
.macro UNTRAIN_RET
142-
#ifdef CONFIG_RETPOLINE
148+
#if defined(CONFIG_CPU_UNRET_ENTRY) || defined(CONFIG_CPU_IBPB_ENTRY)
143149
ANNOTATE_UNRET_END
144150
ALTERNATIVE_2 "", \
145-
"call zen_untrain_ret", X86_FEATURE_UNRET, \
151+
CALL_ZEN_UNTRAIN_RET, X86_FEATURE_UNRET, \
146152
"call entry_ibpb", X86_FEATURE_ENTRY_IBPB
147153
#endif
148154
.endm

arch/x86/include/asm/static_call.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
#define ARCH_DEFINE_STATIC_CALL_TRAMP(name, func) \
4747
__ARCH_DEFINE_STATIC_CALL_TRAMP(name, ".byte 0xe9; .long " #func " - (. + 4)")
4848

49-
#ifdef CONFIG_RETPOLINE
49+
#ifdef CONFIG_RETHUNK
5050
#define ARCH_DEFINE_STATIC_CALL_NULL_TRAMP(name) \
5151
__ARCH_DEFINE_STATIC_CALL_TRAMP(name, "jmp __x86_return_thunk")
5252
#else

arch/x86/kernel/alternative.c

+5
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,7 @@ void __init_or_module noinline apply_retpolines(s32 *start, s32 *end)
508508
}
509509
}
510510

511+
#ifdef CONFIG_RETHUNK
511512
/*
512513
* Rewrite the compiler generated return thunk tail-calls.
513514
*
@@ -569,6 +570,10 @@ void __init_or_module noinline apply_returns(s32 *start, s32 *end)
569570
}
570571
}
571572
}
573+
#else
574+
void __init_or_module noinline apply_returns(s32 *start, s32 *end) { }
575+
#endif /* CONFIG_RETHUNK */
576+
572577
#else /* !CONFIG_RETPOLINE || !CONFIG_OBJTOOL */
573578

574579
void __init_or_module noinline apply_retpolines(s32 *start, s32 *end) { }

arch/x86/kernel/cpu/amd.c

+2
Original file line numberDiff line numberDiff line change
@@ -864,6 +864,7 @@ static void init_amd_bd(struct cpuinfo_x86 *c)
864864

865865
void init_spectral_chicken(struct cpuinfo_x86 *c)
866866
{
867+
#ifdef CONFIG_CPU_UNRET_ENTRY
867868
u64 value;
868869

869870
/*
@@ -880,6 +881,7 @@ void init_spectral_chicken(struct cpuinfo_x86 *c)
880881
wrmsrl_safe(MSR_ZEN2_SPECTRAL_CHICKEN, value);
881882
}
882883
}
884+
#endif
883885
}
884886

885887
static void init_amd_zn(struct cpuinfo_x86 *c)

arch/x86/kernel/cpu/bugs.c

+27-15
Original file line numberDiff line numberDiff line change
@@ -842,7 +842,6 @@ static int __init retbleed_parse_cmdline(char *str)
842842
early_param("retbleed", retbleed_parse_cmdline);
843843

844844
#define RETBLEED_UNTRAIN_MSG "WARNING: BTB untrained return thunk mitigation is only effective on AMD/Hygon!\n"
845-
#define RETBLEED_COMPILER_MSG "WARNING: kernel not compiled with RETPOLINE or -mfunction-return capable compiler; falling back to IBPB!\n"
846845
#define RETBLEED_INTEL_MSG "WARNING: Spectre v2 mitigation leaves CPU vulnerable to RETBleed attacks, data leaks possible!\n"
847846

848847
static void __init retbleed_select_mitigation(void)
@@ -857,18 +856,33 @@ static void __init retbleed_select_mitigation(void)
857856
return;
858857

859858
case RETBLEED_CMD_UNRET:
860-
retbleed_mitigation = RETBLEED_MITIGATION_UNRET;
859+
if (IS_ENABLED(CONFIG_CPU_UNRET_ENTRY)) {
860+
retbleed_mitigation = RETBLEED_MITIGATION_UNRET;
861+
} else {
862+
pr_err("WARNING: kernel not compiled with CPU_UNRET_ENTRY.\n");
863+
goto do_cmd_auto;
864+
}
861865
break;
862866

863867
case RETBLEED_CMD_IBPB:
864-
retbleed_mitigation = RETBLEED_MITIGATION_IBPB;
868+
if (IS_ENABLED(CONFIG_CPU_IBPB_ENTRY)) {
869+
retbleed_mitigation = RETBLEED_MITIGATION_IBPB;
870+
} else {
871+
pr_err("WARNING: kernel not compiled with CPU_IBPB_ENTRY.\n");
872+
goto do_cmd_auto;
873+
}
865874
break;
866875

876+
do_cmd_auto:
867877
case RETBLEED_CMD_AUTO:
868878
default:
869879
if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD ||
870-
boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)
871-
retbleed_mitigation = RETBLEED_MITIGATION_UNRET;
880+
boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) {
881+
if (IS_ENABLED(CONFIG_CPU_UNRET_ENTRY))
882+
retbleed_mitigation = RETBLEED_MITIGATION_UNRET;
883+
else if (IS_ENABLED(CONFIG_CPU_IBPB_ENTRY))
884+
retbleed_mitigation = RETBLEED_MITIGATION_IBPB;
885+
}
872886

873887
/*
874888
* The Intel mitigation (IBRS or eIBRS) was already selected in
@@ -881,14 +895,6 @@ static void __init retbleed_select_mitigation(void)
881895

882896
switch (retbleed_mitigation) {
883897
case RETBLEED_MITIGATION_UNRET:
884-
885-
if (!IS_ENABLED(CONFIG_RETPOLINE) ||
886-
!IS_ENABLED(CONFIG_CC_HAS_RETURN_THUNK)) {
887-
pr_err(RETBLEED_COMPILER_MSG);
888-
retbleed_mitigation = RETBLEED_MITIGATION_IBPB;
889-
goto retbleed_force_ibpb;
890-
}
891-
892898
setup_force_cpu_cap(X86_FEATURE_RETHUNK);
893899
setup_force_cpu_cap(X86_FEATURE_UNRET);
894900

@@ -900,7 +906,6 @@ static void __init retbleed_select_mitigation(void)
900906
break;
901907

902908
case RETBLEED_MITIGATION_IBPB:
903-
retbleed_force_ibpb:
904909
setup_force_cpu_cap(X86_FEATURE_ENTRY_IBPB);
905910
mitigate_smt = true;
906911
break;
@@ -1271,6 +1276,12 @@ static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void)
12711276
return SPECTRE_V2_CMD_AUTO;
12721277
}
12731278

1279+
if (cmd == SPECTRE_V2_CMD_IBRS && !IS_ENABLED(CONFIG_CPU_IBRS_ENTRY)) {
1280+
pr_err("%s selected but not compiled in. Switching to AUTO select\n",
1281+
mitigation_options[i].option);
1282+
return SPECTRE_V2_CMD_AUTO;
1283+
}
1284+
12741285
if (cmd == SPECTRE_V2_CMD_IBRS && boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) {
12751286
pr_err("%s selected but not Intel CPU. Switching to AUTO select\n",
12761287
mitigation_options[i].option);
@@ -1328,7 +1339,8 @@ static void __init spectre_v2_select_mitigation(void)
13281339
break;
13291340
}
13301341

1331-
if (boot_cpu_has_bug(X86_BUG_RETBLEED) &&
1342+
if (IS_ENABLED(CONFIG_CPU_IBRS_ENTRY) &&
1343+
boot_cpu_has_bug(X86_BUG_RETBLEED) &&
13321344
retbleed_cmd != RETBLEED_CMD_OFF &&
13331345
boot_cpu_has(X86_FEATURE_IBRS) &&
13341346
boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) {

arch/x86/kernel/static_call.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ void arch_static_call_transform(void *site, void *tramp, void *func, bool tail)
126126
}
127127
EXPORT_SYMBOL_GPL(arch_static_call_transform);
128128

129-
#ifdef CONFIG_RETPOLINE
129+
#ifdef CONFIG_RETHUNK
130130
/*
131131
* This is called by apply_returns() to fix up static call trampolines,
132132
* specifically ARCH_DEFINE_STATIC_CALL_NULL_TRAMP which is recorded as

0 commit comments

Comments
 (0)