From 287ebb0993df5dca60c3aaa965fedc87dd840918 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Fri, 29 Jun 2007 21:54:15 +0000 Subject: [PATCH] Implement struct lwp->lwp_vmspace. Leave p_vmspace intact. This allows vkernels to run threaded and to run emulated VM spaces on a per-thread basis. struct proc->p_vmspace is left intact, making it easy to switch into and out of an emulated VM space. This is needed for the virtual kernel SMP work. This also gives us the flexibility to run emulated VM spaces in their own threads, or in a limited number of separate threads. Linux does this and they say it improved performance. I don't think it necessarily improved performance but its nice to have the flexibility to do it in the future. --- sys/kern/init_main.c | 3 +- sys/kern/kern_exec.c | 8 +++- sys/kern/kern_fork.c | 3 +- sys/kern/kern_msfbuf.c | 5 ++- sys/kern/kern_sig.c | 14 +++---- sys/kern/vfs_aio.c | 40 +++++++++----------- sys/platform/pc32/i386/genassym.c | 5 ++- sys/platform/pc32/i386/machdep.c | 6 +-- sys/platform/pc32/i386/pmap.c | 55 +++++++++++++++++++++------- sys/platform/pc32/i386/swtch.s | 14 +++---- sys/platform/pc32/i386/trap.c | 40 ++++++++++---------- sys/platform/vkernel/i386/cpu_regs.c | 7 ++-- sys/platform/vkernel/i386/genassym.c | 5 ++- sys/platform/vkernel/i386/swtch.s | 14 +++---- sys/platform/vkernel/i386/trap.c | 40 ++++++++++---------- sys/platform/vkernel/platform/pmap.c | 53 +++++++++++++++++++-------- sys/sys/proc.h | 5 ++- sys/sys/vkernel.h | 8 ++-- sys/vm/pmap.h | 5 ++- sys/vm/vm_fault.c | 5 ++- sys/vm/vm_vmspace.c | 51 ++++++++++++++------------ 21 files changed, 226 insertions(+), 160 deletions(-) diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index 0143b40236..3f67762ddf 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -40,7 +40,7 @@ * * @(#)init_main.c 8.9 (Berkeley) 1/21/94 * $FreeBSD: src/sys/kern/init_main.c,v 1.134.2.8 2003/06/06 20:21:32 tegge Exp $ - * $DragonFly: src/sys/kern/init_main.c,v 1.80 2007/05/02 05:55:35 dillon Exp $ + * $DragonFly: src/sys/kern/init_main.c,v 1.81 2007/06/29 21:54:08 dillon Exp $ */ #include "opt_init_path.h" @@ -396,6 +396,7 @@ proc0_init(void *dummy __unused) /* Allocate a prototype map so we have something to fork. */ pmap_pinit0(vmspace_pmap(&vmspace0)); p->p_vmspace = &vmspace0; + lp->lwp_vmspace = p->p_vmspace; sysref_init(&vmspace0.vm_sysref, &vmspace_sysref_class); vm_map_init(&vmspace0.vm_map, round_page(VM_MIN_USER_ADDRESS), diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index b402f8c9d5..2bfe02b41b 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/kern/kern_exec.c,v 1.107.2.15 2002/07/30 15:40:46 nectar Exp $ - * $DragonFly: src/sys/kern/kern_exec.c,v 1.57 2007/06/07 23:14:25 dillon Exp $ + * $DragonFly: src/sys/kern/kern_exec.c,v 1.58 2007/06/29 21:54:08 dillon Exp $ */ #include @@ -172,6 +172,12 @@ kern_execve(struct nlookupdata *nd, struct image_args *args) struct vattr attr; int (*img_first) (struct image_params *); + if (p->p_nthreads != 1) { + kprintf("pid %d attempt to exec with multiple LWPs present\n", + p->p_pid); + return (EINVAL); + } + if (debug_execve_args) { kprintf("%s()\n", __func__); print_execve_args(args); diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 55e126a8ab..e7be5e0eeb 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -37,7 +37,7 @@ * * @(#)kern_fork.c 8.6 (Berkeley) 4/8/94 * $FreeBSD: src/sys/kern/kern_fork.c,v 1.72.2.14 2003/06/26 04:15:10 silby Exp $ - * $DragonFly: src/sys/kern/kern_fork.c,v 1.68 2007/04/29 18:25:34 dillon Exp $ + * $DragonFly: src/sys/kern/kern_fork.c,v 1.69 2007/06/29 21:54:08 dillon Exp $ */ #include "opt_ktrace.h" @@ -568,6 +568,7 @@ restart: lp = zalloc(lwp_zone); bzero(lp, sizeof(*lp)); lp->lwp_proc = destproc; + lp->lwp_vmspace = destproc->p_vmspace; lp->lwp_tid = tid; LIST_INSERT_HEAD(&destproc->p_lwps, lp, lwp_list); destproc->p_nthreads++; diff --git a/sys/kern/kern_msfbuf.c b/sys/kern/kern_msfbuf.c index b9ff427d01..8a73e58c1f 100644 --- a/sys/kern/kern_msfbuf.c +++ b/sys/kern/kern_msfbuf.c @@ -36,7 +36,7 @@ * Copyright (c) 1998 David Greenman. All rights reserved. * src/sys/kern/kern_sfbuf.c,v 1.7 2004/05/13 19:46:18 dillon * - * $DragonFly: src/sys/kern/kern_msfbuf.c,v 1.20 2007/04/30 07:18:53 dillon Exp $ + * $DragonFly: src/sys/kern/kern_msfbuf.c,v 1.21 2007/06/29 21:54:08 dillon Exp $ */ /* * MSFBUFs cache linear multi-page ephermal mappings and operate similar @@ -273,7 +273,8 @@ msf_map_ubuf(struct msf_buf **msfp, void *base, size_t nbytes, int flags) return (ERANGE); } - if ((paddr = pmap_extract(&curproc->p_vmspace->vm_pmap, (vm_offset_t)base)) != 0) + if ((paddr = pmap_extract(&curthread->td_lwp->lwp_vmspace->vm_pmap, + (vm_offset_t)base)) != 0) msf = msf_alloc(PHYS_TO_VM_PAGE(paddr), flags); else msf = msf_alloc(NULL, flags); diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 933340e341..ef1b756055 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -37,7 +37,7 @@ * * @(#)kern_sig.c 8.7 (Berkeley) 4/18/94 * $FreeBSD: src/sys/kern/kern_sig.c,v 1.72.2.17 2003/05/16 16:34:34 obrien Exp $ - * $DragonFly: src/sys/kern/kern_sig.c,v 1.78 2007/05/24 20:51:16 dillon Exp $ + * $DragonFly: src/sys/kern/kern_sig.c,v 1.79 2007/06/29 21:54:08 dillon Exp $ */ #include "opt_ktrace.h" @@ -820,10 +820,10 @@ trapsignal(struct lwp *lp, int sig, u_long code) * context, switch back to the virtual kernel context before * trying to post the signal. */ - if (p->p_vkernel && p->p_vkernel->vk_current) { - struct trapframe *tf = curthread->td_lwp->lwp_md.md_regs; + if (lp->lwp_ve) { + struct trapframe *tf = lp->lwp_md.md_regs; tf->tf_trapno = 0; - vkernel_trap(p, tf); + vkernel_trap(lp, tf); } @@ -1748,10 +1748,10 @@ postsig(int sig) * context, switch back to the virtual kernel context before * trying to post the signal. */ - if (p->p_vkernel && p->p_vkernel->vk_current) { - struct trapframe *tf = curthread->td_lwp->lwp_md.md_regs; + if (lp->lwp_ve) { + struct trapframe *tf = lp->lwp_md.md_regs; tf->tf_trapno = 0; - vkernel_trap(p, tf); + vkernel_trap(lp, tf); } lwp_delsig(lp, sig); diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c index 052c0be24d..7b85be979c 100644 --- a/sys/kern/vfs_aio.c +++ b/sys/kern/vfs_aio.c @@ -14,7 +14,7 @@ * of the author. This software is distributed AS-IS. * * $FreeBSD: src/sys/kern/vfs_aio.c,v 1.70.2.28 2003/05/29 06:15:35 alc Exp $ - * $DragonFly: src/sys/kern/vfs_aio.c,v 1.40 2007/04/30 07:18:54 dillon Exp $ + * $DragonFly: src/sys/kern/vfs_aio.c,v 1.41 2007/06/29 21:54:08 dillon Exp $ */ /* @@ -619,17 +619,13 @@ aio_daemon(void *uproc, struct trapframe *frame) struct aiocblist *aiocbe; struct aioproclist *aiop; struct kaioinfo *ki; - struct proc *curcp, *mycp, *userp; - struct vmspace *myvm; + struct proc *mycp, *userp; + struct vmspace *curvm; + struct lwp *mylwp; struct ucred *cr; - /* - * Local copies of curproc (cp) and vmspace (myvm). Get extra - * reference on myvm so we can use pmap_replacevm() - */ - mycp = curproc; - myvm = mycp->p_vmspace; - sysref_get(&myvm->vm_sysref); + mylwp = curthread->td_lwp; + mycp = mylwp->lwp_proc; if (mycp->p_textvp) { vrele(mycp->p_textvp); @@ -682,14 +678,9 @@ aio_daemon(void *uproc, struct trapframe *frame) * and creating too many daemons.) */ wakeup(mycp); + curvm = NULL; for (;;) { - /* - * curcp is the current daemon process context. - * userp is the current user process context. - */ - curcp = mycp; - /* * Take daemon off of free queue */ @@ -714,9 +705,12 @@ aio_daemon(void *uproc, struct trapframe *frame) /* * Connect to process address space for user program. */ - if (userp != curcp) { - pmap_replacevm(mycp, userp->p_vmspace, 1); - curcp = userp; + if (curvm != userp->p_vmspace) { + pmap_setlwpvm(mylwp, userp->p_vmspace); + if (curvm) + sysref_put(&curvm->vm_sysref); + curvm = userp->p_vmspace; + sysref_get(&curvm->vm_sysref); } ki = userp->p_aioinfo; @@ -781,10 +775,11 @@ aio_daemon(void *uproc, struct trapframe *frame) /* * Disconnect from user address space. */ - if (curcp != mycp) { + if (curvm) { /* swap our original address space back in */ - pmap_replacevm(mycp, myvm, 1); - curcp = mycp; + pmap_setlwpvm(mylwp, mycp->p_vmspace); + sysref_put(&curvm->vm_sysref); + curvm = NULL; } /* @@ -820,7 +815,6 @@ aio_daemon(void *uproc, struct trapframe *frame) mycp->p_vmspace->vm_sysref.refcnt); } #endif - sysref_put(&myvm->vm_sysref); exit1(0); } } diff --git a/sys/platform/pc32/i386/genassym.c b/sys/platform/pc32/i386/genassym.c index d9fd3fa067..3f8ebced5b 100644 --- a/sys/platform/pc32/i386/genassym.c +++ b/sys/platform/pc32/i386/genassym.c @@ -35,7 +35,7 @@ * * from: @(#)genassym.c 5.11 (Berkeley) 5/10/91 * $FreeBSD: src/sys/i386/i386/genassym.c,v 1.86.2.3 2002/03/03 05:42:49 nyan Exp $ - * $DragonFly: src/sys/platform/pc32/i386/genassym.c,v 1.56 2007/02/25 23:17:13 corecode Exp $ + * $DragonFly: src/sys/platform/pc32/i386/genassym.c,v 1.57 2007/06/29 21:54:10 dillon Exp $ */ #include @@ -77,7 +77,10 @@ ASSYM(P_VMSPACE, offsetof(struct proc, p_vmspace)); ASSYM(VM_PMAP, offsetof(struct vmspace, vm_pmap)); ASSYM(PM_ACTIVE, offsetof(struct pmap, pm_active)); +ASSYM(LWP_VMSPACE, offsetof(struct lwp, lwp_vmspace)); + ASSYM(TD_PROC, offsetof(struct thread, td_proc)); +ASSYM(TD_LWP, offsetof(struct thread, td_lwp)); ASSYM(TD_PCB, offsetof(struct thread, td_pcb)); ASSYM(TD_SP, offsetof(struct thread, td_sp)); ASSYM(TD_PRI, offsetof(struct thread, td_pri)); diff --git a/sys/platform/pc32/i386/machdep.c b/sys/platform/pc32/i386/machdep.c index f935ee4237..82f1f5a4e0 100644 --- a/sys/platform/pc32/i386/machdep.c +++ b/sys/platform/pc32/i386/machdep.c @@ -36,7 +36,7 @@ * * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 * $FreeBSD: src/sys/i386/i386/machdep.c,v 1.385.2.30 2003/05/31 08:48:05 alc Exp $ - * $DragonFly: src/sys/platform/pc32/i386/machdep.c,v 1.123 2007/06/07 23:45:51 dillon Exp $ + * $DragonFly: src/sys/platform/pc32/i386/machdep.c,v 1.124 2007/06/29 21:54:10 dillon Exp $ */ #include "use_apm.h" @@ -723,9 +723,9 @@ sendupcall(struct vmupcall *vu, int morepending) * context, switch back to the virtual kernel context before * trying to post the signal. */ - if (p->p_vkernel && p->p_vkernel->vk_current) { + if (lp->lwp_ve) { lp->lwp_md.md_regs->tf_trapno = 0; - vkernel_trap(p, lp->lwp_md.md_regs); + vkernel_trap(lp, lp->lwp_md.md_regs); } /* diff --git a/sys/platform/pc32/i386/pmap.c b/sys/platform/pc32/i386/pmap.c index 1cb56f2f21..213b7c7d69 100644 --- a/sys/platform/pc32/i386/pmap.c +++ b/sys/platform/pc32/i386/pmap.c @@ -40,7 +40,7 @@ * * from: @(#)pmap.c 7.7 (Berkeley) 5/12/91 * $FreeBSD: src/sys/i386/i386/pmap.c,v 1.250.2.18 2002/03/06 22:48:53 silby Exp $ - * $DragonFly: src/sys/platform/pc32/i386/pmap.c,v 1.79 2007/06/08 00:57:02 dillon Exp $ + * $DragonFly: src/sys/platform/pc32/i386/pmap.c,v 1.80 2007/06/29 21:54:10 dillon Exp $ */ /* @@ -2211,6 +2211,7 @@ pmap_object_init_pt(pmap_t pmap, vm_offset_t addr, vm_prot_t prot, vm_size_t size, int limit) { struct rb_vm_page_scan_info info; + struct lwp *lp; int psize; /* @@ -2223,7 +2224,8 @@ pmap_object_init_pt(pmap_t pmap, vm_offset_t addr, vm_prot_t prot, /* * We can't preinit if the pmap is not the current pmap */ - if (curproc == NULL || pmap != vmspace_pmap(curproc->p_vmspace)) + lp = curthread->td_lwp; + if (lp == NULL || pmap != vmspace_pmap(lp->lwp_vmspace)) return; psize = i386_btop(size); @@ -2317,6 +2319,7 @@ pmap_prefault(pmap_t pmap, vm_offset_t addra, vm_map_entry_t entry) vm_pindex_t pindex; vm_page_t m, mpte; vm_object_t object; + struct lwp *lp; /* * We do not currently prefault mappings that use virtual page @@ -2324,7 +2327,8 @@ pmap_prefault(pmap_t pmap, vm_offset_t addra, vm_map_entry_t entry) */ if (entry->maptype == VM_MAPTYPE_VPAGETABLE) return; - if (curproc == NULL || (pmap != vmspace_pmap(curproc->p_vmspace))) + lp = curthread->td_lwp; + if (lp == NULL || (pmap != vmspace_pmap(lp->lwp_vmspace))) return; object = entry->object.vm_object; @@ -2758,6 +2762,7 @@ pmap_page_exists_quick(pmap_t pmap, vm_page_t m) void pmap_remove_pages(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) { + struct lwp *lp; unsigned *pte, tpte; pv_entry_t pv, npv; vm_page_t m; @@ -2765,7 +2770,8 @@ pmap_remove_pages(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) int iscurrentpmap; int32_t save_generation; - if (curproc && pmap == vmspace_pmap(curproc->p_vmspace)) + lp = curthread->td_lwp; + if (lp && pmap == vmspace_pmap(lp->lwp_vmspace)) iscurrentpmap = 1; else iscurrentpmap = 0; @@ -3210,20 +3216,47 @@ pmap_mincore(pmap_t pmap, vm_offset_t addr) * Replace p->p_vmspace with a new one. If adjrefs is non-zero the new * vmspace will be ref'd and the old one will be deref'd. * - * If the process is the current process, pm_active will be properly - * adjusted for both vmspaces and the new vmspace will be activated. + * The vmspace for all lwps associated with the process will be adjusted + * and cr3 will be reloaded if any lwp is the current lwp. */ void pmap_replacevm(struct proc *p, struct vmspace *newvm, int adjrefs) { - struct pmap *pmap; struct vmspace *oldvm; + struct lwp *lp; + crit_enter(); oldvm = p->p_vmspace; if (oldvm != newvm) { - crit_enter(); p->p_vmspace = newvm; - if (p == curproc) { + KKASSERT(p->p_nthreads == 1); + lp = LIST_FIRST(&p->p_lwps); + pmap_setlwpvm(lp, newvm); + if (adjrefs) { + sysref_get(&newvm->vm_sysref); + sysref_put(&oldvm->vm_sysref); + } + } + crit_exit(); +} + +/* + * Set the vmspace for a LWP. The vmspace is almost universally set the + * same as the process vmspace, but virtual kernels need to swap out contexts + * on a per-lwp basis. + */ +void +pmap_setlwpvm(struct lwp *lp, struct vmspace *newvm) +{ + struct vmspace *oldvm; + struct pmap *pmap; + + crit_enter(); + oldvm = lp->lwp_vmspace; + + if (oldvm != newvm) { + lp->lwp_vmspace = newvm; + if (curthread->td_lwp == lp) { pmap = vmspace_pmap(newvm); #if defined(SMP) atomic_set_int(&pmap->pm_active, 1 << mycpu->gd_cpuid); @@ -3243,10 +3276,6 @@ pmap_replacevm(struct proc *p, struct vmspace *newvm, int adjrefs) pmap->pm_active &= ~1; #endif } - if (adjrefs) { - sysref_get(&newvm->vm_sysref); - sysref_put(&oldvm->vm_sysref); - } } crit_exit(); } diff --git a/sys/platform/pc32/i386/swtch.s b/sys/platform/pc32/i386/swtch.s index 7bba89de02..11812b89fe 100644 --- a/sys/platform/pc32/i386/swtch.s +++ b/sys/platform/pc32/i386/swtch.s @@ -66,7 +66,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/i386/i386/swtch.s,v 1.89.2.10 2003/01/23 03:36:24 ps Exp $ - * $DragonFly: src/sys/platform/pc32/i386/swtch.s,v 1.46 2007/04/30 17:41:15 dillon Exp $ + * $DragonFly: src/sys/platform/pc32/i386/swtch.s,v 1.47 2007/06/29 21:54:10 dillon Exp $ */ #include "use_npx.h" @@ -127,9 +127,9 @@ ENTRY(cpu_heavy_switch) movl %edi,PCB_EDI(%edx) movl %ecx,%ebx /* EBX = curthread */ - movl TD_PROC(%ecx),%ecx + movl TD_LWP(%ecx),%ecx movl PCPU(cpuid), %eax - movl P_VMSPACE(%ecx), %ecx /* ECX = vmspace */ + movl LWP_VMSPACE(%ecx), %ecx /* ECX = vmspace */ MPLOCKED btrl %eax, VM_PMAP+PM_ACTIVE(%ecx) /* @@ -224,11 +224,11 @@ ENTRY(cpu_exit_switch) * If this is a process/lwp, deactivate the pmap after we've * switched it out. */ - movl TD_PROC(%ebx),%ecx + movl TD_LWP(%ebx),%ecx testl %ecx,%ecx jz 2f movl PCPU(cpuid), %eax - movl P_VMSPACE(%ecx), %ecx /* ECX = vmspace */ + movl LWP_VMSPACE(%ecx), %ecx /* ECX = vmspace */ MPLOCKED btrl %eax, VM_PMAP+PM_ACTIVE(%ecx) 2: /* @@ -274,7 +274,7 @@ ENTRY(cpu_exit_switch) ENTRY(cpu_heavy_restore) popfl movl TD_PCB(%eax),%edx /* EDX = PCB */ - movl TD_PROC(%eax),%ecx + movl TD_LWP(%eax),%ecx #if defined(SWTCH_OPTIM_STATS) incl _swtch_optim_stats @@ -284,7 +284,7 @@ ENTRY(cpu_heavy_restore) * safely test/reload %cr3 until after we have set the bit in the * pmap (remember, we do not hold the MP lock in the switch code). */ - movl P_VMSPACE(%ecx), %ecx /* ECX = vmspace */ + movl LWP_VMSPACE(%ecx), %ecx /* ECX = vmspace */ movl PCPU(cpuid), %esi MPLOCKED btsl %esi, VM_PMAP+PM_ACTIVE(%ecx) diff --git a/sys/platform/pc32/i386/trap.c b/sys/platform/pc32/i386/trap.c index ae9ddbfea5..77a72c9959 100644 --- a/sys/platform/pc32/i386/trap.c +++ b/sys/platform/pc32/i386/trap.c @@ -36,7 +36,7 @@ * * from: @(#)trap.c 7.4 (Berkeley) 5/13/91 * $FreeBSD: src/sys/i386/i386/trap.c,v 1.147.2.11 2003/02/27 19:09:59 luoqi Exp $ - * $DragonFly: src/sys/platform/pc32/i386/trap.c,v 1.104 2007/04/29 18:25:36 dillon Exp $ + * $DragonFly: src/sys/platform/pc32/i386/trap.c,v 1.105 2007/06/29 21:54:10 dillon Exp $ */ /* @@ -629,7 +629,7 @@ restart: * saved FP state that the virtual kernel needs * to hand over to a different emulated process. */ - if (p->p_vkernel && p->p_vkernel->vk_current && + if (lp->lwp_ve && (td->td_pcb->pcb_flags & FP_VIRTFP) ) { npxdna(); @@ -857,8 +857,8 @@ kernel_trap: * VM context managed by a virtual kernel then let the virtual kernel * handle it. */ - if (p->p_vkernel && p->p_vkernel->vk_current) { - vkernel_trap(p, frame); + if (lp->lwp_ve) { + vkernel_trap(lp, frame); goto out; } @@ -909,7 +909,7 @@ trap_pfault(struct trapframe *frame, int usermode, vm_offset_t eva) int rv = 0; vm_prot_t ftype; thread_t td = curthread; - struct proc *p = td->td_proc; + struct lwp *lp = td->td_lwp; va = trunc_page(eva); if (va >= KERNBASE) { @@ -937,8 +937,8 @@ trap_pfault(struct trapframe *frame, int usermode, vm_offset_t eva) * vm is initialized above to NULL. If curproc is NULL * or curproc->p_vmspace is NULL the fault is fatal. */ - if (p != NULL) - vm = p->p_vmspace; + if (lp != NULL) + vm = lp->lwp_vmspace; if (vm == NULL) goto nogo; @@ -956,7 +956,7 @@ trap_pfault(struct trapframe *frame, int usermode, vm_offset_t eva) * Keep swapout from messing with us during this * critical time. */ - PHOLD(p); + PHOLD(lp->lwp_proc); /* * Grow the stack if necessary @@ -967,9 +967,9 @@ trap_pfault(struct trapframe *frame, int usermode, vm_offset_t eva) * a growable stack region, or if the stack * growth succeeded. */ - if (!grow_stack (p, va)) { + if (!grow_stack(lp->lwp_proc, va)) { rv = KERN_FAILURE; - PRELE(p); + PRELE(lp->lwp_proc); goto nogo; } @@ -978,7 +978,7 @@ trap_pfault(struct trapframe *frame, int usermode, vm_offset_t eva) (ftype & VM_PROT_WRITE) ? VM_FAULT_DIRTY : VM_FAULT_NORMAL); - PRELE(p); + PRELE(lp->lwp_proc); } else { /* * Don't have to worry about process locking or stacks in the kernel. @@ -1138,7 +1138,7 @@ dblfault_handler(void) int trapwrite(unsigned addr) { - struct proc *p; + struct lwp *lp; vm_offset_t va; struct vmspace *vm; int rv; @@ -1150,13 +1150,13 @@ trapwrite(unsigned addr) if (va >= VM_MAX_USER_ADDRESS) return (1); - p = curproc; - vm = p->p_vmspace; + lp = curthread->td_lwp; + vm = lp->lwp_vmspace; - PHOLD(p); + PHOLD(lp->lwp_proc); - if (!grow_stack (p, va)) { - PRELE(p); + if (!grow_stack(lp->lwp_proc, va)) { + PRELE(lp->lwp_proc); return (1); } @@ -1165,7 +1165,7 @@ trapwrite(unsigned addr) */ rv = vm_fault(&vm->vm_map, va, VM_PROT_WRITE, VM_FAULT_DIRTY); - PRELE(p); + PRELE(lp->lwp_proc); if (rv != KERN_SUCCESS) return 1; @@ -1236,8 +1236,8 @@ syscall2(struct trapframe *frame) * Restore the virtual kernel context and return from its system * call. The current frame is copied out to the virtual kernel. */ - if (p->p_vkernel && p->p_vkernel->vk_current) { - error = vkernel_trap(p, frame); + if (lp->lwp_ve) { + error = vkernel_trap(lp, frame); frame->tf_eax = error; if (error) frame->tf_eflags |= PSL_C; diff --git a/sys/platform/vkernel/i386/cpu_regs.c b/sys/platform/vkernel/i386/cpu_regs.c index 142c50f87d..2fa15087a2 100644 --- a/sys/platform/vkernel/i386/cpu_regs.c +++ b/sys/platform/vkernel/i386/cpu_regs.c @@ -37,7 +37,7 @@ * * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 * $FreeBSD: src/sys/i386/i386/machdep.c,v 1.385.2.30 2003/05/31 08:48:05 alc Exp $ - * $DragonFly: src/sys/platform/vkernel/i386/cpu_regs.c,v 1.15 2007/05/17 21:08:50 dillon Exp $ + * $DragonFly: src/sys/platform/vkernel/i386/cpu_regs.c,v 1.16 2007/06/29 21:54:11 dillon Exp $ */ #include "use_ether.h" @@ -515,7 +515,6 @@ void sendupcall(struct vmupcall *vu, int morepending) { struct lwp *lp = curthread->td_lwp; - struct proc *p = lp->lwp_proc; struct trapframe *regs; struct upcall upcall; struct upc_frame upc_frame; @@ -526,9 +525,9 @@ sendupcall(struct vmupcall *vu, int morepending) * context, switch back to the virtual kernel context before * trying to post the signal. */ - if (p->p_vkernel && p->p_vkernel->vk_current) { + if (lp->lwp_ve) { lp->lwp_md.md_regs->tf_trapno = 0; - vkernel_trap(p, lp->lwp_md.md_regs); + vkernel_trap(lp, lp->lwp_md.md_regs); } /* diff --git a/sys/platform/vkernel/i386/genassym.c b/sys/platform/vkernel/i386/genassym.c index 576ee04406..8c4bdd93b6 100644 --- a/sys/platform/vkernel/i386/genassym.c +++ b/sys/platform/vkernel/i386/genassym.c @@ -35,7 +35,7 @@ * * from: @(#)genassym.c 5.11 (Berkeley) 5/10/91 * $FreeBSD: src/sys/i386/i386/genassym.c,v 1.86.2.3 2002/03/03 05:42:49 nyan Exp $ - * $DragonFly: src/sys/platform/vkernel/i386/genassym.c,v 1.57 2007/02/25 23:17:13 corecode Exp $ + * $DragonFly: src/sys/platform/vkernel/i386/genassym.c,v 1.58 2007/06/29 21:54:11 dillon Exp $ */ #include @@ -75,7 +75,10 @@ ASSYM(P_VMSPACE, offsetof(struct proc, p_vmspace)); ASSYM(VM_PMAP, offsetof(struct vmspace, vm_pmap)); ASSYM(PM_ACTIVE, offsetof(struct pmap, pm_active)); +ASSYM(LWP_VMSPACE, offsetof(struct lwp, lwp_vmspace)); + ASSYM(TD_PROC, offsetof(struct thread, td_proc)); +ASSYM(TD_LWP, offsetof(struct thread, td_lwp)); ASSYM(TD_PCB, offsetof(struct thread, td_pcb)); ASSYM(TD_SP, offsetof(struct thread, td_sp)); ASSYM(TD_PRI, offsetof(struct thread, td_pri)); diff --git a/sys/platform/vkernel/i386/swtch.s b/sys/platform/vkernel/i386/swtch.s index 8e8402f114..8b53677cfc 100644 --- a/sys/platform/vkernel/i386/swtch.s +++ b/sys/platform/vkernel/i386/swtch.s @@ -66,7 +66,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/i386/i386/swtch.s,v 1.89.2.10 2003/01/23 03:36:24 ps Exp $ - * $DragonFly: src/sys/platform/vkernel/i386/swtch.s,v 1.6 2007/04/29 18:25:38 dillon Exp $ + * $DragonFly: src/sys/platform/vkernel/i386/swtch.s,v 1.7 2007/06/29 21:54:11 dillon Exp $ */ #include "use_npx.h" @@ -126,9 +126,9 @@ ENTRY(cpu_heavy_switch) movl %edi,PCB_EDI(%edx) movl %ecx,%ebx /* EBX = curthread */ - movl TD_PROC(%ecx),%ecx + movl TD_LWP(%ecx),%ecx movl PCPU(cpuid), %eax - movl P_VMSPACE(%ecx), %ecx /* ECX = vmspace */ + movl LWP_VMSPACE(%ecx), %ecx /* ECX = vmspace */ MPLOCKED btrl %eax, VM_PMAP+PM_ACTIVE(%ecx) /* @@ -225,11 +225,11 @@ ENTRY(cpu_exit_switch) * If this is a process/lwp, deactivate the pmap after we've * switched it out. */ - movl TD_PROC(%ebx),%ecx + movl TD_LWP(%ebx),%ecx testl %ecx,%ecx jz 2f movl PCPU(cpuid), %eax - movl P_VMSPACE(%ecx), %ecx /* ECX = vmspace */ + movl LWP_VMSPACE(%ecx), %ecx /* ECX = vmspace */ MPLOCKED btrl %eax, VM_PMAP+PM_ACTIVE(%ecx) 2: /* @@ -275,7 +275,7 @@ ENTRY(cpu_exit_switch) ENTRY(cpu_heavy_restore) popfl movl TD_PCB(%eax),%edx /* EDX = PCB */ - movl TD_PROC(%eax),%ecx + movl TD_LWP(%eax),%ecx #if defined(SWTCH_OPTIM_STATS) incl _swtch_optim_stats @@ -285,7 +285,7 @@ ENTRY(cpu_heavy_restore) * safely test/reload %cr3 until after we have set the bit in the * pmap (remember, we do not hold the MP lock in the switch code). */ - movl P_VMSPACE(%ecx), %ecx /* ECX = vmspace */ + movl LWP_VMSPACE(%ecx), %ecx /* ECX = vmspace */ movl PCPU(cpuid), %esi MPLOCKED btsl %esi, VM_PMAP+PM_ACTIVE(%ecx) diff --git a/sys/platform/vkernel/i386/trap.c b/sys/platform/vkernel/i386/trap.c index b600c5e2c8..319a7aba5e 100644 --- a/sys/platform/vkernel/i386/trap.c +++ b/sys/platform/vkernel/i386/trap.c @@ -36,7 +36,7 @@ * * from: @(#)trap.c 7.4 (Berkeley) 5/13/91 * $FreeBSD: src/sys/i386/i386/trap.c,v 1.147.2.11 2003/02/27 19:09:59 luoqi Exp $ - * $DragonFly: src/sys/platform/vkernel/i386/trap.c,v 1.24 2007/06/18 18:57:12 josepht Exp $ + * $DragonFly: src/sys/platform/vkernel/i386/trap.c,v 1.25 2007/06/29 21:54:11 dillon Exp $ */ /* @@ -551,7 +551,7 @@ restart: * saved FP state that the (emulated) virtual kernel * needs to hand over to a different emulated process. */ - if (p->p_vkernel && p->p_vkernel->vk_current && + if (lp->lwp_ve && (td->td_pcb->pcb_flags & FP_VIRTFP) ) { npxdna(frame); @@ -598,8 +598,8 @@ restart: * VM context managed by a virtual kernel then let the virtual kernel * handle it. */ - if (p->p_vkernel && p->p_vkernel->vk_current) { - vkernel_trap(p, frame); + if (lp->lwp_ve) { + vkernel_trap(lp, frame); goto out; } @@ -858,7 +858,7 @@ trap_pfault(struct trapframe *frame, int usermode, vm_offset_t eva) int rv = 0; vm_prot_t ftype; thread_t td = curthread; - struct proc *p = td->td_proc; + struct lwp *lp = td->td_lwp; va = trunc_page(eva); if (usermode == FALSE) { @@ -872,8 +872,8 @@ trap_pfault(struct trapframe *frame, int usermode, vm_offset_t eva) * vm is initialized above to NULL. If curproc is NULL * or curproc->p_vmspace is NULL the fault is fatal. */ - if (p != NULL) - vm = p->p_vmspace; + if (lp != NULL) + vm = lp->lwp_vmspace; if (vm == NULL) goto nogo; @@ -891,7 +891,7 @@ trap_pfault(struct trapframe *frame, int usermode, vm_offset_t eva) * Keep swapout from messing with us during this * critical time. */ - PHOLD(p); + PHOLD(lp->lwp_proc); /* * Grow the stack if necessary @@ -902,9 +902,9 @@ trap_pfault(struct trapframe *frame, int usermode, vm_offset_t eva) * a growable stack region, or if the stack * growth succeeded. */ - if (!grow_stack (p, va)) { + if (!grow_stack (lp->lwp_proc, va)) { rv = KERN_FAILURE; - PRELE(p); + PRELE(lp->lwp_proc); goto nogo; } @@ -913,7 +913,7 @@ trap_pfault(struct trapframe *frame, int usermode, vm_offset_t eva) (ftype & VM_PROT_WRITE) ? VM_FAULT_DIRTY : VM_FAULT_NORMAL); - PRELE(p); + PRELE(lp->lwp_proc); } else { /* * Don't have to worry about process locking or stacks in the kernel. @@ -1061,7 +1061,7 @@ dblfault_handler(void) int trapwrite(unsigned addr) { - struct proc *p; + struct lwp *lp; vm_offset_t va; struct vmspace *vm; int rv; @@ -1073,13 +1073,13 @@ trapwrite(unsigned addr) if (va >= VM_MAX_USER_ADDRESS) return (1); - p = curproc; - vm = p->p_vmspace; + lp = curthread->td_lwp; + vm = lp->lwp_vmspace; - PHOLD(p); + PHOLD(lp->lwp_proc); - if (!grow_stack (p, va)) { - PRELE(p); + if (!grow_stack (lp->lwp_proc, va)) { + PRELE(lp->lwp_proc); return (1); } @@ -1088,7 +1088,7 @@ trapwrite(unsigned addr) */ rv = vm_fault(&vm->vm_map, va, VM_PROT_WRITE, VM_FAULT_DIRTY); - PRELE(p); + PRELE(lp->lwp_proc); if (rv != KERN_SUCCESS) return 1; @@ -1151,8 +1151,8 @@ syscall2(struct trapframe *frame) * Restore the virtual kernel context and return from its system * call. The current frame is copied out to the virtual kernel. */ - if (p->p_vkernel && p->p_vkernel->vk_current) { - error = vkernel_trap(p, frame); + if (lp->lwp_ve) { + error = vkernel_trap(lp, frame); frame->tf_eax = error; if (error) frame->tf_eflags |= PSL_C; diff --git a/sys/platform/vkernel/platform/pmap.c b/sys/platform/vkernel/platform/pmap.c index aba704af46..d760f09bdf 100644 --- a/sys/platform/vkernel/platform/pmap.c +++ b/sys/platform/vkernel/platform/pmap.c @@ -38,7 +38,7 @@ * * from: @(#)pmap.c 7.7 (Berkeley) 5/12/91 * $FreeBSD: src/sys/i386/i386/pmap.c,v 1.250.2.18 2002/03/06 22:48:53 silby Exp $ - * $DragonFly: src/sys/platform/vkernel/platform/pmap.c,v 1.22 2007/06/18 18:57:13 josepht Exp $ + * $DragonFly: src/sys/platform/vkernel/platform/pmap.c,v 1.23 2007/06/29 21:54:12 dillon Exp $ */ /* * NOTE: PMAP_INVAL_ADD: In pc32 this function is called prior to adjusting @@ -1986,6 +1986,7 @@ pmap_object_init_pt(pmap_t pmap, vm_offset_t addr, vm_prot_t prot, vm_size_t size, int limit) { struct rb_vm_page_scan_info info; + struct lwp *lp; int psize; /* @@ -1998,7 +1999,8 @@ pmap_object_init_pt(pmap_t pmap, vm_offset_t addr, vm_prot_t prot, /* * We can't preinit if the pmap is not the current pmap */ - if (curproc == NULL || pmap != vmspace_pmap(curproc->p_vmspace)) + lp = curthread->td_lwp; + if (lp == NULL || pmap != vmspace_pmap(lp->lwp_vmspace)) return; psize = size >> PAGE_SHIFT; @@ -2086,12 +2088,13 @@ static int pmap_prefault_pageorder[] = { void pmap_prefault(pmap_t pmap, vm_offset_t addra, vm_map_entry_t entry) { - int i; vm_offset_t starta; vm_offset_t addr; vm_pindex_t pindex; vm_page_t m, mpte; vm_object_t object; + struct lwp *lp; + int i; /* * We do not currently prefault mappings that use virtual page @@ -2099,7 +2102,8 @@ pmap_prefault(pmap_t pmap, vm_offset_t addra, vm_map_entry_t entry) */ if (entry->maptype == VM_MAPTYPE_VPAGETABLE) return; - if (curproc == NULL || (pmap != vmspace_pmap(curproc->p_vmspace))) + lp = curthread->td_lwp; + if (lp == NULL || pmap != vmspace_pmap(lp->lwp_vmspace)) return; object = entry->object.vm_object; @@ -2539,8 +2543,10 @@ pmap_remove_pages(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) pmap_inval_info info; int iscurrentpmap; int32_t save_generation; + struct lwp *lp; - if (curproc && pmap == vmspace_pmap(curproc->p_vmspace)) + lp = curthread->td_lwp; + if (lp && pmap == vmspace_pmap(lp->lwp_vmspace)) iscurrentpmap = 1; else iscurrentpmap = 0; @@ -2975,14 +2981,36 @@ pmap_mincore(pmap_t pmap, vm_offset_t addr) void pmap_replacevm(struct proc *p, struct vmspace *newvm, int adjrefs) { - struct pmap *pmap; struct vmspace *oldvm; + struct lwp *lp; oldvm = p->p_vmspace; + crit_enter(); if (oldvm != newvm) { - crit_enter(); p->p_vmspace = newvm; - if (p == curproc) { + KKASSERT(p->p_nthreads == 1); + lp = LIST_FIRST(&p->p_lwps); + pmap_setlwpvm(lp, newvm); + if (adjrefs) { + sysref_get(&newvm->vm_sysref); + sysref_put(&oldvm->vm_sysref); + } + } + crit_exit(); +} + +void +pmap_setlwpvm(struct lwp *lp, struct vmspace *newvm) +{ + struct vmspace *oldvm; + struct pmap *pmap; + + crit_enter(); + oldvm = lp->lwp_vmspace; + + if (oldvm != newvm) { + lp->lwp_vmspace = newvm; + if (curthread->td_lwp == lp) { pmap = vmspace_pmap(newvm); #if defined(SMP) atomic_set_int(&pmap->pm_active, 1 << mycpu->gd_cpuid); @@ -2991,10 +3019,6 @@ pmap_replacevm(struct proc *p, struct vmspace *newvm, int adjrefs) #endif #if defined(SWTCH_OPTIM_STATS) tlb_flush_count++; -#endif -#if 0 - curthread->td_pcb->pcb_cr3 = vtophys(pmap->pm_pdir); - load_cr3(curthread->td_pcb->pcb_cr3); #endif pmap = vmspace_pmap(oldvm); #if defined(SMP) @@ -3004,14 +3028,11 @@ pmap_replacevm(struct proc *p, struct vmspace *newvm, int adjrefs) pmap->pm_active &= ~1; #endif } - if (adjrefs) { - sysref_get(&newvm->vm_sysref); - sysref_put(&oldvm->vm_sysref); - } } crit_exit(); } + vm_offset_t pmap_addr_hint(vm_object_t obj, vm_offset_t addr, vm_size_t size) { diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 27f19c95f3..1c049ae31a 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -37,7 +37,7 @@ * * @(#)proc.h 8.15 (Berkeley) 5/19/95 * $FreeBSD: src/sys/sys/proc.h,v 1.99.2.9 2003/06/06 20:21:32 tegge Exp $ - * $DragonFly: src/sys/sys/proc.h,v 1.107 2007/04/29 18:25:33 dillon Exp $ + * $DragonFly: src/sys/sys/proc.h,v 1.108 2007/06/29 21:54:14 dillon Exp $ */ #ifndef _SYS_PROC_H_ @@ -131,6 +131,7 @@ struct pargs { struct jail; struct vkernel; +struct vmspace_entry; struct ktrace_node; enum lwpstat { @@ -151,6 +152,8 @@ struct lwp { LIST_ENTRY(lwp) lwp_list; /* List of all threads in the proc. */ struct proc *lwp_proc; /* Link to our proc. */ + struct vmspace *lwp_vmspace; /* Inherited from p_vmspace */ + struct vmspace_entry *lwp_ve; /* Used by the vkernel */ lwpid_t lwp_tid; /* Our thread id . */ diff --git a/sys/sys/vkernel.h b/sys/sys/vkernel.h index f37266cf48..5148051968 100644 --- a/sys/sys/vkernel.h +++ b/sys/sys/vkernel.h @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/sys/vkernel.h,v 1.8 2007/01/08 19:45:39 dillon Exp $ + * $DragonFly: src/sys/sys/vkernel.h,v 1.9 2007/06/29 21:54:14 dillon Exp $ */ #ifndef _SYS_VKERNEL_H_ @@ -71,13 +71,11 @@ RB_PROTOTYPE(vmspace_rb_tree, vmspace_entry, rb_entry, rb_vmspace_compare); * structure. */ struct vkernel { - struct vmspace *vk_save_vmspace; /* saved VM space */ struct trapframe vk_save_trapframe; /* swapped context */ struct vextframe vk_save_vextframe; struct trapframe *vk_user_trapframe; /* copyback to vkernel */ struct vextframe *vk_user_vextframe; struct vkernel_common *vk_common; /* shared data */ - struct vmspace_entry *vk_current; }; struct vkernel_common { @@ -90,7 +88,7 @@ struct vmspace_entry { void *id; struct vmspace *vmspace; int flags; - int refs; /* when vk_current */ + int refs; /* current LWP assignments */ RB_ENTRY(vmspace_entry) rb_entry; }; @@ -98,7 +96,7 @@ struct vmspace_entry { void vkernel_inherit(struct proc *p1, struct proc *p2); void vkernel_exit(struct proc *p); -int vkernel_trap(struct proc *p, struct trapframe *frame); +int vkernel_trap(struct lwp *lp, struct trapframe *frame); #endif diff --git a/sys/vm/pmap.h b/sys/vm/pmap.h index bae7c901b7..06d0281f53 100644 --- a/sys/vm/pmap.h +++ b/sys/vm/pmap.h @@ -62,7 +62,7 @@ * rights to redistribute these changes. * * $FreeBSD: src/sys/vm/pmap.h,v 1.33.2.4 2002/03/06 22:44:24 silby Exp $ - * $DragonFly: src/sys/vm/pmap.h,v 1.25 2007/04/29 18:25:41 dillon Exp $ + * $DragonFly: src/sys/vm/pmap.h,v 1.26 2007/06/29 21:54:15 dillon Exp $ */ /* @@ -91,6 +91,7 @@ struct proc; struct thread; struct vm_page; struct vmspace; +struct vmspace_entry; /* * Most of these variables represent parameters set up by low level MD kernel @@ -171,6 +172,8 @@ void pmap_init_proc (struct proc *); void pmap_init_thread (struct thread *td); void pmap_dispose_proc (struct proc *p); void pmap_replacevm (struct proc *, struct vmspace *, int); +void pmap_setlwpvm (struct lwp *, struct vmspace *); + vm_offset_t pmap_addr_hint (vm_object_t obj, vm_offset_t addr, vm_size_t size); void *pmap_kenter_temporary (vm_paddr_t pa, int i); void pmap_init2 (void); diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c index 5c9590a990..52b0cc3ff4 100644 --- a/sys/vm/vm_fault.c +++ b/sys/vm/vm_fault.c @@ -67,7 +67,7 @@ * rights to redistribute these changes. * * $FreeBSD: src/sys/vm/vm_fault.c,v 1.108.2.8 2002/02/26 05:49:27 silby Exp $ - * $DragonFly: src/sys/vm/vm_fault.c,v 1.42 2007/06/07 23:00:39 dillon Exp $ + * $DragonFly: src/sys/vm/vm_fault.c,v 1.43 2007/06/29 21:54:15 dillon Exp $ */ /* @@ -418,9 +418,10 @@ RetryFault: vm_page_t vm_fault_page_quick(vm_offset_t va, vm_prot_t fault_type, int *errorp) { + struct lwp *lp = curthread->td_lwp; vm_page_t m; - m = vm_fault_page(&curproc->p_vmspace->vm_map, va, + m = vm_fault_page(&lp->lwp_vmspace->vm_map, va, fault_type, VM_FAULT_NORMAL, errorp); return(m); } diff --git a/sys/vm/vm_vmspace.c b/sys/vm/vm_vmspace.c index 9209a69232..56016d254b 100644 --- a/sys/vm/vm_vmspace.c +++ b/sys/vm/vm_vmspace.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/vm/vm_vmspace.c,v 1.11 2007/04/29 18:25:41 dillon Exp $ + * $DragonFly: src/sys/vm/vm_vmspace.c,v 1.12 2007/06/29 21:54:15 dillon Exp $ */ #include "opt_ddb.h" @@ -149,11 +149,15 @@ sys_vmspace_ctl(struct vmspace_ctl_args *uap) struct vkernel_common *vc; struct vmspace_entry *ve; struct vkernel *vk; + struct lwp *lwp; struct proc *p; int framesz; int error; - if ((vk = curproc->p_vkernel) == NULL) + lwp = curthread->td_lwp; + p = lwp->lwp_proc; + + if ((vk = p->p_vkernel) == NULL) return (EINVAL); vc = vk->vk_common; if ((ve = vkernel_find_vmspace(vc, uap->id)) == NULL) @@ -162,8 +166,8 @@ sys_vmspace_ctl(struct vmspace_ctl_args *uap) /* * Signal mailbox interlock */ - if (curproc->p_flag & P_MAILBOX) { - curproc->p_flag &= ~P_MAILBOX; + if (p->p_flag & P_MAILBOX) { + p->p_flag &= ~P_MAILBOX; return (EINTR); } @@ -174,11 +178,8 @@ sys_vmspace_ctl(struct vmspace_ctl_args *uap) * install the passed register context. Return with * EJUSTRETURN so the syscall code doesn't adjust the context. */ - p = curproc; ++ve->refs; framesz = sizeof(struct trapframe); - vk->vk_current = ve; - vk->vk_save_vmspace = p->p_vmspace; vk->vk_user_trapframe = uap->tframe; vk->vk_user_vextframe = uap->vframe; bcopy(uap->sysmsg_frame, &vk->vk_save_trapframe, framesz); @@ -196,11 +197,10 @@ sys_vmspace_ctl(struct vmspace_ctl_args *uap) bcopy(&vk->vk_save_vextframe.vx_tls, &curthread->td_tls, sizeof(vk->vk_save_vextframe.vx_tls)); set_user_TLS(); - vk->vk_current = NULL; - vk->vk_save_vmspace = NULL; --ve->refs; } else { - pmap_replacevm(p, ve->vmspace, 0); + lwp->lwp_ve = ve; + pmap_setlwpvm(lwp, ve->vmspace); set_user_TLS(); set_vkernel_fp(uap->sysmsg_frame); error = EJUSTRETURN; @@ -456,6 +456,7 @@ vkernel_exit(struct proc *p) struct vkernel_common *vc; struct vmspace_entry *ve; struct vkernel *vk; + struct lwp *lp; int freeme = 0; vk = p->p_vkernel; @@ -471,16 +472,18 @@ vkernel_exit(struct proc *p) * that the process should enter vkernel_trap() before the handling * the signal. */ - if ((ve = vk->vk_current) != NULL) { - kprintf("Killed with active VC, notify kernel list\n"); + LIST_FOREACH(lp, &p->p_lwps, lwp_list) { + if ((ve = lp->lwp_ve) != NULL) { + kprintf("Warning, pid %d killed with active VC!\n", + p->p_pid); #ifdef DDB - db_print_backtrace(); + db_print_backtrace(); #endif - vk->vk_current = NULL; - pmap_replacevm(p, vk->vk_save_vmspace, 0); - vk->vk_save_vmspace = NULL; - KKASSERT(ve->refs > 0); - --ve->refs; + lp->lwp_ve = NULL; + pmap_setlwpvm(lp, p->p_vmspace); + KKASSERT(ve->refs > 0); + --ve->refs; + } } /* @@ -505,8 +508,9 @@ vkernel_exit(struct proc *p) * or otherwise needs to return control to the virtual kernel context. */ int -vkernel_trap(struct proc *p, struct trapframe *frame) +vkernel_trap(struct lwp *lp, struct trapframe *frame) { + struct proc *p = lp->lwp_proc; struct vmspace_entry *ve; struct vkernel *vk; int error; @@ -515,15 +519,14 @@ vkernel_trap(struct proc *p, struct trapframe *frame) * Which vmspace entry was running? */ vk = p->p_vkernel; - ve = vk->vk_current; - vk->vk_current = NULL; + ve = lp->lwp_ve; KKASSERT(ve != NULL); /* - * Switch the process context back to the virtual kernel's VM space. + * Switch the LWP vmspace back to the virtual kernel's VM space. */ - pmap_replacevm(p, vk->vk_save_vmspace, 0); - vk->vk_save_vmspace = NULL; + lp->lwp_ve = NULL; + pmap_setlwpvm(lp, p->p_vmspace); KKASSERT(ve->refs > 0); --ve->refs; -- 2.41.0