Module Name:    src
Committed By:   uebayasi
Date:           Wed Feb 10 13:58:08 UTC 2010

Modified Files:
        src/sys/arch/arm/arm32 [uebayasi-xip]: pmap.c

Log Message:
Convert pmap_enter() and pmap_vac_me_harder().


To generate a diff of this commit:
cvs rdiff -u -r1.211.2.3 -r1.211.2.4 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.211.2.3 src/sys/arch/arm/arm32/pmap.c:1.211.2.4
--- src/sys/arch/arm/arm32/pmap.c:1.211.2.3	Wed Feb 10 13:26:22 2010
+++ src/sys/arch/arm/arm32/pmap.c	Wed Feb 10 13:58:08 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: pmap.c,v 1.211.2.3 2010/02/10 13:26:22 uebayasi Exp $	*/
+/*	$NetBSD: pmap.c,v 1.211.2.4 2010/02/10 13:58:08 uebayasi Exp $	*/
 
 /*
  * Copyright 2003 Wasabi Systems, Inc.
@@ -211,7 +211,7 @@
 #include <machine/param.h>
 #include <arm/arm32/katelib.h>
 
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.211.2.3 2010/02/10 13:26:22 uebayasi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.211.2.4 2010/02/10 13:58:08 uebayasi Exp $");
 
 #ifdef PMAP_DEBUG
 
@@ -656,10 +656,10 @@
 static int		pmap_l2ptp_ctor(void *, void *, int);
 static int		pmap_l2dtable_ctor(void *, void *, int);
 
-static void		pmap_vac_me_harder(struct vm_page *, pmap_t, vaddr_t);
+static void		pmap_vac_me_harder(struct vm_page_md *, paddr_t, pmap_t, vaddr_t);
 #ifdef PMAP_CACHE_VIVT
-static void		pmap_vac_me_kpmap(struct vm_page *, pmap_t, vaddr_t);
-static void		pmap_vac_me_user(struct vm_page *, pmap_t, vaddr_t);
+static void		pmap_vac_me_kpmap(struct vm_page_md *, paddr_t, pmap_t, vaddr_t);
+static void		pmap_vac_me_user(struct vm_page_md *, paddr_t, pmap_t, vaddr_t);
 #endif
 
 static void		pmap_clearbit(struct vm_page *, u_int);
@@ -673,7 +673,7 @@
 	PMAP_FLUSH_SECONDARY,
 	PMAP_CLEAN_PRIMARY
 };
-static void		pmap_flush_page(struct vm_page *, enum pmap_flush_op);
+static void		pmap_flush_page(struct vm_page_md *, paddr_t, enum pmap_flush_op);
 #endif
 static void		pmap_page_remove(struct vm_page *);
 
@@ -1573,50 +1573,50 @@
 };
 
 static inline int
-pmap_get_vac_flags(const struct vm_page *pg)
+pmap_get_vac_flags(const struct vm_page_md *md)
 {
 	int kidx, uidx;
 
 	kidx = 0;
-	if (pg->mdpage.kro_mappings || pg->mdpage.krw_mappings > 1)
+	if (md->kro_mappings || md->krw_mappings > 1)
 		kidx |= 1;
-	if (pg->mdpage.krw_mappings)
+	if (md->krw_mappings)
 		kidx |= 2;
 
 	uidx = 0;
-	if (pg->mdpage.uro_mappings || pg->mdpage.urw_mappings > 1)
+	if (md->uro_mappings || md->urw_mappings > 1)
 		uidx |= 1;
-	if (pg->mdpage.urw_mappings)
+	if (md->urw_mappings)
 		uidx |= 2;
 
 	return (pmap_vac_flags[uidx][kidx]);
 }
 
 static inline void
-pmap_vac_me_harder(struct vm_page *pg, pmap_t pm, vaddr_t va)
+pmap_vac_me_harder(struct vm_page_md *md, paddr_t pa, pmap_t pm, vaddr_t va)
 {
 	int nattr;
 
-	nattr = pmap_get_vac_flags(pg);
+	nattr = pmap_get_vac_flags(md);
 
 	if (nattr < 0) {
-		pg->mdpage.pvh_attrs &= ~PVF_NC;
+		md->pvh_attrs &= ~PVF_NC;
 		return;
 	}
 
-	if (nattr == 0 && (pg->mdpage.pvh_attrs & PVF_NC) == 0)
+	if (nattr == 0 && (md->pvh_attrs & PVF_NC) == 0)
 		return;
 
 	if (pm == pmap_kernel())
-		pmap_vac_me_kpmap(pg, pm, va);
+		pmap_vac_me_kpmap(md, pa, pm, va);
 	else
-		pmap_vac_me_user(pg, pm, va);
+		pmap_vac_me_user(md, pa, pm, va);
 
-	pg->mdpage.pvh_attrs = (pg->mdpage.pvh_attrs & ~PVF_NC) | nattr;
+	md->pvh_attrs = (md->pvh_attrs & ~PVF_NC) | nattr;
 }
 
 static void
-pmap_vac_me_kpmap(struct vm_page *pg, pmap_t pm, vaddr_t va)
+pmap_vac_me_kpmap(struct vm_page_md *md, paddr_t pa, pmap_t pm, vaddr_t va)
 {
 	u_int u_cacheable, u_entries;
 	struct pv_entry *pv;
@@ -1628,19 +1628,19 @@
 	 * kernel-writable pages.
 	 */
 	u_cacheable = 0;
