]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
x86/smp: Add smp_ops.stop_this_cpu() callback
authorKirill A. Shutemov <kirill.shutemov@linux.intel.com>
Fri, 14 Jun 2024 09:59:01 +0000 (12:59 +0300)
committerBorislav Petkov (AMD) <bp@alien8.de>
Mon, 17 Jun 2024 15:46:20 +0000 (17:46 +0200)
If the helper is defined, it is called instead of halt() to stop the CPU at the
end of stop_this_cpu() and on crash CPU shutdown.

ACPI MADT will use it to hand over the CPU to BIOS in order to be able to wake
it up again after kexec.

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Kai Huang <kai.huang@intel.com>
Tested-by: Tao Liu <ltao@redhat.com>
Link: https://lore.kernel.org/r/20240614095904.1345461-17-kirill.shutemov@linux.intel.com
arch/x86/include/asm/smp.h
arch/x86/kernel/process.c
arch/x86/kernel/reboot.c

index a35936b512fee639db9930fa64b543687edbf0b8..ca073f40698fad98b0ded3ea854dc35c203fa5f4 100644 (file)
@@ -35,6 +35,7 @@ struct smp_ops {
        int (*cpu_disable)(void);
        void (*cpu_die)(unsigned int cpu);
        void (*play_dead)(void);
+       void (*stop_this_cpu)(void);
 
        void (*send_call_func_ipi)(const struct cpumask *mask);
        void (*send_call_func_single_ipi)(int cpu);
index b8441147eb5e84bc6b75648a1228c16850cd5897..f63f8fd00a91f3d1171f307b92179556ba2d716d 100644 (file)
@@ -835,6 +835,13 @@ void __noreturn stop_this_cpu(void *dummy)
         */
        cpumask_clear_cpu(cpu, &cpus_stop_mask);
 
+#ifdef CONFIG_SMP
+       if (smp_ops.stop_this_cpu) {
+               smp_ops.stop_this_cpu();
+               unreachable();
+       }
+#endif
+
        for (;;) {
                /*
                 * Use native_halt() so that memory contents don't change
index bb7a44af7efd19690132d15d97550b5a22cbec2a..0e0a4cf6b5eb1702d61a94583e69f26a228d1940 100644 (file)
@@ -880,6 +880,12 @@ static int crash_nmi_callback(unsigned int val, struct pt_regs *regs)
        cpu_emergency_disable_virtualization();
 
        atomic_dec(&waiting_for_crash_ipi);
+
+       if (smp_ops.stop_this_cpu) {
+               smp_ops.stop_this_cpu();
+               unreachable();
+       }
+
        /* Assume hlt works */
        halt();
        for (;;)