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