Index: amd64/amd64/machdep.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/amd64/amd64/machdep.c,v retrieving revision 1.675.2.2 diff -u -r1.675.2.2 machdep.c --- amd64/amd64/machdep.c 19 Dec 2007 20:52:37 -0000 1.675.2.2 +++ amd64/amd64/machdep.c 9 Jan 2008 15:36:04 -0000 @@ -1161,7 +1161,7 @@ * This may be done better later if it gets more high level * components in it. If so just link td->td_proc here. */ - proc_linkup(&proc0, &thread0); + proc_linkup0(&proc0, &thread0); preload_metadata = (caddr_t)(uintptr_t)(modulep + KERNBASE); preload_bootstrap_relocate(KERNBASE); Index: amd64/amd64/pmap.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/amd64/amd64/pmap.c,v retrieving revision 1.590.2.3 diff -u -r1.590.2.3 pmap.c --- amd64/amd64/pmap.c 13 Dec 2007 19:34:22 -0000 1.590.2.3 +++ amd64/amd64/pmap.c 9 Jan 2008 15:36:05 -0000 @@ -1208,7 +1208,7 @@ * Initialize a preallocated and zeroed pmap structure, * such as one in a vmspace structure. */ -void +int pmap_pinit(pmap_t pmap) { vm_page_t pml4pg; @@ -1238,6 +1238,8 @@ pmap->pm_active = 0; TAILQ_INIT(&pmap->pm_pvchunk); bzero(&pmap->pm_stats, sizeof pmap->pm_stats); + + return (1); } /* Index: arm/arm/pmap.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/arm/arm/pmap.c,v retrieving revision 1.86.2.1 diff -u -r1.86.2.1 pmap.c --- arm/arm/pmap.c 7 Dec 2007 22:28:49 -0000 1.86.2.1 +++ arm/arm/pmap.c 9 Jan 2008 15:36:06 -0000 @@ -3813,7 +3813,7 @@ * such as one in a vmspace structure. */ -void +int pmap_pinit(pmap_t pmap) { PDEBUG(1, printf("pmap_pinit: pmap = %08x\n", (uint32_t) pmap)); @@ -3832,6 +3832,7 @@ pmap_enter(pmap, vector_page, PHYS_TO_VM_PAGE(systempage.pv_pa), VM_PROT_READ, 1); } + return (1); } Index: arm/at91/kb920x_machdep.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/arm/at91/kb920x_machdep.c,v retrieving revision 1.23.2.1 diff -u -r1.23.2.1 kb920x_machdep.c --- arm/at91/kb920x_machdep.c 2 Dec 2007 14:19:37 -0000 1.23.2.1 +++ arm/at91/kb920x_machdep.c 9 Jan 2008 15:36:06 -0000 @@ -449,7 +449,7 @@ undefined_handler_address = (u_int)undefinedinstruction_bounce; undefined_init(); - proc_linkup(&proc0, &thread0); + proc_linkup0(&proc0, &thread0); thread0.td_kstack = kernelstack.pv_va; thread0.td_pcb = (struct pcb *) (thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1; Index: arm/sa11x0/assabet_machdep.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/arm/sa11x0/assabet_machdep.c,v retrieving revision 1.21 diff -u -r1.21 assabet_machdep.c --- arm/sa11x0/assabet_machdep.c 6 Dec 2006 06:34:54 -0000 1.21 +++ arm/sa11x0/assabet_machdep.c 9 Jan 2008 15:36:07 -0000 @@ -422,7 +422,7 @@ /* Set stack for exception handlers */ - proc_linkup(&proc0, &thread0); + proc_linkup0(&proc0, &thread0); thread0.td_kstack = kernelstack.pv_va; thread0.td_pcb = (struct pcb *) (thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1; Index: arm/xscale/i80321/ep80219_machdep.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/arm/xscale/i80321/ep80219_machdep.c,v retrieving revision 1.7 diff -u -r1.7 ep80219_machdep.c --- arm/xscale/i80321/ep80219_machdep.c 23 May 2007 13:20:50 -0000 1.7 +++ arm/xscale/i80321/ep80219_machdep.c 9 Jan 2008 15:36:07 -0000 @@ -426,7 +426,7 @@ undefined_handler_address = (u_int)undefinedinstruction_bounce; undefined_init(); - proc_linkup(&proc0, &thread0); + proc_linkup0(&proc0, &thread0); thread0.td_kstack = kernelstack.pv_va; thread0.td_pcb = (struct pcb *) (thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1; Index: arm/xscale/i80321/iq31244_machdep.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/arm/xscale/i80321/iq31244_machdep.c,v retrieving revision 1.28 diff -u -r1.28 iq31244_machdep.c --- arm/xscale/i80321/iq31244_machdep.c 23 May 2007 13:20:50 -0000 1.28 +++ arm/xscale/i80321/iq31244_machdep.c 9 Jan 2008 15:36:14 -0000 @@ -424,7 +424,7 @@ undefined_handler_address = (u_int)undefinedinstruction_bounce; undefined_init(); - proc_linkup(&proc0, &thread0); + proc_linkup0(&proc0, &thread0); thread0.td_kstack = kernelstack.pv_va; thread0.td_pcb = (struct pcb *) (thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1; Index: arm/xscale/i8134x/crb_machdep.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/arm/xscale/i8134x/crb_machdep.c,v retrieving revision 1.2 diff -u -r1.2 crb_machdep.c --- arm/xscale/i8134x/crb_machdep.c 22 Sep 2007 16:25:43 -0000 1.2 +++ arm/xscale/i8134x/crb_machdep.c 9 Jan 2008 15:36:14 -0000 @@ -409,7 +409,7 @@ #ifdef KSE proc_linkup(&proc0, &ksegrp0, &thread0); #else - proc_linkup(&proc0, &thread0); + proc_linkup0(&proc0, &thread0); #endif thread0.td_kstack = kernelstack.pv_va; thread0.td_pcb = (struct pcb *) Index: arm/xscale/ixp425/avila_machdep.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/arm/xscale/ixp425/avila_machdep.c,v retrieving revision 1.5 diff -u -r1.5 avila_machdep.c --- arm/xscale/ixp425/avila_machdep.c 23 May 2007 13:20:50 -0000 1.5 +++ arm/xscale/ixp425/avila_machdep.c 9 Jan 2008 15:36:14 -0000 @@ -490,7 +490,7 @@ undefined_handler_address = (u_int)undefinedinstruction_bounce; undefined_init(); - proc_linkup(&proc0, &thread0); + proc_linkup0(&proc0, &thread0); thread0.td_kstack = kernelstack.pv_va; thread0.td_pcb = (struct pcb *) (thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1; Index: compat/pecoff/imgact_pecoff.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/compat/pecoff/imgact_pecoff.c,v retrieving revision 1.40 diff -u -r1.40 imgact_pecoff.c --- compat/pecoff/imgact_pecoff.c 5 Jul 2007 07:38:17 -0000 1.40 +++ compat/pecoff/imgact_pecoff.c 9 Jan 2008 15:36:23 -0000 @@ -416,7 +416,11 @@ wp = (void *) ((char *) ap + sizeof(struct coff_aouthdr)); error = pecoff_read_from(FIRST_THREAD_IN_PROC(imgp->proc), imgp->vp, peofs + PECOFF_HDR_SIZE, (caddr_t) sh, scnsiz); - exec_new_vmspace(imgp, &pecoff_sysvec); + if (error) + return (error); + error = exec_new_vmspace(imgp, &pecoff_sysvec); + if (error) + return (error); vmspace = imgp->proc->p_vmspace; for (i = 0; i < fp->f_nscns; i++) { prot = VM_PROT_WRITE; /* XXX for relocation? */ Index: compat/svr4/imgact_svr4.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/compat/svr4/imgact_svr4.c,v retrieving revision 1.25 diff -u -r1.25 imgact_svr4.c --- compat/svr4/imgact_svr4.c 1 Apr 2005 20:00:10 -0000 1.25 +++ compat/svr4/imgact_svr4.c 9 Jan 2008 15:36:23 -0000 @@ -120,7 +120,9 @@ /* * Destroy old process VM and create a new one (with a new stack) */ - exec_new_vmspace(imgp, &svr4_sysvec); + error = exec_new_vmspace(imgp, &svr4_sysvec); + if (error) + goto fail; vmspace = imgp->proc->p_vmspace; /* Index: i386/i386/machdep.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/i386/i386/machdep.c,v retrieving revision 1.658.2.1 diff -u -r1.658.2.1 machdep.c --- i386/i386/machdep.c 19 Dec 2007 20:47:44 -0000 1.658.2.1 +++ i386/i386/machdep.c 9 Jan 2008 15:36:44 -0000 @@ -2113,7 +2113,7 @@ * This may be done better later if it gets more high level * components in it. If so just link td->td_proc here. */ - proc_linkup(&proc0, &thread0); + proc_linkup0(&proc0, &thread0); metadata_missing = 0; if (bootinfo.bi_modulep) { Index: i386/i386/pmap.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/i386/i386/pmap.c,v retrieving revision 1.594.2.4 diff -u -r1.594.2.4 pmap.c --- i386/i386/pmap.c 13 Dec 2007 19:34:23 -0000 1.594.2.4 +++ i386/i386/pmap.c 9 Jan 2008 15:36:44 -0000 @@ -1248,7 +1248,7 @@ * Initialize a preallocated and zeroed pmap structure, * such as one in a vmspace structure. */ -void +int pmap_pinit(pmap_t pmap) { vm_page_t m, ptdpg[NPGPTD]; @@ -1265,6 +1265,11 @@ if (pmap->pm_pdir == NULL) { pmap->pm_pdir = (pd_entry_t *)kmem_alloc_nofault(kernel_map, NBPTD); + + if (pmap->pm_pdir == NULL) { + PMAP_LOCK_DESTROY(pmap); + return (0); + } #ifdef PAE pmap->pm_pdpt = uma_zalloc(pdptzone, M_WAITOK | M_ZERO); KASSERT(((vm_offset_t)pmap->pm_pdpt & @@ -1318,6 +1323,8 @@ pmap->pm_active = 0; TAILQ_INIT(&pmap->pm_pvchunk); bzero(&pmap->pm_stats, sizeof pmap->pm_stats); + + return (1); } /* Index: i386/ibcs2/imgact_coff.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/i386/ibcs2/imgact_coff.c,v retrieving revision 1.67 diff -u -r1.67 imgact_coff.c --- i386/ibcs2/imgact_coff.c 31 May 2007 11:51:51 -0000 1.67 +++ i386/ibcs2/imgact_coff.c 9 Jan 2008 15:36:44 -0000 @@ -337,7 +337,9 @@ VOP_UNLOCK(imgp->vp, 0, td); - exec_new_vmspace(imgp, &ibcs2_svr3_sysvec); + error = exec_new_vmspace(imgp, &ibcs2_svr3_sysvec); + if (error) + goto fail; vmspace = imgp->proc->p_vmspace; for (i = 0; i < nscns; i++) { Index: i386/linux/imgact_linux.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/i386/linux/imgact_linux.c,v retrieving revision 1.55 diff -u -r1.55 imgact_linux.c --- i386/linux/imgact_linux.c 24 Feb 2007 16:49:24 -0000 1.55 +++ i386/linux/imgact_linux.c 9 Jan 2008 15:36:44 -0000 @@ -119,7 +119,9 @@ /* * Destroy old process VM and create a new one (with a new stack) */ - exec_new_vmspace(imgp, &linux_sysvec); + error = exec_new_vmspace(imgp, &linux_sysvec); + if (error) + goto fail; vmspace = imgp->proc->p_vmspace; /* Index: ia64/ia64/machdep.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/ia64/ia64/machdep.c,v retrieving revision 1.225 diff -u -r1.225 machdep.c --- ia64/ia64/machdep.c 4 Aug 2007 19:33:27 -0000 1.225 +++ ia64/ia64/machdep.c 9 Jan 2008 15:36:45 -0000 @@ -789,7 +789,7 @@ msgbufp = (struct msgbuf *)pmap_steal_memory(MSGBUF_SIZE); msgbufinit(msgbufp, MSGBUF_SIZE); - proc_linkup(&proc0, &thread0); + proc_linkup0(&proc0, &thread0); /* * Init mapping for kernel stack for proc 0 */ Index: ia64/ia64/pmap.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/ia64/ia64/pmap.c,v retrieving revision 1.191 diff -u -r1.191 pmap.c --- ia64/ia64/pmap.c 4 Aug 2007 19:36:14 -0000 1.191 +++ ia64/ia64/pmap.c 9 Jan 2008 15:36:45 -0000 @@ -710,7 +710,7 @@ * Initialize a preallocated and zeroed pmap structure, * such as one in a vmspace structure. */ -void +int pmap_pinit(struct pmap *pmap) { int i; @@ -721,6 +721,7 @@ pmap->pm_active = 0; TAILQ_INIT(&pmap->pm_pvlist); bzero(&pmap->pm_stats, sizeof pmap->pm_stats); + return (1); } /*************************************************** Index: kern/imgact_aout.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/kern/imgact_aout.c,v retrieving revision 1.101 diff -u -r1.101 imgact_aout.c --- kern/imgact_aout.c 16 Mar 2006 08:51:59 -0000 1.101 +++ kern/imgact_aout.c 9 Jan 2008 15:36:45 -0000 @@ -198,9 +198,11 @@ /* * Destroy old process VM and create a new one (with a new stack) */ - exec_new_vmspace(imgp, &aout_sysvec); + error = exec_new_vmspace(imgp, &aout_sysvec); vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY, td); + if (error) + return (error); /* * The vm space can be changed by exec_new_vmspace Index: kern/imgact_elf.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/kern/imgact_elf.c,v retrieving revision 1.178.2.2 diff -u -r1.178.2.2 imgact_elf.c --- kern/imgact_elf.c 6 Dec 2007 14:19:42 -0000 1.178.2.2 +++ kern/imgact_elf.c 9 Jan 2008 15:36:45 -0000 @@ -677,10 +677,12 @@ */ VOP_UNLOCK(imgp->vp, 0, td); - exec_new_vmspace(imgp, sv); + error = exec_new_vmspace(imgp, sv); imgp->proc->p_sysent = sv; vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY, td); + if (error) + return (error); vmspace = imgp->proc->p_vmspace; Index: kern/imgact_gzip.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/kern/imgact_gzip.c,v retrieving revision 1.55 diff -u -r1.55 imgact_gzip.c --- kern/imgact_gzip.c 24 Dec 2005 04:57:50 -0000 1.55 +++ kern/imgact_gzip.c 9 Jan 2008 15:36:45 -0000 @@ -239,9 +239,13 @@ /* * Destroy old process VM and create a new one (with a new stack) */ - exec_new_vmspace(gz->ip, &aout_sysvec); + error = exec_new_vmspace(gz->ip, &aout_sysvec); vn_lock(gz->ip->vp, LK_EXCLUSIVE | LK_RETRY, td); + if (error) { + gz->where = __LINE__; + return (error); + } vmspace = gz->ip->proc->p_vmspace; Index: kern/kern_exec.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/kern/kern_exec.c,v retrieving revision 1.308.2.1 diff -u -r1.308.2.1 kern_exec.c --- kern/kern_exec.c 6 Dec 2007 14:19:42 -0000 1.308.2.1 +++ kern/kern_exec.c 9 Jan 2008 15:36:45 -0000 @@ -915,7 +915,9 @@ pmap_remove_pages(vmspace_pmap(vmspace)); vm_map_remove(map, vm_map_min(map), vm_map_max(map)); } else { - vmspace_exec(p, sv->sv_minuser, sv->sv_maxuser); + error = vmspace_exec(p, sv->sv_minuser, sv->sv_maxuser); + if (error) + return (error); vmspace = p->p_vmspace; map = &vmspace->vm_map; } Index: kern/kern_fork.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/kern/kern_fork.c,v retrieving revision 1.282.2.1 diff -u -r1.282.2.1 kern_fork.c --- kern/kern_fork.c 6 Nov 2007 02:59:40 -0000 1.282.2.1 +++ kern/kern_fork.c 9 Jan 2008 15:36:45 -0000 @@ -195,6 +195,7 @@ struct filedesc_to_leader *fdtol; struct thread *td2; struct sigacts *newsigacts; + struct vmspace *vm2; int error; /* Can't copy and clear. */ @@ -218,7 +219,9 @@ PROC_UNLOCK(p1); } - vm_forkproc(td, NULL, NULL, flags); + error = vm_forkproc(td, NULL, NULL, NULL, flags); + if (error) + goto norfproc_fail; /* * Close all file descriptors. @@ -236,6 +239,7 @@ if (flags & RFFDG) fdunshare(p1, td); +norfproc_fail: if ((p1->p_flag & P_HADTHREADS) && (flags & (RFCFDG | RFFDG))) { PROC_LOCK(p1); @@ -243,11 +247,37 @@ PROC_UNLOCK(p1); } *procp = NULL; - return (0); + return (error); } /* Allocate new proc. */ newproc = uma_zalloc(proc_zone, M_WAITOK); + if (TAILQ_EMPTY(&newproc->p_threads)) { + td2 = thread_alloc(); + if (td2 == NULL) { + error = ENOMEM; + goto fail1; + } + proc_linkup(newproc, td2); + sched_newproc(newproc, td2); + } else + td2 = FIRST_THREAD_IN_PROC(newproc); + + /* Allocate and switch to an alternate kstack if specified. */ + if (pages != 0) { + if (!vm_thread_new_altkstack(td2, pages)) { + error = ENOMEM; + goto fail1; + } + } + if ((flags & RFMEM) == 0) { + vm2 = vmspace_fork(p1->p_vmspace); + if (vm2 == NULL) { + error = ENOMEM; + goto fail1; + } + } else + vm2 = NULL; #ifdef MAC mac_init_proc(newproc); #endif @@ -374,7 +404,6 @@ lastpid = trypid; p2 = newproc; - td2 = FIRST_THREAD_IN_PROC(newproc); p2->p_state = PRS_NEW; /* protect against others */ p2->p_pid = trypid; /* @@ -450,9 +479,6 @@ * Start by zeroing the section of proc that is zero-initialized, * then copy the section that is copied directly from the parent. */ - /* Allocate and switch to an alternate kstack if specified. */ - if (pages != 0) - vm_thread_new_altkstack(td2, pages); PROC_LOCK(p2); PROC_LOCK(p1); @@ -624,7 +650,7 @@ * Finish creating the child process. It will return via a different * execution path later. (ie: directly into user mode) */ - vm_forkproc(td, p2, td2, flags); + vm_forkproc(td, p2, td2, vm2, flags); if (flags == (RFFDG | RFPROC)) { PCPU_INC(cnt.v_forks); @@ -707,6 +733,7 @@ #ifdef MAC mac_destroy_proc(newproc); #endif +fail1: uma_zfree(proc_zone, newproc); pause("fork", hz / 2); return (error); Index: kern/kern_kse.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/kern/kern_kse.c,v retrieving revision 1.235 diff -u -r1.235 kern_kse.c --- kern/kern_kse.c 17 Sep 2007 05:27:20 -0000 1.235 +++ kern/kern_kse.c 9 Jan 2008 15:36:45 -0000 @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -64,7 +65,7 @@ TAILQ_HEAD_INITIALIZER(zombie_upcalls); static int thread_update_usr_ticks(struct thread *td); -static void thread_alloc_spare(struct thread *td); +static int thread_alloc_spare(struct thread *td); static struct thread *thread_schedule_upcall(struct thread *td, struct kse_upcall *ku); static struct kse_upcall *upcall_alloc(void); @@ -648,6 +649,16 @@ PROC_UNLOCK(p); } + /* + * For the first call this may not have been set. + * Of course nor may it actually be needed. + * thread_schedule_upcall() will look for it. + */ + if (td->td_standin == NULL) { + if (!thread_alloc_spare(td)) + return (ENOMEM); + } + /* * Even bound LWPs get a mailbox and an upcall to hold it. * XXX This should change. @@ -657,13 +668,6 @@ newku->ku_func = mbx.km_func; bcopy(&mbx.km_stack, &newku->ku_stack, sizeof(stack_t)); - /* - * For the first call this may not have been set. - * Of course nor may it actually be needed. - * thread_schedule_upcall() will look for it. - */ - if (td->td_standin == NULL) - thread_alloc_spare(td); PROC_LOCK(p); PROC_SLOCK(p); /* @@ -989,20 +993,23 @@ * XXX BUG.. we need to get the cr ref after the thread has * checked and chenged its own, not 6 months before... */ -void +int thread_alloc_spare(struct thread *td) { struct thread *spare; if (td->td_standin) - return; + return (1); spare = thread_alloc(); + if (spare == NULL) + return (0); td->td_standin = spare; bzero(&spare->td_startzero, __rangeof(struct thread, td_startzero, td_endzero)); spare->td_proc = td->td_proc; spare->td_ucred = crhold(td->td_ucred); spare->td_flags = TDF_INMEM; + return (1); } /* @@ -1170,8 +1177,18 @@ KASSERT(ku->ku_owner == td, ("wrong owner")); KASSERT(!TD_CAN_UNBIND(td), ("can unbind")); - if (td->td_standin == NULL) - thread_alloc_spare(td); + if (td->td_standin == NULL) { + if (!thread_alloc_spare(td)) { + PROC_LOCK(p); + if (kern_logsigexit) + log(LOG_INFO, + "pid %d (%s), uid %d: thread_alloc_spare failed\n", + p->p_pid, p->p_comm, + td->td_ucred ? td->td_ucred->cr_uid : -1); + sigexit(td, SIGSEGV); /* XXX ? */ + /* panic("thread_user_enter: thread_alloc_spare failed"); */ + } + } ku->ku_mflags = fuword32((void *)&ku->ku_mailbox->km_flags); tmbx = (void *)fuword((void *)&ku->ku_mailbox->km_curthread); if ((tmbx == NULL) || (tmbx == (void *)-1L) || @@ -1385,7 +1402,7 @@ * for when we re-enter the kernel. */ if (td->td_standin == NULL) - thread_alloc_spare(td); + thread_alloc_spare(td); /* XXX care of failure ? */ } ku->ku_mflags = 0; Index: kern/kern_proc.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/kern/kern_proc.c,v retrieving revision 1.252.2.2 diff -u -r1.252.2.2 kern_proc.c --- kern/kern_proc.c 14 Dec 2007 13:41:08 -0000 1.252.2.2 +++ kern/kern_proc.c 9 Jan 2008 15:36:45 -0000 @@ -147,20 +147,21 @@ /* INVARIANTS checks go here */ p = (struct proc *)mem; td = FIRST_THREAD_IN_PROC(p); + if (td != NULL) { #ifdef INVARIANTS - KASSERT((p->p_numthreads == 1), - ("bad number of threads in exiting process")); - KASSERT((td != NULL), ("proc_dtor: bad thread pointer")); - KASSERT(STAILQ_EMPTY(&p->p_ktr), ("proc_dtor: non-empty p_ktr")); + KASSERT((p->p_numthreads == 1), + ("bad number of threads in exiting process")); + KASSERT(STAILQ_EMPTY(&p->p_ktr), ("proc_dtor: non-empty p_ktr")); #endif - /* Dispose of an alternate kstack, if it exists. - * XXX What if there are more than one thread in the proc? - * The first thread in the proc is special and not - * freed, so you gotta do this here. - */ - if (((p->p_flag & P_KTHREAD) != 0) && (td->td_altkstack != 0)) - vm_thread_dispose_altkstack(td); + /* Dispose of an alternate kstack, if it exists. + * XXX What if there are more than one thread in the proc? + * The first thread in the proc is special and not + * freed, so you gotta do this here. + */ + if (((p->p_flag & P_KTHREAD) != 0) && (td->td_altkstack != 0)) + vm_thread_dispose_altkstack(td); + } EVENTHANDLER_INVOKE(process_dtor, p); if (p->p_ksi != NULL) KASSERT(! KSI_ONQ(p->p_ksi), ("SIGCHLD queue")); @@ -173,18 +174,15 @@ proc_init(void *mem, int size, int flags) { struct proc *p; - struct thread *td; p = (struct proc *)mem; p->p_sched = (struct p_sched *)&p[1]; - td = thread_alloc(); bzero(&p->p_mtx, sizeof(struct mtx)); mtx_init(&p->p_mtx, "process lock", NULL, MTX_DEF | MTX_DUPOK); mtx_init(&p->p_slock, "process slock", NULL, MTX_SPIN | MTX_RECURSE); + TAILQ_INIT(&p->p_threads); /* all threads in proc */ EVENTHANDLER_INVOKE(process_init, p); p->p_stats = pstats_alloc(); - proc_linkup(p, td); - sched_newproc(p, td); return (0); } Index: kern/kern_sig.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/kern/kern_sig.c,v retrieving revision 1.349.2.1 diff -u -r1.349.2.1 kern_sig.c --- kern/kern_sig.c 1 Nov 2007 19:04:13 -0000 1.349.2.1 +++ kern/kern_sig.c 9 Jan 2008 15:36:45 -0000 @@ -102,7 +102,7 @@ struct filterops sig_filtops = { 0, filt_sigattach, filt_sigdetach, filt_signal }; -static int kern_logsigexit = 1; +int kern_logsigexit = 1; SYSCTL_INT(_kern, KERN_LOGSIGEXIT, logsigexit, CTLFLAG_RW, &kern_logsigexit, 0, "Log processes quitting on abnormal signals to syslog(3)"); Index: kern/kern_thr.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/kern/kern_thr.c,v retrieving revision 1.62 diff -u -r1.62 kern_thr.c --- kern/kern_thr.c 16 Aug 2007 05:26:41 -0000 1.62 +++ kern/kern_thr.c 9 Jan 2008 15:36:45 -0000 @@ -175,6 +175,8 @@ /* Initialize our td */ newtd = thread_alloc(); + if (newtd == NULL) + return (ENOMEM); /* * Try the copyout as soon as we allocate the td so we don't Index: kern/kern_thread.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/kern/kern_thread.c,v retrieving revision 1.255.2.1 diff -u -r1.255.2.1 kern_thread.c --- kern/kern_thread.c 14 Dec 2007 13:41:09 -0000 1.255.2.1 +++ kern/kern_thread.c 9 Jan 2008 15:36:49 -0000 @@ -183,14 +183,13 @@ td = (struct thread *)mem; - vm_thread_new(td, 0); - cpu_thread_setup(td); td->td_sleepqueue = sleepq_alloc(); td->td_turnstile = turnstile_alloc(); EVENTHANDLER_INVOKE(thread_init, td); td->td_sched = (struct td_sched *)&td[1]; sched_newthread(td); umtx_thread_init(td); + td->td_kstack = 0; return (0); } @@ -207,7 +206,6 @@ turnstile_free(td->td_turnstile); sleepq_free(td->td_sleepqueue); umtx_thread_fini(td); - vm_thread_dispose(td); } /* @@ -219,10 +217,16 @@ * proc_init() */ void +proc_linkup0(struct proc *p, struct thread *td) +{ + TAILQ_INIT(&p->p_threads); /* all threads in proc */ + proc_linkup(p, td); +} + +void proc_linkup(struct proc *p, struct thread *td) { - TAILQ_INIT(&p->p_threads); /* all threads in proc */ #ifdef KSE TAILQ_INIT(&p->p_upcalls); /* upcall list */ #endif @@ -314,9 +318,18 @@ struct thread * thread_alloc(void) { + struct thread *td; thread_reap(); /* check if any zombies to get */ - return (uma_zalloc(thread_zone, M_WAITOK)); + + td = (struct thread *)uma_zalloc(thread_zone, M_WAITOK); + KASSERT(td->td_kstack == 0, ("thread_alloc got thread with kstack")); + if (!vm_thread_new(td, 0)) { + uma_zfree(thread_zone, td); + return (NULL); + } + cpu_thread_setup(td); + return (td); } @@ -328,6 +341,10 @@ { cpu_thread_clean(td); + if (td->td_altkstack != 0) + vm_thread_dispose_altkstack(td); + if (td->td_kstack != 0) + vm_thread_dispose(td); uma_zfree(thread_zone, td); } Index: pc98/pc98/machdep.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/pc98/pc98/machdep.c,v retrieving revision 1.396 diff -u -r1.396 machdep.c --- pc98/pc98/machdep.c 6 Jun 2007 13:04:15 -0000 1.396 +++ pc98/pc98/machdep.c 9 Jan 2008 15:37:19 -0000 @@ -1917,7 +1917,7 @@ * This may be done better later if it gets more high level * components in it. If so just link td->td_proc here. */ - proc_linkup(&proc0, &thread0); + proc_linkup0(&proc0, &thread0); /* * Initialize DMAC Index: powerpc/powerpc/machdep.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/powerpc/powerpc/Attic/machdep.c,v retrieving revision 1.103.2.1 diff -u -r1.103.2.1 machdep.c --- powerpc/powerpc/machdep.c 14 Nov 2007 16:41:31 -0000 1.103.2.1 +++ powerpc/powerpc/machdep.c 9 Jan 2008 15:37:22 -0000 @@ -292,7 +292,7 @@ /* * Start initializing proc0 and thread0. */ - proc_linkup(&proc0, &thread0); + proc_linkup0(&proc0, &thread0); thread0.td_frame = &frame0; /* Index: powerpc/powerpc/pmap_dispatch.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/powerpc/powerpc/pmap_dispatch.c,v retrieving revision 1.9 diff -u -r1.9 pmap_dispatch.c --- powerpc/powerpc/pmap_dispatch.c 5 Dec 2006 04:01:52 -0000 1.9 +++ powerpc/powerpc/pmap_dispatch.c 9 Jan 2008 15:37:22 -0000 @@ -193,10 +193,11 @@ MMU_PAGE_INIT(mmu_obj, m); } -void +int pmap_pinit(pmap_t pmap) { MMU_PINIT(mmu_obj, pmap); + return (1); } void Index: sparc64/sparc64/machdep.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/sparc64/sparc64/machdep.c,v retrieving revision 1.138 diff -u -r1.138 machdep.c --- sparc64/sparc64/machdep.c 16 Jun 2007 23:26:00 -0000 1.138 +++ sparc64/sparc64/machdep.c 9 Jan 2008 15:37:23 -0000 @@ -399,7 +399,7 @@ /* * Initialize proc0 stuff (p_contested needs to be done early). */ - proc_linkup(&proc0, &thread0); + proc_linkup0(&proc0, &thread0); proc0.p_md.md_sigtramp = NULL; proc0.p_md.md_utrap = NULL; thread0.td_kstack = kstack0; Index: sparc64/sparc64/pmap.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/sparc64/sparc64/pmap.c,v retrieving revision 1.166 diff -u -r1.166 pmap.c --- sparc64/sparc64/pmap.c 7 Oct 2007 18:03:03 -0000 1.166 +++ sparc64/sparc64/pmap.c 9 Jan 2008 15:37:24 -0000 @@ -1006,7 +1006,7 @@ * Initialize a preallocated and zeroed pmap structure, such as one in a * vmspace structure. */ -void +int pmap_pinit(pmap_t pm) { vm_page_t ma[TSB_PAGES]; @@ -1021,6 +1021,10 @@ if (pm->pm_tsb == NULL) { pm->pm_tsb = (struct tte *)kmem_alloc_nofault(kernel_map, TSB_BSIZE); + if (pm->pm_tsb == NULL) { + PMAP_LOCK_DESTROY(pm); + return (0); + } } /* @@ -1044,6 +1048,7 @@ pm->pm_context[i] = -1; pm->pm_active = 0; bzero(&pm->pm_stats, sizeof(pm->pm_stats)); + return (1); } /* Index: sun4v/sun4v/machdep.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/sun4v/sun4v/machdep.c,v retrieving revision 1.15 diff -u -r1.15 machdep.c --- sun4v/sun4v/machdep.c 16 Jun 2007 22:30:38 -0000 1.15 +++ sun4v/sun4v/machdep.c 9 Jan 2008 15:37:24 -0000 @@ -364,7 +364,7 @@ * Initialize proc0 stuff (p_contested needs to be done early). */ - proc_linkup(&proc0, &thread0); + proc_linkup0(&proc0, &thread0); proc0.p_md.md_sigtramp = NULL; proc0.p_md.md_utrap = NULL; frame0.tf_tstate = TSTATE_IE | TSTATE_PEF | TSTATE_PRIV; Index: sun4v/sun4v/pmap.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/sun4v/sun4v/pmap.c,v retrieving revision 1.39 diff -u -r1.39 pmap.c --- sun4v/sun4v/pmap.c 16 Jun 2007 04:57:05 -0000 1.39 +++ sun4v/sun4v/pmap.c 9 Jan 2008 15:37:24 -0000 @@ -1703,7 +1703,7 @@ * Initialize a preallocated and zeroed pmap structure, such as one in a * vmspace structure. */ -void +int pmap_pinit(pmap_t pmap) { int i; @@ -1723,6 +1723,7 @@ TAILQ_INIT(&pmap->pm_pvlist); PMAP_LOCK_INIT(pmap); bzero(&pmap->pm_stats, sizeof pmap->pm_stats); + return (1); } /* Index: sys/proc.h =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/sys/proc.h,v retrieving revision 1.491.2.1 diff -u -r1.491.2.1 proc.h --- sys/proc.h 6 Dec 2007 14:19:43 -0000 1.491.2.1 +++ sys/proc.h 9 Jan 2008 15:37:24 -0000 @@ -840,6 +840,7 @@ void pargs_free(struct pargs *pa); void pargs_hold(struct pargs *pa); void procinit(void); +void proc_linkup0(struct proc *p, struct thread *td); void proc_linkup(struct proc *p, struct thread *td); void proc_reparent(struct proc *child, struct proc *newparent); struct pstats *pstats_alloc(void); Index: sys/signalvar.h =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/sys/signalvar.h,v retrieving revision 1.77 diff -u -r1.77 signalvar.h --- sys/signalvar.h 5 Oct 2006 01:56:11 -0000 1.77 +++ sys/signalvar.h 9 Jan 2008 15:37:25 -0000 @@ -299,6 +299,7 @@ extern int sugid_coredump; /* Sysctl variable kern.sugid_coredump */ extern struct mtx sigio_lock; +extern int kern_logsigexit; /* Sysctl variable kern.logsigexit */ /* * Lock the pointers for a sigio object in the underlying objects of Index: vm/pmap.h =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/vm/pmap.h,v retrieving revision 1.79 diff -u -r1.79 pmap.h --- vm/pmap.h 1 Aug 2006 19:06:05 -0000 1.79 +++ vm/pmap.h 9 Jan 2008 15:37:25 -0000 @@ -114,7 +114,7 @@ vm_object_t object, vm_pindex_t pindex, vm_size_t size); boolean_t pmap_page_exists_quick(pmap_t pmap, vm_page_t m); void pmap_page_init(vm_page_t m); -void pmap_pinit(pmap_t); +int pmap_pinit(pmap_t); void pmap_pinit0(pmap_t); void pmap_protect(pmap_t, vm_offset_t, vm_offset_t, vm_prot_t); void pmap_qenter(vm_offset_t, vm_page_t *, int); Index: vm/vm_extern.h =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/vm/vm_extern.h,v retrieving revision 1.78 diff -u -r1.78 vm_extern.h --- vm/vm_extern.h 29 May 2006 21:28:56 -0000 1.78 +++ vm/vm_extern.h 9 Jan 2008 15:37:25 -0000 @@ -70,14 +70,14 @@ void vm_fault_copy_entry(vm_map_t, vm_map_t, vm_map_entry_t, vm_map_entry_t); void vm_fault_unwire(vm_map_t, vm_offset_t, vm_offset_t, boolean_t); int vm_fault_wire(vm_map_t, vm_offset_t, vm_offset_t, boolean_t, boolean_t); -void vm_forkproc(struct thread *, struct proc *, struct thread *, int); +int vm_forkproc(struct thread *, struct proc *, struct thread *, struct vmspace *, int); void vm_waitproc(struct proc *); int vm_mmap(vm_map_t, vm_offset_t *, vm_size_t, vm_prot_t, vm_prot_t, int, objtype_t, void *, vm_ooffset_t); void vm_set_page_size(void); struct vmspace *vmspace_alloc(vm_offset_t, vm_offset_t); struct vmspace *vmspace_fork(struct vmspace *); -void vmspace_exec(struct proc *, vm_offset_t, vm_offset_t); -void vmspace_unshare(struct proc *); +int vmspace_exec(struct proc *, vm_offset_t, vm_offset_t); +int vmspace_unshare(struct proc *); void vmspace_exit(struct thread *); struct vmspace *vmspace_acquire_ref(struct proc *); void vmspace_free(struct vmspace *); @@ -92,8 +92,8 @@ void vm_imgact_unmap_page(struct sf_buf *sf); void vm_thread_dispose(struct thread *td); void vm_thread_dispose_altkstack(struct thread *td); -void vm_thread_new(struct thread *td, int pages); -void vm_thread_new_altkstack(struct thread *td, int pages); +int vm_thread_new(struct thread *td, int pages); +int vm_thread_new_altkstack(struct thread *td, int pages); void vm_thread_swapin(struct thread *td); void vm_thread_swapout(struct thread *td); #endif /* _KERNEL */ Index: vm/vm_glue.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/vm/vm_glue.c,v retrieving revision 1.225 diff -u -r1.225 vm_glue.c --- vm/vm_glue.c 21 Sep 2007 05:07:07 -0000 1.225 +++ vm/vm_glue.c 9 Jan 2008 15:37:25 -0000 @@ -321,7 +321,7 @@ * This routine directly affects the fork perf for a process and * create performance for a thread. */ -void +int vm_thread_new(struct thread *td, int pages) { vm_object_t ksobj; @@ -338,18 +338,22 @@ * Allocate an object for the kstack. */ ksobj = vm_object_allocate(OBJT_DEFAULT, pages); - td->td_kstack_obj = ksobj; /* * Get a kernel virtual address for this thread's kstack. */ ks = kmem_alloc_nofault(kernel_map, (pages + KSTACK_GUARD_PAGES) * PAGE_SIZE); - if (ks == 0) - panic("vm_thread_new: kstack allocation failed"); + if (ks == 0) { + printf("vm_thread_new: kstack allocation failed\n"); + vm_object_deallocate(ksobj); + return (0); + } + if (KSTACK_GUARD_PAGES != 0) { pmap_qremove(ks, KSTACK_GUARD_PAGES); ks += KSTACK_GUARD_PAGES * PAGE_SIZE; } + td->td_kstack_obj = ksobj; td->td_kstack = ks; /* * Knowing the number of pages allocated is useful when you @@ -372,6 +376,7 @@ } VM_OBJECT_UNLOCK(ksobj); pmap_qenter(ks, ma, pages); + return (1); } /* @@ -403,6 +408,7 @@ vm_object_deallocate(ksobj); kmem_free(kernel_map, ks - (KSTACK_GUARD_PAGES * PAGE_SIZE), (pages + KSTACK_GUARD_PAGES) * PAGE_SIZE); + td->td_kstack = 0; } /* @@ -468,7 +474,7 @@ /* * Set up a variable-sized alternate kstack. */ -void +int vm_thread_new_altkstack(struct thread *td, int pages) { @@ -476,7 +482,7 @@ td->td_altkstack_obj = td->td_kstack_obj; td->td_altkstack_pages = td->td_kstack_pages; - vm_thread_new(td, pages); + return (vm_thread_new(td, pages)); } /* @@ -504,14 +510,16 @@ * ready to run. The new process is set up so that it returns directly * to user mode to avoid stack copying and relocation problems. */ -void -vm_forkproc(td, p2, td2, flags) +int +vm_forkproc(td, p2, td2, vm2, flags) struct thread *td; struct proc *p2; struct thread *td2; + struct vmspace *vm2; int flags; { struct proc *p1 = td->td_proc; + int error; if ((flags & RFPROC) == 0) { /* @@ -521,11 +529,13 @@ */ if ((flags & RFMEM) == 0) { if (p1->p_vmspace->vm_refcnt > 1) { - vmspace_unshare(p1); + error = vmspace_unshare(p1); + if (error) + return (error); } } cpu_fork(td, p2, td2, flags); - return; + return (0); } if (flags & RFMEM) { @@ -538,7 +548,7 @@ } if ((flags & RFMEM) == 0) { - p2->p_vmspace = vmspace_fork(p1->p_vmspace); + p2->p_vmspace = vm2; if (p1->p_vmspace->vm_shm) shmfork(p1, p2); } @@ -548,6 +558,7 @@ * and make the child ready to run. */ cpu_fork(td, p2, td2, flags); + return (0); } /* Index: vm/vm_map.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/vm/vm_map.c,v retrieving revision 1.388.2.1 diff -u -r1.388.2.1 vm_map.c --- vm/vm_map.c 31 Oct 2007 02:31:51 -0000 1.388.2.1 +++ vm/vm_map.c 9 Jan 2008 15:37:25 -0000 @@ -197,7 +197,6 @@ struct vmspace *vm; vm = (struct vmspace *)mem; - pmap_release(vmspace_pmap(vm)); vm_map_zfini(&vm->vm_map, sizeof(vm->vm_map)); } @@ -208,8 +207,8 @@ vm = (struct vmspace *)mem; + vm->vm_map.pmap = NULL; (void)vm_map_zinit(&vm->vm_map, sizeof(vm->vm_map), flags); - pmap_pinit(vmspace_pmap(vm)); return (0); } @@ -272,6 +271,10 @@ struct vmspace *vm; vm = uma_zalloc(vmspace_zone, M_WAITOK); + if (vm->vm_map.pmap == NULL && !pmap_pinit(vmspace_pmap(vm))) { + uma_zfree(vmspace_zone, vm); + return (NULL); + } CTR1(KTR_VM, "vmspace_alloc: %p", vm); _vm_map_init(&vm->vm_map, min, max); vm->vm_map.pmap = vmspace_pmap(vm); /* XXX */ @@ -321,6 +324,12 @@ (void)vm_map_remove(&vm->vm_map, vm->vm_map.min_offset, vm->vm_map.max_offset); + /* + * XXX Comment out the pmap_release call for now. The + * vmspace_zone is marked as UMA_ZONE_NOFREE, and bugs cause + * pmap.resident_count to be != 0 on exit sometimes. + */ +/* pmap_release(vmspace_pmap(vm)); */ uma_zfree(vmspace_zone, vm); } @@ -2584,6 +2593,8 @@ vm_map_lock(old_map); vm2 = vmspace_alloc(old_map->min_offset, old_map->max_offset); + if (vm2 == NULL) + goto unlock_and_return; vm2->vm_taddr = vm1->vm_taddr; vm2->vm_daddr = vm1->vm_daddr; vm2->vm_maxsaddr = vm1->vm_maxsaddr; @@ -2675,7 +2686,7 @@ } old_entry = old_entry->next; } - +unlock_and_return: vm_map_unlock(old_map); return (vm2); @@ -3003,13 +3014,15 @@ * Unshare the specified VM space for exec. If other processes are * mapped to it, then create a new one. The new vmspace is null. */ -void +int vmspace_exec(struct proc *p, vm_offset_t minuser, vm_offset_t maxuser) { struct vmspace *oldvmspace = p->p_vmspace; struct vmspace *newvmspace; newvmspace = vmspace_alloc(minuser, maxuser); + if (newvmspace == NULL) + return (ENOMEM); newvmspace->vm_swrss = oldvmspace->vm_swrss; /* * This code is written like this for prototype purposes. The @@ -3024,27 +3037,31 @@ if (p == curthread->td_proc) /* XXXKSE ? */ pmap_activate(curthread); vmspace_free(oldvmspace); + return (0); } /* * Unshare the specified VM space for forcing COW. This * is called by rfork, for the (RFMEM|RFPROC) == 0 case. */ -void +int vmspace_unshare(struct proc *p) { struct vmspace *oldvmspace = p->p_vmspace; struct vmspace *newvmspace; if (oldvmspace->vm_refcnt == 1) - return; + return (0); newvmspace = vmspace_fork(oldvmspace); + if (newvmspace == NULL) + return (ENOMEM); PROC_VMSPACE_LOCK(p); p->p_vmspace = newvmspace; PROC_VMSPACE_UNLOCK(p); if (p == curthread->td_proc) /* XXXKSE ? */ pmap_activate(curthread); vmspace_free(oldvmspace); + return (0); } /*