From 717f5931a0579bac239d80913b3aa4ef11e5dc7a Mon Sep 17 00:00:00 2001 From: "Chang S. Bae" Date: Fri, 6 Nov 2026 17:27:35 -0800 Subject: [PATCH] x86/microcode: Gate soft-offlined SMT siblings handling Handling of soft-offlined SMT siblings relies on NMI events, but is currently also executed even if use_nmi is false. This causes a practical problem on !use_nmi systems. When SMT siblings are soft-offlined, kick_offline_cpus() sends NMIs to them, but the offline NMI handler is already switched off. Thus, those siblings appear not responding, the rendezvous goes timeout, then finally the load fails. Gate the wake-up and release paths on use_nmi. Otherwise, keep the soft-offlined siblings in the offline state instead. Fixes: 8f849ff63bcb ("x86/microcode: Handle "offline" CPUs correctly") Signed-off-by: Chang S. Bae Cc: stable@vger.kernel.org --- Now I ended up sorting out this could be a real issue on AMD systems. But I appreciate if someone likely from AMD could test and confirm this fix before moving on. --- arch/x86/kernel/cpu/microcode/core.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c index 0dd0c7241c57..f1bd399f5ebf 100644 --- a/arch/x86/kernel/cpu/microcode/core.c +++ b/arch/x86/kernel/cpu/microcode/core.c @@ -498,21 +498,36 @@ static void release_offline_cpus(void) per_cpu(ucode_ctrl.ctrl, cpu) = SCTRL_DONE; } +static void keep_offline_cpus(void) +{ + unsigned int cpu; + + for_each_cpu(cpu, &cpu_offline_mask) + per_cpu(ucode_ctrl.result, cpu) = UCODE_OFFLINE; +} + static void load_primary(unsigned int cpu) { unsigned int nr_offl = cpumask_weight(&cpu_offline_mask); bool proceed = true; - /* Kick soft-offlined SMT siblings if required */ - if (!cpu && nr_offl) - proceed = kick_offline_cpus(nr_offl); + /* + * Kick soft-offlined SMT siblings via NMI events, when required and + * NMI use is configured. Otherwise, keep them in the offline state. + */ + if (!cpu && nr_offl) { + if (microcode_ops->use_nmi) + proceed = kick_offline_cpus(nr_offl); + else + keep_offline_cpus(); + } /* If the soft-offlined CPUs did not respond, abort */ if (proceed) __load_primary(cpu); /* Unconditionally release soft-offlined SMT siblings if required */ - if (!cpu && nr_offl) + if (microcode_ops->use_nmi && !cpu && nr_offl) release_offline_cpus(); } -- 2.53.0