DragonFly kernel List (threaded) for 2007-02
DragonFly BSD
DragonFly kernel List (threaded) for 2007-02
[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]

[PATCH] 1:1 Userland threading stage 2.11/4:


From: "Simon 'corecode' Schubert" <corecode@xxxxxxxxxxxx>
Date: Sat, 03 Feb 2007 11:55:30 +0100

Move signals into lwps, take p_lwp out of proc.

Originally-Submitted-by:  David Xu <davidxu@freebsd.org>
---

This time as attachment, by request of tom.

This is an updated and polished version. If no objections come, I'd like to commit this in 5 hours.

cheers
 simon

bin/ps/keyword.c                           |    2 +-
bin/ps/print.c                             |    4 +-
sys/cpu/i386/include/cpu.h                 |    2 +-
sys/ddb/db_ps.c                            |   12 ++-
sys/dev/misc/spigot/spigot.c               |    4 +-
sys/dev/misc/syscons/syscons.c             |    4 +-
sys/emulation/43bsd/43bsd_signal.c         |   26 +++---
sys/emulation/linux/i386/linux_machdep.c   |   14 ++--
sys/emulation/linux/i386/linux_ptrace.c    |   16 ++--
sys/emulation/linux/i386/linux_sysvec.c    |   62 +++++++-------
sys/emulation/linux/linux_signal.c         |   16 ++--
sys/emulation/posix4/ksched.c              |   28 +++---
sys/emulation/posix4/p1003_1b.c            |   19 +++-
sys/emulation/posix4/posix4.h              |   11 ++-
sys/kern/imgact_elf.c                      |    9 ++-
sys/kern/init_main.c                       |   25 +++---
sys/kern/kern_checkpoint.c                 |   12 ++-
sys/kern/kern_descrip.c                    |    6 +-
sys/kern/kern_event.c                      |    2 +-
sys/kern/kern_exec.c                       |   11 ++-
sys/kern/kern_exit.c                       |   16 ++--
sys/kern/kern_fork.c                       |   19 ++---
sys/kern/kern_kinfo.c                      |    4 +-
sys/kern/kern_memio.c                      |    2 +-
sys/kern/kern_proc.c                       |    2 +
sys/kern/kern_resource.c                   |   11 ++-
sys/kern/kern_sig.c                        |  123 +++++++++++++++-------------
sys/kern/kern_synch.c                      |   51 +++++++----
sys/kern/kern_threads.c                    |   11 ++-
sys/kern/kern_time.c                       |    2 +-
sys/kern/kern_usched.c                     |    6 +-
sys/kern/lwkt_caps.c                       |    7 +--
sys/kern/lwkt_msgport.c                    |    2 +-
sys/kern/sys_generic.c                     |   11 ++-
sys/kern/sys_process.c                     |   17 ++--
sys/kern/tty.c                             |   51 ++++++++---
sys/kern/tty_pty.c                         |    6 +-
sys/kern/vfs_aio.c                         |   10 ++-
sys/netproto/ncp/ncp_ncp.c                 |    6 +-
sys/netproto/smb/smb_iod.c                 |    3 +-
sys/netproto/smb/smb_subr.c                |   13 ++-
sys/platform/pc32/i386/machdep.c           |   23 +++---
sys/platform/pc32/i386/math_emulate.c      |    2 +-
sys/platform/pc32/i386/pmap.c              |   21 +++--
sys/platform/pc32/i386/procfs_machdep.c    |   48 +++++++++--
sys/platform/pc32/i386/sys_machdep.c       |    4 +-
sys/platform/pc32/i386/trap.c              |    6 +-
sys/platform/pc32/i386/vm_machdep.c        |    6 +-
sys/platform/pc32/isa/npx.c                |    4 +-
sys/platform/vkernel/i386/cpu_regs.c       |   16 ++--
sys/platform/vkernel/i386/npx.c            |    2 +-
sys/platform/vkernel/i386/procfs_machdep.c |   42 ++++++++--
sys/platform/vkernel/i386/trap.c           |   10 ++-
sys/platform/vkernel/platform/init.c       |    4 +-
sys/platform/vkernel/platform/pmap.c       |   21 +++--
sys/sys/caps.h                             |    2 +-
sys/sys/kinfo.h                            |    2 +-
sys/sys/proc.h                             |   32 +++-----
sys/sys/ptrace.h                           |    2 +-
sys/sys/reg.h                              |    2 +-
sys/sys/signalvar.h                        |   35 ++++----
sys/vfs/mfs/mfs_vfsops.c                   |    2 +-
sys/vfs/nfs/nfs_socket.c                   |    9 ++-
sys/vfs/procfs/procfs_status.c             |    5 +-
sys/vm/vm_glue.c                           |   16 +++-
sys/vm/vm_meter.c                          |   10 ++-
sys/vm/vm_pageout.c                        |    3 +-
usr.bin/systat/pigs.c                      |    2 +-
usr.bin/top/machine.c                      |    4 +-
69 files changed, 601 insertions(+), 392 deletions(-)
diff --git a/bin/ps/keyword.c b/bin/ps/keyword.c
index 8f8c267..70f0630 100644
--- a/bin/ps/keyword.c
+++ b/bin/ps/keyword.c
@@ -151,7 +151,7 @@ static const VAR var[] = {
 	{"ppid", "PPID", NULL, 0, pvar, NULL, PIDLEN, POFF(ppid), UINT, PIDFMT,
 		NULL},
 	{"pri", "PRI", NULL, 0, pri, NULL, 3, 0, 0, NULL, NULL},
-	{"re", "RE", NULL, 0, lpvar, NULL, 3, LPOFF(swtime), UINT, "d", NULL},
+	{"re", "RE", NULL, 0, lpvar, NULL, 3, POFF(swtime), UINT, "d", NULL},
 	{"rgid", "RGID", NULL, 0, pvar, NULL, UIDLEN, POFF(rgid),
 		UINT, UIDFMT, NULL},
 #if 0
diff --git a/bin/ps/print.c b/bin/ps/print.c
index 5f86b5e..49ce4f7 100644
--- a/bin/ps/print.c
+++ b/bin/ps/print.c
@@ -466,12 +466,12 @@ getpcpu(const KINFO *k)
 #define	fxtofl(fixpt)	((double)(fixpt) / fscale)
 
 	/* XXX - I don't like this */
-	if (KI_LWP(k, swtime) == 0 || (KI_PROC(k, flags) & P_SWAPPEDOUT))
+	if (KI_PROC(k, swtime) == 0 || (KI_PROC(k, flags) & P_SWAPPEDOUT))
 		return (0.0);
 	if (rawcpu)
 		return (100.0 * fxtofl(KI_LWP(k, pctcpu)));
 	return (100.0 * fxtofl(KI_LWP(k, pctcpu)) /
-		(1.0 - exp(KI_LWP(k, swtime) * log(fxtofl(ccpu)))));
+		(1.0 - exp(KI_PROC(k, swtime) * log(fxtofl(ccpu)))));
 }
 
 void
diff --git a/sys/cpu/i386/include/cpu.h b/sys/cpu/i386/include/cpu.h
index 1490db7..209af78 100644
--- a/sys/cpu/i386/include/cpu.h
+++ b/sys/cpu/i386/include/cpu.h
@@ -62,7 +62,7 @@
 
 #define	cpu_exec(p)	/* nothing */
 #define cpu_swapin(p)	/* nothing */
-#define cpu_setstack(p, ap)		((p)->p_md.md_regs[SP] = (ap))
+#define cpu_setstack(lp, ap)		((lp)->lwp_md.md_regs[SP] = (ap))
 
 #define CLKF_INTR(framep)	(mycpu->gd_intr_nesting_level > 1 || (curthread->td_flags & TDF_INTTHREAD))
 #define	CLKF_PC(framep)		((framep)->if_eip)
diff --git a/sys/ddb/db_ps.c b/sys/ddb/db_ps.c
index c3727ef..a3ce78c 100644
--- a/sys/ddb/db_ps.c
+++ b/sys/ddb/db_ps.c
@@ -49,6 +49,7 @@ db_ps(db_expr_t dummy1, boolean_t dummy2, db_expr_t dummy3, char *dummy4)
 	int cpuidx;
 	int nl = 0;
 	volatile struct proc *p, *pp;
+	struct lwp *lp;
 
 	np = nprocs;
 
@@ -74,16 +75,21 @@ db_ps(db_expr_t dummy1, boolean_t dummy2, db_expr_t dummy3, char *dummy4)
 		if (pp == NULL)
 			pp = p;
 
