Module Name: src Committed By: riz Date: Sat Mar 10 16:49:01 UTC 2012
Modified Files: src/sys/kern [netbsd-6]: kern_exec.c Log Message: Pull up following revision(s) (requested by martin in ticket #107): sys/kern/kern_exec.c: revision 1.345 sys/kern/kern_exec.c: revision 1.346 Make sure the child of a posix_spawn operation is not preempted during the times when it does not have any vm_space. Should fix PR kern/46153. Remove a KPREEMPT_ENABLE() in an error path I overlooked in the previous change - pointed out by Manuel Bouyer. While there, add a KASSERT() to make sure we have preemption enabled in the success case. To generate a diff of this commit: cvs rdiff -u -r1.339.2.2 -r1.339.2.3 src/sys/kern/kern_exec.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/kern_exec.c diff -u src/sys/kern/kern_exec.c:1.339.2.2 src/sys/kern/kern_exec.c:1.339.2.3 --- src/sys/kern/kern_exec.c:1.339.2.2 Wed Feb 22 18:43:35 2012 +++ src/sys/kern/kern_exec.c Sat Mar 10 16:49:01 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_exec.c,v 1.339.2.2 2012/02/22 18:43:35 riz Exp $ */ +/* $NetBSD: kern_exec.c,v 1.339.2.3 2012/03/10 16:49:01 riz Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -59,7 +59,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.339.2.2 2012/02/22 18:43:35 riz Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.339.2.3 2012/03/10 16:49:01 riz Exp $"); #include "opt_exec.h" #include "opt_ktrace.h" @@ -1778,11 +1778,13 @@ spawn_return(void *arg) register_t retval; bool have_reflock; + /* we have been created non-preemptable */ + KASSERT(l->l_nopreempt == 1); + /* * The following actions may block, so we need a temporary * vmspace - borrow the kernel one */ - KPREEMPT_DISABLE(l); l->l_proc->p_vmspace = proc0.p_vmspace; pmap_activate(l); KPREEMPT_ENABLE(l); @@ -1908,8 +1910,6 @@ spawn_return(void *arg) KPREEMPT_DISABLE(l); pmap_deactivate(l); l->l_proc->p_vmspace = NULL; - KPREEMPT_ENABLE(l); - /* now do the real exec */ rw_enter(&exec_lock, RW_READER); @@ -1920,6 +1920,10 @@ spawn_return(void *arg) else if (error) goto report_error; + /* we now have our own vmspace */ + KPREEMPT_ENABLE(l); + KASSERT(l->l_nopreempt == 0); + /* done, signal parent */ mutex_enter(&spawn_data->sed_mtx_child); cv_signal(&spawn_data->sed_cv_child_ready); @@ -1940,7 +1944,7 @@ spawn_return(void *arg) KPREEMPT_DISABLE(l); pmap_deactivate(l); l->l_proc->p_vmspace = NULL; - KPREEMPT_ENABLE(l); + /* do not enable preemption without vmspace */ } /* @@ -2269,6 +2273,8 @@ sys_posix_spawn(struct lwp *l1, const st kauth_cred_free(ocred); } + l2->l_nopreempt = 1; /* start it non-preemptable */ + /* * It's now safe for the scheduler and other processes to see the * child process.