From 9561cbad80d3084f178f87b955c8deb19d694ceb Mon Sep 17 00:00:00 2001 From: jhb Date: Wed, 17 Feb 2016 01:45:34 +0000 Subject: [PATCH] MFC 295418,295419: Fix hangs or panics when misbehaved kernel threads return from their main function. 295418: Mark proc0 as a kernel process via the P_KTHREAD flag. All other kernel processes have this flag set and all threads in proc0 (including thread0) have the similar TDP_KTHREAD flag set. 295419: Call kthread_exit() rather than kproc_exit() for a premature kthread exit. Kernel threads (and processes) are supposed to call kthread_exit() (or kproc_exit()) to terminate. However, the kernel includes a fallback in fork_exit() to force a kthread exit if a kernel thread's "main" routine returns. This fallback was added back when the kernel only had processes and was not updated to call kthread_exit() instead of kproc_exit() when threads were added to the kernel. This mistake was particularly exciting when the errant thread belonged to proc0. Due to the missing P_KTHREAD flag the fallback did not kick in and instead tried to return to userland via whatever garbage was in the trapframe. With P_KTHREAD set it tried to terminate proc0 resulting in other amusements. PR: 204999 git-svn-id: svn://svn.freebsd.org/base/stable/8@295684 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- sys/kern/init_main.c | 2 +- sys/kern/kern_fork.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index 5cd793e51..0e5206ea0 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -451,7 +451,7 @@ proc0_init(void *dummy __unused) session0.s_leader = p; p->p_sysent = &null_sysvec; - p->p_flag = P_SYSTEM | P_INMEM; + p->p_flag = P_SYSTEM | P_INMEM | P_KTHREAD; p->p_state = PRS_NORMAL; knlist_init_mtx(&p->p_klist, &p->p_mtx); STAILQ_INIT(&p->p_ktr); diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 7ee5a69af..417f19ab4 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -878,7 +878,7 @@ fork_exit(callout, arg, frame) if (p->p_flag & P_KTHREAD) { printf("Kernel thread \"%s\" (pid %d) exited prematurely.\n", td->td_name, p->p_pid); - kproc_exit(0); + kthread_exit(); } mtx_assert(&Giant, MA_NOTOWNED); -- 2.42.0