Skip to content
This repository was archived by the owner on Oct 31, 2024. It is now read-only.

Commit a39bfa5

Browse files
pa1guptagregkh
authored andcommitted
x86/bhi: Add BHI mitigation knob
commit ec9404e upstream. Branch history clearing software sequences and hardware control BHI_DIS_S were defined to mitigate Branch History Injection (BHI). Add cmdline spectre_bhi={on|off|auto} to control BHI mitigation: auto - Deploy the hardware mitigation BHI_DIS_S, if available. on - Deploy the hardware mitigation BHI_DIS_S, if available, otherwise deploy the software sequence at syscall entry and VMexit. off - Turn off BHI mitigation. The default is auto mode which does not deploy the software sequence mitigation. This is because of the hardening done in the syscall dispatch path, which is the likely target of BHI. Signed-off-by: Pawan Gupta <pawan.kumar.gupta@linux.intel.com> Signed-off-by: Daniel Sneddon <daniel.sneddon@linux.intel.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Alexandre Chartre <alexandre.chartre@oracle.com> Reviewed-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Daniel Sneddon <daniel.sneddon@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent a96b54b commit a39bfa5

5 files changed

Lines changed: 165 additions & 7 deletions

File tree

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

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -138,11 +138,10 @@ associated with the source address of the indirect branch. Specifically,
138138
the BHB might be shared across privilege levels even in the presence of
139139
Enhanced IBRS.
140140

141-
Currently the only known real-world BHB attack vector is via
142-
unprivileged eBPF. Therefore, it's highly recommended to not enable
143-
unprivileged eBPF, especially when eIBRS is used (without retpolines).
144-
For a full mitigation against BHB attacks, it's recommended to use
145-
retpolines (or eIBRS combined with retpolines).
141+
Previously the only known real-world BHB attack vector was via unprivileged
142+
eBPF. Further research has found attacks that don't require unprivileged eBPF.
143+
For a full mitigation against BHB attacks it is recommended to set BHI_DIS_S or
144+
use the BHB clearing sequence.
146145

147146
Attack scenarios
148147
----------------
@@ -430,6 +429,21 @@ The possible values in this file are:
430429
'PBRSB-eIBRS: Not affected' CPU is not affected by PBRSB
431430
=========================== =======================================================
432431

432+
- Branch History Injection (BHI) protection status:
433+
434+
.. list-table::
435+
436+
* - BHI: Not affected
437+
- System is not affected
438+
* - BHI: Retpoline
439+
- System is protected by retpoline
440+
* - BHI: BHI_DIS_S
441+
- System is protected by BHI_DIS_S
442+
* - BHI: SW loop
443+
- System is protected by software clearing sequence
444+
* - BHI: Syscall hardening
445+
- Syscalls are hardened against BHI
446+
433447
Full mitigation might require a microcode update from the CPU
434448
vendor. When the necessary microcode is not available, the kernel will
435449
report vulnerability.
@@ -484,7 +498,11 @@ Spectre variant 2
484498

485499
Systems which support enhanced IBRS (eIBRS) enable IBRS protection once at
486500
boot, by setting the IBRS bit, and they're automatically protected against
487-
Spectre v2 variant attacks.
501+
some Spectre v2 variant attacks. The BHB can still influence the choice of
502+
indirect branch predictor entry, and although branch predictor entries are
503+
isolated between modes when eIBRS is enabled, the BHB itself is not isolated
504+
between modes. Systems which support BHI_DIS_S will set it to protect against
505+
BHI attacks.
488506

489507
On Intel's enhanced IBRS systems, this includes cross-thread branch target
490508
injections on SMT systems (STIBP). In other words, Intel eIBRS enables
@@ -638,6 +656,21 @@ kernel command line.
638656
spectre_v2=off. Spectre variant 1 mitigations
639657
cannot be disabled.
640658

659+
spectre_bhi=
660+
661+
[X86] Control mitigation of Branch History Injection
662+
(BHI) vulnerability. Syscalls are hardened against BHI
663+
regardless of this setting. This setting affects the deployment
664+
of the HW BHI control and the SW BHB clearing sequence.
665+
666+
on
667+
unconditionally enable.
668+
off
669+
unconditionally disable.
670+
auto
671+
enable if hardware mitigation
672+
control(BHI_DIS_S) is available.
673+
641674
For spectre_v2_user see Documentation/admin-guide/kernel-parameters.txt
642675

