kexec: machine_shutdown.x86_64
PATCH 9/14 kexec: machine_shutdown.x86_64
Factor out the apic and smp shutdown code from machine_restart so it can be called by in the kexec reboot path as well.
arch/x86_64/kernel/reboot.c +29 -32
@@ -91,31 +91,6 @@ [target] "b" (WARMBOOT_TRAMP)); } -#ifdef CONFIG_SMP -static void smp_halt (void ) -{ -int cpuid =safe_smp_processor_id (); -static int first_entry =1 ; - -if (first_entry) { - first_entry =0 ; -smp_call_function ((void *)machine_restart,NULL ,1 ,0 ); - } - -smp_stop_cpu (); - -/* AP calling this. Just halt */ -if (cpuid != boot_cpu_id) { -for (;;) - asm("hlt" ); - } - -/* Wait for all other CPUs to have run smp_stop_cpu */ -while (!cpus_empty (cpu_online_map)) -rep_nop (); -} -#endif -static inline void kb_wait (void ) {int i;
@@ -125,23 +100,45 @@break ; } -void machine_restart (char * __unused) +void machine_shutdown (void ) { -int i; - +/* Stop the cpus and apics */ #ifdef CONFIG_SMP -smp_halt (); -#endif +int reboot_cpu_id; + +/* The boot cpu is always logical cpu 0 */ + reboot_cpu_id =0 ; +/* Make certain the cpu I'm about to reboot on is online */ +if (!cpu_isset (reboot_cpu_id, cpu_online_map)) { + reboot_cpu_id =smp_processor_id (); + } + +/* Make certain I only run on the appropriate processor */ +set_cpus_allowed (current,cpumask_of_cpu (reboot_cpu_id)); + +/* O.K Now that I'm on the appropriate processor, +* stop all of the others. +*/ +smp_send_stop (); +#endif +local_irq_disable (); - +#ifndef CONFIG_SMP disable_local_APIC ();#endif disable_IO_APIC (); - +local_irq_enable (); +} + +void machine_restart (char * __unused) +{ +int i; + +machine_shutdown ();/* Tell the BIOS if we want cold or warm reboot */ *((unsigned short *)__va (0x472 )) = reboot_mode;