Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=3a2e117e220f000f95187ea1e1bbe83b0ed5fdfb
Commit:     3a2e117e220f000f95187ea1e1bbe83b0ed5fdfb
Parent:     3dde7a3c74bcc25c6fc31b836fec8c91fb0b2b8f
Author:     Paul Mundt <[EMAIL PROTECTED]>
AuthorDate: Tue May 1 16:33:10 2007 +0900
Committer:  Paul Mundt <[EMAIL PROTECTED]>
CommitDate: Mon May 7 02:11:57 2007 +0000

    sh: Add die chain notifiers.
    
    Add the atomic die chains in, kprobes needs these.
    
    Signed-off-by: Paul Mundt <[EMAIL PROTECTED]>
---
 arch/sh/kernel/process.c |   15 ++++++++++++---
 arch/sh/kernel/traps.c   |   19 +++++++++++++++++--
 arch/sh/mm/fault.c       |   39 +++++++++++++++++++++++++++++++++++++--
 include/asm-sh/kdebug.h  |   35 +++++++++++++++++++++++++++++++++++
 include/asm-sh/system.h  |    3 +++
 5 files changed, 104 insertions(+), 7 deletions(-)

diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
index 286c803..329b3f3 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 7710783..7b40f0f 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)
 {
diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c
index fa5d7f0..0ecc117 100644
--- a/arch/sh/mm/fault.c
+++ b/arch/sh/mm/fault.c
@@ -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
@@ -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(&notify_page_fault_chain, nb);
+}
+
+int unregister_page_fault_notifier(struct notifier_block *nb)
+{
+       return atomic_notifier_chain_unregister(&notify_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(&notify_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,
@@ -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
diff --git a/include/asm-sh/kdebug.h b/include/asm-sh/kdebug.h
new file mode 100644
index 0000000..ef009ba
--- /dev/null
+++ b/include/asm-sh/kdebug.h
@@ -0,0 +1,35 @@
+#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 */
diff --git a/include/asm-sh/system.h b/include/asm-sh/system.h
index 4a6a19f..127af30 100644
--- a/include/asm-sh/system.h
+++ b/include/asm-sh/system.h
@@ -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
@@ -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)
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to