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 <npig...@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

Reply via email to