Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=9caebec7b8093574fca5a334a1939530872d75e3
Commit:     9caebec7b8093574fca5a334a1939530872d75e3
Parent:     5d1938c83ca826891a02badef7c9ea8ed57e01a2
Author:     Christoph Hellwig <[EMAIL PROTECTED]>
AuthorDate: Sat May 12 17:56:11 2007 +0200
Committer:  Haavard Skinnemoen <[EMAIL PROTECTED]>
CommitDate: Sun May 13 17:07:46 2007 +0200

    [AVR32] optimize pagefault path
    
    Avoid the costly notifier list in the pagefault path and call
    the kprobes code directly.  The same change went into the 2.6.22
    cycle for powerpc, 2s390 and sparc64 already.
    
    Signed-off-by: Christoph Hellwig <[EMAIL PROTECTED]>
    Signed-off-by: Haavard Skinnemoen <[EMAIL PROTECTED]>
---
 arch/avr32/kernel/kprobes.c |    7 +------
 arch/avr32/mm/fault.c       |   36 ++++++++++++------------------------
 include/asm-avr32/kdebug.h  |   17 +++++++++++++----
 include/asm-avr32/kprobes.h |    1 +
 4 files changed, 27 insertions(+), 34 deletions(-)

diff --git a/arch/avr32/kernel/kprobes.c b/arch/avr32/kernel/kprobes.c
index 004c94b..4942ee6 100644
--- a/arch/avr32/kernel/kprobes.c
+++ b/arch/avr32/kernel/kprobes.c
@@ -179,7 +179,7 @@ static int __kprobes post_kprobe_handler(struct pt_regs 
*regs)
        return 1;
 }
 
-static int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
+int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
 {
        struct kprobe *cur = kprobe_running();
 
@@ -216,11 +216,6 @@ int __kprobes kprobe_exceptions_notify(struct 
notifier_block *self,
                if (post_kprobe_handler(args->regs))
                        ret = NOTIFY_STOP;
                break;
-       case DIE_FAULT:
-               if (kprobe_running()
-                   && kprobe_fault_handler(args->regs, args->trapnr))
-                       ret = NOTIFY_STOP;
-               break;
        default:
                break;
        }
diff --git a/arch/avr32/mm/fault.c b/arch/avr32/mm/fault.c
index 88b00b1..e011f1c 100644
--- a/arch/avr32/mm/fault.c
+++ b/arch/avr32/mm/fault.c
@@ -12,41 +12,30 @@
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/pagemap.h>
-
 #include <linux/kdebug.h>
+#include <linux/kprobes.h>
+
 #include <asm/mmu_context.h>
 #include <asm/sysreg.h>
 #include <asm/tlb.h>
 #include <asm/uaccess.h>
 
 #ifdef CONFIG_KPROBES
-ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain);
-
-/* Hook to register for page fault notifications */
-int register_page_fault_notifier(struct notifier_block *nb)
+static inline int notify_page_fault(struct pt_regs *regs, int trap)
 {
-       return atomic_notifier_chain_register(&notify_page_fault_chain, nb);
-}
+       int ret = 0;
 
-int unregister_page_fault_notifier(struct notifier_block *nb)
-{
-       return atomic_notifier_chain_unregister(&notify_page_fault_chain, nb);
-}
+       if (!user_mode(regs)) {
+               if (kprobe_running() && kprobe_fault_handler(regs, trap))
+                       ret = 1;
+       }
 
-static inline int notify_page_fault(enum die_val val, struct pt_regs *regs,
-                                   int trap, int sig)
-{
-       struct die_args args = {
-               .regs = regs,
-               .trapnr = trap,
-       };
-       return atomic_notifier_call_chain(&notify_page_fault_chain, val, &args);
+       return ret;
 }
 #else
-static inline int notify_page_fault(enum die_val val, struct pt_regs *regs,
-                                   int trap, int sig)
+static inline int notify_page_fault(struct pt_regs *regs, int trap)
 {
-       return NOTIFY_DONE;
+       return 0;
 }
 #endif
 
@@ -76,8 +65,7 @@ asmlinkage void do_page_fault(unsigned long ecr, struct 
pt_regs *regs)
        long signr;
        int code;
 
-       if (notify_page_fault(DIE_PAGE_FAULT, regs,
-                             ecr, SIGSEGV) == NOTIFY_STOP)
+       if (notify_page_fault(regs, ecr))
                return;
 
        address = sysreg_read(TLBEAR);
diff --git a/include/asm-avr32/kdebug.h b/include/asm-avr32/kdebug.h
index de41927..7f54e2b 100644
--- a/include/asm-avr32/kdebug.h
+++ b/include/asm-avr32/kdebug.h
@@ -5,13 +5,22 @@
 
 /* Grossly misnamed. */
 enum die_val {
-       DIE_FAULT,
        DIE_BREAKPOINT,
        DIE_SSTEP,
-       DIE_PAGE_FAULT,
 };
 
-int register_page_fault_notifier(struct notifier_block *nb);
-int unregister_page_fault_notifier(struct notifier_block *nb);
+/*
+ * These are only here because kprobes.c wants them to implement a
+ * blatant layering violation.  Will hopefully go away soon once all
+ * architectures are updated.
+ */
+static inline int register_page_fault_notifier(struct notifier_block *nb)
+{
+       return 0;
+}
+static inline int unregister_page_fault_notifier(struct notifier_block *nb)
+{
+       return 0;
+}
 
 #endif /* __ASM_AVR32_KDEBUG_H */
diff --git a/include/asm-avr32/kprobes.h b/include/asm-avr32/kprobes.h
index 09a5cbe..190a637 100644
--- a/include/asm-avr32/kprobes.h
+++ b/include/asm-avr32/kprobes.h
@@ -26,6 +26,7 @@ struct arch_specific_insn {
        kprobe_opcode_t insn[MAX_INSN_SIZE];
 };
 
+extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr);
 extern int kprobe_exceptions_notify(struct notifier_block *self,
                                    unsigned long val, void *data);
 
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to