mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-30 10:49:28 +00:00
Pull extend-notify-die into release branch
This commit is contained in:
commit
cb8a55e4cd
5 changed files with 162 additions and 60 deletions
|
@ -347,7 +347,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
|
||||||
((struct fnptr *)kretprobe_trampoline)->ip;
|
((struct fnptr *)kretprobe_trampoline)->ip;
|
||||||
|
|
||||||
spin_lock_irqsave(&kretprobe_lock, flags);
|
spin_lock_irqsave(&kretprobe_lock, flags);
|
||||||
head = kretprobe_inst_table_head(current);
|
head = kretprobe_inst_table_head(current);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* It is possible to have multiple instances associated with a given
|
* It is possible to have multiple instances associated with a given
|
||||||
|
@ -363,9 +363,9 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
|
||||||
* kretprobe_trampoline
|
* kretprobe_trampoline
|
||||||
*/
|
*/
|
||||||
hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
|
hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
|
||||||
if (ri->task != current)
|
if (ri->task != current)
|
||||||
/* another task is sharing our hash bucket */
|
/* another task is sharing our hash bucket */
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (ri->rp && ri->rp->handler)
|
if (ri->rp && ri->rp->handler)
|
||||||
ri->rp->handler(ri, regs);
|
ri->rp->handler(ri, regs);
|
||||||
|
@ -394,7 +394,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
|
||||||
* kprobe_handler() that we don't want the post_handler
|
* kprobe_handler() that we don't want the post_handler
|
||||||
* to run (and have re-enabled preemption)
|
* to run (and have re-enabled preemption)
|
||||||
*/
|
*/
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called with kretprobe_lock held */
|
/* Called with kretprobe_lock held */
|
||||||
|
@ -739,12 +739,16 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
|
||||||
|
|
||||||
switch(val) {
|
switch(val) {
|
||||||
case DIE_BREAK:
|
case DIE_BREAK:
|
||||||
if (pre_kprobes_handler(args))
|
/* err is break number from ia64_bad_break() */
|
||||||
ret = NOTIFY_STOP;
|
if (args->err == 0x80200 || args->err == 0x80300)
|
||||||
|
if (pre_kprobes_handler(args))
|
||||||
|
ret = NOTIFY_STOP;
|
||||||
break;
|
break;
|
||||||
case DIE_SS:
|
case DIE_FAULT:
|
||||||
if (post_kprobes_handler(args->regs))
|
/* err is vector number from ia64_fault() */
|
||||||
ret = NOTIFY_STOP;
|
if (args->err == 36)
|
||||||
|
if (post_kprobes_handler(args->regs))
|
||||||
|
ret = NOTIFY_STOP;
|
||||||
break;
|
break;
|
||||||
case DIE_PAGE_FAULT:
|
case DIE_PAGE_FAULT:
|
||||||
/* kprobe_running() needs smp_processor_id() */
|
/* kprobe_running() needs smp_processor_id() */
|
||||||
|
|
|
@ -51,6 +51,9 @@
|
||||||
*
|
*
|
||||||
* 2005-08-12 Keith Owens <kaos@sgi.com>
|
* 2005-08-12 Keith Owens <kaos@sgi.com>
|
||||||
* Convert MCA/INIT handlers to use per event stacks and SAL/OS state.
|
* 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/config.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
@ -58,7 +61,6 @@
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/irq.h>
|
#include <linux/irq.h>
|
||||||
#include <linux/kallsyms.h>
|
|
||||||
#include <linux/smp_lock.h>
|
#include <linux/smp_lock.h>
|
||||||
#include <linux/bootmem.h>
|
#include <linux/bootmem.h>
|
||||||
#include <linux/acpi.h>
|
#include <linux/acpi.h>
|
||||||
|
@ -69,6 +71,7 @@
|
||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
|
|
||||||
#include <asm/delay.h>
|
#include <asm/delay.h>
|
||||||
|
#include <asm/kdebug.h>
|
||||||
#include <asm/machvec.h>
|
#include <asm/machvec.h>
|
||||||
#include <asm/meminit.h>
|
#include <asm/meminit.h>
|
||||||
#include <asm/page.h>
|
#include <asm/page.h>
|
||||||
|
@ -132,6 +135,14 @@ extern void salinfo_log_wakeup(int type, u8 *buffer, u64 size, int irqsafe);
|
||||||
|
|
||||||
static int mca_init;
|
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
|
* IA64_MCA log support
|
||||||
*/
|
*/
|
||||||
|
@ -526,13 +537,16 @@ ia64_mca_wakeup_all(void)
|
||||||
* Outputs : None
|
* Outputs : None
|
||||||
*/
|
*/
|
||||||
static irqreturn_t
|
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;
|
unsigned long flags;
|
||||||
int cpu = smp_processor_id();
|
int cpu = smp_processor_id();
|
||||||
|
|
||||||
/* Mask all interrupts */
|
/* Mask all interrupts */
|
||||||
local_irq_save(flags);
|
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;
|
ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_DONE;
|
||||||
/* Register with the SAL monarch that the slave has
|
/* Register with the SAL monarch that the slave has
|
||||||
|
@ -540,10 +554,18 @@ ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *ptregs)
|
||||||
*/
|
*/
|
||||||
ia64_sal_mc_rendez();
|
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. */
|
/* Wait for the monarch cpu to exit. */
|
||||||
while (monarch_cpu != -1)
|
while (monarch_cpu != -1)
|
||||||
cpu_relax(); /* spin until monarch leaves */
|
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 */
|
/* Enable all interrupts */
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
|
@ -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 */
|
oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */
|
||||||
previous_current = ia64_mca_modify_original_stack(regs, sw, sos, "MCA");
|
previous_current = ia64_mca_modify_original_stack(regs, sw, sos, "MCA");
|
||||||
monarch_cpu = cpu;
|
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);
|
ia64_wait_for_slaves(cpu);
|
||||||
|
|
||||||
/* Wakeup all the processors which are spinning in the rendezvous loop.
|
/* Wakeup all the processors which are spinning in the rendezvous loop.
|
||||||
|
@ -942,6 +967,9 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
|
||||||
* spinning in SAL does not work.
|
* spinning in SAL does not work.
|
||||||
*/
|
*/
|
||||||
ia64_mca_wakeup_all();
|
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 */
|
/* Get the MCA error record and log it */
|
||||||
ia64_mca_log_sal_error_record(SAL_INFO_TYPE_MCA);
|
ia64_mca_log_sal_error_record(SAL_INFO_TYPE_MCA);
|
||||||
|
@ -960,6 +988,9 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
|
||||||
ia64_sal_clear_state_info(SAL_INFO_TYPE_MCA);
|
ia64_sal_clear_state_info(SAL_INFO_TYPE_MCA);
|
||||||
sos->os_status = IA64_MCA_CORRECTED;
|
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);
|
set_curr_task(cpu, previous_current);
|
||||||
monarch_cpu = -1;
|
monarch_cpu = -1;
|
||||||
|
@ -1188,6 +1219,37 @@ ia64_mca_cpe_poll (unsigned long dummy)
|
||||||
|
|
||||||
#endif /* CONFIG_ACPI */
|
#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
|
* C portion of the OS INIT handler
|
||||||
*
|
*
|
||||||
|
@ -1212,8 +1274,7 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
|
||||||
static atomic_t slaves;
|
static atomic_t slaves;
|
||||||
static atomic_t monarchs;
|
static atomic_t monarchs;
|
||||||
task_t *previous_current;
|
task_t *previous_current;
|
||||||
int cpu = smp_processor_id(), c;
|
int cpu = smp_processor_id();
|
||||||
struct task_struct *g, *t;
|
|
||||||
|
|
||||||
oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */
|
oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */
|
||||||
console_loglevel = 15; /* make sure printks make it to console */
|
console_loglevel = 15; /* make sure printks make it to console */
|
||||||
|
@ -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;
|
ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_INIT;
|
||||||
while (monarch_cpu == -1)
|
while (monarch_cpu == -1)
|
||||||
cpu_relax(); /* spin until monarch enters */
|
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)
|
while (monarch_cpu != -1)
|
||||||
cpu_relax(); /* spin until monarch leaves */
|
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);
|
printk("Slave on cpu %d returning to normal service.\n", cpu);
|
||||||
set_curr_task(cpu, previous_current);
|
set_curr_task(cpu, previous_current);
|
||||||
ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE;
|
ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE;
|
||||||
|
@ -1263,6 +1333,9 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
|
||||||
}
|
}
|
||||||
|
|
||||||
monarch_cpu = cpu;
|
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
|
* Wait for a bit. On some machines (e.g., HP's zx2000 and zx6000, INIT can be
|
||||||
|
@ -1273,27 +1346,16 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
|
||||||
printk("Delaying for 5 seconds...\n");
|
printk("Delaying for 5 seconds...\n");
|
||||||
udelay(5*1000000);
|
udelay(5*1000000);
|
||||||
ia64_wait_for_slaves(cpu);
|
ia64_wait_for_slaves(cpu);
|
||||||
printk(KERN_ERR "Processes interrupted by INIT -");
|
/* If nobody intercepts DIE_INIT_MONARCH_PROCESS then we drop through
|
||||||
for_each_online_cpu(c) {
|
* to default_monarch_init_process() above and just print all the
|
||||||
struct ia64_sal_os_state *s;
|
* tasks.
|
||||||
t = __va(__per_cpu_mca[c] + IA64_MCA_CPU_INIT_STACK_OFFSET);
|
*/
|
||||||
s = (struct ia64_sal_os_state *)((char *)t + MCA_SOS_OFFSET);
|
if (notify_die(DIE_INIT_MONARCH_PROCESS, "INIT", regs, 0, 0, 0)
|
||||||
g = s->prev_task;
|
== NOTIFY_STOP)
|
||||||
if (g) {
|
ia64_mca_spin(__FUNCTION__);
|
||||||
if (g->pid)
|
if (notify_die(DIE_INIT_MONARCH_LEAVE, "INIT", regs, 0, 0, 0)
|
||||||
printk(" %d", g->pid);
|
== NOTIFY_STOP)
|
||||||
else
|
ia64_mca_spin(__FUNCTION__);
|
||||||
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);
|
|
||||||
}
|
|
||||||
printk("\nINIT dump complete. Monarch on cpu %d returning to normal service.\n", cpu);
|
printk("\nINIT dump complete. Monarch on cpu %d returning to normal service.\n", cpu);
|
||||||
atomic_dec(&monarchs);
|
atomic_dec(&monarchs);
|
||||||
set_curr_task(cpu, previous_current);
|
set_curr_task(cpu, previous_current);
|
||||||
|
@ -1462,6 +1524,10 @@ ia64_mca_init(void)
|
||||||
s64 rc;
|
s64 rc;
|
||||||
struct ia64_sal_retval isrv;
|
struct ia64_sal_retval isrv;
|
||||||
u64 timeout = IA64_MCA_RENDEZ_TIMEOUT; /* platform specific */
|
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__);
|
IA64_MCA_DEBUG("%s: begin\n", __FUNCTION__);
|
||||||
|
|
||||||
|
@ -1555,6 +1621,10 @@ ia64_mca_init(void)
|
||||||
"(status %ld)\n", rc);
|
"(status %ld)\n", rc);
|
||||||
return;
|
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__);
|
IA64_MCA_DEBUG("%s: registered OS INIT handler with SAL\n", __FUNCTION__);
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,9 @@
|
||||||
* Copyright (C) 1998-2003 Hewlett-Packard Co
|
* Copyright (C) 1998-2003 Hewlett-Packard Co
|
||||||
* David Mosberger-Tang <davidm@hpl.hp.com>
|
* David Mosberger-Tang <davidm@hpl.hp.com>
|
||||||
* 04/11/17 Ashok Raj <ashok.raj@intel.com> Added CPU Hotplug Support
|
* 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> */
|
#define __KERNEL_SYSCALLS__ /* see <asm/unistd.h> */
|
||||||
#include <linux/config.h>
|
#include <linux/config.h>
|
||||||
|
@ -34,6 +37,7 @@
|
||||||
#include <asm/elf.h>
|
#include <asm/elf.h>
|
||||||
#include <asm/ia32.h>
|
#include <asm/ia32.h>
|
||||||
#include <asm/irq.h>
|
#include <asm/irq.h>
|
||||||
|
#include <asm/kdebug.h>
|
||||||
#include <asm/pgalloc.h>
|
#include <asm/pgalloc.h>
|
||||||
#include <asm/processor.h>
|
#include <asm/processor.h>
|
||||||
#include <asm/sal.h>
|
#include <asm/sal.h>
|
||||||
|
@ -808,12 +812,14 @@ cpu_halt (void)
|
||||||
void
|
void
|
||||||
machine_restart (char *restart_cmd)
|
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);
|
(*efi.reset_system)(EFI_RESET_WARM, 0, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
machine_halt (void)
|
machine_halt (void)
|
||||||
{
|
{
|
||||||
|
(void) notify_die(DIE_MACHINE_HALT, "", NULL, 0, 0, 0);
|
||||||
cpu_halt();
|
cpu_halt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,17 +30,20 @@ fpswa_interface_t *fpswa_interface;
|
||||||
EXPORT_SYMBOL(fpswa_interface);
|
EXPORT_SYMBOL(fpswa_interface);
|
||||||
|
|
||||||
struct notifier_block *ia64die_chain;
|
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;
|
return notifier_chain_register(&ia64die_chain, nb);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
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
|
void __init
|
||||||
trap_init (void)
|
trap_init (void)
|
||||||
|
@ -105,6 +108,7 @@ die (const char *str, struct pt_regs *regs, long err)
|
||||||
if (++die.lock_owner_depth < 3) {
|
if (++die.lock_owner_depth < 3) {
|
||||||
printk("%s[%d]: %s %ld [%d]\n",
|
printk("%s[%d]: %s %ld [%d]\n",
|
||||||
current->comm, current->pid, str, err, ++die_counter);
|
current->comm, current->pid, str, err, ++die_counter);
|
||||||
|
(void) notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV);
|
||||||
show_regs(regs);
|
show_regs(regs);
|
||||||
} else
|
} else
|
||||||
printk(KERN_ERR "Recursive die() failure, output suppressed\n");
|
printk(KERN_ERR "Recursive die() failure, output suppressed\n");
|
||||||
|
@ -155,9 +159,8 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
|
||||||
switch (break_num) {
|
switch (break_num) {
|
||||||
case 0: /* unknown error (used by GCC for __builtin_abort()) */
|
case 0: /* unknown error (used by GCC for __builtin_abort()) */
|
||||||
if (notify_die(DIE_BREAK, "break 0", regs, break_num, TRAP_BRKPT, SIGTRAP)
|
if (notify_die(DIE_BREAK, "break 0", regs, break_num, TRAP_BRKPT, SIGTRAP)
|
||||||
== NOTIFY_STOP) {
|
== NOTIFY_STOP)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
die_if_kernel("bugcheck!", regs, break_num);
|
die_if_kernel("bugcheck!", regs, break_num);
|
||||||
sig = SIGILL; code = ILL_ILLOPC;
|
sig = SIGILL; code = ILL_ILLOPC;
|
||||||
break;
|
break;
|
||||||
|
@ -210,15 +213,6 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
|
||||||
sig = SIGILL; code = __ILL_BNDMOD;
|
sig = SIGILL; code = __ILL_BNDMOD;
|
||||||
break;
|
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:
|
default:
|
||||||
if (break_num < 0x40000 || break_num > 0x100000)
|
if (break_num < 0x40000 || break_num > 0x100000)
|
||||||
die_if_kernel("Bad break", regs, break_num);
|
die_if_kernel("Bad break", regs, break_num);
|
||||||
|
@ -226,6 +220,9 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
|
||||||
if (break_num < 0x80000) {
|
if (break_num < 0x80000) {
|
||||||
sig = SIGILL; code = __ILL_BREAK;
|
sig = SIGILL; code = __ILL_BREAK;
|
||||||
} else {
|
} else {
|
||||||
|
if (notify_die(DIE_BREAK, "bad break", regs, break_num, TRAP_BRKPT, SIGTRAP)
|
||||||
|
== NOTIFY_STOP)
|
||||||
|
return;
|
||||||
sig = SIGTRAP; code = TRAP_BRKPT;
|
sig = SIGTRAP; code = TRAP_BRKPT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -578,12 +575,11 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case 35: siginfo.si_code = TRAP_BRANCH; ifa = 0; break;
|
case 35: siginfo.si_code = TRAP_BRANCH; ifa = 0; break;
|
||||||
case 36:
|
case 36: siginfo.si_code = TRAP_TRACE; ifa = 0; break;
|
||||||
if (notify_die(DIE_SS, "ss", ®s, vector,
|
|
||||||
vector, SIGTRAP) == NOTIFY_STOP)
|
|
||||||
return;
|
|
||||||
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_signo = SIGTRAP;
|
||||||
siginfo.si_errno = 0;
|
siginfo.si_errno = 0;
|
||||||
siginfo.si_addr = (void __user *) ifa;
|
siginfo.si_addr = (void __user *) ifa;
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
* 2005-Apr Rusty Lynch <rusty.lynch@intel.com> and Anil S Keshavamurthy
|
* 2005-Apr Rusty Lynch <rusty.lynch@intel.com> and Anil S Keshavamurthy
|
||||||
* <anil.s.keshavamurthy@intel.com> adopted from
|
* <anil.s.keshavamurthy@intel.com> adopted from
|
||||||
* include/asm-x86_64/kdebug.h
|
* include/asm-x86_64/kdebug.h
|
||||||
|
*
|
||||||
|
* 2005-Oct Keith Owens <kaos@sgi.com>. Expand notify_die to cover more
|
||||||
|
* events.
|
||||||
*/
|
*/
|
||||||
#include <linux/notifier.h>
|
#include <linux/notifier.h>
|
||||||
|
|
||||||
|
@ -35,13 +38,36 @@ struct die_args {
|
||||||
int signr;
|
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;
|
extern struct notifier_block *ia64die_chain;
|
||||||
|
|
||||||
enum die_val {
|
enum die_val {
|
||||||
DIE_BREAK = 1,
|
DIE_BREAK = 1,
|
||||||
DIE_SS,
|
DIE_FAULT,
|
||||||
|
DIE_OOPS,
|
||||||
DIE_PAGE_FAULT,
|
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,
|
static inline int notify_die(enum die_val val, char *str, struct pt_regs *regs,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue