Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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


+16 -12
+5 -6
arch/x86/kernel/cpu/bugs.c
··· 14 14 #include <linux/module.h> 15 15 #include <linux/nospec.h> 16 16 #include <linux/prctl.h> 17 + #include <linux/sched/smt.h> 17 18 18 19 #include <asm/spec-ctrl.h> 19 20 #include <asm/cmdline.h> ··· 345 344 return; 346 345 347 346 mutex_lock(&spec_ctrl_mutex); 348 - mask = x86_spec_ctrl_base; 349 - if (cpu_smt_control == CPU_SMT_ENABLED) 347 + 348 + mask = x86_spec_ctrl_base & ~SPEC_CTRL_STIBP; 349 + if (sched_smt_active()) 350 350 mask |= SPEC_CTRL_STIBP; 351 - else 352 - mask &= ~SPEC_CTRL_STIBP; 353 351 354 352 if (mask != x86_spec_ctrl_base) { 355 353 pr_info("Spectre v2 cross-process SMT mitigation: %s STIBP\n", 356 - cpu_smt_control == CPU_SMT_ENABLED ? 357 - "Enabling" : "Disabling"); 354 + mask & SPEC_CTRL_STIBP ? "Enabling" : "Disabling"); 358 355 x86_spec_ctrl_base = mask; 359 356 on_each_cpu(update_stibp_msr, NULL, 1); 360 357 }
+2
include/linux/sched/smt.h
··· 15 15 static inline bool sched_smt_active(void) { return false; } 16 16 #endif 17 17 18 + void arch_smt_update(void); 19 + 18 20 #endif
+9 -6
kernel/cpu.c
··· 10 10 #include <linux/sched/signal.h> 11 11 #include <linux/sched/hotplug.h> 12 12 #include <linux/sched/task.h> 13 + #include <linux/sched/smt.h> 13 14 #include <linux/unistd.h> 14 15 #include <linux/cpu.h> 15 16 #include <linux/oom.h> ··· 367 366 } 368 367 369 368 #endif /* CONFIG_HOTPLUG_CPU */ 369 + 370 + /* 371 + * Architectures that need SMT-specific errata handling during SMT hotplug 372 + * should override this. 373 + */ 374 + void __weak arch_smt_update(void) { } 370 375 371 376 #ifdef CONFIG_HOTPLUG_SMT 372 377 enum cpuhp_smt_control cpu_smt_control __read_mostly = CPU_SMT_ENABLED; ··· 1018 1011 * concurrent CPU hotplug via cpu_add_remove_lock. 1019 1012 */ 1020 1013 lockup_detector_cleanup(); 1014 + arch_smt_update(); 1021 1015 return ret; 1022 1016 } 1023 1017 ··· 1147 1139 ret = cpuhp_up_callbacks(cpu, st, target); 1148 1140 out: 1149 1141 cpus_write_unlock(); 1142 + arch_smt_update(); 1150 1143 return ret; 1151 1144 } 1152 1145 ··· 2063 2054 /* Tell user space about the state change */ 2064 2055 kobject_uevent(&dev->kobj, KOBJ_ONLINE); 2065 2056 } 2066 - 2067 - /* 2068 - * Architectures that need SMT-specific errata handling during SMT hotplug 2069 - * should override this. 2070 - */ 2071 - void __weak arch_smt_update(void) { }; 2072 2057 2073 2058 static int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval) 2074 2059 {