lkml.org 
[lkml]   [2019]   [Jan]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3/4] powerpc/livepatch: small cleanups in save_stack_trace_tsk_reliable()
    Date
    Mostly cosmetic changes:

    - Group common stack pointer code at the top
    - Simplify the first frame logic
    - Code stackframe iteration into for...loop construct
    - Check for trace->nr_entries overflow before adding any into the array

    Suggested-by: Nicolai Stange <nstange@suse.de>
    Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
    ---
    arch/powerpc/kernel/stacktrace.c | 40 +++++++++++---------------------
    1 file changed, 14 insertions(+), 26 deletions(-)

    diff --git a/arch/powerpc/kernel/stacktrace.c b/arch/powerpc/kernel/stacktrace.c
    index 06688f4d557b..28c3c25755d7 100644
    --- a/arch/powerpc/kernel/stacktrace.c
    +++ b/arch/powerpc/kernel/stacktrace.c
    @@ -95,20 +95,11 @@ save_stack_trace_tsk_reliable(struct task_struct *tsk,
    struct stack_trace *trace)
    {
    unsigned long sp;
    + unsigned long newsp;
    unsigned long stack_page = (unsigned long)task_stack_page(tsk);
    unsigned long stack_end;
    int graph_idx = 0;
    -
    - /*
    - * The last frame (unwinding first) may not yet have saved
    - * its LR onto the stack.
    - */
    - int firstframe = 1;
    -
    - if (tsk == current)
    - sp = current_stack_pointer();
    - else
    - sp = tsk->thread.ksp;
    + bool firstframe;

    stack_end = stack_page + THREAD_SIZE;
    if (!is_idle_task(tsk)) {
    @@ -135,14 +126,20 @@ save_stack_trace_tsk_reliable(struct task_struct *tsk,
    stack_end -= STACK_FRAME_OVERHEAD;
    }

    + if (tsk == current)
    + sp = current_stack_pointer();
    + else
    + sp = tsk->thread.ksp;
    +
    if (sp < stack_page + sizeof(struct thread_struct) ||
    sp > stack_end - STACK_FRAME_MIN_SIZE) {
    return 1;
    }

    - for (;;) {
    + for (firstframe = true; sp != stack_end;
    + firstframe = false, sp = newsp) {
    unsigned long *stack = (unsigned long *) sp;
    - unsigned long newsp, ip;
    + unsigned long ip;

    /* sanity check: ABI requires SP to be aligned 16 bytes. */
    if (sp & 0xF)
    @@ -163,10 +160,8 @@ save_stack_trace_tsk_reliable(struct task_struct *tsk,
    * rest of the frame may be uninitialized, continue to
    * the next.
    */
    - if (firstframe) {
    - firstframe = 0;
    - goto next;
    - }
    + if (firstframe)
    + continue;

    /* Mark stacktraces with exception frames as unreliable. */
    if (sp <= stack_end - STACK_INT_FRAME_SIZE &&
    @@ -193,19 +188,12 @@ save_stack_trace_tsk_reliable(struct task_struct *tsk,
    return 1;
    #endif

    + if (trace->nr_entries >= trace->max_entries)
    + return -E2BIG;
    if (!trace->skip)
    trace->entries[trace->nr_entries++] = ip;
    else
    trace->skip--;
    -
    -next:
    - if (newsp == stack_end)
    - break;
    -
    - if (trace->nr_entries >= trace->max_entries)
    - return -E2BIG;
    -
    - sp = newsp;
    }
    return 0;
    }
    --
    2.20.1
    \
     
     \ /
      Last update: 2019-01-22 16:58    [W:2.389 / U:0.176 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site