aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/mm
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2007-04-30 06:56:46 -0400
committerPaul Mackerras <paulus@samba.org>2007-05-02 06:57:39 -0400
commit9f90b997de4efd5404a8c52f89c400f0f4e2d216 (patch)
tree7dd6adc27b196e672fedd464a42700e336cd210a /arch/powerpc/mm
parenteb609e52d188775da738a1ffd1e982e6212c77d7 (diff)
[POWERPC] Minor fault path optimization
Call the kprobes pagefault handler directly instead of going through the complex notifier chain. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/mm')
-rw-r--r--arch/powerpc/mm/fault.c42
1 files changed, 15 insertions, 27 deletions
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index 03aeb3a46077..a0f88026e464 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -39,37 +39,26 @@
39#include <asm/kdebug.h> 39#include <asm/kdebug.h>
40#include <asm/siginfo.h> 40#include <asm/siginfo.h>
41 41
42#ifdef CONFIG_KPROBES
43ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain);
44 42
45/* Hook to register for page fault notifications */ 43#ifdef CONFIG_KPROBES
46int register_page_fault_notifier(struct notifier_block *nb) 44static inline int notify_page_fault(struct pt_regs *regs)
47{
48 return atomic_notifier_chain_register(&notify_page_fault_chain, nb);
49}
50
51int unregister_page_fault_notifier(struct notifier_block *nb)
52{ 45{
53 return atomic_notifier_chain_unregister(&notify_page_fault_chain, nb); 46 int ret = 0;
54} 47
48 /* kprobe_running() needs smp_processor_id() */
49 if (!user_mode(regs)) {
50 preempt_disable();
51 if (kprobe_running() && kprobe_fault_handler(regs, 11))
52 ret = 1;
53 preempt_enable();
54 }
55 55
56static inline int notify_page_fault(enum die_val val, const char *str, 56 return ret;
57 struct pt_regs *regs, long err, int trap, int sig)
58{
59 struct die_args args = {
60 .regs = regs,
61 .str = str,
62 .err = err,
63 .trapnr = trap,
64 .signr = sig
65 };
66 return atomic_notifier_call_chain(&notify_page_fault_chain, val, &args);
67} 57}
68#else 58#else
69static inline int notify_page_fault(enum die_val val, const char *str, 59static inline int notify_page_fault(struct pt_regs *regs)
70 struct pt_regs *regs, long err, int trap, int sig)
71{ 60{
72 return NOTIFY_DONE; 61 return 0;
73} 62}
74#endif 63#endif
75 64
@@ -175,8 +164,7 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
175 is_write = error_code & ESR_DST; 164 is_write = error_code & ESR_DST;
176#endif /* CONFIG_4xx || CONFIG_BOOKE */ 165#endif /* CONFIG_4xx || CONFIG_BOOKE */
177 166
178 if (notify_page_fault(DIE_PAGE_FAULT, "page_fault", regs, error_code, 167 if (notify_page_fault(regs))
179 11, SIGSEGV) == NOTIFY_STOP)
180 return 0; 168 return 0;
181 169
182 if (trap == 0x300) { 170 if (trap == 0x300) {