Fix a bogosity apparently inherited from when the Utah 4.3BSD code base

was converted to use Mach VM for Net2/4.4BSD.  The user segment table
pointer was originally stored in the PCB.  When Mach VM came along,
however, it was also stored in the pmap, and loaded into the PCB in
pmap_activate().  pmap_activate() would then note that the PCB's USTP
was now in sync with the pmap's USTP, and the low-level context switch
code would use the value from the PCB.

However, pmap_activate() would also load the hardware MMU context if
the pmap was the current pmap (or, in the case where pmaps can be shared,
such as in NetBSD, if the proc was the current proc).  The low-level
context switch code would then reload the hardware _again_ using the
USTP from the PCB.

However, the optimization of not calling pmap_activate() if "stchanged"
was false ended up causing some processes to use stale USTP values from
the PCB when the low-level context switch code reloaded the hardware!
This was noticed by using a real vfork(2) (which worked for some time
before failing, surprisingly!)

Since I'm hard pressed to find any real optimization here (since the
hardware was always reloaded once, sometimes twice!), the code now always
calls pmap_activate(), which uses the correct USTP value (the one in the
pmap).  The PCB's USTP is now ignored, and should eventually be g/c'd.

Another optimization can actually be performed, and I have added a comment
describing what it is, but have not yet implemented it.

Also note that most of the loadustp() functions where actually incomplete.
This has been corrected.  These functions should probably be split up into
MMU-specific operations, and called indirectly, rather than doing constant
run-time decision making based on values that will never change during the
course of a boot's lifetime.
This commit is contained in:
thorpej 1998-01-05 23:16:21 +00:00
parent 10cc9f3b70
commit a8f80ad4fd
6 changed files with 90 additions and 264 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: locore.s,v 1.93 1998/01/01 19:52:50 thorpej Exp $ */
/* $NetBSD: locore.s,v 1.94 1998/01/05 23:16:21 thorpej Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@ -1280,51 +1280,18 @@ Lswnofpsave:
movl a1,_curpcb
movb a1@(PCB_FLAGS+1),pcbflag | copy of pcb_flags low byte
/* see if pmap_activate needs to be called; should remove this */
movl a0@(P_VMSPACE),a2 | vmspace = p->p_vmspace
#ifdef DIAGNOSTIC
tstl a2 | map == VM_MAP_NULL?
jeq Lbadsw | panic
#endif
movl a2@(VM_PMAP),a2 | pmap = vmspace->vm_map.pmap
tstl a2@(PM_STCHG) | pmap->st_changed?
jeq Lswnochg | no, skip
/*
* Activate process's address space.
* XXX Should remember the last USTP value loaded, and call this
* XXX only if it has changed.
*/
pea a0@ | push proc
jbsr _pmap_activate | pmap_activate(p)
addql #4,sp
movl _curpcb,a1 | restore p_addr
Lswnochg:
lea tmpstk,sp | now goto a tmp stack for NMI
cmpl #MMU_68040,_mmutype
jeq Lres2
movl #CACHE_CLR,d0
movc d0,cacr | invalidate cache(s)
pflusha | flush entire TLB
jra Lres3
Lres2:
.word 0xf518 | pflusha (68040)
| movl #CACHE40_ON,d0
| movc d0,cacr | invalidate cache(s)
#ifdef M68060
cmpl #CPU_68060,_cputype
jne Lres3
movc cacr,d2
orl #IC60_CUBC,d2 | clear user btc
movc d2,cacr
#endif
Lres3:
movl a1@(PCB_USTP),d0 | get USTP
moveq #PGSHIFT,d1
lsll d1,d0 | convert to addr
cmpl #MMU_68040,_mmutype
jeq Lres4
lea _protorp,a0 | CRP prototype
movl d0,a0@(4) | stash USTP
pmove a0@,crp | load new user root pointer
jra Lres5
Lres4:
.word 0x4e7b,0x0806 | movc d0,URP
Lres5:
movl a1@(PCB_CMAP2),_CMAP2 | reload tmp map
moveml a1@(PCB_REGS),d2-d7/a2-a7 | and registers
movl a1@(PCB_USP),a0
@ -1785,17 +1752,18 @@ ENTRY(loadustp)
moveq #PGSHIFT,d1
lsll d1,d0 | convert to addr
#ifdef M68060
cmpl #CPU_68060,_cputype
jeq Lldustp060
cmpl #CPU_68060,_cputype | 68060?
jeq Lldustp060 | yes, skip
#endif
cmpl #MMU_68040,_mmutype
jeq Lldustp040
cmpl #MMU_68040,_mmutype | 68040?
jeq Lldustp040 | yes, skip
pflusha | flush entire TLB
lea _protorp,a0 | CRP prototype
movl d0,a0@(4) | stash USTP
pmove a0@,crp | load root pointer
movl #DC_CLEAR,d0
movc d0,cacr | invalidate on-chip d-cache
rts | since pmove flushes TLB
movl #CACHE_CLR,d0
movc d0,cacr | invalidate cache(s)
rts
#ifdef M68060
Lldustp060:
movc cacr,d1
@ -1803,6 +1771,7 @@ Lldustp060:
movc d1,cacr
#endif
Lldustp040:
.word 0xf518 | pflusha
.word 0x4e7b,0x0806 | movec d0,URP
rts

