| From 9fcf89f6d5cf3cabd68ceac65fbd1c3801e41b9e Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Thu, 21 Oct 2021 09:55:17 +0900 |
| Subject: ARM: clang: Do not rely on lr register for stacktrace |
| |
| From: Masami Hiramatsu <mhiramat@kernel.org> |
| |
| [ Upstream commit b3ea5d56f212ad81328c82454829a736197ebccc ] |
| |
| Currently the stacktrace on clang compiled arm kernel uses the 'lr' |
| register to find the first frame address from pt_regs. However, that |
| is wrong after calling another function, because the 'lr' register |
| is used by 'bl' instruction and never be recovered. |
| |
| As same as gcc arm kernel, directly use the frame pointer (r11) of |
| the pt_regs to find the first frame address. |
| |
| Note that this fixes kretprobe stacktrace issue only with |
| CONFIG_UNWINDER_FRAME_POINTER=y. For the CONFIG_UNWINDER_ARM, |
| we need another fix. |
| |
| Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org> |
| Reviewed-by: Nick Desaulniers <ndesaulniers@google.com> |
| Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| arch/arm/kernel/stacktrace.c | 3 +-- |
| 1 file changed, 1 insertion(+), 2 deletions(-) |
| |
| diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c |
| index 76ea4178a55cb..db798eac74315 100644 |
| --- a/arch/arm/kernel/stacktrace.c |
| +++ b/arch/arm/kernel/stacktrace.c |
| @@ -54,8 +54,7 @@ int notrace unwind_frame(struct stackframe *frame) |
| |
| frame->sp = frame->fp; |
| frame->fp = *(unsigned long *)(fp); |
| - frame->pc = frame->lr; |
| - frame->lr = *(unsigned long *)(fp + 4); |
| + frame->pc = *(unsigned long *)(fp + 4); |
| #else |
| /* check current frame pointer is within bounds */ |
| if (fp < low + 12 || fp > high - 4) |
| -- |
| 2.33.0 |
| |