diff options
Diffstat (limited to 'arch/arm/kernel/traps.c')
-rw-r--r-- | arch/arm/kernel/traps.c | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index c34db4e868fa..5595fdd75e82 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/kallsyms.h> | 19 | #include <linux/kallsyms.h> |
20 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <linux/kprobes.h> | ||
22 | 23 | ||
23 | #include <asm/atomic.h> | 24 | #include <asm/atomic.h> |
24 | #include <asm/cacheflush.h> | 25 | #include <asm/cacheflush.h> |
@@ -46,15 +47,6 @@ __setup("user_debug=", user_debug_setup); | |||
46 | 47 | ||
47 | static void dump_mem(const char *str, unsigned long bottom, unsigned long top); | 48 | static void dump_mem(const char *str, unsigned long bottom, unsigned long top); |
48 | 49 | ||
49 | static inline int in_exception_text(unsigned long ptr) | ||
50 | { | ||
51 | extern char __exception_text_start[]; | ||
52 | extern char __exception_text_end[]; | ||
53 | |||
54 | return ptr >= (unsigned long)&__exception_text_start && | ||
55 | ptr < (unsigned long)&__exception_text_end; | ||
56 | } | ||
57 | |||
58 | void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame) | 50 | void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame) |
59 | { | 51 | { |
60 | #ifdef CONFIG_KALLSYMS | 52 | #ifdef CONFIG_KALLSYMS |
@@ -322,6 +314,17 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs) | |||
322 | get_user(instr, (u32 __user *)pc); | 314 | get_user(instr, (u32 __user *)pc); |
323 | } | 315 | } |
324 | 316 | ||
317 | #ifdef CONFIG_KPROBES | ||
318 | /* | ||
319 | * It is possible to have recursive kprobes, so we can't call | ||
320 | * the kprobe trap handler with the undef_lock held. | ||
321 | */ | ||
322 | if (instr == KPROBE_BREAKPOINT_INSTRUCTION && !user_mode(regs)) { | ||
323 | kprobe_trap_handler(regs, instr); | ||
324 | return; | ||
325 | } | ||
326 | #endif | ||
327 | |||
325 | spin_lock_irqsave(&undef_lock, flags); | 328 | spin_lock_irqsave(&undef_lock, flags); |
326 | list_for_each_entry(hook, &undef_hook, node) { | 329 | list_for_each_entry(hook, &undef_hook, node) { |
327 | if ((instr & hook->instr_mask) == hook->instr_val && | 330 | if ((instr & hook->instr_mask) == hook->instr_val && |