View File

@ -1,4 +1,4 @@
/* $NetBSD: locore.s,v 1.47 1998/01/01 19:52:56 thorpej Exp $ */
/* $NetBSD: locore.s,v 1.48 1998/01/05 23:16:25 thorpej Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@ -1217,51 +1217,18 @@ Lswnofpsave:
movl a1,_curpcb
movb a1@(PCB_FLAGS+1),pcbflag | copy of pcb_flags low byte
/* see if pmap_activate needs to be called; should remove this */
movl a0@(P_VMSPACE),a2 | vmspace = p->p_vmspace
#ifdef DIAGNOSTIC
tstl a2 | map == VM_MAP_NULL?
jeq Lbadsw | panic
#endif
movl a2@(VM_PMAP),a2 | pmap = vmspace->vm_map.pmap
tstl a2@(PM_STCHG) | pmap->st_changed?
jeq Lswnochg | no, skip
/*
* Activate process's address space.
* XXX Should remember the last USTP value loaded, and call this
* XXX only if it has changed.
*/
pea a0@ | push proc
jbsr _pmap_activate | pmap_activate(p)
addql #4,sp
movl _curpcb,a1 | restore p_addr
Lswnochg:
lea tmpstk,sp | now goto a tmp stack for NMI
cmpl #MMU_68040,_mmutype
jeq Lres2
movl #CACHE_CLR,d0
movc d0,cacr | invalidate cache(s)
pflusha | flush entire TLB
jra Lres3
Lres2:
.word 0xf518 | pflusha (68040)
movl #CACHE40_ON,d0
movc d0,cacr | invalidate cache(s)
#ifdef M68060
cmpl #CPU_68060,_cputype | a 060?
jne Lres3 | no
movc cacr,d2
orl #IC60_CUBC,d2 | clear user branch cache entries
movc d2,cacr
#endif
Lres3:
movl a1@(PCB_USTP),d0 | get USTP
moveq #PGSHIFT,d1
lsll d1,d0 | convert to addr
cmpl #MMU_68040,_mmutype
jeq Lres4
lea _protorp,a0 | CRP prototype
movl d0,a0@(4) | stash USTP
pmove a0@,crp | load new user root pointer
jra Lres5
Lres4:
.word 0x4e7b,0x0806 | movc d0,URP
Lres5:
movl a1@(PCB_CMAP2),_CMAP2 | reload tmp map
moveml a1@(PCB_REGS),#0xFCFC | and registers
movl a1@(PCB_USP),a0
@ -1564,17 +1531,18 @@ ENTRY(loadustp)
moveq #PGSHIFT,d1
lsll d1,d0 | convert to addr
#if defined(M68060)
cmpl #CPU_68060,_cputype | a 060?
jeq Lldustp060
cmpl #CPU_68060,_cputype | 68060?
jeq Lldustp060 | yes, skip
#endif
cmpl #MMU_68040,_mmutype
jeq Lldustp040
cmpl #MMU_68040,_mmutype | 68040?
jeq Lldustp040 | yes, skip
pflusha | flush entire TLB
lea _protorp,a0 | CRP prototype
movl d0,a0@(4) | stash USTP
pmove a0@,crp | load root pointer
movl #DC_CLEAR,d0
movl #CACHE_CLR,d0
movc d0,cacr | invalidate on-chip d-cache
rts | since pmove flushes TLB
rts
#if defined(M68060)
Lldustp060:
movc cacr,d1
@ -1582,7 +1550,8 @@ Lldustp060:
movc d1,cacr
#endif
Lldustp040:
.word 0x4e7b,0x0806 | movec d0,URP
.word 0xf518 | pflusha
.word 0x4e7b,0x0806 | movec d0,URP
rts
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: locore.s,v 1.81 1997/12/31 10:12:55 thorpej Exp $ */
/* $NetBSD: locore.s,v 1.82 1998/01/05 23:16:27 thorpej Exp $ */
/*
* Copyright (c) 1994, 1995 Gordon W. Ross
@ -1293,63 +1293,18 @@ Lswnofpsave:
movl a0@(P_ADDR),a1 | get p_addr
movl a1,_C_LABEL(curpcb)
/* see if pmap_activate needs to be called; should remove this */
movl a0@(P_VMSPACE),a2 | vmspace = p->p_vmspace
#ifdef DIAGNOSTIC
tstl a2 | map == VM_MAP_NULL?
jeq Lbadsw | panic
#endif
movl a2@(VM_PMAP),a2 | pmap = vmspace->vm_map.pmap
tstl a2@(PM_STCHG) | pmap->st_changed?
jeq Lswnochg | no, skip
/*
* Activate process's address space.
* XXX Should remember the last USTP value loaded, and call this
* XXX only if it has changed.
*/
pea a0@ | push proc
jbsr _C_LABEL(pmap_activate) | pmap_activate(p)
addql #4,sp
movl _C_LABEL(curpcb),a1 | restore p_addr
Lswnochg:
lea _ASM_LABEL(tmpstk),sp | now goto a tmp stack for NMI
#if defined(M68040)
#if defined(M68020) || defined(M68030)
cmpl #MMU_68040,_C_LABEL(mmutype) | 68040?
jne Lres1a | no, skip
#endif
.word 0xf518 | yes, pflusha
movl a1@(PCB_USTP),d0 | get USTP
moveq #PGSHIFT,d1
lsll d1,d0 | convert to addr
.long 0x4e7b0806 | movc d0,urp
jra Lcxswdone
Lres1a:
#endif
movl #CACHE_CLR,d0
movc d0,cacr | invalidate cache(s)
#if defined(M68K_MMU_MOTOROLA)
#if defined(M68K_MMU_HP)
tstl _C_LABEL(mmutype) | HP MMU?
jeq Lhpmmu4 | yes, skip
#endif
pflusha | flush entire TLB
movl a1@(PCB_USTP),d0 | get USTP
moveq #PGSHIFT,d1
lsll d1,d0 | convert to addr
lea _C_LABEL(protorp),a0 | CRP prototype
movl d0,a0@(4) | stash USTP
pmove a0@,crp | load new user root pointer
jra Lcxswdone | thats it
Lhpmmu4:
#endif
#if defined(M68K_MMU_HP)
MMUADDR(a0)
movl a0@(MMUTBINVAL),d1 | invalidate TLB
tstl _C_LABEL(ectype) | got external VAC?
jle Lnocache1 | no, skip
andl #~MMU_CEN,a0@(MMUCMD) | toggle cache enable
orl #MMU_CEN,a0@(MMUCMD) | to clear data cache
Lnocache1:
movl a1@(PCB_USTP),a0@(MMUUSTP) | context switch
#endif
Lcxswdone:
moveml a1@(PCB_REGS),#0xFCFC | and registers
movl a1@(PCB_USP),a0
movl a0,usp | and USP
@ -1763,20 +1718,30 @@ ENTRY(loadustp)
#if defined(M68040)
cmpl #MMU_68040,_C_LABEL(mmutype) | 68040?
jne LmotommuC | no, skip
.word 0xf518 | yes, pflusha
.long 0x4e7b0806 | movc d0,urp
rts
LmotommuC:
#endif
pflusha | flush entire TLB
lea _C_LABEL(protorp),a0 | CRP prototype
movl d0,a0@(4) | stash USTP
pmove a0@,crp | load root pointer
movl #DC_CLEAR,d0
movc d0,cacr | invalidate on-chip d-cache
rts | since pmove flushes TLB
movl #CACHE_CLR,d0
movc d0,cacr | invalidate cache(s)
rts
Lhpmmu9:
#endif
#if defined(M68K_MMU_HP)
movl #CACHE_CLR,d0
movc d0,cacr | invalidate cache(s)
MMUADDR(a0)
movl a0@(MMUTBINVAL),d1 | invalidate TLB
tstl _C_LABEL(ectype) | have external VAC?
jle 1f | no, skip
andl #~MMU_CEN,a0@(MMUCMD) | toggle cache enable
orl #MMU_CEN,a0@(MMUCMD) | to clear data cache
1:
movl sp@(4),a0@(MMUUSTP) | load a new USTP
#endif
rts

