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:
thorpej 1997-09-16 01:52:00 +00:00
parent c19335a76d
commit d1fbc82e28
2 changed files with 27 additions and 9 deletions

View File

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

View File

@ -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();
}
/*