static void crash_shutdown_secondary(void *passed_regs) { struct pt_regs *regs = passed_regs; int cpu = smp_processor_id(); /* * If we are passed registers, use those. Otherwise get the * regs from the last interrupt, which should be correct, as * we are in an interrupt. But if the regs are not there, * pull them from the top of the stack. They are probably * wrong, but we need something to keep from crashing again. */ if (!regs) regs = get_irq_regs(); if (!regs) regs = task_pt_regs(current); if (!cpu_online(cpu)) return; /* We won't be sent IPIs any more. */ set_cpu_online(cpu, false); local_irq_disable(); if (!cpumask_test_cpu(cpu, &cpus_in_crash)) crash_save_cpu(regs, cpu); cpumask_set_cpu(cpu, &cpus_in_crash); while (!atomic_read(&kexec_ready_to_reboot)) cpu_relax(); kexec_reboot(); /* NOTREACHED */ }
/* * Exec the new kernel (reboot) */ static int my_exec(void) { int result; result = kexec_reboot(); /* I have failed if I make it here */ fprintf(stderr, "kexec failed: %s\n", strerror(errno)); return -1; }
static void boot_process(struct load_url_result *result, void *data) { struct boot_task *task = data; int rc = -1; if (task->cancelled) { cleanup_cancellations(task, result); return; } if (load_pending(task->image) || load_pending(task->initrd) || load_pending(task->dtb)) return; if (check_load(task, "kernel image", task->image) || check_load(task, "initrd", task->initrd) || check_load(task, "dtb", task->dtb)) goto no_load; /* we make a copy of the local paths, as the boot hooks might update * and/or create these */ task->local_image = task->image ? task->image->local : NULL; task->local_initrd = task->initrd ? task->initrd->local : NULL; task->local_dtb = task->dtb ? task->dtb->local : NULL; run_boot_hooks(task); update_status(task->status_fn, task->status_arg, BOOT_STATUS_INFO, _("performing kexec_load")); rc = kexec_load(task); if (rc) { update_status(task->status_fn, task->status_arg, BOOT_STATUS_ERROR, _("kexec load failed")); } no_load: cleanup_load(task->image); cleanup_load(task->initrd); cleanup_load(task->dtb); if (!rc) { update_status(task->status_fn, task->status_arg, BOOT_STATUS_INFO, _("performing kexec reboot")); rc = kexec_reboot(task); if (rc) { update_status(task->status_fn, task->status_arg, BOOT_STATUS_ERROR, _("kexec reboot failed")); } } }