fault.c (9f90b997de4efd5404a8c52f89c400f0f4e2d216) fault.c (1eeb66a1bb973534dc3d064920a5ca683823372e)
1/*
2 * PowerPC version
3 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
4 *
5 * Derived from "arch/i386/mm/fault.c"
6 * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
7 *
8 * Modified by Cort Dougan and Paul Mackerras.

--- 14 unchanged lines hidden (view full) ---

23#include <linux/types.h>
24#include <linux/ptrace.h>
25#include <linux/mman.h>
26#include <linux/mm.h>
27#include <linux/interrupt.h>
28#include <linux/highmem.h>
29#include <linux/module.h>
30#include <linux/kprobes.h>
1/*
2 * PowerPC version
3 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
4 *
5 * Derived from "arch/i386/mm/fault.c"
6 * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
7 *
8 * Modified by Cort Dougan and Paul Mackerras.

--- 14 unchanged lines hidden (view full) ---

23#include <linux/types.h>
24#include <linux/ptrace.h>
25#include <linux/mman.h>
26#include <linux/mm.h>
27#include <linux/interrupt.h>
28#include <linux/highmem.h>
29#include <linux/module.h>
30#include <linux/kprobes.h>
31#include <linux/kdebug.h>
31
32#include <asm/page.h>
33#include <asm/pgtable.h>
34#include <asm/mmu.h>
35#include <asm/mmu_context.h>
36#include <asm/system.h>
37#include <asm/uaccess.h>
38#include <asm/tlbflush.h>
32
33#include <asm/page.h>
34#include <asm/pgtable.h>
35#include <asm/mmu.h>
36#include <asm/mmu_context.h>
37#include <asm/system.h>
38#include <asm/uaccess.h>
39#include <asm/tlbflush.h>
39#include <asm/kdebug.h>
40#include <asm/siginfo.h>
41
40#include <asm/siginfo.h>
41
42
43#ifdef CONFIG_KPROBES
42#ifdef CONFIG_KPROBES
44static inline int notify_page_fault(struct pt_regs *regs)
43ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain);
44
45/* Hook to register for page fault notifications */
46int register_page_fault_notifier(struct notifier_block *nb)
45{
47{
46 int ret = 0;
48 return atomic_notifier_chain_register(&notify_page_fault_chain, nb);
49}
47
50
48 /* kprobe_running() needs smp_processor_id() */
49 if (!user_mode(regs)) {
50 preempt_disable();
51 if (kprobe_running() && kprobe_fault_handler(regs, 11))
52 ret = 1;
53 preempt_enable();
54 }
51int unregister_page_fault_notifier(struct notifier_block *nb)
52{
53 return atomic_notifier_chain_unregister(&notify_page_fault_chain, nb);
54}
55
55
56 return ret;
56static inline int notify_page_fault(enum die_val val, const char *str,
57 struct pt_regs *regs, long err, int trap, int sig)
58{
59 struct die_args args = {
60 .regs = regs,
61 .str = str,
62 .err = err,
63 .trapnr = trap,
64 .signr = sig
65 };
66 return atomic_notifier_call_chain(&notify_page_fault_chain, val, &args);
57}
58#else
67}
68#else
59static inline int notify_page_fault(struct pt_regs *regs)
69static inline int notify_page_fault(enum die_val val, const char *str,
70 struct pt_regs *regs, long err, int trap, int sig)
60{
71{
61 return 0;
72 return NOTIFY_DONE;
62}
63#endif
64
65/*
66 * Check whether the instruction at regs->nip is a store using
67 * an update addressing form which will update r1.
68 */
69static int store_updates_sp(struct pt_regs *regs)

--- 89 unchanged lines hidden (view full) ---

159 if (trap == 0x400)
160 error_code &= 0x48200000;
161 else
162 is_write = error_code & DSISR_ISSTORE;
163#else
164 is_write = error_code & ESR_DST;
165#endif /* CONFIG_4xx || CONFIG_BOOKE */
166
73}
74#endif
75
76/*
77 * Check whether the instruction at regs->nip is a store using
78 * an update addressing form which will update r1.
79 */
80static int store_updates_sp(struct pt_regs *regs)

--- 89 unchanged lines hidden (view full) ---

170 if (trap == 0x400)
171 error_code &= 0x48200000;
172 else
173 is_write = error_code & DSISR_ISSTORE;
174#else
175 is_write = error_code & ESR_DST;
176#endif /* CONFIG_4xx || CONFIG_BOOKE */
177
167 if (notify_page_fault(regs))
178 if (notify_page_fault(DIE_PAGE_FAULT, "page_fault", regs, error_code,
179 11, SIGSEGV) == NOTIFY_STOP)
168 return 0;
169
170 if (trap == 0x300) {
171 if (debugger_fault_handler(regs))
172 return 0;
173 }
174
175 /* On a kernel SLB miss we can only check for a valid exception entry */

--- 262 unchanged lines hidden ---
180 return 0;
181
182 if (trap == 0x300) {
183 if (debugger_fault_handler(regs))
184 return 0;
185 }
186
187 /* On a kernel SLB miss we can only check for a valid exception entry */

--- 262 unchanged lines hidden ---