[PATCH v3 2/3] m68k: correctly handle IO worker stack frame set-up
From: Michael Schmitz <schmitzmic@gmail.com>
Date: 2021-06-20 08:14:43
Also in:
linux-m68k
Subsystem:
m68k architecture, the rest · Maintainers:
Geert Uytterhoeven, Linus Torvalds
Create full stack frame plus switch stack frame in copy_thread() when creating a kernel worker thread. The switch stack frame will then be consumed in resume(), leaving a full stack frame of zero content for ptrace to play with. Change ret_from_exception switch stack handling to restore the switch stack (and pop the return address restored by that)after return from kernel worker threads. Patch suggested by Linus (authored, actually - replace my signoff if that's not appropriate, please). Tested on both ARAnyM and Falcon hardware. CC: Eric W. Biederman <redacted> CC: Linus Torvalds <torvalds@linux-foundation.org> CC: Andreas Schwab <redacted> Signed-off-by: Michael Schmitz <schmitzmic@gmail.com> --- arch/m68k/kernel/entry.S | 11 +++++++++++ arch/m68k/kernel/process.c | 13 +++++++++---- 2 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S
index 275452a..0c25038 100644
--- a/arch/m68k/kernel/entry.S
+++ b/arch/m68k/kernel/entry.S@@ -147,6 +147,15 @@ ENTRY(ret_from_fork) addql #4,%sp jra ret_from_exception + | A kernel thread will jump here directly from resume, + | with the stack containing the full register state + | (pt_regs and switch_stack). + | + | The argument will be in d7, and the kernel function + | to call will be in a3. + | + | If the kernel function returns, we want to return + | to user space - it has done a kernel_execve(). ENTRY(ret_from_kernel_thread) | a3 contains the kernel thread payload, d7 - its argument movel %d1,%sp@-
@@ -154,6 +163,8 @@ ENTRY(ret_from_kernel_thread) movel %d7,(%sp) jsr %a3@ addql #4,%sp + RESTORE_SWITCH_STACK + addql #4,%sp jra ret_from_exception #if defined(CONFIG_COLDFIRE) || !defined(CONFIG_MMU)
diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c
index 7dd0eea..f9598e0 100644
--- a/arch/m68k/kernel/process.c
+++ b/arch/m68k/kernel/process.c@@ -192,12 +192,17 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, unsigned long arg, if (unlikely(p->flags & (PF_KTHREAD | PF_IO_WORKER))) { /* kernel thread */ - memset(frame, 0, sizeof(struct fork_frame)); + struct switch_stack *kstp = &frame->sw - 1; + + /* kernel thread - a kernel-side switch-stack and the full user fork_frame */ + memset(kstp, 0, sizeof(struct switch_stack) + sizeof(struct fork_frame)); + frame->regs.sr = PS_S; - frame->sw.a3 = usp; /* function */ - frame->sw.d7 = arg; - frame->sw.retpc = (unsigned long)ret_from_kernel_thread; + kstp->a3 = usp; /* function */ + kstp->d7 = arg; + kstp->retpc = (unsigned long)ret_from_kernel_thread; p->thread.usp = 0; + p->thread.ksp = (unsigned long)kstp; return 0; } memcpy(frame, container_of(current_pt_regs(), struct fork_frame, regs),
--
2.7.4