[PATCH v2] arm: backtrace-clang: fix wrong sp usage for unwinding

Maninder Singh <[email protected]>
Newsgroups dev.linux.lists.llvm,org.infradead.lists.linux-arm-kernel,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
show_stack() can be called for any task, but c_backtrace is always
unwinding frames based on "sp" register.

Which leads to printing backtrace of current task instead of
required task.

Try with normal TC:
==================
       for_each_process(p){
               sched_show_task(p);
       }

[7.433271] task:kthreadd        state:S stack:0     pid:2     tgid:2     ppid:0      task_flags:0x208040 flags:0x00000000
[7.433633] Call trace:
[7.433640] [<80113418>] (dump_backtrace) from [<80113510>] (show_stack+0x14/0x18)
..
[7.433676] [<8016749c>] (sched_show_task) from [<803cb324>] (meminfo_proc_show+0x6c/0x930)
[7.434019]  r5:8158e300 r4:8b4882d0
[7.434024] [<803cb324>] (meminfo_proc_show) from [<80365788>] (seq_read_iter+0x148/0x4bc)
[7.434045] [<80365788>] (seq_read_iter) from [<803c044c>] (proc_reg_read_iter+0xb8/0xc4)
[7.434060] [<803c044c>] (proc_reg_read_iter) from [<80377104>] (copy_splice_read+0x228/0x308)

It should unwind frame based on passed "fp".
(CONFIG_UNWINDER_FRAME_POINTER=y)

Extra sp manipulation is needed only when c_backtrace()
is called from dump_backtrace() with "frame == fp" i.e.
NULL regs and not current task. (Suggested by Ard Biesheuvel)

Otherwise passed "fp" should be used to unwind backtraces.

With fix:
=========
[13.933732] task:kthreadd        state:S stack:0     pid:2     tgid:2     ppid:0      task_flags:0x208040 flags:0x00000000
[13.934165] Call trace:
[13.934604] [<80afa1a8>] (schedule) from [<8015426c>] (kthreadd+0x124/0x208)
[13.934654]  r10:8100bbf0 r4:8116f440
[13.934664] [<8015426c>] (kthreadd) from [<8010010c>] (ret_from_fork+0x14/0x28)
[13.934691] Exception stack(0xf081df9c to 0xf081dfe4)

Signed-off-by: Onkarnath <[email protected]>
Signed-off-by: Maninder Singh <[email protected]>
---
v1 -> v2: don't ignore sp manipulation completely, instead use it for NULL regs.

 arch/arm/lib/backtrace-clang.S | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/arm/lib/backtrace-clang.S b/arch/arm/lib/backtrace-clang.S
index 290c52a60fc6..bf9738070af7 100644
--- a/arch/arm/lib/backtrace-clang.S
+++ b/arch/arm/lib/backtrace-clang.S
@@ -107,8 +107,10 @@ ENDPROC(c_backtrace)
 
 /*
  * Switches the current frame to be the frame for dump_stack.
+ * (Only in case of current task using current registers)
  */
-		add	frame, sp, #24		@ switch to false frame
+		cmp	frame, fp
+		addeq	frame, sp, #24		@ switch to false frame
 for_each_frame:	tst	frame, mask		@ Check for address exceptions
 		bne	no_frame
 
-- 
2.34.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.