[PATCH v5 14/20] x86/bugs: Add attack vector controls for BHI

From: David Kaplan
Date: Fri May 09 2025 - 12:31:50 EST


There are two BHI mitigations, one for SYSCALL and one for VMEXIT.
Split these up so they can be selected individually based on attack
vector.

Signed-off-by: David Kaplan <david.kaplan@xxxxxxx>
---
arch/x86/kernel/cpu/bugs.c | 38 +++++++++++++++++++++++++++-----------
1 file changed, 27 insertions(+), 11 deletions(-)

diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index 305a11fa9521..667385808400 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -1905,8 +1905,9 @@ static bool __init spec_ctrl_bhi_dis(void)
enum bhi_mitigations {
BHI_MITIGATION_OFF,
BHI_MITIGATION_AUTO,
- BHI_MITIGATION_ON,
+ BHI_MITIGATION_FULL,
BHI_MITIGATION_VMEXIT_ONLY,
+ BHI_MITIGATION_SYSCALL_ONLY
};

static enum bhi_mitigations bhi_mitigation __ro_after_init =
@@ -1920,7 +1921,7 @@ static int __init spectre_bhi_parse_cmdline(char *str)
if (!strcmp(str, "off"))
bhi_mitigation = BHI_MITIGATION_OFF;
else if (!strcmp(str, "on"))
- bhi_mitigation = BHI_MITIGATION_ON;
+ bhi_mitigation = BHI_MITIGATION_FULL;
else if (!strcmp(str, "vmexit"))
bhi_mitigation = BHI_MITIGATION_VMEXIT_ONLY;
else
@@ -1932,11 +1933,22 @@ early_param("spectre_bhi", spectre_bhi_parse_cmdline);

static void __init bhi_select_mitigation(void)
{
- if (!boot_cpu_has(X86_BUG_BHI) || cpu_mitigations_off())
+ if (!boot_cpu_has(X86_BUG_BHI))
bhi_mitigation = BHI_MITIGATION_OFF;

- if (bhi_mitigation == BHI_MITIGATION_AUTO)
- bhi_mitigation = BHI_MITIGATION_ON;
+ if (bhi_mitigation != BHI_MITIGATION_AUTO)
+ return;
+
+ if (cpu_attack_vector_mitigated(CPU_MITIGATE_USER_KERNEL)) {
+ if (cpu_attack_vector_mitigated(CPU_MITIGATE_GUEST_HOST))
+ bhi_mitigation = BHI_MITIGATION_FULL;
+ else
+ bhi_mitigation = BHI_MITIGATION_SYSCALL_ONLY;
+ } else if (cpu_attack_vector_mitigated(CPU_MITIGATE_GUEST_HOST)) {
+ bhi_mitigation = BHI_MITIGATION_VMEXIT_ONLY;
+ } else {
+ bhi_mitigation = BHI_MITIGATION_OFF;
+ }
}

static void __init bhi_update_mitigation(void)
@@ -1969,15 +1981,19 @@ static void __init bhi_apply_mitigation(void)
if (!IS_ENABLED(CONFIG_X86_64))
return;

- if (bhi_mitigation == BHI_MITIGATION_VMEXIT_ONLY) {
- pr_info("Spectre BHI mitigation: SW BHB clearing on VM exit only\n");
+ /* Mitigate KVM if guest->host protection is desired */
+ if (bhi_mitigation == BHI_MITIGATION_FULL ||
+ bhi_mitigation == BHI_MITIGATION_VMEXIT_ONLY) {
setup_force_cpu_cap(X86_FEATURE_CLEAR_BHB_VMEXIT);
- return;
+ pr_info("Spectre BHI mitigation: SW BHB clearing on VM exit\n");
}

- pr_info("Spectre BHI mitigation: SW BHB clearing on syscall and VM exit\n");
- setup_force_cpu_cap(X86_FEATURE_CLEAR_BHB_LOOP);
- setup_force_cpu_cap(X86_FEATURE_CLEAR_BHB_VMEXIT);
+ /* Mitigate syscalls if user->kernel protection is desired */
+ if (bhi_mitigation == BHI_MITIGATION_FULL ||
+ bhi_mitigation == BHI_MITIGATION_SYSCALL_ONLY) {
+ setup_force_cpu_cap(X86_FEATURE_CLEAR_BHB_LOOP);
+ pr_info("Spectre BHI mitigation: SW BHB clearing on syscall\n");
+ }
}

static void __init spectre_v2_select_mitigation(void)
--
2.34.1