aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2007-05-16 08:52:19 -0400
committerTony Luck <tony.luck@intel.com>2007-05-16 12:00:51 -0400
commit576fe0bd7e52dce7afb6b9b2450744555b2eb53a (patch)
treeacf2a5f8d7f7906cfa2da9bf53a74d8e3fcd42bb
parent17028c5c91580036eb41da2fad292965fa3b9a7d (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.c9
-rw-r--r--arch/ia64/mm/fault.c41
-rw-r--r--include/asm-ia64/kdebug.h16
-rw-r--r--include/asm-ia64/kprobes.h1
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
823static int __kprobes kprobes_fault_handler(struct pt_regs *regs, int trapnr) 823int __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 @@
19extern void die (char *, struct pt_regs *, long); 19extern void die (char *, struct pt_regs *, long);
20 20
21#ifdef CONFIG_KPROBES 21#ifdef CONFIG_KPROBES
22ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); 22static inline int notify_page_fault(struct pt_regs *regs, int trap)
23
24/* Hook to register for page fault notifications */
25int register_page_fault_notifier(struct notifier_block *nb)
26{
27 return atomic_notifier_chain_register(&notify_page_fault_chain, nb);
28}
29
30int unregister_page_fault_notifier(struct notifier_block *nb)
31{ 23{
32 return atomic_notifier_chain_unregister(&notify_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
35static 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(&notify_page_fault_chain, val, &args);
46} 35}
47#else 36#else
48static inline int notify_page_fault(enum die_val val, const char *str, 37static 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
31extern int register_page_fault_notifier(struct notifier_block *); 31/*
32extern 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 */
36static inline int register_page_fault_notifier(struct notifier_block *nb)
37{
38 return 0;
39}
40static inline int unregister_page_fault_notifier(struct notifier_block *nb)
41{
42 return 0;
43}
33 44
34enum die_val { 45enum 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
123extern int kprobes_fault_handler(struct pt_regs *regs, int trapnr);
123extern int kprobe_exceptions_notify(struct notifier_block *self, 124extern int kprobe_exceptions_notify(struct notifier_block *self,
124 unsigned long val, void *data); 125 unsigned long val, void *data);
125 126