View File

@ -1,4 +1,4 @@
/* $NetBSD: locore.s,v 1.92 1998/01/01 19:53:03 thorpej Exp $ */
/* $NetBSD: locore.s,v 1.93 1998/01/05 23:16:30 thorpej Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@ -1110,43 +1110,18 @@ Lswnofpsave:
movl a0@(P_ADDR),a1 | get p_addr
movl a1,_C_LABEL(curpcb)
/* see if pmap_activate needs to be called; should remove this */
movl a0@(P_VMSPACE),a2 | vmspace = p->p_vmspace
#ifdef DIAGNOSTIC
tstl a2 | map == VM_MAP_NULL?
jeq Lbadsw | panic
#endif
movl a2@(VM_PMAP),a2 | pmap = vmspace->vm_map.pmap
tstl a2@(PM_STCHG) | pmap->st_changed?
jeq Lswnochg | no, skip
/*
* Activate the process's address space.
* XXX Should remember the last USTP value loaded, and call this
* XXX only if it has changed.
*/
pea a0@ | push proc
jbsr _C_LABEL(pmap_activate) | pmap_activate(p)
addql #4,sp
movl _C_LABEL(curpcb),a1 | restore p_addr
Lswnochg:
lea _ASM_LABEL(tmpstk),sp | now goto a tmp stack for NMI
#if defined(M68040)
cmpl #MMU_68040,_C_LABEL(mmutype) | 68040?
jne Lres1a | no, skip
.word 0xf518 | yes, pflusha
movl a1@(PCB_USTP),d0 | get USTP
moveq #PGSHIFT,d1
lsll d1,d0 | convert to addr
.long 0x4e7b0806 | movc d0,urp
jra Lcxswdone
Lres1a:
#endif
movl #CACHE_CLR,d0
movc d0,cacr | invalidate cache(s)
pflusha | flush entire TLB
movl a1@(PCB_USTP),d0 | get USTP
moveq #PGSHIFT,d1
lsll d1,d0 | convert to addr
lea _C_LABEL(protorp),a0 | CRP prototype
movl d0,a0@(4) | stash USTP
pmove a0@,crp | load new user root pointer
Lcxswdone:
moveml a1@(PCB_REGS),#0xFCFC | and registers
movl a1@(PCB_USP),a0
movl a0,usp | and USP
@ -1454,16 +1429,18 @@ ENTRY(loadustp)
#if defined(M68040)
cmpl #MMU_68040,_C_LABEL(mmutype) | 68040?
jne LmotommuC | no, skip
.word 0xf518 | pflusha
.long 0x4e7b0806 | movec d0, URP
rts
LmotommuC:
#endif
pflusha | flush entire TLB
lea _C_LABEL(protorp),a0 | CRP prototype
movl d0,a0@(4) | stash USTP
pmove a0@,crp | load root pointer
movl #DC_CLEAR,d0
movc d0,cacr | invalidate on-chip d-cache
rts | since pmove flushes TLB
movl #CACHE_CLR,d0
movc d0,cacr | invalidate cache(s)
rts
/*
* Set processor priority level calls. Most are implemented with

View File

@ -1,4 +1,4 @@
/* $NetBSD: locore.s,v 1.31 1998/01/01 19:53:08 thorpej Exp $ */
/* $NetBSD: locore.s,v 1.32 1998/01/05 23:16:32 thorpej Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@ -1135,43 +1135,18 @@ Lswnofpsave:
movl a0@(P_ADDR),a1 | get p_addr
movl a1,_curpcb
/* see if pmap_activate needs to be called; should remove this */
movl a0@(P_VMSPACE),a2 | vmspace = p->p_vmspace
#ifdef DIAGNOSTIC
tstl a2 | map == VM_MAP_NULL?
jeq Lbadsw | panic
#endif
movl a2@(VM_PMAP),a2 | pmap = vmspace->vm_map.pmap
tstl a2@(PM_STCHG) | pmap->st_changed?
jeq Lswnochg | no, skip
/*
* Activate process's address space.
* XXX Should remember the last USTP value loaded, and call this
* XXX only of it has changed.
*/
pea a0@ | push proc
jbsr _pmap_activate | pmap_activate(p)
addql #4,sp
movl _curpcb,a1 | restore p_addr
Lswnochg:
lea tmpstk,sp | now goto a tmp stack for NMI
#if defined(M68040)
cmpl #MMU_68040,_mmutype | 68040?
jne Lres1a | no, skip
.word 0xf518 | yes, pflusha
movl a1@(PCB_USTP),d0 | get USTP
moveq #PGSHIFT,d1
lsll d1,d0 | convert to addr
.long 0x4e7b0806 | movc d0,urp
jra Lcxswdone
Lres1a:
#endif
movl #CACHE_CLR,d0
movc d0,cacr | invalidate cache(s)
pflusha | flush entire TLB
movl a1@(PCB_USTP),d0 | get USTP
moveq #PGSHIFT,d1
lsll d1,d0 | convert to addr
lea _protorp,a0 | CRP prototype
movl d0,a0@(4) | stash USTP
pmove a0@,crp | load new user root pointer
Lcxswdone:
moveml a1@(PCB_REGS),#0xFCFC | and registers
movl a1@(PCB_USP),a0
movl a0,usp | and USP
@ -1512,16 +1487,18 @@ ENTRY(loadustp)
#if defined(M68040)
cmpl #MMU_68040,_mmutype | 68040?
jne LmotommuC | no, skip
.word 0xf518 | pflusha
.long 0x4e7b0806 | movc d0,urp
rts
LmotommuC:
#endif
pflusha | flush entire TLB
lea _protorp,a0 | CRP prototype
movl d0,a0@(4) | stash USTP
pmove a0@,crp | load root pointer
movl #DC_CLEAR,d0
movc d0,cacr | invalidate on-chip d-cache
rts | since pmove flushes TLB
movl #CACHE_CLR,d0
movc d0,cacr | invalidate cache(s)
rts
ENTRY(ploadw)
movl sp@(4),a0 | address to load

