Module Name:    src
Committed By:   maxv
Date:           Fri Feb  1 05:44:29 UTC 2019

Modified Files:
        src/sys/arch/x86/include: pmap.h pmap_pv.h
        src/sys/arch/x86/x86: pmap.c

Log Message:
Change the format of the pp_attrs field: instead of using PTE bits
directly, use abstracted bits that are converted from/to PTE bits when
needed (in pmap_sync_pv).

This allows us to use the same pp_attrs for pmaps that have PTE bits at
different locations.


To generate a diff of this commit:
cvs rdiff -u -r1.93 -r1.94 src/sys/arch/x86/include/pmap.h
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/x86/include/pmap_pv.h
cvs rdiff -u -r1.317 -r1.318 src/sys/arch/x86/x86/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/x86/include/pmap.h
diff -u src/sys/arch/x86/include/pmap.h:1.93 src/sys/arch/x86/include/pmap.h:1.94
--- src/sys/arch/x86/include/pmap.h:1.93	Mon Dec 17 06:58:54 2018
+++ src/sys/arch/x86/include/pmap.h	Fri Feb  1 05:44:29 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: pmap.h,v 1.93 2018/12/17 06:58:54 maxv Exp $	*/
+/*	$NetBSD: pmap.h,v 1.94 2019/02/01 05:44:29 maxv Exp $	*/
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -111,6 +111,7 @@
 
 #if defined(_KERNEL)
 #include <sys/kcpuset.h>
+#include <x86/pmap_pv.h>
 #include <uvm/pmap/pmap_pvt.h>
 
 #define BTSEG_NONE	0
@@ -306,11 +307,11 @@ extern long nkptp[PTP_LEVELS];
 #define	pmap_resident_count(pmap)	((pmap)->pm_stats.resident_count)
 #define	pmap_wired_count(pmap)		((pmap)->pm_stats.wired_count)
 
-#define pmap_clear_modify(pg)		pmap_clear_attrs(pg, PG_M)
-#define pmap_clear_reference(pg)	pmap_clear_attrs(pg, PG_U)
+#define pmap_clear_modify(pg)		pmap_clear_attrs(pg, PP_ATTRS_M)
+#define pmap_clear_reference(pg)	pmap_clear_attrs(pg, PP_ATTRS_U)
 #define pmap_copy(DP,SP,D,L,S)		__USE(L)
-#define pmap_is_modified(pg)		pmap_test_attrs(pg, PG_M)
-#define pmap_is_referenced(pg)		pmap_test_attrs(pg, PG_U)
+#define pmap_is_modified(pg)		pmap_test_attrs(pg, PP_ATTRS_M)
+#define pmap_is_referenced(pg)		pmap_test_attrs(pg, PP_ATTRS_U)
 #define pmap_move(DP,SP,D,L,S)
 #define pmap_phys_address(ppn)		(x86_ptob(ppn) & ~X86_MMAP_FLAG_MASK)
 #define pmap_mmap_flags(ppn)		x86_mmap_flags(ppn)
