This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
[tip:perf/urgent] kprobes/x86: Fix removed int3 checking order
- From: tip-bot for Masami Hiramatsu <mhiramat at redhat dot com>
- To: linux-tip-commits at vger dot kernel dot org
- Cc: linux-kernel at vger dot kernel dot org, acme at redhat dot com, paulus at samba dot org, hpa at zytor dot com, mingo at redhat dot com, a dot p dot zijlstra at chello dot nl, efault at gmx dot de, ananth at in dot ibm dot com, anderson at redhat dot com, fweisbec at gmail dot com, dle-develop at lists dot sourceforge dot net, tglx at linutronix dot de, mhiramat at redhat dot com, mingo at elte dot hu, systemtap at sources dot redhat dot com
- Date: Tue, 11 May 2010 07:25:20 GMT
- Subject: [tip:perf/urgent] kprobes/x86: Fix removed int3 checking order
- Git-commit-id: 829e92458532b1dbfeb972435d45bb060cdbf5a3
- References: <20100427223348.2322.9112.stgit@localhost6.localdomain6>
- Reply-to: mingo at redhat dot com, hpa at zytor dot com, paulus at samba dot org, acme at redhat dot com, linux-kernel at vger dot kernel dot org, a dot p dot zijlstra at chello dot nl, efault at gmx dot de, anderson at redhat dot com, ananth at in dot ibm dot com, dle-develop at lists dot sourceforge dot net, fweisbec at gmail dot com, tglx at linutronix dot de, mhiramat at redhat dot com, systemtap at sources dot redhat dot com, mingo at elte dot hu
Commit-ID: 829e92458532b1dbfeb972435d45bb060cdbf5a3
Gitweb: http://git.kernel.org/tip/829e92458532b1dbfeb972435d45bb060cdbf5a3
Author: Masami Hiramatsu <mhiramat@redhat.com>
AuthorDate: Tue, 27 Apr 2010 18:33:49 -0400
Committer: Ingo Molnar <mingo@elte.hu>
CommitDate: Tue, 11 May 2010 09:14:25 +0200
kprobes/x86: Fix removed int3 checking order
Fix kprobe/x86 to check removed int3 when failing to get kprobe
from hlist. Since we have a time window between checking int3
exists on probed address and getting kprobe on that address,
we can have following scenario:
-------
CPU1 CPU2
hit int3
check int3 exists
remove int3
remove kprobe from hlist
get kprobe from hlist
no kprobe->OOPS!
-------
This patch moves int3 checking if there is no kprobe on that
address for fixing this problem as follows:
------
CPU1 CPU2
hit int3
remove int3
remove kprobe from hlist
get kprobe from hlist
no kprobe->check int3 exists
->rollback&retry
------
Signed-off-by: Masami Hiramatsu <mhiramat@redhat.com>
Acked-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: systemtap <systemtap@sources.redhat.com>
Cc: DLE <dle-develop@lists.sourceforge.net>
Cc: Dave Anderson <anderson@redhat.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <20100427223348.2322.9112.stgit@localhost6.localdomain6>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
arch/x86/kernel/kprobes.c | 27 +++++++++++++--------------
1 files changed, 13 insertions(+), 14 deletions(-)
diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c
index b43bbae..1658efd 100644
--- a/arch/x86/kernel/kprobes.c
+++ b/arch/x86/kernel/kprobes.c
@@ -534,20 +534,6 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
struct kprobe_ctlblk *kcb;
addr = (kprobe_opcode_t *)(regs->ip - sizeof(kprobe_opcode_t));
- if (*addr != BREAKPOINT_INSTRUCTION) {
- /*
- * The breakpoint instruction was removed right
- * after we hit it. Another cpu has removed
- * either a probepoint or a debugger breakpoint
- * at this address. In either case, no further
- * handling of this interrupt is appropriate.
- * Back up over the (now missing) int3 and run
- * the original instruction.
- */
- regs->ip = (unsigned long)addr;
- return 1;
- }
-
/*
* We don't want to be preempted for the entire
* duration of kprobe processing. We conditionally
@@ -579,6 +565,19 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
setup_singlestep(p, regs, kcb, 0);
return 1;
}
+ } else if (*addr != BREAKPOINT_INSTRUCTION) {
+ /*
+ * The breakpoint instruction was removed right
+ * after we hit it. Another cpu has removed
+ * either a probepoint or a debugger breakpoint
+ * at this address. In either case, no further
+ * handling of this interrupt is appropriate.
+ * Back up over the (now missing) int3 and run
+ * the original instruction.
+ */
+ regs->ip = (unsigned long)addr;
+ preempt_enable_no_resched();
+ return 1;
} else if (kprobe_running()) {
p = __get_cpu_var(current_kprobe);
if (p->break_handler && p->break_handler(p, regs)) {