• Pratyush Anand's avatar
    arm64: fix unwind_frame() for filtered out fn for function graph tracing · c3655e72
    Pratyush Anand authored
    [ Upstream commit 9f416319 ]
    
    do_task_stat() calls get_wchan(), which further does unwind_frame().
    unwind_frame() restores frame->pc to original value in case function
    graph tracer has modified a return address (LR) in a stack frame to hook
    a function return. However, if function graph tracer has hit a filtered
    function, then we can't unwind it as ftrace_push_return_trace() has
    biased the index(frame->graph) with a 'huge negative'
    offset(-FTRACE_NOTRACE_DEPTH).
    
    Moreover, arm64 stack walker defines index(frame->graph) as unsigned
    int, which can not compare a -ve number.
    
    Similar problem we can have with calling of walk_stackframe() from
    save_stack_trace_tsk() or dump_backtrace().
    
    This patch fixes unwind_frame() to test the index for -ve value and
    restore index accordingly before we can restore frame->pc.
    
    Reproducer:
    
    cd /sys/kernel/debug/tracing/
    echo schedule > set_graph_notrace
    echo 1 > options/display-graph
    echo wakeup > current_tracer
    ps -ef | grep -i agent
    
    Above commands result in:
    Unable to handle kernel paging request at virtual address ffff801bd3d1e000
    pgd = ffff8003cbe97c00
    [ffff801bd3d1e000] *pgd=0000000000000000, *pud=0000000000000000
    Internal error: Oops: 96000006 [#1] SMP
    [...]
    CPU: 5 PID: 11696 Comm: ps Not tainted 4.11.0+ #33
    [...]
    task: ffff8003c21ba000 task.stack: ffff8003cc6c0000
    PC is at unwind_frame+0x12c/0x180
    LR is at get_wchan+0xd4/0x134
    pc : [<ffff00000808892c>] lr : [<ffff0000080860b8>] pstate: 60000145
    sp : ffff8003cc6c3ab0
    x29: ffff8003cc6c3ab0 x28: 0000000000000001
    x27: 0000000000000026 x26: 0000000000000026
    x25: 00000000000012d8 x24: 0000000000000000
    x23: ffff8003c1c04000 x22: ffff000008c83000
    x21: ffff8003c1c00000 x20: 000000000000000f
    x19: ffff8003c1bc0000 x18: 0000fffffc593690
    x17: 0000000000000000 x16: 0000000000000001
    x15: 0000b855670e2b60 x14: 0003e97f22cf1d0f
    x13: 0000000000000001 x12: 0000000000000000
    x11: 00000000e8f4883e x10: 0000000154f47ec8
    x9 : 0000000070f367c0 x8 : 0000000000000000
    x7 : 00008003f7290000 x6 : 0000000000000018
    x5 : 0000000000000000 x4 : ffff8003c1c03cb0
    x3 : ffff8003c1c03ca0 x2 : 00000017ffe80000
    x1 : ffff8003cc6c3af8 x0 : ffff8003d3e9e000
    
    Process ps (pid: 11696, stack limit = 0xffff8003cc6c0000)
    Stack: (0xffff8003cc6c3ab0 to 0xffff8003cc6c4000)
    [...]
    [<ffff00000808892c>] unwind_frame+0x12c/0x180
    [<ffff000008305008>] do_task_stat+0x864/0x870
    [<ffff000008305c44>] proc_tgid_stat+0x3c/0x48
    [<ffff0000082fde0c>] proc_single_show+0x5c/0xb8
    [<ffff0000082b27e0>] seq_read+0x160/0x414
    [<ffff000008289e6c>] __vfs_read+0x58/0x164
    [<ffff00000828b164>] vfs_read+0x88/0x144
    [<ffff00000828c2e8>] SyS_read+0x60/0xc0
    [<ffff0000080834a0>] __sys_trace_return+0x0/0x4
    
    Fixes: 20380bb3 (arm64: ftrace: fix a stack tracer's output under function graph tracer)
    Signed-off-by: default avatarPratyush Anand <panand@redhat.com>
    Signed-off-by: default avatarJerome Marchand <jmarchan@redhat.com>
    [catalin.marinas@arm.com: replace WARN_ON with WARN_ON_ONCE]
    Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
    Signed-off-by: default avatarSasha Levin <alexander.levin@microsoft.com>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    c3655e72