svn commit: r252289 - projects/bhyve_npt_pmap/sys/amd64/amd64
Neel Natu
neel at FreeBSD.org
Thu Jun 27 05:38:20 UTC 2013
Author: neel
Date: Thu Jun 27 05:38:19 2013
New Revision: 252289
URL: http://svnweb.freebsd.org/changeset/base/252289
Log:
The regular x86 PTEs and nested PTEs are similar but not identical.
In some instances they have bits that are equivalent but at different
positions. In other instances a bit in the regular PTE has no equivalent
in the nested PTE. The PG_G bit is an example of the latter.
Undefine the PG_G macro in pmap.c so it is not inadvertently tested
with nested PTEs.
Use a function 'pmap_global_bit(pmap_t)' to compute the bitmask for the
"global" bit in the PTE.
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 Thu Jun 27 02:27:13 2013 (r252288)
+++ projects/bhyve_npt_pmap/sys/amd64/amd64/pmap.c Thu Jun 27 05:38:19 2013 (r252289)
@@ -156,6 +156,35 @@ __FBSDID("$FreeBSD$");
#define EPT_PG_A (1 << 8)
#define EPT_PG_M (1 << 9)
+/*
+ * undef the PG_xx macros that define bits in the regular x86 PTEs that have
+ * a different position in nested PTEs.
+ *
+ * The appropriate bitmask is now calculated at runtime based on the pmap
+ * type.
+ */
+
+#undef PG_G
+#define X86_PG_G 0x100
+static __inline pt_entry_t
+pmap_global_bit(pmap_t pmap)
+{
+ pt_entry_t mask;
+
+ switch (pmap->pm_type) {
+ case PT_X86:
+ mask = X86_PG_G;
+ break;
+ case PT_EPT:
+ mask = 0;
+ break;
+ default:
+ panic("pmap_global_bit: invalid pm_type %d", pmap->pm_type);
+ }
+
+ return (mask);
+}
+
#if !defined(DIAGNOSTIC)
#ifdef __GNUC_GNU_INLINE__
#define PMAP_INLINE __attribute__((__gnu_inline__)) inline
@@ -316,7 +345,7 @@ static boolean_t pmap_try_insert_pv_entr
vm_page_t m, struct rwlock **lockp);
static void pmap_update_pde(pmap_t pmap, vm_offset_t va, pd_entry_t *pde,
pd_entry_t newpde);
-static void pmap_update_pde_invalidate(vm_offset_t va, pd_entry_t newpde);
+static void pmap_update_pde_invalidate(pmap_t, vm_offset_t va, pd_entry_t pde);
static vm_page_t _pmap_allocpte(pmap_t pmap, vm_pindex_t ptepindex,
struct rwlock **lockp);
@@ -545,6 +574,9 @@ static void
create_pagetables(vm_paddr_t *firstaddr)
{
int i, j, ndm1g, nkpdpe;
+ pt_entry_t PG_G;
+
+ PG_G = pmap_global_bit(kernel_pmap);
/* Allocate page table pages for the direct map */
ndmpdp = (ptoa(Maxmem) + NBPDP - 1) >> PDPSHIFT;
@@ -958,9 +990,12 @@ pmap_cache_bits(pmap_t pmap, int mode, b
* The calling thread must be pinned to a processor.
*/
static void
-pmap_update_pde_invalidate(vm_offset_t va, pd_entry_t newpde)
+pmap_update_pde_invalidate(pmap_t pmap, vm_offset_t va, pd_entry_t newpde)
{
u_long cr4;
+ pt_entry_t PG_G;
+
+ PG_G = pmap_global_bit(pmap);
if ((newpde & PG_PS) == 0)
/* Demotion: flush a specific 2MB page mapping. */
@@ -1092,6 +1127,7 @@ pmap_invalidate_cache(void)
struct pde_action {
cpuset_t invalidate; /* processors that invalidate their TLB */
+ pmap_t pmap;
vm_offset_t va;
pd_entry_t *pde;
pd_entry_t newpde;
@@ -1113,7 +1149,7 @@ pmap_update_pde_teardown(void *arg)
struct pde_action *act = arg;
if (CPU_ISSET(PCPU_GET(cpuid), &act->invalidate))
- pmap_update_pde_invalidate(act->va, act->newpde);
+ pmap_update_pde_invalidate(act->pmap, act->va, act->newpde);
}
/*
@@ -1143,6 +1179,7 @@ pmap_update_pde(pmap_t pmap, vm_offset_t
act.store = cpuid;
act.invalidate = active;
act.va = va;
+ act.pmap = pmap;
act.pde = pde;
act.newpde = newpde;
CPU_SET(cpuid, &active);
@@ -1152,7 +1189,7 @@ pmap_update_pde(pmap_t pmap, vm_offset_t
} else {
pde_store(pde, newpde);
if (CPU_ISSET(cpuid, &active))
- pmap_update_pde_invalidate(va, newpde);
+ pmap_update_pde_invalidate(pmap, va, newpde);
}
sched_unpin();
}
@@ -1200,7 +1237,7 @@ pmap_update_pde(pmap_t pmap, vm_offset_t
pde_store(pde, newpde);
if (pmap == kernel_pmap || !CPU_EMPTY(&pmap->pm_active))
- pmap_update_pde_invalidate(va, newpde);
+ pmap_update_pde_invalidate(pmap, va, newpde);
}
#endif /* !SMP */
@@ -1413,7 +1450,9 @@ pmap_kextract(vm_offset_t va)
PMAP_INLINE void
pmap_kenter(vm_offset_t va, vm_paddr_t pa)
{
- pt_entry_t *pte;
+ pt_entry_t *pte, PG_G;
+
+ PG_G = pmap_global_bit(kernel_pmap);
pte = vtopte(va);
pte_store(pte, pa | PG_RW | PG_V | PG_G);
@@ -1422,9 +1461,11 @@ pmap_kenter(vm_offset_t va, vm_paddr_t p
static __inline void
pmap_kenter_attr(vm_offset_t va, vm_paddr_t pa, int mode)
{
- pt_entry_t *pte;
+ pt_entry_t *pte, PG_G;
int cache_bits;
+ PG_G = pmap_global_bit(kernel_pmap);
+
pte = vtopte(va);
cache_bits = pmap_cache_bits(kernel_pmap, mode, 0);
pte_store(pte, pa | PG_RW | PG_V | PG_G | cache_bits);
@@ -1474,10 +1515,12 @@ pmap_map(vm_offset_t *virt, vm_paddr_t s
void
pmap_qenter(vm_offset_t sva, vm_page_t *ma, int count)
{
- pt_entry_t *endpte, oldpte, pa, *pte;
+ pt_entry_t *endpte, oldpte, pa, *pte, PG_G;
vm_page_t m;
int cache_bits;
+ PG_G = pmap_global_bit(kernel_pmap);
+
oldpte = 0;
pte = vtopte(sva);
endpte = pte + count;
@@ -2164,7 +2207,7 @@ reclaim_pv_chunk(pmap_t locked_pmap, str
struct md_page *pvh;
pd_entry_t *pde;
pmap_t pmap;
- pt_entry_t *pte, tpte;
+ pt_entry_t *pte, tpte, PG_G;
pv_entry_t pv;
vm_offset_t va;
vm_page_t free, m, m_pc;
@@ -2199,6 +2242,7 @@ reclaim_pv_chunk(pmap_t locked_pmap, str
mtx_lock(&pv_chunks_mutex);
continue;
}
+ PG_G = pmap_global_bit(pmap);
}
/*
@@ -2724,10 +2768,12 @@ pmap_demote_pde_locked(pmap_t pmap, pd_e
struct rwlock **lockp)
{
pd_entry_t newpde, oldpde;
- pt_entry_t *firstpte, newpte;
+ pt_entry_t *firstpte, newpte, PG_G;
vm_paddr_t mptepa;
vm_page_t free, mpte;
+ PG_G = pmap_global_bit(pmap);
+
PMAP_LOCK_ASSERT(pmap, MA_OWNED);
oldpde = *pde;
KASSERT((oldpde & (PG_PS | PG_V)) == (PG_PS | PG_V),
@@ -2849,6 +2895,9 @@ pmap_remove_pde(pmap_t pmap, pd_entry_t
pd_entry_t oldpde;
vm_offset_t eva, va;
vm_page_t m, mpte;
+ pt_entry_t PG_G;
+
+ PG_G = pmap_global_bit(pmap);
PMAP_LOCK_ASSERT(pmap, MA_OWNED);
KASSERT((sva & PDRMASK) == 0,
@@ -2968,10 +3017,12 @@ pmap_remove(pmap_t pmap, vm_offset_t sva
pml4_entry_t *pml4e;
pdp_entry_t *pdpe;
pd_entry_t ptpaddr, *pde;
- pt_entry_t *pte;
+ pt_entry_t *pte, PG_G;
vm_page_t free = NULL;
int anyvalid;
+ PG_G = pmap_global_bit(pmap);
+
/*
* Perform an unsynchronized read. This is, however, safe.
*/
@@ -3180,6 +3231,9 @@ pmap_protect_pde(pmap_t pmap, pd_entry_t
vm_offset_t eva, va;
vm_page_t m;
boolean_t anychanged;
+ pt_entry_t PG_G;
+
+ PG_G = pmap_global_bit(pmap);
PMAP_LOCK_ASSERT(pmap, MA_OWNED);
KASSERT((sva & PDRMASK) == 0,
@@ -3220,9 +3274,11 @@ pmap_protect(pmap_t pmap, vm_offset_t sv
pml4_entry_t *pml4e;
pdp_entry_t *pdpe;
pd_entry_t ptpaddr, *pde;
- pt_entry_t *pte;
+ pt_entry_t *pte, PG_G;
boolean_t anychanged, pv_lists_locked;
+ PG_G = pmap_global_bit(pmap);
+
if ((prot & VM_PROT_READ) == VM_PROT_NONE) {
pmap_remove(pmap, sva, eva);
return;
@@ -3359,10 +3415,12 @@ pmap_promote_pde(pmap_t pmap, pd_entry_t
struct rwlock **lockp)
{
pd_entry_t newpde;
- pt_entry_t *firstpte, oldpte, pa, *pte;
+ pt_entry_t *firstpte, oldpte, pa, *pte, PG_G;
vm_offset_t oldpteva;
vm_page_t mpte;
+ PG_G = pmap_global_bit(pmap);
+
PMAP_LOCK_ASSERT(pmap, MA_OWNED);
/*
@@ -3482,12 +3540,14 @@ pmap_enter(pmap_t pmap, vm_offset_t va,
{
struct rwlock *lock;
pd_entry_t *pde;
- pt_entry_t *pte;
+ pt_entry_t *pte, PG_G;
pt_entry_t newpte, origpte;
pv_entry_t pv;
vm_paddr_t opa, pa;
vm_page_t mpte, om;
+ PG_G = pmap_global_bit(pmap);
+
va = trunc_page(va);
KASSERT(va <= VM_MAX_KERNEL_ADDRESS, ("pmap_enter: toobig"));
KASSERT(va < UPT_MIN_ADDRESS || va >= UPT_MAX_ADDRESS,
More information about the svn-src-projects
mailing list