From f6d0271729d6eb549c3ccc7d80a28b200801e97c Mon Sep 17 00:00:00 2001 From: jhb Date: Mon, 8 Feb 2016 23:11:23 +0000 Subject: 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 particular 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 MFC after: 1 week --- sys/kern/kern_fork.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sys/kern/kern_fork.c') diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 9abe08c..34af264 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -1040,7 +1040,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); -- cgit v1.1 From 736e07849585def123cc8c3042c05c77f3d11e2e Mon Sep 17 00:00:00 2001 From: kib Date: Tue, 9 Feb 2016 16:30:16 +0000 Subject: Rename P_KTHREAD struct proc p_flag to P_KPROC. I left as is an apparent bug in ntoskrnl_var.h:AT_PASSIVE_LEVEL() definition. Suggested by: jhb Sponsored by: The FreeBSD Foundation --- sys/kern/kern_fork.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sys/kern/kern_fork.c') diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 34af264..94e139e 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -1037,7 +1037,7 @@ fork_exit(void (*callout)(void *, struct trapframe *), void *arg, * Check if a kernel thread misbehaved and returned from its main * function. */ - if (p->p_flag & P_KTHREAD) { + if (p->p_flag & P_KPROC) { printf("Kernel thread \"%s\" (pid %d) exited prematurely.\n", td->td_name, p->p_pid); kthread_exit(); -- cgit v1.1