aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/mm/fault.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-08 23:32:43 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-08 23:32:43 -0400
commit0c23664ee8c42f247dba7ceb620baabd892cef88 (patch)
treee3f37e3260bd938b293cfb8f70f8969b19539973 /arch/sparc64/mm/fault.c
parent6ec129c3a2f8b38bc37e42348470ccfcb7460146 (diff)
parent127cda1e8cc282de1ca7a9dcc3866841977b9fcc (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6: [SPARC64]: Optimize fault kprobe handling just like powerpc. [SPARC]: Wire up utimensat syscall. [SPARC64]: Fix request_irq() ignored result warnings in PCI controller code. [SPARC64]: Kill asm-sparc64/pbm.h [ATYFB]: Fix sparc includes. [QLA2XXX]: Fix build on sparc. [SPARC64]: Removal of trivial pci_controller_info uses. [SPARC64]: Move index info pci_pbm_info. [SPARC64]: Move {setup,teardown}_msi_irq into pci_pbm_info. [SPARC64]: Move pci_ops into pci_pbm_info. [SPARC64] SBUS: Error interrupt registry cleanups. [SPARC64] PCI: Use root list of pbm's instead of pci_controller_info's [SPARC64] PCI: Kill PROM_PCIRNG_MAX and PROM_PCIIMAP_MAX. [SPARC64] PCI: Use common routine to fetch PBM properties.
Diffstat (limited to 'arch/sparc64/mm/fault.c')
-rw-r--r--arch/sparc64/mm/fault.c45
1 files changed, 14 insertions, 31 deletions
diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c
index c32e309f7788..b582024d2199 100644
--- a/arch/sparc64/mm/fault.c
+++ b/arch/sparc64/mm/fault.c
@@ -32,36 +32,23 @@
32#include <asm/mmu_context.h> 32#include <asm/mmu_context.h>
33 33
34#ifdef CONFIG_KPROBES 34#ifdef CONFIG_KPROBES
35ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); 35static inline int notify_page_fault(struct pt_regs *regs)
36
37/* Hook to register for page fault notifications */
38int register_page_fault_notifier(struct notifier_block *nb)
39{ 36{
40 return atomic_notifier_chain_register(&notify_page_fault_chain, nb); 37 int ret = 0;
41} 38
42 39 /* kprobe_running() needs smp_processor_id() */
43int unregister_page_fault_notifier(struct notifier_block *nb) 40 if (!user_mode(regs)) {
44{ 41 preempt_disable();
45 return atomic_notifier_chain_unregister(&notify_page_fault_chain, nb); 42 if (kprobe_running() && kprobe_fault_handler(regs, 0))
46} 43 ret = 1;
47 44 preempt_enable();
48static inline int notify_page_fault(enum die_val val, const char *str, 45 }
49 struct pt_regs *regs, long err, int trap, int sig) 46 return ret;
50{
51 struct die_args args = {
52 .regs = regs,
53 .str = str,
54 .err = err,
55 .trapnr = trap,
56 .signr = sig
57 };
58 return atomic_notifier_call_chain(&notify_page_fault_chain, val, &args);
59} 47}
60#else 48#else
61static inline int notify_page_fault(enum die_val val, const char *str, 49static inline int notify_page_fault(struct pt_regs *regs)
62 struct pt_regs *regs, long err, int trap, int sig)
63{ 50{
64 return NOTIFY_DONE; 51 return 0;
65} 52}
66#endif 53#endif
67 54
@@ -120,9 +107,6 @@ static void __kprobes unhandled_fault(unsigned long address,
120 printk(KERN_ALERT "tsk->{mm,active_mm}->pgd = %016lx\n", 107 printk(KERN_ALERT "tsk->{mm,active_mm}->pgd = %016lx\n",
121 (tsk->mm ? (unsigned long) tsk->mm->pgd : 108 (tsk->mm ? (unsigned long) tsk->mm->pgd :
122 (unsigned long) tsk->active_mm->pgd)); 109 (unsigned long) tsk->active_mm->pgd));
123 if (notify_die(DIE_GPF, "general protection fault", regs,
124 0, 0, SIGSEGV) == NOTIFY_STOP)
125 return;
126 die_if_kernel("Oops", regs); 110 die_if_kernel("Oops", regs);
127} 111}
128 112
@@ -299,8 +283,7 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
299 283
300 fault_code = get_thread_fault_code(); 284 fault_code = get_thread_fault_code();
301 285
302 if (notify_page_fault(DIE_PAGE_FAULT, "page_fault", regs, 286 if (notify_page_fault(regs))
303 fault_code, 0, SIGSEGV) == NOTIFY_STOP)
304 return; 287 return;
305 288
306 si_code = SEGV_MAPERR; 289 si_code = SEGV_MAPERR;