Module Name:    src
Committed By:   skrll
Date:           Fri Apr  3 14:07:26 UTC 2009

Modified Files:
        src/sys/arch/hppa/hppa [nick-hppapmap]: pmap.c

Log Message:
Track referrenced and modified attributes of pages correct, i.e. as
described in pmap(9).

Inherit uncacheable attribute if the page already has non-equiv aliases.

Tidy-up a comment while I'm here.


To generate a diff of this commit:
cvs rdiff -u -r1.43.8.43 -r1.43.8.44 src/sys/arch/hppa/hppa/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/hppa/hppa/pmap.c
diff -u src/sys/arch/hppa/hppa/pmap.c:1.43.8.43 src/sys/arch/hppa/hppa/pmap.c:1.43.8.44
--- src/sys/arch/hppa/hppa/pmap.c:1.43.8.43	Sat Mar 28 11:00:47 2009
+++ src/sys/arch/hppa/hppa/pmap.c	Fri Apr  3 14:07:26 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: pmap.c,v 1.43.8.43 2009/03/28 11:00:47 skrll Exp $	*/
+/*	$NetBSD: pmap.c,v 1.43.8.44 2009/04/03 14:07:26 skrll Exp $	*/
 
 /*-
  * Copyright (c) 2001, 2002 The NetBSD Foundation, Inc.
@@ -64,7 +64,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.43.8.43 2009/03/28 11:00:47 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.43.8.44 2009/04/03 14:07:26 skrll Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -511,6 +511,7 @@
 {
 	bool nonequiv = false;
 	struct pv_entry *tpve;
+	u_int attrs;
 
 	/* we should only be looking if we're not PVF_NC */
 	KASSERT((pg->mdpage.pvh_attrs & PVF_NC) == 0);
@@ -521,15 +522,13 @@
 	    ptep));
 
 	if (ptep) {
-		/* Reset page flags with flags for new mapping */
-		pg->mdpage.pvh_attrs = pmap_pvh_attrs(*ptep);
+		attrs = pmap_pvh_attrs(*ptep);
 
 		DPRINTF(PDB_FOLLOW|PDB_ALIAS,
 		    ("%s: va 0x%08x attrs 0x%08x (new)\n", __func__, (int)va,
-		    pmap_pvh_attrs(*ptep)));
+		    attrs));
 	} else {
-		/* Reset page flags. */
-		pg->mdpage.pvh_attrs = 0;
+		attrs = 0;
 
 		DPRINTF(PDB_FOLLOW|PDB_ALIAS,
 		    ("%s: va 0x%08x (removed)\n", __func__, (int)va));
@@ -544,7 +543,7 @@
 
 		/* XXX LOCK */
 		pte = pmap_vp_find(tpve->pv_pmap, tpve->pv_va);
-		pg->mdpage.pvh_attrs |= pmap_pvh_attrs(pte);
+		attrs |= pmap_pvh_attrs(pte);
 
 		if (((va ^ tpve->pv_va) & HPPA_PGAOFF) != 0)
 			nonequiv = true;
@@ -555,21 +554,29 @@
 		    pmap_pvh_attrs(pte), nonequiv ? "alias" : ""));
 	}
 
-	/* No more to be done. */
-	if (!nonequiv)
+	if (!nonequiv) {
+		/*
+		 * Inherit uncacheable attribute if set as it means we already
+		 * have non-equiv aliases
+		 */
+		if (ptep && (attrs & PVF_UNCACHEABLE) != 0)
+			*ptep |= PTE_PROT(TLB_UNCACHEABLE);
+
+		/* No more to be done. */
 		return;
+	}
 
 	if (ptep) {
-		if ((pg->mdpage.pvh_attrs & (PVF_WRITE|PVF_MOD)) != 0) {
+		if ((attrs & (PVF_WRITE|PVF_MOD)) != 0) {
 			/*
-			 * We have non-equiv aliases and the new (some)
-			 * mapping(s are) is writable (or modified). We must
-			 * mark the all mappings as uncacheable
-			 * (if they're not already marked as such).
+			 * We have non-equiv aliases and the new/some 
+			 * mapping(s) is/are is writable (or modified). We must
+			 * mark the all mappings as uncacheable (if they're not
+			 * already marked as such).
 			 */
 			pg->mdpage.pvh_aliases++;
 
-			if ((pg->mdpage.pvh_attrs & PVF_UNCACHEABLE) == 0)
+			if ((attrs & PVF_UNCACHEABLE) == 0)
 				__changebit(pg, PVF_UNCACHEABLE, 0);
 
 			*ptep |= PTE_PROT(TLB_UNCACHEABLE);
@@ -578,7 +585,7 @@
 			    ("%s: page marked uncacheable\n", __func__));
 		}
 	} else {
-		if ((pg->mdpage.pvh_attrs & PVF_UNCACHEABLE) != 0) {
+		if ((attrs & PVF_UNCACHEABLE) != 0) {
 			/*
 			 * We've removed a non-equiv aliases. We can check
 			 * marked uncacheable. We can now mark it cacheable.
@@ -1385,7 +1392,10 @@
 				pmap_check_alias(pg, pg->mdpage.pvh_list,
 				    sva, NULL);
 
+				pg->mdpage.pvh_attrs |= pmap_pvh_attrs(pte);
+
 				mutex_exit(&pg->mdpage.pvh_lock);
+
 				if (pve != NULL)
 					pmap_pv_free(pve);
 			}
@@ -1549,8 +1559,13 @@
 	int res;
 
 	KASSERT(mutex_owned(&pg->mdpage.pvh_lock));
+	KASSERT(((set | clear) &
+	    ~(PVF_MOD|PVF_REF|PVF_UNCACHEABLE|PVF_WRITE)) == 0);
+
+	/* preserve other bits */
+	res = pg->mdpage.pvh_attrs & (set | clear);
+	pg->mdpage.pvh_attrs ^= res;
 
-	res = pg->mdpage.pvh_attrs = 0;
 	for (pve = pg->mdpage.pvh_list; pve; pve = pve->pv_next) {
 		pmap_t pmap = pve->pv_pmap;
 		vaddr_t va = pve->pv_va;
@@ -1845,13 +1860,15 @@
 		if (pmap_initialized && (pg = PHYS_TO_VM_PAGE(PTE_PAGE(pte)))) {
 
 			mutex_enter(&pg->mdpage.pvh_lock);
-			pg->mdpage.pvh_attrs &= ~PVF_KENTER;
 
-			/* just in case we have enter/kenter mismatch */
 			pve = pmap_pv_remove(pg, pmap, va);
-			if ((pte & PVF_NC) != 0)
+
+			if ((pg->mdpage.pvh_attrs & PVF_NC) == 0) {
 				pmap_check_alias(pg, pg->mdpage.pvh_list, va,
 				    NULL);
+			}
+
+			pg->mdpage.pvh_attrs &= ~PVF_NC;
 
 			mutex_exit(&pg->mdpage.pvh_lock);
 			if (pve != NULL)

Reply via email to