arch/x86/include/asm/processor.h | 2 +- arch/x86/kernel/process.c | 14 +++++++++++++- arch/x86/kernel/reboot.c | 2 +- arch/x86/kernel/smp.c | 9 ++++++--- 4 files changed, 21 insertions(+), 6 deletions(-)
From cbf1606332c48b32c4bb8d61ac6911e3064e79fc Mon Sep 17 00:00:00 2001
From: Guocai He <guocai.he.cn@windriver.com>
Date: Wed, 4 Sep 2024 04:45:26 +0000
Subject: [PATCH] patch for poweroff
---
arch/x86/include/asm/processor.h | 2 +-
arch/x86/kernel/process.c | 14 +++++++++++++-
arch/x86/kernel/reboot.c | 2 +-
arch/x86/kernel/smp.c | 9 ++++++---
4 files changed, 21 insertions(+), 6 deletions(-)
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 5f4e79d14613..4c1cf610807a 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -975,7 +975,7 @@ bool xen_set_default_idle(void);
#define xen_set_default_idle 0
#endif
-void stop_this_cpu(void *dummy);
+void stop_this_cpu(bool sync);
void df_debug(struct pt_regs *regs, long error_code);
void microcode_check(void);
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 2243af6530f8..35d5cf73716e 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -590,9 +590,21 @@ bool xen_set_default_idle(void)
}
#endif
-void stop_this_cpu(void *dummy)
+atomic_t cpus_stop_in_ipi;
+void stop_this_cpu(bool sync)
{
local_irq_disable();
+
+ /*
+ * Account this cpu and loop until the other cpus reached this
+ * point. If they don't react, the control cpu will raise an NMI.
+ */
+ if(sync) {
+ atomic_dec(&cpus_stop_in_ipi);
+ while (atomic_read(&cpus_stop_in_ipi))
+ cpu_relax();
+ }
+
/*
* Remove this CPU:
*/
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
index 3f677832fc12..389643727e37 100644
--- a/arch/x86/kernel/reboot.c
+++ b/arch/x86/kernel/reboot.c
@@ -742,7 +742,7 @@ static void native_machine_halt(void)
tboot_shutdown(TB_SHUTDOWN_HALT);
- stop_this_cpu(NULL);
+ stop_this_cpu(false);
}
static void native_machine_power_off(void)
diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c
index f2a749586252..9dee65b96115 100644
--- a/arch/x86/kernel/smp.c
+++ b/arch/x86/kernel/smp.c
@@ -112,6 +112,7 @@
* about nothing of note with C stepping upwards.
*/
+extern atomic_t cpus_stop_in_ipi;
static atomic_t stopping_cpu = ATOMIC_INIT(-1);
static bool smp_no_nmi_ipi = false;
@@ -162,7 +163,7 @@ static int smp_stop_nmi_callback(unsigned int val, struct pt_regs *regs)
return NMI_HANDLED;
cpu_emergency_vmxoff();
- stop_this_cpu(NULL);
+ stop_this_cpu(false);
return NMI_HANDLED;
}
@@ -175,7 +176,7 @@ asmlinkage __visible void smp_reboot_interrupt(void)
{
ipi_entering_ack_irq();
cpu_emergency_vmxoff();
- stop_this_cpu(NULL);
+ stop_this_cpu(true);
irq_exit();
}
@@ -192,7 +193,8 @@ static void native_stop_other_cpus(int wait)
if (reboot_force)
return;
-
+
+ atomic_set(&cpus_stop_in_ipi, num_online_cpus() - 1);
/*
* Use an own vector here because smp_call_function
* does lots of things not suitable in a panic situation.
@@ -256,6 +258,7 @@ static void native_stop_other_cpus(int wait)
local_irq_save(flags);
disable_local_APIC();
mcheck_cpu_clear(this_cpu_ptr(&cpu_info));
+ atomic_set(&cpus_stop_in_ipi, 0);
local_irq_restore(flags);
}
--
2.25.1
© 2016 - 2024 Red Hat, Inc.