[RFC PATCH v3 04/10] x86/bugs: Use Virtual MSRs to request BHI_DIS_S

From: Chao Gao
Date: Wed Apr 10 2024 - 10:51:55 EST


From: Pawan Gupta <pawan.kumar.gupta@xxxxxxxxxxxxxxx>

Mitigation for BHI is to use hardware control BHI_DIS_S or the software
sequence. On platforms that support BHI_DIS_S, a software sequence may
be ineffective to mitigate BHI. Guests that are not aware of BHI_DIS_S
on host, and deploy the ineffective software sequence clear_bhb_loop(),
may become vulnerable to BHI.

To overcome this problem Intel has defined a virtual MSR interface
through which guests can report their mitigation status and request VMM
to deploy relevant hardware mitigations.

Use this virtual MSR interface to tell VMM that the guest is using a
short software sequence. Based on this information a VMM can deploy
BHI_DIS_S for the guest using virtual SPEC_CTRL.

Signed-off-by: Pawan Gupta <pawan.kumar.gupta@xxxxxxxxxxxxxxx>
Signed-off-by: Chao Gao <chao.gao@xxxxxxxxx>
---
arch/x86/include/asm/msr-index.h | 18 ++++++++++++++++++
arch/x86/kernel/cpu/bugs.c | 26 ++++++++++++++++++++++++++
arch/x86/kernel/cpu/common.c | 1 +
arch/x86/kernel/cpu/cpu.h | 1 +
4 files changed, 46 insertions(+)

diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index e72c2b872957..18a4081bf5cb 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -196,6 +196,7 @@
* IA32_XAPIC_DISABLE_STATUS MSR
* supported
*/
+#define ARCH_CAP_VIRTUAL_ENUM BIT_ULL(63) /* MSR_VIRTUAL_ENUMERATION supported */

#define MSR_IA32_FLUSH_CMD 0x0000010b
#define L1D_FLUSH BIT(0) /*
@@ -1178,6 +1179,23 @@
#define MSR_IA32_VMX_MISC_VMWRITE_SHADOW_RO_FIELDS (1ULL << 29)
#define MSR_IA32_VMX_MISC_PREEMPTION_TIMER_SCALE 0x1F

+/* Intel virtual MSRs */
+#define MSR_VIRTUAL_ENUMERATION 0x50000000
+#define VIRT_ENUM_MITIGATION_CTRL_SUPPORT BIT(0) /*
+ * Mitigation ctrl via virtual
+ * MSRs supported
+ */
+
+#define MSR_VIRTUAL_MITIGATION_ENUM 0x50000001
+#define MITI_ENUM_BHB_CLEAR_SEQ_S_SUPPORT BIT(0) /* VMM supports BHI_DIS_S */
+
+#define MSR_VIRTUAL_MITIGATION_CTRL 0x50000002
+#define MITI_CTRL_BHB_CLEAR_SEQ_S_USED_BIT 0 /*
+ * Request VMM to deploy
+ * BHI_DIS_S mitigation
+ */
+#define MITI_CTRL_BHB_CLEAR_SEQ_S_USED BIT(MITI_CTRL_BHB_CLEAR_SEQ_S_USED_BIT)
+
/* AMD-V MSRs */
#define MSR_VM_CR 0xc0010114
#define MSR_VM_IGNNE 0xc0010115
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index 295463707e68..e74e4c51d387 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -50,6 +50,8 @@ static void __init l1d_flush_select_mitigation(void);
static void __init srso_select_mitigation(void);
static void __init gds_select_mitigation(void);

+void virt_mitigation_ctrl_init(void);
+
/* The base value of the SPEC_CTRL MSR without task-specific bits set */
u64 x86_spec_ctrl_base;
EXPORT_SYMBOL_GPL(x86_spec_ctrl_base);
@@ -171,6 +173,8 @@ void __init cpu_select_mitigations(void)
*/
srso_select_mitigation();
gds_select_mitigation();
+
+ virt_mitigation_ctrl_init();
}

/*
@@ -1680,6 +1684,28 @@ static void __init bhi_select_mitigation(void)
pr_info("Spectre BHI mitigation: SW BHB clearing on syscall\n");
}

+void virt_mitigation_ctrl_init(void)
+{
+ u64 msr_virt_enum, msr_mitigation_enum;
+
+ if (!(x86_read_arch_cap_msr() & ARCH_CAP_VIRTUAL_ENUM))
+ return;
+
+ rdmsrl(MSR_VIRTUAL_ENUMERATION, msr_virt_enum);
+ if (!(msr_virt_enum & VIRT_ENUM_MITIGATION_CTRL_SUPPORT))
+ return;
+
+ rdmsrl(MSR_VIRTUAL_MITIGATION_ENUM, msr_mitigation_enum);
+
+ if (msr_mitigation_enum & MITI_ENUM_BHB_CLEAR_SEQ_S_SUPPORT) {
+ /* When BHI short seq is being used, request BHI_DIS_S */
+ if (boot_cpu_has(X86_FEATURE_CLEAR_BHB_LOOP))
+ msr_set_bit(MSR_VIRTUAL_MITIGATION_CTRL, MITI_CTRL_BHB_CLEAR_SEQ_S_USED_BIT);
+ else
+ msr_clear_bit(MSR_VIRTUAL_MITIGATION_CTRL, MITI_CTRL_BHB_CLEAR_SEQ_S_USED_BIT);
+ }
+}
+
static void __init spectre_v2_select_mitigation(void)
{
enum spectre_v2_mitigation_cmd cmd = spectre_v2_parse_cmdline();
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 754d91857d63..29f16655a7a0 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -1960,6 +1960,7 @@ void identify_secondary_cpu(struct cpuinfo_x86 *c)
update_gds_msr();

tsx_ap_init();
+ virt_mitigation_ctrl_init();
}

void print_cpu_info(struct cpuinfo_x86 *c)
diff --git a/arch/x86/kernel/cpu/cpu.h b/arch/x86/kernel/cpu/cpu.h
index ea9e07d57c8d..1cddf506b6ae 100644
--- a/arch/x86/kernel/cpu/cpu.h
+++ b/arch/x86/kernel/cpu/cpu.h
@@ -87,6 +87,7 @@ void cpu_select_mitigations(void);
extern void x86_spec_ctrl_setup_ap(void);
extern void update_srbds_msr(void);
extern void update_gds_msr(void);
+extern void virt_mitigation_ctrl_init(void);

extern enum spectre_v2_mitigation spectre_v2_enabled;

--
2.39.3