lkml.org 
[lkml]   [2010]   [May]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[tip:perf/urgent] kprobes/x86: Fix removed int3 checking order
    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)) {

    \
     
     \ /
      Last update: 2010-05-12 10:08    [W:4.208 / U:0.968 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site