summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2018-11-25 19:33:39 +0100
committerBen Hutchings <ben@decadent.org.uk>2019-05-22 23:15:14 +0100
commit19a284b2e3ace2112a0bac3c2cf39e5c94e7e890 (patch)
treec8e795a4d4806a160a01eb5694e26b0095576ea3
parentb772b1dd9a3718dc565039b5953793c71713b9c6 (diff)
downloadlinux-stable-19a284b2e3ace2112a0bac3c2cf39e5c94e7e890.tar.gz
linux-stable-19a284b2e3ace2112a0bac3c2cf39e5c94e7e890.tar.bz2
linux-stable-19a284b2e3ace2112a0bac3c2cf39e5c94e7e890.zip
x86/speculation: Rework SMT state change
commit a74cfffb03b73d41e08f84c2e5c87dec0ce3db9f upstream. arch_smt_update() is only called when the sysfs SMT control knob is changed. This means that when SMT is enabled in the sysfs control knob the system is considered to have SMT active even if all siblings are offline. To allow finegrained control of the speculation mitigations, the actual SMT state is more interesting than the fact that siblings could be enabled. Rework the code, so arch_smt_update() is invoked from each individual CPU hotplug function, and simplify the update function while at it. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Ingo Molnar <mingo@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Andy Lutomirski <luto@kernel.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Jiri Kosina <jkosina@suse.cz> Cc: Tom Lendacky <thomas.lendacky@amd.com> Cc: Josh Poimboeuf <jpoimboe@redhat.com> Cc: Andrea Arcangeli <aarcange@redhat.com> Cc: David Woodhouse <dwmw@amazon.co.uk> Cc: Tim Chen <tim.c.chen@linux.intel.com> Cc: Andi Kleen <ak@linux.intel.com> Cc: Dave Hansen <dave.hansen@intel.com> Cc: Casey Schaufler <casey.schaufler@intel.com> Cc: Asit Mallick <asit.k.mallick@intel.com> Cc: Arjan van de Ven <arjan@linux.intel.com> Cc: Jon Masters <jcm@redhat.com> Cc: Waiman Long <longman9394@gmail.com> Cc: Greg KH <gregkh@linuxfoundation.org> Cc: Dave Stewart <david.c.stewart@intel.com> Cc: Kees Cook <keescook@chromium.org> Link: https://lkml.kernel.org/r/20181125185004.521974984@linutronix.de [bwh: Backported to 3.16: adjust context] Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
-rw-r--r--arch/x86/kernel/cpu/bugs.c11
-rw-r--r--include/linux/sched/smt.h2
-rw-r--r--kernel/cpu.c10
3 files changed, 16 insertions, 7 deletions
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index 31b53f1956d6..0110f3b7dcd8 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/nospec.h>
#include <linux/prctl.h>
+#include <linux/sched/smt.h>
#include <asm/spec-ctrl.h>
#include <asm/cmdline.h>
@@ -403,16 +404,14 @@ void arch_smt_update(void)
return;
mutex_lock(&spec_ctrl_mutex);
- mask = x86_spec_ctrl_base;
- if (IS_ENABLED(CONFIG_X86_HT))
+
+ mask = x86_spec_ctrl_base & ~SPEC_CTRL_STIBP;
+ if (sched_smt_active())
mask |= SPEC_CTRL_STIBP;
- else
- mask &= ~SPEC_CTRL_STIBP;
if (mask != x86_spec_ctrl_base) {
pr_info("Spectre v2 cross-process SMT mitigation: %s STIBP\n",
- IS_ENABLED(CONFIG_X86_HT) ?
- "Enabling" : "Disabling");
+ mask & SPEC_CTRL_STIBP ? "Enabling" : "Disabling");
x86_spec_ctrl_base = mask;
on_each_cpu(update_stibp_msr, NULL, 1);
}
diff --git a/include/linux/sched/smt.h b/include/linux/sched/smt.h
index 5209c268c6fd..559ac4590593 100644
--- a/include/linux/sched/smt.h
+++ b/include/linux/sched/smt.h
@@ -15,4 +15,6 @@ static __always_inline bool sched_smt_active(void)
static inline bool sched_smt_active(void) { return false; }
#endif
+void arch_smt_update(void);
+
#endif
diff --git a/kernel/cpu.c b/kernel/cpu.c
index e160b9b065e6..f069ad2b2b40 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -8,6 +8,7 @@
#include <linux/init.h>
#include <linux/notifier.h>
#include <linux/sched.h>
+#include <linux/sched/smt.h>
#include <linux/unistd.h>
#include <linux/cpu.h>
#include <linux/oom.h>
@@ -179,6 +180,12 @@ void cpu_hotplug_enable(void)
#endif /* CONFIG_HOTPLUG_CPU */
+/*
+ * Architectures that need SMT-specific errata handling during SMT hotplug
+ * should override this.
+ */
+void __weak arch_smt_update(void) { }
+
/* Need to know about CPUs going up/down? */
int __ref register_cpu_notifier(struct notifier_block *nb)
{
@@ -394,6 +401,7 @@ out_release:
cpu_hotplug_done();
if (!err)
cpu_notify_nofail(CPU_POST_DEAD | mod, hcpu);
+ arch_smt_update();
return err;
}
@@ -495,7 +503,7 @@ out_notify:
__cpu_notify(CPU_UP_CANCELED | mod, hcpu, nr_calls, NULL);
out:
cpu_hotplug_done();
-
+ arch_smt_update();
return ret;
}