From page 6-9 of "Alpha AXP Architecture Reference Manual, Second Edition":
An IMB intruction must be executed after software or I/O devices write into the instruction stream or modify the instruction stream virtual address mapping, and before the new value is fetched as an instruction. We were missing calls to IMB after mappings were changed, which caused systems with large I-caches (e.g. my AlphaStation 500) to fail miserably when mapping in new pages of program text, or when context switching (I couldn't even get the shell from init!).
This commit is contained in:
parent
c19335a76d
commit
d1fbc82e28
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: locore.s,v 1.35 1997/09/02 18:53:26 thorpej Exp $ */
|
||||
/* $NetBSD: locore.s,v 1.36 1997/09/16 01:52:00 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
|
||||
@ -29,7 +29,7 @@
|
||||
|
||||
#include <machine/asm.h>
|
||||
|
||||
__KERNEL_RCSID(0, "$NetBSD: locore.s,v 1.35 1997/09/02 18:53:26 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: locore.s,v 1.36 1997/09/16 01:52:00 thorpej Exp $");
|
||||
|
||||
#ifndef EVCNT_COUNTERS
|
||||
#include <machine/intrcnt.h>
|
||||
@ -46,7 +46,8 @@ __KERNEL_RCSID(0, "$NetBSD: locore.s,v 1.35 1997/09/02 18:53:26 thorpej Exp $");
|
||||
\
|
||||
/* Flush out the entire TLB. (XXX only user side?) */ \
|
||||
ldiq a0, -2 ; \
|
||||
call_pal PAL_OSF1_tbi
|
||||
call_pal PAL_OSF1_tbi ; \
|
||||
call_pal PAL_imb
|
||||
|
||||
|
||||
/* don't reorder instructions; paranoia. */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: pmap.old.c,v 1.22 1997/09/03 19:07:32 thorpej Exp $ */
|
||||
/* $NetBSD: pmap.old.c,v 1.23 1997/09/16 01:52:01 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1991, 1993
|
||||
@ -98,7 +98,7 @@
|
||||
|
||||
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
|
||||
|
||||
__KERNEL_RCSID(0, "$NetBSD: pmap.old.c,v 1.22 1997/09/03 19:07:32 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: pmap.old.c,v 1.23 1997/09/16 01:52:01 thorpej Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -300,6 +300,7 @@ _pmap_activate(pmap)
|
||||
|
||||
Lev1map[kvtol1pte(VM_MIN_ADDRESS)] = pmap->pm_stpte;
|
||||
ALPHA_TBIAP();
|
||||
alpha_pal_imb();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -823,13 +824,22 @@ pmap_page_protect(pa, prot)
|
||||
if (!PAGE_IS_MANAGED(pa))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Even though we don't change the mapping of the page,
|
||||
* we still flush the I-cache if VM_PROT_EXECUTE is set
|
||||
* because we might be "adding" execute permissions to
|
||||
* a previously non-execute page.
|
||||
*/
|
||||
|
||||
switch (prot) {
|
||||
case VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE:
|
||||
alpha_pal_imb();
|
||||
case VM_PROT_READ|VM_PROT_WRITE:
|
||||
case VM_PROT_ALL:
|
||||
return;
|
||||
/* copy_on_write */
|
||||
case VM_PROT_READ:
|
||||
case VM_PROT_READ|VM_PROT_EXECUTE:
|
||||
alpha_pal_imb();
|
||||
case VM_PROT_READ:
|
||||
/* XXX */ pmap_changebit(pa, PG_KWE | PG_UWE, FALSE);
|
||||
return;
|
||||
/* remove_all */
|
||||
@ -917,8 +927,11 @@ pmap_protect(pmap, sva, eva, prot)
|
||||
while (sva < nssva) {
|
||||
if (pmap_pte_v(pte) && pmap_pte_prot_chg(pte, bits)) {
|
||||
pmap_pte_set_prot(pte, bits);
|
||||
if (needtflush)
|
||||
if (needtflush) {
|
||||
ALPHA_TBIS(sva);
|
||||
if (prot & VM_PROT_EXECUTE)
|
||||
alpha_pal_imb();
|
||||
}
|
||||
#ifdef PMAPSTATS
|
||||
protect_stats.changed++;
|
||||
#endif
|
||||
@ -1160,8 +1173,11 @@ validate:
|
||||
*/
|
||||
wired = ((*pte ^ npte) == PG_WIRED);
|
||||
*pte = npte;
|
||||
if (!wired && active_pmap(pmap))
|
||||
if (!wired && active_pmap(pmap)) {
|
||||
ALPHA_TBIS(va);
|
||||
if (prot & VM_PROT_EXECUTE)
|
||||
alpha_pal_imb();
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if ((pmapdebug & PDB_WIRING) && pmap != pmap_kernel())
|
||||
pmap_check_wiring("enter", trunc_page(pmap_pte(pmap, va)));
|
||||
@ -1295,6 +1311,7 @@ pmap_update()
|
||||
printf("pmap_update()\n");
|
||||
#endif
|
||||
ALPHA_TBIA();
|
||||
alpha_pal_imb();
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user