643676
Mitigation selection guide

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6031,6 +6031,17 @@
60316031
sonypi.*= [HW] Sony Programmable I/O Control Device driver
60326032
See Documentation/admin-guide/laptops/sonypi.rst
60336033

6034+
spectre_bhi= [X86] Control mitigation of Branch History Injection
6035+
(BHI) vulnerability. Syscalls are hardened against BHI
6036+
reglardless of this setting. This setting affects the
6037+
deployment of the HW BHI control and the SW BHB
6038+
clearing sequence.
6039+
6040+
on - unconditionally enable.
6041+
off - unconditionally disable.
6042+
auto - (default) enable only if hardware mitigation
6043+
control(BHI_DIS_S) is available.
6044+
60346045
spectre_v2= [X86] Control mitigation of Spectre variant 2
60356046
(indirect branch speculation) vulnerability.
60366047
The default operation protects the kernel from

arch/x86/Kconfig

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2612,6 +2612,31 @@ config MITIGATION_RFDS
26122612
stored in floating point, vector and integer registers.
26132613
See also <file:Documentation/admin-guide/hw-vuln/reg-file-data-sampling.rst>
26142614

2615+
choice
2616+
prompt "Clear branch history"
2617+
depends on CPU_SUP_INTEL
2618+
default SPECTRE_BHI_AUTO
2619+
help
2620+
Enable BHI mitigations. BHI attacks are a form of Spectre V2 attacks
2621+
where the branch history buffer is poisoned to speculatively steer
2622+
indirect branches.
2623+
See <file:Documentation/admin-guide/hw-vuln/spectre.rst>
2624+
2625+
config SPECTRE_BHI_ON
2626+
bool "on"
2627+
help
2628+
Equivalent to setting spectre_bhi=on command line parameter.
2629+
config SPECTRE_BHI_OFF
2630+
bool "off"
2631+
help
2632+
Equivalent to setting spectre_bhi=off command line parameter.
2633+
config SPECTRE_BHI_AUTO
2634+
bool "auto"
2635+
help
2636+
Equivalent to setting spectre_bhi=auto command line parameter.
2637+
2638+
endchoice
2639+
26152640
endif
26162641

26172642
config ARCH_HAS_ADD_PAGES

arch/x86/include/asm/cpufeatures.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,7 @@
464464
*/
465465
#define X86_FEATURE_CLEAR_BHB_LOOP (21*32+ 1) /* "" Clear branch history at syscall entry using SW loop */
466466
#define X86_FEATURE_BHI_CTRL (21*32+ 2) /* "" BHI_DIS_S HW control available */
467+
#define X86_FEATURE_CLEAR_BHB_HW (21*32+ 3) /* "" BHI_DIS_S HW control enabled */
467468

