aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/mm/fault_64.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2007-10-16 04:24:07 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-16 12:42:50 -0400
commit74a0b5762713a26496db72eac34fbbed46f20fce (patch)
tree4a14df7c07ebc16283454f33713519a0e10b5c43 /arch/x86/mm/fault_64.c
parentd5a7430ddcdb598261d70f7eb1bf450b5be52085 (diff)
x86: optimize page faults like all other achitectures and kill notifier cruft
x86(-64) are the last architectures still using the page fault notifier cruft for the kprobes page fault hook. This patch converts them to the proper direct calls, and removes the now unused pagefault notifier bits aswell as the cruft in kprobes.c that was related to this mess. I know Andi didn't really like this, but all other architecture maintainers agreed the direct calls are much better and besides the obvious cruft removal a common way of dealing with kprobes across architectures is important aswell. [akpm@linux-foundation.org: build fix] [akpm@linux-foundation.org: fix sparc64] Signed-off-by: Christoph Hellwig <hch@lst.de> Cc: Andi Kleen <ak@suse.de> Cc: <linux-arch@vger.kernel.org> Cc: Prasanna S Panchamukhi <prasanna@in.ibm.com> Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com> Cc: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/x86/mm/fault_64.c')
-rw-r--r--arch/x86/mm/fault_64.c44
1 files changed, 19 insertions, 25 deletions
diff --git a/arch/x86/mm/fault_64.c b/arch/x86/mm/fault_64.c
index 54816adb8e93..5e0e54906c48 100644
--- a/arch/x86/mm/fault_64.c
+++ b/arch/x86/mm/fault_64.c
@@ -25,6 +25,7 @@
25#include <linux/kprobes.h> 25#include <linux/kprobes.h>
26#include <linux/uaccess.h> 26#include <linux/uaccess.h>
27#include <linux/kdebug.h> 27#include <linux/kdebug.h>
28#include <linux/kprobes.h>
28 29
29#include <asm/system.h> 30#include <asm/system.h>
30#include <asm/pgalloc.h> 31#include <asm/pgalloc.h>
@@ -40,34 +41,27 @@
40#define PF_RSVD (1<<3) 41#define PF_RSVD (1<<3)
41#define PF_INSTR (1<<4) 42#define PF_INSTR (1<<4)
42 43
43static ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); 44#ifdef CONFIG_KPROBES
44 45static inline int notify_page_fault(struct pt_regs *regs)
45/* Hook to register for page fault notifications */
46int register_page_fault_notifier(struct notifier_block *nb)
47{ 46{
48 vmalloc_sync_all(); 47 int ret = 0;
49 return atomic_notifier_chain_register(&notify_page_fault_chain, nb); 48
50} 49 /* kprobe_running() needs smp_processor_id() */
51EXPORT_SYMBOL_GPL(register_page_fault_notifier); 50 if (!user_mode(regs)) {
51 preempt_disable();
52 if (kprobe_running() && kprobe_fault_handler(regs, 14))
53 ret = 1;
54 preempt_enable();
55 }
52 56
53int unregister_page_fault_notifier(struct notifier_block *nb) 57 return ret;
54{
55 return atomic_notifier_chain_unregister(&notify_page_fault_chain, nb);
56} 58}
57EXPORT_SYMBOL_GPL(unregister_page_fault_notifier); 59#else
58 60static inline int notify_page_fault(struct pt_regs *regs)
59static inline int notify_page_fault(struct pt_regs *regs, long err)
60{ 61{
61 struct die_args args = { 62 return 0;
62 .regs = regs,
63 .str = "page fault",
64 .err = err,
65 .trapnr = 14,
66 .signr = SIGSEGV
67 };
68 return atomic_notifier_call_chain(&notify_page_fault_chain,
69 DIE_PAGE_FAULT, &args);
70} 63}
64#endif
71 65
72/* Sometimes the CPU reports invalid exceptions on prefetch. 66/* Sometimes the CPU reports invalid exceptions on prefetch.
73 Check that here and ignore. 67 Check that here and ignore.
@@ -345,7 +339,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
345 if (vmalloc_fault(address) >= 0) 339 if (vmalloc_fault(address) >= 0)
346 return; 340 return;
347 } 341 }
348 if (notify_page_fault(regs, error_code) == NOTIFY_STOP) 342 if (notify_page_fault(regs))
349 return; 343 return;
350 /* 344 /*
351 * Don't take the mm semaphore here. If we fixup a prefetch 345 * Don't take the mm semaphore here. If we fixup a prefetch
@@ -354,7 +348,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
354 goto bad_area_nosemaphore; 348 goto bad_area_nosemaphore;
355 } 349 }
356 350
357 if (notify_page_fault(regs, error_code) == NOTIFY_STOP) 351 if (notify_page_fault(regs))
358 return; 352 return;
359 353
360 if (likely(regs->eflags & X86_EFLAGS_IF)) 354 if (likely(regs->eflags & X86_EFLAGS_IF))