Loading arch/ia64/kernel/kprobes.c +13 −9 Original line number Diff line number Diff line Loading @@ -739,10 +739,14 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, switch(val) { case DIE_BREAK: /* err is break number from ia64_bad_break() */ if (args->err == 0x80200 || args->err == 0x80300) if (pre_kprobes_handler(args)) ret = NOTIFY_STOP; break; case DIE_SS: case DIE_FAULT: /* err is vector number from ia64_fault() */ if (args->err == 36) if (post_kprobes_handler(args->regs)) ret = NOTIFY_STOP; break; Loading arch/ia64/kernel/mca.c +95 −25 Original line number Diff line number Diff line Loading @@ -51,6 +51,9 @@ * * 2005-08-12 Keith Owens <kaos@sgi.com> * Convert MCA/INIT handlers to use per event stacks and SAL/OS state. * * 2005-10-07 Keith Owens <kaos@sgi.com> * Add notify_die() hooks. */ #include <linux/config.h> #include <linux/types.h> Loading @@ -58,7 +61,6 @@ #include <linux/sched.h> #include <linux/interrupt.h> #include <linux/irq.h> #include <linux/kallsyms.h> #include <linux/smp_lock.h> #include <linux/bootmem.h> #include <linux/acpi.h> Loading @@ -69,6 +71,7 @@ #include <linux/workqueue.h> #include <asm/delay.h> #include <asm/kdebug.h> #include <asm/machvec.h> #include <asm/meminit.h> #include <asm/page.h> Loading Loading @@ -132,6 +135,14 @@ extern void salinfo_log_wakeup(int type, u8 *buffer, u64 size, int irqsafe); static int mca_init; static void inline ia64_mca_spin(const char *func) { printk(KERN_EMERG "%s: spinning here, not returning to SAL\n", func); while (1) cpu_relax(); } /* * IA64_MCA log support */ Loading Loading @@ -526,13 +537,16 @@ ia64_mca_wakeup_all(void) * Outputs : None */ static irqreturn_t ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *ptregs) ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *regs) { unsigned long flags; int cpu = smp_processor_id(); /* Mask all interrupts */ local_irq_save(flags); if (notify_die(DIE_MCA_RENDZVOUS_ENTER, "MCA", regs, 0, 0, 0) == NOTIFY_STOP) ia64_mca_spin(__FUNCTION__); ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_DONE; /* Register with the SAL monarch that the slave has Loading @@ -540,10 +554,18 @@ ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *ptregs) */ ia64_sal_mc_rendez(); if (notify_die(DIE_MCA_RENDZVOUS_PROCESS, "MCA", regs, 0, 0, 0) == NOTIFY_STOP) ia64_mca_spin(__FUNCTION__); /* Wait for the monarch cpu to exit. */ while (monarch_cpu != -1) cpu_relax(); /* spin until monarch leaves */ if (notify_die(DIE_MCA_RENDZVOUS_LEAVE, "MCA", regs, 0, 0, 0) == NOTIFY_STOP) ia64_mca_spin(__FUNCTION__); /* Enable all interrupts */ local_irq_restore(flags); return IRQ_HANDLED; Loading Loading @@ -933,6 +955,9 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw, oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */ previous_current = ia64_mca_modify_original_stack(regs, sw, sos, "MCA"); monarch_cpu = cpu; if (notify_die(DIE_MCA_MONARCH_ENTER, "MCA", regs, 0, 0, 0) == NOTIFY_STOP) ia64_mca_spin(__FUNCTION__); ia64_wait_for_slaves(cpu); /* Wakeup all the processors which are spinning in the rendezvous loop. Loading @@ -942,6 +967,9 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw, * spinning in SAL does not work. */ ia64_mca_wakeup_all(); if (notify_die(DIE_MCA_MONARCH_PROCESS, "MCA", regs, 0, 0, 0) == NOTIFY_STOP) ia64_mca_spin(__FUNCTION__); /* Get the MCA error record and log it */ ia64_mca_log_sal_error_record(SAL_INFO_TYPE_MCA); Loading @@ -960,6 +988,9 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw, ia64_sal_clear_state_info(SAL_INFO_TYPE_MCA); sos->os_status = IA64_MCA_CORRECTED; } if (notify_die(DIE_MCA_MONARCH_LEAVE, "MCA", regs, 0, 0, recover) == NOTIFY_STOP) ia64_mca_spin(__FUNCTION__); set_curr_task(cpu, previous_current); monarch_cpu = -1; Loading Loading @@ -1188,6 +1219,37 @@ ia64_mca_cpe_poll (unsigned long dummy) #endif /* CONFIG_ACPI */ static int default_monarch_init_process(struct notifier_block *self, unsigned long val, void *data) { int c; struct task_struct *g, *t; if (val != DIE_INIT_MONARCH_PROCESS) return NOTIFY_DONE; printk(KERN_ERR "Processes interrupted by INIT -"); for_each_online_cpu(c) { struct ia64_sal_os_state *s; t = __va(__per_cpu_mca[c] + IA64_MCA_CPU_INIT_STACK_OFFSET); s = (struct ia64_sal_os_state *)((char *)t + MCA_SOS_OFFSET); g = s->prev_task; if (g) { if (g->pid) printk(" %d", g->pid); else printk(" %d (cpu %d task 0x%p)", g->pid, task_cpu(g), g); } } printk("\n\n"); if (read_trylock(&tasklist_lock)) { do_each_thread (g, t) { printk("\nBacktrace of pid %d (%s)\n", t->pid, t->comm); show_stack(t, NULL); } while_each_thread (g, t); read_unlock(&tasklist_lock); } return NOTIFY_DONE; } /* * C portion of the OS INIT handler * Loading @@ -1212,8 +1274,7 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw, static atomic_t slaves; static atomic_t monarchs; task_t *previous_current; int cpu = smp_processor_id(), c; struct task_struct *g, *t; int cpu = smp_processor_id(); oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */ console_loglevel = 15; /* make sure printks make it to console */ Loading Loading @@ -1253,8 +1314,17 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw, ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_INIT; while (monarch_cpu == -1) cpu_relax(); /* spin until monarch enters */ if (notify_die(DIE_INIT_SLAVE_ENTER, "INIT", regs, 0, 0, 0) == NOTIFY_STOP) ia64_mca_spin(__FUNCTION__); if (notify_die(DIE_INIT_SLAVE_PROCESS, "INIT", regs, 0, 0, 0) == NOTIFY_STOP) ia64_mca_spin(__FUNCTION__); while (monarch_cpu != -1) cpu_relax(); /* spin until monarch leaves */ if (notify_die(DIE_INIT_SLAVE_LEAVE, "INIT", regs, 0, 0, 0) == NOTIFY_STOP) ia64_mca_spin(__FUNCTION__); printk("Slave on cpu %d returning to normal service.\n", cpu); set_curr_task(cpu, previous_current); ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE; Loading @@ -1263,6 +1333,9 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw, } monarch_cpu = cpu; if (notify_die(DIE_INIT_MONARCH_ENTER, "INIT", regs, 0, 0, 0) == NOTIFY_STOP) ia64_mca_spin(__FUNCTION__); /* * Wait for a bit. On some machines (e.g., HP's zx2000 and zx6000, INIT can be Loading @@ -1273,27 +1346,16 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw, printk("Delaying for 5 seconds...\n"); udelay(5*1000000); ia64_wait_for_slaves(cpu); printk(KERN_ERR "Processes interrupted by INIT -"); for_each_online_cpu(c) { struct ia64_sal_os_state *s; t = __va(__per_cpu_mca[c] + IA64_MCA_CPU_INIT_STACK_OFFSET); s = (struct ia64_sal_os_state *)((char *)t + MCA_SOS_OFFSET); g = s->prev_task; if (g) { if (g->pid) printk(" %d", g->pid); else printk(" %d (cpu %d task 0x%p)", g->pid, task_cpu(g), g); } } printk("\n\n"); if (read_trylock(&tasklist_lock)) { do_each_thread (g, t) { printk("\nBacktrace of pid %d (%s)\n", t->pid, t->comm); show_stack(t, NULL); } while_each_thread (g, t); read_unlock(&tasklist_lock); } /* If nobody intercepts DIE_INIT_MONARCH_PROCESS then we drop through * to default_monarch_init_process() above and just print all the * tasks. */ if (notify_die(DIE_INIT_MONARCH_PROCESS, "INIT", regs, 0, 0, 0) == NOTIFY_STOP) ia64_mca_spin(__FUNCTION__); if (notify_die(DIE_INIT_MONARCH_LEAVE, "INIT", regs, 0, 0, 0) == NOTIFY_STOP) ia64_mca_spin(__FUNCTION__); printk("\nINIT dump complete. Monarch on cpu %d returning to normal service.\n", cpu); atomic_dec(&monarchs); set_curr_task(cpu, previous_current); Loading Loading @@ -1462,6 +1524,10 @@ ia64_mca_init(void) s64 rc; struct ia64_sal_retval isrv; u64 timeout = IA64_MCA_RENDEZ_TIMEOUT; /* platform specific */ static struct notifier_block default_init_monarch_nb = { .notifier_call = default_monarch_init_process, .priority = 0/* we need to notified last */ }; IA64_MCA_DEBUG("%s: begin\n", __FUNCTION__); Loading Loading @@ -1555,6 +1621,10 @@ ia64_mca_init(void) "(status %ld)\n", rc); return; } if (register_die_notifier(&default_init_monarch_nb)) { printk(KERN_ERR "Failed to register default monarch INIT process\n"); return; } IA64_MCA_DEBUG("%s: registered OS INIT handler with SAL\n", __FUNCTION__); Loading arch/ia64/kernel/process.c +6 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,9 @@ * Copyright (C) 1998-2003 Hewlett-Packard Co * David Mosberger-Tang <davidm@hpl.hp.com> * 04/11/17 Ashok Raj <ashok.raj@intel.com> Added CPU Hotplug Support * * 2005-10-07 Keith Owens <kaos@sgi.com> * Add notify_die() hooks. */ #define __KERNEL_SYSCALLS__ /* see <asm/unistd.h> */ #include <linux/config.h> Loading Loading @@ -34,6 +37,7 @@ #include <asm/elf.h> #include <asm/ia32.h> #include <asm/irq.h> #include <asm/kdebug.h> #include <asm/pgalloc.h> #include <asm/processor.h> #include <asm/sal.h> Loading Loading @@ -808,12 +812,14 @@ cpu_halt (void) void machine_restart (char *restart_cmd) { (void) notify_die(DIE_MACHINE_RESTART, restart_cmd, NULL, 0, 0, 0); (*efi.reset_system)(EFI_RESET_WARM, 0, 0, NULL); } void machine_halt (void) { (void) notify_die(DIE_MACHINE_HALT, "", NULL, 0, 0, 0); cpu_halt(); } Loading arch/ia64/kernel/traps.c +20 −24 Original line number Diff line number Diff line Loading @@ -30,17 +30,20 @@ fpswa_interface_t *fpswa_interface; EXPORT_SYMBOL(fpswa_interface); struct notifier_block *ia64die_chain; static DEFINE_SPINLOCK(die_notifier_lock); int register_die_notifier(struct notifier_block *nb) int register_die_notifier(struct notifier_block *nb) { int err = 0; unsigned long flags; spin_lock_irqsave(&die_notifier_lock, flags); err = notifier_chain_register(&ia64die_chain, nb); spin_unlock_irqrestore(&die_notifier_lock, flags); return err; return notifier_chain_register(&ia64die_chain, nb); } EXPORT_SYMBOL_GPL(register_die_notifier); int unregister_die_notifier(struct notifier_block *nb) { return notifier_chain_unregister(&ia64die_chain, nb); } EXPORT_SYMBOL_GPL(unregister_die_notifier); void __init trap_init (void) Loading Loading @@ -105,6 +108,7 @@ die (const char *str, struct pt_regs *regs, long err) if (++die.lock_owner_depth < 3) { printk("%s[%d]: %s %ld [%d]\n", current->comm, current->pid, str, err, ++die_counter); (void) notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV); show_regs(regs); } else printk(KERN_ERR "Recursive die() failure, output suppressed\n"); Loading Loading @@ -155,9 +159,8 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs) switch (break_num) { case 0: /* unknown error (used by GCC for __builtin_abort()) */ if (notify_die(DIE_BREAK, "break 0", regs, break_num, TRAP_BRKPT, SIGTRAP) == NOTIFY_STOP) { == NOTIFY_STOP) return; } die_if_kernel("bugcheck!", regs, break_num); sig = SIGILL; code = ILL_ILLOPC; break; Loading Loading @@ -210,15 +213,6 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs) sig = SIGILL; code = __ILL_BNDMOD; break; case 0x80200: case 0x80300: if (notify_die(DIE_BREAK, "kprobe", regs, break_num, TRAP_BRKPT, SIGTRAP) == NOTIFY_STOP) { return; } sig = SIGTRAP; code = TRAP_BRKPT; break; default: if (break_num < 0x40000 || break_num > 0x100000) die_if_kernel("Bad break", regs, break_num); Loading @@ -226,6 +220,9 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs) if (break_num < 0x80000) { sig = SIGILL; code = __ILL_BREAK; } else { if (notify_die(DIE_BREAK, "bad break", regs, break_num, TRAP_BRKPT, SIGTRAP) == NOTIFY_STOP) return; sig = SIGTRAP; code = TRAP_BRKPT; } } Loading Loading @@ -578,12 +575,11 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa, #endif break; case 35: siginfo.si_code = TRAP_BRANCH; ifa = 0; break; case 36: if (notify_die(DIE_SS, "ss", ®s, vector, vector, SIGTRAP) == NOTIFY_STOP) return; siginfo.si_code = TRAP_TRACE; ifa = 0; break; case 36: siginfo.si_code = TRAP_TRACE; ifa = 0; break; } if (notify_die(DIE_FAULT, "ia64_fault", ®s, vector, siginfo.si_code, SIGTRAP) == NOTIFY_STOP) return; siginfo.si_signo = SIGTRAP; siginfo.si_errno = 0; siginfo.si_addr = (void __user *) ifa; Loading include/asm-ia64/kdebug.h +28 −2 Original line number Diff line number Diff line Loading @@ -22,6 +22,9 @@ * 2005-Apr Rusty Lynch <rusty.lynch@intel.com> and Anil S Keshavamurthy * <anil.s.keshavamurthy@intel.com> adopted from * include/asm-x86_64/kdebug.h * * 2005-Oct Keith Owens <kaos@sgi.com>. Expand notify_die to cover more * events. */ #include <linux/notifier.h> Loading @@ -35,13 +38,36 @@ struct die_args { int signr; }; int register_die_notifier(struct notifier_block *nb); extern int register_die_notifier(struct notifier_block *); extern int unregister_die_notifier(struct notifier_block *); extern struct notifier_block *ia64die_chain; enum die_val { DIE_BREAK = 1, DIE_SS, DIE_FAULT, DIE_OOPS, DIE_PAGE_FAULT, DIE_MACHINE_HALT, DIE_MACHINE_RESTART, DIE_MCA_MONARCH_ENTER, DIE_MCA_MONARCH_PROCESS, DIE_MCA_MONARCH_LEAVE, DIE_MCA_SLAVE_ENTER, DIE_MCA_SLAVE_PROCESS, DIE_MCA_SLAVE_LEAVE, DIE_MCA_RENDZVOUS_ENTER, DIE_MCA_RENDZVOUS_PROCESS, DIE_MCA_RENDZVOUS_LEAVE, DIE_INIT_MONARCH_ENTER, DIE_INIT_MONARCH_PROCESS, DIE_INIT_MONARCH_LEAVE, DIE_INIT_SLAVE_ENTER, DIE_INIT_SLAVE_PROCESS, DIE_INIT_SLAVE_LEAVE, DIE_KDEBUG_ENTER, DIE_KDEBUG_LEAVE, DIE_KDUMP_ENTER, DIE_KDUMP_LEAVE, }; static inline int notify_die(enum die_val val, char *str, struct pt_regs *regs, Loading Loading
arch/ia64/kernel/kprobes.c +13 −9 Original line number Diff line number Diff line Loading @@ -739,10 +739,14 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, switch(val) { case DIE_BREAK: /* err is break number from ia64_bad_break() */ if (args->err == 0x80200 || args->err == 0x80300) if (pre_kprobes_handler(args)) ret = NOTIFY_STOP; break; case DIE_SS: case DIE_FAULT: /* err is vector number from ia64_fault() */ if (args->err == 36) if (post_kprobes_handler(args->regs)) ret = NOTIFY_STOP; break; Loading
arch/ia64/kernel/mca.c +95 −25 Original line number Diff line number Diff line Loading @@ -51,6 +51,9 @@ * * 2005-08-12 Keith Owens <kaos@sgi.com> * Convert MCA/INIT handlers to use per event stacks and SAL/OS state. * * 2005-10-07 Keith Owens <kaos@sgi.com> * Add notify_die() hooks. */ #include <linux/config.h> #include <linux/types.h> Loading @@ -58,7 +61,6 @@ #include <linux/sched.h> #include <linux/interrupt.h> #include <linux/irq.h> #include <linux/kallsyms.h> #include <linux/smp_lock.h> #include <linux/bootmem.h> #include <linux/acpi.h> Loading @@ -69,6 +71,7 @@ #include <linux/workqueue.h> #include <asm/delay.h> #include <asm/kdebug.h> #include <asm/machvec.h> #include <asm/meminit.h> #include <asm/page.h> Loading Loading @@ -132,6 +135,14 @@ extern void salinfo_log_wakeup(int type, u8 *buffer, u64 size, int irqsafe); static int mca_init; static void inline ia64_mca_spin(const char *func) { printk(KERN_EMERG "%s: spinning here, not returning to SAL\n", func); while (1) cpu_relax(); } /* * IA64_MCA log support */ Loading Loading @@ -526,13 +537,16 @@ ia64_mca_wakeup_all(void) * Outputs : None */ static irqreturn_t ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *ptregs) ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *regs) { unsigned long flags; int cpu = smp_processor_id(); /* Mask all interrupts */ local_irq_save(flags); if (notify_die(DIE_MCA_RENDZVOUS_ENTER, "MCA", regs, 0, 0, 0) == NOTIFY_STOP) ia64_mca_spin(__FUNCTION__); ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_DONE; /* Register with the SAL monarch that the slave has Loading @@ -540,10 +554,18 @@ ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *ptregs) */ ia64_sal_mc_rendez(); if (notify_die(DIE_MCA_RENDZVOUS_PROCESS, "MCA", regs, 0, 0, 0) == NOTIFY_STOP) ia64_mca_spin(__FUNCTION__); /* Wait for the monarch cpu to exit. */ while (monarch_cpu != -1) cpu_relax(); /* spin until monarch leaves */ if (notify_die(DIE_MCA_RENDZVOUS_LEAVE, "MCA", regs, 0, 0, 0) == NOTIFY_STOP) ia64_mca_spin(__FUNCTION__); /* Enable all interrupts */ local_irq_restore(flags); return IRQ_HANDLED; Loading Loading @@ -933,6 +955,9 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw, oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */ previous_current = ia64_mca_modify_original_stack(regs, sw, sos, "MCA"); monarch_cpu = cpu; if (notify_die(DIE_MCA_MONARCH_ENTER, "MCA", regs, 0, 0, 0) == NOTIFY_STOP) ia64_mca_spin(__FUNCTION__); ia64_wait_for_slaves(cpu); /* Wakeup all the processors which are spinning in the rendezvous loop. Loading @@ -942,6 +967,9 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw, * spinning in SAL does not work. */ ia64_mca_wakeup_all(); if (notify_die(DIE_MCA_MONARCH_PROCESS, "MCA", regs, 0, 0, 0) == NOTIFY_STOP) ia64_mca_spin(__FUNCTION__); /* Get the MCA error record and log it */ ia64_mca_log_sal_error_record(SAL_INFO_TYPE_MCA); Loading @@ -960,6 +988,9 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw, ia64_sal_clear_state_info(SAL_INFO_TYPE_MCA); sos->os_status = IA64_MCA_CORRECTED; } if (notify_die(DIE_MCA_MONARCH_LEAVE, "MCA", regs, 0, 0, recover) == NOTIFY_STOP) ia64_mca_spin(__FUNCTION__); set_curr_task(cpu, previous_current); monarch_cpu = -1; Loading Loading @@ -1188,6 +1219,37 @@ ia64_mca_cpe_poll (unsigned long dummy) #endif /* CONFIG_ACPI */ static int default_monarch_init_process(struct notifier_block *self, unsigned long val, void *data) { int c; struct task_struct *g, *t; if (val != DIE_INIT_MONARCH_PROCESS) return NOTIFY_DONE; printk(KERN_ERR "Processes interrupted by INIT -"); for_each_online_cpu(c) { struct ia64_sal_os_state *s; t = __va(__per_cpu_mca[c] + IA64_MCA_CPU_INIT_STACK_OFFSET); s = (struct ia64_sal_os_state *)((char *)t + MCA_SOS_OFFSET); g = s->prev_task; if (g) { if (g->pid) printk(" %d", g->pid); else printk(" %d (cpu %d task 0x%p)", g->pid, task_cpu(g), g); } } printk("\n\n"); if (read_trylock(&tasklist_lock)) { do_each_thread (g, t) { printk("\nBacktrace of pid %d (%s)\n", t->pid, t->comm); show_stack(t, NULL); } while_each_thread (g, t); read_unlock(&tasklist_lock); } return NOTIFY_DONE; } /* * C portion of the OS INIT handler * Loading @@ -1212,8 +1274,7 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw, static atomic_t slaves; static atomic_t monarchs; task_t *previous_current; int cpu = smp_processor_id(), c; struct task_struct *g, *t; int cpu = smp_processor_id(); oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */ console_loglevel = 15; /* make sure printks make it to console */ Loading Loading @@ -1253,8 +1314,17 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw, ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_INIT; while (monarch_cpu == -1) cpu_relax(); /* spin until monarch enters */ if (notify_die(DIE_INIT_SLAVE_ENTER, "INIT", regs, 0, 0, 0) == NOTIFY_STOP) ia64_mca_spin(__FUNCTION__); if (notify_die(DIE_INIT_SLAVE_PROCESS, "INIT", regs, 0, 0, 0) == NOTIFY_STOP) ia64_mca_spin(__FUNCTION__); while (monarch_cpu != -1) cpu_relax(); /* spin until monarch leaves */ if (notify_die(DIE_INIT_SLAVE_LEAVE, "INIT", regs, 0, 0, 0) == NOTIFY_STOP) ia64_mca_spin(__FUNCTION__); printk("Slave on cpu %d returning to normal service.\n", cpu); set_curr_task(cpu, previous_current); ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE; Loading @@ -1263,6 +1333,9 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw, } monarch_cpu = cpu; if (notify_die(DIE_INIT_MONARCH_ENTER, "INIT", regs, 0, 0, 0) == NOTIFY_STOP) ia64_mca_spin(__FUNCTION__); /* * Wait for a bit. On some machines (e.g., HP's zx2000 and zx6000, INIT can be Loading @@ -1273,27 +1346,16 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw, printk("Delaying for 5 seconds...\n"); udelay(5*1000000); ia64_wait_for_slaves(cpu); printk(KERN_ERR "Processes interrupted by INIT -"); for_each_online_cpu(c) { struct ia64_sal_os_state *s; t = __va(__per_cpu_mca[c] + IA64_MCA_CPU_INIT_STACK_OFFSET); s = (struct ia64_sal_os_state *)((char *)t + MCA_SOS_OFFSET); g = s->prev_task; if (g) { if (g->pid) printk(" %d", g->pid); else printk(" %d (cpu %d task 0x%p)", g->pid, task_cpu(g), g); } } printk("\n\n"); if (read_trylock(&tasklist_lock)) { do_each_thread (g, t) { printk("\nBacktrace of pid %d (%s)\n", t->pid, t->comm); show_stack(t, NULL); } while_each_thread (g, t); read_unlock(&tasklist_lock); } /* If nobody intercepts DIE_INIT_MONARCH_PROCESS then we drop through * to default_monarch_init_process() above and just print all the * tasks. */ if (notify_die(DIE_INIT_MONARCH_PROCESS, "INIT", regs, 0, 0, 0) == NOTIFY_STOP) ia64_mca_spin(__FUNCTION__); if (notify_die(DIE_INIT_MONARCH_LEAVE, "INIT", regs, 0, 0, 0) == NOTIFY_STOP) ia64_mca_spin(__FUNCTION__); printk("\nINIT dump complete. Monarch on cpu %d returning to normal service.\n", cpu); atomic_dec(&monarchs); set_curr_task(cpu, previous_current); Loading Loading @@ -1462,6 +1524,10 @@ ia64_mca_init(void) s64 rc; struct ia64_sal_retval isrv; u64 timeout = IA64_MCA_RENDEZ_TIMEOUT; /* platform specific */ static struct notifier_block default_init_monarch_nb = { .notifier_call = default_monarch_init_process, .priority = 0/* we need to notified last */ }; IA64_MCA_DEBUG("%s: begin\n", __FUNCTION__); Loading Loading @@ -1555,6 +1621,10 @@ ia64_mca_init(void) "(status %ld)\n", rc); return; } if (register_die_notifier(&default_init_monarch_nb)) { printk(KERN_ERR "Failed to register default monarch INIT process\n"); return; } IA64_MCA_DEBUG("%s: registered OS INIT handler with SAL\n", __FUNCTION__); Loading
arch/ia64/kernel/process.c +6 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,9 @@ * Copyright (C) 1998-2003 Hewlett-Packard Co * David Mosberger-Tang <davidm@hpl.hp.com> * 04/11/17 Ashok Raj <ashok.raj@intel.com> Added CPU Hotplug Support * * 2005-10-07 Keith Owens <kaos@sgi.com> * Add notify_die() hooks. */ #define __KERNEL_SYSCALLS__ /* see <asm/unistd.h> */ #include <linux/config.h> Loading Loading @@ -34,6 +37,7 @@ #include <asm/elf.h> #include <asm/ia32.h> #include <asm/irq.h> #include <asm/kdebug.h> #include <asm/pgalloc.h> #include <asm/processor.h> #include <asm/sal.h> Loading Loading @@ -808,12 +812,14 @@ cpu_halt (void) void machine_restart (char *restart_cmd) { (void) notify_die(DIE_MACHINE_RESTART, restart_cmd, NULL, 0, 0, 0); (*efi.reset_system)(EFI_RESET_WARM, 0, 0, NULL); } void machine_halt (void) { (void) notify_die(DIE_MACHINE_HALT, "", NULL, 0, 0, 0); cpu_halt(); } Loading
arch/ia64/kernel/traps.c +20 −24 Original line number Diff line number Diff line Loading @@ -30,17 +30,20 @@ fpswa_interface_t *fpswa_interface; EXPORT_SYMBOL(fpswa_interface); struct notifier_block *ia64die_chain; static DEFINE_SPINLOCK(die_notifier_lock); int register_die_notifier(struct notifier_block *nb) int register_die_notifier(struct notifier_block *nb) { int err = 0; unsigned long flags; spin_lock_irqsave(&die_notifier_lock, flags); err = notifier_chain_register(&ia64die_chain, nb); spin_unlock_irqrestore(&die_notifier_lock, flags); return err; return notifier_chain_register(&ia64die_chain, nb); } EXPORT_SYMBOL_GPL(register_die_notifier); int unregister_die_notifier(struct notifier_block *nb) { return notifier_chain_unregister(&ia64die_chain, nb); } EXPORT_SYMBOL_GPL(unregister_die_notifier); void __init trap_init (void) Loading Loading @@ -105,6 +108,7 @@ die (const char *str, struct pt_regs *regs, long err) if (++die.lock_owner_depth < 3) { printk("%s[%d]: %s %ld [%d]\n", current->comm, current->pid, str, err, ++die_counter); (void) notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV); show_regs(regs); } else printk(KERN_ERR "Recursive die() failure, output suppressed\n"); Loading Loading @@ -155,9 +159,8 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs) switch (break_num) { case 0: /* unknown error (used by GCC for __builtin_abort()) */ if (notify_die(DIE_BREAK, "break 0", regs, break_num, TRAP_BRKPT, SIGTRAP) == NOTIFY_STOP) { == NOTIFY_STOP) return; } die_if_kernel("bugcheck!", regs, break_num); sig = SIGILL; code = ILL_ILLOPC; break; Loading Loading @@ -210,15 +213,6 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs) sig = SIGILL; code = __ILL_BNDMOD; break; case 0x80200: case 0x80300: if (notify_die(DIE_BREAK, "kprobe", regs, break_num, TRAP_BRKPT, SIGTRAP) == NOTIFY_STOP) { return; } sig = SIGTRAP; code = TRAP_BRKPT; break; default: if (break_num < 0x40000 || break_num > 0x100000) die_if_kernel("Bad break", regs, break_num); Loading @@ -226,6 +220,9 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs) if (break_num < 0x80000) { sig = SIGILL; code = __ILL_BREAK; } else { if (notify_die(DIE_BREAK, "bad break", regs, break_num, TRAP_BRKPT, SIGTRAP) == NOTIFY_STOP) return; sig = SIGTRAP; code = TRAP_BRKPT; } } Loading Loading @@ -578,12 +575,11 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa, #endif break; case 35: siginfo.si_code = TRAP_BRANCH; ifa = 0; break; case 36: if (notify_die(DIE_SS, "ss", ®s, vector, vector, SIGTRAP) == NOTIFY_STOP) return; siginfo.si_code = TRAP_TRACE; ifa = 0; break; case 36: siginfo.si_code = TRAP_TRACE; ifa = 0; break; } if (notify_die(DIE_FAULT, "ia64_fault", ®s, vector, siginfo.si_code, SIGTRAP) == NOTIFY_STOP) return; siginfo.si_signo = SIGTRAP; siginfo.si_errno = 0; siginfo.si_addr = (void __user *) ifa; Loading
include/asm-ia64/kdebug.h +28 −2 Original line number Diff line number Diff line Loading @@ -22,6 +22,9 @@ * 2005-Apr Rusty Lynch <rusty.lynch@intel.com> and Anil S Keshavamurthy * <anil.s.keshavamurthy@intel.com> adopted from * include/asm-x86_64/kdebug.h * * 2005-Oct Keith Owens <kaos@sgi.com>. Expand notify_die to cover more * events. */ #include <linux/notifier.h> Loading @@ -35,13 +38,36 @@ struct die_args { int signr; }; int register_die_notifier(struct notifier_block *nb); extern int register_die_notifier(struct notifier_block *); extern int unregister_die_notifier(struct notifier_block *); extern struct notifier_block *ia64die_chain; enum die_val { DIE_BREAK = 1, DIE_SS, DIE_FAULT, DIE_OOPS, DIE_PAGE_FAULT, DIE_MACHINE_HALT, DIE_MACHINE_RESTART, DIE_MCA_MONARCH_ENTER, DIE_MCA_MONARCH_PROCESS, DIE_MCA_MONARCH_LEAVE, DIE_MCA_SLAVE_ENTER, DIE_MCA_SLAVE_PROCESS, DIE_MCA_SLAVE_LEAVE, DIE_MCA_RENDZVOUS_ENTER, DIE_MCA_RENDZVOUS_PROCESS, DIE_MCA_RENDZVOUS_LEAVE, DIE_INIT_MONARCH_ENTER, DIE_INIT_MONARCH_PROCESS, DIE_INIT_MONARCH_LEAVE, DIE_INIT_SLAVE_ENTER, DIE_INIT_SLAVE_PROCESS, DIE_INIT_SLAVE_LEAVE, DIE_KDEBUG_ENTER, DIE_KDEBUG_LEAVE, DIE_KDUMP_ENTER, DIE_KDUMP_LEAVE, }; static inline int notify_die(enum die_val val, char *str, struct pt_regs *regs, Loading