static void kexec_prepare_cpus(void) { wake_offline_cpus(); smp_call_function(kexec_smp_down, NULL, /* wait */0); local_irq_disable(); hard_irq_disable(); mb(); /* make sure IRQs are disabled before we say they are */ get_paca()->kexec_state = KEXEC_STATE_IRQS_OFF; kexec_prepare_cpus_wait(KEXEC_STATE_IRQS_OFF); /* we are sure every CPU has IRQs off at this point */ kexec_all_irq_disabled = 1; /* after we tell the others to go down */ if (ppc_md.kexec_cpu_down) ppc_md.kexec_cpu_down(0, 0); /* * Before removing MMU mappings make sure all CPUs have entered real * mode: */ kexec_prepare_cpus_wait(KEXEC_STATE_REAL_MODE); put_cpu(); }
static void kexec_prepare_cpus_wait(int wait_state) { int my_cpu, i, notified=-1; wake_offline_cpus(); my_cpu = get_cpu(); /* Make sure each CPU has atleast made it to the state we need */ for (i=0; i < NR_CPUS; i++) { if (i == my_cpu) continue; while (paca[i].kexec_state < wait_state) { barrier(); if (!cpu_possible(i)) { printk("kexec: cpu %d hw_cpu_id %d is not" " possible, ignoring\n", i, paca[i].hw_cpu_id); break; } if (!cpu_online(i)) { /* Fixme: this can be spinning in * pSeries_secondary_wait with a paca * waiting for it to go online. */ printk("kexec: cpu %d hw_cpu_id %d is not" " online, ignoring\n", i, paca[i].hw_cpu_id); break; } if (i != notified) { printk( "kexec: waiting for cpu %d (physical" " %d) to enter %i state\n", i, paca[i].hw_cpu_id, wait_state); notified = i; } } } mb(); }