x86/speculation: Rework SMT state change
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> Cc: stable@vger.kernel.org Link: https://lkml.kernel.org/r/20181125185004.521974984@linutronix.de
This commit is contained in:
parent
321a874a7e
commit
a74cfffb03
|
@ -14,6 +14,7 @@
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/nospec.h>
|
#include <linux/nospec.h>
|
||||||
#include <linux/prctl.h>
|
#include <linux/prctl.h>
|
||||||
|
#include <linux/sched/smt.h>
|
||||||
|
|
||||||
#include <asm/spec-ctrl.h>
|
#include <asm/spec-ctrl.h>
|
||||||
#include <asm/cmdline.h>
|
#include <asm/cmdline.h>
|
||||||
|
@ -344,16 +345,14 @@ void arch_smt_update(void)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mutex_lock(&spec_ctrl_mutex);
|
mutex_lock(&spec_ctrl_mutex);
|
||||||
mask = x86_spec_ctrl_base;
|
|
||||||
if (cpu_smt_control == CPU_SMT_ENABLED)
|
mask = x86_spec_ctrl_base & ~SPEC_CTRL_STIBP;
|
||||||
|
if (sched_smt_active())
|
||||||
mask |= SPEC_CTRL_STIBP;
|
mask |= SPEC_CTRL_STIBP;
|
||||||
else
|
|
||||||
mask &= ~SPEC_CTRL_STIBP;
|
|
||||||
|
|
||||||
if (mask != x86_spec_ctrl_base) {
|
if (mask != x86_spec_ctrl_base) {
|
||||||
pr_info("Spectre v2 cross-process SMT mitigation: %s STIBP\n",
|
pr_info("Spectre v2 cross-process SMT mitigation: %s STIBP\n",
|
||||||
cpu_smt_control == CPU_SMT_ENABLED ?
|
mask & SPEC_CTRL_STIBP ? "Enabling" : "Disabling");
|
||||||
"Enabling" : "Disabling");
|
|
||||||
x86_spec_ctrl_base = mask;
|
x86_spec_ctrl_base = mask;
|
||||||
on_each_cpu(update_stibp_msr, NULL, 1);
|
on_each_cpu(update_stibp_msr, NULL, 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,4 +15,6 @@ static __always_inline bool sched_smt_active(void)
|
||||||
static inline bool sched_smt_active(void) { return false; }
|
static inline bool sched_smt_active(void) { return false; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void arch_smt_update(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
15
kernel/cpu.c
15
kernel/cpu.c
|
@ -10,6 +10,7 @@
|
||||||
#include <linux/sched/signal.h>
|
#include <linux/sched/signal.h>
|
||||||
#include <linux/sched/hotplug.h>
|
#include <linux/sched/hotplug.h>
|
||||||
#include <linux/sched/task.h>
|
#include <linux/sched/task.h>
|
||||||
|
#include <linux/sched/smt.h>
|
||||||
#include <linux/unistd.h>
|
#include <linux/unistd.h>
|
||||||
#include <linux/cpu.h>
|
#include <linux/cpu.h>
|
||||||
#include <linux/oom.h>
|
#include <linux/oom.h>
|
||||||
|
@ -367,6 +368,12 @@ static void lockdep_release_cpus_lock(void)
|
||||||
|
|
||||||
#endif /* CONFIG_HOTPLUG_CPU */
|
#endif /* CONFIG_HOTPLUG_CPU */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Architectures that need SMT-specific errata handling during SMT hotplug
|
||||||
|
* should override this.
|
||||||
|
*/
|
||||||
|
void __weak arch_smt_update(void) { }
|
||||||
|
|
||||||
#ifdef CONFIG_HOTPLUG_SMT
|
#ifdef CONFIG_HOTPLUG_SMT
|
||||||
enum cpuhp_smt_control cpu_smt_control __read_mostly = CPU_SMT_ENABLED;
|
enum cpuhp_smt_control cpu_smt_control __read_mostly = CPU_SMT_ENABLED;
|
||||||
EXPORT_SYMBOL_GPL(cpu_smt_control);
|
EXPORT_SYMBOL_GPL(cpu_smt_control);
|
||||||
|
@ -1011,6 +1018,7 @@ out:
|
||||||
* concurrent CPU hotplug via cpu_add_remove_lock.
|
* concurrent CPU hotplug via cpu_add_remove_lock.
|
||||||
*/
|
*/
|
||||||
lockup_detector_cleanup();
|
lockup_detector_cleanup();
|
||||||
|
arch_smt_update();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1139,6 +1147,7 @@ static int _cpu_up(unsigned int cpu, int tasks_frozen, enum cpuhp_state target)
|
||||||
ret = cpuhp_up_callbacks(cpu, st, target);
|
ret = cpuhp_up_callbacks(cpu, st, target);
|
||||||
out:
|
out:
|
||||||
cpus_write_unlock();
|
cpus_write_unlock();
|
||||||
|
arch_smt_update();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2055,12 +2064,6 @@ static void cpuhp_online_cpu_device(unsigned int cpu)
|
||||||
kobject_uevent(&dev->kobj, KOBJ_ONLINE);
|
kobject_uevent(&dev->kobj, KOBJ_ONLINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Architectures that need SMT-specific errata handling during SMT hotplug
|
|
||||||
* should override this.
|
|
||||||
*/
|
|
||||||
void __weak arch_smt_update(void) { };
|
|
||||||
|
|
||||||
static int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval)
|
static int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval)
|
||||||
{
|
{
|
||||||
int cpu, ret = 0;
|
int cpu, ret = 0;
|
||||||
|
|
Loading…
Reference in New Issue