summaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/traps.c
diff options
context:
space:
mode:
authorNicolas Pitre2007-12-03 23:22:36 +0100
committerRussell King2008-01-26 16:25:17 +0100
commit796969104cab0d454dbc792ad0d12a4f365a8564 (patch)
tree214eebbe0c8cdee597184feb365c60b574650f6a /arch/arm/kernel/traps.c
parentARM kprobes: prevent some functions involved with kprobes from being probed (diff)
downloadkernel-qcow2-linux-796969104cab0d454dbc792ad0d12a4f365a8564.tar.gz
kernel-qcow2-linux-796969104cab0d454dbc792ad0d12a4f365a8564.tar.xz
kernel-qcow2-linux-796969104cab0d454dbc792ad0d12a4f365a8564.zip
ARM kprobes: special hook for the kprobes breakpoint handler
The kprobes code is already able to cope with reentrant probes, so its handler must be called outside of the region protected by undef_lock. If ever this lock is released when handlers are called then this commit could be reverted. Signed-off-by: Nicolas Pitre <nico@marvell.com>
Diffstat (limited to 'arch/arm/kernel/traps.c')
-rw-r--r--arch/arm/kernel/traps.c12
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 @@
#include <linux/kallsyms.h>
#include <linux/delay.h>
#include <linux/init.h>
+#include <linux/kprobes.h>
#include <asm/atomic.h>
#include <asm/cacheflush.h>
@@ -313,6 +314,17 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
get_user(instr, (u32 __user *)pc);
}
+#ifdef CONFIG_KPROBES
+ /*
+ * It is possible to have recursive kprobes, so we can't call
+ * the kprobe trap handler with the undef_lock held.
+ */
+ if (instr == KPROBE_BREAKPOINT_INSTRUCTION && !user_mode(regs)) {
+ kprobe_trap_handler(regs, instr);
+ return;
+ }
+#endif
+
spin_lock_irqsave(&undef_lock, flags);
list_for_each_entry(hook, &undef_hook, node) {
if ((instr & hook->instr_mask) == hook->instr_val &&