-		db_printf("%5d %8p %4d %5d %5d %06x  %d",
+		/* XXX lwp */
+		lp = FIRST_LWP_IN_PROC(p);
+		db_printf("%5d %8p %8p %4d %5d %5d %06x  %d",
 		    p->p_pid, (volatile void *)p,
+		    (void *)lp->lwp_thread->td_pcb,
 		    p->p_ucred ? p->p_ucred->cr_ruid : 0, pp->p_pid,
 		    p->p_pgrp ? p->p_pgrp->pg_id : 0, p->p_flag, p->p_stat);
-		if (p->p_wchan) {
-			db_printf("  %6s %8p", p->p_wmesg, (void *)p->p_wchan);
+		if (lp->lwp_wchan) {
+			db_printf("  %6s %8p", lp->lwp_wmesg,
+			    (void *)lp->lwp_wchan);
 		} else {
 			db_printf("                 ");
 		}
 		db_printf(" %s\n", p->p_comm ? p->p_comm : "");
+		db_dump_td_tokens(lp->lwp_thread);
 
 		p = p->p_list.le_next;
 		if (p == NULL && np > 0)
diff --git a/sys/dev/misc/spigot/spigot.c b/sys/dev/misc/spigot/spigot.c
index 527907f..5779f6a 100644
--- a/sys/dev/misc/spigot/spigot.c
+++ b/sys/dev/misc/spigot/spigot.c
@@ -237,10 +237,10 @@ spigot_ioctl(struct dev_ioctl_args *ap)
 		if (securelevel > 0)
 			return EPERM;
 #endif
-		curproc->p_md.md_regs->tf_eflags |= PSL_IOPL;
+		curthread->td_lwp->lwp_md.md_regs->tf_eflags |= PSL_IOPL;
 		break;
 	case	SPIGOT_IOPL_OFF: /* deny access to the IO PAGE */
-		curproc->p_md.md_regs->tf_eflags &= ~PSL_IOPL;
+		curthread->td_lwp->lwp_md.md_regs->tf_eflags &= ~PSL_IOPL;
 		break;
 	case	SPIGOT_GET_INFO:
 		info = (struct spigot_info *)data;
diff --git a/sys/dev/misc/syscons/syscons.c b/sys/dev/misc/syscons/syscons.c
index 845db1c..409b056 100644
--- a/sys/dev/misc/syscons/syscons.c
+++ b/sys/dev/misc/syscons/syscons.c
@@ -996,11 +996,11 @@ scioctl(struct dev_ioctl_args *ap)
 	    return error;
 	if (securelevel > 0)
 	    return EPERM;
-	curproc->p_md.md_regs->tf_eflags |= PSL_IOPL;
+	curthread->td_lwp->lwp_md.md_regs->tf_eflags |= PSL_IOPL;
 	return 0;
 
     case KDDISABIO:     	/* disallow io operations (default) */
-	curproc->p_md.md_regs->tf_eflags &= ~PSL_IOPL;
+	curthread->td_lwp->lwp_md.md_regs->tf_eflags &= ~PSL_IOPL;
 	return 0;
 
     case KDSKBSTATE:    	/* set keyboard state (locks) */
diff --git a/sys/emulation/43bsd/43bsd_signal.c b/sys/emulation/43bsd/43bsd_signal.c
index 5c39853..daaa2c6 100644
--- a/sys/emulation/43bsd/43bsd_signal.c
+++ b/sys/emulation/43bsd/43bsd_signal.c
@@ -113,14 +113,14 @@ sys_osigvec(struct osigvec_args *uap)
 int
 sys_osigblock(struct osigblock_args *uap)
 {
-	struct proc *p = curproc;
+	struct lwp *lp = curthread->td_lwp;
 	sigset_t set;
 
 	OSIG2SIG(uap->mask, set);
 	SIG_CANTMASK(set);
 	crit_enter();
-	SIG2OSIG(p->p_sigmask, uap->sysmsg_result);
-	SIGSETOR(p->p_sigmask, set);
+	SIG2OSIG(lp->lwp_sigmask, uap->sysmsg_result);
+	SIGSETOR(lp->lwp_sigmask, set);
 	crit_exit();
 	return (0);
 }
@@ -128,14 +128,14 @@ sys_osigblock(struct osigblock_args *uap)
 int
 sys_osigsetmask(struct osigsetmask_args *uap)
 {
-	struct proc *p = curproc;
+	struct lwp *lp = curthread->td_lwp;
 	sigset_t set;
 
 	OSIG2SIG(uap->mask, set);
 	SIG_CANTMASK(set);
 	crit_enter();
-	SIG2OSIG(p->p_sigmask, uap->sysmsg_result);
-	SIGSETLO(p->p_sigmask, set);
+	SIG2OSIG(lp->lwp_sigmask, uap->sysmsg_result);
+	SIGSETLO(lp->lwp_sigmask, set);
 	crit_exit();
 	return (0);
 }
@@ -143,20 +143,20 @@ sys_osigsetmask(struct osigsetmask_args *uap)
 int
 sys_osigstack(struct osigstack_args *uap)
 {
-	struct proc *p = curproc;
+	struct lwp *lp = curthread->td_lwp;
 	struct sigstack ss;
 	int error = 0;
 
-	ss.ss_sp = p->p_sigstk.ss_sp;
-	ss.ss_onstack = p->p_sigstk.ss_flags & SS_ONSTACK;
+	ss.ss_sp = lp->lwp_sigstk.ss_sp;
+	ss.ss_onstack = lp->lwp_sigstk.ss_flags & SS_ONSTACK;
 	if (uap->oss && (error = copyout(&ss, uap->oss,
 	    sizeof(struct sigstack))))
 		return (error);
 	if (uap->nss && (error = copyin(uap->nss, &ss, sizeof(ss))) == 0) {
-		p->p_sigstk.ss_sp = ss.ss_sp;
-		p->p_sigstk.ss_size = 0;
-		p->p_sigstk.ss_flags |= ss.ss_onstack & SS_ONSTACK;
-		p->p_flag |= P_ALTSTACK;
+		lp->lwp_sigstk.ss_sp = ss.ss_sp;
+		lp->lwp_sigstk.ss_size = 0;
+		lp->lwp_sigstk.ss_flags |= ss.ss_onstack & SS_ONSTACK;
+		lp->lwp_flag |= LWP_ALTSTACK;
 	}
 	return (error);
 }
diff --git a/sys/emulation/linux/i386/linux_machdep.c b/sys/emulation/linux/i386/linux_machdep.c
index 28f637b..0f41a94 100644
--- a/sys/emulation/linux/i386/linux_machdep.c
+++ b/sys/emulation/linux/i386/linux_machdep.c
@@ -429,7 +429,8 @@ sys_linux_clone(struct linux_clone_args *args)
 		return (ESRCH);
 
 	p2->p_sigparent = exit_signal;
-	p2->p_md.md_regs->tf_esp = (unsigned int)args->stack;
+	ONLY_LWP_IN_PROC(p2)->lwp_md.md_regs->tf_esp =
+	    (unsigned int)args->stack;
 
 #ifdef DEBUG
 	if (ldebug(clone))
@@ -661,10 +662,10 @@ int
 sys_linux_iopl(struct linux_iopl_args *args)
 {
 	struct thread *td = curthread;
-	struct proc *p = td->td_proc;
+	struct lwp *lp = td->td_lwp;
 	int error;
 
-	KKASSERT(p);
+	KKASSERT(lp);
 
 	if (args->level < 0 || args->level > 3)
 		return (EINVAL);
@@ -672,7 +673,8 @@ sys_linux_iopl(struct linux_iopl_args *args)
 		return (error);
 	if (securelevel > 0)
 		return (EPERM);
-	p->p_md.md_regs->tf_eflags = (p->p_md.md_regs->tf_eflags & ~PSL_IOPL) |
+	lp->lwp_md.md_regs->tf_eflags =
+	    (lp->lwp_md.md_regs->tf_eflags & ~PSL_IOPL) |
 	    (args->level * (PSL_IOPL / 3));
 	return (0);
 }
@@ -841,7 +843,7 @@ int
 sys_linux_pause(struct linux_pause_args *args)
 {
 	struct thread *td = curthread;
-	struct proc *p = td->td_proc;
+	struct lwp *lp = td->td_lwp;
 	sigset_t mask;
 	int error;
 
@@ -850,7 +852,7 @@ sys_linux_pause(struct linux_pause_args *args)
 		kprintf(ARGS(pause, ""));
 #endif
 
-	mask = p->p_sigmask;
+	mask = lp->lwp_sigmask;
 
 	error = kern_sigsuspend(&mask);
 
diff --git a/sys/emulation/linux/i386/linux_ptrace.c b/sys/emulation/linux/i386/linux_ptrace.c
index c13739c..b3cc844 100644
--- a/sys/emulation/linux/i386/linux_ptrace.c
+++ b/sys/emulation/linux/i386/linux_ptrace.c
@@ -217,29 +217,33 @@ struct linux_pt_fpxreg {
 
 #ifndef CPU_DISABLE_SSE
 static int
-linux_proc_read_fpxregs(struct thread *td, struct linux_pt_fpxreg *fpxregs)
+linux_proc_read_fpxregs(struct proc *p, struct linux_pt_fpxreg *fpxregs)
 {
+	/* XXX lwp */
+	struct lwp *lp = FIRST_LWP_IN_PROC(p);
 	int error;
 
 	error = 0;
 	if (cpu_fxsr == 0)
 		error = EIO;
 	else
-		bcopy(&td->td_pcb->pcb_save.sv_xmm,
+		bcopy(&lp->lwp_thread->td_pcb->pcb_save.sv_xmm,
 		    fpxregs, sizeof(*fpxregs));
 	return (error);
 }
 
 static int
-linux_proc_write_fpxregs(struct thread *td, struct linux_pt_fpxreg *fpxregs)
+linux_proc_write_fpxregs(struct proc *p, struct linux_pt_fpxreg *fpxregs)
 {
+	/* XXX lwp */
+	struct lwp *lp = FIRST_LWP_IN_PROC(p);
 	int error;
 
 	error = 0;
 	if (cpu_fxsr == 0)
 		error = EIO;
 	else
-		bcopy(fpxregs, &td->td_pcb->pcb_save.sv_xmm,
+		bcopy(fpxregs, &lp->lwp_thread->td_pcb->pcb_save.sv_xmm,
 		    sizeof(*fpxregs));
 	return (error);
 }
@@ -397,7 +401,7 @@ sys_linux_ptrace(struct linux_ptrace_args *uap)
 
 		if (req == PTRACE_GETFPXREGS) {
 			PHOLD(p);
-			error = linux_proc_read_fpxregs(td, &r.fpxreg);
+			error = linux_proc_read_fpxregs(p, &r.fpxreg);
 			PRELE(p);
 			if (error == 0)
 				error = copyout(&r.fpxreg, (caddr_t)uap->data,
@@ -406,7 +410,7 @@ sys_linux_ptrace(struct linux_ptrace_args *uap)
 			/* clear dangerous bits exactly as Linux does*/
 			r.fpxreg.mxcsr &= 0xffbf;
 			PHOLD(p);
-			error = linux_proc_write_fpxregs(td, &r.fpxreg);
+			error = linux_proc_write_fpxregs(p, &r.fpxreg);
 			PRELE(p);
 		}
 		break;
diff --git a/sys/emulation/linux/i386/linux_sysvec.c b/sys/emulation/linux/i386/linux_sysvec.c
index 92d8b10..161afac 100644
--- a/sys/emulation/linux/i386/linux_sysvec.c
+++ b/sys/emulation/linux/i386/linux_sysvec.c
@@ -248,12 +248,13 @@ static void
 linux_rt_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
 {
 	struct proc *p = curproc;
+	struct lwp *lp = curthread->td_lwp;
 	struct trapframe *regs;
 	struct l_rt_sigframe *fp, frame;
 	int oonstack;
 
-	regs = p->p_md.md_regs;
-	oonstack = p->p_sigstk.ss_flags & SS_ONSTACK;
+	regs = lp->lwp_md.md_regs;
+	oonstack = lp->lwp_sigstk.ss_flags & SS_ONSTACK;
 
 #ifdef DEBUG
 	if (ldebug(rt_sendsig))
@@ -263,11 +264,11 @@ linux_rt_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
 	/*
 	 * Allocate space for the signal handler context.
 	 */
-	if ((p->p_flag & P_ALTSTACK) && !oonstack &&
+	if ((lp->lwp_flag & LWP_ALTSTACK) && !oonstack &&
 	    SIGISMEMBER(p->p_sigacts->ps_sigonstack, sig)) {
-		fp = (struct l_rt_sigframe *)(p->p_sigstk.ss_sp +
-		    p->p_sigstk.ss_size - sizeof(struct l_rt_sigframe));
-		p->p_sigstk.ss_flags |= SS_ONSTACK;
+		fp = (struct l_rt_sigframe *)(lp->lwp_sigstk.ss_sp +
+		    lp->lwp_sigstk.ss_size - sizeof(struct l_rt_sigframe));
+		lp->lwp_sigstk.ss_flags |= SS_ONSTACK;
 	} else
 		fp = (struct l_rt_sigframe *)regs->tf_esp - 1;
 
@@ -286,7 +287,7 @@ linux_rt_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
 		SIGACTION(p, SIGILL) = SIG_DFL;
 		SIGDELSET(p->p_sigignore, SIGILL);
 		SIGDELSET(p->p_sigcatch, SIGILL);
-		SIGDELSET(p->p_sigmask, SIGILL);
+		SIGDELSET(lp->lwp_sigmask, SIGILL);
 #ifdef DEBUG
 		if (ldebug(rt_sendsig))
 			kprintf(LMSG("rt_sendsig: bad stack %p, oonstack=%x"),
@@ -319,9 +320,9 @@ linux_rt_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
 	frame.sf_sc.uc_flags = 0;		/* XXX ??? */
 	frame.sf_sc.uc_link = NULL;		/* XXX ??? */
 
-	frame.sf_sc.uc_stack.ss_sp = p->p_sigstk.ss_sp;
-	frame.sf_sc.uc_stack.ss_size = p->p_sigstk.ss_size;
-	frame.sf_sc.uc_stack.ss_flags = (p->p_flag & P_ALTSTACK)
+	frame.sf_sc.uc_stack.ss_sp = lp->lwp_sigstk.ss_sp;
+	frame.sf_sc.uc_stack.ss_size = lp->lwp_sigstk.ss_size;
+	frame.sf_sc.uc_stack.ss_flags = (lp->lwp_flag & LWP_ALTSTACK)
 	    ? ((oonstack) ? LINUX_SS_ONSTACK : 0) : LINUX_SS_DISABLE;
 
 	bsd_to_linux_sigset(mask, &frame.sf_sc.uc_sigmask);
@@ -350,7 +351,7 @@ linux_rt_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
 	if (ldebug(rt_sendsig))
 		kprintf(LMSG("rt_sendsig flags: 0x%x, sp: %p, ss: 0x%x, mask: 0x%x"),
 		    frame.sf_sc.uc_stack.ss_flags, p->p_sigstk.ss_sp,
-		    p->p_sigstk.ss_size, frame.sf_sc.uc_mcontext.sc_mask);
+		    lp->lwp_sigstk.ss_size, frame.sf_sc.uc_mcontext.sc_mask);
 #endif
 
 	if (copyout(&frame, fp, sizeof(frame)) != 0) {
@@ -396,6 +397,7 @@ static void
 linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
 {
 	struct proc *p = curproc;
+	struct lwp *lp = curthread->td_lwp;
 	struct trapframe *regs;
 	struct l_sigframe *fp, frame;
 	l_sigset_t lmask;
@@ -407,8 +409,8 @@ linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
 		return;
 	}
 
-	regs = p->p_md.md_regs;
-	oonstack = p->p_sigstk.ss_flags & SS_ONSTACK;
+	regs = lp->lwp_md.md_regs;
+	oonstack = lp->lwp_sigstk.ss_flags & SS_ONSTACK;
 
 #ifdef DEBUG
 	if (ldebug(sendsig))
@@ -419,11 +421,11 @@ linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
 	/*
 	 * Allocate space for the signal handler context.
 	 */
-	if ((p->p_flag & P_ALTSTACK) && !oonstack &&
+	if ((lp->lwp_flag & LWP_ALTSTACK) && !oonstack &&
 	    SIGISMEMBER(p->p_sigacts->ps_sigonstack, sig)) {
-		fp = (struct l_sigframe *)(p->p_sigstk.ss_sp +
-		    p->p_sigstk.ss_size - sizeof(struct l_sigframe));
-		p->p_sigstk.ss_flags |= SS_ONSTACK;
+		fp = (struct l_sigframe *)(lp->lwp_sigstk.ss_sp +
+		    lp->lwp_sigstk.ss_size - sizeof(struct l_sigframe));
+		lp->lwp_sigstk.ss_flags |= SS_ONSTACK;
 	} else
 		fp = (struct l_sigframe *)regs->tf_esp - 1;
 
@@ -442,7 +444,7 @@ linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
 		SIGACTION(p, SIGILL) = SIG_DFL;
 		SIGDELSET(p->p_sigignore, SIGILL);
 		SIGDELSET(p->p_sigcatch, SIGILL);
-		SIGDELSET(p->p_sigmask, SIGILL);
+		SIGDELSET(lp->lwp_sigmask, SIGILL);
 		ksignal(p, SIGILL);
 		return;
 	}
@@ -526,13 +528,13 @@ linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
 int
 sys_linux_sigreturn(struct linux_sigreturn_args *args)
 {
-	struct proc *p = curproc;
+	struct lwp *lp = curthread->td_lwp;
 	struct l_sigframe frame;
 	struct trapframe *regs;
 	l_sigset_t lmask;
 	int eflags, i;
 
-	regs = p->p_md.md_regs;
+	regs = lp->lwp_md.md_regs;
 
 #ifdef DEBUG
 	if (ldebug(sigreturn))
@@ -572,16 +574,16 @@ sys_linux_sigreturn(struct linux_sigreturn_args *args)
 	 */
 #define	CS_SECURE(cs)	(ISPL(cs) == SEL_UPL)
 	if (!CS_SECURE(frame.sf_sc.sc_cs)) {
-		trapsignal(p, SIGBUS, T_PROTFLT);
+		trapsignal(lp, SIGBUS, T_PROTFLT);
 		return(EINVAL);
 	}
 
-	p->p_sigstk.ss_flags &= ~SS_ONSTACK;
+	lp->lwp_sigstk.ss_flags &= ~SS_ONSTACK;
 	lmask.__bits[0] = frame.sf_sc.sc_mask;
 	for (i = 0; i < (LINUX_NSIG_WORDS-1); i++)
 		lmask.__bits[i+1] = frame.sf_extramask[i];
-	linux_to_bsd_sigset(&lmask, &p->p_sigmask);
-	SIG_CANTMASK(p->p_sigmask);
+	linux_to_bsd_sigset(&lmask, &lp->lwp_sigmask);
+	SIG_CANTMASK(lp->lwp_sigmask);
 
 	/*
 	 * Restore signal context.
@@ -619,7 +621,7 @@ sys_linux_sigreturn(struct linux_sigreturn_args *args)
 int
 sys_linux_rt_sigreturn(struct linux_rt_sigreturn_args *args)
 {
-	struct proc *p = curproc;
+	struct lwp *lp = curthread->td_lwp;
 	struct l_ucontext uc;
 	struct l_sigcontext *context;
 	l_stack_t *lss;
@@ -627,7 +629,7 @@ sys_linux_rt_sigreturn(struct linux_rt_sigreturn_args *args)
 	struct trapframe *regs;
 	int eflags;
 
-	regs = p->p_md.md_regs;
+	regs = lp->lwp_md.md_regs;
 
 #ifdef DEBUG
 	if (ldebug(rt_sigreturn))
@@ -669,13 +671,13 @@ sys_linux_rt_sigreturn(struct linux_rt_sigreturn_args *args)
 	 */
 #define	CS_SECURE(cs)	(ISPL(cs) == SEL_UPL)
 	if (!CS_SECURE(context->sc_cs)) {
-		trapsignal(p, SIGBUS, T_PROTFLT);
+		trapsignal(lp, SIGBUS, T_PROTFLT);
 		return(EINVAL);
 	}
 
-	p->p_sigstk.ss_flags &= ~SS_ONSTACK;
-	linux_to_bsd_sigset(&uc.uc_sigmask, &p->p_sigmask);
-	SIG_CANTMASK(p->p_sigmask);
+	lp->lwp_sigstk.ss_flags &= ~SS_ONSTACK;
+	linux_to_bsd_sigset(&uc.uc_sigmask, &lp->lwp_sigmask);
+	SIG_CANTMASK(lp->lwp_sigmask);
 
 	/*
 	 * Restore signal context
diff --git a/sys/emulation/linux/linux_signal.c b/sys/emulation/linux/linux_signal.c
index 420cb66..132130d 100644
--- a/sys/emulation/linux/linux_signal.c
+++ b/sys/emulation/linux/linux_signal.c
@@ -279,7 +279,7 @@ sys_linux_rt_sigprocmask(struct linux_rt_sigprocmask_args *args)
 int
 sys_linux_sgetmask(struct linux_sgetmask_args *args)
 {
-	struct proc *p = curproc;
+	struct lwp *lp = curthread->td_lwp;
 	l_sigset_t mask;
 
 #ifdef DEBUG
@@ -287,7 +287,7 @@ sys_linux_sgetmask(struct linux_sgetmask_args *args)
 		kprintf(ARGS(sgetmask, ""));
 #endif
 
-	bsd_to_linux_sigset(&p->p_sigmask, &mask);
+	bsd_to_linux_sigset(&lp->lwp_sigmask, &mask);
 	args->sysmsg_result = mask.__bits[0];
 	return (0);
 }
@@ -295,7 +295,7 @@ sys_linux_sgetmask(struct linux_sgetmask_args *args)
 int
 sys_linux_ssetmask(struct linux_ssetmask_args *args)
 {
-	struct proc *p = curproc;
+	struct lwp *lp = curthread->td_lwp;
 	l_sigset_t lset;
 	sigset_t bset;
 
@@ -304,13 +304,13 @@ sys_linux_ssetmask(struct linux_ssetmask_args *args)
 		kprintf(ARGS(ssetmask, "%08lx"), (unsigned long)args->mask);
 #endif
 
-	bsd_to_linux_sigset(&p->p_sigmask, &lset);
+	bsd_to_linux_sigset(&lp->lwp_sigmask, &lset);
 	args->sysmsg_result = lset.__bits[0];
 	LINUX_SIGEMPTYSET(lset);
 	lset.__bits[0] = args->mask;
 	linux_to_bsd_sigset(&lset, &bset);
-	p->p_sigmask = bset;
-	SIG_CANTMASK(p->p_sigmask);
+	lp->lwp_sigmask = bset;
+	SIG_CANTMASK(lp->lwp_sigmask);
 	return (0);
 }
 
@@ -318,7 +318,7 @@ int
 sys_linux_sigpending(struct linux_sigpending_args *args)
 {
 	struct thread *td = curthread;
-	struct proc *p = td->td_proc;
+	struct lwp *lp = td->td_lwp;
 	sigset_t set;
 	l_sigset_t linux_set;
 	l_osigset_t mask;
@@ -332,7 +332,7 @@ sys_linux_sigpending(struct linux_sigpending_args *args)
 	error = kern_sigpending(&set);
 
 	if (error == 0) {
-		SIGSETAND(set, p->p_sigmask);
+		SIGSETAND(set, lp->lwp_sigmask);
 		bsd_to_linux_sigset(&set, &linux_set);
 		mask = linux_set.__bits[0];
 		error = copyout(&mask, args->mask, sizeof(mask));
diff --git a/sys/emulation/posix4/ksched.c b/sys/emulation/posix4/ksched.c
index a0f56a7..2191619 100644
--- a/sys/emulation/posix4/ksched.c
+++ b/sys/emulation/posix4/ksched.c
@@ -95,11 +95,11 @@ int ksched_detach(struct ksched *p)
 #define P1B_PRIO_MAX rtpprio_to_p4prio(RTP_PRIO_MIN)
 
 static __inline int
-getscheduler(register_t *ret, struct ksched *ksched, struct proc *p)
+getscheduler(register_t *ret, struct ksched *ksched, struct lwp *lp)
 {
 	int e = 0;
 
-	switch (p->p_lwp.lwp_rtprio.type)
+	switch (lp->lwp_rtprio.type)
 	{
 		case RTP_PRIO_FIFO:
 		*ret = SCHED_FIFO;
@@ -118,29 +118,29 @@ getscheduler(register_t *ret, struct ksched *ksched, struct proc *p)
 }
 
 int ksched_setparam(register_t *ret, struct ksched *ksched,
-	struct proc *p, const struct sched_param *param)
+	struct lwp *lp, const struct sched_param *param)
 {
 	register_t policy;
 	int e;
 
-	e = getscheduler(&policy, ksched, p);
+	e = getscheduler(&policy, ksched, lp);
 
 	if (e == 0)
 	{
 		if (policy == SCHED_OTHER)
 			e = EINVAL;
 		else
-			e = ksched_setscheduler(ret, ksched, p, policy, param);
+			e = ksched_setscheduler(ret, ksched, lp, policy, param);
 	}
 
 	return e;
 }
 
 int ksched_getparam(register_t *ret, struct ksched *ksched,
-	struct proc *p, struct sched_param *param)
+	struct lwp *lp, struct sched_param *param)
 {
-	if (RTP_PRIO_IS_REALTIME(p->p_lwp.lwp_rtprio.type))
-		param->sched_priority = rtpprio_to_p4prio(p->p_rtprio.prio);
+	if (RTP_PRIO_IS_REALTIME(lp->lwp_rtprio.type))
+		param->sched_priority = rtpprio_to_p4prio(lp->lwp_rtprio.prio);
 
 	return 0;
 }
@@ -153,7 +153,7 @@ int ksched_getparam(register_t *ret, struct ksched *ksched,
  *
  */
 int ksched_setscheduler(register_t *ret, struct ksched *ksched,
-	struct proc *p, int policy, const struct sched_param *param)
+	struct lwp *lp, int policy, const struct sched_param *param)
 {
 	int e = 0;
 	struct rtprio rtp;
@@ -170,7 +170,7 @@ int ksched_setscheduler(register_t *ret, struct ksched *ksched,
 			rtp.type = (policy == SCHED_FIFO)
 				? RTP_PRIO_FIFO : RTP_PRIO_REALTIME;
 
-			p->p_lwp.lwp_rtprio = rtp;
+			lp->lwp_rtprio = rtp;
 			need_user_resched();
 		}
 		else
@@ -183,7 +183,7 @@ int ksched_setscheduler(register_t *ret, struct ksched *ksched,
 		{
 			rtp.type = RTP_PRIO_NORMAL;
 			rtp.prio = p4prio_to_rtpprio(param->sched_priority);
-			p->p_lwp.lwp_rtprio = rtp;
+			lp->lwp_rtprio = rtp;
 
 			/* XXX Simply revert to whatever we had for last
 			 *     normal scheduler priorities.
@@ -199,9 +199,9 @@ int ksched_setscheduler(register_t *ret, struct ksched *ksched,
 	return e;
 }
 
-int ksched_getscheduler(register_t *ret, struct ksched *ksched, struct proc *p)
+int ksched_getscheduler(register_t *ret, struct ksched *ksched, struct lwp *lp)
 {
-	return getscheduler(ret, ksched, p);
+	return getscheduler(ret, ksched, lp);
 }
 
 /* ksched_yield: Yield the CPU.
@@ -257,7 +257,7 @@ int ksched_get_priority_min(register_t *ret, struct ksched *ksched, int policy)
 }
 
 int ksched_rr_get_interval(register_t *ret, struct ksched *ksched,
-	struct proc *p, struct timespec *timespec)
+	struct lwp *lp, struct timespec *timespec)
 {
 	*timespec = ksched->rr_interval;
 
diff --git a/sys/emulation/posix4/p1003_1b.c b/sys/emulation/posix4/p1003_1b.c
index 176699f..e80734e 100644
--- a/sys/emulation/posix4/p1003_1b.c
+++ b/sys/emulation/posix4/p1003_1b.c
@@ -172,13 +172,15 @@ int
 sys_sched_setparam(struct sched_setparam_args *uap)
 {
 	struct proc *p = curproc;
+	struct lwp *lp;
 	int e;
 
 	struct sched_param sched_param;
 	copyin(uap->param, &sched_param, sizeof(sched_param));
 
 	if ((e = p31b_proc(p, uap->pid, &p)) == 0) {
-		e = ksched_setparam(&uap->sysmsg_result, ksched, p,
+		lp = FIRST_LWP_IN_PROC(p); /* XXX lwp */
+		e = ksched_setparam(&uap->sysmsg_result, ksched, lp,
 		    (const struct sched_param *)&sched_param);
 	}
 	return e;
@@ -189,6 +191,7 @@ sys_sched_getparam(struct sched_getparam_args *uap)
 {
 	struct proc *p = curproc;
 	struct proc *targetp;
+	struct lwp *lp;
 	struct sched_param sched_param;
 	int e;
  
@@ -200,7 +203,8 @@ sys_sched_getparam(struct sched_getparam_args *uap)
 		targetp = p;
 	}
  
-	e = ksched_getparam(&uap->sysmsg_result, ksched, targetp, &sched_param);
+	lp = FIRST_LWP_IN_PROC(targetp); /* XXX lwp */
+	e = ksched_getparam(&uap->sysmsg_result, ksched, lp, &sched_param);
 
 	if (!e)
 		copyout(&sched_param, uap->param, sizeof(sched_param));
@@ -212,13 +216,15 @@ int
 sys_sched_setscheduler(struct sched_setscheduler_args *uap)
 {
 	struct proc *p = curproc;
+	struct lwp *lp;
 	int e;
 
 	struct sched_param sched_param;
 	copyin(uap->param, &sched_param, sizeof(sched_param));
 
 	if ((e = p31b_proc(p, uap->pid, &p)) == 0) {
-		e = ksched_setscheduler(&uap->sysmsg_result, ksched, p,
+		lp = FIRST_LWP_IN_PROC(p); /* XXX lwp */
+		e = ksched_setscheduler(&uap->sysmsg_result, ksched, lp,
 		    uap->policy, (const struct sched_param *)&sched_param);
 	}
 	return e;
@@ -229,6 +235,7 @@ sys_sched_getscheduler(struct sched_getscheduler_args *uap)
 {
 	struct proc *p = curproc;
 	struct proc *targetp;
+	struct lwp *lp;
 	int e;
  
 	if (uap->pid != 0 && uap->pid != p->p_pid) {
@@ -239,7 +246,8 @@ sys_sched_getscheduler(struct sched_getscheduler_args *uap)
 		targetp = p;
 	}
  
-	e = ksched_getscheduler(&uap->sysmsg_result, ksched, targetp);
+	lp = FIRST_LWP_IN_PROC(targetp); /* XXX lwp */
+	e = ksched_getscheduler(&uap->sysmsg_result, ksched, lp);
 
 	return e;
 }
@@ -267,10 +275,11 @@ sys_sched_rr_get_interval(struct sched_rr_get_interval_args *uap)
 {
 	int e;
 	struct proc *p = curproc;
+	struct lwp *lp = curthread->td_lwp;
 
 	if ((e = p31b_proc(p, uap->pid, &p)) == 0) {
 	    e = ksched_rr_get_interval(&uap->sysmsg_result, ksched,
-		    p, uap->interval);
+		    lp, uap->interval);
 	}
 	return e;
 }
diff --git a/sys/emulation/posix4/posix4.h b/sys/emulation/posix4/posix4.h
index 6d99ace..f2eb449 100644
--- a/sys/emulation/posix4/posix4.h
+++ b/sys/emulation/posix4/posix4.h
@@ -48,6 +48,7 @@ MALLOC_DECLARE(M_P31B);
 #define p31b_free(P) kfree((P), M_P31B)
 
 struct proc;
+struct lwp;
 
 int p31b_proc (struct proc *, pid_t, struct proc **);
 
@@ -83,13 +84,13 @@ int ksched_attach(struct ksched **);
 int ksched_detach(struct ksched *);
 
 int ksched_setparam(register_t *, struct ksched *,
-	struct proc *, const struct sched_param *);
+	struct lwp *, const struct sched_param *);
 int ksched_getparam(register_t *, struct ksched *,
-	struct proc *, struct sched_param *);
+	struct lwp *, struct sched_param *);
 
 int ksched_setscheduler(register_t *, struct ksched *,
-	struct proc *, int, const struct sched_param *);
-int ksched_getscheduler(register_t *, struct ksched *, struct proc *);
+	struct lwp *, int, const struct sched_param *);
+int ksched_getscheduler(register_t *, struct ksched *, struct lwp *);
 
 int ksched_yield(register_t *, struct ksched *);
 
@@ -97,7 +98,7 @@ int ksched_get_priority_max(register_t *, struct ksched *, int);
 int ksched_get_priority_min(register_t *, struct ksched *, int);
 
 int ksched_rr_get_interval(register_t *, struct ksched *,
-	struct proc *, struct timespec *);
+	struct lwp *, struct timespec *);
 
 #endif /* _KPOSIX_PRIORITY_SCHEDULING */
 
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
index 3bce496..60d3ce7 100644
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -1249,9 +1249,10 @@ elf_corehdr(struct proc *p, struct file *fp, struct ucred *cred, int numsegs,
 	status->pr_osreldate = osreldate;
 	status->pr_cursig = p->p_sig;
 	status->pr_pid = p->p_pid;
-	fill_regs(&p->p_lwp, &status->pr_reg);
+	/* XXX lwp */
+	fill_regs(FIRST_LWP_IN_PROC(p), &status->pr_reg);
 
-	fill_fpregs(&p->p_lwp, fpregset);
+	fill_fpregs(FIRST_LWP_IN_PROC(p), fpregset);
 
 	psinfo->pr_version = PRPSINFO_VERSION;
 	psinfo->pr_psinfosz = sizeof(prpsinfo_t);
@@ -1415,7 +1416,9 @@ elf_putsigs(struct proc *p, elf_buf_t target)
 		bcopy(p->p_procsig, &csi->csi_procsig, sizeof(struct procsig));
 		bcopy(p->p_procsig->ps_sigacts, &csi->csi_sigacts, sizeof(struct sigacts));
 		bcopy(&p->p_realtimer, &csi->csi_itimerval, sizeof(struct itimerval));
-		bcopy(&p->p_sigmask, &csi->csi_sigmask, sizeof(sigset_t));
+		/* XXX lwp */
+		bcopy(&FIRST_LWP_IN_PROC(p)->lwp_sigmask, &csi->csi_sigmask,
+			sizeof(sigset_t));
 	}
 	return(error);
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index f531c85..50f9cae 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -84,6 +84,7 @@ static struct plimit limit0;
 static struct vmspace vmspace0;
 struct proc *initproc;
 struct proc proc0;
+struct lwp lwp0;
 struct thread thread0;
 
 int cmask = CMASK;
@@ -158,15 +159,15 @@ mi_proc0init(struct globaldata *gd, struct user *proc0paddr)
 	lwkt_set_comm(&thread0, "thread0");
 	proc0.p_addr = (void *)thread0.td_kstack;
 	LIST_INIT(&proc0.p_lwps);
-	LIST_INSERT_HEAD(&proc0.p_lwps, &proc0.p_lwp, lwp_list);
-	proc0.p_lwp.lwp_thread = &thread0;
-	proc0.p_lwp.lwp_proc = &proc0;
+	LIST_INSERT_HEAD(&proc0.p_lwps, &lwp0, lwp_list);
+	lwp0.lwp_thread = &thread0;
+	lwp0.lwp_proc = &proc0;
 	proc0.p_usched = usched_init();
-	proc0.p_lwp.lwp_cpumask = 0xFFFFFFFF;
+	lwp0.lwp_cpumask = 0xFFFFFFFF;
 	varsymset_init(&proc0.p_varsymset, NULL);
 	thread0.td_flags |= TDF_RUNNING;
 	thread0.td_proc = &proc0;
-	thread0.td_lwp = &proc0.p_lwp;
+	thread0.td_lwp = &lwp0;
 	thread0.td_switch = cpu_heavy_switch;   /* YYY eventually LWKT */
 }
 
@@ -299,7 +300,7 @@ proc0_init(void *dummy __unused)
 	struct lwp *lp;
 
 	p = &proc0;
-	lp = &proc0.p_lwp;	/* XXX lwp to be: lwp0 */
+	lp = &lwp0;
 
 	/*
 	 * Initialize process and pgrp structures.
@@ -331,7 +332,7 @@ proc0_init(void *dummy __unused)
 	p->p_nice = NZERO;
 	p->p_rtprio.type = RTP_PRIO_NORMAL;
 	p->p_rtprio.prio = 0;
-	p->p_lwp.lwp_rtprio = p->p_rtprio;
+	lp->lwp_rtprio = p->p_rtprio;
 
 	p->p_peers = 0;
 	p->p_leader = p;
@@ -469,9 +470,7 @@ start_init(void *dummy)
 
 	p = curproc;
 
-	KKASSERT(p->p_nthreads == 1);
-
-	lp = LIST_FIRST(&p->p_lwps);
+	lp = ONLY_LWP_IN_PROC(p);
 
 	/* Get the vnode for '/'.  Set p->p_fd->fd_cdir to reference it. */
 	mp = mountlist_boot_getfirst();
@@ -610,11 +609,11 @@ create_init(const void *udata __unused)
 	struct lwp *lp;
 
 	crit_enter();
-	error = fork1(&proc0.p_lwp, RFFDG | RFPROC, &initproc);
+	error = fork1(&lwp0, RFFDG | RFPROC, &initproc);
 	if (error)
 		panic("cannot fork init: %d", error);
 	initproc->p_flag |= P_SYSTEM;
-	lp = LIST_FIRST(&initproc->p_lwps);
+	lp = ONLY_LWP_IN_PROC(initproc);
 	cpu_set_fork_handler(lp, start_init, NULL);
 	crit_exit();
 }
@@ -626,7 +625,7 @@ SYSINIT(init,SI_SUB_CREATE_INIT, SI_ORDER_FIRST, create_init, NULL)
 static void
 kick_init(const void *udata __unused)
 {
-	start_forked_proc(&proc0.p_lwp, initproc);
+	start_forked_proc(&lwp0, initproc);
 }
 SYSINIT(kickinit,SI_SUB_KTHREAD_INIT, SI_ORDER_FIRST, kick_init, NULL)
 
diff --git a/sys/kern/kern_checkpoint.c b/sys/kern/kern_checkpoint.c
index 870e4c5..b69d742 100644
--- a/sys/kern/kern_checkpoint.c
+++ b/sys/kern/kern_checkpoint.c
@@ -287,6 +287,7 @@ static int
 elf_loadnotes(struct proc *p, prpsinfo_t *psinfo, prstatus_t *status, 
 	   prfpregset_t *fpregset) 
 {
+	struct lwp *lp;
 	int error;
 
 	/* validate status and psinfo */
@@ -301,9 +302,11 @@ elf_loadnotes(struct proc *p, prpsinfo_t *psinfo, prstatus_t *status,
 		error = EINVAL;
 		goto done;
 	}
-	if ((error = set_regs(&p->p_lwp, &status->pr_reg)) != 0)
+	/* XXX lwp */
+	lp = FIRST_LWP_IN_PROC(p);
+	if ((error = set_regs(lp, &status->pr_reg)) != 0)
 		goto done;
-	error = set_fpregs(&p->p_lwp, fpregset);
+	error = set_fpregs(lp, fpregset);
 	strlcpy(p->p_comm, psinfo->pr_fname, sizeof(p->p_comm));
 	/* XXX psinfo->pr_psargs not yet implemented */
  done:	
@@ -449,6 +452,7 @@ elf_getsigs(struct proc *p, struct file *fp)
 	int error;
 	struct ckpt_siginfo *csi;
 	struct sigacts *tmpsigacts;
+	struct lwp *lp;
 
 	TRACE_ENTER;
 	csi = kmalloc(sizeof(struct ckpt_siginfo), M_TEMP, M_ZERO | M_WAITOK);
@@ -466,7 +470,9 @@ elf_getsigs(struct proc *p, struct file *fp)
 	bcopy(&csi->csi_sigacts, p->p_procsig->ps_sigacts, sizeof(struct sigacts));
 	bcopy(&csi->csi_itimerval, &p->p_realtimer, sizeof(struct itimerval));
 	SIG_CANTMASK(csi->csi_sigmask);
-	bcopy(&csi->csi_sigmask, &p->p_sigmask, sizeof(sigset_t));
+	/* XXX lwp */
+	lp = FIRST_LWP_IN_PROC(p);
+	bcopy(&csi->csi_sigmask, &lp->lwp_sigmask, sizeof(sigset_t));
 	p->p_sigparent = csi->csi_sigparent;
  done:
 	if (csi)
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index 732f994..e1f43d3 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -1631,7 +1631,7 @@ void
 fdfree(struct proc *p)
 {
 	/* Take any thread of p */
-	struct thread *td = LIST_FIRST(&p->p_lwps)->lwp_thread;
+	struct thread *td = FIRST_LWP_IN_PROC(p)->lwp_thread;
 	struct filedesc *fdp = p->p_fd;
 	struct fdnode *fdnode;
 	int i;
@@ -1879,7 +1879,7 @@ void
 setugidsafety(struct proc *p)
 {
 	/* Take any thread of p */
-	struct thread *td = LIST_FIRST(&p->p_lwps)->lwp_thread;
+	struct thread *td = FIRST_LWP_IN_PROC(p)->lwp_thread;
 	struct filedesc *fdp = p->p_fd;
 	int i;
 
@@ -1918,7 +1918,7 @@ void
 fdcloseexec(struct proc *p)
 {
 	/* Take any thread of p */
-	struct thread *td = LIST_FIRST(&p->p_lwps)->lwp_thread;
+	struct thread *td = FIRST_LWP_IN_PROC(p)->lwp_thread;
 	struct filedesc *fdp = p->p_fd;
 	int i;
 
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index 621bc49..6aac714 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -925,7 +925,7 @@ knote_fdclose(struct proc *p, int fd)
 	struct filedesc *fdp = p->p_fd;
 	struct klist *list = &fdp->fd_knlist[fd];
 	/* Take any thread of p */
-	struct thread *td = LIST_FIRST(&p->p_lwps)->lwp_thread;
+	struct thread *td = FIRST_LWP_IN_PROC(p)->lwp_thread;
 
 	knote_remove(td, list);
 }
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
index cc7d6b4..27f15ee 100644
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -146,6 +146,7 @@ int
 kern_execve(struct nlookupdata *nd, struct image_args *args)
 {
 	struct thread *td = curthread;
+	struct lwp *lp = td->td_lwp;
 	struct proc *p = td->td_proc;
 	register_t *stack_base;
 	int error, len, i;
@@ -347,7 +348,7 @@ interpret:
 	len = min(nd->nl_nch.ncp->nc_nlen, MAXCOMLEN);
 	bcopy(nd->nl_nch.ncp->nc_name, p->p_comm, len);
 	p->p_comm[len] = 0;
-	bcopy(p->p_comm, p->p_lwp.lwp_thread->td_comm, MAXCOMLEN+1);
+	bcopy(p->p_comm, lp->lwp_thread->td_comm, MAXCOMLEN+1);
 
 	/*
 	 * mark as execed, wakeup the process that vforked (if any) and tell
@@ -442,7 +443,7 @@ interpret:
 	p->p_acflag &= ~AFORK;
 
 	/* Set values passed into the program in registers. */
-	setregs(td->td_lwp, imgp->entry_addr, (u_long)(uintptr_t)stack_base,
+	exec_setregs(imgp->entry_addr, (u_long)(uintptr_t)stack_base,
 	    imgp->ps_strings);
 
 	/* Free any previous argument cache */
@@ -627,6 +628,10 @@ exec_new_vmspace(struct image_params *imgp, struct vmspace *vmcopy)
 	imgp->vmspace_destroyed = 1;
 
 	/*
+	 * XXX lwp here would be a good place to kill sibling lwps
+	 */
+
+	/*
 	 * Prevent a pending AIO from modifying the new address space.
 	 */
 	aio_proc_rundown(imgp->proc);
@@ -649,7 +654,7 @@ exec_new_vmspace(struct image_params *imgp, struct vmspace *vmcopy)
 	} else if (vmspace->vm_refcnt == 1 && vmspace->vm_exitingcnt == 0) {
 		shmexit(vmspace);
 		if (vmspace->vm_upcalls)
-			upc_release(vmspace, &imgp->proc->p_lwp);
+			upc_release(vmspace, ONLY_LWP_IN_PROC(imgp->proc));
 		pmap_remove_pages(vmspace_pmap(vmspace),
 			0, VM_MAX_USER_ADDRESS);
 		vm_map_remove(map, 0, VM_MAX_USER_ADDRESS);
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index 30fa495..289d866 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -212,7 +212,7 @@ exit1(int rv)
 	 * Release upcalls associated with this process
 	 */
 	if (vm->vm_upcalls)
-		upc_release(vm, &p->p_lwp);
+		upc_release(vm, lp);
 
 	/* clean up data related to virtual kernel operation */
 	if (p->p_vkernel)
@@ -421,7 +421,7 @@ int
 kern_wait(pid_t pid, int *status, int options, struct rusage *rusage, int *res)
 {
 	struct thread *td = curthread;
-	struct thread *deadtd;
+	struct lwp *deadlp;
 	struct proc *q = td->td_proc;
 	struct proc *p, *t;
 	int nfound, error;
@@ -470,8 +470,7 @@ loop:
 
 		nfound++;
 		if (p->p_flag & P_ZOMBIE) {
-			KKASSERT((p->p_nthreads == 1));
-			deadtd = LIST_FIRST(&p->p_lwps)->lwp_thread;
+			deadlp = ONLY_LWP_IN_PROC(p);
 
 			/*
 			 * Other kernel threads may be in the middle of 
@@ -484,7 +483,7 @@ loop:
 				while (p->p_lock)
 					tsleep(p, 0, "reap3", hz);
 			}
-			lwkt_wait_free(deadtd);
+			lwkt_wait_free(deadlp->lwp_thread);
 
 			/*
 			 * The process's thread may still be in the middle
@@ -497,13 +496,13 @@ loop:
 			 *
 			 * YYY no wakeup occurs so we depend on the timeout.
 			 */
-			if ((deadtd->td_flags & (TDF_RUNNING|TDF_PREEMPT_LOCK|TDF_EXITING)) != TDF_EXITING) {
-				tsleep(deadtd, 0, "reap2", 1);
+			if ((deadlp->lwp_thread->td_flags & (TDF_RUNNING|TDF_PREEMPT_LOCK|TDF_EXITING)) != TDF_EXITING) {
+				tsleep(deadlp->lwp_thread, 0, "reap2", 1);
 				goto loop;
 			}
 
 			/* scheduling hook for heuristic */
-			p->p_usched->heuristic_exiting(td->td_lwp, deadtd->td_lwp);
+			p->p_usched->heuristic_exiting(td->td_lwp, deadlp);
 
 			/* Take care of our return values. */
 			*res = p->p_pid;
@@ -557,6 +556,7 @@ loop:
 			}
 
 			vm_waitproc(p);
+			zfree(lwp_zone, deadlp);
 			zfree(proc_zone, p);
 			nprocs--;
 			return (0);
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index f4587c2..b5307d2 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -217,7 +217,7 @@ fork1(struct lwp *lp1, int flags, struct proc **procp)
 	pgrp = NULL;
 	if ((flags & RFPGLOCK) && (pgrp = p1->p_pgrp) != NULL) {
 		lockmgr(&pgrp->pg_lock, LK_SHARED);
-		if (CURSIGNB(p1)) {
+		if (CURSIGNB(lp1)) {
 			error = ERESTART;
 			goto done;
 		}
@@ -266,6 +266,7 @@ fork1(struct lwp *lp1, int flags, struct proc **procp)
 
 	/* Allocate new proc. */
 	p2 = zalloc(proc_zone);
+	lp2 = zalloc(lwp_zone);
 
 	/*
 	 * Setup linkage for kernel based threading XXX lwp
@@ -286,7 +287,6 @@ fork1(struct lwp *lp1, int flags, struct proc **procp)
 	LIST_INIT(&p2->p_lwps);
 
 	/* XXX lwp */
-	lp2 = &p2->p_lwp;
 	lp2->lwp_proc = p2;
 	lp2->lwp_tid = 0;
 	LIST_INSERT_HEAD(&p2->p_lwps, lp2, lwp_list);
@@ -313,7 +313,7 @@ fork1(struct lwp *lp1, int flags, struct proc **procp)
 			(caddr_t)&lp2->lwp_startzero));
 	bcopy(&p1->p_startcopy, &p2->p_startcopy,
 	    (unsigned) ((caddr_t)&p2->p_endcopy - (caddr_t)&p2->p_startcopy));
-	bcopy(&p1->p_lwp.lwp_startcopy, &lp2->lwp_startcopy,
+	bcopy(&lp1->lwp_startcopy, &lp2->lwp_startcopy,
 	    (unsigned) ((caddr_t)&lp2->lwp_endcopy -
 			(caddr_t)&lp2->lwp_startcopy));
 
@@ -413,7 +413,8 @@ fork1(struct lwp *lp1, int flags, struct proc **procp)
 	 * Preserve some more flags in subprocess.  P_PROFIL has already
 	 * been preserved.
 	 */
-	p2->p_flag |= p1->p_flag & (P_SUGID | P_ALTSTACK);
+	p2->p_flag |= p1->p_flag & P_SUGID;
+	lp2->lwp_flag |= lp1->lwp_flag & LWP_ALTSTACK;
 	if (p1->p_session->s_ttyvp != NULL && p1->p_flag & P_CONTROLT)
 		p2->p_flag |= P_CONTROLT;
 	if (flags & RFPPWAIT)
@@ -475,7 +476,7 @@ fork1(struct lwp *lp1, int flags, struct proc **procp)
 	p2->p_usched = p1->p_usched;
 	lp2->lwp_cpbase = mycpu->gd_schedclock.time -
 			mycpu->gd_schedclock.periodic;
-	p2->p_usched->heuristic_forking(&p1->p_lwp, lp2);
+	p2->p_usched->heuristic_forking(lp1, lp2);
 	crit_exit();
 
 	/*
@@ -489,7 +490,7 @@ fork1(struct lwp *lp1, int flags, struct proc **procp)
 	 * execution path later.  (ie: directly into user mode)
 	 */
 	vm_fork(lp1, p2, flags);
-	caps_fork(p1, p2, flags);
+	caps_fork(lp1->lwp_thread, lp2->lwp_thread, flags);
 
 	if (flags == (RFFDG | RFPROC)) {
 		mycpu->gd_cnt.v_forks++;
@@ -589,11 +590,7 @@ rm_at_fork(forklist_fn function)
 void
 start_forked_proc(struct lwp *lp1, struct proc *p2)
 {
-	struct lwp *lp2;
-
-	KKASSERT(p2 != NULL && p2->p_nthreads == 1);
-
-	lp2 = LIST_FIRST(&p2->p_lwps);
+	struct lwp *lp2 = ONLY_LWP_IN_PROC(p2);
 
 	/*
 	 * Move from SIDL to RUN queue, and activate the process's thread.
diff --git a/sys/kern/kern_kinfo.c b/sys/kern/kern_kinfo.c
index d9b814a..6831066 100644
--- a/sys/kern/kern_kinfo.c
+++ b/sys/kern/kern_kinfo.c
@@ -124,6 +124,7 @@ fill_kinfo_proc(struct proc *p, struct kinfo_proc *kp)
 	kp->kp_exitstat = p->p_xstat;
 	kp->kp_nthreads = p->p_nthreads;
 	kp->kp_nice = p->p_nice;
+	kp->kp_swtime = p->p_swtime;
 
 	kp->kp_vm_map_size = p->p_vmspace->vm_map.size;
 	kp->kp_vm_rssize = p->p_vmspace->vm_rssize;
@@ -150,8 +151,8 @@ fill_kinfo_lwp(struct lwp *lwp, struct kinfo_lwp *kl)
 	kl->kl_pid = lwp->lwp_proc->p_pid;
 	kl->kl_tid = lwp->lwp_tid;
 
-#ifdef notyet
 	kl->kl_flags = lwp->lwp_flag;
+#ifdef notyet
 	kl->kl_stat = lwp->lwp_stat;
 #endif
 	kl->kl_tdflags = lwp->lwp_thread->td_flags;
@@ -170,7 +171,6 @@ fill_kinfo_lwp(struct lwp *lwp, struct kinfo_lwp *kl)
 	kl->kl_iticks = lwp->lwp_thread->td_iticks;
 	kl->kl_cpticks = lwp->lwp_cpticks;
 	kl->kl_pctcpu = lwp->lwp_pctcpu;
-	kl->kl_swtime = lwp->lwp_swtime;
 	kl->kl_slptime = lwp->lwp_slptime;
 	kl->kl_origcpu = lwp->lwp_usdata.bsd4.origcpu;	/* XXX TGEN same */
 	kl->kl_estcpu = lwp->lwp_usdata.bsd4.estcpu;
diff --git a/sys/kern/kern_memio.c b/sys/kern/kern_memio.c
index ee8ecc9..95b6fb5 100644
--- a/sys/kern/kern_memio.c
+++ b/sys/kern/kern_memio.c
@@ -260,7 +260,7 @@ mmrw(cdev_t dev, struct uio *uio, int flags)
 				error = EPERM;
 				break;
 			}
-			if (CURSIG(curproc) != 0) {
+			if (CURSIG(curthread->td_lwp) != 0) {
 				/*
 				 * Use tsleep() to get the error code right.
 				 * It should return immediately.
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
index 9561248..3ac3520 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -83,6 +83,7 @@ struct proclist allproc;
 struct proclist zombproc;
 struct spinlock allproc_spin;
 vm_zone_t proc_zone;
+vm_zone_t lwp_zone;
 vm_zone_t thread_zone;
 
 /*
@@ -129,6 +130,7 @@ procinit(void)
 	pidhashtbl = hashinit(maxproc / 4, M_PROC, &pidhash);
 	pgrphashtbl = hashinit(maxproc / 4, M_PROC, &pgrphash);
 	proc_zone = zinit("PROC", sizeof (struct proc), 0, 0, 5);
+	lwp_zone = zinit("LWP", sizeof (struct lwp), 0, 0, 5);
 	thread_zone = zinit("THREAD", sizeof (struct thread), 0, 0, 5);
 	uihashinit();
 }
diff --git a/sys/kern/kern_resource.c b/sys/kern/kern_resource.c
index b3c9bc2..2d97e7e 100644
--- a/sys/kern/kern_resource.c
+++ b/sys/kern/kern_resource.c
@@ -243,6 +243,7 @@ donice(struct proc *chgp, int n)
 {
 	struct proc *curp = curproc;
 	struct ucred *cr = curp->p_ucred;
+	struct lwp *lp;
 
 	if (cr->cr_uid && cr->cr_ruid &&
 	    cr->cr_uid != chgp->p_ucred->cr_uid &&
@@ -255,7 +256,8 @@ donice(struct proc *chgp, int n)
 	if (n < chgp->p_nice && suser_cred(cr, 0))
 		return (EACCES);
 	chgp->p_nice = n;
-	chgp->p_usched->resetpriority(&chgp->p_lwp);
+	FOREACH_LWP_IN_PROC(lp, chgp)
+		chgp->p_usched->resetpriority(lp);
 	return (0);
 }
 
@@ -268,6 +270,7 @@ sys_rtprio(struct rtprio_args *uap)
 {
 	struct proc *curp = curproc;
 	struct proc *p;
+	struct lwp *lp;
 	struct ucred *cr = curp->p_ucred;
 	struct rtprio rtp;
 	int error;
@@ -284,9 +287,11 @@ sys_rtprio(struct rtprio_args *uap)
 	if (p == 0)
 		return (ESRCH);
 
+	/* XXX lwp */
+	lp = FIRST_LWP_IN_PROC(p);
 	switch (uap->function) {
 	case RTP_LOOKUP:
-		return (copyout(&p->p_lwp.lwp_rtprio, uap->rtp, sizeof(struct rtprio)));
+		return (copyout(&lp->lwp_rtprio, uap->rtp, sizeof(struct rtprio)));
 	case RTP_SET:
 		if (cr->cr_uid && cr->cr_ruid &&
 		    cr->cr_uid != p->p_ucred->cr_uid &&
@@ -317,7 +322,7 @@ sys_rtprio(struct rtprio_args *uap)
 		case RTP_PRIO_IDLE:
 			if (rtp.prio > RTP_PRIO_MAX)
 				return (EINVAL);
-			p->p_lwp.lwp_rtprio = rtp;
+			lp->lwp_rtprio = rtp;
 			return (0);
 		default:
 			return (EINVAL);
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index b45cb65..9c93dc1 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -395,6 +395,7 @@ void
 execsigs(struct proc *p)
 {
 	struct sigacts *ps = p->p_sigacts;
+	struct lwp *lp;
 	int sig;
 
 	/*
@@ -416,10 +417,11 @@ execsigs(struct proc *p)
 	 * Reset stack state to the user stack.
 	 * Clear set of signals caught on the signal stack.
 	 */
-	p->p_sigstk.ss_flags = SS_DISABLE;
-	p->p_sigstk.ss_size = 0;
-	p->p_sigstk.ss_sp = 0;
-	p->p_flag &= ~P_ALTSTACK;
+	lp = ONLY_LWP_IN_PROC(p);
+	lp->lwp_sigstk.ss_flags = SS_DISABLE;
+	lp->lwp_sigstk.ss_size = 0;
+	lp->lwp_sigstk.ss_sp = 0;
+	lp->lwp_flag &= ~LWP_ALTSTACK;
 	/*
 	 * Reset no zombies if child dies flag as Solaris does.
 	 */
@@ -436,25 +438,25 @@ int
 kern_sigprocmask(int how, sigset_t *set, sigset_t *oset)
 {
 	struct thread *td = curthread;
-	struct proc *p = td->td_proc;
+	struct lwp *lp = td->td_lwp;
 	int error;
 
 	if (oset != NULL)
-		*oset = p->p_sigmask;
+		*oset = lp->lwp_sigmask;
 
 	error = 0;
 	if (set != NULL) {
 		switch (how) {
 		case SIG_BLOCK:
 			SIG_CANTMASK(*set);
-			SIGSETOR(p->p_sigmask, *set);
+			SIGSETOR(lp->lwp_sigmask, *set);
 			break;
 		case SIG_UNBLOCK:
-			SIGSETNAND(p->p_sigmask, *set);
+			SIGSETNAND(lp->lwp_sigmask, *set);
 			break;
 		case SIG_SETMASK:
 			SIG_CANTMASK(*set);
-			p->p_sigmask = *set;
+			lp->lwp_sigmask = *set;
 			break;
 		default:
 			error = EINVAL;
@@ -520,6 +522,7 @@ int
 kern_sigsuspend(struct __sigset *set)
 {
 	struct thread *td = curthread;
+	struct lwp *lp = td->td_lwp;
 	struct proc *p = td->td_proc;
 	struct sigacts *ps = p->p_sigacts;
 
@@ -530,11 +533,11 @@ kern_sigsuspend(struct __sigset *set)
 	 * save it here and mark the sigacts structure
 	 * to indicate this.
 	 */
-	p->p_oldsigmask = p->p_sigmask;
-	p->p_flag |= P_OLDMASK;
+	lp->lwp_oldsigmask = lp->lwp_sigmask;
+	lp->lwp_flag |= LWP_OLDMASK;
 
 	SIG_CANTMASK(*set);
-	p->p_sigmask = *set;
+	lp->lwp_sigmask = *set;
 	while (tsleep(ps, PCATCH, "pause", 0) == 0)
 		/* void */;
 	/* always return EINTR rather than ERESTART... */
@@ -564,25 +567,26 @@ int
 kern_sigaltstack(struct sigaltstack *ss, struct sigaltstack *oss)
 {
 	struct thread *td = curthread;
+	struct lwp *lp = td->td_lwp;
 	struct proc *p = td->td_proc;
 
-	if ((p->p_flag & P_ALTSTACK) == 0)
-		p->p_sigstk.ss_flags |= SS_DISABLE;
+	if ((lp->lwp_flag & LWP_ALTSTACK) == 0)
+		lp->lwp_sigstk.ss_flags |= SS_DISABLE;
 
 	if (oss)
-		*oss = p->p_sigstk;
+		*oss = lp->lwp_sigstk;
 
 	if (ss) {
 		if (ss->ss_flags & SS_DISABLE) {
-			if (p->p_sigstk.ss_flags & SS_ONSTACK)
+			if (lp->lwp_sigstk.ss_flags & SS_ONSTACK)
 				return (EINVAL);
-			p->p_flag &= ~P_ALTSTACK;
-			p->p_sigstk.ss_flags = ss->ss_flags;
+			lp->lwp_flag &= ~LWP_ALTSTACK;
+			lp->lwp_sigstk.ss_flags = ss->ss_flags;
 		} else {
 			if (ss->ss_size < p->p_sysent->sv_minsigstksz)
 				return (ENOMEM);
-			p->p_flag |= P_ALTSTACK;
-			p->p_sigstk = *ss;
+			lp->lwp_flag |= LWP_ALTSTACK;
+			lp->lwp_sigstk = *ss;
 		}
 	}
 
@@ -757,8 +761,9 @@ pgsignal(struct pgrp *pgrp, int sig, int checkctty)
  * Otherwise, post it normally.
  */
 void
-trapsignal(struct proc *p, int sig, u_long code)
+trapsignal(struct lwp *lp, int sig, u_long code)
 {
+	struct proc *p = lp->lwp_proc;
 	struct sigacts *ps = p->p_sigacts;
 
 	/*
@@ -774,18 +779,18 @@ trapsignal(struct proc *p, int sig, u_long code)
 
 
 	if ((p->p_flag & P_TRACED) == 0 && SIGISMEMBER(p->p_sigcatch, sig) &&
-	    !SIGISMEMBER(p->p_sigmask, sig)) {
-		p->p_lwp.lwp_ru.ru_nsignals++;
+	    !SIGISMEMBER(lp->lwp_sigmask, sig)) {
+		lp->lwp_ru.ru_nsignals++;
 #ifdef KTRACE
-		if (KTRPOINT(p->p_thread, KTR_PSIG))
+		if (KTRPOINT(lp->lwp_thread, KTR_PSIG))
 			ktrpsig(p, sig, ps->ps_sigact[_SIG_IDX(sig)],
-				&p->p_sigmask, code);
+				&lp->lwp_sigmask, code);
 #endif
 		(*p->p_sysent->sv_sendsig)(ps->ps_sigact[_SIG_IDX(sig)], sig,
-						&p->p_sigmask, code);
-		SIGSETOR(p->p_sigmask, ps->ps_catchmask[_SIG_IDX(sig)]);
+						&lp->lwp_sigmask, code);
+		SIGSETOR(lp->lwp_sigmask, ps->ps_catchmask[_SIG_IDX(sig)]);
 		if (!SIGISMEMBER(ps->ps_signodefer, sig))
-			SIGADDSET(p->p_sigmask, sig);
+			SIGADDSET(lp->lwp_sigmask, sig);
 		if (SIGISMEMBER(ps->ps_sigreset, sig)) {
 			/*
 			 * See kern_sigaction() for origin of this code.
@@ -819,7 +824,7 @@ trapsignal(struct proc *p, int sig, u_long code)
 void
 ksignal(struct proc *p, int sig)
 {
-	struct lwp *lp = &p->p_lwp;
+	struct lwp *lp = FIRST_LWP_IN_PROC(p);
 	int prop;
 	sig_t action;
 
@@ -851,7 +856,7 @@ ksignal(struct proc *p, int sig)
 		 */
 		if (SIGISMEMBER(p->p_sigignore, sig) || (p->p_flag & P_WEXIT))
 			return;
-		if (SIGISMEMBER(p->p_sigmask, sig))
+		if (SIGISMEMBER(lp->lwp_sigmask, sig))
 			action = SIG_HOLD;
 		else if (SIGISMEMBER(p->p_sigcatch, sig))
 			action = SIG_CATCH;
@@ -1056,7 +1061,7 @@ ksignal(struct proc *p, int sig)
 	if (lp == lwkt_preempted_proc()) {
 		signotify();
 	} else if (p->p_stat == SRUN) {
-		struct thread *td = p->p_thread;
+		struct thread *td = lp->lwp_thread;
 
 		KASSERT(td != NULL, 
 		    ("pid %d NULL p_thread stat %d flags %08x",
@@ -1111,6 +1116,7 @@ kern_sigtimedwait(sigset_t waitset, siginfo_t *info, struct timespec *timeout)
 {
 	sigset_t savedmask, set;
 	struct proc *p = curproc;
+	struct lwp *lp = curthread->td_lwp;
 	int error, sig, hz, timevalid = 0;
 	struct timespec rts, ets, ts;
 	struct timeval tv;
@@ -1118,7 +1124,7 @@ kern_sigtimedwait(sigset_t waitset, siginfo_t *info, struct timespec *timeout)
 	error = 0;
 	sig = 0;
 	SIG_CANTMASK(waitset);
-	savedmask = p->p_sigmask;
+	savedmask = lp->lwp_sigmask;
 
 	if (timeout) {
 		if (timeout->tv_sec >= 0 && timeout->tv_nsec >= 0 &&
@@ -1134,10 +1140,10 @@ kern_sigtimedwait(sigset_t waitset, siginfo_t *info, struct timespec *timeout)
 		set = p->p_siglist;
 		SIGSETAND(set, waitset);
 		if ((sig = sig_ffs(&set)) != 0) {
-			SIGFILLSET(p->p_sigmask);
-			SIGDELSET(p->p_sigmask, sig);
-			SIG_CANTMASK(p->p_sigmask);
-			sig = issignal(p);
+			SIGFILLSET(lp->lwp_sigmask);
+			SIGDELSET(lp->lwp_sigmask, sig);
+			SIG_CANTMASK(lp->lwp_sigmask);
+			sig = issignal(lp);
 			/*
 			 * It may be a STOP signal, in the case, issignal
 			 * returns 0, because we may stop there, and new
@@ -1178,8 +1184,8 @@ kern_sigtimedwait(sigset_t waitset, siginfo_t *info, struct timespec *timeout)
 		} else
 			hz = 0;
 
-		p->p_sigmask = savedmask;
-		SIGSETNAND(p->p_sigmask, waitset);
+		lp->lwp_sigmask = savedmask;
+		SIGSETNAND(lp->lwp_sigmask, waitset);
 		error = tsleep(&p->p_sigacts, PCATCH, "sigwt", hz);
 		if (timeout) {
 			if (error == ERESTART) {
@@ -1193,7 +1199,7 @@ kern_sigtimedwait(sigset_t waitset, siginfo_t *info, struct timespec *timeout)
 		/* Retry ... */
 	}
 
-	p->p_sigmask = savedmask;
+	lp->lwp_sigmask = savedmask;
 	if (sig) {
 		error = 0;
 		bzero(info, sizeof(*info));
@@ -1267,12 +1273,13 @@ sys_sigwaitinfo(struct sigwaitinfo_args *uap)
  * system call, return EINTR or ERESTART as appropriate.
  */
 int
-iscaught(struct proc *p)
+iscaught(struct lwp *lp)
 {
+	struct proc *p = lp->lwp_proc;
 	int sig;
 
 	if (p) {
-		if ((sig = CURSIG(p)) != 0) {
+		if ((sig = CURSIG(lp)) != 0) {
 			if (SIGISMEMBER(p->p_sigacts->ps_sigintr, sig))
 				return (EINTR);                        
 			return (ERESTART);     
@@ -1297,8 +1304,9 @@ iscaught(struct proc *p)
  *		postsig(sig);
  */
 int
-issignal(struct proc *p)
+issignal(struct lwp *lp)
 {
+	struct proc *p = lp->lwp_proc;
 	sigset_t mask;
 	int sig, prop;
 
@@ -1307,7 +1315,7 @@ issignal(struct proc *p)
 		int traced = (p->p_flag & P_TRACED) || (p->p_stops & S_SIG);
 
 		mask = p->p_siglist;
-		SIGSETNAND(mask, p->p_sigmask);
+		SIGSETNAND(mask, lp->lwp_sigmask);
 		if (p->p_flag & P_PPWAIT)
 			SIG_STOPSIGMASK(mask);
 		if (!SIGNOTEMPTY(mask)) { 	/* no signal to send */
@@ -1360,7 +1368,7 @@ issignal(struct proc *p)
 			 * signal is being masked, look for other signals.
 			 */
 			SIGADDSET(p->p_siglist, sig);
-			if (SIGISMEMBER(p->p_sigmask, sig))
+			if (SIGISMEMBER(lp->lwp_sigmask, sig))
 				continue;
 
 			/*
@@ -1470,8 +1478,8 @@ issignal(struct proc *p)
 void
 postsig(int sig)
 {
-	struct thread *td = curthread;
-	struct proc *p = td->td_proc;
+	struct lwp *lp = curthread->td_lwp;
+	struct proc *p = lp->lwp_proc;
 	struct sigacts *ps = p->p_sigacts;
 	sig_t action;
 	sigset_t returnmask;
@@ -1493,9 +1501,9 @@ postsig(int sig)
 	SIGDELSET(p->p_siglist, sig);
 	action = ps->ps_sigact[_SIG_IDX(sig)];
 #ifdef KTRACE
-	if (KTRPOINT(td, KTR_PSIG))
-		ktrpsig(p, sig, action, p->p_flag & P_OLDMASK ?
-			&p->p_oldsigmask : &p->p_sigmask, 0);
+	if (KTRPOINT(lp->lwp_thread, KTR_PSIG))
+		ktrpsig(p, sig, action, lp->lwp_flag & LWP_OLDMASK ?
+			&lp->lwp_oldsigmask : &lp->lwp_sigmask, 0);
 #endif
 	STOPEVENT(p, S_SIG, sig);
 
@@ -1510,7 +1518,7 @@ postsig(int sig)
 		/*
 		 * If we get here, the signal must be caught.
 		 */
-		KASSERT(action != SIG_IGN && !SIGISMEMBER(p->p_sigmask, sig),
+		KASSERT(action != SIG_IGN && !SIGISMEMBER(lp->lwp_sigmask, sig),
 		    ("postsig action"));
 
 		crit_enter();
@@ -1552,18 +1560,19 @@ postsig(int sig)
 		 * mask from before the sigsuspend is what we want
 		 * restored after the signal processing is completed.
 		 */
-		if (p->p_flag & P_OLDMASK) {
-			returnmask = p->p_oldsigmask;
-			p->p_flag &= ~P_OLDMASK;
+		if (lp->lwp_flag & LWP_OLDMASK) {
+			returnmask = lp->lwp_oldsigmask;
+			lp->lwp_flag &= ~LWP_OLDMASK;
 		} else {
-			returnmask = p->p_sigmask;
+			returnmask = lp->lwp_sigmask;
 		}
-		SIGSETOR(p->p_sigmask, ps->ps_catchmask[_SIG_IDX(sig)]);
+
+		SIGSETOR(lp->lwp_sigmask, ps->ps_catchmask[_SIG_IDX(sig)]);
 		if (!SIGISMEMBER(ps->ps_signodefer, sig))
-			SIGADDSET(p->p_sigmask, sig);
+			SIGADDSET(lp->lwp_sigmask, sig);
 
 		crit_exit();
-		p->p_lwp.lwp_ru.ru_nsignals++;
+		lp->lwp_ru.ru_nsignals++;
 		if (p->p_sig != sig) {
 			code = 0;
 		} else {
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c
index 7a33621..cf64a5c 100644
--- a/sys/kern/kern_synch.c
+++ b/sys/kern/kern_synch.c
@@ -143,7 +143,7 @@ SYSCTL_PROC(_kern, OID_AUTO, quantum, CTLTYPE_INT|CTLFLAG_RW,
  * can set CCPU_SHIFT to (FSHIFT + 1) which will use a slower/less-accurate
  * (more general) method of calculating the %age of CPU used by a process.
  *
- * decay 95% of `p_pctcpu' in 60 seconds; see CCPU_SHIFT before changing 
+ * decay 95% of `lwp_pctcpu' in 60 seconds; see CCPU_SHIFT before changing
  */
 #define CCPU_SHIFT	11
 
@@ -190,19 +190,23 @@ schedcpu(void *arg)
 static int
 schedcpu_stats(struct proc *p, void *data __unused)
 {
+	struct lwp *lp;
+
+	/* XXX lwp */
+	lp = FIRST_LWP_IN_PROC(p);
 	crit_enter();
 	p->p_swtime++;
 	if (p->p_stat == SSLEEP)
-		p->p_slptime++;
+		lp->lwp_slptime++;
 
 	/*
 	 * Only recalculate processes that are active or have slept
 	 * less then 2 seconds.  The schedulers understand this.
 	 */
-	if (p->p_slptime <= 1) {
-		p->p_usched->recalculate(&p->p_lwp);
+	if (lp->lwp_slptime <= 1) {
+		p->p_usched->recalculate(lp);
 	} else {
-		p->p_pctcpu = (p->p_pctcpu * ccpu) >> FSHIFT;
+		lp->lwp_pctcpu = (lp->lwp_pctcpu * ccpu) >> FSHIFT;
 	}
 	crit_exit();
 	return(0);
@@ -217,18 +221,21 @@ static int
 schedcpu_resource(struct proc *p, void *data __unused)
 {
 	u_int64_t ttime;
+	struct lwp *lp;
 
+	/* XXX lwp */
+	lp = FIRST_LWP_IN_PROC(p);
 	crit_enter();
 	if (p->p_stat == SIDL || 
 	    (p->p_flag & P_ZOMBIE) ||
 	    p->p_limit == NULL || 
-	    p->p_thread == NULL
+	    lp->lwp_thread == NULL
 	) {
 		crit_exit();
 		return(0);
 	}
 
-	ttime = p->p_thread->td_sticks + p->p_thread->td_uticks;
+	ttime = lp->lwp_thread->td_sticks + lp->lwp_thread->td_uticks;
 
 	switch(plimit_testcpulimit(p->p_limit, ttime)) {
 	case PLIMIT_TESTCPU_KILL:
@@ -326,6 +333,7 @@ int
 tsleep(void *ident, int flags, const char *wmesg, int timo)
 {
 	struct thread *td = curthread;
+	struct lwp *lp = td->td_lwp;
 	struct proc *p = td->td_proc;		/* may be NULL */
 	globaldata_t gd;
 	int sig;
@@ -379,7 +387,7 @@ tsleep(void *ident, int flags, const char *wmesg, int timo)
 	/*
 	 * Setup for the current process (if this is a process). 
 	 */
-	if (p) {
+	if (lp) {
 		if (catch) {
 			/*
 			 * Early termination if PCATCH was set and a
@@ -389,7 +397,7 @@ tsleep(void *ident, int flags, const char *wmesg, int timo)
 			 * Early termination only occurs when tsleep() is
 			 * entered while in a normal SRUN state.
 			 */
-			if ((sig = CURSIG(p)) != 0)
+			if ((sig = CURSIG(lp)) != 0)
 				goto resume;
 
 			/*
@@ -415,8 +423,8 @@ tsleep(void *ident, int flags, const char *wmesg, int timo)
 		 */
 		if (flags & PNORESCHED)
 			td->td_flags |= TDF_NORESCHED;
-		p->p_usched->release_curproc(&p->p_lwp);
-		p->p_slptime = 0;
+		p->p_usched->release_curproc(lp);
+		lp->lwp_slptime = 0;
 	}
 
 	/*
@@ -442,13 +450,13 @@ tsleep(void *ident, int flags, const char *wmesg, int timo)
 	/*
 	 * Beddy bye bye.
 	 */
-	if (p) {
+	if (lp) {
 		/*
 		 * Ok, we are sleeping.  Place us in the SSLEEP state.
 		 */
 		KKASSERT((p->p_flag & P_ONRUNQ) == 0);
 		p->p_stat = SSLEEP;
-		p->p_lwp.lwp_ru.ru_nvcsw++;
+		lp->lwp_ru.ru_nvcsw++;
 		lwkt_switch();
 
 		/*
@@ -456,9 +464,9 @@ tsleep(void *ident, int flags, const char *wmesg, int timo)
 		 * slept for over a second, recalculate our estcpu.
 		 */
 		p->p_stat = SRUN;
-		if (p->p_slptime)
-			p->p_usched->recalculate(&p->p_lwp);
-		p->p_slptime = 0;
+		if (lp->lwp_slptime)
+			p->p_usched->recalculate(lp);
+		lp->lwp_slptime = 0;
 	} else {
 		lwkt_switch();
 	}
@@ -508,7 +516,7 @@ resume:
 		if (catch && error == 0) {
 			if ((p->p_flag & P_MAILBOX) && sig == 0) {
 				error = EINTR;
-			} else if ((sig != 0 || (sig = CURSIG(p)))) {
+			} else if (sig != 0 || (sig = CURSIG(lp))) {
 				if (SIGISMEMBER(p->p_sigacts->ps_sigintr, sig))
 					error = EINTR;
 				else
@@ -899,11 +907,13 @@ wakeup_domain_one(void *ident, int domain)
 void
 setrunnable(struct proc *p)
 {
+	/* XXX lwp */
+	struct lwp *lp = FIRST_LWP_IN_PROC(p);
 	crit_enter();
 	ASSERT_MP_LOCK_HELD(curthread);
 	p->p_flag &= ~P_STOPPED;
 	if (p->p_stat == SSLEEP && (p->p_flag & P_BREAKTSLEEP)) {
-		unsleep_and_wakeup_thread(p->p_thread);
+		unsleep_and_wakeup_thread(lp->lwp_thread);
 	}
 	crit_exit();
 }
@@ -995,12 +1005,15 @@ loadav(void *arg)
 static int
 loadav_count_runnable(struct proc *p, void *data)
 {
+	struct lwp *lp;
 	int *nrunp = data;
 	thread_t td;
 
+	/* XXX lwp */
+	lp = FIRST_LWP_IN_PROC(p);
 	switch (p->p_stat) {
 	case SRUN:
-		if ((td = p->p_thread) == NULL)
+		if ((td = lp->lwp_thread) == NULL)
 			break;
 		if (td->td_flags & TDF_BLOCKED)
 			break;
diff --git a/sys/kern/kern_threads.c b/sys/kern/kern_threads.c
index fd2556f..a738a41 100644
--- a/sys/kern/kern_threads.c
+++ b/sys/kern/kern_threads.c
@@ -58,6 +58,14 @@
 #include <sys/sysproto.h>
 #include <sys/uio.h>		/* uio_yield() fixme */
 
+
+/*
+ * XXX lwp
+ *
+ * I am unhappy code, please remove me
+ */
+
+
 /*
  * Low level support for sleep/wakeup paradigm
  * If a timeout is specified:
@@ -132,7 +140,8 @@ sys_thr_wakeup(struct thr_wakeup_args *uap)
 	}
 
 	pSlave->p_wakeup++;
-	if((pSlave->p_stat == SSLEEP) && (pSlave->p_wchan == pSlave)) {
+	if((pSlave->p_stat == SSLEEP) &&
+	   (FIRST_LWP_IN_PROC(pSlave)->lwp_wchan == pSlave)) {
 		wakeup(pSlave);
 		return(0);
 	}
diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c
index 7a7f71e..3635375 100644
--- a/sys/kern/kern_time.c
+++ b/sys/kern/kern_time.c
@@ -268,7 +268,7 @@ nanosleep1(struct timespec *rqt, struct timespec *rmt)
 				lwkt_switch();
 				systimer_del(&info); /* make sure it's gone */
 			}
-			error = iscaught(td->td_proc);
+			error = iscaught(td->td_lwp);
 		} else if (tv.tv_sec == 0) {
 			error = tsleep(&nanowait, PCATCH, "nanslp", ticks);
 		} else {
diff --git a/sys/kern/kern_usched.c b/sys/kern/kern_usched.c
index 261f895..9d3adf7 100644
--- a/sys/kern/kern_usched.c
+++ b/sys/kern/kern_usched.c
@@ -185,8 +185,12 @@ sys_usched_set(struct usched_set_args *uap)
 		 * disassociation' and another ABI call to do a 'full
 		 * reassociation'
 		 */
+		/* XXX lwp have to deal with multiple lwps here */
+		if (p->p_nthreads != 1)
+			return (EINVAL);
 		if (item && item != p->p_usched) {
-			p->p_usched->release_curproc(&p->p_lwp);
+			/* XXX lwp */
+			p->p_usched->release_curproc(ONLY_LWP_IN_PROC(p));
 			p->p_usched = item;
 		} else if (item == NULL) {
 			error = EINVAL;
diff --git a/sys/kern/lwkt_caps.c b/sys/kern/lwkt_caps.c
index 485bcc5..6625f02 100644
--- a/sys/kern/lwkt_caps.c
+++ b/sys/kern/lwkt_caps.c
@@ -508,15 +508,10 @@ caps_free(caps_kinfo_t caps)
  * forked condition and reforge the connection.
  */
 void
-caps_fork(struct proc *p1, struct proc *p2, int flags)
+caps_fork(struct thread *td1, struct thread *td2, int flags)
 {
     caps_kinfo_t caps1;
     caps_kinfo_t caps2;
-    thread_t td1;
-    thread_t td2;
-
-    td1 = p1->p_thread;
-    td2 = p2->p_thread;
 
     /*
      * Create dummy entries with the same id's as the originals.  Note
diff --git a/sys/kern/lwkt_msgport.c b/sys/kern/lwkt_msgport.c
index d90e2e8..e189b7b 100644
--- a/sys/kern/lwkt_msgport.c
+++ b/sys/kern/lwkt_msgport.c
@@ -685,7 +685,7 @@ lwkt_default_waitport(lwkt_port_t port, lwkt_msg_t msg)
 		     * completion after sending an abort request.
 		     */
 		    if (msg->ms_flags & MSGF_PCATCH) {
-			if (sentabort == 0 && CURSIG(port->mp_td->td_proc)) {
+			if (sentabort == 0 && CURSIG(port->mp_td->td_lwp)) {
 			    sentabort = 1;
 			    lwkt_abortmsg(msg);
 			    continue;
diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c
index 68eab0f..fde5711 100644
--- a/sys/kern/sys_generic.c
+++ b/sys/kern/sys_generic.c
@@ -1072,6 +1072,7 @@ void
 selrecord(struct thread *selector, struct selinfo *sip)
 {
 	struct proc *p;
+	struct lwp *lp;
 	pid_t mypid;
 
 	if ((p = selector->td_proc) == NULL)
@@ -1080,8 +1081,12 @@ selrecord(struct thread *selector, struct selinfo *sip)
 	mypid = p->p_pid;
 	if (sip->si_pid == mypid)
 		return;
+	/* XXX lwp
+	 * pfind ? this is seriously broken code for LWP
+	 */
 	if (sip->si_pid && (p = pfind(sip->si_pid)) &&
-	    p->p_wchan == (caddr_t)&selwait) {
+	    (lp = FIRST_LWP_IN_PROC(p)) &&
+	    lp->lwp_wchan == (caddr_t)&selwait) {
 		sip->si_flags |= SI_COLL;
 	} else {
 		sip->si_pid = mypid;
@@ -1106,8 +1111,10 @@ selwakeup(struct selinfo *sip)
 	p = pfind(sip->si_pid);
 	sip->si_pid = 0;
 	if (p != NULL) {
+		/* XXX lwp */
+		struct lwp *lp = FIRST_LWP_IN_PROC(p);
 		crit_enter();
-		if (p->p_wchan == (caddr_t)&selwait) {
+		if (lp->lwp_wchan == (caddr_t)&selwait) {
 			/*
 			 * Flag the process to break the tsleep when 
 			 * setrunnable is called, but only call setrunnable
diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c
index f0123ae..6de396d 100644
--- a/sys/kern/sys_process.c
+++ b/sys/kern/sys_process.c
@@ -273,6 +273,7 @@ int
 kern_ptrace(struct proc *curp, int req, pid_t pid, void *addr, int data, int *res)
 {
 	struct proc *p, *pp;
+	struct lwp *lp;
 	struct iovec iov;
 	struct uio uio;
 	struct ptrace_io_desc *piod;
@@ -377,6 +378,8 @@ kern_ptrace(struct proc *curp, int req, pid_t pid, void *addr, int data, int *re
 		return EINVAL;
 	}
 
+	/* XXX lwp */
+	lp = FIRST_LWP_IN_PROC(p);
 #ifdef FIX_SSTEP
 	/*
 	 * Single step fixup ala procfs
@@ -416,14 +419,14 @@ kern_ptrace(struct proc *curp, int req, pid_t pid, void *addr, int data, int *re
 		PHOLD(p);
 
 		if (req == PT_STEP) {
-			if ((error = ptrace_single_step (&p->p_lwp))) {
+			if ((error = ptrace_single_step (lp))) {
 				PRELE(p);
 				return error;
 			}
 		}
 
 		if (addr != (void *)1) {
-			if ((error = ptrace_set_pc (p,
+			if ((error = ptrace_set_pc (lp,
 			    (u_long)(uintfptr_t)addr))) {
 				PRELE(p);
 				return error;
@@ -485,7 +488,7 @@ kern_ptrace(struct proc *curp, int req, pid_t pid, void *addr, int data, int *re
 		uio.uio_resid = sizeof(int);
 		uio.uio_segflg = UIO_SYSSPACE;
 		uio.uio_rw = write ? UIO_WRITE : UIO_READ;
-		uio.uio_td = curp->p_thread;
+		uio.uio_td = curthread;
 		error = procfs_domem(curp, p, NULL, &uio);
 		if (uio.uio_resid != 0) {
 			/*
@@ -519,7 +522,7 @@ kern_ptrace(struct proc *curp, int req, pid_t pid, void *addr, int data, int *re
 		uio.uio_offset = (off_t)(uintptr_t)piod->piod_offs;
 		uio.uio_resid = piod->piod_len;
 		uio.uio_segflg = UIO_USERSPACE;
-		uio.uio_td = curp->p_thread;
+		uio.uio_td = curthread;
 		switch (piod->piod_op) {
 		case PIOD_READ_D:
 		case PIOD_READ_I:
id *addr, int data, int *re
 			uio.uio_resid = sizeof(struct reg);
 			uio.uio_segflg = UIO_SYSSPACE;
 			uio.uio_rw = write ? UIO_WRITE : UIO_READ;
-			uio.uio_td = curp->p_thread;
+			uio.uio_td = curthread;
 			return (procfs_doregs(curp, p, NULL, &uio));
 		}
 #endif /* defined(PT_SETREGS) || defined(PT_GETREGS) */
@@ -587,7 +590,7 @@ kern_ptrace(struct proc *curp, int req, pid_t pid, void *addr, int data, int *re
 			uio.uio_resid = sizeof(struct fpreg);
 			uio.uio_segflg = UIO_SYSSPACE;
 			uio.uio_rw = write ? UIO_WRITE : UIO_READ;
-			uio.uio_td = curp->p_thread;
+			uio.uio_td = curthread;
 			return (procfs_dofpregs(curp, p, NULL, &uio));
 		}
 #endif /* defined(PT_SETFPREGS) || defined(PT_GETFPREGS) */
@@ -613,7 +616,7 @@ kern_ptrace(struct proc *curp, int req, pid_t pid, void *addr, int data, int *re
 			uio.uio_resid = sizeof(struct dbreg);
 			uio.uio_segflg = UIO_SYSSPACE;
 			uio.uio_rw = write ? UIO_WRITE : UIO_READ;
-			uio.uio_td = curp->p_thread;
+			uio.uio_td = curthread;
 			return (procfs_dodbregs(curp, p, NULL, &uio));
 		}
 #endif /* defined(PT_SETDBREGS) || defined(PT_GETDBREGS) */
diff --git a/sys/kern/tty.c b/sys/kern/tty.c
index a7ec5bb..96e845b 100644
--- a/sys/kern/tty.c
+++ b/sys/kern/tty.c
@@ -760,6 +760,7 @@ int
 ttioctl(struct tty *tp, u_long cmd, void *data, int flag)
 {
 	struct thread *td = curthread;
+	struct lwp *lp = td->td_lwp;
 	struct proc *p = td->td_proc;
 	int error;
 
@@ -801,7 +802,7 @@ ttioctl(struct tty *tp, u_long cmd, void *data, int flag)
 #endif
 		while (isbackground(p, tp) && !(p->p_flag & P_PPWAIT) &&
 		    !SIGISMEMBER(p->p_sigignore, SIGTTOU) &&
-		    !SIGISMEMBER(p->p_sigmask, SIGTTOU)) {
+		    !SIGISMEMBER(lp->lwp_sigmask, SIGTTOU)) {
 			if (p->p_pgrp->pg_jobc == 0)
 				return (EIO);
 			pgsignal(p->p_pgrp, SIGTTOU, 1);
@@ -1542,11 +1543,14 @@ ttread(struct tty *tp, struct uio *uio, int flag)
 	tcflag_t lflag;
 	cc_t *cc = tp->t_cc;
 	struct proc *pp;
+	struct lwp *lp;
 	int first, error = 0;
 	int has_stime = 0, last_cc = 0;
 	long slp = 0;		/* XXX this should be renamed `timo'. */
 	struct timeval stime;
 
+	lp = curthread->td_lwp;
+
 loop:
 	crit_enter();
 	lflag = tp->t_lflag;
@@ -1565,7 +1569,7 @@ loop:
 	if ((pp = curproc) && isbackground(pp, tp)) {
 		crit_exit();
 		if (SIGISMEMBER(pp->p_sigignore, SIGTTIN) ||
-		    SIGISMEMBER(pp->p_sigmask, SIGTTIN) ||
+		    SIGISMEMBER(lp->lwp_sigmask, SIGTTIN) ||
 		    (pp->p_flag & P_PPWAIT) || pp->p_pgrp->pg_jobc == 0)
 			return (EIO);
 		pgsignal(pp->p_pgrp, SIGTTIN, 1);
@@ -1833,9 +1837,11 @@ ttwrite(struct tty *tp, struct uio *uio, int flag)
 	char *cp = NULL;
 	int cc, ce;
 	struct proc *pp;
+	struct lwp *lp;
 	int i, hiwat, cnt, error;
 	char obuf[OBUFSIZ];
 
+	lp = curthread->td_lwp;
 	hiwat = tp->t_ohiwat;
 	cnt = uio->uio_resid;
 	error = 0;
@@ -1868,7 +1874,7 @@ loop:
 	if ((pp = curproc) && isbackground(pp, tp) &&
 	    ISSET(tp->t_lflag, TOSTOP) && !(pp->p_flag & P_PPWAIT) &&
 	    !SIGISMEMBER(pp->p_sigignore, SIGTTOU) &&
-	    !SIGISMEMBER(pp->p_sigmask, SIGTTOU)) {
+	    !SIGISMEMBER(lp->lwp_sigmask, SIGTTOU)) {
 		if (pp->p_pgrp->pg_jobc == 0) {
 			error = EIO;
 			goto out;
@@ -2307,6 +2313,7 @@ void
 ttyinfo(struct tty *tp)
 {
 	struct proc *p, *pick;
+	struct lwp *lp;
 	struct rusage ru;
 	int tmp;
 
@@ -2332,8 +2339,7 @@ ttyinfo(struct tty *tp)
 		 * in particular the wmesg, require a critical section for
 		 * safe access (YYY and we are still not MP safe).
 		 *
-		 * NOTE: p_wmesg is p_thread->td_wmesg, and p_comm is
-		 * p_thread->td_comm.
+		 * NOTE: lwp_wmesg is lwp_thread->td_wmesg.
 		 */
 		char buf[64];
 		const char *str;
@@ -2350,18 +2356,30 @@ ttyinfo(struct tty *tp)
 				pick = p;
 		}
 
+		/* XXX lwp */
+		lp = FIRST_LWP_IN_PROC(pick);
+		if (lp == NULL) {
+			ttyprintf(tp, "foreground process without lwp\n");
+			tp->t_rocount = 0;
+			return;
+		}
+
 		/*
 		 * Figure out what wait/process-state message, and command
 		 * buffer to present
 		 */
+		/*
+		 * XXX lwp This is a horrible mixture.  We need to rework this
+		 * as soon as lwps have their own runnable status.
+		 */
 		if (pick->p_flag & P_WEXIT)
 			str = "exiting";
 		else if (pick->p_stat == SRUN)
 			str = "running";
 		else if (pick->p_stat == SIDL)
 			str = "spawning";
-		else if (pick->p_wmesg)	/* p_thread must not be NULL */
-			str = pick->p_wmesg;
+		else if (lp->lwp_wmesg)	/* lwp_thread must not be NULL */
+			str = lp->lwp_wmesg;
 		else
 			str = "iowait";
 
@@ -2373,14 +2391,14 @@ ttyinfo(struct tty *tp)
 		 * 'pick' becomes invalid the moment we exit the critical
 		 * section.
 		 */
-		if (pick->p_thread && (pick->p_flag & P_SWAPPEDOUT) == 0) {
+		if (lp->lwp_thread && (pick->p_flag & P_SWAPPEDOUT) == 0) {
 			calcru_proc(pick, &ru);
 			isinmem = 1;
 		} else {
 			isinmem = 0;
 		}
 
-		pctcpu = (pick->p_pctcpu * 10000 + FSCALE / 2) >> FSHIFT;
+		pctcpu = (lp->lwp_pctcpu * 10000 + FSCALE / 2) >> FSHIFT;
 
 		if (pick->p_stat == SIDL || (pick->p_flag & P_ZOMBIE))
 		    vmsz = 0;
@@ -2424,9 +2442,14 @@ ttyinfo(struct tty *tp)
 static int
 proc_compare(struct proc *p1, struct proc *p2)
 {
-
+	struct lwp *lp1, *lp2;
 	if (p1 == NULL)
 		return (1);
+
+	/* XXX lwp */
+	lp1 = FIRST_LWP_IN_PROC(p1);
+	lp2 = FIRST_LWP_IN_PROC(p2);
+
 	/*
 	 * see if at least one of them is runnable
 	 */
@@ -2439,9 +2462,9 @@ proc_compare(struct proc *p1, struct proc *p2)
 		/*
 		 * tie - favor one with highest recent cpu utilization
 		 */
-		if (p2->p_cpticks > p1->p_cpticks)
+		if (lp2->lwp_cpticks > lp1->lwp_cpticks)
 			return (1);
-		if (p1->p_cpticks > p2->p_cpticks)
+		if (lp1->lwp_cpticks > lp2->lwp_cpticks)
 			return (0);
 		return (p2->p_pid > p1->p_pid);	/* tie - return highest pid */
 	}
@@ -2459,9 +2482,9 @@ proc_compare(struct proc *p1, struct proc *p2)
 	/*
 	 * pick the one with the smallest sleep time
 	 */
-	if (p2->p_slptime > p1->p_slptime)
+	if (lp2->lwp_slptime > lp1->lwp_slptime)
 		return (0);
-	if (p1->p_slptime > p2->p_slptime)
+	if (lp1->lwp_slptime > lp2->lwp_slptime)
 		return (1);
 	/*
 	 * favor one sleeping in a non-interruptible sleep
diff --git a/sys/kern/tty_pty.c b/sys/kern/tty_pty.c
index 8dd02cf..96c7120 100644
--- a/sys/kern/tty_pty.c
+++ b/sys/kern/tty_pty.c
@@ -233,13 +233,17 @@ ptsread(struct dev_read_args *ap)
 	struct proc *p = curproc;
 	struct tty *tp = dev->si_tty;
 	struct pt_ioctl *pti = dev->si_drv1;
+	struct lwp *lp;
+
 	int error = 0;
 
+	lp = curthread->td_lwp;
+
 again:
 	if (pti->pt_flags & PF_REMOTE) {
 		while (isbackground(p, tp)) {
 			if (SIGISMEMBER(p->p_sigignore, SIGTTIN) ||
-			    SIGISMEMBER(p->p_sigmask, SIGTTIN) ||
+			    SIGISMEMBER(lp->lwp_sigmask, SIGTTIN) ||
 			    p->p_pgrp->pg_jobc == 0 || p->p_flag & P_PPWAIT)
 				return (EIO);
 			pgsignal(p->p_pgrp, SIGTTIN, 1);
diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c
index 0feb289..16b23bf 100644
--- a/sys/kern/vfs_aio.c
+++ b/sys/kern/vfs_aio.c
@@ -347,7 +347,8 @@ aio_free_entry(struct aiocblist *aiocbe)
 	}
 
 	/* aiocbe is going away, we need to destroy any knotes */
-	knote_remove(p->p_thread, &aiocbe->klist);
+	/* XXX lwp knote wants a thread, but only cares about the process */
+	knote_remove(FIRST_LWP_IN_PROC(p)->lwp_thread, &aiocbe->klist);
 
 	if ((ki->kaio_flags & KAIO_WAKEUP) || ((ki->kaio_flags & KAIO_RUNDOWN)
 	    && ((ki->kaio_buffer_count == 0) && (ki->kaio_queue_count == 0)))) {
@@ -874,11 +875,11 @@ aio_newproc(void)
 	struct lwp *lp, *nlp;
 	struct proc *np;
 
-	lp = &proc0.p_lwp;
+	lp = &lwp0;
 	error = fork1(lp, RFPROC|RFMEM|RFNOWAIT, &np);
 	if (error)
 		return error;
-	nlp = LIST_FIRST(&np->p_lwps);
+	nlp = ONLY_LWP_IN_PROC(np);
 	cpu_set_fork_handler(nlp, aio_daemon, curproc);
 	start_forked_proc(lp, np);
 
@@ -1262,7 +1263,8 @@ _aio_aqueue(struct aiocb *job, struct aio_liojob *lj, int type)
 	kev.filter = EVFILT_AIO;
 	kev.flags = EV_ADD | EV_ENABLE | EV_FLAG1;
 	kev.data = (intptr_t)aiocbe;
-	error = kqueue_register(kq, &kev, p->p_thread);
+	/* XXX lwp kqueue_register takes a thread, but only uses its proc */
+	error = kqueue_register(kq, &kev, FIRST_LWP_IN_PROC(p)->lwp_thread);
 aqueue_fail:
 	if (error) {
 		fdrop(fp);
diff --git a/sys/netproto/ncp/ncp_ncp.c b/sys/netproto/ncp/ncp_ncp.c
index 663708b..54a626f 100644
--- a/sys/netproto/ncp/ncp_ncp.c
+++ b/sys/netproto/ncp/ncp_ncp.c
@@ -89,14 +89,16 @@ int
 ncp_chkintr(struct ncp_conn *conn, struct thread *td)
 {
 	sigset_t tmpset;
+	struct lwp *lp = td->td_lwp;
 	struct proc *p = td->td_proc;
 
 	if (p == NULL)
 		return 0;
 	tmpset = p->p_siglist;
-	SIGSETNAND(tmpset, p->p_sigmask);
+	SIGSETOR(tmpset, lp->lwp_siglist);
+	SIGSETNAND(tmpset, lp->lwp_sigmask);
 	SIGSETNAND(tmpset, p->p_sigignore);
-	if (SIGNOTEMPTY(p->p_siglist) && NCP_SIGMASK(tmpset))
+	if (SIGNOTEMPTY(tmpset) && NCP_SIGMASK(tmpset))
                 return EINTR;
 	return 0;
 }
diff --git a/sys/netproto/smb/smb_iod.c b/sys/netproto/smb/smb_iod.c
index 39e289c..cd2c20e 100644
--- a/sys/netproto/smb/smb_iod.c
+++ b/sys/netproto/smb/smb_iod.c
@@ -682,7 +682,8 @@ smb_iod_create(struct smb_vc *vcp)
 		kfree(iod, M_SMBIOD);
 		return error;
 	}
-	iod->iod_td = newp->p_thread;
+	/* XXX lwp */
+	iod->iod_td = ONLY_LWP_IN_PROC(newp)->lwp_thread;
 	return 0;
 }
 
diff --git a/sys/netproto/smb/smb_subr.c b/sys/netproto/smb/smb_subr.c
index c42a48e..f198e1a 100644
--- a/sys/netproto/smb/smb_subr.c
+++ b/sys/netproto/smb/smb_subr.c
@@ -78,13 +78,16 @@ smb_proc_intr(struct thread *td)
 {
 	sigset_t tmpset;
 	struct proc *p;
+	struct lwp *lp;
 
 	if (td == NULL || (p = td->td_proc) == NULL)
 		return 0;
+	lp = td->td_lwp;
 	tmpset = p->p_siglist;
-	SIGSETNAND(tmpset, p->p_sigmask);
+	SIGSETOR(tmpset, lp->lwp_siglist);
+	SIGSETNAND(tmpset, lp->lwp_sigmask);
 	SIGSETNAND(tmpset, p->p_sigignore);
-	if (SIGNOTEMPTY(p->p_siglist) && SMB_SIGMASK(tmpset))
+	if (SIGNOTEMPTY(tmpset) && SMB_SIGMASK(tmpset))
                 return EINTR;
 	return 0;
 }
@@ -374,7 +377,7 @@ kthread_create2(void (*func)(void *), void *arg,
 	struct proc *p2;
 	struct lwp *lp2;
 
-	error = fork1(&proc0.p_lwp, RFMEM | RFFDG | RFPROC | flags, &p2);
+	error = fork1(&lwp0, RFMEM | RFFDG | RFPROC | flags, &p2);
 	if (error)
 		return error;
 
@@ -386,7 +389,7 @@ kthread_create2(void (*func)(void *), void *arg,
 	p2->p_flag |= P_SYSTEM;
 	p2->p_procsig->ps_flag |= PS_NOCLDWAIT;
 
-	lp2 = LIST_FIRST(&p2->p_lwps);
+	lp2 = ONLY_LWP_IN_PROC(p2);
 
 	/* set up arg0 for 'ps', et al */
 	__va_start(ap, fmt);
@@ -395,7 +398,7 @@ kthread_create2(void (*func)(void *), void *arg,
 
 	/* call the processes' main()... */
 	cpu_set_fork_handler(lp2, func, arg);
-	start_forked_proc(&proc0.p_lwp, p2);
+	start_forked_proc(&lwp0, p2);
 
 	return 0;
 }
diff --git a/sys/platform/pc32/i386/machdep.c b/sys/platform/pc32/i386/machdep.c
index 60d9e84..ce723db 100644
--- a/sys/platform/pc32/i386/machdep.c
+++ b/sys/platform/pc32/i386/machdep.c
@@ -437,8 +437,7 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
 		sf.sf_uc.uc_mcontext.mc_xflags |= PGEX_MAILBOX;
 
 	/* Allocate and validate space for the signal handler context. */
-	/* XXX lwp flags */
-        if ((p->p_flag & P_ALTSTACK) != 0 && !oonstack &&
+        if ((lp->lwp_flag & LWP_ALTSTACK) != 0 && !oonstack &&
 	    SIGISMEMBER(psp->ps_sigonstack, sig)) {
 		sfp = (struct sigframe *)(lp->lwp_sigstk.ss_sp +
 		    lp->lwp_sigstk.ss_size - sizeof(struct sigframe));
@@ -628,7 +627,7 @@ sys_sigreturn(struct sigreturn_args *uap)
 
 		/* go back to user mode if both flags are set */
 		if ((eflags & PSL_VIP) && (eflags & PSL_VIF))
-			trapsignal(lp->lwp_proc, SIGBUS, 0);
+			trapsignal(lp, SIGBUS, 0);
 
 		if (vm86->vm86_has_vme) {
 			eflags = (tf->tf_eflags & ~VME_USERCHANGE) |
@@ -677,7 +676,7 @@ sys_sigreturn(struct sigreturn_args *uap)
 		cs = ucp->uc_mcontext.mc_cs;
 		if (!CS_SECURE(cs)) {
 			kprintf("sigreturn: cs = 0x%x\n", cs);
-			trapsignal(lp->lwp_proc, SIGBUS, T_PROTFLT);
+			trapsignal(lp, SIGBUS, T_PROTFLT);
 			return(EINVAL);
 		}
 		bcopy(&ucp->uc_mcontext.mc_gs, regs, sizeof(struct trapframe));
@@ -958,10 +957,12 @@ cpu_idle(void)
  * Clear registers on exec
  */
 void
-setregs(struct lwp *lp, u_long entry, u_long stack, u_long ps_strings)
+exec_setregs(u_long entry, u_long stack, u_long ps_strings)
 {
+	struct thread *td = curthread;
+	struct lwp *lp = td->td_lwp;
+	struct pcb *pcb = td->td_pcb;
 	struct trapframe *regs = lp->lwp_md.md_regs;
-	struct pcb *pcb = lp->lwp_thread->td_pcb;
 
 	/* was i386_user_cleanup() in NetBSD */
 	user_ldt_free(pcb);
@@ -991,7 +992,7 @@ setregs(struct lwp *lp, u_long entry, u_long stack, u_long ps_strings)
                 pcb->pcb_dr3 = 0;
                 pcb->pcb_dr6 = 0;
                 pcb->pcb_dr7 = 0;
-                if (pcb == curthread->td_pcb) {
+                if (pcb == td->td_pcb) {
 		        /*
 			 * Clear the debug registers on the running
 			 * CPU, otherwise they will end up affecting
@@ -1009,7 +1010,7 @@ setregs(struct lwp *lp, u_long entry, u_long stack, u_long ps_strings)
 	 * traps to the emulator (if it is done at all) mainly because
 	 * emulators don't provide an entry point for initialization.
 	 */
-	lp->lwp_thread->td_pcb->pcb_flags &= ~FP_SOFTFP;
+	pcb->pcb_flags &= ~FP_SOFTFP;
 
 	/*
 	 * note: do not set CR0_TS here.  npxinit() must do it after clearing
@@ -2075,7 +2076,7 @@ init386(int first)
 	thread0.td_pcb->pcb_flags = 0;
 	thread0.td_pcb->pcb_cr3 = (int)IdlePTD;	/* should already be setup */
 	thread0.td_pcb->pcb_ext = 0;
-	proc0.p_lwp.lwp_md.md_regs = &proc0_tf;
+	lwp0.lwp_md.md_regs = &proc0_tf;
 }
 
 /*
@@ -2156,9 +2157,9 @@ f00f_hack(void *unused)
 #endif /* defined(I586_CPU) && !NO_F00F_HACK */
 
 int
-ptrace_set_pc(struct proc *p, unsigned long addr)
+ptrace_set_pc(struct lwp *lp, unsigned long addr)
 {
-	p->p_md.md_regs->tf_eip = addr;
+	lp->lwp_md.md_regs->tf_eip = addr;
 	return (0);
 }
 
diff --git a/sys/platform/pc32/i386/math_emulate.c b/sys/platform/pc32/i386/math_emulate.c
index 2117d14..f0016b4 100644
--- a/sys/platform/pc32/i386/math_emulate.c
+++ b/sys/platform/pc32/i386/math_emulate.c
@@ -606,7 +606,7 @@ static int __regoffset[] = {
 	tEAX, tECX, tEDX, tEBX, tESP, tEBP, tESI, tEDI
 };
 
-#define REG(x) (((int *)curproc->p_md.md_regs)[__regoffset[(x)]])
+#define REG(x) (((int *)curthread->td_lwp->lwp_md.md_regs)[__regoffset[(x)]])
 
 static char *
 sib(struct trapframe *info, int mod)
diff --git a/sys/platform/pc32/i386/pmap.c b/sys/platform/pc32/i386/pmap.c
index 9a4a667..77b1fea 100644
--- a/sys/platform/pc32/i386/pmap.c
+++ b/sys/platform/pc32/i386/pmap.c
@@ -898,10 +898,12 @@ pmap_init_thread(thread_t td)
 void
 pmap_init_proc(struct proc *p, struct thread *td)
 {
+	struct lwp *lp = ONLY_LWP_IN_PROC(p);
+
 	p->p_addr = (void *)td->td_kstack;
-	p->p_thread = td;
+	lp->lwp_thread = td;
 	td->td_proc = p;
-	td->td_lwp = &p->p_lwp;
+	td->td_lwp = lp;
 	td->td_switch = cpu_heavy_switch;
 #ifdef SMP
 	KKASSERT(td->td_mpcount == 1);
@@ -916,13 +918,16 @@ pmap_init_proc(struct proc *p, struct thread *td)
 struct thread *
 pmap_dispose_proc(struct proc *p)
 {
-	struct thread *td;
+	struct thread *td = NULL;
+	struct lwp *lp;
 
 	KASSERT(p->p_lock == 0, ("attempt to dispose referenced proc! %p", p));
 
-	if ((td = p->p_thread) != NULL) {
-	    p->p_thread = NULL;
+	lp = ONLY_LWP_IN_PROC(p);
+	if (lp != NULL && (td = lp->lwp_thread) != NULL) {
 	    td->td_proc = NULL;
+	    td->td_lwp = NULL;
+	    lp->lwp_thread = NULL;
 	}
 	p->p_addr = NULL;
 	return(td);
@@ -3189,6 +3194,8 @@ pmap_activate(struct proc *p)
 {
 	pmap_t	pmap;
 
+	KKASSERT((p == curproc));
+
 	pmap = vmspace_pmap(p->p_vmspace);
 #if defined(SMP)
 	atomic_set_int(&pmap->pm_active, 1 << mycpu->gd_cpuid);
@@ -3198,8 +3205,8 @@ pmap_activate(struct proc *p)
 #if defined(SWTCH_OPTIM_STATS)
 	tlb_flush_count++;
 #endif
-	p->p_thread->td_pcb->pcb_cr3 = vtophys(pmap->pm_pdir);
-	load_cr3(p->p_thread->td_pcb->pcb_cr3);
+	curthread->td_pcb->pcb_cr3 = vtophys(pmap->pm_pdir);
+	load_cr3(curthread->td_pcb->pcb_cr3);
 }
 
 void
diff --git a/sys/platform/pc32/i386/procfs_machdep.c b/sys/platform/pc32/i386/procfs_machdep.c
index de74b3a..c788f73 100644
--- a/sys/platform/pc32/i386/procfs_machdep.c
+++ b/sys/platform/pc32/i386/procfs_machdep.c
@@ -84,33 +84,52 @@
 int
 procfs_read_regs(struct proc *p, struct reg *regs)
 {
+	struct lwp *lp;
+
 	if (p->p_flag & P_SWAPPEDOUT)
 		return (EIO);
-	return (fill_regs(&p->p_lwp, regs));
+	/* XXX lwp */
+	lp = FIRST_LWP_IN_PROC(p);
+	return (fill_regs(lp, regs));
 }
 
 int
 procfs_write_regs(struct proc *p, struct reg *regs)
 {
+	struct lwp *lp;
+
 	if (p->p_flag & P_SWAPPEDOUT)
 		return (EIO);
-	return (set_regs(&p->p_lwp, regs));
+
+	/* XXX lwp */
+	lp = FIRST_LWP_IN_PROC(p);
+	return (set_regs(lp, regs));
 }
 
 int
 procfs_read_dbregs(struct proc *p, struct dbreg *dbregs)
 {
+	struct lwp *lp;
+
 	if (p->p_flag & P_SWAPPEDOUT)
 		return (EIO);
-	return (fill_dbregs(&p->p_lwp, dbregs));
+
+	/* XXX lwp */
+	lp = FIRST_LWP_IN_PROC(p);
+	return (fill_dbregs(lp, dbregs));
 }
 
 int
 procfs_write_dbregs(struct proc *p, struct dbreg *dbregs)
 {
+	struct lwp *lp;
+
 	if (p->p_flag & P_SWAPPEDOUT)
 		return (EIO);
-	return (set_dbregs(&p->p_lwp, dbregs));
+
+	/* XXX lwp */
+	lp = FIRST_LWP_IN_PROC(p);
+	return (set_dbregs(lp, dbregs));
 }
 
 /*
@@ -121,23 +140,38 @@ procfs_write_dbregs(struct proc *p, struct dbreg *dbregs)
 int
 procfs_read_fpregs(struct proc *p, struct fpreg *fpregs)
 {
+	struct lwp *lp;
+
 	if (p->p_flag & P_SWAPPEDOUT)
 		return (EIO);
-	return (fill_fpregs(&p->p_lwp, fpregs));
+
+	/* XXX lwp */
+	lp = FIRST_LWP_IN_PROC(p);
+	return (fill_fpregs(lp, fpregs));
 }
 
 int
 procfs_write_fpregs(struct proc *p, struct fpreg *fpregs)
 {
+	struct lwp *lp;
+
 	if (p->p_flag & P_SWAPPEDOUT)
 		return (EIO);
-	return (set_fpregs(&p->p_lwp, fpregs));
+
+	/* XXX lwp */
+	lp = FIRST_LWP_IN_PROC(p);
+	return (set_fpregs(lp, fpregs));
 }
 
 int
 procfs_sstep(struct proc *p)
 {
+	struct lwp *lp;
+
 	if (p->p_flag & P_SWAPPEDOUT)
 		return (EIO);
-	return (ptrace_single_step(&p->p_lwp));
+
+	/* XXX lwp */
+	lp = FIRST_LWP_IN_PROC(p);
+	return (ptrace_single_step(lp));
 }
diff --git a/sys/platform/pc32/i386/sys_machdep.c b/sys/platform/pc32/i386/sys_machdep.c
index 6c96b8b..23f9f0c 100644
--- a/sys/platform/pc32/i386/sys_machdep.c
+++ b/sys/platform/pc32/i386/sys_machdep.c
@@ -558,7 +558,7 @@ check_descs(union descriptor *descs, int num)
 int
 cpu_set_iopl(void)
 {
-	curproc->p_md.md_regs->tf_eflags |= PSL_IOPL;
+	curthread->td_lwp->lwp_md.md_regs->tf_eflags |= PSL_IOPL;
 	return(0);
 }
 
@@ -568,7 +568,7 @@ cpu_set_iopl(void)
 int
 cpu_clr_iopl(void)
 {
-	curproc->p_md.md_regs->tf_eflags &= ~PSL_IOPL;
+	curthread->td_lwp->lwp_md.md_regs->tf_eflags &= ~PSL_IOPL;
 	return(0);
 }
 
diff --git a/sys/platform/pc32/i386/trap.c b/sys/platform/pc32/i386/trap.c
index c7597b5..887cc08 100644
--- a/sys/platform/pc32/i386/trap.c
+++ b/sys/platform/pc32/i386/trap.c
@@ -273,7 +273,7 @@ recheck:
 	 * Post any pending signals.  If running a virtual kernel be sure
 	 * to restore the virtual kernel's vmspace before posting the signal.
 	 */
-	if ((sig = CURSIG(p)) != 0) {
+	if ((sig = CURSIG(lp)) != 0) {
 		get_mplock();
 		postsig(sig);
 		rel_mplock();
@@ -862,7 +862,7 @@ kernel_trap:
 		i = (*p->p_sysent->sv_transtrap)(i, type);
 
 	MAKEMPSAFE(have_mplock);
-	trapsignal(p, i, ucode);
+	trapsignal(lp, i, ucode);
 
 #ifdef DEBUG
 	if (type <= MAX_TRAP_MSG) {
@@ -1378,7 +1378,7 @@ bad:
 	if ((orig_tf_eflags & PSL_T) && !(orig_tf_eflags & PSL_VM)) {
 		MAKEMPSAFE(have_mplock);
 		frame->tf_eflags &= ~PSL_T;
-		trapsignal(p, SIGTRAP, 0);
+		trapsignal(lp, SIGTRAP, 0);
 	}
 
 	/*
diff --git a/sys/platform/pc32/i386/vm_machdep.c b/sys/platform/pc32/i386/vm_machdep.c
index f79d94e..95752ba 100644
--- a/sys/platform/pc32/i386/vm_machdep.c
+++ b/sys/platform/pc32/i386/vm_machdep.c
@@ -192,12 +192,12 @@ cpu_fork(struct lwp *lp1, struct lwp *lp2, int flags)
 	bcopy(&lp1->lwp_thread->td_tls, &lp2->lwp_thread->td_tls,
 	      sizeof(lp2->lwp_thread->td_tls));
 	/*
-	 * Now, cpu_switch() can schedule the new process.
+	 * Now, cpu_switch() can schedule the new lwp.
 	 * pcb_esp is loaded pointing to the cpu_switch() stack frame
 	 * containing the return address when exiting cpu_switch.
 	 * This will normally be to fork_trampoline(), which will have
-	 * %ebx loaded with the new proc's pointer.  fork_trampoline()
-	 * will set up a stack to call fork_return(p, frame); to complete
+	 * %ebx loaded with the new lwp's pointer.  fork_trampoline()
+	 * will set up a stack to call fork_return(lp, frame); to complete
 	 * the return to user-mode.
 	 */
 }
diff --git a/sys/platform/pc32/isa/npx.c b/sys/platform/pc32/isa/npx.c
index 6f8b0ce..07c5bfd 100644
--- a/sys/platform/pc32/isa/npx.c
+++ b/sys/platform/pc32/isa/npx.c
@@ -812,14 +812,14 @@ npx_intr(void *dummy)
 		 * in doreti, and the frame for that could easily be set up
 		 * just before it is used).
 		 */
-		curproc->p_md.md_regs = INTR_TO_TRAPFRAME(frame);
+		curthread->td_lwp->lwp_md.md_regs = INTR_TO_TRAPFRAME(frame);
 		/*
 		 * Encode the appropriate code for detailed information on
 		 * this exception.
 		 */
 		code = 
 		    fpetable[(*exstat & ~control & 0x3f) | (*exstat & 0x40)];
-		trapsignal(curproc, SIGFPE, code);
+		trapsignal(curthread->td_lwp, SIGFPE, code);
 	} else {
 		/*
 		 * Nested interrupt.  These losers occur when:
diff --git a/sys/platform/vkernel/i386/cpu_regs.c b/sys/platform/vkernel/i386/cpu_regs.c
index 5772a9f..9fceaa5 100644
--- a/sys/platform/vkernel/i386/cpu_regs.c
+++ b/sys/platform/vkernel/i386/cpu_regs.c
@@ -241,7 +241,7 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
 
 	/* Allocate and validate space for the signal handler context. */
 	/* XXX lwp flags */
-        if ((p->p_flag & P_ALTSTACK) != 0 && !oonstack &&
+        if ((lp->lwp_flag & LWP_ALTSTACK) != 0 && !oonstack &&
 	    SIGISMEMBER(psp->ps_sigonstack, sig)) {
 		sfp = (struct sigframe *)(lp->lwp_sigstk.ss_sp +
 		    lp->lwp_sigstk.ss_size - sizeof(struct sigframe));
@@ -476,7 +476,7 @@ sys_sigreturn(struct sigreturn_args *uap)
 		cs = ucp.uc_mcontext.mc_cs;
 		if (!CS_SECURE(cs)) {
 			kprintf("sigreturn: cs = 0x%x\n", cs);
-			trapsignal(lp->lwp_proc, SIGBUS, T_PROTFLT);
+			trapsignal(lp, SIGBUS, T_PROTFLT);
 			return(EINVAL);
 		}
 		bcopy(&ucp.uc_mcontext.mc_gs, regs, sizeof(struct trapframe));
@@ -730,8 +730,10 @@ cpu_idle(void)
  * Clear registers on exec
  */
 void
-setregs(struct lwp *lp, u_long entry, u_long stack, u_long ps_strings)
+exec_setregs(u_long entry, u_long stack, u_long ps_strings)
 {
+	struct thread *td = curthread;
+	struct lwp *lp = td->td_lwp;
 	struct trapframe *regs = lp->lwp_md.md_regs;
 	struct pcb *pcb = lp->lwp_thread->td_pcb;
 
@@ -763,7 +765,7 @@ setregs(struct lwp *lp, u_long entry, u_long stack, u_long ps_strings)
                 pcb->pcb_dr3 = 0;
                 pcb->pcb_dr6 = 0;
                 pcb->pcb_dr7 = 0;
-                if (pcb == curthread->td_pcb) {
+                if (pcb == td->td_pcb) {
 		        /*
 			 * Clear the debug registers on the running
 			 * CPU, otherwise they will end up affecting
@@ -781,7 +783,7 @@ setregs(struct lwp *lp, u_long entry, u_long stack, u_long ps_strings)
 	 * traps to the emulator (if it is done at all) mainly because
 	 * emulators don't provide an entry point for initialization.
 	 */
-	lp->lwp_thread->td_pcb->pcb_flags &= ~FP_SOFTFP;
+	pcb->pcb_flags &= ~FP_SOFTFP;
 
 	/*
 	 * note: do not set CR0_TS here.  npxinit() must do it after clearing
@@ -871,9 +873,9 @@ extern inthand_t *Xrsvdary[256];
 #endif
 
 int
-ptrace_set_pc(struct proc *p, unsigned long addr)
+ptrace_set_pc(struct lwp *lp, unsigned long addr)
 {
-	p->p_md.md_regs->tf_eip = addr;
+	lp->lwp_md.md_regs->tf_eip = addr;
 	return (0);
 }
 
diff --git a/sys/platform/vkernel/i386/npx.c b/sys/platform/vkernel/i386/npx.c
index 7a1785d..9e3da80 100644
--- a/sys/platform/vkernel/i386/npx.c
+++ b/sys/platform/vkernel/i386/npx.c
@@ -413,7 +413,7 @@ npx_intr(void *dummy)
 		 * in doreti, and the frame for that could easily be set up
 		 * just before it is used).
 		 */
-		curproc->p_md.md_regs = INTR_TO_TRAPFRAME(frame);
+		curthread->td_lwp->lwp_md.md_regs = INTR_TO_TRAPFRAME(frame);
 		/*
 		 * Encode the appropriate code for detailed information on
 		 * this exception.
diff --git a/sys/platform/vkernel/i386/procfs_machdep.c b/sys/platform/vkernel/i386/procfs_machdep.c
index 1ad2331..7914e02 100644
--- a/sys/platform/vkernel/i386/procfs_machdep.c
+++ b/sys/platform/vkernel/i386/procfs_machdep.c
@@ -84,33 +84,49 @@
 int
 procfs_read_regs(struct proc *p, struct reg *regs)
 {
+	struct lwp *lp;
+
 	if (p->p_flag & P_SWAPPEDOUT)
 		return (EIO);
-	return (fill_regs(&p->p_lwp, regs));
+	/* XXX lwp */
+	lp = FIRST_LWP_IN_PROC(p);
+	return (fill_regs(lp, regs));
 }
 
 int
 procfs_write_regs(struct proc *p, struct reg *regs)
 {
+	struct lwp *lp;
+
 	if (p->p_flag & P_SWAPPEDOUT)
 		return (EIO);
-	return (set_regs(&p->p_lwp, regs));
+	/* XXX lwp */
+	lp = FIRST_LWP_IN_PROC(p);
+	return (set_regs(lp, regs));
 }
 
 int
 procfs_read_dbregs(struct proc *p, struct dbreg *dbregs)
 {
+	struct lwp *lp;
+
 	if (p->p_flag & P_SWAPPEDOUT)
 		return (EIO);
-	return (fill_dbregs(&p->p_lwp, dbregs));
+	/* XXX lwp */
+	lp = FIRST_LWP_IN_PROC(p);
+	return (fill_dbregs(lp, dbregs));
 }
 
 int
 procfs_write_dbregs(struct proc *p, struct dbreg *dbregs)
 {
+	struct lwp *lp;
+
 	if (p->p_flag & P_SWAPPEDOUT)
 		return (EIO);
-	return (set_dbregs(&p->p_lwp, dbregs));
+	/* XXX lwp */
+	lp = FIRST_LWP_IN_PROC(p);
+	return (set_dbregs(lp, dbregs));
 }
 
 /*
@@ -121,23 +137,35 @@ procfs_write_dbregs(struct proc *p, struct dbreg *dbregs)
 int
 procfs_read_fpregs(struct proc *p, struct fpreg *fpregs)
 {
+	struct lwp *lp;
+
 	if (p->p_flag & P_SWAPPEDOUT)
 		return (EIO);
-	return (fill_fpregs(&p->p_lwp, fpregs));
+	/* XXX lwp */
+	lp = FIRST_LWP_IN_PROC(p);
+	return (fill_fpregs(lp, fpregs));
 }
 
 int
 procfs_write_fpregs(struct proc *p, struct fpreg *fpregs)
 {
+	struct lwp *lp;
+
 	if (p->p_flag & P_SWAPPEDOUT)
 		return (EIO);
-	return (set_fpregs(&p->p_lwp, fpregs));
+	/* XXX lwp */
+	lp = FIRST_LWP_IN_PROC(p);
+	return (set_fpregs(lp, fpregs));
 }
 
 int
 procfs_sstep(struct proc *p)
 {
+	struct lwp *lp;
+
 	if (p->p_flag & P_SWAPPEDOUT)
 		return (EIO);
-	return (ptrace_single_step(&p->p_lwp));
+	/* XXX lwp */
+	lp = FIRST_LWP_IN_PROC(p);
+	return (ptrace_single_step(lp));
 }
diff --git a/sys/platform/vkernel/i386/trap.c b/sys/platform/vkernel/i386/trap.c
index 4a554cc..a6b84ce 100644
--- a/sys/platform/vkernel/i386/trap.c
+++ b/sys/platform/vkernel/i386/trap.c
@@ -257,7 +257,7 @@ recheck:
 	/*
 	 * Post any pending signals
 	 */
-	if ((sig = CURSIG(p)) != 0) {
+	if ((sig = CURSIG(lp)) != 0) {
 		get_mplock();
 		postsig(sig);
 		rel_mplock();
@@ -603,7 +603,7 @@ restart:
 		i = (*p->p_sysent->sv_transtrap)(i, type);
 
 	MAKEMPSAFE(have_mplock);
-	trapsignal(p, i, ucode);
+	trapsignal(lp, i, ucode);
 
 #ifdef DEBUG
 	if (type <= MAX_TRAP_MSG) {
@@ -638,6 +638,7 @@ kern_trap(struct trapframe *frame)
 {
 	struct globaldata *gd = mycpu;
 	struct thread *td = gd->gd_curthread;
+	struct lwp *lp;
 	struct proc *p;
 	int i = 0, ucode = 0, type, code;
 #ifdef SMP
@@ -648,6 +649,7 @@ kern_trap(struct trapframe *frame)
 #endif
 	vm_offset_t eva;
 
+	lp = td->td_lwp;
 	p = td->td_proc;
 
 	if (frame->tf_trapno == T_PAGEFLT) 
@@ -815,7 +817,7 @@ kernel_trap:
 		i = (*p->p_sysent->sv_transtrap)(i, type);
 
 	MAKEMPSAFE(have_mplock);
-	trapsignal(p, i, ucode);
+	trapsignal(lp, i, ucode);
 
 #ifdef DEBUG
 	if (type <= MAX_TRAP_MSG) {
@@ -1297,7 +1299,7 @@ bad:
 	if ((orig_tf_eflags & PSL_T) /*&& !(orig_tf_eflags & PSL_VM)*/) {
 		MAKEMPSAFE(have_mplock);
 		frame->tf_eflags &= ~PSL_T;
-		trapsignal(p, SIGTRAP, 0);
+		trapsignal(lp, SIGTRAP, 0);
 	}
 
 	/*
diff --git a/sys/platform/vkernel/platform/init.c b/sys/platform/vkernel/platform/init.c
index 0a8b17c..eab58ea 100644
--- a/sys/platform/vkernel/platform/init.c
+++ b/sys/platform/vkernel/platform/init.c
@@ -508,7 +508,7 @@ init_vkernel(void)
 	mi_gdinit(&gd->mi, 0);
 	cpu_gdinit(gd, 0);
 	mi_proc0init(&gd->mi, proc0paddr);
-	proc0.p_lwp.lwp_md.md_regs = &proc0_tf;
+	lwp0.lwp_md.md_regs = &proc0_tf;
 
 	/*init_locks();*/
 	cninit();
@@ -533,7 +533,7 @@ init_vkernel(void)
 #endif
 #if 0
 	thread0.td_pcb_cr3 ... MMU
-	proc0.p_lwp.lwp_md.md_regs = &proc0_tf;
+	lwp0.lwp_md.md_regs = &proc0_tf;
 #endif
 }
 
diff --git a/sys/platform/vkernel/platform/pmap.c b/sys/platform/vkernel/platform/pmap.c
index 607afec..743bb11 100644
--- a/sys/platform/vkernel/platform/pmap.c
+++ b/sys/platform/vkernel/platform/pmap.c
@@ -855,10 +855,12 @@ pmap_init_thread(thread_t td)
 void
 pmap_init_proc(struct proc *p, struct thread *td)
 {
+	struct lwp *lp = ONLY_LWP_IN_PROC(p);
+
 	p->p_addr = (void *)td->td_kstack;
-	p->p_thread = td;
+	lp->lwp_thread = td;
 	td->td_proc = p;
-	td->td_lwp = &p->p_lwp;
+	td->td_lwp = lp;
 	td->td_switch = cpu_heavy_switch;
 #ifdef SMP
 	KKASSERT(td->td_mpcount == 1);
@@ -873,12 +875,15 @@ pmap_init_proc(struct proc *p, struct thread *td)
 struct thread *
 pmap_dispose_proc(struct proc *p)
 {
-	struct thread *td;
+	struct thread *td = NULL;
+	struct lwp *lp;
 
 	KASSERT(p->p_lock == 0, ("attempt to dispose referenced proc! %p", p));
 
-	if ((td = p->p_thread) != NULL) {
-		p->p_thread = NULL;
+	lp = ONLY_LWP_IN_PROC(p);
+	if (lp != NULL && (td = lp->lwp_thread) != NULL) {
+		lp->lwp_thread = NULL;
+		td->td_lwp = NULL;
 		td->td_proc = NULL;
 	}
 	p->p_addr = NULL;
@@ -2980,8 +2985,10 @@ pmap_activate(struct proc *p)
 	tlb_flush_count++;
 #endif
 #if 0
-	p->p_thread->td_pcb->pcb_cr3 = vtophys(pmap->pm_pdir);
-	load_cr3(p->p_thread->td_pcb->pcb_cr3);
+	KKASSERT((p == curproc));
+
+	curthread->td_pcb->pcb_cr3 = vtophys(pmap->pm_pdir);
+	load_cr3(curthread->td_pcb->pcb_cr3);
 #endif
 }
 
diff --git a/sys/sys/caps.h b/sys/sys/caps.h
index a64bf93..034e82b 100644
--- a/sys/sys/caps.h
+++ b/sys/sys/caps.h
@@ -164,7 +164,7 @@ typedef struct caps_kmsg {
  * kernel support
  */
 void caps_exit(struct thread *td);
-void caps_fork(struct proc *p1, struct proc *p2, int flags);
+void caps_fork(struct thread *td1, struct thread *td2, int flags);
 
 #else
 
diff --git a/sys/sys/kinfo.h b/sys/sys/kinfo.h
index e5d2a95..07556f2 100644
--- a/sys/sys/kinfo.h
+++ b/sys/sys/kinfo.h
@@ -120,7 +120,6 @@ struct kinfo_lwp {
 	uint64_t	kl_iticks;
 	uint64_t	kl_cpticks;	/* sched quantums used */
 	u_int		kl_pctcpu;	/* percentage cputime */
-	u_int		kl_swtime;	/* time swapped in or out */
 	u_int		kl_slptime;	/* time since last blocked */
 	int		kl_origcpu;	/* originally scheduled on cpu */
 	int		kl_estcpu;
@@ -180,6 +179,7 @@ struct kinfo_proc {
 	u_short		kp_exitstat;	/* exit status information */
 	int		kp_nthreads;
 	int		kp_nice;
+	unsigned int	kp_swtime;
 
 	vm_size_t	kp_vm_map_size;	/* vmmap virtual size */
 	segsz_t		kp_vm_rssize;		/* resident set size */
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index 69c38c8..5150195 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -145,8 +145,8 @@ struct lwp {
 
 	lwpid_t		lwp_tid;	/* Our thread id . */
 
-#ifdef notyet
 	int		lwp_flag;	/* P_* flags. */
+#ifdef notyet
 	char		lwp_stat;	/* S* process status. */
 #endif
 
@@ -159,7 +159,6 @@ struct lwp {
 	sysclock_t	lwp_cpticks;	/* cpu used in sched clock ticks */
 	sysclock_t	lwp_cpbase;	/* Measurement base */
 	fixpt_t		lwp_pctcpu;	/* %cpu for this process */
-	u_int		lwp_swtime;	/* Time swapped in or out. */
 	u_int		lwp_slptime;	/* Time since last blocked. */
 
 	int		lwp_traceflag;	/* Kernel trace points. */
@@ -193,6 +192,7 @@ struct	proc {
 	struct filedesc	*p_fd;		/* Ptr to open files structure. */
 	struct filedesc_to_leader *p_fdtol; /* Ptr to tracking node XXX lwp */
 	struct plimit	*p_limit;	/* Process limits. */
+	struct pstats	*p_stats;
 	void		*p_pad0;
 	struct	procsig	*p_procsig;
 #define p_sigacts	p_procsig->ps_sigacts
@@ -220,11 +220,7 @@ struct	proc {
 
 	struct vmspace	*p_vmspace;	/* Current address space. */
 
-#define p_cpticks p_lwp.lwp_cpticks
-#define p_cpbase p_lwp.lwp_cpbase
-#define p_pctcpu p_lwp.lwp_pctcpu
-#define p_swtime p_lwp.lwp_swtime
-#define p_slptime p_lwp.lwp_slptime
+	unsigned int	p_swtime;	/* Time swapped in or out */
 
 	struct itimerval p_realtimer;	/* Alarm timer. */
 	struct itimerval p_timer[3];	/* Virtual-time timers. */
@@ -236,8 +232,6 @@ struct	proc {
 
 	struct vnode	*p_textvp;	/* Vnode of executable. */
 
-#define p_usdata p_lwp.lwp_usdata
-	
 	unsigned int	p_stops;	/* procfs event bitmask */
 	unsigned int	p_stype;	/* procfs stop event type */
 	char		p_step;		/* procfs stop *once* flag */
@@ -245,7 +239,6 @@ struct	proc {
 	char		p_pad2[2];	/* padding for alignment */
 	struct		sigiolst p_sigiolst;	/* list of sigio sources */
 	int		p_sigparent;	/* signal to parent on exit */
-#define p_oldsigmask p_lwp.lwp_oldsigmask
 	int		p_sig;		/* for core dump/debugger XXX */
         u_long		p_code;		/* for core dump/debugger XXX */
 	struct klist	p_klist;	/* knotes attached to this process */
@@ -261,9 +254,6 @@ struct	proc {
 /* The following fields are all copied upon creation in fork. */
 #define	p_startcopy	p_comm
 
-#define p_sigmask p_lwp.lwp_sigmask
-#define p_sigstk p_lwp.lwp_sigstk
-
 	char		p_comm[MAXCOMLEN+1]; /* typ 16+1 bytes */
 	char		p_lock;		/* Process lock (prevent swap) count. */
 	char		p_nice;		/* Process "nice" value. */
@@ -279,7 +269,6 @@ struct	proc {
 /* End area that is copied on creation. */
 #define	p_endcopy	p_addr
 	struct user	*p_addr;	/* Kernel virtual addr of u-area (PROC ONLY) XXX lwp */
-#define p_md p_lwp.lwp_md
 
 	u_short		p_xstat;	/* Exit status or last stop signal */
 	u_short		p_acflag;	/* Accounting flags. */
@@ -293,17 +282,15 @@ struct	proc {
 	struct proc	*p_peers;	/* XXX lwp */
 	struct proc	*p_leader;	/* XXX lwp */
 	void		*p_emuldata;	/* process-specific emulator state */
-#define p_thread p_lwp.lwp_thread
 	struct usched	*p_usched;	/* Userland scheduling control */
 	struct vkernel	*p_vkernel;	/* Virtual kernel extension */
 	int		p_numposixlocks; /* number of POSIX locks */
 
-	struct lwp	p_lwp;		/* Embedded lwp XXX */
 	struct spinlock p_spin;		/* Spinlock for LWP access to proc */
 };
 
-#define p_wchan		p_thread->td_wchan
-#define p_wmesg		p_thread->td_wmesg
+#define lwp_wchan	lwp_thread->td_wchan
+#define lwp_wmesg	lwp_thread->td_wmesg
 #define	p_session	p_pgrp->pg_session
 #define	p_pgid		p_pgrp->pg_id
 
@@ -351,13 +338,16 @@ struct	proc {
 #define	P_DEADLKTREAT   0x800000 /* lock aquisition - deadlock treatment */
 
 #define	P_JAILED	0x1000000 /* Process is in jail */
-#define	P_OLDMASK	0x2000000 /* need to restore mask before pause */
-#define	P_ALTSTACK	0x4000000 /* have alternate signal stack */
+#define	P_UNUSED0	0x2000000 /* need to restore mask before pause */
+#define	P_UNUSED1	0x4000000 /* have alternate signal stack */
 #define	P_INEXEC	0x8000000 /* Process is in execve(). */
 #define P_PASSIVE_ACQ	0x10000000 /* Passive acquire cpu (see kern_switch) */
 #define	P_UPCALLWAIT	0x20000000 /* Wait for upcall or signal */
 #define P_XCPU		0x40000000 /* SIGXCPU */
 
+#define	LWP_ALTSTACK	0x0000001 /* have alternate signal stack */
+#define	LWP_OLDMASK	0x0000002 /* need to restore mask before pause */
+
 #define	FIRST_LWP_IN_PROC(p)		LIST_FIRST(&(p)->p_lwps)
 #define	FOREACH_LWP_IN_PROC(lp, p)	\
 	LIST_FOREACH((lp), &(p)->p_lwps, lwp_list)
@@ -423,6 +413,7 @@ extern u_long pgrphash;
 #endif
 
 extern struct proc proc0;		/* Process slot for swapper. */
+extern struct lwp lwp0;			/* LWP slot for swapper. */
 extern struct thread thread0;		/* Thread slot for swapper. */
 extern int hogticks;			/* Limit on kernel cpu hogs. */
 extern int nprocs, maxproc;		/* Current and max number of procs. */
@@ -453,6 +444,7 @@ struct proc *zpfind (pid_t);	/* Find zombie process by id. */
 struct vm_zone;
 struct globaldata;
 extern struct vm_zone *proc_zone;
+extern struct vm_zone *lwp_zone;
 
 int	enterpgrp (struct proc *p, pid_t pgid, int mksess);
 void	proc_add_allproc(struct proc *p);
diff --git a/sys/sys/ptrace.h b/sys/sys/ptrace.h
index ea8278d..9c382f6 100644
--- a/sys/sys/ptrace.h
+++ b/sys/sys/ptrace.h
@@ -84,7 +84,7 @@ struct proc;
 struct lwp;
 
 void	proc_reparent (struct proc *child, struct proc *newparent);
-int	ptrace_set_pc (struct proc *p, unsigned long addr);
+int	ptrace_set_pc (struct lwp *p, unsigned long addr);
 int	ptrace_single_step (struct lwp *lp);
 int	kern_ptrace (struct proc *p, int req, pid_t pid, void *addr,
 		int data, int *res);
diff --git a/sys/sys/reg.h b/sys/sys/reg.h
index cdd8323..d19f438 100644
--- a/sys/sys/reg.h
+++ b/sys/sys/reg.h
@@ -61,7 +61,7 @@ int	fill_regs (struct lwp *lp, struct reg *regs);
 int	fill_dbregs (struct lwp *lp, struct dbreg *dbregs);
 int	set_fpregs (struct lwp *, struct fpreg *);
 int	set_regs (struct lwp *lp, struct reg *regs);
-void	setregs (struct lwp *, u_long, u_long, u_long);
+void	exec_setregs (u_long, u_long, u_long);
 int	set_dbregs (struct lwp *lp, struct dbreg *dbregs);
 
 #endif
diff --git a/sys/sys/signalvar.h b/sys/sys/signalvar.h
index 63d4392..3dac6a8 100644
--- a/sys/sys/signalvar.h
+++ b/sys/sys/signalvar.h
@@ -189,16 +189,16 @@ extern int sugid_coredump;	/* Sysctl variable kern.sugid_coredump */
 void	check_sigacts (void);
 void	execsigs (struct proc *p);
 void	gsignal (int pgid, int sig);
-int	issignal (struct proc *p);
-int	iscaught (struct proc *p);
+int	issignal (struct lwp *lp);
+int	iscaught (struct lwp *p);
 void	killproc (struct proc *p, char *why);
 void	pgsigio (struct sigio *, int signum, int checkctty);
 void	pgsignal (struct pgrp *pgrp, int sig, int checkctty);
 void	postsig (int sig);
 void	ksignal (struct proc *p, int sig);
 void	siginit (struct proc *p);
-void	trapsignal (struct proc *p, int sig, u_long code);
-static int __cursig (struct proc *p);
+void	trapsignal (struct lwp *p, int sig, u_long code);
+static int __cursig (struct lwp *p);
 
 /*
  * Machine-dependent functions:
@@ -212,8 +212,8 @@ int	checkpoint_signal_handler(struct proc *p);
 /*
  * Inline functions:
  */
-#define	CURSIG(p)	__cursig(p)
-#define CURSIGNB(p)	__cursignb(p)
+#define	CURSIG(lp)	__cursig(lp)
+#define CURSIGNB(lp)	__cursignb(lp)
 
 /*
  * Determine signal that should be delivered to process p, the current
@@ -224,31 +224,34 @@ int	checkpoint_signal_handler(struct proc *p);
  */
 static __inline
 int
-__cursig(struct proc *p)
+__cursig(struct lwp *lp)
 {
+	struct proc *p;
 	sigset_t tmpset;
 	int r;
 
+	p = lp->lwp_proc;
 	tmpset = p->p_siglist;
-	SIGSETNAND(tmpset, p->p_sigmask);
-	if (SIGISEMPTY(p->p_siglist) ||
-	     (!(p->p_flag & P_TRACED) && SIGISEMPTY(tmpset))) {
+	SIGSETOR(tmpset, lp->lwp_siglist);
+	SIGSETNAND(tmpset, lp->lwp_sigmask);
+	if (!(p->p_flag & P_TRACED) && SIGISEMPTY(tmpset))
 		return(0);
-	}
-	r = issignal(p);
+	r = issignal(lp);
 	return(r);
 }
 
 static __inline
 int
-__cursignb(struct proc *p)
+__cursignb(struct lwp *lp)
 {
+	struct proc *p;
 	sigset_t tmpset;
 
+	p = lp->lwp_proc;
 	tmpset = p->p_siglist;
-	SIGSETNAND(tmpset, p->p_sigmask);
-	if (SIGISEMPTY(p->p_siglist) ||
-	     (!(p->p_flag & P_TRACED) && SIGISEMPTY(tmpset))) {
+	SIGSETOR(tmpset, lp->lwp_siglist);
+	SIGSETNAND(tmpset, lp->lwp_sigmask);
+	if ((!(p->p_flag & P_TRACED) && SIGISEMPTY(tmpset))) {
 		return(FALSE);
 	}
 	return (TRUE);
diff --git a/sys/vfs/mfs/mfs_vfsops.c b/sys/vfs/mfs/mfs_vfsops.c
index 2b1ecb3..aa477db 100644
--- a/sys/vfs/mfs/mfs_vfsops.c
+++ b/sys/vfs/mfs/mfs_vfsops.c
@@ -441,7 +441,7 @@ mfs_start(struct mount *mp, int flags)
 			gotsig = 0;
 			if (dounmount(mp, 0) != 0) {
 				KKASSERT(td->td_proc);
-				sig = CURSIG(td->td_proc);
+				sig = CURSIG(td->td_lwp);
 				if (sig)
 					SIGDELSET(td->td_proc->p_siglist, sig);
 			}
diff --git a/sys/vfs/nfs/nfs_socket.c b/sys/vfs/nfs/nfs_socket.c
index a31ec20..ba84575 100644
--- a/sys/vfs/nfs/nfs_socket.c
+++ b/sys/vfs/nfs/nfs_socket.c
@@ -1548,6 +1548,7 @@ nfs_sigintr(struct nfsmount *nmp, struct nfsreq *rep, struct thread *td)
 {
 	sigset_t tmpset;
 	struct proc *p;
+	struct lwp *lp;
 
 	if (rep && (rep->r_flags & R_SOFTTERM))
 		return (EINTR);
@@ -1560,10 +1561,12 @@ nfs_sigintr(struct nfsmount *nmp, struct nfsreq *rep, struct thread *td)
 	if (td == NULL || (p = td->td_proc) == NULL)
 		return (0);
 
-	tmpset = p->p_siglist;
-	SIGSETNAND(tmpset, p->p_sigmask);
+	lp = td->td_lwp;
+	tmpset = lp->lwp_siglist;
+	SIGSETOR(tmpset, p->p_siglist);
+	SIGSETNAND(tmpset, lp->lwp_sigmask);
 	SIGSETNAND(tmpset, p->p_sigignore);
-	if (SIGNOTEMPTY(p->p_siglist) && NFSINT_SIGMASK(tmpset))
+	if (SIGNOTEMPTY(tmpset) && NFSINT_SIGMASK(tmpset))
 		return (EINTR);
 
 	return (0);
diff --git a/sys/vfs/procfs/procfs_status.c b/sys/vfs/procfs/procfs_status.c
index 33b28ef..bcc5de2 100644
--- a/sys/vfs/procfs/procfs_status.c
+++ b/sys/vfs/procfs/procfs_status.c
@@ -61,6 +61,7 @@ int
 procfs_dostatus(struct proc *curp, struct proc *p, struct pfsnode *pfs,
 		struct uio *uio)
 {
+	struct lwp *lp;
 	struct session *sess;
 	struct tty *tp;
 	struct ucred *cr;
@@ -87,6 +88,8 @@ procfs_dostatus(struct proc *curp, struct proc *p, struct pfsnode *pfs,
 	KASSERT(sizeof(psbuf) > MAXCOMLEN,
 			("Too short buffer for new MAXCOMLEN"));
 
+	lp = FIRST_LWP_IN_PROC(p);
 	ps = psbuf;
 	bcopy(p->p_comm, ps, MAXCOMLEN);
 	ps[MAXCOMLEN] = '\0';
@@ -136,7 +139,7 @@ procfs_dostatus(struct proc *curp, struct proc *p, struct pfsnode *pfs,
 	DOCHECK();
 
 	ps += ksnprintf(ps, psbuf + sizeof(psbuf) - ps, " %s",
-		(p->p_wchan && p->p_wmesg) ? p->p_wmesg : "nochan");
+		(lp->lwp_wchan && lp->lwp_wmesg) ? lp->lwp_wmesg : "nochan");
 	DOCHECK();
 
 	cr = p->p_ucred;
diff --git a/sys/vm/vm_glue.c b/sys/vm/vm_glue.c
index dda7480..5c3196a 100644
--- a/sys/vm/vm_glue.c
+++ b/sys/vm/vm_glue.c
@@ -429,11 +429,14 @@ static int
 scheduler_callback(struct proc *p, void *data)
 {
 	struct scheduler_info *info = data;
+	struct lwp *lp;
 	segsz_t pgs;
 	int pri;
 
 	if (p->p_flag & P_SWAPWAIT) {
-		pri = p->p_swtime + p->p_slptime - p->p_nice * 8;
+		/* XXX lwp */
+		lp = FIRST_LWP_IN_PROC(p);
+		pri = p->p_swtime + lp->lwp_slptime - p->p_nice * 8;
 
 		/*
 		 * The more pages paged out while we were swapped,
@@ -519,6 +522,7 @@ static int
 swapout_procs_callback(struct proc *p, void *data)
 {
 	struct vmspace *vm;
+	struct lwp *lp;
 	int action = *(int *)data;
 
 	if (!swappable(p))
@@ -530,13 +534,15 @@ swapout_procs_callback(struct proc *p, void *data)
 		/*
 		 * do not swap out a realtime process
 		 */
-		if (RTP_PRIO_IS_REALTIME(p->p_lwp.lwp_rtprio.type))
+		/* XXX lwp */
+		lp = FIRST_LWP_IN_PROC(p);
+		if (RTP_PRIO_IS_REALTIME(lp->lwp_rtprio.type))
 			return(0);
 
 		/*
 		 * Guarentee swap_idle_threshold time in memory
 		 */
-		if (p->p_slptime < swap_idle_threshold1)
+		if (lp->lwp_slptime < swap_idle_threshold1)
 			return(0);
 
 		/*
@@ -546,7 +552,7 @@ swapout_procs_callback(struct proc *p, void *data)
 		 */
 		if (((action & VM_SWAP_NORMAL) == 0) &&
 		    (((action & VM_SWAP_IDLE) == 0) ||
-		     (p->p_slptime < swap_idle_threshold2))) {
+		     (lp->lwp_slptime < swap_idle_threshold2))) {
 			return(0);
 		}
 
@@ -558,7 +564,7 @@ swapout_procs_callback(struct proc *p, void *data)
 		 */
 		if ((action & VM_SWAP_NORMAL) ||
 		    ((action & VM_SWAP_IDLE) &&
-		     (p->p_slptime > swap_idle_threshold2))) {
+		     (lp->lwp_slptime > swap_idle_threshold2))) {
 			swapout(p);
 		}
 
diff --git a/sys/vm/vm_meter.c b/sys/vm/vm_meter.c
index 79c7675..e176070 100644
--- a/sys/vm/vm_meter.c
+++ b/sys/vm/vm_meter.c
@@ -137,6 +137,7 @@ static int
 do_vmtotal_callback(struct proc *p, void *data)
 {
 	struct vmtotal *totalp = data;
+	struct lwp *lp;
 	vm_map_entry_t entry;
 	vm_map_t map;
 	int paging;
@@ -144,6 +145,9 @@ do_vmtotal_callback(struct proc *p, void *data)
 	if (p->p_flag & P_SYSTEM)
 		return(0);
 
+	/* XXX lwp */
+	lp = FIRST_LWP_IN_PROC(p);
+
 	switch (p->p_stat) {
 	case 0:
 		return(0);
@@ -151,12 +155,12 @@ do_vmtotal_callback(struct proc *p, void *data)
 		if ((p->p_flag & P_SWAPPEDOUT) == 0) {
 			if ((p->p_flag & P_SINTR) == 0)
 				totalp->t_dw++;
-			else if (p->p_slptime < maxslp)
+			else if (lp->lwp_slptime < maxslp)
 				totalp->t_sl++;
-		} else if (p->p_slptime < maxslp) {
+		} else if (lp->lwp_slptime < maxslp) {
 			totalp->t_sw++;
 		}
-		if (p->p_slptime >= maxslp)
+		if (lp->lwp_slptime >= maxslp)
 			return(0);
 		break;
 
diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c
index 168d8d2..9ccfb25 100644
--- a/sys/vm/vm_pageout.c
+++ b/sys/vm/vm_pageout.c
@@ -1184,7 +1184,8 @@ rescan0:
 		if (info.bigproc != NULL) {
 			killproc(info.bigproc, "out of swap space");
 			info.bigproc->p_nice = PRIO_MIN;
-			info.bigproc->p_usched->resetpriority(&info.bigproc->p_lwp);
+			info.bigproc->p_usched->resetpriority(
+				FIRST_LWP_IN_PROC(info.bigproc));
 			wakeup(&vmstats.v_free_count);
 			PRELE(info.bigproc);
 		}
diff --git a/usr.bin/systat/pigs.c b/usr.bin/systat/pigs.c
index 8299154..34c54fd 100644
--- a/usr.bin/systat/pigs.c
+++ b/usr.bin/systat/pigs.c
@@ -207,7 +207,7 @@ fetchpigs(void)
 		pt[i].pt_kp = &kpp[i];
 		pp = &kpp[i];
 		pctp = &pt[i].pt_pctcpu;
-		time = pp->kp_lwp.kl_swtime;
+		time = pp->kp_swtime;
 		if (time == 0 || (pp->kp_flags & P_SWAPPEDOUT))
 			*pctp = 0;
 		else
diff --git a/usr.bin/top/machine.c b/usr.bin/top/machine.c
index 2c8cfa4..8236ad7 100644
--- a/usr.bin/top/machine.c
+++ b/usr.bin/top/machine.c
@@ -86,8 +86,8 @@ struct handle
 #define VP(pp, field) ((pp)->kp_vm_ ## field)
 
 /* define what weighted cpu is.  */
-#define weighted_cpu(pct, pp) (LP((pp), swtime) == 0 ? 0.0 : \
-			 ((pct) / (1.0 - exp(LP((pp), swtime) * logcpu))))
+#define weighted_cpu(pct, pp) (PP((pp), swtime) == 0 ? 0.0 : \
+			 ((pct) / (1.0 - exp(PP((pp), swtime) * logcpu))))
 
 /* what we consider to be process size: */
 #define PROCSIZE(pp) (VP((pp), map_size) / 1024)

Attachment: signature.asc
Description: OpenPGP digital signature



[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]