-	SLIST_FOREACH(pv, &pg->mdpage.pvh_list, pv_link) {
+	SLIST_FOREACH(pv, &md->pvh_list, pv_link) {
 		if (pv->pv_pmap != pm && (pv->pv_flags & PVF_NC) == 0)
 			u_cacheable++;
 	}
 
-	u_entries = pg->mdpage.urw_mappings + pg->mdpage.uro_mappings;
+	u_entries = md->urw_mappings + md->uro_mappings;
 
 	/* 
 	 * We know we have just been updating a kernel entry, so if
 	 * all user pages are already cacheable, then there is nothing
 	 * further to do.
 	 */
-	if (pg->mdpage.k_mappings == 0 && u_cacheable == u_entries)
+	if (md->k_mappings == 0 && u_cacheable == u_entries)
 		return;
 
 	if (u_entries) {
@@ -1649,7 +1649,7 @@
 		 * might not be set correctly, call pmap_vac_me_user
 		 * to recalculate the settings.
 		 */
-		SLIST_FOREACH(pv, &pg->mdpage.pvh_list, pv_link) {
+		SLIST_FOREACH(pv, &md->pvh_list, pv_link) {
 			/* 
 			 * We know kernel mappings will get set
 			 * correctly in other calls.  We also know
@@ -1664,7 +1664,7 @@
 			 * is writable but non-cacheable, then we can
 			 * skip this entry also.  
 			 */
-			if (pg->mdpage.k_mappings &&
+			if (md->k_mappings &&
 			    (pv->pv_flags & (PVF_NC | PVF_WRITE)) ==
 			    (PVF_NC | PVF_WRITE))
 				continue;
@@ -1674,7 +1674,7 @@
 			 * entries and the page is already 
 			 * read-only/cacheable.
 			 */
-			if (pg->mdpage.krw_mappings == 0 &&
+			if (md->krw_mappings == 0 &&
 			    (pv->pv_flags & (PVF_NC | PVF_WRITE)) == 0)
 				continue;
 
@@ -1684,18 +1684,18 @@
 			 * can't tell if they are correct or not, so
 			 * we recalculate anyway.
 			 */
-			pmap_vac_me_user(pg, (last_pmap = pv->pv_pmap), 0);
+			pmap_vac_me_user(md, pa, (last_pmap = pv->pv_pmap), 0);
 		}
 
-		if (pg->mdpage.k_mappings == 0)
+		if (md->k_mappings == 0)
 			return;
 	}
 
-	pmap_vac_me_user(pg, pm, va);
+	pmap_vac_me_user(md, pa, pm, va);
 }
 
 static void
-pmap_vac_me_user(struct vm_page *pg, pmap_t pm, vaddr_t va)
+pmap_vac_me_user(struct vm_page_md *md, paddr_t pa, pmap_t pm, vaddr_t va)
 {
 	pmap_t kpmap = pmap_kernel();
 	struct pv_entry *pv, *npv = NULL;
@@ -1713,7 +1713,7 @@
 	 * Keep a pointer to the first one.
 	 */
 	npv = NULL;
-	SLIST_FOREACH(pv, &pg->mdpage.pvh_list, pv_link) {
+	SLIST_FOREACH(pv, &md->pvh_list, pv_link) {
 		/* Count mappings in the same pmap */
 		if (pm == pv->pv_pmap || kpmap == pv->pv_pmap) {
 			if (entries++ == 0)
@@ -1820,7 +1820,7 @@
 
 #ifdef PMAP_CACHE_VIPT
 static void
-pmap_vac_me_harder(struct vm_page *pg, pmap_t pm, vaddr_t va)
+pmap_vac_me_harder(struct vm_page_md *md, paddr_t pa, pmap_t pm, vaddr_t va)
 {
 	struct pv_entry *pv;
 	vaddr_t tst_mask;
@@ -1828,35 +1828,35 @@
 	struct l2_bucket *l2b;
 	pt_entry_t *ptep, pte, opte;
 	const u_int
-	    rw_mappings = pg->mdpage.urw_mappings + pg->mdpage.krw_mappings,
-	    ro_mappings = pg->mdpage.uro_mappings + pg->mdpage.kro_mappings;
+	    rw_mappings = md->urw_mappings + md->krw_mappings,
+	    ro_mappings = md->uro_mappings + md->kro_mappings;
 
 	/* do we need to do anything? */
 	if (arm_cache_prefer_mask == 0)
 		return;
 
-	NPDEBUG(PDB_VAC, printf("pmap_vac_me_harder: pg=%p, pmap=%p va=%08lx\n",
-	    pg, pm, va));
+	NPDEBUG(PDB_VAC, printf("pmap_vac_me_harder: md=%p, pmap=%p va=%08lx\n",
+	    md, pm, va));
 
 	KASSERT(!va || pm);
-	KASSERT((pg->mdpage.pvh_attrs & PVF_DMOD) == 0 || (pg->mdpage.pvh_attrs & (PVF_DIRTY|PVF_NC)));
+	KASSERT((md->pvh_attrs & PVF_DMOD) == 0 || (md->pvh_attrs & (PVF_DIRTY|PVF_NC)));
 
 	/* Already a conflict? */
-	if (__predict_false(pg->mdpage.pvh_attrs & PVF_NC)) {
+	if (__predict_false(md->pvh_attrs & PVF_NC)) {
 		/* just an add, things are already non-cached */
-		KASSERT(!(pg->mdpage.pvh_attrs & PVF_DIRTY));
-		KASSERT(!(pg->mdpage.pvh_attrs & PVF_MULTCLR));
+		KASSERT(!(md->pvh_attrs & PVF_DIRTY));
+		KASSERT(!(md->pvh_attrs & PVF_MULTCLR));
 		bad_alias = false;
 		if (va) {
 			PMAPCOUNT(vac_color_none);
 			bad_alias = true;
-			KASSERT((rw_mappings == 0) == !(pg->mdpage.pvh_attrs & PVF_WRITE));
+			KASSERT((rw_mappings == 0) == !(md->pvh_attrs & PVF_WRITE));
 			goto fixup;
 		}
-		pv = SLIST_FIRST(&pg->mdpage.pvh_list);
+		pv = SLIST_FIRST(&md->pvh_list);
 		/* the list can't be empty because it would be cachable */
-		if (pg->mdpage.pvh_attrs & PVF_KMPAGE) {
-			tst_mask = pg->mdpage.pvh_attrs;
+		if (md->pvh_attrs & PVF_KMPAGE) {
+			tst_mask = md->pvh_attrs;
 		} else {
 			KASSERT(pv);
 			tst_mask = pv->pv_va;
@@ -1872,9 +1872,9 @@
 				if (tst_mask != (pv->pv_va & arm_cache_prefer_mask))
 					bad_alias = true;
 			}
-			pg->mdpage.pvh_attrs |= PVF_WRITE;
+			md->pvh_attrs |= PVF_WRITE;
 			if (!bad_alias)
-				pg->mdpage.pvh_attrs |= PVF_DIRTY;
+				md->pvh_attrs |= PVF_DIRTY;
 		} else {
 			/*
 			 * We have only read-only mappings.  Let's see if there
@@ -1884,82 +1884,82 @@
 			 */
 			for (; pv; pv = SLIST_NEXT(pv, pv_link)) {
 				if (tst_mask != (pv->pv_va & arm_cache_prefer_mask)) {
-					if (pg->mdpage.pvh_attrs & PVF_KMPAGE)
+					if (md->pvh_attrs & PVF_KMPAGE)
 						bad_alias = true;
 					break;
 				}
 			}
-			pg->mdpage.pvh_attrs &= ~PVF_WRITE;
+			md->pvh_attrs &= ~PVF_WRITE;
 			/*
 			 * No KMPAGE and we exited early, so we must have 
 			 * multiple color mappings.
 			 */
 			if (!bad_alias && pv != NULL)
-				pg->mdpage.pvh_attrs |= PVF_MULTCLR;
+				md->pvh_attrs |= PVF_MULTCLR;
 		}
 
 		/* If no conflicting colors, set everything back to cached */
 		if (!bad_alias) {
 #ifdef DEBUG
-			if ((pg->mdpage.pvh_attrs & PVF_WRITE)
+			if ((md->pvh_attrs & PVF_WRITE)
 			    || ro_mappings < 2) {
-				SLIST_FOREACH(pv, &pg->mdpage.pvh_list, pv_link)
+				SLIST_FOREACH(pv, &md->pvh_list, pv_link)
 					KDASSERT(((tst_mask ^ pv->pv_va) & arm_cache_prefer_mask) == 0);
 			}
 #endif
-			pg->mdpage.pvh_attrs &= (PAGE_SIZE - 1) & ~PVF_NC;
-			pg->mdpage.pvh_attrs |= tst_mask | PVF_COLORED;
+			md->pvh_attrs &= (PAGE_SIZE - 1) & ~PVF_NC;
+			md->pvh_attrs |= tst_mask | PVF_COLORED;
 			/*
 			 * Restore DIRTY bit if page is modified
 			 */
-			if (pg->mdpage.pvh_attrs & PVF_DMOD)
-				pg->mdpage.pvh_attrs |= PVF_DIRTY;
+			if (md->pvh_attrs & PVF_DMOD)
+				md->pvh_attrs |= PVF_DIRTY;
 			PMAPCOUNT(vac_color_restore);
 		} else {
-			KASSERT(SLIST_FIRST(&pg->mdpage.pvh_list) != NULL);
-			KASSERT(SLIST_NEXT(SLIST_FIRST(&pg->mdpage.pvh_list), pv_link) != NULL);
+			KASSERT(SLIST_FIRST(&md->pvh_list) != NULL);
+			KASSERT(SLIST_NEXT(SLIST_FIRST(&md->pvh_list), pv_link) != NULL);
 		}
-		KASSERT((pg->mdpage.pvh_attrs & PVF_DMOD) == 0 || (pg->mdpage.pvh_attrs & (PVF_DIRTY|PVF_NC)));
-		KASSERT((rw_mappings == 0) == !(pg->mdpage.pvh_attrs & PVF_WRITE));
+		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(pg));
-		KASSERT(!(pg->mdpage.pvh_attrs & PVF_WRITE)
-		    || (pg->mdpage.pvh_attrs & PVF_DIRTY));
+		KASSERT(arm_cache_prefer_mask == 0 || pmap_is_page_colored_p(md));
+		KASSERT(!(md->pvh_attrs & PVF_WRITE)
+		    || (md->pvh_attrs & PVF_DIRTY));
 		if (rw_mappings == 0) {
-			pg->mdpage.pvh_attrs &= ~PVF_WRITE;
+			md->pvh_attrs &= ~PVF_WRITE;
 			if (ro_mappings == 1
-			    && (pg->mdpage.pvh_attrs & PVF_MULTCLR)) {
+			    && (md->pvh_attrs & PVF_MULTCLR)) {
 				/*
 				 * If this is the last readonly mapping
 				 * but it doesn't match the current color
 				 * for the page, change the current color
 				 * to match this last readonly mapping.
 				 */
-				pv = SLIST_FIRST(&pg->mdpage.pvh_list);
-				tst_mask = (pg->mdpage.pvh_attrs ^ pv->pv_va)
+				pv = SLIST_FIRST(&md->pvh_list);
+				tst_mask = (md->pvh_attrs ^ pv->pv_va)
 				    & arm_cache_prefer_mask;
 				if (tst_mask) {
-					pg->mdpage.pvh_attrs ^= tst_mask;
+					md->pvh_attrs ^= tst_mask;
 					PMAPCOUNT(vac_color_change);
 				}
 			}
 		}
-		KASSERT((pg->mdpage.pvh_attrs & PVF_DMOD) == 0 || (pg->mdpage.pvh_attrs & (PVF_DIRTY|PVF_NC)));
-		KASSERT((rw_mappings == 0) == !(pg->mdpage.pvh_attrs & PVF_WRITE));
+		KASSERT((md->pvh_attrs & PVF_DMOD) == 0 || (md->pvh_attrs & (PVF_DIRTY|PVF_NC)));
+		KASSERT((rw_mappings == 0) == !(md->pvh_attrs & PVF_WRITE));
 		return;
-	} else if (!pmap_is_page_colored_p(pg)) {
+	} else if (!pmap_is_page_colored_p(md)) {
 		/* not colored so we just use its color */
-		KASSERT(pg->mdpage.pvh_attrs & (PVF_WRITE|PVF_DIRTY));
-		KASSERT(!(pg->mdpage.pvh_attrs & PVF_MULTCLR));
+		KASSERT(md->pvh_attrs & (PVF_WRITE|PVF_DIRTY));
+		KASSERT(!(md->pvh_attrs & PVF_MULTCLR));
 		PMAPCOUNT(vac_color_new);
-		pg->mdpage.pvh_attrs &= PAGE_SIZE - 1;
-		pg->mdpage.pvh_attrs |= PVF_COLORED
+		md->pvh_attrs &= PAGE_SIZE - 1;
+		md->pvh_attrs |= PVF_COLORED
 		    | (va & arm_cache_prefer_mask)
 		    | (rw_mappings > 0 ? PVF_WRITE : 0);
-		KASSERT((pg->mdpage.pvh_attrs & PVF_DMOD) == 0 || (pg->mdpage.pvh_attrs & (PVF_DIRTY|PVF_NC)));
-		KASSERT((rw_mappings == 0) == !(pg->mdpage.pvh_attrs & PVF_WRITE));
+		KASSERT((md->pvh_attrs & PVF_DMOD) == 0 || (md->pvh_attrs & (PVF_DIRTY|PVF_NC)));
+		KASSERT((rw_mappings == 0) == !(md->pvh_attrs & PVF_WRITE));
 		return;
-	} else if (((pg->mdpage.pvh_attrs ^ va) & arm_cache_prefer_mask) == 0) {
+	} else if (((md->pvh_attrs ^ va) & arm_cache_prefer_mask) == 0) {
 		bad_alias = false;
 		if (rw_mappings > 0) {
 			/*
@@ -1968,61 +1968,61 @@
 			 * an aliasing problem.  Regardless mark the page as
 			 * writeable.
 			 */
-			if (pg->mdpage.pvh_attrs & PVF_MULTCLR) {
+			if (md->pvh_attrs & PVF_MULTCLR) {
 				if (ro_mappings < 2) {
 					/*
 					 * If we only have less than two
 					 * read-only mappings, just flush the
 					 * non-primary colors from the cache.
 					 */
-					pmap_flush_page(pg,
+					pmap_flush_page(md, pa,
 					    PMAP_FLUSH_SECONDARY);
 				} else {
 					bad_alias = true;
 				}
 			}
-			pg->mdpage.pvh_attrs |= PVF_WRITE;
+			md->pvh_attrs |= PVF_WRITE;
 		}
 		/* If no conflicting colors, set everything back to cached */
 		if (!bad_alias) {
 #ifdef DEBUG
 			if (rw_mappings > 0
-			    || (pg->mdpage.pvh_attrs & PMAP_KMPAGE)) {
-				tst_mask = pg->mdpage.pvh_attrs & arm_cache_prefer_mask;
-				SLIST_FOREACH(pv, &pg->mdpage.pvh_list, pv_link)
+			    || (md->pvh_attrs & PMAP_KMPAGE)) {
+				tst_mask = md->pvh_attrs & arm_cache_prefer_mask;
+				SLIST_FOREACH(pv, &md->pvh_list, pv_link)
 					KDASSERT(((tst_mask ^ pv->pv_va) & arm_cache_prefer_mask) == 0);
 			}
 #endif
-			if (SLIST_EMPTY(&pg->mdpage.pvh_list))
+			if (SLIST_EMPTY(&md->pvh_list))
 				PMAPCOUNT(vac_color_reuse);
 			else
 				PMAPCOUNT(vac_color_ok);
 
 			/* matching color, just return */
-			KASSERT((pg->mdpage.pvh_attrs & PVF_DMOD) == 0 || (pg->mdpage.pvh_attrs & (PVF_DIRTY|PVF_NC)));
-			KASSERT((rw_mappings == 0) == !(pg->mdpage.pvh_attrs & PVF_WRITE));
+			KASSERT((md->pvh_attrs & PVF_DMOD) == 0 || (md->pvh_attrs & (PVF_DIRTY|PVF_NC)));
+			KASSERT((rw_mappings == 0) == !(md->pvh_attrs & PVF_WRITE));
 			return;
 		}
-		KASSERT(SLIST_FIRST(&pg->mdpage.pvh_list) != NULL);
-		KASSERT(SLIST_NEXT(SLIST_FIRST(&pg->mdpage.pvh_list), pv_link) != NULL);
+		KASSERT(SLIST_FIRST(&md->pvh_list) != NULL);
+		KASSERT(SLIST_NEXT(SLIST_FIRST(&md->pvh_list), pv_link) != NULL);
 
 		/* color conflict.  evict from cache. */
 
-		pmap_flush_page(pg, PMAP_FLUSH_PRIMARY);
-		pg->mdpage.pvh_attrs &= ~PVF_COLORED;
-		pg->mdpage.pvh_attrs |= PVF_NC;
-		KASSERT((pg->mdpage.pvh_attrs & PVF_DMOD) == 0 || (pg->mdpage.pvh_attrs & (PVF_DIRTY|PVF_NC)));
-		KASSERT(!(pg->mdpage.pvh_attrs & PVF_MULTCLR));
+		pmap_flush_page(md, pa, PMAP_FLUSH_PRIMARY);
+		md->pvh_attrs &= ~PVF_COLORED;
+		md->pvh_attrs |= PVF_NC;
+		KASSERT((md->pvh_attrs & PVF_DMOD) == 0 || (md->pvh_attrs & (PVF_DIRTY|PVF_NC)));
+		KASSERT(!(md->pvh_attrs & PVF_MULTCLR));
 		PMAPCOUNT(vac_color_erase);
 	} else if (rw_mappings == 0
-		   && (pg->mdpage.pvh_attrs & PVF_KMPAGE) == 0) {
-		KASSERT((pg->mdpage.pvh_attrs & PVF_WRITE) == 0);
+		   && (md->pvh_attrs & PVF_KMPAGE) == 0) {
+		KASSERT((md->pvh_attrs & PVF_WRITE) == 0);
 
 		/*
 		 * If the page has dirty cache lines, clean it.
 		 */
-		if (pg->mdpage.pvh_attrs & PVF_DIRTY)
-			pmap_flush_page(pg, PMAP_CLEAN_PRIMARY);
+		if (md->pvh_attrs & PVF_DIRTY)
+			pmap_flush_page(md, pa, PMAP_CLEAN_PRIMARY);
 
 		/*
 		 * If this is the first remapping (we know that there are no
@@ -2031,27 +2031,27 @@
 		 * we don't have to do anything.
 		 */
 		if (ro_mappings == 1) {
-			KASSERT(((pg->mdpage.pvh_attrs ^ va) & arm_cache_prefer_mask) != 0);
-			pg->mdpage.pvh_attrs &= PAGE_SIZE - 1;
-			pg->mdpage.pvh_attrs |= (va & arm_cache_prefer_mask);
+			KASSERT(((md->pvh_attrs ^ va) & arm_cache_prefer_mask) != 0);
+			md->pvh_attrs &= PAGE_SIZE - 1;
+			md->pvh_attrs |= (va & arm_cache_prefer_mask);
 			PMAPCOUNT(vac_color_change);
 		} else {
 			PMAPCOUNT(vac_color_blind);
 		}
-		pg->mdpage.pvh_attrs |= PVF_MULTCLR;
-		KASSERT((pg->mdpage.pvh_attrs & PVF_DMOD) == 0 || (pg->mdpage.pvh_attrs & (PVF_DIRTY|PVF_NC)));
-		KASSERT((rw_mappings == 0) == !(pg->mdpage.pvh_attrs & PVF_WRITE));
+		md->pvh_attrs |= PVF_MULTCLR;
+		KASSERT((md->pvh_attrs & PVF_DMOD) == 0 || (md->pvh_attrs & (PVF_DIRTY|PVF_NC)));
+		KASSERT((rw_mappings == 0) == !(md->pvh_attrs & PVF_WRITE));
 		return;
 	} else {
 		if (rw_mappings > 0)
-			pg->mdpage.pvh_attrs |= PVF_WRITE;
+			md->pvh_attrs |= PVF_WRITE;
 
 		/* color conflict.  evict from cache. */
-		pmap_flush_page(pg, PMAP_FLUSH_PRIMARY);
+		pmap_flush_page(md, pa, PMAP_FLUSH_PRIMARY);
 
 		/* the list can't be empty because this was a enter/modify */
-		pv = SLIST_FIRST(&pg->mdpage.pvh_list);
-		if ((pg->mdpage.pvh_attrs & PVF_KMPAGE) == 0) {
+		pv = SLIST_FIRST(&md->pvh_list);
+		if ((md->pvh_attrs & PVF_KMPAGE) == 0) {
 			KASSERT(pv);
 			/*
 			 * If there's only one mapped page, change color to the
@@ -2059,31 +2059,31 @@
 			 * that was erased by pmap_flush_page.
 			 */
 			if (SLIST_NEXT(pv, pv_link) == NULL) {
-				pg->mdpage.pvh_attrs &= PAGE_SIZE - 1;
-				pg->mdpage.pvh_attrs |= (va & arm_cache_prefer_mask);
-				if (pg->mdpage.pvh_attrs & PVF_DMOD)
-					pg->mdpage.pvh_attrs |= PVF_DIRTY;
+				md->pvh_attrs &= PAGE_SIZE - 1;
+				md->pvh_attrs |= (va & arm_cache_prefer_mask);
+				if (md->pvh_attrs & PVF_DMOD)
+					md->pvh_attrs |= PVF_DIRTY;
 				PMAPCOUNT(vac_color_change);
-				KASSERT((pg->mdpage.pvh_attrs & PVF_DMOD) == 0 || (pg->mdpage.pvh_attrs & (PVF_DIRTY|PVF_NC)));
-				KASSERT((rw_mappings == 0) == !(pg->mdpage.pvh_attrs & PVF_WRITE));
-				KASSERT(!(pg->mdpage.pvh_attrs & PVF_MULTCLR));
+				KASSERT((md->pvh_attrs & PVF_DMOD) == 0 || (md->pvh_attrs & (PVF_DIRTY|PVF_NC)));
+				KASSERT((rw_mappings == 0) == !(md->pvh_attrs & PVF_WRITE));
+				KASSERT(!(md->pvh_attrs & PVF_MULTCLR));
 				return;
 			}
 		}
 		bad_alias = true;
-		pg->mdpage.pvh_attrs &= ~PVF_COLORED;
-		pg->mdpage.pvh_attrs |= PVF_NC;
+		md->pvh_attrs &= ~PVF_COLORED;
+		md->pvh_attrs |= PVF_NC;
 		PMAPCOUNT(vac_color_erase);
-		KASSERT((pg->mdpage.pvh_attrs & PVF_DMOD) == 0 || (pg->mdpage.pvh_attrs & (PVF_DIRTY|PVF_NC)));
+		KASSERT((md->pvh_attrs & PVF_DMOD) == 0 || (md->pvh_attrs & (PVF_DIRTY|PVF_NC)));
 	}
 
   fixup:
-	KASSERT((rw_mappings == 0) == !(pg->mdpage.pvh_attrs & PVF_WRITE));
+	KASSERT((rw_mappings == 0) == !(md->pvh_attrs & PVF_WRITE));
 
 	/*
 	 * Turn cacheing on/off for all pages.
 	 */
-	SLIST_FOREACH(pv, &pg->mdpage.pvh_list, pv_link) {
+	SLIST_FOREACH(pv, &md->pvh_list, pv_link) {
 		l2b = pmap_get_l2_bucket(pv->pv_pmap, pv->pv_va);
 		KDASSERT(l2b != NULL);
 		ptep = &l2b->l2b_kva[l2pte_index(pv->pv_va)];
@@ -2325,7 +2325,7 @@
 	 */
 	if (need_vac_me_harder) {
 		if (pg->mdpage.pvh_attrs & PVF_NC)
-			pmap_vac_me_harder(pg, NULL, 0);
+			pmap_vac_me_harder(&pg->mdpage, VM_PAGE_TO_PHYS(pg), NULL, 0);
 	}
 #endif
 
@@ -2467,7 +2467,7 @@
 }
 
 void
-pmap_flush_page(struct vm_page *pg, enum pmap_flush_op flush)
+pmap_flush_page(struct vm_page_md *md, paddr_t pa, enum pmap_flush_op flush)
 {
 	vsize_t va_offset, end_va;
 	void (*cf)(vaddr_t, vsize_t);
@@ -2477,48 +2477,48 @@
 
 	switch (flush) {
 	case PMAP_FLUSH_PRIMARY:
-		if (pg->mdpage.pvh_attrs & PVF_MULTCLR) {
+		if (md->pvh_attrs & PVF_MULTCLR) {
 			va_offset = 0;
 			end_va = arm_cache_prefer_mask;
-			pg->mdpage.pvh_attrs &= ~PVF_MULTCLR;
+			md->pvh_attrs &= ~PVF_MULTCLR;
 			PMAPCOUNT(vac_flush_lots);
 		} else {
-			va_offset = pg->mdpage.pvh_attrs & arm_cache_prefer_mask;
+			va_offset = md->pvh_attrs & arm_cache_prefer_mask;
 			end_va = va_offset;
 			PMAPCOUNT(vac_flush_one);
 		}
 		/*
 		 * Mark that the page is no longer dirty.
 		 */
-		pg->mdpage.pvh_attrs &= ~PVF_DIRTY;
+		md->pvh_attrs &= ~PVF_DIRTY;
 		cf = cpufuncs.cf_idcache_wbinv_range;
 		break;
 	case PMAP_FLUSH_SECONDARY:
 		va_offset = 0;
 		end_va = arm_cache_prefer_mask;
 		cf = cpufuncs.cf_idcache_wbinv_range;
-		pg->mdpage.pvh_attrs &= ~PVF_MULTCLR;
+		md->pvh_attrs &= ~PVF_MULTCLR;
 		PMAPCOUNT(vac_flush_lots);
 		break;
 	case PMAP_CLEAN_PRIMARY:
-		va_offset = pg->mdpage.pvh_attrs & arm_cache_prefer_mask;
+		va_offset = md->pvh_attrs & arm_cache_prefer_mask;
 		end_va = va_offset;
 		cf = cpufuncs.cf_dcache_wb_range;
 		/*
 		 * Mark that the page is no longer dirty.
 		 */
-		if ((pg->mdpage.pvh_attrs & PVF_DMOD) == 0)
-			pg->mdpage.pvh_attrs &= ~PVF_DIRTY;
+		if ((md->pvh_attrs & PVF_DMOD) == 0)
+			md->pvh_attrs &= ~PVF_DIRTY;
 		PMAPCOUNT(vac_clean_one);
 		break;
 	default:
 		return;
 	}
 
-	KASSERT(!(pg->mdpage.pvh_attrs & PVF_NC));
+	KASSERT(!(md->pvh_attrs & PVF_NC));
 
-	NPDEBUG(PDB_VAC, printf("pmap_flush_page: pg=%p (attrs=%#x)\n",
-	    pg, pg->mdpage.pvh_attrs));
+	NPDEBUG(PDB_VAC, printf("pmap_flush_page: md=%p (attrs=%#x)\n",
+	    md, md->pvh_attrs));
 
 	for (; va_offset <= end_va; va_offset += PAGE_SIZE) {
 		const size_t pte_offset = va_offset >> PGSHIFT;
@@ -2526,7 +2526,7 @@
 		const pt_entry_t oldpte = *ptep;
 
 		if (flush == PMAP_FLUSH_SECONDARY
-		    && va_offset == (pg->mdpage.pvh_attrs & arm_cache_prefer_mask))
+		    && va_offset == (md->pvh_attrs & arm_cache_prefer_mask))
 			continue;
 
 		pmap_tlb_flushID_SE(pmap_kernel(), cdstp + va_offset);
@@ -2535,7 +2535,7 @@
 		 * existing cache entries.
 		 */
 		*ptep = L2_S_PROTO
-		    | VM_PAGE_TO_PHYS(pg)
+		    | pa
 		    | L2_S_PROT(PTE_KERNEL, VM_PROT_READ|VM_PROT_WRITE)
 		    | pte_l2_s_cache_mode;
 		PTE_SYNC(ptep);
@@ -2598,7 +2598,7 @@
 		return;
 	}
 #ifdef PMAP_CACHE_VIPT
-	KASSERT(arm_cache_prefer_mask == 0 || pmap_is_page_colored_p(pg));
+	KASSERT(arm_cache_prefer_mask == 0 || pmap_is_page_colored_p(&pg->mdpage));
 #endif
 
 	/*
@@ -2679,7 +2679,7 @@
 		if (pv == NULL) {
 			*pvp = NULL;
 			if (!SLIST_EMPTY(&pg->mdpage.pvh_list))
-				pmap_vac_me_harder(pg, pm, 0);
+				pmap_vac_me_harder(&pg->mdpage, VM_PAGE_TO_PHYS(pg), pm, 0);
 		}
 		pmap_release_pmap_lock(pm);
 	}
@@ -2824,11 +2824,20 @@
 		opg = NULL;
 
 	if (pg) {
+		struct vm_page_md *md;
+
+#ifdef DEVICE_PAGE
+		if (uvm_pageisdevice_p(pg))
+			md = vm_page_device_mdpage_lookup(pg);
+		else
+#endif
+		md = &pg->mdpage;
+
 		/*
 		 * This is to be a managed mapping.
 		 */
 		if ((flags & VM_PROT_ALL) ||
-		    (pg->mdpage.pvh_attrs & PVF_REF)) {
+		    (md->pvh_attrs & PVF_REF)) {
 			/*
 			 * - The access type indicates that we don't need
 			 *   to do referenced emulation.
@@ -2842,7 +2851,7 @@
 
 			if ((prot & VM_PROT_WRITE) != 0 &&
 			    ((flags & VM_PROT_WRITE) != 0 ||
-			     (pg->mdpage.pvh_attrs & PVF_MOD) != 0)) {
+			     (md->pvh_attrs & PVF_MOD) != 0)) {
 				/*
 				 * This is a writable mapping, and the
 				 * page's mod state indicates it has
@@ -2865,11 +2874,11 @@
 			/*
 			 * We're changing the attrs of an existing mapping.
 			 */
-			simple_lock(&pg->mdpage.pvh_slock);
-			oflags = pmap_modify_pv(&pg->mdpage, VM_PAGE_TO_PHYS(pg), pm, va,
+			simple_lock(&md->pvh_slock);
+			oflags = pmap_modify_pv(md, pa, pm, va,
 			    PVF_WRITE | PVF_EXEC | PVF_WIRED |
 			    PVF_MOD | PVF_REF, nflags);
-			simple_unlock(&pg->mdpage.pvh_slock);
+			simple_unlock(&md->pvh_slock);
 
 #ifdef PMAP_CACHE_VIVT
 			/*
@@ -2888,15 +2897,26 @@
 			 * of an existing mapping.
 			 */
 			if (opg) {
+				struct vm_page_md *omd;
+				paddr_t opa;
+
+#ifdef DEVICE_PAGE
+				if (uvm_pageisdevice_p(opg))
+					omd = vm_page_device_mdpage_lookup(opg);
+				else
+#endif
+				omd = &opg->mdpage;
+				opa = VM_PAGE_TO_PHYS(opg);
+
 				/*
 				 * Replacing an existing mapping with a new one.
 				 * It is part of our managed memory so we
 				 * must remove it from the PV list
 				 */
-				simple_lock(&opg->mdpage.pvh_slock);
-				pv = pmap_remove_pv(&opg->mdpage, VM_PAGE_TO_PHYS(opg), pm, va);
-				pmap_vac_me_harder(opg, pm, 0);
-				simple_unlock(&opg->mdpage.pvh_slock);
+				simple_lock(&omd->pvh_slock);
+				pv = pmap_remove_pv(omd, opa, pm, va);
+				pmap_vac_me_harder(omd, opa, pm, 0);
+				simple_unlock(&omd->pvh_slock);
 				oflags = pv->pv_flags;
 
 #ifdef PMAP_CACHE_VIVT
@@ -2958,7 +2978,7 @@
 			 */
 			simple_lock(&opg->mdpage.pvh_slock);
 			pv = pmap_remove_pv(&opg->mdpage, VM_PAGE_TO_PHYS(opg), pm, va);
-			pmap_vac_me_harder(opg, pm, 0);
+			pmap_vac_me_harder(&opg->mdpage, VM_PAGE_TO_PHYS(opg), pm, 0);
 			simple_unlock(&opg->mdpage.pvh_slock);
 			oflags = pv->pv_flags;
 
@@ -3039,7 +3059,7 @@
 
 		if (pg != NULL) {
 			simple_lock(&pg->mdpage.pvh_slock);
-			pmap_vac_me_harder(pg, pm, va);
+			pmap_vac_me_harder(&pg->mdpage, VM_PAGE_TO_PHYS(pg), pm, va);
 			simple_unlock(&pg->mdpage.pvh_slock);
 		}
 	}
@@ -3152,7 +3172,7 @@
 				struct pv_entry *pv;
 				simple_lock(&pg->mdpage.pvh_slock);
 				pv = pmap_remove_pv(&pg->mdpage, VM_PAGE_TO_PHYS(pg), pm, sva);
-				pmap_vac_me_harder(pg, pm, 0);
+				pmap_vac_me_harder(&pg->mdpage, VM_PAGE_TO_PHYS(pg), pm, 0);
 				simple_unlock(&pg->mdpage.pvh_slock);
 				if (pv != NULL) {
 					if (pm->pm_remove_all == false) {
@@ -3298,7 +3318,7 @@
 			PMAPCOUNT(exec_synced_kremove);
 		}
 	}
-	pmap_vac_me_harder(pg, pmap_kernel(), 0);
+	pmap_vac_me_harder(&pg->mdpage, VM_PAGE_TO_PHYS(pg), pmap_kernel(), 0);
 	simple_unlock(&pg->mdpage.pvh_slock);
 
 	return pv;
@@ -3377,17 +3397,17 @@
 			KASSERT(arm_cache_prefer_mask == 0 || (va & PVF_COLORED) == 0);
 			KASSERT((pg->mdpage.pvh_attrs & PVF_NC) == 0);
 			/* if there is a color conflict, evict from cache. */
-			if (pmap_is_page_colored_p(pg)
+			if (pmap_is_page_colored_p(&pg->mdpage)
 			    && ((va ^ pg->mdpage.pvh_attrs) & arm_cache_prefer_mask)) {
 				PMAPCOUNT(vac_color_change);
-				pmap_flush_page(pg, PMAP_FLUSH_PRIMARY);
+				pmap_flush_page(&pg->mdpage, VM_PAGE_TO_PHYS(pg), PMAP_FLUSH_PRIMARY);
 			} else if (pg->mdpage.pvh_attrs & PVF_MULTCLR) {
 				/*
 				 * If this page has multiple colors, expunge
 				 * them.
 				 */
 				PMAPCOUNT(vac_flush_lots2);
-				pmap_flush_page(pg, PMAP_FLUSH_SECONDARY);
+				pmap_flush_page(&pg->mdpage, VM_PAGE_TO_PHYS(pg), PMAP_FLUSH_SECONDARY);
 			}
 			pg->mdpage.pvh_attrs &= PAGE_SIZE - 1;
 			pg->mdpage.pvh_attrs |= PVF_KMPAGE
@@ -3413,7 +3433,7 @@
 				pg->mdpage.pvh_attrs |= PVF_DIRTY;
 			KASSERT((prot & VM_PROT_WRITE) == 0 || (pg->mdpage.pvh_attrs & (PVF_DIRTY|PVF_NC)));
 			simple_lock(&pg->mdpage.pvh_slock);
-			pmap_vac_me_harder(pg, pmap_kernel(), va);
+			pmap_vac_me_harder(&pg->mdpage, VM_PAGE_TO_PHYS(pg), pmap_kernel(), va);
 			simple_unlock(&pg->mdpage.pvh_slock);
 #endif
 		}
@@ -3627,7 +3647,7 @@
 					simple_lock(&pg->mdpage.pvh_slock);
 					f = pmap_modify_pv(&pg->mdpage, VM_PAGE_TO_PHYS(pg), pm, sva,
 					    clr_mask, 0);
-					pmap_vac_me_harder(pg, pm, sva);
+					pmap_vac_me_harder(&pg->mdpage, VM_PAGE_TO_PHYS(pg), pm, sva);
 					simple_unlock(&pg->mdpage.pvh_slock);
 				} else
 					f = PVF_REF | PVF_EXEC;
@@ -3751,7 +3771,7 @@
 		 * mark it clean.
 		 */
 		if ((pg->mdpage.pvh_attrs & (PVF_DMOD|PVF_NC)) == PVF_MOD)
-			pmap_flush_page(pg, PMAP_CLEAN_PRIMARY);
+			pmap_flush_page(&pg->mdpage, VM_PAGE_TO_PHYS(pg), PMAP_CLEAN_PRIMARY);
 #endif
 		pmap_clearbit(pg, PVF_MOD);
 	} else
@@ -4439,7 +4459,7 @@
 	 * This page is now cache resident so it now has a page color.
 	 * Any contents have been obliterated so clear the EXEC flag.
 	 */
-	if (!pmap_is_page_colored_p(pg)) {
+	if (!pmap_is_page_colored_p(&pg->mdpage)) {
 		PMAPCOUNT(vac_color_new);
 		pg->mdpage.pvh_attrs |= PVF_COLORED;
 	}
@@ -4548,7 +4568,7 @@
 	 * This page is now cache resident so it now has a page color.
 	 * Any contents have been obliterated so clear the EXEC flag.
 	 */
-	if (!pmap_is_page_colored_p(pg)) {
+	if (!pmap_is_page_colored_p(&pg->mdpage)) {
 		PMAPCOUNT(vac_color_new);
 		pg->mdpage.pvh_attrs |= PVF_COLORED;
 	}
@@ -4656,7 +4676,7 @@
 	 * Now that the destination page is in the cache, mark it as colored.
 	 * If this was an exec page, discard it.
 	 */
-	if (!pmap_is_page_colored_p(dst_pg)) {
+	if (!pmap_is_page_colored_p(&dst_pg->mdpage)) {
 		PMAPCOUNT(vac_color_new);
 		dst_pg->mdpage.pvh_attrs |= PVF_COLORED;
 	}

Reply via email to