|
Borislav Petkov |
09deb3 |
From: Peter Zijlstra <peterz@infradead.org>
|
|
Borislav Petkov |
09deb3 |
Date: Tue, 14 Jun 2022 23:15:52 +0200
|
|
Borislav Petkov |
09deb3 |
Subject: x86/bugs: Keep a per-CPU IA32_SPEC_CTRL value
|
|
Borislav Petkov |
09deb3 |
Git-commit: caa0ff24d5d0e02abce5e65c3d2b7f20a6617be5
|
|
Borislav Petkov |
43fbd8 |
Patch-mainline: v5.19-rc4
|
|
Borislav Petkov |
09deb3 |
References: bsc#1199657 CVE-2022-29900 CVE-2022-29901
|
|
Borislav Petkov |
09deb3 |
|
|
Borislav Petkov |
09deb3 |
Due to TIF_SSBD and TIF_SPEC_IB the actual IA32_SPEC_CTRL value can
|
|
Borislav Petkov |
09deb3 |
differ from x86_spec_ctrl_base. As such, keep a per-CPU value
|
|
Borislav Petkov |
09deb3 |
reflecting the current task's MSR content.
|
|
Borislav Petkov |
09deb3 |
|
|
Borislav Petkov |
09deb3 |
[jpoimboe: rename]
|
|
Borislav Petkov |
09deb3 |
|
|
Borislav Petkov |
09deb3 |
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
|
|
Borislav Petkov |
09deb3 |
Signed-off-by: Borislav Petkov <bp@suse.de>
|
|
Borislav Petkov |
09deb3 |
Reviewed-by: Josh Poimboeuf <jpoimboe@kernel.org>
|
|
Borislav Petkov |
09deb3 |
Signed-off-by: Borislav Petkov <bp@suse.de>
|
|
Borislav Petkov |
09deb3 |
---
|
|
Borislav Petkov |
09deb3 |
arch/x86/include/asm/nospec-branch.h | 1 +
|
|
Borislav Petkov |
09deb3 |
arch/x86/kernel/cpu/bugs.c | 28 +++++++++++++++++++++++-----
|
|
Borislav Petkov |
09deb3 |
arch/x86/kernel/process.c | 2 +-
|
|
Borislav Petkov |
09deb3 |
3 files changed, 25 insertions(+), 6 deletions(-)
|
|
Borislav Petkov |
09deb3 |
|
|
Borislav Petkov |
09deb3 |
--- a/arch/x86/include/asm/nospec-branch.h
|
|
Borislav Petkov |
09deb3 |
+++ b/arch/x86/include/asm/nospec-branch.h
|
|
Borislav Petkov |
09deb3 |
@@ -253,6 +253,7 @@ static inline void indirect_branch_predi
|
|
Borislav Petkov |
09deb3 |
|
|
Borislav Petkov |
09deb3 |
/* The Intel SPEC CTRL MSR base value cache */
|
|
Borislav Petkov |
09deb3 |
extern u64 x86_spec_ctrl_base;
|
|
Borislav Petkov |
09deb3 |
+extern void write_spec_ctrl_current(u64 val);
|
|
Borislav Petkov |
09deb3 |
|
|
Borislav Petkov |
09deb3 |
/*
|
|
Borislav Petkov |
09deb3 |
* With retpoline, we must use IBRS to restrict branch prediction
|
|
Borislav Petkov |
09deb3 |
--- a/arch/x86/kernel/cpu/bugs.c
|
|
Borislav Petkov |
09deb3 |
+++ b/arch/x86/kernel/cpu/bugs.c
|
|
Borislav Petkov |
09deb3 |
@@ -48,12 +48,30 @@ static void __init taa_select_mitigation
|
|
Borislav Petkov |
09deb3 |
static void __init mmio_select_mitigation(void);
|
|
Borislav Petkov |
09deb3 |
static void __init srbds_select_mitigation(void);
|
|
Borislav Petkov |
09deb3 |
|
|
Borislav Petkov |
09deb3 |
-/* The base value of the SPEC_CTRL MSR that always has to be preserved. */
|
|
Borislav Petkov |
09deb3 |
+/* The base value of the SPEC_CTRL MSR without task-specific bits set */
|
|
Borislav Petkov |
09deb3 |
u64 x86_spec_ctrl_base;
|
|
Borislav Petkov |
09deb3 |
EXPORT_SYMBOL_GPL(x86_spec_ctrl_base);
|
|
Borislav Petkov |
09deb3 |
+
|
|
Borislav Petkov |
09deb3 |
+/* The current value of the SPEC_CTRL MSR with task-specific bits set */
|
|
Borislav Petkov |
09deb3 |
+DEFINE_PER_CPU(u64, x86_spec_ctrl_current);
|
|
Borislav Petkov |
09deb3 |
+EXPORT_SYMBOL_GPL(x86_spec_ctrl_current);
|
|
Borislav Petkov |
09deb3 |
+
|
|
Borislav Petkov |
09deb3 |
static DEFINE_MUTEX(spec_ctrl_mutex);
|
|
Borislav Petkov |
09deb3 |
|
|
Borislav Petkov |
09deb3 |
/*
|
|
Borislav Petkov |
09deb3 |
+ * Keep track of the SPEC_CTRL MSR value for the current task, which may differ
|
|
Borislav Petkov |
09deb3 |
+ * from x86_spec_ctrl_base due to STIBP/SSB in __speculation_ctrl_update().
|
|
Borislav Petkov |
09deb3 |
+ */
|
|
Borislav Petkov |
09deb3 |
+void write_spec_ctrl_current(u64 val)
|
|
Borislav Petkov |
09deb3 |
+{
|
|
Borislav Petkov |
09deb3 |
+ if (this_cpu_read(x86_spec_ctrl_current) == val)
|
|
Borislav Petkov |
09deb3 |
+ return;
|
|
Borislav Petkov |
09deb3 |
+
|
|
Borislav Petkov |
09deb3 |
+ this_cpu_write(x86_spec_ctrl_current, val);
|
|
Borislav Petkov |
09deb3 |
+ wrmsrl(MSR_IA32_SPEC_CTRL, val);
|
|
Borislav Petkov |
09deb3 |
+}
|
|
Borislav Petkov |
09deb3 |
+
|
|
Borislav Petkov |
09deb3 |
+/*
|
|
Borislav Petkov |
09deb3 |
* The vendor and possibly platform specific bits which can be modified in
|
|
Borislav Petkov |
09deb3 |
* x86_spec_ctrl_base.
|
|
Borislav Petkov |
09deb3 |
*/
|
|
Borislav Petkov |
09deb3 |
@@ -1235,7 +1253,7 @@ static void __init spectre_v2_select_mit
|
|
Borislav Petkov |
09deb3 |
if (spectre_v2_in_eibrs_mode(mode)) {
|
|
Borislav Petkov |
09deb3 |
/* Force it so VMEXIT will restore correctly */
|
|
Borislav Petkov |
09deb3 |
x86_spec_ctrl_base |= SPEC_CTRL_IBRS;
|
|
Borislav Petkov |
09deb3 |
- wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base);
|
|
Borislav Petkov |
09deb3 |
+ write_spec_ctrl_current(x86_spec_ctrl_base);
|
|
Borislav Petkov |
09deb3 |
}
|
|
Borislav Petkov |
09deb3 |
|
|
Borislav Petkov |
09deb3 |
switch (mode) {
|
|
Borislav Petkov |
09deb3 |
@@ -1290,7 +1308,7 @@ static void __init spectre_v2_select_mit
|
|
Borislav Petkov |
09deb3 |
|
|
Borislav Petkov |
09deb3 |
static void update_stibp_msr(void * __unused)
|
|
Borislav Petkov |
09deb3 |
{
|
|
Borislav Petkov |
09deb3 |
- wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base);
|
|
Borislav Petkov |
09deb3 |
+ write_spec_ctrl_current(x86_spec_ctrl_base);
|
|
Borislav Petkov |
09deb3 |
}
|
|
Borislav Petkov |
09deb3 |
|
|
Borislav Petkov |
09deb3 |
/* Update x86_spec_ctrl_base in case SMT state changed. */
|
|
Borislav Petkov |
09deb3 |
@@ -1522,7 +1540,7 @@ static enum ssb_mitigation __init __ssb_
|
|
Borislav Petkov |
09deb3 |
x86_amd_ssb_disable();
|
|
Borislav Petkov |
09deb3 |
} else {
|
|
Borislav Petkov |
09deb3 |
x86_spec_ctrl_base |= SPEC_CTRL_SSBD;
|
|
Borislav Petkov |
09deb3 |
- wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base);
|
|
Borislav Petkov |
09deb3 |
+ write_spec_ctrl_current(x86_spec_ctrl_base);
|
|
Borislav Petkov |
09deb3 |
}
|
|
Borislav Petkov |
09deb3 |
}
|
|
Borislav Petkov |
09deb3 |
|
|
Borislav Petkov |
09deb3 |
@@ -1740,7 +1758,7 @@ int arch_prctl_spec_ctrl_get(struct task
|
|
Borislav Petkov |
09deb3 |
void x86_spec_ctrl_setup_ap(void)
|
|
Borislav Petkov |
09deb3 |
{
|
|
Borislav Petkov |
09deb3 |
if (boot_cpu_has(X86_FEATURE_MSR_SPEC_CTRL))
|
|
Borislav Petkov |
09deb3 |
- wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base);
|
|
Borislav Petkov |
09deb3 |
+ write_spec_ctrl_current(x86_spec_ctrl_base);
|
|
Borislav Petkov |
09deb3 |
|
|
Borislav Petkov |
09deb3 |
if (ssb_mode == SPEC_STORE_BYPASS_DISABLE)
|
|
Borislav Petkov |
09deb3 |
x86_amd_ssb_disable();
|
|
Borislav Petkov |
09deb3 |
--- a/arch/x86/kernel/process.c
|
|
Borislav Petkov |
09deb3 |
+++ b/arch/x86/kernel/process.c
|
|
Borislav Petkov |
09deb3 |
@@ -599,7 +599,7 @@ static __always_inline void __speculatio
|
|
Borislav Petkov |
09deb3 |
}
|
|
Borislav Petkov |
09deb3 |
|
|
Borislav Petkov |
09deb3 |
if (updmsr)
|
|
Borislav Petkov |
09deb3 |
- wrmsrl(MSR_IA32_SPEC_CTRL, msr);
|
|
Borislav Petkov |
09deb3 |
+ write_spec_ctrl_current(msr);
|
|
Borislav Petkov |
09deb3 |
}
|
|
Borislav Petkov |
09deb3 |
|
|
Borislav Petkov |
09deb3 |
static unsigned long speculation_ctrl_update_tif(struct task_struct *tsk)
|