diff options
author | Christoph Hellwig <hch@lst.de> | 2007-05-16 08:52:19 -0400 |
---|---|---|
committer | Tony Luck <tony.luck@intel.com> | 2007-05-16 12:00:51 -0400 |
commit | 576fe0bd7e52dce7afb6b9b2450744555b2eb53a (patch) | |
tree | acf2a5f8d7f7906cfa2da9bf53a74d8e3fcd42bb | |
parent | 17028c5c91580036eb41da2fad292965fa3b9a7d (diff) |
[IA64] optimize pagefaults a little
Get rid of the notifier list and call the kprobes code directly
if compiled in. This mirrors the changes that recently went
into powerpc, s390 and sparc64.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Tony Luck <tony.luck@intel.com>
-rw-r--r-- | arch/ia64/kernel/kprobes.c | 9 | ||||
-rw-r--r-- | arch/ia64/mm/fault.c | 41 | ||||
-rw-r--r-- | include/asm-ia64/kdebug.h | 16 | ||||
-rw-r--r-- | include/asm-ia64/kprobes.h | 1 |
4 files changed, 29 insertions, 38 deletions
diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c index be81fe42d80b..5bc46f151344 100644 --- a/arch/ia64/kernel/kprobes.c +++ b/arch/ia64/kernel/kprobes.c | |||
@@ -820,7 +820,7 @@ out: | |||
820 | return 1; | 820 | return 1; |
821 | } | 821 | } |
822 | 822 | ||
823 | static int __kprobes kprobes_fault_handler(struct pt_regs *regs, int trapnr) | 823 | int __kprobes kprobes_fault_handler(struct pt_regs *regs, int trapnr) |
824 | { | 824 | { |
825 | struct kprobe *cur = kprobe_running(); | 825 | struct kprobe *cur = kprobe_running(); |
826 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | 826 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
@@ -904,13 +904,6 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, | |||
904 | if (post_kprobes_handler(args->regs)) | 904 | if (post_kprobes_handler(args->regs)) |
905 | ret = NOTIFY_STOP; | 905 | ret = NOTIFY_STOP; |
906 | break; | 906 | break; |
907 | case DIE_PAGE_FAULT: | ||
908 | /* kprobe_running() needs smp_processor_id() */ | ||
909 | preempt_disable(); | ||
910 | if (kprobe_running() && | ||
911 | kprobes_fault_handler(args->regs, args->trapnr)) | ||
912 | ret = NOTIFY_STOP; | ||
913 | preempt_enable(); | ||
914 | default: | 907 | default: |
915 | break; | 908 | break; |
916 | } | 909 | } |
diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c index 21658e02116c..b87f785c2416 100644 --- a/arch/ia64/mm/fault.c +++ b/arch/ia64/mm/fault.c | |||
@@ -19,36 +19,24 @@ | |||
19 | extern void die (char *, struct pt_regs *, long); | 19 | extern void die (char *, struct pt_regs *, long); |
20 | 20 | ||
21 | #ifdef CONFIG_KPROBES | 21 | #ifdef CONFIG_KPROBES |
22 | ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); | 22 | static inline int notify_page_fault(struct pt_regs *regs, int trap) |
23 | |||
24 | /* Hook to register for page fault notifications */ | ||
25 | int register_page_fault_notifier(struct notifier_block *nb) | ||
26 | { | ||
27 | return atomic_notifier_chain_register(¬ify_page_fault_chain, nb); | ||
28 | } | ||
29 | |||
30 | int unregister_page_fault_notifier(struct notifier_block *nb) | ||
31 | { | 23 | { |
32 | return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb); | 24 | int ret = 0; |
33 | } | 25 | |
26 | if (!user_mode(regs)) { | ||
27 | /* kprobe_running() needs smp_processor_id() */ | ||
28 | preempt_disable(); | ||
29 | if (kprobe_running() && kprobes_fault_handler(regs, trap)) | ||
30 | ret = 1; | ||
31 | preempt_enable(); | ||
32 | } | ||
34 | 33 | ||
35 | static inline int notify_page_fault(enum die_val val, const char *str, | 34 | return ret; |
36 | struct pt_regs *regs, long err, int trap, int sig) | ||
37 | { | ||
38 | struct die_args args = { | ||
39 | .regs = regs, | ||
40 | .str = str, | ||
41 | .err = err, | ||
42 | .trapnr = trap, | ||
43 | .signr = sig | ||
44 | }; | ||
45 | return atomic_notifier_call_chain(¬ify_page_fault_chain, val, &args); | ||
46 | } | 35 | } |
47 | #else | 36 | #else |
48 | static inline int notify_page_fault(enum die_val val, const char *str, | 37 | static inline int notify_page_fault(struct pt_regs *regs, int trap) |
49 | struct pt_regs *regs, long err, int trap, int sig) | ||
50 | { | 38 | { |
51 | return NOTIFY_DONE; | 39 | return 0; |
52 | } | 40 | } |
53 | #endif | 41 | #endif |
54 | 42 | ||
@@ -117,8 +105,7 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re | |||
117 | /* | 105 | /* |
118 | * This is to handle the kprobes on user space access instructions | 106 | * This is to handle the kprobes on user space access instructions |
119 | */ | 107 | */ |
120 | if (notify_page_fault(DIE_PAGE_FAULT, "page fault", regs, code, TRAP_BRKPT, | 108 | if (notify_page_fault(regs, TRAP_BRKPT)) |
121 | SIGSEGV) == NOTIFY_STOP) | ||
122 | return; | 109 | return; |
123 | 110 | ||
124 | down_read(&mm->mmap_sem); | 111 | down_read(&mm->mmap_sem); |
diff --git a/include/asm-ia64/kdebug.h b/include/asm-ia64/kdebug.h index ba211e011a1d..320cd8e754ea 100644 --- a/include/asm-ia64/kdebug.h +++ b/include/asm-ia64/kdebug.h | |||
@@ -28,14 +28,24 @@ | |||
28 | */ | 28 | */ |
29 | #include <linux/notifier.h> | 29 | #include <linux/notifier.h> |
30 | 30 | ||
31 | extern int register_page_fault_notifier(struct notifier_block *); | 31 | /* |
32 | extern int unregister_page_fault_notifier(struct notifier_block *); | 32 | * These are only here because kprobes.c wants them to implement a |
33 | * blatant layering violation. Will hopefully go away soon once all | ||
34 | * architectures are updated. | ||
35 | */ | ||
36 | static inline int register_page_fault_notifier(struct notifier_block *nb) | ||
37 | { | ||
38 | return 0; | ||
39 | } | ||
40 | static inline int unregister_page_fault_notifier(struct notifier_block *nb) | ||
41 | { | ||
42 | return 0; | ||
43 | } | ||
33 | 44 | ||
34 | enum die_val { | 45 | enum die_val { |
35 | DIE_BREAK = 1, | 46 | DIE_BREAK = 1, |
36 | DIE_FAULT, | 47 | DIE_FAULT, |
37 | DIE_OOPS, | 48 | DIE_OOPS, |
38 | DIE_PAGE_FAULT, | ||
39 | DIE_MACHINE_HALT, | 49 | DIE_MACHINE_HALT, |
40 | DIE_MACHINE_RESTART, | 50 | DIE_MACHINE_RESTART, |
41 | DIE_MCA_MONARCH_ENTER, | 51 | DIE_MCA_MONARCH_ENTER, |
diff --git a/include/asm-ia64/kprobes.h b/include/asm-ia64/kprobes.h index 2abc98b336f3..6382e52ec227 100644 --- a/include/asm-ia64/kprobes.h +++ b/include/asm-ia64/kprobes.h | |||
@@ -120,6 +120,7 @@ struct arch_specific_insn { | |||
120 | unsigned short slot; | 120 | unsigned short slot; |
121 | }; | 121 | }; |
122 | 122 | ||
123 | extern int kprobes_fault_handler(struct pt_regs *regs, int trapnr); | ||
123 | extern int kprobe_exceptions_notify(struct notifier_block *self, | 124 | extern int kprobe_exceptions_notify(struct notifier_block *self, |
124 | unsigned long val, void *data); | 125 | unsigned long val, void *data); |
125 | 126 | ||