lkml.org 
[lkml]   [2011]   [Oct]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH 9/X] uprobes: introduce UTASK_SSTEP_ACK state
    Introduce the new state, UTASK_SSTEP_ACK. uprobe_post_notifier()
    sets this state like uprobe_bkpt_notifier() sets UTASK_BP_HIT.

    Change uprobe_notify_resume() to always do the post_xol() logic
    if state != UTASK_BP_HIT and WARN() if the utask->state is wrong.

    This makes the state transitions more explicit. The current code
    returns silently if, say, state == UTASK_RUNNING. But this must
    not happen, we should complain in this case. And, with the new
    state we know for sure that DIE_DEBUG was triggered.
    ---
    include/linux/uprobes.h | 3 ++-
    kernel/uprobes.c | 15 ++++++++-------
    2 files changed, 10 insertions(+), 8 deletions(-)

    diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h
    index a407d17..1591c7c 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 135b9a2..5fd72b8 100644
    --- a/kernel/uprobes.c
    +++ b/kernel/uprobes.c
    @@ -1365,10 +1365,13 @@ 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;

    - post_xol(u, regs); /* TODO: check result? */
    + if (utask->state == UTASK_SSTEP_ACK)
    + post_xol(u, regs); /* TODO: check result? */
    + else
    + WARN_ON_ONCE(1);

    put_uprobe(u);
    utask->active_uprobe = NULL;
    @@ -1416,15 +1419,13 @@ int uprobe_bkpt_notifier(struct pt_regs *regs)
    */
    int uprobe_post_notifier(struct pt_regs *regs)
    {
    - struct uprobe *uprobe;
    - struct uprobe_task *utask;
    + struct uprobe_task *utask = current->utask;

    - if (!current->mm || !current->utask || !current->utask->active_uprobe)
    + if (!current->mm || !utask || !utask->active_uprobe)
    /* task is currently not uprobed */
    return 0;

    - utask = current->utask;
    - uprobe = utask->active_uprobe;
    + utask->state = UTASK_SSTEP_ACK;
    set_thread_flag(TIF_UPROBE);
    return 1;
    }
    --
    1.5.5.1



    \
     
     \ /
      Last update: 2011-10-19 23:59    [W:0.040 / U:0.292 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site