468469
/*
469470
* BUG word(s)

arch/x86/kernel/cpu/bugs.c

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1606,6 +1606,74 @@ static void __init spectre_v2_determine_rsb_fill_type_at_vmexit(enum spectre_v2_
16061606
dump_stack();
16071607
}
16081608

1609+
/*
1610+
* Set BHI_DIS_S to prevent indirect branches in kernel to be influenced by
1611+
* branch history in userspace. Not needed if BHI_NO is set.
1612+
*/
1613+
static bool __init spec_ctrl_bhi_dis(void)
1614+
{
1615+
if (!boot_cpu_has(X86_FEATURE_BHI_CTRL))
1616+
return false;
1617+
1618+
x86_spec_ctrl_base |= SPEC_CTRL_BHI_DIS_S;
1619+
update_spec_ctrl(x86_spec_ctrl_base);
1620+
setup_force_cpu_cap(X86_FEATURE_CLEAR_BHB_HW);
1621+
1622+
return true;
1623+
}
1624+
1625+
enum bhi_mitigations {
1626+
BHI_MITIGATION_OFF,
1627+
BHI_MITIGATION_ON,
1628+
BHI_MITIGATION_AUTO,
1629+
};
1630+
1631+
static enum bhi_mitigations bhi_mitigation __ro_after_init =
1632+
IS_ENABLED(CONFIG_SPECTRE_BHI_ON) ? BHI_MITIGATION_ON :
1633+
IS_ENABLED(CONFIG_SPECTRE_BHI_OFF) ? BHI_MITIGATION_OFF :
1634+
BHI_MITIGATION_AUTO;
1635+
1636+
static int __init spectre_bhi_parse_cmdline(char *str)
1637+
{
1638+
if (!str)
1639+
return -EINVAL;
1640+
1641+
if (!strcmp(str, "off"))
1642+
bhi_mitigation = BHI_MITIGATION_OFF;
1643+
else if (!strcmp(str, "on"))
1644+
bhi_mitigation = BHI_MITIGATION_ON;
1645+
else if (!strcmp(str, "auto"))
1646+
bhi_mitigation = BHI_MITIGATION_AUTO;
1647+
else
1648+
pr_err("Ignoring unknown spectre_bhi option (%s)", str);
1649+
1650+
return 0;
1651+
}
1652+
early_param("spectre_bhi", spectre_bhi_parse_cmdline);
1653+
1654+
static void __init bhi_select_mitigation(void)
1655+
{
1656+
if (bhi_mitigation == BHI_MITIGATION_OFF)
1657+
return;
1658+
1659+
/* Retpoline mitigates against BHI unless the CPU has RRSBA behavior */
1660+
if (cpu_feature_enabled(X86_FEATURE_RETPOLINE) &&
1661+
!(x86_read_arch_cap_msr() & ARCH_CAP_RRSBA))
1662+
return;
1663+
1664+
if (spec_ctrl_bhi_dis())
1665+
return;
1666+
1667+
if (!IS_ENABLED(CONFIG_X86_64))
1668+
return;
1669+
1670+
if (bhi_mitigation == BHI_MITIGATION_AUTO)
1671+
return;
1672+
1673+
setup_force_cpu_cap(X86_FEATURE_CLEAR_BHB_LOOP);
1674+
pr_info("Spectre BHI mitigation: SW BHB clearing on syscall\n");
1675+
}
1676+
16091677
static void __init spectre_v2_select_mitigation(void)
16101678
{
16111679
enum spectre_v2_mitigation_cmd cmd = spectre_v2_parse_cmdline();
@@ -1717,6 +1785,9 @@ static void __init spectre_v2_select_mitigation(void)
17171785
mode == SPECTRE_V2_RETPOLINE)
17181786
spec_ctrl_disable_kernel_rrsba();
17191787

1788+
if (boot_cpu_has(X86_BUG_BHI))
1789+
bhi_select_mitigation();
1790+
17201791
spectre_v2_enabled = mode;
17211792
pr_info("%s\n", spectre_v2_strings[mode]);
17221793

@@ -2732,6 +2803,21 @@ static char *pbrsb_eibrs_state(void)
27322803
}
27332804
}
27342805

2806+
static const char * const spectre_bhi_state(void)
2807+
{
2808+
if (!boot_cpu_has_bug(X86_BUG_BHI))
2809+
return "; BHI: Not affected";
2810+
else if (boot_cpu_has(X86_FEATURE_CLEAR_BHB_HW))
2811+
return "; BHI: BHI_DIS_S";
2812+
else if (boot_cpu_has(X86_FEATURE_CLEAR_BHB_LOOP))
2813+
return "; BHI: SW loop";
2814+
else if (boot_cpu_has(X86_FEATURE_RETPOLINE) &&
2815+
!(x86_read_arch_cap_msr() & ARCH_CAP_RRSBA))
2816+
return "; BHI: Retpoline";
2817+
2818+
return "; BHI: Vulnerable (Syscall hardening enabled)";
2819+
}
2820+
27352821
static ssize_t spectre_v2_show_state(char *buf)
27362822
{
27372823
if (spectre_v2_enabled == SPECTRE_V2_LFENCE)
@@ -2744,13 +2830,15 @@ static ssize_t spectre_v2_show_state(char *buf)
27442830
spectre_v2_enabled == SPECTRE_V2_EIBRS_LFENCE)
27452831
return sysfs_emit(buf, "Vulnerable: eIBRS+LFENCE with unprivileged eBPF and SMT\n");
27462832

2747-
return sysfs_emit(buf, "%s%s%s%s%s%s%s\n",
2833+
return sysfs_emit(buf, "%s%s%s%s%s%s%s%s\n",
27482834
spectre_v2_strings[spectre_v2_enabled],
27492835
ibpb_state(),
27502836
boot_cpu_has(X86_FEATURE_USE_IBRS_FW) ? "; IBRS_FW" : "",
27512837
stibp_state(),
27522838
boot_cpu_has(X86_FEATURE_RSB_CTXSW) ? "; RSB filling" : "",
27532839
pbrsb_eibrs_state(),
2840+
spectre_bhi_state(),
2841+
/* this should always be at the end */
27542842
spectre_v2_module_string());
27552843
}
27562844

0 commit comments

Comments
 (0)