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>