From: Nicholas Piggin <npiggin@gmail.com>
To: linuxppc-dev@lists.ozlabs.org
Cc: Nicholas Piggin <npiggin@gmail.com>
Subject: [PATCH 6/8] powerpc: differentiate kthread from user kernel thread start
Date: Wed, 1 Feb 2023 02:55:32 +1000 [thread overview]
Message-ID: <20230131165534.601490-7-npiggin@gmail.com> (raw)
In-Reply-To: <20230131165534.601490-1-npiggin@gmail.com>
Kernel created user threads start similarly to kernel threads in that
they call a kernel function after first returning from _switch, so they
share ret_from_kernel_thread for this. Kernel threads never return from
that function though, whereas user threads often do (although some
don't, e.g., IO threads).
Split these startup functions in two, and catch kernel threads that
improperly return from their function. This is intended to make the
complicated code a little bit easier to understand.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/kernel/entry_32.S | 20 ++++++++++++++++++--
arch/powerpc/kernel/interrupt_64.S | 18 +++++++++++++++++-
arch/powerpc/kernel/process.c | 7 ++++---
3 files changed, 39 insertions(+), 6 deletions(-)
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index c3fdb3081d3d..c33ac0b454dc 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -186,8 +186,8 @@ ret_from_fork:
li r3,0 /* fork() return value */
b ret_from_syscall
- .globl ret_from_kernel_thread
-ret_from_kernel_thread:
+ .globl ret_from_kernel_user_thread
+ret_from_kernel_user_thread:
bl schedule_tail
mtctr r14
mr r3,r15
@@ -196,6 +196,22 @@ ret_from_kernel_thread:
li r3,0
b ret_from_syscall
+ .globl start_kernel_thread
+start_kernel_thread:
+ bl schedule_tail
+ mtctr r14
+ mr r3,r15
+ PPC440EP_ERR42
+ bctrl
+ /*
+ * This must not return. We actually want to BUG here, not WARN,
+ * because BUG will exit the process which is what the kernel thread
+ * should have done, which may give some hope of continuing.
+ */
+100: trap
+ EMIT_BUG_ENTRY 100b,__FILE__,__LINE__,0
+
+
/*
* This routine switches between two different tasks. The process
* state of one is saved on its kernel stack. Then the state
diff --git a/arch/powerpc/kernel/interrupt_64.S b/arch/powerpc/kernel/interrupt_64.S
index bac1f89501ac..90370b89905b 100644
--- a/arch/powerpc/kernel/interrupt_64.S
+++ b/arch/powerpc/kernel/interrupt_64.S
@@ -739,7 +739,7 @@ _GLOBAL(ret_from_fork)
li r3,0 /* fork() return value */
b .Lsyscall_exit
-_GLOBAL(ret_from_kernel_thread)
+_GLOBAL(ret_from_kernel_user_thread)
bl schedule_tail
mtctr r14
mr r3,r15
@@ -749,3 +749,19 @@ _GLOBAL(ret_from_kernel_thread)
bctrl
li r3,0
b .Lsyscall_exit
+
+_GLOBAL(start_kernel_thread)
+ bl schedule_tail
+ mtctr r14
+ mr r3,r15
+#ifdef CONFIG_PPC64_ELF_ABI_V2
+ mr r12,r14
+#endif
+ bctrl
+ /*
+ * This must not return. We actually want to BUG here, not WARN,
+ * because BUG will exit the process which is what the kernel thread
+ * should have done, which may give some hope of continuing.
+ */
+100: trap
+ EMIT_BUG_ENTRY 100b,__FILE__,__LINE__,0
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 82aad157c5f6..53215cdb19dd 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1742,7 +1742,8 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
struct pt_regs *kregs; /* Switch frame regs */
extern void ret_from_fork(void);
extern void ret_from_fork_scv(void);
- extern void ret_from_kernel_thread(void);
+ extern void ret_from_kernel_user_thread(void);
+ extern void start_kernel_thread(void);
void (*f)(void);
unsigned long sp = (unsigned long)task_stack_page(p) + THREAD_SIZE;
struct thread_info *ti = task_thread_info(p);
@@ -1759,7 +1760,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
sp -= STACK_FRAME_MIN_SIZE;
((unsigned long *)sp)[0] = 0;
- f = ret_from_kernel_thread;
+ f = start_kernel_thread;
p->thread.regs = NULL; /* no user register state */
#ifdef CONFIG_PPC64
clear_tsk_thread_flag(p, TIF_32BIT);
@@ -1786,7 +1787,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
childregs->softe = IRQS_ENABLED;
#endif
ti->flags |= _TIF_RESTOREALL;
- f = ret_from_kernel_thread;
+ f = ret_from_kernel_user_thread;
} else {
struct pt_regs *regs = current_pt_regs();
unsigned long clone_flags = args->flags;
--
2.37.2
next prev parent reply other threads:[~2023-01-31 17:02 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-01-31 16:55 [PATCH 0/8] powerpc: improve copy_thread Nicholas Piggin
2023-01-31 16:55 ` [PATCH 1/8] powerpc: copy_thread remove unused pkey code Nicholas Piggin
2023-01-31 16:55 ` [PATCH 2/8] powerpc: copy_thread make ret_from_fork register setup consistent Nicholas Piggin
2023-01-31 16:55 ` [PATCH 3/8] powerpc: use switch frame for ret_from_kernel_thread parameters Nicholas Piggin
2023-01-31 16:55 ` [PATCH 4/8] powerpc/64: ret_from_fork avoid restoring regs twice Nicholas Piggin
2023-01-31 16:55 ` [PATCH 5/8] powerpc: copy_thread differentiate kthreads and user mode threads Nicholas Piggin
2023-01-31 16:55 ` Nicholas Piggin [this message]
2023-01-31 16:55 ` [PATCH 7/8] powerpc: copy_thread don't set _TIF_RESTOREALL Nicholas Piggin
2023-01-31 16:55 ` [PATCH 8/8] powerpc: copy_thread don't set ppr in user interrupt frame regs Nicholas Piggin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230131165534.601490-7-npiggin@gmail.com \
--to=npiggin@gmail.com \
--cc=linuxppc-dev@lists.ozlabs.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).