lkml.org 
[lkml]   [2011]   [Nov]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Date
    Subject[PATCH v7 3.2-rc2 25/30] uprobes: call post_xol() unconditionally

    Kill sstep_complete(), change uprobe_notify_resume() to use
    post_xol() unconditionally.

    It is wrong to assume that regs->ip always changes after the step.
    rep or jmp/call to self for example. We know that this task has
    already done the step, we can rely on DIE_DEBUG notification.

    Original-patch-from: Oleg Nesterov <oleg@redhat.com>
    Signed-off-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
    ---
    include/linux/uprobes.h | 3 ++-
    kernel/uprobes.c | 38 ++++++++++++--------------------------
    2 files changed, 14 insertions(+), 27 deletions(-)

    diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h
    index add5222..70d639c 100644
    --- a/include/linux/uprobes.h
    +++ b/include/linux/uprobes.h
    @@ -74,7 +74,8 @@ struct uprobe {
    enum uprobe_task_state {
    UTASK_RUNNING,
    UTASK_BP_HIT,
    - UTASK_SSTEP
    + UTASK_SSTEP,
    + UTASK_SSTEP_ACK,
    };

    /*
    diff --git a/kernel/uprobes.c b/kernel/uprobes.c
    index b440acd..50cde86 100644
    --- a/kernel/uprobes.c
    +++ b/kernel/uprobes.c
    @@ -1313,24 +1313,6 @@ static int pre_ssout(struct uprobe *uprobe, struct pt_regs *regs,
    }

    /*
    - * Verify from Instruction Pointer if singlestep has indeed occurred.
    - * If Singlestep has occurred, then do post singlestep fix-ups.
    - */
    -static bool sstep_complete(struct uprobe *uprobe, struct pt_regs *regs)
    -{
    - unsigned long vaddr = instruction_pointer(regs);
    -
    - /*
    - * If we have executed out of line, Instruction pointer
    - * cannot be same as virtual address of XOL slot.
    - */
    - if (vaddr == current->utask->xol_vaddr)
    - return false;
    - post_xol(uprobe, regs);
    - return true;
    -}
    -
    -/*
    * uprobe_notify_resume gets called in task context just before returning
    * to userspace.
    *
    @@ -1377,15 +1359,18 @@ void uprobe_notify_resume(struct pt_regs *regs)
    else
    /* Cannot Singlestep; re-execute the instruction. */
    goto cleanup_ret;
    - } else if (utask->state == UTASK_SSTEP) {
    + } else {
    u = utask->active_uprobe;
    - if (sstep_complete(u, regs)) {
    - put_uprobe(u);
    - utask->active_uprobe = NULL;
    - utask->state = UTASK_RUNNING;
    - user_disable_single_step(current);
    - xol_free_insn_slot(current);
    - }
    + if (utask->state == UTASK_SSTEP_ACK)
    + post_xol(u, regs);
    + else
    + WARN_ON_ONCE(1);
    +
    + put_uprobe(u);
    + utask->active_uprobe = NULL;
    + utask->state = UTASK_RUNNING;
    + user_disable_single_step(current);
    + xol_free_insn_slot(current);
    }
    return;

    @@ -1435,6 +1420,7 @@ int uprobe_post_notifier(struct pt_regs *regs)
    /* task is currently not uprobed */
    return 0;

    + utask->state = UTASK_SSTEP_ACK;
    set_thread_flag(TIF_UPROBE);
    return 1;
    }


    \
     
     \ /
      Last update: 2011-11-18 12:41    [W:4.309 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site