x86: call machine_shutdown and stop all CPUs in native_machine_halt
Impact: really halt all CPUs on halt Function machine_halt (resp. native_machine_halt) is empty for x86 architectures. When command 'halt -f' is invoked, the message "System halted." is displayed but this is not really true because all CPUs are still running. There are also similar inconsistencies for other arches (some uses power-off for halt or forever-loop with IRQs enabled/disabled). IMO there should be used the same approach for all architectures OR what does the message "System halted" really mean? This patch fixes it for x86. Signed-off-by: Ivan Vecera <ivecera@redhat.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
parent
3ad4f59705
commit
d3ec5cae09
5 changed files with 24 additions and 13 deletions
|
@ -193,6 +193,7 @@ extern u8 setup_APIC_eilvt_ibs(u8 vector, u8 msg_type, u8 mask);
|
||||||
static inline void lapic_shutdown(void) { }
|
static inline void lapic_shutdown(void) { }
|
||||||
#define local_apic_timer_c2_ok 1
|
#define local_apic_timer_c2_ok 1
|
||||||
static inline void init_apic_mappings(void) { }
|
static inline void init_apic_mappings(void) { }
|
||||||
|
static inline void disable_local_APIC(void) { }
|
||||||
|
|
||||||
#endif /* !CONFIG_X86_LOCAL_APIC */
|
#endif /* !CONFIG_X86_LOCAL_APIC */
|
||||||
|
|
||||||
|
|
|
@ -314,6 +314,8 @@ extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
|
||||||
|
|
||||||
void default_idle(void);
|
void default_idle(void);
|
||||||
|
|
||||||
|
void stop_this_cpu(void *dummy);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Force strict CPU ordering.
|
* Force strict CPU ordering.
|
||||||
* And yes, this is required on UP too when we're talking
|
* And yes, this is required on UP too when we're talking
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <linux/pm.h>
|
#include <linux/pm.h>
|
||||||
#include <linux/clockchips.h>
|
#include <linux/clockchips.h>
|
||||||
#include <asm/system.h>
|
#include <asm/system.h>
|
||||||
|
#include <asm/apic.h>
|
||||||
|
|
||||||
unsigned long idle_halt;
|
unsigned long idle_halt;
|
||||||
EXPORT_SYMBOL(idle_halt);
|
EXPORT_SYMBOL(idle_halt);
|
||||||
|
@ -122,6 +123,21 @@ void default_idle(void)
|
||||||
EXPORT_SYMBOL(default_idle);
|
EXPORT_SYMBOL(default_idle);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void stop_this_cpu(void *dummy)
|
||||||
|
{
|
||||||
|
local_irq_disable();
|
||||||
|
/*
|
||||||
|
* Remove this CPU:
|
||||||
|
*/
|
||||||
|
cpu_clear(smp_processor_id(), cpu_online_map);
|
||||||
|
disable_local_APIC();
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
if (hlt_works(smp_processor_id()))
|
||||||
|
halt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void do_nothing(void *unused)
|
static void do_nothing(void *unused)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -461,6 +461,11 @@ static void native_machine_restart(char *__unused)
|
||||||
|
|
||||||
static void native_machine_halt(void)
|
static void native_machine_halt(void)
|
||||||
{
|
{
|
||||||
|
/* stop other cpus and apics */
|
||||||
|
machine_shutdown();
|
||||||
|
|
||||||
|
/* stop this cpu */
|
||||||
|
stop_this_cpu(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void native_machine_power_off(void)
|
static void native_machine_power_off(void)
|
||||||
|
|
|
@ -140,19 +140,6 @@ void native_send_call_func_ipi(cpumask_t mask)
|
||||||
send_IPI_mask(mask, CALL_FUNCTION_VECTOR);
|
send_IPI_mask(mask, CALL_FUNCTION_VECTOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stop_this_cpu(void *dummy)
|
|
||||||
{
|
|
||||||
local_irq_disable();
|
|
||||||
/*
|
|
||||||
* Remove this CPU:
|
|
||||||
*/
|
|
||||||
cpu_clear(smp_processor_id(), cpu_online_map);
|
|
||||||
disable_local_APIC();
|
|
||||||
if (hlt_works(smp_processor_id()))
|
|
||||||
for (;;) halt();
|
|
||||||
for (;;);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* this function calls the 'stop' function on all other CPUs in the system.
|
* this function calls the 'stop' function on all other CPUs in the system.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue