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
Approved by:	re (glebius)
This commit is contained in:
jhb 2016-02-16 21:36:48 +00:00
parent faf4c803e3
commit 221a97fa10
2 changed files with 2 additions and 2 deletions

View File

@ -479,7 +479,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_flag2 = 0;
p->p_state = PRS_NORMAL;
knlist_init_mtx(&p->p_klist, &p->p_mtx);

View File

@ -1033,7 +1033,7 @@ fork_exit(void (*callout)(void *, struct trapframe *), void *arg,
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);