]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
powerpc: copy_thread fill in interrupt frame marker and back chain
authorNicholas Piggin <npiggin@gmail.com>
Sun, 27 Nov 2022 12:49:37 +0000 (22:49 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Fri, 2 Dec 2022 06:54:08 +0000 (17:54 +1100)
Backtraces will not recognise the fork system call interrupt without
the regs marker. And regular interrupt entry from userspace creates
the back chain to the user stack, so do this for the initial fork
frame too, to be consistent.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20221127124942.1665522-13-npiggin@gmail.com
arch/powerpc/kernel/process.c

index 0cb5296c6c41e87f62b924c57721bb67304a0e2b..6b1d80bd370ea63fd7d0c3a741db7bc468b4f1ad 100644 (file)
@@ -1757,12 +1757,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 */
@@ -1782,6 +1783,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))