diff --git a/sys/arch/hppa/hppa/pmap.c b/sys/arch/hppa/hppa/pmap.c index b07ce0b18c59..ba43ebd3a1f5 100644 --- a/sys/arch/hppa/hppa/pmap.c +++ b/sys/arch/hppa/hppa/pmap.c @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.c,v 1.35 2007/03/04 05:59:55 christos Exp $ */ +/* $NetBSD: pmap.c,v 1.36 2007/05/18 09:10:50 skrll Exp $ */ /*- * Copyright (c) 2001, 2002 The NetBSD Foundation, Inc. @@ -171,7 +171,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.35 2007/03/04 05:59:55 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.36 2007/05/18 09:10:50 skrll Exp $"); #include #include @@ -1242,6 +1242,7 @@ pmap_pinit(pmap_t pmap) pmap->pmap_refcnt = 1; pmap->pmap_stats.resident_count = 0; pmap->pmap_stats.wired_count = 0; + pmap->pmap_vmspace = NULL; splx(s); } @@ -1324,27 +1325,29 @@ pmap_destroy(pmap_t pmap) void pmap_activate(struct lwp *l) { + struct proc *p = l->l_proc; pmap_t pmap = p->p_vmspace->vm_map.pmap; pa_space_t space = pmap->pmap_space; - struct trapframe *tf = l->l_md.md_regs; + struct pcb *pcb = &l->l_addr->u_pcb; /* space is cached for the copy{in,out}'s pleasure */ - l->l_addr->u_pcb.pcb_space = space; + pcb->pcb_space = space; - /* Load all of the user's space registers. */ - tf->tf_sr0 = tf->tf_sr1 = tf->tf_sr2 = tf->tf_sr3 = - tf->tf_sr4 = tf->tf_sr5 = tf->tf_sr6 = space; - tf->tf_iisq_head = tf->tf_iisq_tail = space; + if (pmap->pmap_vmspace != l->l_proc->p_vmspace) { + struct trapframe *tf = l->l_md.md_regs; + + pmap->pmap_vmspace = l->l_proc->p_vmspace; + + /* Load all of the user's space registers. */ + tf->tf_sr0 = tf->tf_sr1 = tf->tf_sr2 = tf->tf_sr3 = + tf->tf_sr4 = tf->tf_sr5 = tf->tf_sr6 = space; + tf->tf_iisq_head = tf->tf_iisq_tail = space; + + /* Load the protection registers. */ + tf->tf_pidr1 = tf->tf_pidr2 = pmap->pmap_pid; + } - /* - * Load the protection registers. NB that - * if p *is* the current process, we set pidr2 - * to the new space immediately, so any copyins - * or copyouts that happen before we return to - * userspace work. - */ - tf->tf_pidr1 = tf->tf_pidr2 = pmap->pmap_pid; if (p == curproc) mtctl(pmap->pmap_pid, CR_PIDR2); } diff --git a/sys/arch/hppa/hppa/vm_machdep.c b/sys/arch/hppa/hppa/vm_machdep.c index af1c32849633..1c156096ef10 100644 --- a/sys/arch/hppa/hppa/vm_machdep.c +++ b/sys/arch/hppa/hppa/vm_machdep.c @@ -1,4 +1,4 @@ -/* $NetBSD: vm_machdep.c,v 1.25 2007/05/17 14:51:20 yamt Exp $ */ +/* $NetBSD: vm_machdep.c,v 1.26 2007/05/18 09:10:50 skrll Exp $ */ /* $OpenBSD: vm_machdep.c,v 1.25 2001/09/19 20:50:56 mickey Exp $ */ @@ -34,7 +34,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.25 2007/05/17 14:51:20 yamt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.26 2007/05/18 09:10:50 skrll Exp $"); #include #include @@ -121,6 +121,9 @@ void cpu_lwp_fork(struct lwp *l1, struct lwp *l2, void *stack, size_t stacksize, void (*func)(void *), void *arg) { + struct proc *p = l2->l_proc; + pmap_t pmap = p->p_vmspace->vm_map.pmap; + pa_space_t space = pmap->pmap_space; struct pcb *pcbp; struct trapframe *tf; register_t sp, osp; @@ -147,6 +150,8 @@ cpu_lwp_fork(struct lwp *l1, struct lwp *l2, void *stack, size_t stacksize, sp = (register_t)l2->l_addr + PAGE_SIZE; l2->l_md.md_regs = tf = (struct trapframe *)sp; sp += sizeof(struct trapframe); + + /* copy the l1's trapframe to l2 */ bcopy(l1->l_md.md_regs, tf, sizeof(*tf)); /* @@ -155,8 +160,14 @@ cpu_lwp_fork(struct lwp *l1, struct lwp *l2, void *stack, size_t stacksize, */ cpu_swapin(l2); - /* Activate this process' pmap. */ - pmap_activate(l2); + /* Load all of the user's space registers. */ + tf->tf_sr0 = tf->tf_sr1 = tf->tf_sr3 = tf->tf_sr2 = + tf->tf_sr4 = tf->tf_sr5 = tf->tf_sr6 = space; + tf->tf_iisq_head = tf->tf_iisq_tail = space; + tf->tf_pidr1 = tf->tf_pidr2 = pmap->pmap_pid; + + /* record the vmspace just in case it changes underneath us. */ + pmap->pmap_vmspace = p->p_vmspace; /* * theoretically these could be inherited from the father, diff --git a/sys/arch/hppa/include/pmap.h b/sys/arch/hppa/include/pmap.h index a21a034595e0..cbb9307dfa19 100644 --- a/sys/arch/hppa/include/pmap.h +++ b/sys/arch/hppa/include/pmap.h @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.h,v 1.12 2007/04/07 09:02:07 skrll Exp $ */ +/* $NetBSD: pmap.h,v 1.13 2007/05/18 09:10:50 skrll Exp $ */ /* $OpenBSD: pmap.h,v 1.14 2001/05/09 15:31:24 art Exp $ */ @@ -92,6 +92,7 @@ struct pmap { pa_space_t pmap_space; /* space for this pmap */ u_int pmap_pid; /* protection id for pmap */ struct pmap_statistics pmap_stats; /* statistics */ + struct vmspace *pmap_vmspace; /* last vmspace */ } *pmap_t; extern pmap_t kernel_pmap; /* The kernel's map */