]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
arm64: smp: Fix hot-unplug tearing by forcing unregistration
authorJinjie Ruan <ruanjinjie@huawei.com>
Wed, 10 Jun 2026 07:52:01 +0000 (15:52 +0800)
committerWill Deacon <will@kernel.org>
Mon, 29 Jun 2026 10:47:05 +0000 (11:47 +0100)
Sashiko review pointed out the following issue[1].

Commit eba4675008a6 ("arm64: arch_register_cpu() variant to check if
an ACPI handle is now available.") introduced architectural safety
blocks inside arch_unregister_cpu(). If a hot-unplug operation is
determined to be a physical hardware removal (where _STA evaluates to
!ACPI_STA_DEVICE_PRESENT), or if firmware evaluation fails, it aborts
the unregistration transaction early to protect unreadied arm64
infrastructure.

However, returning early from arch_unregister_cpu() causes a catastrophic
state tearing because the generic ACPI layer (acpi_processor_post_eject())
unconditionally continues its cleanup flow. This leaves the stale sysfs
device leaked in the memory, deadlocking any subsequent hot-add attempts
on the same CPU.

Fix it by simplifying arch_unregister_cpu() to always proceed with
the unregistration, as a pr_err_once() warning is sufficient to make
it more visible for currently not supported physical CPU removal.
Also remove the redundant NULL check on acpi_handle as it cannot be
NULL when calling arch_unregister_cpu().

Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Jonathan Cameron <jic23@kernel.org>
Cc: James Morse <james.morse@arm.com>
Cc: stable@vger.kernel.org
Link: https://sashiko.dev/#/patchset/20260520022023.126670-1-ruanjinjie@huawei.com
Fixes: eba4675008a6 ("arm64: arch_register_cpu() variant to check if an ACPI handle is now available.")
Suggested-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Will Deacon <will@kernel.org>
arch/arm64/kernel/smp.c

index d46022f7207540c260736f06b15ac69699f3fdb7..0584d17f33baa8c2ff69d47add4ee64fd95048d0 100644 (file)
@@ -535,23 +535,13 @@ void arch_unregister_cpu(int cpu)
 {
        acpi_handle acpi_handle = acpi_get_processor_handle(cpu);
        struct cpu *c = &per_cpu(cpu_devices, cpu);
-       acpi_status status;
        unsigned long long sta;
-
-       if (!acpi_handle) {
-               pr_err_once("Removing a CPU without associated ACPI handle\n");
-               return;
-       }
+       acpi_status status;
 
        status = acpi_evaluate_integer(acpi_handle, "_STA", NULL, &sta);
-       if (ACPI_FAILURE(status))
-               return;
-
-       /* For now do not allow anything that looks like physical CPU HP */
-       if (cpu_present(cpu) && !(sta & ACPI_STA_DEVICE_PRESENT)) {
+       if (!ACPI_FAILURE(status) &&
+           cpu_present(cpu) && !(sta & ACPI_STA_DEVICE_PRESENT))
                pr_err_once("Changing CPU present bit is not supported\n");
-               return;
-       }
 
        unregister_cpu(c);
 }