[PATCH] Userland threading stage 2.10:

Simon 'corecode' Schubert corecode at fs.ei.tum.de
Thu Feb 1 14:06:11 PST 2007


Move signals into lwps, take the lwp out of proc.

Originally-Submitted-by:  David Xu <davidxu at freebsd.org>
---
This is quite preliminary.  It seems to work in my vkernel and tomorrow I'll give it some more thorough testing on my SMP box.
Please review and/or try it out.

cheers
 simon
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                       |    8 +-
sys/kern/kern_exit.c                       |   16 ++--
sys/kern/kern_fork.c                       |   17 ++--
sys/kern/kern_memio.c                      |    2 +-
sys/kern/kern_proc.c                       |   87 +-------------------
sys/kern/kern_resource.c                   |   11 ++-
sys/kern/kern_sig.c                        |  123 +++++++++++++++-------------
sys/kern/kern_synch.c                      |   40 ++++++---
sys/kern/kern_threads.c                    |    3 +-
sys/kern/kern_time.c                       |    2 +-
sys/kern/kern_usched.c                     |    3 +-
sys/kern/lwkt_caps.c                       |    5 +-
sys/kern/lwkt_msgport.c                    |    2 +-
sys/kern/sys_generic.c                     |   11 ++-
sys/kern/sys_process.c                     |   17 ++--
sys/kern/tty.c                             |   50 ++++++++---
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           |   25 +++---
sys/platform/pc32/i386/math_emulate.c      |    2 +-
sys/platform/pc32/i386/pmap.c              |   20 +++--
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        |   36 +--------
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/i386/vm_machdep.c     |   30 -------
sys/platform/vkernel/platform/init.c       |    4 +-
sys/platform/vkernel/platform/pmap.c       |   20 +++--
sys/sys/proc.h                             |   33 +++----
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                           |    5 +-
sys/vm/vm_pageout.c                        |    3 +-
62 files changed, 559 insertions(+), 509 deletions(-)
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 0768a09..c893f89 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));
		csi->csi_sigparent = p->p_sigparent;
	}
	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_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..71a9abd 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 */
@@ -649,7 +650,8 @@ 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);
+			/* XXX lwp, why dont use curthread ? */
+			upc_release(vmspace, FIRST_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..c02a1d0 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();
	/*
@@ -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_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 b8107b1..4301931 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();
}
@@ -596,91 +598,6 @@ DB_SHOW_COMMAND(pgrpdump, pgrpdump)
}
#endif /* DDB */
-#if 0
-/*
- * Fill in an eproc structure for the specified thread.
- */
-void
-fill_eproc_td(thread_t td, struct eproc *ep, struct proc *xp)
-{
-	bzero(ep, sizeof(*ep));
-
-	ep->e_uticks = td->td_uticks;
-	ep->e_sticks = td->td_sticks;
-	ep->e_iticks = td->td_iticks;
-	ep->e_tdev = NOUDEV;
-	ep->e_cpuid = td->td_gd->gd_cpuid;
-	if (td->td_wmesg) {
-		strncpy(ep->e_wmesg, td->td_wmesg, WMESGLEN);
-		ep->e_wmesg[WMESGLEN] = 0;
-	}
-
-	/*
-	 * Fake up portions of the proc structure copied out by the sysctl
-	 * to return useful information.  Note that using td_pri directly
-	 * is messy because it includes critial section data so we fake
-	 * up an rtprio.prio for threads.
-	 */
-	if (xp) {
-		*xp = *initproc;
-		xp->p_rtprio.type = RTP_PRIO_THREAD;
-		xp->p_rtprio.prio = td->td_pri & TDPRI_MASK;
-		xp->p_pid = -1;
-	}
-}
-
-/*
- * Fill in an eproc structure for the specified process.
- */
-void
-fill_eproc(struct proc *p, struct eproc *ep)
-{
-	struct tty *tp;
-
-	fill_eproc_td(p->p_thread, ep, NULL);
-
-	ep->e_paddr = p;
-	if (p->p_ucred) {
-		ep->e_ucred = *p->p_ucred;
-	}
-	if (p->p_procsig) {
-		ep->e_procsig = *p->p_procsig;
-	}
-	if (p->p_stat != SIDL && (p->p_flag & P_ZOMBIE) == 0 && 
-	    p->p_vmspace != NULL) {
-		struct vmspace *vm = p->p_vmspace;
-		ep->e_vm = *vm;
-		ep->e_vm.vm_rssize = vmspace_resident_count(vm); /*XXX*/
-	}
-	if (p->p_pptr)
-		ep->e_ppid = p->p_pptr->p_pid;
-	if (p->p_pgrp) {
-		ep->e_pgid = p->p_pgrp->pg_id;
-		ep->e_jobc = p->p_pgrp->pg_jobc;
-		ep->e_sess = p->p_pgrp->pg_session;
-
-		if (ep->e_sess) {
-			bcopy(ep->e_sess->s_login, ep->e_login, sizeof(ep->e_login));
-			if (ep->e_sess->s_ttyvp)
-				ep->e_flag = EPROC_CTTY;
-			if (p->p_session && SESS_LEADER(p))
-				ep->e_flag |= EPROC_SLEADER;
-		}
-	}
-	if ((p->p_flag & P_CONTROLT) &&
-	    (ep->e_sess != NULL) &&
-	    ((tp = ep->e_sess->s_ttyp) != NULL)) {
-		ep->e_tdev = dev2udev(tp->t_dev);
-		ep->e_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
-		ep->e_tsess = tp->t_session;
-	} else {
-		ep->e_tdev = NOUDEV;
-	}
-	if (p->p_ucred->cr_prison)
-		ep->e_jailid = p->p_ucred->cr_prison->pr_id;
-}
-#endif
-
/*
 * Locate a process on the zombie list.  Return a held process or NULL.
 */
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..b937cd1 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 = FIRST_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..b953972 100644
--- a/sys/kern/kern_synch.c
+++ b/sys/kern/kern_synch.c
@@ -190,6 +190,10 @@ 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)
@@ -200,7 +204,7 @@ schedcpu_stats(struct proc *p, void *data __unused)
	 * less then 2 seconds.  The schedulers understand this.
	 */
	if (p->p_slptime <= 1) {
-		p->p_usched->recalculate(&p->p_lwp);
+		p->p_usched->recalculate(lp);
	} else {
		p->p_pctcpu = (p->p_pctcpu * ccpu) >> FSHIFT;
	}
