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
|
* 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;
|
||||||
|
|
Loading…
Reference in New Issue