Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 1 Jul 2013 20:30:49 +0000 (UTC)
From:      Neel Natu <neel@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r252476 - projects/bhyve_npt_pmap/sys/amd64/amd64
Message-ID:  <201307012030.r61KUnNA046075@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: neel
Date: Mon Jul  1 20:30:48 2013
New Revision: 252476
URL: http://svnweb.freebsd.org/changeset/base/252476

Log:
  Don't fiddle with the PAT bits directly since they do not exist in nested
  page table entries.
  
  The 'pmap_swap_pat()' function swaps the PG_PTE_PAT and PG_PDE_PAT bits
  for the regular x86 page tables and is a no-op for nested page tables.

Modified:
  projects/bhyve_npt_pmap/sys/amd64/amd64/pmap.c

Modified: projects/bhyve_npt_pmap/sys/amd64/amd64/pmap.c
==============================================================================
--- projects/bhyve_npt_pmap/sys/amd64/amd64/pmap.c	Mon Jul  1 20:05:43 2013	(r252475)
+++ projects/bhyve_npt_pmap/sys/amd64/amd64/pmap.c	Mon Jul  1 20:30:48 2013	(r252476)
@@ -229,11 +229,17 @@ pmap_modified_bit(pmap_t pmap)
 	return (mask);
 }
 
+#undef PG_PDE_PAT
+#define	X86_PG_PDE_PAT			0x1000
+
 #undef PG_PDE_CACHE
-#define	X86_PG_PDE_CACHE		(PG_PDE_PAT | PG_NC_PWT | PG_NC_PCD)
+#define	X86_PG_PDE_CACHE		(X86_PG_PDE_PAT | PG_NC_PWT | PG_NC_PCD)
+
+#undef PG_PTE_PAT
+#define	X86_PG_PTE_PAT			0x080
 
 #undef PG_PTE_CACHE
-#define	X86_PG_PTE_CACHE		(PG_PTE_PAT | PG_NC_PWT | PG_NC_PCD)
+#define	X86_PG_PTE_CACHE		(X86_PG_PTE_PAT | PG_NC_PWT | PG_NC_PCD)
 
 #if !defined(DIAGNOSTIC)
 #ifdef __GNUC_GNU_INLINE__
@@ -993,6 +999,34 @@ SYSCTL_ULONG(_vm_pmap_pdpe, OID_AUTO, de
  * Low level helper routines.....
  ***************************************************/
 
+static pt_entry_t
+pmap_swap_pat(pmap_t pmap, pt_entry_t entry)
+{
+	int x86_pat_bits = X86_PG_PTE_PAT | X86_PG_PDE_PAT;
+
+	switch (pmap->pm_type) {
+	case PT_X86:
+		/* Verify that both PAT bits are not set at the same time */
+		KASSERT((entry & x86_pat_bits) != x86_pat_bits,
+			("Invalid PAT bits in entry %#lx", entry));
+
+		/* Swap the PAT bits if one of them is set */
+		if ((entry & x86_pat_bits) != 0)
+			entry ^= x86_pat_bits;
+		break;
+	case PT_EPT:
+		/*
+		 * Nothing to do - the memory attributes are represented
+		 * the same way for regular pages and superpages.
+		 */
+		break;
+	default:
+		panic("pmap_switch_pat_bits: bad pm_type %d", pmap->pm_type);
+	}
+
+	return (entry);
+}
+
 /*
  * Determine the appropriate bits to set in a PTE or PDE for a specified
  * caching mode.
@@ -1008,7 +1042,7 @@ pmap_cache_bits(pmap_t pmap, int mode, b
 	switch (pmap->pm_type) {
 	case PT_X86:
 		/* The PAT bit is different for PTE's and PDE's. */
-		pat_flag = is_pde ? PG_PDE_PAT : PG_PTE_PAT;
+		pat_flag = is_pde ? X86_PG_PDE_PAT : X86_PG_PTE_PAT;
 
 		/* Map the caching mode to a PAT index. */
 		pat_idx = pat_index[mode];
@@ -3044,8 +3078,7 @@ pmap_demote_pde_locked(pmap_t pmap, pd_e
 	KASSERT((oldpde & (PG_M | PG_RW)) != PG_RW,
 	    ("pmap_demote_pde: oldpde is missing PG_M"));
 	newpte = oldpde & ~PG_PS;
-	if ((newpte & PG_PDE_PAT) != 0)
-		newpte ^= PG_PDE_PAT | PG_PTE_PAT;
+	newpte = pmap_swap_pat(pmap, newpte);
 
 	/*
 	 * If the page table page is new, initialize it.
@@ -3741,8 +3774,7 @@ setpte:
 	/*
 	 * Propagate the PAT index to its proper position.
 	 */
-	if ((newpde & PG_PTE_PAT) != 0)
-		newpde ^= PG_PDE_PAT | PG_PTE_PAT;
+	newpde = pmap_swap_pat(pmap, newpde);
 
 	/*
 	 * Map the superpage.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201307012030.r61KUnNA046075>