summaryrefslogtreecommitdiff
path: root/arch/sparc64/mm
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2007-05-08 18:25:14 -0700
committerDavid S. Miller <davem@sunset.davemloft.net>2007-05-08 18:25:14 -0700
commit127cda1e8cc282de1ca7a9dcc3866841977b9fcc (patch)
tree800169fa92dc96160044d914ca1ca9fea60339ea /arch/sparc64/mm
parent6c1142602c9c8faedbc1321892a169652a173fc7 (diff)
downloadlinux-3.10-127cda1e8cc282de1ca7a9dcc3866841977b9fcc.tar.gz
linux-3.10-127cda1e8cc282de1ca7a9dcc3866841977b9fcc.tar.bz2
linux-3.10-127cda1e8cc282de1ca7a9dcc3866841977b9fcc.zip
[SPARC64]: Optimize fault kprobe handling just like powerpc.
And eliminate DIE_GPF while we're at it. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/mm')
-rw-r--r--arch/sparc64/mm/fault.c45
1 files changed, 14 insertions, 31 deletions
diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c
index c32e309f778..b582024d219 100644
--- a/arch/sparc64/mm/fault.c
+++ b/arch/sparc64/mm/fault.c
@@ -32,36 +32,23 @@
#include <asm/mmu_context.h>
#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)
+static inline int notify_page_fault(struct pt_regs *regs)
{
- 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, const char *str,
- struct pt_regs *regs, long err, int trap, int sig)
-{
- struct die_args args = {
- .regs = regs,
- .str = str,
- .err = err,
- .trapnr = trap,
- .signr = sig
- };
- return atomic_notifier_call_chain(&notify_page_fault_chain, val, &args);
+ int ret = 0;
+
+ /* kprobe_running() needs smp_processor_id() */
+ if (!user_mode(regs)) {
+ preempt_disable();
+ if (kprobe_running() && kprobe_fault_handler(regs, 0))
+ ret = 1;
+ preempt_enable();
+ }
+ return ret;
}
#else
-static inline int notify_page_fault(enum die_val val, const char *str,
- struct pt_regs *regs, long err, int trap, int sig)
+static inline int notify_page_fault(struct pt_regs *regs)
{
- return NOTIFY_DONE;
+ return 0;
}
#endif
@@ -120,9 +107,6 @@ static void __kprobes unhandled_fault(unsigned long address,
printk(KERN_ALERT "tsk->{mm,active_mm}->pgd = %016lx\n",
(tsk->mm ? (unsigned long) tsk->mm->pgd :
(unsigned long) tsk->active_mm->pgd));
- if (notify_die(DIE_GPF, "general protection fault", regs,
- 0, 0, SIGSEGV) == NOTIFY_STOP)
- return;
die_if_kernel("Oops", regs);
}
@@ -299,8 +283,7 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
fault_code = get_thread_fault_code();
- if (notify_page_fault(DIE_PAGE_FAULT, "page_fault", regs,
- fault_code, 0, SIGSEGV) == NOTIFY_STOP)
+ if (notify_page_fault(regs))
return;
si_code = SEGV_MAPERR;