Skip to content

Commit f3e68ab

Browse files
KAGA-KOKOgregkh
authored andcommitted
Revert "x86/apic: Ignore secondary threads if nosmt=force"
commit 506a66f upstream Dave Hansen reported, that it's outright dangerous to keep SMT siblings disabled completely so they are stuck in the BIOS and wait for SIPI. The reason is that Machine Check Exceptions are broadcasted to siblings and the soft disabled sibling has CR4.MCE = 0. If a MCE is delivered to a logical core with CR4.MCE = 0, it asserts IERR#, which shuts down or reboots the machine. The MCE chapter in the SDM contains the following blurb: Because the logical processors within a physical package are tightly coupled with respect to shared hardware resources, both logical processors are notified of machine check errors that occur within a given physical processor. If machine-check exceptions are enabled when a fatal error is reported, all the logical processors within a physical package are dispatched to the machine-check exception handler. If machine-check exceptions are disabled, the logical processors enter the shutdown state and assert the IERR# signal. When enabling machine-check exceptions, the MCE flag in control register CR4 should be set for each logical processor. Reverting the commit which ignores siblings at enumeration time solves only half of the problem. The core cpuhotplug logic needs to be adjusted as well. This thoughtful engineered mechanism also turns the boot process on all Intel HT enabled systems into a MCE lottery. MCE is enabled on the boot CPU before the secondary CPUs are brought up. Depending on the number of physical cores the window in which this situation can happen is smaller or larger. On a HSW-EX it's about 750ms: MCE is enabled on the boot CPU: [ 0.244017] mce: CPU supports 22 MCE banks The corresponding sibling #72 boots: [ 1.008005] .... node #0, CPUs: #72 That means if an MCE hits on physical core 0 (logical CPUs 0 and 72) between these two points the machine is going to shutdown. At least it's a known safe state. It's obvious that the early boot can be hit by an MCE as well and then runs into the same situation because MCEs are not yet enabled on the boot CPU. But after enabling them on the boot CPU, it does not make any sense to prevent the kernel from recovering. Adjust the nosmt kernel parameter documentation as well. Reverts: 2207def ("x86/apic: Ignore secondary threads if nosmt=force") Reported-by: Dave Hansen <dave.hansen@intel.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Tested-by: Tony Luck <tony.luck@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 49221fc commit f3e68ab

File tree

4 files changed

+3
-29
lines changed

4 files changed

+3
-29
lines changed

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2596,12 +2596,8 @@
25962596
Equivalent to smt=1.
25972597

25982598
[KNL,x86] Disable symmetric multithreading (SMT).
2599-
nosmt=force: Force disable SMT, similar to disabling
2600-
it in the BIOS except that some of the
2601-
resource partitioning effects which are
2602-
caused by having SMT enabled in the BIOS
2603-
cannot be undone. Depending on the CPU
2604-
type this might have a performance impact.
2599+
nosmt=force: Force disable SMT, cannot be undone
2600+
via the sysfs control file.
26052601

26062602
nospectre_v2 [X86] Disable all mitigations for the Spectre variant 2
26072603
(indirect branch prediction) vulnerability. System may

arch/x86/include/asm/apic.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -616,10 +616,8 @@ extern int default_check_phys_apicid_present(int phys_apicid);
616616

617617
#ifdef CONFIG_SMP
618618
bool apic_id_is_primary_thread(unsigned int id);
619-
bool apic_id_disabled(unsigned int id);
620619
#else
621620
static inline bool apic_id_is_primary_thread(unsigned int id) { return false; }
622-
static inline bool apic_id_disabled(unsigned int id) { return false; }
623621
#endif
624622

625623
extern void irq_enter(void);

arch/x86/kernel/acpi/boot.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,7 @@ static int acpi_register_lapic(int id, u32 acpiid, u8 enabled)
181181
}
182182

183183
if (!enabled) {
184-
if (!apic_id_disabled(id))
185-
++disabled_cpus;
184+
++disabled_cpus;
186185
return -EINVAL;
187186
}
188187

arch/x86/kernel/apic/apic.c

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2107,16 +2107,6 @@ bool apic_id_is_primary_thread(unsigned int apicid)
21072107
return !(apicid & mask);
21082108
}
21092109

2110-
/**
2111-
* apic_id_disabled - Check whether APIC ID is disabled via SMT control
2112-
* @id: APIC ID to check
2113-
*/
2114-
bool apic_id_disabled(unsigned int id)
2115-
{
2116-
return (cpu_smt_control == CPU_SMT_FORCE_DISABLED &&
2117-
!apic_id_is_primary_thread(id));
2118-
}
2119-
21202110
/*
21212111
* Should use this API to allocate logical CPU IDs to keep nr_logical_cpuids
21222112
* and cpuid_to_apicid[] synchronized.
@@ -2212,15 +2202,6 @@ int generic_processor_info(int apicid, int version)
22122202
return -EINVAL;
22132203
}
22142204

2215-
/*
2216-
* If SMT is force disabled and the APIC ID belongs to
2217-
* a secondary thread, ignore it.
2218-
*/
2219-
if (apic_id_disabled(apicid)) {
2220-
pr_info_once("Ignoring secondary SMT threads\n");
2221-
return -EINVAL;
2222-
}
2223-
22242205
if (apicid == boot_cpu_physical_apicid) {
22252206
/*
22262207
* x86_bios_cpu_apicid is required to have processors listed

0 commit comments

Comments
 (0)