diff options
author | Christoph Hellwig <hch@infradead.org> | 2007-04-30 06:56:46 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2007-05-02 06:57:39 -0400 |
commit | 9f90b997de4efd5404a8c52f89c400f0f4e2d216 (patch) | |
tree | 7dd6adc27b196e672fedd464a42700e336cd210a /arch/powerpc | |
parent | eb609e52d188775da738a1ffd1e982e6212c77d7 (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')
-rw-r--r-- | arch/powerpc/kernel/kprobes.c | 10 | ||||
-rw-r--r-- | arch/powerpc/mm/fault.c | 42 |
2 files changed, 16 insertions, 36 deletions
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c index ef647e7a9dc3..c27f41870c8f 100644 --- a/arch/powerpc/kernel/kprobes.c +++ b/arch/powerpc/kernel/kprobes.c | |||
@@ -410,7 +410,7 @@ out: | |||
410 | return 1; | 410 | return 1; |
411 | } | 411 | } |
412 | 412 | ||
413 | static int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) | 413 | int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) |
414 | { | 414 | { |
415 | struct kprobe *cur = kprobe_running(); | 415 | struct kprobe *cur = kprobe_running(); |
416 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | 416 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
@@ -495,14 +495,6 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, | |||
495 | if (post_kprobe_handler(args->regs)) | 495 | if (post_kprobe_handler(args->regs)) |
496 | ret = NOTIFY_STOP; | 496 | ret = NOTIFY_STOP; |
497 | break; | 497 | break; |
498 | case DIE_PAGE_FAULT: | ||
499 | /* kprobe_running() needs smp_processor_id() */ | ||
500 | preempt_disable(); | ||
501 | if (kprobe_running() && | ||
502 | kprobe_fault_handler(args->regs, args->trapnr)) | ||
503 | ret = NOTIFY_STOP; | ||
504 | preempt_enable(); | ||
505 | break; | ||
506 | default: | 498 | default: |
507 | break; | 499 | break; |
508 | } | 500 | } |
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 | ||
43 | ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); | ||
44 | 42 | ||
45 | /* Hook to register for page fault notifications */ | 43 | #ifdef CONFIG_KPROBES |
46 | int register_page_fault_notifier(struct notifier_block *nb) | 44 | static inline int notify_page_fault(struct pt_regs *regs) |
47 | { | ||
48 | return atomic_notifier_chain_register(¬ify_page_fault_chain, nb); | ||
49 | } | ||
50 | |||
51 | int unregister_page_fault_notifier(struct notifier_block *nb) | ||
52 | { | 45 | { |
53 | return atomic_notifier_chain_unregister(¬ify_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 | ||
56 | static 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(¬ify_page_fault_chain, val, &args); | ||
67 | } | 57 | } |
68 | #else | 58 | #else |
69 | static inline int notify_page_fault(enum die_val val, const char *str, | 59 | static 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) { |