Commit cf59764
ftrace: Fix deadloop caused by direct call in ftrace selftest
After direct call is enabled for arm64, ftrace selftest enters a
dead loop:
<trace_selftest_dynamic_test_func>:
00 bti c
01 mov x9, x30 <trace_direct_tramp>:
02 bl <trace_direct_tramp> ----------> ret
|
lr/x30 is 03, return to 03
|
03 mov w0, #0x0 <-----------------------------|
| |
| dead loop! |
| |
04 ret ---- lr/x30 is still 03, go back to 03 ----|
The reason is that when the direct caller trace_direct_tramp() returns
to the patched function trace_selftest_dynamic_test_func(), lr is still
the address after the instrumented instruction in the patched function,
so when the patched function exits, it returns to itself!
To fix this issue, we need to restore lr before trace_direct_tramp()
exits, so make trace_direct_tramp() a weak symbol and rewrite it for
arm64.
To detect this issue directly, call DYN_FTRACE_TEST_NAME() before
register_ftrace_graph().
Reported-by: Li Huafei <lihuafei1@huawei.com>
Signed-off-by: Xu Kuohai <xukuohai@huawei.com>1 parent cf9a578 commit cf59764
File tree
2 files changed
+13
-1
lines changed- arch/arm64/kernel
- kernel/trace
2 files changed
+13
-1
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
357 | 357 | | |
358 | 358 | | |
359 | 359 | | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
785 | 785 | | |
786 | 786 | | |
787 | 787 | | |
788 | | - | |
| 788 | + | |
789 | 789 | | |
790 | 790 | | |
791 | 791 | | |
| |||
868 | 868 | | |
869 | 869 | | |
870 | 870 | | |
| 871 | + | |
| 872 | + | |
871 | 873 | | |
872 | 874 | | |
873 | 875 | | |
| |||
0 commit comments