Skip to content

Commit cae74ba

Browse files
svens-s390Alexander Gordeev
authored andcommitted
s390/ftrace: Use unwinder instead of __builtin_return_address()
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>
1 parent 9679fec commit cae74ba

File tree

3 files changed

+23
-6
lines changed

3 files changed

+23
-6
lines changed

arch/s390/include/asm/ftrace.h

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,8 @@
88

99
#ifndef __ASSEMBLY__
1010

11-
#ifdef CONFIG_CC_IS_CLANG
12-
/* https://llvm.org/pr41424 */
13-
#define ftrace_return_address(n) 0UL
14-
#else
15-
#define ftrace_return_address(n) __builtin_return_address(n)
16-
#endif
11+
unsigned long return_address(unsigned int n);
12+
#define ftrace_return_address(n) return_address(n)
1713

1814
void ftrace_caller(void);
1915

arch/s390/kernel/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ CFLAGS_REMOVE_ftrace.o = $(CC_FLAGS_FTRACE)
1111
# Do not trace early setup code
1212
CFLAGS_REMOVE_early.o = $(CC_FLAGS_FTRACE)
1313
CFLAGS_REMOVE_rethook.o = $(CC_FLAGS_FTRACE)
14+
CFLAGS_REMOVE_stacktrace.o = $(CC_FLAGS_FTRACE)
15+
CFLAGS_REMOVE_unwind_bc.o = $(CC_FLAGS_FTRACE)
1416

1517
endif
1618

arch/s390/kernel/stacktrace.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,3 +101,22 @@ void arch_stack_walk_user(stack_trace_consume_fn consume_entry, void *cookie,
101101
}
102102
pagefault_enable();
103103
}
104+
105+
unsigned long return_address(unsigned int n)
106+
{
107+
struct unwind_state state;
108+
unsigned long addr;
109+
110+
/* Increment to skip current stack entry */
111+
n++;
112+
113+
unwind_for_each_frame(&state, NULL, NULL, 0) {
114+
addr = unwind_get_return_address(&state);
115+
if (!addr)
116+
break;
117+
if (!n--)
118+
return addr;
119+
}
120+
return 0;
121+
}
122+
EXPORT_SYMBOL_GPL(return_address);

0 commit comments

Comments
 (0)