[kvm-unit-tests PATCH v8 09/35] powerpc: Fix stack backtrace termination

Nicholas Piggin
2024-04-05T08:36:24Z

The backtrace handler terminates when it sees a NULL caller address,
but the powerpc stack setup does not keep such a NULL caller frame
at the start of the stack.

This happens to work on pseries because the memory at 0 is mapped and
it contains 0 at the location of the return address pointer if it
were a stack frame. But this is fragile, and does not work with powernv
where address 0 contains firmware instructions.

Use the existing dummy frame on stack as the NULL caller, and create a
new frame on stack for the entry code.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
powerpc/cstart64.S | 15 +++++++++++++++
1 file changed, 15 insertions(+)

diff --git a/powerpc/cstart64.S b/powerpc/cstart64.S
index e18ae9a22..80baabe8f 100644
--- a/powerpc/cstart64.S
+++ b/powerpc/cstart64.S
@@ -46,6 +46,21 @@ start:
add r1, r1, r31
add r2, r2, r31

+ /* Zero backpointers in initial stack frame so backtrace() stops */
+ li r0,0
+ std r0,0(r1)
+ std r0,16(r1)
+
+ /*
+ * Create entry frame of 64-bytes, same as the initial frame. A callee
+ * may use the caller frame to store LR, and backtrace() termination
+ * looks for return address == NULL, so the initial stack frame can't
+ * be used to call C or else it could overwrite the zeroed LR save slot
+ * and break backtrace termination. This frame would be unnecessary if
+ * backtrace looked for a zeroed frame address.
+ */
+ stdu r1,-64(r1)
+
/* save DTB pointer */
std r3, 56(r1)

--
2.43.0