[RFC PATCH 12/19] powerpc: copy_thread fill in interrupt frame marker and back chain
Nicholas Piggin
npiggin at gmail.com
Mon Oct 31 16:54:33 AEDT 2022
Backtraces will not recognise the fork system call interrupt without
the regs marker. And at least perf starts unwinding the user stack
from gpr[1] directly, but regular interrupt entry from userspace creates
the back chain to the user stack, so do this too, to be consistent.
Signed-off-by: Nicholas Piggin <npiggin at gmail.com>
---
arch/powerpc/kernel/process.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index a097879b0474..27956831fa5d 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1728,12 +1728,13 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
/* Create initial stack frame. */
sp -= STACK_USER_INT_FRAME_SIZE;
- ((unsigned long *)sp)[0] = 0;
+ *(unsigned long *)(sp + STACK_INT_FRAME_MARKER) = STACK_FRAME_REGS_MARKER;
/* Copy registers */
childregs = (struct pt_regs *)(sp + STACK_INT_FRAME_REGS);
if (unlikely(args->fn)) {
/* kernel thread */
+ ((unsigned long *)sp)[0] = 0;
memset(childregs, 0, sizeof(struct pt_regs));
childregs->gpr[1] = sp + STACK_USER_INT_FRAME_SIZE;
/* function */
@@ -1753,6 +1754,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
*childregs = *regs;
if (usp)
childregs->gpr[1] = usp;
+ ((unsigned long *)sp)[0] = childregs->gpr[1];
p->thread.regs = childregs;
/* 64s sets this in ret_from_fork */
if (!IS_ENABLED(CONFIG_PPC_BOOK3S_64))
--
2.37.2
More information about the Linuxppc-dev
mailing list