Skip to content

Commit

Permalink
perf: Stop stack frame walking off kernel addresses boundaries
Browse files Browse the repository at this point in the history
While processing kernel perf callchains, an bad entry can be
considered as a valid stack pointer but not as a kernel address.

In this case, we hang in an endless loop. This can happen in an
x86-32 kernel after processing the last entry in a kernel
stacktrace.

Just stop the stack frame walking after we encounter an invalid
kernel address.

This fixes a hard lockup in x86-32.

Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Paul Mackerras <paulus@samba.org>
LKML-Reference: <1262227945-27014-1-git-send-regression-fweisbec@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
  • Loading branch information
Frederic Weisbecker authored and Ingo Molnar committed Jan 13, 2010
1 parent 7284ce6 commit c2c5d45
Showing 1 changed file with 8 additions and 6 deletions.
14 changes: 8 additions & 6 deletions arch/x86/kernel/dumpstack.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,15 @@ print_context_stack_bp(struct thread_info *tinfo,
while (valid_stack_ptr(tinfo, ret_addr, sizeof(*ret_addr), end)) {
unsigned long addr = *ret_addr;

if (__kernel_text_address(addr)) {
ops->address(data, addr, 1);
frame = frame->next_frame;
ret_addr = &frame->return_address;
print_ftrace_graph_addr(addr, data, ops, tinfo, graph);
}
if (!__kernel_text_address(addr))
break;

ops->address(data, addr, 1);
frame = frame->next_frame;
ret_addr = &frame->return_address;
print_ftrace_graph_addr(addr, data, ops, tinfo, graph);
}

return (unsigned long)frame;
}
EXPORT_SYMBOL_GPL(print_context_stack_bp);
Expand Down

0 comments on commit c2c5d45

Please sign in to comment.