@@ -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,7 +423,7 @@ 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_usched->release_curproc(lp);
		p->p_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();
		/*
@@ -457,7 +465,7 @@ tsleep(void *ident, int flags, const char *wmesg, int timo)
		 */
		p->p_stat = SRUN;
		if (p->p_slptime)
-			p->p_usched->recalculate(&p->p_lwp);
+			p->p_usched->recalculate(lp);
		p->p_slptime = 0;
	} else {
		lwkt_switch();
@@ -505,10 +513,11 @@ tsleep(void *ident, int flags, const char *wmesg, int timo)
	 */
resume:
	if (p) {
-		if (catch && error == 0) {
+		p->p_flag &= ~(P_BREAKTSLEEP | P_SINTR);
+		if (catch && error == 0 && (sig != 0 || (sig = CURSIG(lp)))) {
			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 +908,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 +1006,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..74f3d5c 100644
--- a/sys/kern/kern_threads.c
+++ b/sys/kern/kern_threads.c
@@ -132,7 +132,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..e76820e 100644
--- a/sys/kern/kern_usched.c
+++ b/sys/kern/kern_usched.c
@@ -186,7 +186,8 @@ sys_usched_set(struct usched_set_args *uap)
		 * reassociation'
		 */
		if (item && item != p->p_usched) {
-			p->p_usched->release_curproc(&p->p_lwp);
+			/* XXX lwp */
+			p->p_usched->release_curproc(FIRST_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..8787de9 100644
--- a/sys/kern/lwkt_caps.c
+++ b/sys/kern/lwkt_caps.c
@@ -515,8 +515,9 @@ caps_fork(struct proc *p1, struct proc *p2, int flags)
    thread_t td1;
    thread_t td2;

-    td1 = p1->p_thread;
-    td2 = p2->p_thread;
+    /* XXX lwp */
+    td1 = FIRST_LWP_IN_PROC(p1)->lwp_thread;
+    td2 = FIRST_LWP_IN_PROC(p2)->lwp_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:
@@ -561,7 +564,7 @@ kern_ptrace(struct proc *curp, int req, pid_t pid, void *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..a7c2202 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)) {
		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,13 @@ ttyinfo(struct tty *tp)
static int
proc_compare(struct proc *p1, struct proc *p2)
{
-
+	struct lwp *lp1, *lp2;
	if (p1 == NULL)
		return (1);
+
+	lp1 = FIRST_LWP_IN_PROC(p1);
+	lp2 = FIRST_LWP_IN_PROC(p2);
+
	/*
	 * see if at least one of them is runnable
	 */
@@ -2439,9 +2461,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 +2481,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..e4d601c 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 trapframe *regs = lp->lwp_md.md_regs;
-	struct pcb *pcb = lp->lwp_thread->td_pcb;
+	struct thread *td = curthread;
+	struct lwp *lp = td->td_lwp;
+	struct pcb *pcb = td->td_pcb;
+ 	struct trapframe *regs = lp->lwp_md.md_regs;
	/* 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..34febc3 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,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) {
	    td->td_proc = NULL;
+	    lp->lwp_thread = NULL;
	}
	p->p_addr = NULL;
	return(td);
@@ -3189,6 +3193,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 +3204,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 7cb953b..4ea0a49 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.
	 */
}
@@ -303,36 +303,6 @@ cpu_proc_wait(struct proc *p)
		lwkt_free_thread(td);
}
-/*
- * Dump the machine specific header information at the start of a core dump.
- */
-int
-cpu_coredump(struct thread *td, struct vnode *vp, struct ucred *cred)
-{
-	struct proc *p = td->td_proc;
-	int error;
-	caddr_t tempuser;
-
-	KKASSERT(p);
-	tempuser = kmalloc(ctob(UPAGES), M_TEMP, M_WAITOK);
-	if (!tempuser)
-		return EINVAL;
-	
-	bzero(tempuser, ctob(UPAGES));
-	bcopy(p->p_addr, tempuser, sizeof(struct user));
-	bcopy(p->p_md.md_regs,
-	      tempuser + ((caddr_t) p->p_md.md_regs - (caddr_t) p->p_addr),
-	      sizeof(struct trapframe));
-	bcopy(p->p_thread->td_pcb, tempuser + ((char *)p->p_thread->td_pcb - (char *)p->p_addr), sizeof(struct pcb));
-
-	error = vn_rdwr(UIO_WRITE, vp, (caddr_t) tempuser, ctob(UPAGES),
-			(off_t)0, UIO_SYSSPACE, IO_UNIT, cred, (int *)NULL);
-
-	kfree(tempuser, M_TEMP);
-	
-	return error;
-}
-
#ifdef notyet
static void
setredzone(u_short *pte, caddr_t vaddr)
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 b003418..817fd68 100644
--- a/sys/platform/vkernel/i386/cpu_regs.c
+++ b/sys/platform/vkernel/i386/cpu_regs.c
@@ -239,7 +239,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));
@@ -474,7 +474,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));
@@ -728,8 +728,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;
@@ -761,7 +763,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
@@ -779,7 +781,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
@@ -869,9 +871,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 4e0f221..9007122 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) 
@@ -805,7 +807,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) {
@@ -1287,7 +1289,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/i386/vm_machdep.c b/sys/platform/vkernel/i386/vm_machdep.c
index 8a08c79..bbdd771 100644
--- a/sys/platform/vkernel/i386/vm_machdep.c
+++ b/sys/platform/vkernel/i386/vm_machdep.c
@@ -303,36 +303,6 @@ cpu_proc_wait(struct proc *p)
		lwkt_free_thread(td);
}
-/*
- * Dump the machine specific header information at the start of a core dump.
- */
-int
-cpu_coredump(struct thread *td, struct vnode *vp, struct ucred *cred)
-{
-	struct proc *p = td->td_proc;
-	int error;
-	caddr_t tempuser;
-
-	KKASSERT(p);
-	tempuser = kmalloc(ctob(UPAGES), M_TEMP, M_WAITOK);
-	if (!tempuser)
-		return EINVAL;
-	
-	bzero(tempuser, ctob(UPAGES));
-	bcopy(p->p_addr, tempuser, sizeof(struct user));
-	bcopy(p->p_md.md_regs,
-	      tempuser + ((caddr_t) p->p_md.md_regs - (caddr_t) p->p_addr),
-	      sizeof(struct trapframe));
-	bcopy(p->p_thread->td_pcb, tempuser + ((char *)p->p_thread->td_pcb - (char *)p->p_addr), sizeof(struct pcb));
-
-	error = vn_rdwr(UIO_WRITE, vp, (caddr_t) tempuser, ctob(UPAGES),
-			(off_t)0, UIO_SYSSPACE, IO_UNIT, cred, (int *)NULL);
-
-	kfree(tempuser, M_TEMP);
-	
-	return error;
-}
-
#ifdef notyet
static void
setredzone(u_short *pte, caddr_t vaddr)
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..7c2adea 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,14 @@ 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_proc = NULL;
	}
	p->p_addr = NULL;
