summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_proc.c
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2007-11-05 11:36:16 +0000
committerkib <kib@FreeBSD.org>2007-11-05 11:36:16 +0000
commit9ae733819b7cdf0eef51ba1b18d39feb136a9dbf (patch)
treecccec36134d2cab5ce1eabb67dcaab5981e9beb0 /sys/kern/kern_proc.c
parentf3f033b9b90ea07350fbe7483af3d9636cb31d1d (diff)
downloadFreeBSD-src-9ae733819b7cdf0eef51ba1b18d39feb136a9dbf.zip
FreeBSD-src-9ae733819b7cdf0eef51ba1b18d39feb136a9dbf.tar.gz
Fix for the panic("vm_thread_new: kstack allocation failed") and
silent NULL pointer dereference in the i386 and sparc64 pmap_pinit() when the kmem_alloc_nofault() failed to allocate address space. Both functions now return error instead of panicing or dereferencing NULL. As consequence, vmspace_exec() and vmspace_unshare() returns the errno int. struct vmspace arg was added to vm_forkproc() to avoid dealing with failed allocation when most of the fork1() job is already done. The kernel stack for the thread is now set up in the thread_alloc(), that itself may return NULL. Also, allocation of the first process thread is performed in the fork1() to properly deal with stack allocation failure. proc_linkup() is separated into proc_linkup() called from fork1(), and proc_linkup0(), that is used to set up the kernel process (was known as swapper). In collaboration with: Peter Holm Reviewed by: jhb
Diffstat (limited to 'sys/kern/kern_proc.c')
-rw-r--r--sys/kern/kern_proc.c28
1 files changed, 13 insertions, 15 deletions
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
index f75112f..71e2b10 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -145,20 +145,21 @@ proc_dtor(void *mem, int size, void *arg)
/* 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);
+ }
if (p->p_ksi != NULL)
KASSERT(! KSI_ONQ(p->p_ksi), ("SIGCHLD queue"));
}
@@ -170,17 +171,14 @@ static int
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 */
p->p_stats = pstats_alloc();
- proc_linkup(p, td);
- sched_newproc(p, td);
return (0);
}
OpenPOWER on IntegriCloud