diff options
Diffstat (limited to 'arch/arm/kernel/traps.c')
-rw-r--r-- | arch/arm/kernel/traps.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 65bb762b2d80..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> |
@@ -313,6 +314,17 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs) | |||
313 | get_user(instr, (u32 __user *)pc); | 314 | get_user(instr, (u32 __user *)pc); |
314 | } | 315 | } |
315 | 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 | |||
316 | spin_lock_irqsave(&undef_lock, flags); | 328 | spin_lock_irqsave(&undef_lock, flags); |
317 | list_for_each_entry(hook, &undef_hook, node) { | 329 | list_for_each_entry(hook, &undef_hook, node) { |
318 | if ((instr & hook->instr_mask) == hook->instr_val && | 330 | if ((instr & hook->instr_mask) == hook->instr_val && |