Skip to content

Commit 6606515

Browse files
pa1guptatorvalds
authored andcommitted
x86/bugs: Make sure MSR_SPEC_CTRL is updated properly upon resume from S3
The "force" argument to write_spec_ctrl_current() is currently ambiguous as it does not guarantee the MSR write. This is due to the optimization that writes to the MSR happen only when the new value differs from the cached value. This is fine in most cases, but breaks for S3 resume when the cached MSR value gets out of sync with the hardware MSR value due to S3 resetting it. When x86_spec_ctrl_current is same as x86_spec_ctrl_base, the MSR write is skipped. Which results in SPEC_CTRL mitigations not getting restored. Move the MSR write from write_spec_ctrl_current() to a new function that unconditionally writes to the MSR. Update the callers accordingly and rename functions. [ bp: Rework a bit. ] Fixes: caa0ff2 ("x86/bugs: Keep a per-CPU IA32_SPEC_CTRL value") Suggested-by: Borislav Petkov <[email protected]> Signed-off-by: Pawan Gupta <[email protected]> Signed-off-by: Borislav Petkov (AMD) <[email protected]> Reviewed-by: Thomas Gleixner <[email protected]> Cc: <[email protected]> Link: https://lore.kernel.org/r/806d39b0bfec2fe8f50dc5446dff20f5bb24a959.1669821572.git.pawan.kumar.gupta@linux.intel.com Signed-off-by: Linus Torvalds <[email protected]>
1 parent a1e9185 commit 6606515

File tree

3 files changed

+16
-9
lines changed

3 files changed

+16
-9
lines changed

arch/x86/include/asm/nospec-branch.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ static inline void indirect_branch_prediction_barrier(void)
321321
/* The Intel SPEC CTRL MSR base value cache */
322322
extern u64 x86_spec_ctrl_base;
323323
DECLARE_PER_CPU(u64, x86_spec_ctrl_current);
324-
extern void write_spec_ctrl_current(u64 val, bool force);
324+
extern void update_spec_ctrl_cond(u64 val);
325325
extern u64 spec_ctrl_current(void);
326326

327327
/*

arch/x86/kernel/cpu/bugs.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,18 @@ EXPORT_SYMBOL_GPL(x86_spec_ctrl_current);
6060

6161
static DEFINE_MUTEX(spec_ctrl_mutex);
6262

63+
/* Update SPEC_CTRL MSR and its cached copy unconditionally */
64+
static void update_spec_ctrl(u64 val)
65+
{
66+
this_cpu_write(x86_spec_ctrl_current, val);
67+
wrmsrl(MSR_IA32_SPEC_CTRL, val);
68+
}
69+
6370
/*
6471
* Keep track of the SPEC_CTRL MSR value for the current task, which may differ
6572
* from x86_spec_ctrl_base due to STIBP/SSB in __speculation_ctrl_update().
6673
*/
67-
void write_spec_ctrl_current(u64 val, bool force)
74+
void update_spec_ctrl_cond(u64 val)
6875
{
6976
if (this_cpu_read(x86_spec_ctrl_current) == val)
7077
return;
@@ -75,7 +82,7 @@ void write_spec_ctrl_current(u64 val, bool force)
7582
* When KERNEL_IBRS this MSR is written on return-to-user, unless
7683
* forced the update can be delayed until that time.
7784
*/
78-
if (force || !cpu_feature_enabled(X86_FEATURE_KERNEL_IBRS))
85+
if (!cpu_feature_enabled(X86_FEATURE_KERNEL_IBRS))
7986
wrmsrl(MSR_IA32_SPEC_CTRL, val);
8087
}
8188

@@ -1328,7 +1335,7 @@ static void __init spec_ctrl_disable_kernel_rrsba(void)
13281335

13291336
if (ia32_cap & ARCH_CAP_RRSBA) {
13301337
x86_spec_ctrl_base |= SPEC_CTRL_RRSBA_DIS_S;
1331-
write_spec_ctrl_current(x86_spec_ctrl_base, true);
1338+
update_spec_ctrl(x86_spec_ctrl_base);
13321339
}
13331340
}
13341341

@@ -1450,7 +1457,7 @@ static void __init spectre_v2_select_mitigation(void)
14501457

14511458
if (spectre_v2_in_ibrs_mode(mode)) {
14521459
x86_spec_ctrl_base |= SPEC_CTRL_IBRS;
1453-
write_spec_ctrl_current(x86_spec_ctrl_base, true);
1460+
update_spec_ctrl(x86_spec_ctrl_base);
14541461
}
14551462

14561463
switch (mode) {
@@ -1564,7 +1571,7 @@ static void __init spectre_v2_select_mitigation(void)
15641571
static void update_stibp_msr(void * __unused)
15651572
{
15661573
u64 val = spec_ctrl_current() | (x86_spec_ctrl_base & SPEC_CTRL_STIBP);
1567-
write_spec_ctrl_current(val, true);
1574+
update_spec_ctrl(val);
15681575
}
15691576

15701577
/* Update x86_spec_ctrl_base in case SMT state changed. */
@@ -1797,7 +1804,7 @@ static enum ssb_mitigation __init __ssb_select_mitigation(void)
17971804
x86_amd_ssb_disable();
17981805
} else {
17991806
x86_spec_ctrl_base |= SPEC_CTRL_SSBD;
1800-
write_spec_ctrl_current(x86_spec_ctrl_base, true);
1807+
update_spec_ctrl(x86_spec_ctrl_base);
18011808
}
18021809
}
18031810

@@ -2048,7 +2055,7 @@ int arch_prctl_spec_ctrl_get(struct task_struct *task, unsigned long which)
20482055
void x86_spec_ctrl_setup_ap(void)
20492056
{
20502057
if (boot_cpu_has(X86_FEATURE_MSR_SPEC_CTRL))
2051-
write_spec_ctrl_current(x86_spec_ctrl_base, true);
2058+
update_spec_ctrl(x86_spec_ctrl_base);
20522059

20532060
if (ssb_mode == SPEC_STORE_BYPASS_DISABLE)
20542061
x86_amd_ssb_disable();

arch/x86/kernel/process.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -600,7 +600,7 @@ static __always_inline void __speculation_ctrl_update(unsigned long tifp,
600600
}
601601

602602
if (updmsr)
603-
write_spec_ctrl_current(msr, false);
603+
update_spec_ctrl_cond(msr);
604604
}
605605

606606
static unsigned long speculation_ctrl_update_tif(struct task_struct *tsk)

0 commit comments

Comments
 (0)