linux/arch/x86
Thomas Gleixner 1f5e7eb786 x86/smp: Make stop_other_cpus() more robust
Tony reported intermittent lockups on poweroff. His analysis identified the
wbinvd() in stop_this_cpu() as the culprit. This was added to ensure that
on SME enabled machines a kexec() does not leave any stale data in the
caches when switching from encrypted to non-encrypted mode or vice versa.

That wbinvd() is conditional on the SME feature bit which is read directly
from CPUID. But that readout does not check whether the CPUID leaf is
available or not. If it's not available the CPU will return the value of
the highest supported leaf instead. Depending on the content the "SME" bit
might be set or not.

That's incorrect but harmless. Making the CPUID readout conditional makes
the observed hangs go away, but it does not fix the underlying problem:

CPU0					CPU1

 stop_other_cpus()
   send_IPIs(REBOOT);			stop_this_cpu()
   while (num_online_cpus() > 1);         set_online(false);
   proceed... -> hang
				          wbinvd()

WBINVD is an expensive operation and if multiple CPUs issue it at the same
time the resulting delays are even larger.

But CPU0 already observed num_online_cpus() going down to 1 and proceeds
which causes the system to hang.

This issue exists independent of WBINVD, but the delays caused by WBINVD
make it more prominent.

Make this more robust by adding a cpumask which is initialized to the
online CPU mask before sending the IPIs and CPUs clear their bit in
stop_this_cpu() after the WBINVD completed. Check for that cpumask to
become empty in stop_other_cpus() instead of watching num_online_cpus().

The cpumask cannot plug all holes either, but it's better than a raw
counter and allows to restrict the NMI fallback IPI to be sent only the
CPUs which have not reported within the timeout window.

Fixes: 08f253ec37 ("x86/cpu: Clear SME feature flag when not in use")
Reported-by: Tony Battersby <tonyb@cybernetics.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Borislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: Ashok Raj <ashok.raj@intel.com>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/all/3817d810-e0f1-8ef8-0bbd-663b919ca49b@cybernetics.com
Link: https://lore.kernel.org/r/87h6r770bv.ffs@tglx
2023-06-20 14:51:46 +02:00
..
boot * Do conditional __tdx_hypercall() 'output' processing via an 2023-04-28 09:36:09 -07:00
coco * Do conditional __tdx_hypercall() 'output' processing via an 2023-04-28 09:36:09 -07:00
configs x86/defconfig: Enable CONFIG_DEBUG_WX=y 2022-09-02 10:41:42 +02:00
crypto modules-6.4-rc1 2023-04-27 16:36:55 -07:00
entry Objtool changes for v6.4: 2023-04-28 14:02:54 -07:00
events perf/x86/uncore: Correct the number of CHAs on SPR 2023-05-24 22:19:41 +02:00
hyperv Objtool changes for v6.4: 2023-04-28 14:02:54 -07:00
ia32 x86/signal/32: Merge native and compat 32-bit signal code 2022-10-19 09:58:49 +02:00
include x86/smp: Make stop_other_cpus() more robust 2023-06-20 14:51:46 +02:00
kernel x86/smp: Make stop_other_cpus() more robust 2023-06-20 14:51:46 +02:00
kvm KVM: VMX: add MSR_IA32_TSX_CTRL into msrs_to_save 2023-05-21 04:05:51 -04:00
lib x86: re-introduce support for ERMS copies for user space accesses 2023-05-26 12:34:20 -07:00
math-emu
mm x86/mm: Avoid incomplete Global INVLPG flushes 2023-05-17 08:55:02 -07:00
net bpf, x86: Simplify the parsing logic of structure parameters 2023-01-10 15:53:22 -08:00
pci xen: branch for v6.4-rc4 2023-05-27 09:42:56 -07:00
platform Objtool changes for v6.4: 2023-04-28 14:02:54 -07:00
power x86/cpu: Mark {hlt,resume}_play_dead() __noreturn 2023-04-14 17:31:27 +02:00
purgatory purgatory: fix disabling debug info 2023-04-08 19:36:53 +09:00
ras
realmode x86/boot: Skip realmode init code when running as Xen PV guest 2022-11-25 12:05:22 +01:00
tools ELF: fix all "Elf" typos 2023-04-08 13:45:37 -07:00
um um: make stub data pages size tweakable 2023-04-20 23:08:43 +02:00
video
virt/vmx/tdx
xen Objtool changes for v6.4: 2023-04-28 14:02:54 -07:00
.gitignore x86/purgatory: Omit use of bin2c 2022-07-25 10:32:32 +02:00
Kbuild
Kconfig Add support for new Linear Address Masking CPU feature. This is similar 2023-04-28 09:43:49 -07:00
Kconfig.assembler crypto: x86/aria-avx - fix build failure with old binutils 2023-01-20 18:29:31 +08:00
Kconfig.cpu
Kconfig.debug docs: move x86 documentation into Documentation/arch/ 2023-03-30 12:58:51 -06:00
Makefile x86/build: Make 64-bit defconfig the default 2023-02-15 14:20:17 +01:00
Makefile_32.cpu
Makefile.um um: Only disable SSE on clang to work around old GCC bugs 2023-04-04 09:57:05 +02:00