void default_machine_crash_shutdown(struct pt_regs *regs) { unsigned int i; int (*old_handler)(struct pt_regs *regs); /* * This function is only called after the system * has panicked or is otherwise in a critical state. * The minimum amount of code to allow a kexec'd kernel * to run successfully needs to happen here. * * In practice this means stopping other cpus in * an SMP system. * The kernel is broken so disable interrupts. */ hard_irq_disable(); /* * Make a note of crashing cpu. Will be used in machine_kexec * such that another IPI will not be sent. */ crashing_cpu = smp_processor_id(); crash_save_cpu(regs, crashing_cpu); crash_kexec_prepare_cpus(crashing_cpu); cpu_set(crashing_cpu, cpus_in_crash); #if defined(CONFIG_PPC_STD_MMU_64) && defined(CONFIG_SMP) crash_kexec_wait_realmode(crashing_cpu); #endif machine_kexec_mask_interrupts(); /* * Call registered shutdown routines savely. Swap out * __debugger_fault_handler, and replace on exit. */ old_handler = __debugger_fault_handler; __debugger_fault_handler = handle_fault; crash_shutdown_cpu = smp_processor_id(); for (i = 0; crash_shutdown_handles[i]; i++) { if (setjmp(crash_shutdown_buf) == 0) { /* * Insert syncs and delay to ensure * instructions in the dangerous region don't * leak away from this protected region. */ asm volatile("sync; isync"); /* dangerous region */ crash_shutdown_handles[i](); asm volatile("sync; isync"); } } crash_shutdown_cpu = -1; __debugger_fault_handler = old_handler; crash_kexec_stop_spus(); if (ppc_md.kexec_cpu_down) ppc_md.kexec_cpu_down(1, 0); }
/* Override the weak function in kernel/panic.c */ void crash_smp_send_stop(void) { if (_crash_smp_send_stop) _crash_smp_send_stop(); crash_kexec_prepare_cpus(); }
void default_machine_crash_shutdown(struct pt_regs *regs) { local_irq_disable(); crashing_cpu = smp_processor_id(); crash_save_cpu(regs, crashing_cpu); crash_kexec_prepare_cpus(); cpumask_set_cpu(crashing_cpu, &cpus_in_crash); }
void default_machine_crash_shutdown(struct pt_regs *regs) { unsigned int irq; /* * This function is only called after the system * has panicked or is otherwise in a critical state. * The minimum amount of code to allow a kexec'd kernel * to run successfully needs to happen here. * * In practice this means stopping other cpus in * an SMP system. * The kernel is broken so disable interrupts. */ hard_irq_disable(); for_each_irq(irq) { struct irq_desc *desc = irq_desc + irq; if (desc->status & IRQ_INPROGRESS) desc->chip->eoi(irq); if (!(desc->status & IRQ_DISABLED)) desc->chip->disable(irq); } /* * Make a note of crashing cpu. Will be used in machine_kexec * such that another IPI will not be sent. */ crashing_cpu = smp_processor_id(); crash_save_cpu(regs, crashing_cpu); crash_kexec_prepare_cpus(crashing_cpu); cpu_set(crashing_cpu, cpus_in_crash); crash_kexec_stop_spus(); if (ppc_md.kexec_cpu_down) ppc_md.kexec_cpu_down(1, 0); }
void default_machine_crash_shutdown(struct pt_regs *regs) { unsigned int i; int (*old_handler)(struct pt_regs *regs); /* * This function is only called after the system * has panicked or is otherwise in a critical state. * The minimum amount of code to allow a kexec'd kernel * to run successfully needs to happen here. * * In practice this means stopping other cpus in * an SMP system. * The kernel is broken so disable interrupts. */ local_irq_disable(); for_each_irq(i) { struct irq_desc *desc = irq_desc + i; if (desc->status & IRQ_INPROGRESS) desc->chip->eoi(i); if (!(desc->status & IRQ_DISABLED)) desc->chip->disable(i); } /* * Call registered shutdown routines savely. Swap out * __debugger_fault_handler, and replace on exit. */ old_handler = __debugger_fault_handler; __debugger_fault_handler = handle_fault; for (i = 0; crash_shutdown_handles[i]; i++) { if (setjmp(crash_shutdown_buf) == 0) { /* * Insert syncs and delay to ensure * instructions in the dangerous region don't * leak away from this protected region. */ asm volatile("sync; isync"); /* dangerous region */ crash_shutdown_handles[i](); asm volatile("sync; isync"); /* * wait a little while to see if we get a * machine check */ __delay(200); } } __debugger_fault_handler = old_handler; /* * Make a note of crashing cpu. Will be used in machine_kexec * such that another IPI will not be sent. */ crashing_cpu = smp_processor_id(); crash_save_this_cpu(regs, crashing_cpu); crash_kexec_prepare_cpus(crashing_cpu); cpu_set(crashing_cpu, cpus_in_crash); crash_kexec_stop_spus(); if (ppc_md.kexec_cpu_down) ppc_md.kexec_cpu_down(1, 0); }
void default_machine_crash_shutdown(struct pt_regs *regs) { unsigned int i; int (*old_handler)(struct pt_regs *regs); /* * This function is only called after the system * has panicked or is otherwise in a critical state. * The minimum amount of code to allow a kexec'd kernel * to run successfully needs to happen here. * * In practice this means stopping other cpus in * an SMP system. * The kernel is broken so disable interrupts. */ hard_irq_disable(); /* * Make a note of crashing cpu. Will be used in machine_kexec * such that another IPI will not be sent. */ crashing_cpu = smp_processor_id(); /* * If we came in via system reset, wait a while for the secondary * CPUs to enter. */ if (TRAP(regs) == 0x100) mdelay(PRIMARY_TIMEOUT); crash_kexec_prepare_cpus(crashing_cpu); crash_save_cpu(regs, crashing_cpu); time_to_dump = 1; crash_kexec_wait_realmode(crashing_cpu); machine_kexec_mask_interrupts(); /* * Call registered shutdown routines safely. Swap out * __debugger_fault_handler, and replace on exit. */ old_handler = __debugger_fault_handler; __debugger_fault_handler = handle_fault; crash_shutdown_cpu = smp_processor_id(); for (i = 0; i < CRASH_HANDLER_MAX && crash_shutdown_handles[i]; i++) { if (setjmp(crash_shutdown_buf) == 0) { /* * Insert syncs and delay to ensure * instructions in the dangerous region don't * leak away from this protected region. */ asm volatile("sync; isync"); /* dangerous region */ crash_shutdown_handles[i](); asm volatile("sync; isync"); } } crash_shutdown_cpu = -1; __debugger_fault_handler = old_handler; if (ppc_md.kexec_cpu_down) ppc_md.kexec_cpu_down(1, 0); }