pmap_activate shouldn't play with the trap frame - especially not now it's

called by the MI code.

Implement a way of tracking the vmspace allocated to a process and its
LWPs so that if it changes underneath us we can correct the space id in
the trapframe in pmap_activate for now.

An example of when this happens is vfork/exec.

An exec hook is probably the way to go.
This commit is contained in:
skrll 2007-05-18 09:10:50 +00:00
parent fbf7d918bc
commit 843d692d5a
3 changed files with 36 additions and 21 deletions

View File

@ -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 <sys/cdefs.h>
__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 <sys/param.h>
#include <sys/systm.h>
@ -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);
}

View File

@ -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 <sys/cdefs.h>
__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 <sys/param.h>
#include <sys/systm.h>
@ -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,

View File

@ -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 */