Index: kern/kern_exec.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_exec.c,v retrieving revision 1.466 diff -u -r1.466 kern_exec.c --- kern/kern_exec.c 11 Jun 2019 23:18:55 -0000 1.466 +++ kern/kern_exec.c 13 Jun 2019 18:37:49 -0000 @@ -1207,10 +1207,16 @@ * exited and exec()/exit() are the only places it will be cleared. */ if ((p->p_lflag & PL_PPWAIT) != 0) { + lwp_t *lp; + mutex_enter(proc_lock); + lp = p->p_vforklwp; + p->p_vforklwp = NULL; + l->l_lwpctl = NULL; /* was on loan from blocked parent */ p->p_lflag &= ~PL_PPWAIT; - cv_broadcast(&p->p_pptr->p_waitcv); + + cv_broadcast(&lp->l_waitcv); mutex_exit(proc_lock); } Index: kern/kern_exit.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_exit.c,v retrieving revision 1.275 diff -u -r1.275 kern_exit.c --- kern/kern_exit.c 17 May 2019 03:34:26 -0000 1.275 +++ kern/kern_exit.c 13 Jun 2019 18:37:49 -0000 @@ -342,9 +342,14 @@ */ mutex_enter(proc_lock); if (p->p_lflag & PL_PPWAIT) { + lwp_t *lp; + l->l_lwpctl = NULL; /* was on loan from blocked parent */ p->p_lflag &= ~PL_PPWAIT; - cv_broadcast(&p->p_pptr->p_waitcv); + + lp = p->p_vforklwp; + p->p_vforklwp = NULL; + cv_broadcast(&lp->l_waitcv); } if (SESS_LEADER(p)) { Index: kern/kern_fork.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_fork.c,v retrieving revision 1.212 diff -u -r1.212 kern_fork.c --- kern/kern_fork.c 3 May 2019 22:34:21 -0000 1.212 +++ kern/kern_fork.c 13 Jun 2019 18:37:49 -0000 @@ -413,7 +413,6 @@ if (flags & FORK_PPWAIT) { /* Mark ourselves as waiting for a child. */ - l1->l_pflag |= LP_VFORKWAIT; p2->p_lflag = PL_PPWAIT; p2->p_vforklwp = l1; } else { @@ -610,10 +609,10 @@ /* * Preserve synchronization semantics of vfork. If waiting for - * child to exec or exit, sleep until it clears LP_VFORKWAIT. + * child to exec or exit, sleep until it clears p_vforklwp. */ - while (p2->p_lflag & PL_PPWAIT) // XXX: p2 can go invalid - cv_wait(&p1->p_waitcv, proc_lock); + while (p1->p_vforklwp) + cv_wait(&l1->l_waitcv, proc_lock); /* * Let the parent know that we are tracing its child. Index: sys/lwp.h =================================================================== RCS file: /cvsroot/src/sys/sys/lwp.h,v retrieving revision 1.183 diff -u -r1.183 lwp.h --- sys/lwp.h 17 May 2019 03:34:26 -0000 1.183 +++ sys/lwp.h 13 Jun 2019 18:37:48 -0000 @@ -256,7 +256,6 @@ #define LP_INTR 0x00000040 /* Soft interrupt handler */ #define LP_SYSCTLWRITE 0x00000080 /* sysctl write lock held */ #define LP_MUSTJOIN 0x00000100 /* Must join kthread on exit */ -#define LP_VFORKWAIT 0x00000200 /* Waiting at vfork() for a child */ #define LP_SINGLESTEP 0x00000400 /* Single step thread in ptrace(2) */ #define LP_TIMEINTR 0x00010000 /* Time this soft interrupt */ #define LP_PREEMPTING 0x00020000 /* mi_switch called involuntarily */