View File

@ -1,4 +1,4 @@
/* $NetBSD: locore.s,v 1.25 1998/01/01 19:53:12 thorpej Exp $ */
/* $NetBSD: locore.s,v 1.26 1998/01/05 23:16:34 thorpej Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@ -1304,51 +1304,18 @@ Lswnofpsave:
movl a0@(P_ADDR),a1 | get p_addr
movl a1,_curpcb
/* see if pmap_activate needs to be called; should remove this */
movl a0@(P_VMSPACE),a2 | vmspace = p->p_vmspace
#ifdef DIAGNOSTIC
tstl a2 | map == VM_MAP_NULL?
jeq Lbadsw | panic
#endif
movl a2@(VM_PMAP),a2 | pmap = vmspace->vm_map.pmap
tstl a2@(PM_STCHG) | pmap->st_changed?
jeq Lswnochg | no, skip
/*
* Activate the process's address space.
* XXX Should remember the last USTP value loaded, and call this
* XXX only if it has changed.
*/
pea a0@ | push proc
jbsr _pmap_activate | pmap_activate(p)
addql #4,sp
movl _curpcb,a1 | restore p_addr
Lswnochg:
lea tmpstk,sp | now goto a tmp stack for NMI
#if defined(M68040) || defined(M68060)
cmpl #MMU_68040,_mmutype | 68040?
jne Lres1a | no, skip
.word 0xf518 | yes, pflusha
#ifdef M68060
cmpl #CPU_68060,_cputype
jne Lres3
movc cacr,d0
orl #IC60_CUBC,d0 | clear user branch cache entries
movc d0,cacr
Lres3:
#endif
movl a1@(PCB_USTP),d0 | get USTP
moveq #PGSHIFT,d1
lsll d1,d0 | convert to addr
.long 0x4e7b0806 | movc d0,urp
jra Lcxswdone
Lres1a:
#endif
movl #CACHE_CLR,d0
movc d0,cacr | invalidate cache(s)
pflusha | flush entire TLB
movl a1@(PCB_USTP),d0 | get USTP
moveq #PGSHIFT,d1
lsll d1,d0 | convert to addr
lea _protorp,a0 | CRP prototype
movl d0,a0@(4) | stash USTP
pmove a0@,crp | load new user root pointer
Lcxswdone:
moveml a1@(PCB_REGS),#0xFCFC | and registers
movl a1@(PCB_USP),a0
movl a0,usp | and USP
@ -1718,6 +1685,7 @@ ENTRY(loadustp)
#if defined(M68040) || defined(M68060)
cmpl #MMU_68040,_mmutype | 68040?
jne LmotommuC | no, skip
.word 0xf518 | pflusha
.long 0x4e7b0806 | movc d0,urp
#ifdef M68060
cmpl #CPU_68060,_cputype
@ -1730,12 +1698,13 @@ Lldno60:
rts
LmotommuC:
#endif
pflusha | flush entire TLB
lea _protorp,a0 | CRP prototype
movl d0,a0@(4) | stash USTP
pmove a0@,crp | load root pointer
movl #DC_CLEAR,d0
movc d0,cacr | invalidate on-chip d-cache
rts | since pmove flushes TLB
movl #CACHE_CLR,d0
movc d0,cacr | invalidate cache(s)
rts
ENTRY(ploadw)
#if defined(M68030)