Skip to content

Commit

Permalink
s390/ftrace: Use unwinder instead of __builtin_return_address()
Browse files Browse the repository at this point in the history
Using __builtin_return_address(n) might return undefined values
when used with values of n outside of the stack. This was noticed
when __builtin_return_address() was called in ftrace on top level
functions like the interrupt handlers.

As this behaviour cannot be fixed, use the s390 stack unwinder and
remove the ftrace compilation flags for unwind_bc.c and stacktrace.c
to prevent the unwinding function polluting function traces.

Another advantage is that this also works with clang.

Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
  • Loading branch information
Sven Schnelle authored and Alexander Gordeev committed Apr 29, 2024
1 parent 9679fec commit cae74ba
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 6 deletions.
8 changes: 2 additions & 6 deletions arch/s390/include/asm/ftrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,8 @@

#ifndef __ASSEMBLY__

#ifdef CONFIG_CC_IS_CLANG
/* https://llvm.org/pr41424 */
#define ftrace_return_address(n) 0UL
#else
#define ftrace_return_address(n) __builtin_return_address(n)
#endif
unsigned long return_address(unsigned int n);
#define ftrace_return_address(n) return_address(n)

void ftrace_caller(void);

Expand Down
2 changes: 2 additions & 0 deletions arch/s390/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ CFLAGS_REMOVE_ftrace.o = $(CC_FLAGS_FTRACE)
# Do not trace early setup code
CFLAGS_REMOVE_early.o = $(CC_FLAGS_FTRACE)
CFLAGS_REMOVE_rethook.o = $(CC_FLAGS_FTRACE)
CFLAGS_REMOVE_stacktrace.o = $(CC_FLAGS_FTRACE)
CFLAGS_REMOVE_unwind_bc.o = $(CC_FLAGS_FTRACE)

endif

Expand Down
19 changes: 19 additions & 0 deletions arch/s390/kernel/stacktrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,22 @@ void arch_stack_walk_user(stack_trace_consume_fn consume_entry, void *cookie,
}
pagefault_enable();
}

unsigned long return_address(unsigned int n)
{
struct unwind_state state;
unsigned long addr;

/* Increment to skip current stack entry */
n++;

unwind_for_each_frame(&state, NULL, NULL, 0) {
addr = unwind_get_return_address(&state);
if (!addr)
break;
if (!n--)
return addr;
}
return 0;
}
EXPORT_SYMBOL_GPL(return_address);

0 comments on commit cae74ba

Please sign in to comment.