svn commit: r253313 - in projects/bhyve_npt_pmap/sys/amd64: amd64 include vmm/intel
Neel Natu
neel at FreeBSD.org
Sat Jul 13 01:24:17 UTC 2013
Author: neel
Date: Sat Jul 13 01:24:16 2013
New Revision: 253313
URL: http://svnweb.freebsd.org/changeset/base/253313
Log:
If the 'PMAP_PDE_SUPERPAGE' bit is not set in 'pm_flags' then the pmap does
not support 2MB superpages. We don't allow superpage promotion within these
pmaps.
The X86 pmaps unconditionally set the PMAP_PDE_SUPERPAGE bit.
The EPT pmaps set the PMAP_PDE_SUPERPAGE bit only if the processor advertises
2MB superpages in the EPT.
Modified:
projects/bhyve_npt_pmap/sys/amd64/amd64/pmap.c
projects/bhyve_npt_pmap/sys/amd64/include/pmap.h
projects/bhyve_npt_pmap/sys/amd64/vmm/intel/ept.c
Modified: projects/bhyve_npt_pmap/sys/amd64/amd64/pmap.c
==============================================================================
--- projects/bhyve_npt_pmap/sys/amd64/amd64/pmap.c Sat Jul 13 00:53:56 2013 (r253312)
+++ projects/bhyve_npt_pmap/sys/amd64/amd64/pmap.c Sat Jul 13 01:24:16 2013 (r253313)
@@ -773,6 +773,7 @@ pmap_bootstrap(vm_paddr_t *firstaddr)
kernel_pmap->pm_pml4 = (pdp_entry_t *)PHYS_TO_DMAP(KPML4phys);
CPU_FILL(&kernel_pmap->pm_active); /* don't allow deactivation */
TAILQ_INIT(&kernel_pmap->pm_pvchunk);
+ kernel_pmap->pm_flags = PMAP_PDE_SUPERPAGE;
/*
* Initialize the global pv list lock.
@@ -1087,6 +1088,16 @@ pmap_cache_mask(pmap_t pmap, boolean_t i
return (mask);
}
+static __inline boolean_t
+pmap_ps_enabled(pmap_t pmap)
+{
+
+ if ((pmap->pm_flags & PMAP_PDE_SUPERPAGE) != 0)
+ return (TRUE);
+ else
+ return (FALSE);
+}
+
static void
pmap_update_pde_store(pmap_t pmap, pd_entry_t *pde, pd_entry_t newpde)
{
@@ -1969,6 +1980,7 @@ pmap_pinit0(pmap_t pmap)
PCPU_SET(curpmap, pmap);
TAILQ_INIT(&pmap->pm_pvchunk);
bzero(&pmap->pm_stats, sizeof pmap->pm_stats);
+ pmap->pm_flags = PMAP_PDE_SUPERPAGE;
}
/*
@@ -1976,7 +1988,7 @@ pmap_pinit0(pmap_t pmap)
* such as one in a vmspace structure.
*/
int
-pmap_pinit_type(pmap_t pmap, enum pmap_type pm_type)
+pmap_pinit_type(pmap_t pmap, enum pmap_type pm_type, int flags)
{
vm_page_t pml4pg;
pt_entry_t PG_A, PG_M;
@@ -2021,6 +2033,7 @@ pmap_pinit_type(pmap_t pmap, enum pmap_t
CPU_ZERO(&pmap->pm_active);
TAILQ_INIT(&pmap->pm_pvchunk);
bzero(&pmap->pm_stats, sizeof pmap->pm_stats);
+ pmap->pm_flags = flags;
return (1);
}
@@ -2029,7 +2042,7 @@ int
pmap_pinit(pmap_t pmap)
{
- return (pmap_pinit_type(pmap, PT_X86));
+ return (pmap_pinit_type(pmap, PT_X86, PMAP_PDE_SUPERPAGE));
}
/*
@@ -3991,7 +4004,8 @@ unchanged:
* populated, then attempt promotion.
*/
if ((mpte == NULL || mpte->wire_count == NPTEPG) &&
- pg_ps_enabled && (m->flags & PG_FICTITIOUS) == 0 &&
+ pg_ps_enabled && pmap_ps_enabled(pmap) &&
+ (m->flags & PG_FICTITIOUS) == 0 &&
vm_reserv_level_iffullpop(m) == 0)
pmap_promote_pde(pmap, pde, va, &lock);
@@ -4105,7 +4119,8 @@ pmap_enter_object(pmap_t pmap, vm_offset
va = start + ptoa(diff);
if ((va & PDRMASK) == 0 && va + NBPDR <= end &&
(VM_PAGE_TO_PHYS(m) & PDRMASK) == 0 &&
- pg_ps_enabled && vm_reserv_level_iffullpop(m) == 0 &&
+ pg_ps_enabled && pmap_ps_enabled(pmap) &&
+ vm_reserv_level_iffullpop(m) == 0 &&
pmap_enter_pde(pmap, va, m, prot, &lock))
m = &m[NBPDR / PAGE_SIZE - 1];
else
@@ -4284,6 +4299,8 @@ pmap_object_init_pt(pmap_t pmap, vm_offs
KASSERT(object->type == OBJT_DEVICE || object->type == OBJT_SG,
("pmap_object_init_pt: non-device object"));
if ((addr & (NBPDR - 1)) == 0 && (size & (NBPDR - 1)) == 0) {
+ if (!pmap_ps_enabled(pmap))
+ return;
if (!vm_object_populate(object, pindex, pindex + atop(size)))
return;
p = vm_page_lookup(object, pindex);
Modified: projects/bhyve_npt_pmap/sys/amd64/include/pmap.h
==============================================================================
--- projects/bhyve_npt_pmap/sys/amd64/include/pmap.h Sat Jul 13 00:53:56 2013 (r253312)
+++ projects/bhyve_npt_pmap/sys/amd64/include/pmap.h Sat Jul 13 01:24:16 2013 (r253313)
@@ -259,8 +259,12 @@ struct pmap {
struct pmap_statistics pm_stats; /* pmap statistics */
struct vm_radix pm_root; /* spare page table pages */
long pm_eptgen; /* EPT pmap generation id */
+ int pm_flags;
};
+/* flags */
+#define PMAP_PDE_SUPERPAGE (1 << 0) /* supports 2MB superpages */
+
typedef struct pmap *pmap_t;
#ifdef _KERNEL
@@ -278,7 +282,7 @@ extern struct pmap kernel_pmap_store;
#define PMAP_TRYLOCK(pmap) mtx_trylock(&(pmap)->pm_mtx)
#define PMAP_UNLOCK(pmap) mtx_unlock(&(pmap)->pm_mtx)
-int pmap_pinit_type(pmap_t pmap, enum pmap_type pm_type);
+int pmap_pinit_type(pmap_t pmap, enum pmap_type pm_type, int flags);
#endif
/*
Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/intel/ept.c
==============================================================================
--- projects/bhyve_npt_pmap/sys/amd64/vmm/intel/ept.c Sat Jul 13 00:53:56 2013 (r253312)
+++ projects/bhyve_npt_pmap/sys/amd64/vmm/intel/ept.c Sat Jul 13 01:24:16 2013 (r253313)
@@ -59,12 +59,11 @@ __FBSDID("$FreeBSD$");
#define INVEPT_ALL_TYPES_SUPPORTED(cap) \
(((cap) & INVEPT_ALL_TYPES_MASK) == INVEPT_ALL_TYPES_MASK)
-static uint64_t page_sizes_mask;
+static int ept_pmap_flags;
int
ept_init(void)
{
- int page_shift;
uint64_t cap;
cap = rdmsr(MSR_VMX_EPT_VPID_CAP);
@@ -84,17 +83,8 @@ ept_init(void)
!INVEPT_ALL_TYPES_SUPPORTED(cap))
return (EINVAL);
- /* Set bits in 'page_sizes_mask' for each valid page size */
- page_shift = PAGE_SHIFT;
- page_sizes_mask = 1UL << page_shift; /* 4KB page */
-
- page_shift += 9;
if (EPT_PDE_SUPERPAGE(cap))
- page_sizes_mask |= 1UL << page_shift; /* 2MB superpage */
-
- page_shift += 9;
- if (EPT_PDPTE_SUPERPAGE(cap))
- page_sizes_mask |= 1UL << page_shift; /* 1GB superpage */
+ ept_pmap_flags |= PMAP_PDE_SUPERPAGE; /* 2MB superpage */
return (0);
}
@@ -155,7 +145,7 @@ static int
ept_pinit(pmap_t pmap)
{
- return (pmap_pinit_type(pmap, PT_EPT));
+ return (pmap_pinit_type(pmap, PT_EPT, ept_pmap_flags));
}
struct vmspace *
More information about the svn-src-projects
mailing list