aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2007-05-08 21:25:14 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-05-08 21:25:14 -0400
commit127cda1e8cc282de1ca7a9dcc3866841977b9fcc (patch)
tree800169fa92dc96160044d914ca1ca9fea60339ea /arch/sparc64
parent6c1142602c9c8faedbc1321892a169652a173fc7 (diff)
[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')
-rw-r--r--arch/sparc64/kernel/kprobes.c11
-rw-r--r--arch/sparc64/mm/fault.c45
2 files changed, 15 insertions, 41 deletions
diff --git a/arch/sparc64/kernel/kprobes.c b/arch/sparc64/kernel/kprobes.c
index a44fe47a3c2b..c93a15b785fa 100644
--- a/arch/sparc64/kernel/kprobes.c
+++ b/arch/sparc64/kernel/kprobes.c
@@ -313,7 +313,7 @@ out:
313 return 1; 313 return 1;
314} 314}
315 315
316static int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) 316int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
317{ 317{
318 struct kprobe *cur = kprobe_running(); 318 struct kprobe *cur = kprobe_running();
319 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); 319 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
@@ -403,15 +403,6 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
403 if (post_kprobe_handler(args->regs)) 403 if (post_kprobe_handler(args->regs))
404 ret = NOTIFY_STOP; 404 ret = NOTIFY_STOP;
405 break; 405 break;
406 case DIE_GPF:
407 case DIE_PAGE_FAULT:
408 /* kprobe_running() needs smp_processor_id() */
409 preempt_disable();
410 if (kprobe_running() &&
411 kprobe_fault_handler(args->regs, args->trapnr))
412 ret = NOTIFY_STOP;
413 preempt_enable();
414 break;
415 default: 406 default:
416 break; 407 break;
417 } 408 }
diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c
index c32e309f7788..b582024d2199 100644
--- a/arch/sparc64/mm/fault.c
+++ b/arch/sparc64/mm/fault.c
@@ -32,36 +32,23 @@
32#include <asm/mmu_context.h> 32#include <asm/mmu_context.h>
33 33
34#ifdef CONFIG_KPROBES 34#ifdef CONFIG_KPROBES
35ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); 35static inline int notify_page_fault(struct pt_regs *regs)
36
37/* Hook to register for page fault notifications */
38int register_page_fault_notifier(struct notifier_block *nb)
39{ 36{
40 return atomic_notifier_chain_register(&notify_page_fault_chain, nb); 37 int ret = 0;
41} 38
42 39 /* kprobe_running() needs smp_processor_id() */
43int unregister_page_fault_notifier(struct notifier_block *nb) 40 if (!user_mode(regs)) {
44{ 41 preempt_disable();
45 return atomic_notifier_chain_unregister(&notify_page_fault_chain, nb); 42 if (kprobe_running() && kprobe_fault_handler(regs, 0))
46} 43 ret = 1;
47 44 preempt_enable();
48static inline int notify_page_fault(enum die_val val, const char *str, 45 }
49 struct pt_regs *regs, long err, int trap, int sig) 46 return ret;
50{
51 struct die_args args = {
52 .regs = regs,
53 .str = str,
54 .err = err,
55 .trapnr = trap,
56 .signr = sig
57 };
58 return atomic_notifier_call_chain(&notify_page_fault_chain, val, &args);
59} 47}
60#else 48#else
61static inline int notify_page_fault(enum die_val val, const char *str, 49static inline int notify_page_fault(struct pt_regs *regs)
62 struct pt_regs *regs, long err, int trap, int sig)
63{ 50{
64 return NOTIFY_DONE; 51 return 0;
65} 52}
66#endif 53#endif
67 54
@@ -120,9 +107,6 @@ static void __kprobes unhandled_fault(unsigned long address,
120 printk(KERN_ALERT "tsk->{mm,active_mm}->pgd = %016lx\n", 107 printk(KERN_ALERT "tsk->{mm,active_mm}->pgd = %016lx\n",
121 (tsk->mm ? (unsigned long) tsk->mm->pgd : 108 (tsk->mm ? (unsigned long) tsk->mm->pgd :
122 (unsigned long) tsk->active_mm->pgd)); 109 (unsigned long) tsk->active_mm->pgd));
123 if (notify_die(DIE_GPF, "general protection fault", regs,
124 0, 0, SIGSEGV) == NOTIFY_STOP)
125 return;
126 die_if_kernel("Oops", regs); 110 die_if_kernel("Oops", regs);
127} 111}
128 112
@@ -299,8 +283,7 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
299 283
300 fault_code = get_thread_fault_code(); 284 fault_code = get_thread_fault_code();
301 285
302 if (notify_page_fault(DIE_PAGE_FAULT, "page_fault", regs, 286 if (notify_page_fault(regs))
303 fault_code, 0, SIGSEGV) == NOTIFY_STOP)
304 return; 287 return;
305 288
306 si_code = SEGV_MAPERR; 289 si_code = SEGV_MAPERR;