Skip to content

Commit d91bdd9

Browse files
committed
cpu/SMT: Make SMT control more robust against enumeration failures
The SMT control mechanism got added as speculation attack vector mitigation. The implemented logic relies on the primary thread mask to be set up properly. This turns out to be an issue with XEN/PV guests because their CPU hotplug mechanics do not enumerate APICs and therefore the mask is never correctly populated. This went unnoticed so far because by chance XEN/PV ends up with smp_num_siblings == 2. So smt_hotplug_control stays at its default value CPU_SMT_ENABLED and the primary thread mask is never evaluated in the context of CPU hotplug. This stopped "working" with the upcoming overhaul of the topology evaluation which legitimately provides a fake topology for XEN/PV. That sets smp_num_siblings to 1, which causes the core CPU hot-plug core to refuse to bring up the APs. This happens because smt_hotplug_control is set to CPU_SMT_NOT_SUPPORTED which causes cpu_smt_allowed() to evaluate the unpopulated primary thread mask with the conclusion that all non-boot CPUs are not valid to be plugged. Make cpu_smt_allowed() more robust and take CPU_SMT_NOT_SUPPORTED and CPU_SMT_NOT_IMPLEMENTED into account. Rename it to cpu_bootable() while at it as that makes it more clear what the function is about. The primary mask issue on x86 XEN/PV needs to be addressed separately as there are users outside of the CPU hotplug code too. Fixes: 05736e4 ("cpu/hotplug: Provide knobs to control SMT") Reported-by: Juergen Gross <jgross@suse.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Tested-by: Juergen Gross <jgross@suse.com> Tested-by: Sohil Mehta <sohil.mehta@intel.com> Tested-by: Michael Kelley <mikelley@microsoft.com> Tested-by: Peter Zijlstra (Intel) <peterz@infradead.org> Tested-by: Zhang Rui <rui.zhang@intel.com> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lore.kernel.org/r/20230814085112.149440843@linutronix.de
1 parent ee545b9 commit d91bdd9

File tree

1 file changed

+13
-5
lines changed

1 file changed

+13
-5
lines changed

kernel/cpu.c

+13-5
Original file line numberDiff line numberDiff line change
@@ -659,11 +659,19 @@ static inline bool cpu_smt_thread_allowed(unsigned int cpu)
659659
#endif
660660
}
661661

662-
static inline bool cpu_smt_allowed(unsigned int cpu)
662+
static inline bool cpu_bootable(unsigned int cpu)
663663
{
664664
if (cpu_smt_control == CPU_SMT_ENABLED && cpu_smt_thread_allowed(cpu))
665665
return true;
666666

667+
/* All CPUs are bootable if controls are not configured */
668+
if (cpu_smt_control == CPU_SMT_NOT_IMPLEMENTED)
669+
return true;
670+
671+
/* All CPUs are bootable if CPU is not SMT capable */
672+
if (cpu_smt_control == CPU_SMT_NOT_SUPPORTED)
673+
return true;
674+
667675
if (topology_is_primary_thread(cpu))
668676
return true;
669677

@@ -685,7 +693,7 @@ bool cpu_smt_possible(void)
685693
EXPORT_SYMBOL_GPL(cpu_smt_possible);
686694

687695
#else
688-
static inline bool cpu_smt_allowed(unsigned int cpu) { return true; }
696+
static inline bool cpu_bootable(unsigned int cpu) { return true; }
689697
#endif
690698

691699
static inline enum cpuhp_state
@@ -788,10 +796,10 @@ static int bringup_wait_for_ap_online(unsigned int cpu)
788796
* SMT soft disabling on X86 requires to bring the CPU out of the
789797
* BIOS 'wait for SIPI' state in order to set the CR4.MCE bit. The
790798
* CPU marked itself as booted_once in notify_cpu_starting() so the
791-
* cpu_smt_allowed() check will now return false if this is not the
799+
* cpu_bootable() check will now return false if this is not the
792800
* primary sibling.
793801
*/
794-
if (!cpu_smt_allowed(cpu))
802+
if (!cpu_bootable(cpu))
795803
return -ECANCELED;
796804
return 0;
797805
}
@@ -1741,7 +1749,7 @@ static int cpu_up(unsigned int cpu, enum cpuhp_state target)
17411749
err = -EBUSY;
17421750
goto out;
17431751
}
1744-
if (!cpu_smt_allowed(cpu)) {
1752+
if (!cpu_bootable(cpu)) {
17451753
err = -EPERM;
17461754
goto out;
17471755
}

0 commit comments

Comments
 (0)