@@ -2980,8 +2984,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/proc.h b/sys/sys/proc.h
index 69c38c8..2a1c959 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
@@ -193,6 +193,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 +221,9 @@ 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
+	u_int		p_pctcpu;
+	u_int		p_swtime;
+	u_int		p_slptime;
	struct itimerval p_realtimer;	/* Alarm timer. */
	struct itimerval p_timer[3];	/* Virtual-time timers. */
@@ -236,8 +235,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 +242,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 +257,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 +272,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 +285,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 +341,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 +416,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 +447,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"));
+	/* XXX lwp */
+	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..4bdf5c1 100644
--- a/sys/vm/vm_glue.c
+++ b/sys/vm/vm_glue.c
@@ -519,6 +519,7 @@ static int
swapout_procs_callback(struct proc *p, void *data)
{
	struct vmspace *vm;
+	struct lwp *lp;
	int action = *(int *)data;
@@ -530,7 +531,9 @@ 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);
		/*
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);
		}
--
1.5.0.rc2.g544a

Attachment:
signature.asc
-------------- next part --------------
A non-text attachment was scrubbed...
Name: pgp00002.pgp
Type: application/octet-stream
Size: 252 bytes
Desc: "Description: OpenPGP digital signature"
URL: <http://lists.dragonflybsd.org/pipermail/kernel/attachments/20070201/7982f641/attachment-0019.obj>


More information about the Kernel mailing list