Fix two cases of handling stale page table information:

1. when reading the referenced/modified bits the TLB entry must be flushed
   before reading the in-core version.
2. when wrapping up an entire segment in pmap_page_protect(), flush the PTPs
   from the TLB to prevent a table-walking operation to pick up stale - or
   possibly bogus - PTEs.

(hopefully I'll get a few of my hairs back now..)
This commit is contained in:
pk 1996-05-29 20:58:38 +00:00
parent eb46d3c03e
commit 57e61589e7
1 changed files with 30 additions and 24 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: pmap.c,v 1.61 1996/05/27 01:12:34 pk Exp $ */ /* $NetBSD: pmap.c,v 1.62 1996/05/29 20:58:38 pk Exp $ */
/* /*
* Copyright (c) 1996 * Copyright (c) 1996
@ -2404,22 +2404,26 @@ pv_syncflags4m(pv0)
if (sp->sg_pte == NULL) /* invalid */ if (sp->sg_pte == NULL) /* invalid */
continue; continue;
tpte = getptesw4m(pm, va); /*
* We need the PTE from memory as the TLB version will
* always have the SRMMU_PG_R bit on.
*/
if (CTX_USABLE(pm,rp)) { if (CTX_USABLE(pm,rp)) {
setcontext(pm->pm_ctxnum); setcontext(pm->pm_ctxnum);
if (vactype != VAC_NONE && (tpte & SRMMU_PG_M))
cache_flush_page(va); /* XXX: do we need this?*/
tlb_flush_page(va); tlb_flush_page(va);
} }
tpte = getptesw4m(pm, va);
if ((tpte & SRMMU_TETYPE) == SRMMU_TEPTE && /* if valid pte */ if ((tpte & SRMMU_TETYPE) == SRMMU_TEPTE && /* if valid pte */
(tpte & (SRMMU_PG_M|SRMMU_PG_R))) { /* and mod/refd */ (tpte & (SRMMU_PG_M|SRMMU_PG_R))) { /* and mod/refd */
flags |= (tpte >> PG_M_SHIFT4M) & flags |= (tpte >> PG_M_SHIFT4M) &
(PV_MOD4M|PV_REF4M|PV_C4M); (PV_MOD4M|PV_REF4M|PV_C4M);
tpte &= ~(SRMMU_PG_M | SRMMU_PG_R); tpte &= ~(SRMMU_PG_M | SRMMU_PG_R);
if (CTX_USABLE(pm,rp)) /* TLB has been invalidated, so just update memory */
setpte4m(va, tpte); /* flushes cache too */
else
setptesw4m(pm, va, tpte); setptesw4m(pm, va, tpte);
if (vactype != VAC_NONE &&
CTX_USABLE(pm,rp) && (tpte & SRMMU_PG_M))
cache_flush_page(va); /* XXX: do we need this?*/
} }
} }
pv0->pv_flags = flags; pv0->pv_flags = flags;
@ -4849,6 +4853,8 @@ pmap_page_protect4m(pa, prot)
/* if we're done with a region, leave it */ /* if we're done with a region, leave it */
} else { /* User mode mapping */ } else { /* User mode mapping */
if (CTX_USABLE(pm,rp))
tlb_flush_segment(vr, vs);
rp->rg_seg_ptps[vs] = SRMMU_TEINVALID; rp->rg_seg_ptps[vs] = SRMMU_TEINVALID;
free(sp->sg_pte, M_VMPMAP); free(sp->sg_pte, M_VMPMAP);
sp->sg_pte = NULL; sp->sg_pte = NULL;