Hi,
#define PV_BEEN_EXECD(f) (((f) & (PVF_REF | PVF_EXEC)) == (PVF_REF | PVF_EXEC))
#define PV_BEEN_REFD(f) (((f) & PVF_REF) != 0)
and from pmap.h:
* The PVF_MOD and PVF_REF flags are stored in the mdpage for each
* page. PVF_WIRED, PVF_WRITE, and PVF_NC are kept in individual
* pv_entry's for each page. They live in the same "namespace" so
* that we can clear multiple attributes at a time.
well, this isn't stricly about clearing, but using PVF_REF in those macros
does mean you are likely to want | attrs too.
-Artturi
diff --git a/sys/arch/arm/arm/pmap7.c b/sys/arch/arm/arm/pmap7.c
index 0d32bf9..64c1227 100644
--- a/sys/arch/arm/arm/pmap7.c
+++ b/sys/arch/arm/arm/pmap7.c
@@ -1247,8 +1247,7 @@ pmap_enter(pmap_t pm, vaddr_t va, paddr_t pa, vm_prot_t
prot, int flags)
struct vm_page *pg, *opg;
struct pv_entry *pve;
pt_entry_t *ptep, npte, opte;
- u_int nflags;
- u_int oflags;
+ u_int nflags, oflags, oattrs;
int mapped = 1;
NPDEBUG(PDB_ENTER, printf("pmap_enter: pm %p va 0x%lx pa 0x%lx prot %x
flag %x\n", pm, va, pa, prot, flags));
@@ -1287,7 +1286,7 @@ pmap_enter(pmap_t pm, vaddr_t va, paddr_t pa, vm_prot_t
prot, int flags)
ptep = &l2b->l2b_kva[l2pte_index(va)];
opte = *ptep;
npte = pa;
- oflags = 0;
+ oflags = oattrs = 0;
if (opte != 0) { /* not l2pte_valid!!! MIOD */
/*
@@ -1346,6 +1345,7 @@ pmap_enter(pmap_t pm, vaddr_t va, paddr_t pa, vm_prot_t
prot, int flags)
/*
* We're changing the attrs of an existing mapping.
*/
+ oattrs = opg->mdpage.pvh_attrs;
oflags = pmap_modify_pv(pg, pm, va,
PVF_WRITE | PVF_EXEC | PVF_WIRED |
PVF_MOD | PVF_REF, nflags);
@@ -1372,6 +1372,7 @@ pmap_enter(pmap_t pm, vaddr_t va, paddr_t pa, vm_prot_t
prot, int flags)
* It is part of our managed memory so we
* must remove it from the PV list
*/
+ oattrs = opg->mdpage.pvh_attrs;
pve = pmap_remove_pv(opg, pm, va);
oflags = pve->pv_flags;
} else
@@ -1402,6 +1403,7 @@ pmap_enter(pmap_t pm, vaddr_t va, paddr_t pa, vm_prot_t
prot, int flags)
* Looks like there's an existing 'managed' mapping
* at this address.
*/
+ oattrs = opg->mdpage.pvh_attrs;
pve = pmap_remove_pv(opg, pm, va);
oflags = pve->pv_flags;
@@ -1455,10 +1457,10 @@ pmap_enter(pmap_t pm, vaddr_t va, paddr_t pa, vm_prot_t
prot, int flags)
}
}
- if (PV_BEEN_EXECD(oflags))
+ if (PV_BEEN_EXECD(oflags | oattrs))
pmap_tlb_flushID_SE(pm, va);
else
- if (PV_BEEN_REFD(oflags))
+ if (PV_BEEN_REFD(oflags | oattrs))
pmap_tlb_flushD_SE(pm, va);
}