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:
parent
eb46d3c03e
commit
57e61589e7
|
@ -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
|
||||
|
@ -2404,22 +2404,26 @@ pv_syncflags4m(pv0)
|
|||
if (sp->sg_pte == NULL) /* invalid */
|
||||
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)) {
|
||||
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);
|
||||
}
|
||||
tpte = getptesw4m(pm, va);
|
||||
|
||||
if ((tpte & SRMMU_TETYPE) == SRMMU_TEPTE && /* if valid pte */
|
||||
(tpte & (SRMMU_PG_M|SRMMU_PG_R))) { /* and mod/refd */
|
||||
flags |= (tpte >> PG_M_SHIFT4M) &
|
||||
(PV_MOD4M|PV_REF4M|PV_C4M);
|
||||
tpte &= ~(SRMMU_PG_M | SRMMU_PG_R);
|
||||
if (CTX_USABLE(pm,rp))
|
||||
setpte4m(va, tpte); /* flushes cache too */
|
||||
else
|
||||
/* TLB has been invalidated, so just update memory */
|
||||
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;
|
||||
|
@ -4849,6 +4853,8 @@ pmap_page_protect4m(pa, prot)
|
|||
/* if we're done with a region, leave it */
|
||||
|
||||
} else { /* User mode mapping */
|
||||
if (CTX_USABLE(pm,rp))
|
||||
tlb_flush_segment(vr, vs);
|
||||
rp->rg_seg_ptps[vs] = SRMMU_TEINVALID;
|
||||
free(sp->sg_pte, M_VMPMAP);
|
||||
sp->sg_pte = NULL;
|
||||
|
|
Loading…
Reference in New Issue