svn commit: r253335 - projects/bhyve_npt_pmap/sys/amd64/vmm/intel
Neel Natu
neel at FreeBSD.org
Sun Jul 14 03:55:33 UTC 2013
Author: neel
Date: Sun Jul 14 03:55:31 2013
New Revision: 253335
URL: http://svnweb.freebsd.org/changeset/base/253335
Log:
Use a function to convert the physical address of the EPT to the EPTP value
that is written to the VMCS.
This is needed because the value of bit 6 in the EPTP is based on the A/D bit
capability advertised by the processor and thus cannot be known at compile
time.
Also, store the EPTP value directly in the 'struct vmx' instead of storing
the physical address of the EPT PML4 table.
Modified:
projects/bhyve_npt_pmap/sys/amd64/vmm/intel/ept.c
projects/bhyve_npt_pmap/sys/amd64/vmm/intel/ept.h
projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmcs.c
projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmcs.h
projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmx.c
projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmx.h
Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/intel/ept.c
==============================================================================
--- projects/bhyve_npt_pmap/sys/amd64/vmm/intel/ept.c Sun Jul 14 03:45:03 2013 (r253334)
+++ projects/bhyve_npt_pmap/sys/amd64/vmm/intel/ept.c Sun Jul 14 03:55:31 2013 (r253335)
@@ -48,8 +48,9 @@ __FBSDID("$FreeBSD$");
#define EPT_MEMORY_TYPE_WB(cap) ((cap) & (1UL << 14))
#define EPT_PDE_SUPERPAGE(cap) ((cap) & (1UL << 16)) /* 2MB pages */
#define EPT_PDPTE_SUPERPAGE(cap) ((cap) & (1UL << 17)) /* 1GB pages */
-#define INVVPID_SUPPORTED(cap) ((cap) & (1UL << 32))
#define INVEPT_SUPPORTED(cap) ((cap) & (1UL << 20))
+#define AD_BITS_SUPPORTED(cap) ((cap) & (1UL << 21))
+#define INVVPID_SUPPORTED(cap) ((cap) & (1UL << 32))
#define INVVPID_ALL_TYPES_MASK 0xF0000000000UL
#define INVVPID_ALL_TYPES_SUPPORTED(cap) \
@@ -59,7 +60,11 @@ __FBSDID("$FreeBSD$");
#define INVEPT_ALL_TYPES_SUPPORTED(cap) \
(((cap) & INVEPT_ALL_TYPES_MASK) == INVEPT_ALL_TYPES_MASK)
+#define EPT_PWLEVELS 4 /* page walk levels */
+#define EPT_ENABLE_AD_BITS (1 << 6)
+
static int ept_pmap_flags;
+static int ept_enable_ad_bits;
int
ept_init(void)
@@ -86,6 +91,9 @@ ept_init(void)
if (EPT_PDE_SUPERPAGE(cap))
ept_pmap_flags |= PMAP_PDE_SUPERPAGE; /* 2MB superpage */
+ if (AD_BITS_SUPPORTED(cap))
+ ept_enable_ad_bits = 1;
+
return (0);
}
@@ -132,11 +140,11 @@ invept_single_context(void *arg)
}
void
-ept_invalidate_mappings(u_long pml4ept)
+ept_invalidate_mappings(u_long eptp)
{
struct invept_desc invept_desc = { 0 };
- invept_desc.eptp = EPTP(pml4ept);
+ invept_desc.eptp = eptp;
smp_rendezvous(NULL, invept_single_context, NULL, &invept_desc);
}
@@ -161,3 +169,15 @@ ept_vmspace_free(struct vmspace *vmspace
vmspace_free(vmspace);
}
+
+uint64_t
+eptp(uint64_t pml4)
+{
+ uint64_t eptp_val;
+
+ eptp_val = pml4 | (EPT_PWLEVELS - 1) << 3 | PAT_WRITE_BACK;
+ if (ept_enable_ad_bits)
+ eptp_val |= EPT_ENABLE_AD_BITS;
+
+ return (eptp_val);
+}
Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/intel/ept.h
==============================================================================
--- projects/bhyve_npt_pmap/sys/amd64/vmm/intel/ept.h Sun Jul 14 03:45:03 2013 (r253334)
+++ projects/bhyve_npt_pmap/sys/amd64/vmm/intel/ept.h Sun Jul 14 03:55:31 2013 (r253335)
@@ -31,11 +31,9 @@
struct vmx;
-#define EPT_PWLEVELS 4 /* page walk levels */
-#define EPTP(pml4) ((pml4) | (EPT_PWLEVELS - 1) << 3 | PAT_WRITE_BACK)
-
int ept_init(void);
-void ept_invalidate_mappings(u_long ept_pml4);
+void ept_invalidate_mappings(u_long eptp);
struct vmspace *ept_vmspace_alloc(vm_offset_t min, vm_offset_t max);
void ept_vmspace_free(struct vmspace *vmspace);
+uint64_t eptp(uint64_t pml4);
#endif
Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmcs.c
==============================================================================
--- projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmcs.c Sun Jul 14 03:45:03 2013 (r253334)
+++ projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmcs.c Sun Jul 14 03:55:31 2013 (r253335)
@@ -318,14 +318,14 @@ done:
int
vmcs_set_defaults(struct vmcs *vmcs,
- u_long host_rip, u_long host_rsp, u_long ept_pml4,
+ u_long host_rip, u_long host_rsp, uint64_t eptp,
uint32_t pinbased_ctls, uint32_t procbased_ctls,
uint32_t procbased_ctls2, uint32_t exit_ctls,
uint32_t entry_ctls, u_long msr_bitmap, uint16_t vpid)
{
int error, codesel, datasel, tsssel;
u_long cr0, cr4, efer;
- uint64_t eptp, pat, fsbase, idtrbase;
+ uint64_t pat, fsbase, idtrbase;
uint32_t exc_bitmap;
codesel = vmm_get_host_codesel();
@@ -432,7 +432,6 @@ vmcs_set_defaults(struct vmcs *vmcs,
goto done;
/* eptp */
- eptp = EPTP(ept_pml4);
if ((error = vmwrite(VMCS_EPTP, eptp)) != 0)
goto done;
Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmcs.h
==============================================================================
--- projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmcs.h Sun Jul 14 03:45:03 2013 (r253334)
+++ projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmcs.h Sun Jul 14 03:55:31 2013 (r253335)
@@ -47,7 +47,7 @@ struct msr_entry {
int vmcs_set_msr_save(struct vmcs *vmcs, u_long g_area, u_int g_count);
int vmcs_set_defaults(struct vmcs *vmcs, u_long host_rip, u_long host_rsp,
- u_long ept_pml4,
+ uint64_t eptp,
uint32_t pinbased_ctls, uint32_t procbased_ctls,
uint32_t procbased_ctls2, uint32_t exit_ctls,
uint32_t entry_ctls, u_long msr_bitmap,
Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmx.c
==============================================================================
--- projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmx.c Sun Jul 14 03:45:03 2013 (r253334)
+++ projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmx.c Sun Jul 14 03:55:31 2013 (r253335)
@@ -692,7 +692,7 @@ vmx_vminit(struct vm *vm, pmap_t pmap)
}
vmx->vm = vm;
- vmx->eptphys = vtophys((vm_offset_t)pmap->pm_pml4);
+ vmx->eptp = eptp(vtophys((vm_offset_t)pmap->pm_pml4));
/*
* Clean up EPTP-tagged guest physical and combined mappings
@@ -703,7 +703,7 @@ vmx_vminit(struct vm *vm, pmap_t pmap)
*
* Combined mappings for this EP4TA are also invalidated for all VPIDs.
*/
- ept_invalidate_mappings(vmx->eptphys);
+ ept_invalidate_mappings(vmx->eptp);
msr_bitmap_initialize(vmx->msr_bitmap);
@@ -759,7 +759,7 @@ vmx_vminit(struct vm *vm, pmap_t pmap)
error = vmcs_set_defaults(&vmx->vmcs[i],
(u_long)vmx_longjmp,
(u_long)&vmx->ctx[i],
- vmx->eptphys,
+ vmx->eptp,
pinbased_ctls,
procbased_ctls,
procbased_ctls2,
Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmx.h
==============================================================================
--- projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmx.h Sun Jul 14 03:45:03 2013 (r253334)
+++ projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmx.h Sun Jul 14 03:55:31 2013 (r253335)
@@ -88,7 +88,7 @@ struct vmx {
struct vmxctx ctx[VM_MAXCPU];
struct vmxcap cap[VM_MAXCPU];
struct vmxstate state[VM_MAXCPU];
- vm_paddr_t eptphys;
+ uint64_t eptp;
struct vm *vm;
};
CTASSERT((offsetof(struct vmx, vmcs) & PAGE_MASK) == 0);
More information about the svn-src-projects
mailing list