|
From: tip-bot f. M. H. <mhi...@re...> - 2010-05-11 07:26:02
|
Commit-ID: 829e92458532b1dbfeb972435d45bb060cdbf5a3 Gitweb: http://git.kernel.org/tip/829e92458532b1dbfeb972435d45bb060cdbf5a3 Author: Masami Hiramatsu <mhi...@re...> AuthorDate: Tue, 27 Apr 2010 18:33:49 -0400 Committer: Ingo Molnar <mi...@el...> 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 <mhi...@re...> Acked-by: Ananth N Mavinakayanahalli <an...@in...> Cc: systemtap <sys...@so...> Cc: DLE <dle...@li...> Cc: Dave Anderson <and...@re...> Cc: Peter Zijlstra <a.p...@ch...> Cc: Mike Galbraith <ef...@gm...> Cc: Paul Mackerras <pa...@sa...> Cc: Arnaldo Carvalho de Melo <ac...@re...> Cc: Frederic Weisbecker <fwe...@gm...> LKML-Reference: <20100427223348.2322.9112.stgit@localhost6.localdomain6> Signed-off-by: Ingo Molnar <mi...@el...> --- 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)) { |