diff options
Diffstat (limited to 'arch/sh/mm/fault.c')
| -rw-r--r-- | arch/sh/mm/fault.c | 39 | 
1 files changed, 37 insertions, 2 deletions
diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c index fa5d7f0b9f1..9207da67ff8 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 <linux/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, @@ -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  | 
