Module Name: src
Committed By: matt
Date: Fri Feb 1 15:02:32 UTC 2013
Modified Files:
src/sys/arch/arm/arm32: pmap.c
Log Message:
cleanup PVF_WRITE & pvh_attrs interaction.
To generate a diff of this commit:
cvs rdiff -u -r1.250 -r1.251 src/sys/arch/arm/arm32/pmap.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/arm/arm32/pmap.c
diff -u src/sys/arch/arm/arm32/pmap.c:1.250 src/sys/arch/arm/arm32/pmap.c:1.251
--- src/sys/arch/arm/arm32/pmap.c:1.250 Thu Jan 31 22:01:49 2013
+++ src/sys/arch/arm/arm32/pmap.c Fri Feb 1 15:02:31 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.c,v 1.250 2013/01/31 22:01:49 skrll Exp $ */
+/* $NetBSD: pmap.c,v 1.251 2013/02/01 15:02:31 matt Exp $ */
/*
* Copyright 2003 Wasabi Systems, Inc.
@@ -212,7 +212,7 @@
#include <arm/cpuconf.h>
#include <arm/arm32/katelib.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.250 2013/01/31 22:01:49 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.251 2013/02/01 15:02:31 matt Exp $");
#ifdef PMAP_DEBUG
@@ -693,6 +693,12 @@ pmap_debug(int level)
}
#endif /* PMAP_DEBUG */
+#ifdef PMAP_CACHE_VIPT
+#define PMAP_VALIDATE_MD_PAGE(md) \
+ KASSERTMSG(arm_cache_prefer_mask == 0 || (((md)->pvh_attrs & PVF_WRITE) == 0) == ((md)->urw_mappings + (md)->krw_mappings == 0), \
+ "(md) %p: attrs=%#x urw=%u krw=%u", (md), \
+ (md)->pvh_attrs, (md)->urw_mappings, (md)->krw_mappings);
+#endif /* PMAP_CACHE_VIPT */
/*
* A bunch of routines to conditionally flush the caches/TLB depending
* on whether the specified pmap actually needs to be flushed at any
@@ -890,6 +896,13 @@ pmap_enter_pv(struct vm_page_md *md, pad
#ifdef PMAP_CACHE_VIPT
/*
+ * Even though pmap_vac_me_harder will set PVF_WRITE for us,
+ * do it here as well to keep the mappings & KVF_WRITE consistent.
+ */
+ if (arm_cache_prefer_mask != 0 && (flags & PVF_WRITE) != 0) {
+ md->pvh_attrs |= PVF_WRITE;
+ }
+ /*
* If this is an exec mapping and its the first exec mapping
* for this page, make sure to sync the I-cache.
*/
@@ -1008,8 +1021,11 @@ pmap_remove_pv(struct vm_page_md *md, pa
* mappings (ignoring KMPAGE), clear the WRITE flag and writeback
* the contents to memory.
*/
- if (md->krw_mappings + md->urw_mappings == 0)
- md->pvh_attrs &= ~PVF_WRITE;
+ if (arm_cache_prefer_mask != 0) {
+ if (md->krw_mappings + md->urw_mappings == 0)
+ md->pvh_attrs &= ~PVF_WRITE;
+ PMAP_VALIDATE_MD_PAGE(md);
+ }
KASSERT((md->pvh_attrs & PVF_DMOD) == 0 || (md->pvh_attrs & (PVF_DIRTY|PVF_NC)));
#endif /* PMAP_CACHE_VIPT */
@@ -1087,10 +1103,12 @@ pmap_modify_pv(struct vm_page_md *md, pa
}
}
#ifdef PMAP_CACHE_VIPT
- if (md->urw_mappings + md->krw_mappings == 0) {
- md->pvh_attrs &= ~PVF_WRITE;
- } else {
- md->pvh_attrs |= PVF_WRITE;
+ if (arm_cache_prefer_mask != 0) {
+ if (md->urw_mappings + md->krw_mappings == 0) {
+ md->pvh_attrs &= ~PVF_WRITE;
+ } else {
+ md->pvh_attrs |= PVF_WRITE;
+ }
}
/*
* We have two cases here: the first is from enter_pv (new exec
@@ -1847,7 +1865,7 @@ pmap_vac_me_harder(struct vm_page_md *md
* Only check for a bad alias if we have writable mappings.
*/
tst_mask &= arm_cache_prefer_mask;
- if (rw_mappings > 0 && arm_cache_prefer_mask) {
+ if (rw_mappings > 0) {
for (; pv && !bad_alias; pv = SLIST_NEXT(pv, pv_link)) {
/* if there's a bad alias, stop checking. */
if (tst_mask != (pv->pv_va & arm_cache_prefer_mask))
@@ -1903,7 +1921,7 @@ pmap_vac_me_harder(struct vm_page_md *md
KASSERT((md->pvh_attrs & PVF_DMOD) == 0 || (md->pvh_attrs & (PVF_DIRTY|PVF_NC)));
KASSERT((rw_mappings == 0) == !(md->pvh_attrs & PVF_WRITE));
} else if (!va) {
- KASSERT(arm_cache_prefer_mask == 0 || pmap_is_page_colored_p(md));
+ KASSERT(pmap_is_page_colored_p(md));
KASSERT(!(md->pvh_attrs & PVF_WRITE)
|| (md->pvh_attrs & PVF_DIRTY));
if (rw_mappings == 0) {
@@ -2227,10 +2245,12 @@ pmap_clearbit(struct vm_page_md *md, pad
md->uro_mappings++;
}
#ifdef PMAP_CACHE_VIPT
- if (md->urw_mappings + md->krw_mappings == 0) {
- md->pvh_attrs &= ~PVF_WRITE;
- } else {
- KASSERT(md->pvh_attrs & PVF_WRITE);
+ if (arm_cache_prefer_mask != 0) {
+ if (md->urw_mappings + md->krw_mappings == 0) {
+ md->pvh_attrs &= ~PVF_WRITE;
+ } else {
+ PMAP_VALIDATE_MD_PAGE(md);
+ }
}
if (want_syncicache)
need_syncicache = true;
@@ -2564,7 +2584,7 @@ pmap_page_remove(struct vm_page_md *md,
if (PV_IS_EXEC_P(md->pvh_attrs))
PMAPCOUNT(exec_discarded_page_protect);
md->pvh_attrs &= ~PVF_EXEC;
- KASSERT((md->urw_mappings + md->krw_mappings == 0) == !(md->pvh_attrs & PVF_WRITE));
+ PMAP_VALIDATE_MD_PAGE(md);
#endif
return;
}
@@ -2663,9 +2683,11 @@ pmap_page_remove(struct vm_page_md *md,
md->pvh_attrs &= ~PVF_EXEC;
KASSERT(md->urw_mappings == 0);
KASSERT(md->uro_mappings == 0);
- if (md->krw_mappings == 0)
- md->pvh_attrs &= ~PVF_WRITE;
- KASSERT((md->urw_mappings + md->krw_mappings == 0) == !(md->pvh_attrs & PVF_WRITE));
+ if (arm_cache_prefer_mask != 0) {
+ if (md->krw_mappings == 0)
+ md->pvh_attrs &= ~PVF_WRITE;
+ PMAP_VALIDATE_MD_PAGE(md);
+ }
#endif
if (flush) {
@@ -2809,8 +2831,7 @@ pmap_enter(pmap_t pm, vaddr_t va, paddr_
/*
* This is to be a managed mapping.
*/
- if ((flags & VM_PROT_ALL) ||
- (md->pvh_attrs & PVF_REF)) {
+ if ((flags & VM_PROT_ALL) || (md->pvh_attrs & PVF_REF)) {
/*
* - The access type indicates that we don't need
* to do referenced emulation.
@@ -3050,9 +3071,7 @@ pmap_enter(pmap_t pm, vaddr_t va, paddr_
KASSERT(uvm_page_locked_p(pg));
#endif
KASSERT((md->pvh_attrs & PVF_DMOD) == 0 || (md->pvh_attrs & (PVF_DIRTY|PVF_NC)));
- KASSERTMSG(arm_cache_prefer_mask == 0 || ((md->pvh_attrs & PVF_WRITE) == 0) == (md->urw_mappings + md->krw_mappings == 0),
- "pg %p: attrs=%#x urw=%u krw=%u", pg,
- md->pvh_attrs, md->urw_mappings, md->krw_mappings);
+ PMAP_VALIDATE_MD_PAGE(md);
}
#endif
@@ -3470,7 +3489,9 @@ pmap_kremove(vaddr_t va, vsize_t len)
KASSERT(omd->kro_mappings == 0);
omd->pvh_attrs &= ~PVF_KMPAGE;
#ifdef PMAP_CACHE_VIPT
- omd->pvh_attrs &= ~PVF_WRITE;
+ if (arm_cache_prefer_mask != 0) {
+ omd->pvh_attrs &= ~PVF_WRITE;
+ }
#endif
pmap_kmpages--;
#ifdef PMAP_CACHE_VIPT