aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/avr32/kernel/kprobes.c7
-rw-r--r--arch/avr32/mm/fault.c36
-rw-r--r--include/asm-avr32/kdebug.h17
-rw-r--r--include/asm-avr32/kprobes.h1
4 files changed, 27 insertions, 34 deletions
diff --git a/arch/avr32/kernel/kprobes.c b/arch/avr32/kernel/kprobes.c
index 004c94b6fc1d..4942ee662e0b 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)
179 return 1; 179 return 1;
180} 180}
181 181
182static int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) 182int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
183{ 183{
184 struct kprobe *cur = kprobe_running(); 184 struct kprobe *cur = kprobe_running();
185 185
@@ -216,11 +216,6 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
216 if (post_kprobe_handler(args->regs)) 216 if (post_kprobe_handler(args->regs))
217 ret = NOTIFY_STOP; 217 ret = NOTIFY_STOP;
218 break; 218 break;
219 case DIE_FAULT:
220 if (kprobe_running()
221 && kprobe_fault_handler(args->regs, args->trapnr))
222 ret = NOTIFY_STOP;
223 break;
224 default: 219 default:
225 break; 220 break;
226 } 221 }
diff --git a/arch/avr32/mm/fault.c b/arch/avr32/mm/fault.c
index 88b00b15970f..e011f1ce1875 100644
--- a/arch/avr32/mm/fault.c
+++ b/arch/avr32/mm/fault.c
@@ -12,41 +12,30 @@
12#include <linux/mm.h> 12#include <linux/mm.h>
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/pagemap.h> 14#include <linux/pagemap.h>
15
16#include <linux/kdebug.h> 15#include <linux/kdebug.h>
16#include <linux/kprobes.h>
17
17#include <asm/mmu_context.h> 18#include <asm/mmu_context.h>
18#include <asm/sysreg.h> 19#include <asm/sysreg.h>
19#include <asm/tlb.h> 20#include <asm/tlb.h>
20#include <asm/uaccess.h> 21#include <asm/uaccess.h>
21 22
22#ifdef CONFIG_KPROBES 23#ifdef CONFIG_KPROBES
23ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); 24static inline int notify_page_fault(struct pt_regs *regs, int trap)
24
25/* Hook to register for page fault notifications */
26int register_page_fault_notifier(struct notifier_block *nb)
27{ 25{
28 return atomic_notifier_chain_register(&notify_page_fault_chain, nb); 26 int ret = 0;
29}
30 27
31int unregister_page_fault_notifier(struct notifier_block *nb) 28 if (!user_mode(regs)) {
32{ 29 if (kprobe_running() && kprobe_fault_handler(regs, trap))
33 return atomic_notifier_chain_unregister(&notify_page_fault_chain, nb); 30 ret = 1;
34} 31 }
35 32
36static inline int notify_page_fault(enum die_val val, struct pt_regs *regs, 33 return ret;
37 int trap, int sig)
38{
39 struct die_args args = {
40 .regs = regs,
41 .trapnr = trap,
42 };
43 return atomic_notifier_call_chain(&notify_page_fault_chain, val, &args);
44} 34}
45#else 35#else
46static inline int notify_page_fault(enum die_val val, struct pt_regs *regs, 36static inline int notify_page_fault(struct pt_regs *regs, int trap)
47 int trap, int sig)
48{ 37{
49 return NOTIFY_DONE; 38 return 0;
50} 39}
51#endif 40#endif
52 41
@@ -76,8 +65,7 @@ asmlinkage void do_page_fault(unsigned long ecr, struct pt_regs *regs)
76 long signr; 65 long signr;
77 int code; 66 int code;
78 67
79 if (notify_page_fault(DIE_PAGE_FAULT, regs, 68 if (notify_page_fault(regs, ecr))
80 ecr, SIGSEGV) == NOTIFY_STOP)
81 return; 69 return;
82 70
83 address = sysreg_read(TLBEAR); 71 address = sysreg_read(TLBEAR);
diff --git a/include/asm-avr32/kdebug.h b/include/asm-avr32/kdebug.h
index de419278fc39..7f54e2b15d13 100644
--- a/include/asm-avr32/kdebug.h
+++ b/include/asm-avr32/kdebug.h
@@ -5,13 +5,22 @@
5 5
6/* Grossly misnamed. */ 6/* Grossly misnamed. */
7enum die_val { 7enum die_val {
8 DIE_FAULT,
9 DIE_BREAKPOINT, 8 DIE_BREAKPOINT,
10 DIE_SSTEP, 9 DIE_SSTEP,
11 DIE_PAGE_FAULT,
12}; 10};
13 11
14int register_page_fault_notifier(struct notifier_block *nb); 12/*
15int unregister_page_fault_notifier(struct notifier_block *nb); 13 * These are only here because kprobes.c wants them to implement a
14 * blatant layering violation. Will hopefully go away soon once all
15 * architectures are updated.
16 */
17static inline int register_page_fault_notifier(struct notifier_block *nb)
18{
19 return 0;
20}
21static inline int unregister_page_fault_notifier(struct notifier_block *nb)
22{
23 return 0;
24}
16 25
17#endif /* __ASM_AVR32_KDEBUG_H */ 26#endif /* __ASM_AVR32_KDEBUG_H */
diff --git a/include/asm-avr32/kprobes.h b/include/asm-avr32/kprobes.h
index 09a5cbe2f896..190a6377c809 100644
--- a/include/asm-avr32/kprobes.h
+++ b/include/asm-avr32/kprobes.h
@@ -26,6 +26,7 @@ struct arch_specific_insn {
26 kprobe_opcode_t insn[MAX_INSN_SIZE]; 26 kprobe_opcode_t insn[MAX_INSN_SIZE];
27}; 27};
28 28
29extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr);
29extern int kprobe_exceptions_notify(struct notifier_block *self, 30extern int kprobe_exceptions_notify(struct notifier_block *self,
30 unsigned long val, void *data); 31 unsigned long val, void *data);
31 32