Loading arch/sh/kernel/process.c +12 −3 Original line number Diff line number Diff line Loading @@ -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> Loading @@ -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> Loading Loading @@ -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); } Loading @@ -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); Loading arch/sh/kernel/traps.c +17 −2 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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> Loading Loading @@ -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) { Loading arch/sh/mm/fault.c +37 −2 Original line number Diff line number Diff line Loading @@ -2,7 +2,7 @@ * Page fault handler for SH with an MMU. * * Copyright (C) 1999 Niibe Yutaka * Copyright (C) 2003 Paul Mundt * Copyright (C) 2003 - 2007 Paul Mundt * * Based on linux/arch/i386/mm/fault.c: * Copyright (C) 1995 Linus Torvalds Loading @@ -15,12 +15,42 @@ #include <linux/mm.h> #include <linux/hardirq.h> #include <linux/kprobes.h> #include <asm/kdebug.h> #include <asm/system.h> #include <asm/mmu_context.h> #include <asm/tlbflush.h> #include <asm/kgdb.h> extern void die(const char *,struct pt_regs *,long); #ifdef CONFIG_KPROBES ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); /* Hook to register for page fault notifications */ int register_page_fault_notifier(struct notifier_block *nb) { return atomic_notifier_chain_register(¬ify_page_fault_chain, nb); } int unregister_page_fault_notifier(struct notifier_block *nb) { return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb); } static inline int notify_page_fault(enum die_val val, struct pt_regs *regs, int trap, int sig) { struct die_args args = { .regs = regs, .trapnr = trap, }; return atomic_notifier_call_chain(¬ify_page_fault_chain, val, &args); } #else static inline int notify_page_fault(enum die_val val, struct pt_regs *regs, int trap, int sig) { return NOTIFY_DONE; } #endif /* * This routine handles page faults. It determines the address, Loading @@ -39,6 +69,11 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, siginfo_t info; trace_hardirqs_on(); if (notify_page_fault(DIE_PAGE_FAULT, regs, writeaccess, SIGSEGV) == NOTIFY_STOP) return; local_irq_enable(); #ifdef CONFIG_SH_KGDB Loading include/asm-sh/kdebug.h 0 → 100644 +35 −0 Original line number Diff line number Diff line #ifndef __ASM_SH_KDEBUG_H #define __ASM_SH_KDEBUG_H #include <linux/notifier.h> struct pt_regs; struct die_args { struct pt_regs *regs; int trapnr; }; int register_die_notifier(struct notifier_block *nb); int unregister_die_notifier(struct notifier_block *nb); int register_page_fault_notifier(struct notifier_block *nb); int unregister_page_fault_notifier(struct notifier_block *nb); extern struct atomic_notifier_head shdie_chain; /* Grossly misnamed. */ enum die_val { DIE_TRAP, DIE_PAGE_FAULT, }; static inline int notify_die(enum die_val val, struct pt_regs *regs, int trap, int sig) { struct die_args args = { .regs = regs, .trapnr = trap, }; return atomic_notifier_call_chain(&shdie_chain, val, &args); } #endif /* __ASM_SH_KDEBUG_H */ include/asm-sh/system.h +3 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ #include <linux/irqflags.h> #include <linux/compiler.h> #include <asm/types.h> #include <asm/ptrace.h> /* * switch_to() should switch tasks to task nr n, first Loading Loading @@ -255,6 +256,8 @@ static inline unsigned long __cmpxchg(volatile void * ptr, unsigned long old, (unsigned long)_n_, sizeof(*(ptr))); \ }) extern void die(const char *str, struct pt_regs *regs, long err) __attribute__ ((noreturn)); extern void *set_exception_table_vec(unsigned int vec, void *handler); static inline void *set_exception_table_evt(unsigned int evt, void *handler) Loading Loading
arch/sh/kernel/process.c +12 −3 Original line number Diff line number Diff line Loading @@ -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> Loading @@ -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> Loading Loading @@ -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); } Loading @@ -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); Loading
arch/sh/kernel/traps.c +17 −2 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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> Loading Loading @@ -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) { Loading
arch/sh/mm/fault.c +37 −2 Original line number Diff line number Diff line Loading @@ -2,7 +2,7 @@ * Page fault handler for SH with an MMU. * * Copyright (C) 1999 Niibe Yutaka * Copyright (C) 2003 Paul Mundt * Copyright (C) 2003 - 2007 Paul Mundt * * Based on linux/arch/i386/mm/fault.c: * Copyright (C) 1995 Linus Torvalds Loading @@ -15,12 +15,42 @@ #include <linux/mm.h> #include <linux/hardirq.h> #include <linux/kprobes.h> #include <asm/kdebug.h> #include <asm/system.h> #include <asm/mmu_context.h> #include <asm/tlbflush.h> #include <asm/kgdb.h> extern void die(const char *,struct pt_regs *,long); #ifdef CONFIG_KPROBES ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); /* Hook to register for page fault notifications */ int register_page_fault_notifier(struct notifier_block *nb) { return atomic_notifier_chain_register(¬ify_page_fault_chain, nb); } int unregister_page_fault_notifier(struct notifier_block *nb) { return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb); } static inline int notify_page_fault(enum die_val val, struct pt_regs *regs, int trap, int sig) { struct die_args args = { .regs = regs, .trapnr = trap, }; return atomic_notifier_call_chain(¬ify_page_fault_chain, val, &args); } #else static inline int notify_page_fault(enum die_val val, struct pt_regs *regs, int trap, int sig) { return NOTIFY_DONE; } #endif /* * This routine handles page faults. It determines the address, Loading @@ -39,6 +69,11 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, siginfo_t info; trace_hardirqs_on(); if (notify_page_fault(DIE_PAGE_FAULT, regs, writeaccess, SIGSEGV) == NOTIFY_STOP) return; local_irq_enable(); #ifdef CONFIG_SH_KGDB Loading
include/asm-sh/kdebug.h 0 → 100644 +35 −0 Original line number Diff line number Diff line #ifndef __ASM_SH_KDEBUG_H #define __ASM_SH_KDEBUG_H #include <linux/notifier.h> struct pt_regs; struct die_args { struct pt_regs *regs; int trapnr; }; int register_die_notifier(struct notifier_block *nb); int unregister_die_notifier(struct notifier_block *nb); int register_page_fault_notifier(struct notifier_block *nb); int unregister_page_fault_notifier(struct notifier_block *nb); extern struct atomic_notifier_head shdie_chain; /* Grossly misnamed. */ enum die_val { DIE_TRAP, DIE_PAGE_FAULT, }; static inline int notify_die(enum die_val val, struct pt_regs *regs, int trap, int sig) { struct die_args args = { .regs = regs, .trapnr = trap, }; return atomic_notifier_call_chain(&shdie_chain, val, &args); } #endif /* __ASM_SH_KDEBUG_H */
include/asm-sh/system.h +3 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ #include <linux/irqflags.h> #include <linux/compiler.h> #include <asm/types.h> #include <asm/ptrace.h> /* * switch_to() should switch tasks to task nr n, first Loading Loading @@ -255,6 +256,8 @@ static inline unsigned long __cmpxchg(volatile void * ptr, unsigned long old, (unsigned long)_n_, sizeof(*(ptr))); \ }) extern void die(const char *str, struct pt_regs *regs, long err) __attribute__ ((noreturn)); extern void *set_exception_table_vec(unsigned int vec, void *handler); static inline void *set_exception_table_evt(unsigned int evt, void *handler) Loading