diff options
author | Paul Mundt <lethal@linux-sh.org> | 2007-05-01 16:33:10 +0900 |
---|---|---|
committer | Paul Mundt <lethal@hera.kernel.org> | 2007-05-07 02:11:57 +0000 |
commit | 3a2e117e220f000f95187ea1e1bbe83b0ed5fdfb (patch) | |
tree | 57fab5755138283793647b5d0d2a2c872f00a430 /arch/sh/kernel | |
parent | 3dde7a3c74bcc25c6fc31b836fec8c91fb0b2b8f (diff) |
sh: Add die chain notifiers.
Add the atomic die chains in, kprobes needs these.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/kernel')
-rw-r--r-- | arch/sh/kernel/process.c | 15 | ||||
-rw-r--r-- | arch/sh/kernel/traps.c | 19 |
2 files changed, 29 insertions, 5 deletions
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c index 286c80388bf..329b3f3051d 100644 --- a/arch/sh/kernel/process.c +++ b/arch/sh/kernel/process.c @@ -7,7 +7,7 @@ * * SuperH version: Copyright (C) 1999, 2000 Niibe Yutaka & Kaz Kojima * Copyright (C) 2006 Lineo Solutions Inc. support SH4A UBC - * Copyright (C) 2002 - 2006 Paul Mundt + * Copyright (C) 2002 - 2007 Paul Mundt */ #include <linux/module.h> #include <linux/mm.h> @@ -15,6 +15,7 @@ #include <linux/pm.h> #include <linux/kallsyms.h> #include <linux/kexec.h> +#include <asm/kdebug.h> #include <asm/uaccess.h> #include <asm/mmu_context.h> #include <asm/ubc.h> @@ -299,8 +300,8 @@ static void ubc_set_tracing(int asid, unsigned long pc) ctrl_outl(0, UBC_BAMRA); if (current_cpu_data.type == CPU_SH7729 || - current_cpu_data.type == CPU_SH7710 || - current_cpu_data.type == CPU_SH7712 ) { + current_cpu_data.type == CPU_SH7710 || + current_cpu_data.type == CPU_SH7712) { ctrl_outw(BBR_INST | BBR_READ | BBR_CPU, UBC_BBRA); ctrl_outl(BRCR_PCBA | BRCR_PCTE, UBC_BRCR); } else { @@ -496,6 +497,10 @@ asmlinkage void debug_trap_handler(unsigned long r4, unsigned long r5, /* Rewind */ regs->pc -= 2; + if (notify_die(DIE_TRAP, regs, regs->tra & 0xff, + SIGTRAP) == NOTIFY_STOP) + return; + force_sig(SIGTRAP, current); } @@ -511,6 +516,10 @@ asmlinkage void bug_trap_handler(unsigned long r4, unsigned long r5, /* Rewind */ regs->pc -= 2; + if (notify_die(DIE_TRAP, regs, TRAPA_BUG_OPCODE & 0xff, + SIGTRAP) == NOTIFY_STOP) + return; + #ifdef CONFIG_BUG if (__kernel_text_address(instruction_pointer(regs))) { u16 insn = *(u16 *)instruction_pointer(regs); diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c index 77107838271..7b40f0ff3df 100644 --- a/arch/sh/kernel/traps.c +++ b/arch/sh/kernel/traps.c @@ -5,7 +5,7 @@ * SuperH version: Copyright (C) 1999 Niibe Yutaka * Copyright (C) 2000 Philipp Rumpf * Copyright (C) 2000 David Howells - * Copyright (C) 2002 - 2006 Paul Mundt + * Copyright (C) 2002 - 2007 Paul Mundt * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -23,6 +23,7 @@ #include <linux/limits.h> #include <asm/system.h> #include <asm/uaccess.h> +#include <asm/kdebug.h> #ifdef CONFIG_SH_KGDB #include <asm/kgdb.h> @@ -75,7 +76,21 @@ static void dump_mem(const char *str, unsigned long bottom, unsigned long top) } } -DEFINE_SPINLOCK(die_lock); +ATOMIC_NOTIFIER_HEAD(shdie_chain); + +int register_die_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(&shdie_chain, nb); +} +EXPORT_SYMBOL(register_die_notifier); + +int unregister_die_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(&shdie_chain, nb); +} +EXPORT_SYMBOL(unregister_die_notifier); + +static DEFINE_SPINLOCK(die_lock); void die(const char * str, struct pt_regs * regs, long err) { |