@@ -436,7 +437,7 @@ pmap_page_protect(struct vm_page *pg, vm
 {
 	if ((prot & VM_PROT_WRITE) == 0) {
 		if (prot & (VM_PROT_READ|VM_PROT_EXECUTE)) {
-			(void) pmap_clear_attrs(pg, PG_RW);
+			(void)pmap_clear_attrs(pg, PP_ATTRS_W);
 		} else {
 			pmap_page_remove(pg);
 		}
@@ -453,7 +454,7 @@ pmap_pv_protect(paddr_t pa, vm_prot_t pr
 {
 	if ((prot & VM_PROT_WRITE) == 0) {
 		if (prot & (VM_PROT_READ|VM_PROT_EXECUTE)) {
-			(void) pmap_pv_clear_attrs(pa, PG_RW);
+			(void)pmap_pv_clear_attrs(pa, PP_ATTRS_W);
 		} else {
 			pmap_pv_remove(pa);
 		}

Index: src/sys/arch/x86/include/pmap_pv.h
diff -u src/sys/arch/x86/include/pmap_pv.h:1.3 src/sys/arch/x86/include/pmap_pv.h:1.4
--- src/sys/arch/x86/include/pmap_pv.h:1.3	Sun Jun 12 03:35:50 2011
+++ src/sys/arch/x86/include/pmap_pv.h	Fri Feb  1 05:44:29 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: pmap_pv.h,v 1.3 2011/06/12 03:35:50 rmind Exp $	*/
+/*	$NetBSD: pmap_pv.h,v 1.4 2019/02/01 05:44:29 maxv Exp $	*/
 
 /*-
  * Copyright (c)2008 YAMAMOTO Takashi,
@@ -81,7 +81,10 @@ struct pmap_page {
 #define	pp_head	pp_u.u_head
 #define	pp_link	pp_u.u_link
 	uint8_t pp_flags;
-	uint8_t pp_attrs;	/* saved PG_M and PG_U */
+	uint8_t pp_attrs;
+#define PP_ATTRS_M	0x01	/* saved PG_M */
+#define PP_ATTRS_U	0x02	/* saved PG_U */
+#define PP_ATTRS_W	0x04	/* saved PG_RW */
 };
 
 /* pp_flags */

Index: src/sys/arch/x86/x86/pmap.c
diff -u src/sys/arch/x86/x86/pmap.c:1.317 src/sys/arch/x86/x86/pmap.c:1.318
--- src/sys/arch/x86/x86/pmap.c:1.317	Thu Jan 31 20:42:31 2019
+++ src/sys/arch/x86/x86/pmap.c	Fri Feb  1 05:44:29 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: pmap.c,v 1.317 2019/01/31 20:42:31 maxv Exp $	*/
+/*	$NetBSD: pmap.c,v 1.318 2019/02/01 05:44:29 maxv Exp $	*/
 
 /*
  * Copyright (c) 2008, 2010, 2016, 2017 The NetBSD Foundation, Inc.
@@ -130,7 +130,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.317 2019/01/31 20:42:31 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.318 2019/02/01 05:44:29 maxv Exp $");
 
 #include "opt_user_ldt.h"
 #include "opt_lockdebug.h"
@@ -3388,6 +3388,32 @@ pmap_remove_ptes(struct pmap *pmap, stru
 	}
 }
 
+static inline uint8_t
+pmap_pte_to_pp_attrs(pt_entry_t pte)
+{
+	uint8_t ret = 0;
+	if (pte & PG_M)
+		ret |= PP_ATTRS_M;
+	if (pte & PG_U)
+		ret |= PP_ATTRS_U;
+	if (pte & PG_RW)
+		ret |= PP_ATTRS_W;
+	return ret;
+}
+
+static inline pt_entry_t
+pmap_pp_attrs_to_pte(uint8_t attrs)
+{
+	pt_entry_t pte = 0;
+	if (attrs & PP_ATTRS_M)
+		pte |= PG_M;
+	if (attrs & PP_ATTRS_U)
+		pte |= PG_U;
+	if (attrs & PP_ATTRS_W)
+		pte |= PG_RW;
+	return pte;
+}
+
 /*
  * pmap_remove_pte: remove a single PTE from a PTP.
  *
@@ -3461,7 +3487,7 @@ pmap_remove_pte(struct pmap *pmap, struc
 	}
 
 	/* Sync R/M bits. */
-	pp->pp_attrs |= opte;
+	pp->pp_attrs |= pmap_pte_to_pp_attrs(opte);
 	pve = pmap_remove_pv(pp, ptp, va);
 
 	if (pve) {
@@ -3573,13 +3599,15 @@ pmap_remove(struct pmap *pmap, vaddr_t s
 }
 
 /*
- * pmap_sync_pv: clear pte bits and return the old value of the pte.
+ * pmap_sync_pv: clear pte bits and return the old value of the pp_attrs.
  *
+ * => The 'clearbits' parameter is either ~0 or PP_ATTRS_...
  * => Caller should disable kernel preemption.
  * => issues tlb shootdowns if necessary.
  */
 static int
-pmap_sync_pv(struct pv_pte *pvpte, paddr_t pa, int clearbits, pt_entry_t *optep)
+pmap_sync_pv(struct pv_pte *pvpte, paddr_t pa, int clearbits, uint8_t *oattrs,
+    pt_entry_t *optep)
 {
 	struct pmap *pmap;
 	struct vm_page *ptp;
@@ -3597,7 +3625,11 @@ pmap_sync_pv(struct pv_pte *pvpte, paddr
 	KASSERT(ptp == NULL || ptp_va2o(va, 1) == ptp->offset);
 	pmap = ptp_to_pmap(ptp);
 
-	KASSERT(clearbits == ~0 || (clearbits & ~(PG_M | PG_U | PG_RW)) == 0);
+	if (clearbits != ~0) {
+		KASSERT((clearbits & ~(PP_ATTRS_M|PP_ATTRS_U|PP_ATTRS_W)) == 0);
+		clearbits = pmap_pp_attrs_to_pte(clearbits);
+	}
+
 	KASSERT(kpreempt_disabled());
 
 	ptep = pmap_map_pte(pmap, ptp, va);
@@ -3658,7 +3690,9 @@ pmap_sync_pv(struct pv_pte *pvpte, paddr
 	}
 	pmap_unmap_pte();
 
-	*optep = opte;
+	*oattrs = pmap_pte_to_pp_attrs(opte);
+	if (optep != NULL)
+		*optep = opte;
 	return 0;
 }
 
@@ -3685,6 +3719,7 @@ pmap_pp_remove(struct pmap_page *pp, pad
 	struct pv_pte *pvpte;
 	struct pv_entry *killlist = NULL;
 	struct vm_page *ptp;
+	uint8_t oattrs;
 	int count;
 
 	count = SPINLOCK_BACKOFF_MIN;
@@ -3707,7 +3742,7 @@ startover:
 			pmap_reference(pmap);
 		}
 
-		error = pmap_sync_pv(pvpte, pa, ~0, &opte);
+		error = pmap_sync_pv(pvpte, pa, ~0, &oattrs, &opte);
 		if (error == EAGAIN) {
 			int hold_count;
 			KERNEL_UNLOCK_ALL(curlwp, &hold_count);
@@ -3719,7 +3754,7 @@ startover:
 			goto startover;
 		}
 
-		pp->pp_attrs |= opte;
+		pp->pp_attrs |= oattrs;
 		va = pvpte->pte_va;
 		pve = pmap_remove_pv(pp, ptp, va);
 
@@ -3794,6 +3829,7 @@ pmap_test_attrs(struct vm_page *pg, unsi
 {
 	struct pmap_page *pp;
 	struct pv_pte *pvpte;
+	uint8_t oattrs;
 	u_int result;
 	paddr_t pa;
 
@@ -3806,15 +3842,14 @@ pmap_test_attrs(struct vm_page *pg, unsi
 	pa = VM_PAGE_TO_PHYS(pg);
 	kpreempt_disable();
 	for (pvpte = pv_pte_first(pp); pvpte; pvpte = pv_pte_next(pp, pvpte)) {
-		pt_entry_t opte;
 		int error;
 
 		if ((pp->pp_attrs & testbits) != 0) {
 			break;
 		}
-		error = pmap_sync_pv(pvpte, pa, 0, &opte);
+		error = pmap_sync_pv(pvpte, pa, 0, &oattrs, NULL);
 		if (error == 0) {
-			pp->pp_attrs |= opte;
+			pp->pp_attrs |= oattrs;
 		}
 	}
 	result = pp->pp_attrs & testbits;
@@ -3832,6 +3867,7 @@ static bool
 pmap_pp_clear_attrs(struct pmap_page *pp, paddr_t pa, unsigned clearbits)
 {
 	struct pv_pte *pvpte;
+	uint8_t oattrs;
 	u_int result;
 	int count;
 
@@ -3839,10 +3875,9 @@ pmap_pp_clear_attrs(struct pmap_page *pp
 	kpreempt_disable();
 startover:
 	for (pvpte = pv_pte_first(pp); pvpte; pvpte = pv_pte_next(pp, pvpte)) {
-		pt_entry_t opte;
 		int error;
 
-		error = pmap_sync_pv(pvpte, pa, clearbits, &opte);
+		error = pmap_sync_pv(pvpte, pa, clearbits, &oattrs, NULL);
 		if (error == EAGAIN) {
 			int hold_count;
 			KERNEL_UNLOCK_ALL(curlwp, &hold_count);
@@ -3850,7 +3885,7 @@ startover:
 			KERNEL_LOCK(hold_count, curlwp);
 			goto startover;
 		}
-		pp->pp_attrs |= opte;
+		pp->pp_attrs |= oattrs;
 	}
 	result = pp->pp_attrs & clearbits;
 	pp->pp_attrs &= ~clearbits;
@@ -4254,7 +4289,7 @@ pmap_enter_ma(struct pmap *pmap, vaddr_t
 		}
 
 		old_pve = pmap_remove_pv(old_pp, ptp, va);
-		old_pp->pp_attrs |= opte;
+		old_pp->pp_attrs |= pmap_pte_to_pp_attrs(opte);
 	}
 
 	/*

Reply via email to