Skip to content

Commit 963d0d6

Browse files
committed
Merge tag 'x86_bugs_for_v6.12_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 hw mitigation updates from Borislav Petkov: - Add CONFIG_ option for every hw CPU mitigation. The intent is to support configurations and scenarios where the mitigations code is irrelevant - Other small fixlets and improvements * tag 'x86_bugs_for_v6.12_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/bugs: Fix handling when SRSO mitigation is disabled x86/bugs: Add missing NO_SSB flag Documentation/srso: Document a method for checking safe RET operates properly x86/bugs: Add a separate config for GDS x86/bugs: Remove GDS Force Kconfig option x86/bugs: Add a separate config for SSB x86/bugs: Add a separate config for Spectre V2 x86/bugs: Add a separate config for SRBDS x86/bugs: Add a separate config for Spectre v1 x86/bugs: Add a separate config for RETBLEED x86/bugs: Add a separate config for L1TF x86/bugs: Add a separate config for MMIO Stable Data x86/bugs: Add a separate config for TAA x86/bugs: Add a separate config for MDS
2 parents d580d74 + 1dbb6b1 commit 963d0d6

File tree

6 files changed

+281
-48
lines changed

6 files changed

+281
-48
lines changed

Documentation/admin-guide/hw-vuln/srso.rst

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,3 +158,72 @@ poisoned BTB entry and using that safe one for all function returns.
158158
In older Zen1 and Zen2, this is accomplished using a reinterpretation
159159
technique similar to Retbleed one: srso_untrain_ret() and
160160
srso_safe_ret().
161+
162+
Checking the safe RET mitigation actually works
163+
-----------------------------------------------
164+
165+
In case one wants to validate whether the SRSO safe RET mitigation works
166+
on a kernel, one could use two performance counters
167+
168+
* PMC_0xc8 - Count of RET/RET lw retired
169+
* PMC_0xc9 - Count of RET/RET lw retired mispredicted
170+
171+
and compare the number of RETs retired properly vs those retired
172+
mispredicted, in kernel mode. Another way of specifying those events
173+
is::
174+
175+
# perf list ex_ret_near_ret
176+
177+
List of pre-defined events (to be used in -e or -M):
178+
179+
core:
180+
ex_ret_near_ret
181+
[Retired Near Returns]
182+
ex_ret_near_ret_mispred
183+
[Retired Near Returns Mispredicted]
184+
185+
Either the command using the event mnemonics::
186+
187+
# perf stat -e ex_ret_near_ret:k -e ex_ret_near_ret_mispred:k sleep 10s
188+
189+
or using the raw PMC numbers::
190+
191+
# perf stat -e cpu/event=0xc8,umask=0/k -e cpu/event=0xc9,umask=0/k sleep 10s
192+
193+
should give the same amount. I.e., every RET retired should be
194+
mispredicted::
195+
196+
[root@brent: ~/kernel/linux/tools/perf> ./perf stat -e cpu/event=0xc8,umask=0/k -e cpu/event=0xc9,umask=0/k sleep 10s
197+
198+
Performance counter stats for 'sleep 10s':
199+
200+
137,167 cpu/event=0xc8,umask=0/k
201+
137,173 cpu/event=0xc9,umask=0/k
202+
203+
10.004110303 seconds time elapsed
204+
205+
0.000000000 seconds user
206+
0.004462000 seconds sys
207+
208+
vs the case when the mitigation is disabled (spec_rstack_overflow=off)
209+
or not functioning properly, showing usually a lot smaller number of
210+
mispredicted retired RETs vs the overall count of retired RETs during
211+
a workload::
212+
213+
[root@brent: ~/kernel/linux/tools/perf> ./perf stat -e cpu/event=0xc8,umask=0/k -e cpu/event=0xc9,umask=0/k sleep 10s
214+
215+
Performance counter stats for 'sleep 10s':
216+
217+
201,627 cpu/event=0xc8,umask=0/k
218+
4,074 cpu/event=0xc9,umask=0/k
219+
220+
10.003267252 seconds time elapsed
221+
222+
0.002729000 seconds user
223+
0.000000000 seconds sys
224+
225+
Also, there is a selftest which performs the above, go to
226+
tools/testing/selftests/x86/ and do::
227+
228+
make srso
229+
./srso

arch/x86/Kconfig

Lines changed: 108 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2610,24 +2610,15 @@ config MITIGATION_SLS
26102610
against straight line speculation. The kernel image might be slightly
26112611
larger.
26122612

2613-
config MITIGATION_GDS_FORCE
2614-
bool "Force GDS Mitigation"
2613+
config MITIGATION_GDS
2614+
bool "Mitigate Gather Data Sampling"
26152615
depends on CPU_SUP_INTEL
2616-
default n
2616+
default y
26172617
help
2618-
Gather Data Sampling (GDS) is a hardware vulnerability which allows
2619-
unprivileged speculative access to data which was previously stored in
2620-
vector registers.
2621-
2622-
This option is equivalent to setting gather_data_sampling=force on the
2623-
command line. The microcode mitigation is used if present, otherwise
2624-
AVX is disabled as a mitigation. On affected systems that are missing
2625-
the microcode any userspace code that unconditionally uses AVX will
2626-
break with this option set.
2627-
2628-
Setting this option on systems not vulnerable to GDS has no effect.
2629-
2630-
If in doubt, say N.
2618+
Enable mitigation for Gather Data Sampling (GDS). GDS is a hardware
2619+
vulnerability which allows unprivileged speculative access to data
2620+
which was previously stored in vector registers. The attacker uses gather
2621+
instructions to infer the stale vector register data.
26312622

26322623
config MITIGATION_RFDS
26332624
bool "RFDS Mitigation"
@@ -2650,6 +2641,107 @@ config MITIGATION_SPECTRE_BHI
26502641
indirect branches.
26512642
See <file:Documentation/admin-guide/hw-vuln/spectre.rst>
26522643

2644+
config MITIGATION_MDS
2645+
bool "Mitigate Microarchitectural Data Sampling (MDS) hardware bug"
2646+
depends on CPU_SUP_INTEL
2647+
default y
2648+
help
2649+
Enable mitigation for Microarchitectural Data Sampling (MDS). MDS is
2650+
a hardware vulnerability which allows unprivileged speculative access
2651+
to data which is available in various CPU internal buffers.
2652+
See also <file:Documentation/admin-guide/hw-vuln/mds.rst>
2653+
2654+
config MITIGATION_TAA
2655+
bool "Mitigate TSX Asynchronous Abort (TAA) hardware bug"
2656+
depends on CPU_SUP_INTEL
2657+
default y
2658+
help
2659+
Enable mitigation for TSX Asynchronous Abort (TAA). TAA is a hardware
2660+
vulnerability that allows unprivileged speculative access to data
2661+
which is available in various CPU internal buffers by using
2662+
asynchronous aborts within an Intel TSX transactional region.
2663+
See also <file:Documentation/admin-guide/hw-vuln/tsx_async_abort.rst>
2664+
2665+
config MITIGATION_MMIO_STALE_DATA
2666+
bool "Mitigate MMIO Stale Data hardware bug"
2667+
depends on CPU_SUP_INTEL
2668+
default y
2669+
help
2670+
Enable mitigation for MMIO Stale Data hardware bugs. Processor MMIO
2671+
Stale Data Vulnerabilities are a class of memory-mapped I/O (MMIO)
2672+
vulnerabilities that can expose data. The vulnerabilities require the
2673+
attacker to have access to MMIO.
2674+
See also
2675+
<file:Documentation/admin-guide/hw-vuln/processor_mmio_stale_data.rst>
2676+
2677+
config MITIGATION_L1TF
2678+
bool "Mitigate L1 Terminal Fault (L1TF) hardware bug"
2679+
depends on CPU_SUP_INTEL
2680+
default y
2681+
help
2682+
Mitigate L1 Terminal Fault (L1TF) hardware bug. L1 Terminal Fault is a
2683+
hardware vulnerability which allows unprivileged speculative access to data
2684+
available in the Level 1 Data Cache.
2685+
See <file:Documentation/admin-guide/hw-vuln/l1tf.rst
2686+
2687+
config MITIGATION_RETBLEED
2688+
bool "Mitigate RETBleed hardware bug"
2689+
depends on (CPU_SUP_INTEL && MITIGATION_SPECTRE_V2) || MITIGATION_UNRET_ENTRY || MITIGATION_IBPB_ENTRY
2690+
default y
2691+
help
2692+
Enable mitigation for RETBleed (Arbitrary Speculative Code Execution
2693+
with Return Instructions) vulnerability. RETBleed is a speculative
2694+
execution attack which takes advantage of microarchitectural behavior
2695+
in many modern microprocessors, similar to Spectre v2. An
2696+
unprivileged attacker can use these flaws to bypass conventional
2697+
memory security restrictions to gain read access to privileged memory
2698+
that would otherwise be inaccessible.
2699+
2700+
config MITIGATION_SPECTRE_V1
2701+
bool "Mitigate SPECTRE V1 hardware bug"
2702+
default y
2703+
help
2704+
Enable mitigation for Spectre V1 (Bounds Check Bypass). Spectre V1 is a
2705+
class of side channel attacks that takes advantage of speculative
2706+
execution that bypasses conditional branch instructions used for
2707+
memory access bounds check.
2708+
See also <file:Documentation/admin-guide/hw-vuln/spectre.rst>
2709+
2710+
config MITIGATION_SPECTRE_V2
2711+
bool "Mitigate SPECTRE V2 hardware bug"
2712+
default y
2713+
help
2714+
Enable mitigation for Spectre V2 (Branch Target Injection). Spectre
2715+
V2 is a class of side channel attacks that takes advantage of
2716+
indirect branch predictors inside the processor. In Spectre variant 2
2717+
attacks, the attacker can steer speculative indirect branches in the
2718+
victim to gadget code by poisoning the branch target buffer of a CPU
2719+
used for predicting indirect branch addresses.
2720+
See also <file:Documentation/admin-guide/hw-vuln/spectre.rst>
2721+
2722+
config MITIGATION_SRBDS
2723+
bool "Mitigate Special Register Buffer Data Sampling (SRBDS) hardware bug"
2724+
depends on CPU_SUP_INTEL
2725+
default y
2726+
help
2727+
Enable mitigation for Special Register Buffer Data Sampling (SRBDS).
2728+
SRBDS is a hardware vulnerability that allows Microarchitectural Data
2729+
Sampling (MDS) techniques to infer values returned from special
2730+
register accesses. An unprivileged user can extract values returned
2731+
from RDRAND and RDSEED executed on another core or sibling thread
2732+
using MDS techniques.
2733+
See also
2734+
<file:Documentation/admin-guide/hw-vuln/special-register-buffer-data-sampling.rst>
2735+
2736+
config MITIGATION_SSB
2737+
bool "Mitigate Speculative Store Bypass (SSB) hardware bug"
2738+
default y
2739+
help
2740+
Enable mitigation for Speculative Store Bypass (SSB). SSB is a
2741+
hardware security vulnerability and its exploitation takes advantage
2742+
of speculative execution in a similar way to the Meltdown and Spectre
2743+
security vulnerabilities.
2744+
26532745
endif
26542746

26552747
config ARCH_HAS_ADD_PAGES

arch/x86/kernel/cpu/bugs.c

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,8 @@ static void x86_amd_ssb_disable(void)
233233
#define pr_fmt(fmt) "MDS: " fmt
234234

235235
/* Default mitigation for MDS-affected CPUs */
236-
static enum mds_mitigations mds_mitigation __ro_after_init = MDS_MITIGATION_FULL;
236+
static enum mds_mitigations mds_mitigation __ro_after_init =
237+
IS_ENABLED(CONFIG_MITIGATION_MDS) ? MDS_MITIGATION_FULL : MDS_MITIGATION_OFF;
237238
static bool mds_nosmt __ro_after_init = false;
238239

239240
static const char * const mds_strings[] = {
@@ -293,7 +294,8 @@ enum taa_mitigations {
293294
};
294295

295296
/* Default mitigation for TAA-affected CPUs */
296-
static enum taa_mitigations taa_mitigation __ro_after_init = TAA_MITIGATION_VERW;
297+
static enum taa_mitigations taa_mitigation __ro_after_init =
298+
IS_ENABLED(CONFIG_MITIGATION_TAA) ? TAA_MITIGATION_VERW : TAA_MITIGATION_OFF;
297299
static bool taa_nosmt __ro_after_init;
298300

299301
static const char * const taa_strings[] = {
@@ -391,7 +393,8 @@ enum mmio_mitigations {
391393
};
392394

393395
/* Default mitigation for Processor MMIO Stale Data vulnerabilities */
394-
static enum mmio_mitigations mmio_mitigation __ro_after_init = MMIO_MITIGATION_VERW;
396+
static enum mmio_mitigations mmio_mitigation __ro_after_init =
397+
IS_ENABLED(CONFIG_MITIGATION_MMIO_STALE_DATA) ? MMIO_MITIGATION_VERW : MMIO_MITIGATION_OFF;
395398
static bool mmio_nosmt __ro_after_init = false;
396399

397400
static const char * const mmio_strings[] = {
@@ -605,7 +608,8 @@ enum srbds_mitigations {
605608
SRBDS_MITIGATION_HYPERVISOR,
606609
};
607610

608-
static enum srbds_mitigations srbds_mitigation __ro_after_init = SRBDS_MITIGATION_FULL;
611+
static enum srbds_mitigations srbds_mitigation __ro_after_init =
612+
IS_ENABLED(CONFIG_MITIGATION_SRBDS) ? SRBDS_MITIGATION_FULL : SRBDS_MITIGATION_OFF;
609613

610614
static const char * const srbds_strings[] = {
611615
[SRBDS_MITIGATION_OFF] = "Vulnerable",
@@ -731,11 +735,8 @@ enum gds_mitigations {
731735
GDS_MITIGATION_HYPERVISOR,
732736
};
733737

734-
#if IS_ENABLED(CONFIG_MITIGATION_GDS_FORCE)
735-
static enum gds_mitigations gds_mitigation __ro_after_init = GDS_MITIGATION_FORCE;
736-
#else
737-
static enum gds_mitigations gds_mitigation __ro_after_init = GDS_MITIGATION_FULL;
738-
#endif
738+
static enum gds_mitigations gds_mitigation __ro_after_init =
739+
IS_ENABLED(CONFIG_MITIGATION_GDS) ? GDS_MITIGATION_FULL : GDS_MITIGATION_OFF;
739740

740741
static const char * const gds_strings[] = {
741742
[GDS_MITIGATION_OFF] = "Vulnerable",
@@ -871,7 +872,8 @@ enum spectre_v1_mitigation {
871872
};
872873

873874
static enum spectre_v1_mitigation spectre_v1_mitigation __ro_after_init =
874-
SPECTRE_V1_MITIGATION_AUTO;
875+
IS_ENABLED(CONFIG_MITIGATION_SPECTRE_V1) ?
876+
SPECTRE_V1_MITIGATION_AUTO : SPECTRE_V1_MITIGATION_NONE;
875877

876878
static const char * const spectre_v1_strings[] = {
877879
[SPECTRE_V1_MITIGATION_NONE] = "Vulnerable: __user pointer sanitization and usercopy barriers only; no swapgs barriers",
@@ -986,7 +988,7 @@ static const char * const retbleed_strings[] = {
986988
static enum retbleed_mitigation retbleed_mitigation __ro_after_init =
987989
RETBLEED_MITIGATION_NONE;
988990
static enum retbleed_mitigation_cmd retbleed_cmd __ro_after_init =
989-
RETBLEED_CMD_AUTO;
991+
IS_ENABLED(CONFIG_MITIGATION_RETBLEED) ? RETBLEED_CMD_AUTO : RETBLEED_CMD_OFF;
990992

991993
static int __ro_after_init retbleed_nosmt = false;
992994

@@ -1447,17 +1449,18 @@ static void __init spec_v2_print_cond(const char *reason, bool secure)
14471449

14481450
static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void)
14491451
{
1450-
enum spectre_v2_mitigation_cmd cmd = SPECTRE_V2_CMD_AUTO;
1452+
enum spectre_v2_mitigation_cmd cmd;
14511453
char arg[20];
14521454
int ret, i;
14531455

1456+
cmd = IS_ENABLED(CONFIG_MITIGATION_SPECTRE_V2) ? SPECTRE_V2_CMD_AUTO : SPECTRE_V2_CMD_NONE;
14541457
if (cmdline_find_option_bool(boot_command_line, "nospectre_v2") ||
14551458
cpu_mitigations_off())
14561459
return SPECTRE_V2_CMD_NONE;
14571460

14581461
ret = cmdline_find_option(boot_command_line, "spectre_v2", arg, sizeof(arg));
14591462
if (ret < 0)
1460-
return SPECTRE_V2_CMD_AUTO;
1463+
return cmd;
14611464

14621465
for (i = 0; i < ARRAY_SIZE(mitigation_options); i++) {
14631466
if (!match_option(arg, ret, mitigation_options[i].option))
@@ -1467,8 +1470,8 @@ static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void)
14671470
}
14681471

14691472
if (i >= ARRAY_SIZE(mitigation_options)) {
1470-
pr_err("unknown option (%s). Switching to AUTO select\n", arg);
1471-
return SPECTRE_V2_CMD_AUTO;
1473+
pr_err("unknown option (%s). Switching to default mode\n", arg);
1474+
return cmd;
14721475
}
14731476

14741477
if ((cmd == SPECTRE_V2_CMD_RETPOLINE ||
@@ -2021,18 +2024,20 @@ static const struct {
20212024

20222025
static enum ssb_mitigation_cmd __init ssb_parse_cmdline(void)
20232026
{
2024-
enum ssb_mitigation_cmd cmd = SPEC_STORE_BYPASS_CMD_AUTO;
2027+
enum ssb_mitigation_cmd cmd;
20252028
char arg[20];
20262029
int ret, i;
20272030

2031+
cmd = IS_ENABLED(CONFIG_MITIGATION_SSB) ?
2032+
SPEC_STORE_BYPASS_CMD_AUTO : SPEC_STORE_BYPASS_CMD_NONE;
20282033
if (cmdline_find_option_bool(boot_command_line, "nospec_store_bypass_disable") ||
20292034
cpu_mitigations_off()) {
20302035
return SPEC_STORE_BYPASS_CMD_NONE;
20312036
} else {
20322037
ret = cmdline_find_option(boot_command_line, "spec_store_bypass_disable",
20332038
arg, sizeof(arg));
20342039
if (ret < 0)
2035-
return SPEC_STORE_BYPASS_CMD_AUTO;
2040+
return cmd;
20362041

20372042
for (i = 0; i < ARRAY_SIZE(ssb_mitigation_options); i++) {
20382043
if (!match_option(arg, ret, ssb_mitigation_options[i].option))
@@ -2043,8 +2048,8 @@ static enum ssb_mitigation_cmd __init ssb_parse_cmdline(void)
20432048
}
20442049

20452050
if (i >= ARRAY_SIZE(ssb_mitigation_options)) {
2046-
pr_err("unknown option (%s). Switching to AUTO select\n", arg);
2047-
return SPEC_STORE_BYPASS_CMD_AUTO;
2051+
pr_err("unknown option (%s). Switching to default mode\n", arg);
2052+
return cmd;
20482053
}
20492054
}
20502055

@@ -2371,7 +2376,8 @@ EXPORT_SYMBOL_GPL(itlb_multihit_kvm_mitigation);
23712376
#define pr_fmt(fmt) "L1TF: " fmt
23722377

23732378
/* Default mitigation for L1TF-affected CPUs */
2374-
enum l1tf_mitigations l1tf_mitigation __ro_after_init = L1TF_MITIGATION_FLUSH;
2379+
enum l1tf_mitigations l1tf_mitigation __ro_after_init =
2380+
IS_ENABLED(CONFIG_MITIGATION_L1TF) ? L1TF_MITIGATION_FLUSH : L1TF_MITIGATION_OFF;
23752381
#if IS_ENABLED(CONFIG_KVM_INTEL)
23762382
EXPORT_SYMBOL_GPL(l1tf_mitigation);
23772383
#endif
@@ -2551,10 +2557,9 @@ static void __init srso_select_mitigation(void)
25512557
{
25522558
bool has_microcode = boot_cpu_has(X86_FEATURE_IBPB_BRTYPE);
25532559

2554-
if (cpu_mitigations_off())
2555-
return;
2556-
2557-
if (!boot_cpu_has_bug(X86_BUG_SRSO)) {
2560+
if (!boot_cpu_has_bug(X86_BUG_SRSO) ||
2561+
cpu_mitigations_off() ||
2562+
srso_cmd == SRSO_CMD_OFF) {
25582563
if (boot_cpu_has(X86_FEATURE_SBPB))
25592564
x86_pred_cmd = PRED_CMD_SBPB;
25602565
return;
@@ -2585,11 +2590,6 @@ static void __init srso_select_mitigation(void)
25852590
}
25862591

25872592
switch (srso_cmd) {
2588-
case SRSO_CMD_OFF:
2589-
if (boot_cpu_has(X86_FEATURE_SBPB))
2590-
x86_pred_cmd = PRED_CMD_SBPB;
2591-
return;
2592-
25932593
case SRSO_CMD_MICROCODE:
25942594
if (has_microcode) {
25952595
srso_mitigation = SRSO_MITIGATION_MICROCODE;
@@ -2643,6 +2643,8 @@ static void __init srso_select_mitigation(void)
26432643
pr_err("WARNING: kernel not compiled with MITIGATION_SRSO.\n");
26442644
}
26452645
break;
2646+
default:
2647+
break;
26462648
}
26472649

26482650
out:

0 commit comments

Comments
 (0)