Skip to content

Commit

Permalink
powerpc/stacktrace: Fix arch_stack_walk_reliable()
Browse files Browse the repository at this point in the history
The changes to copy_thread() made in commit eed7c42 ("powerpc:
copy_thread differentiate kthreads and user mode threads") inadvertently
broke arch_stack_walk_reliable() because it has knowledge of the stack
layout.

Fix it by changing the condition to match the new logic in
copy_thread(). The changes make the comments about the stack layout
incorrect, rather than rephrasing them just refer the reader to
copy_thread().

Also the comment about the stack backchain is no longer true, since
commit edbd038 ("powerpc: copy_thread add a back chain to the
switch stack frame"), so remove that as well.

Fixes: eed7c42 ("powerpc: copy_thread differentiate kthreads and user mode threads")
Reported-by: Joe Lawrence <[email protected]>
Reviewed-by: Petr Mladek <[email protected]>
Signed-off-by: Michael Ellerman <[email protected]>
Link: https://msgid.link/[email protected]
  • Loading branch information
mpe committed Sep 22, 2023
1 parent c3f4309 commit c5cc3ca
Showing 1 changed file with 5 additions and 22 deletions.
27 changes: 5 additions & 22 deletions arch/powerpc/kernel/stacktrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,29 +73,12 @@ int __no_sanitize_address arch_stack_walk_reliable(stack_trace_consume_fn consum
bool firstframe;

stack_end = stack_page + THREAD_SIZE;
if (!is_idle_task(task)) {
/*
* For user tasks, this is the SP value loaded on
* kernel entry, see "PACAKSAVE(r13)" in _switch() and
* system_call_common().
*
* Likewise for non-swapper kernel threads,
* this also happens to be the top of the stack
* as setup by copy_thread().
*
* Note that stack backlinks are not properly setup by
* copy_thread() and thus, a forked task() will have
* an unreliable stack trace until it's been
* _switch()'ed to for the first time.
*/
stack_end -= STACK_USER_INT_FRAME_SIZE;
} else {
/*
* idle tasks have a custom stack layout,
* c.f. cpu_idle_thread_init().
*/

// See copy_thread() for details.
if (task->flags & PF_KTHREAD)
stack_end -= STACK_FRAME_MIN_SIZE;
}
else
stack_end -= STACK_USER_INT_FRAME_SIZE;

if (task == current)
sp = current_stack_frame();
Expand Down

0 comments on commit c5cc3ca

Please sign in to comment.