Date: Wed, 3 Jul 2013 06:43:06 +0000 (UTC) From: Neel Natu <neel@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r252545 - projects/bhyve_npt_pmap/sys/amd64/vmm/intel Message-ID: <201307030643.r636h65s058541@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: neel Date: Wed Jul 3 06:43:06 2013 New Revision: 252545 URL: http://svnweb.freebsd.org/changeset/base/252545 Log: There is no need to assign a VPID to a virtual machine since we are using nested page tables. All mappings created in the VMX non-root mode are tagged with the EP4TA which is guaranteed to be unique for each virtual machine. This makes the use of VPIDs redundant so get rid of them. 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 Wed Jul 3 06:23:46 2013 (r252544) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/intel/ept.c Wed Jul 3 06:43:06 2013 (r252545) @@ -382,11 +382,14 @@ invept_single_context(void *arg) } void -ept_invalidate_mappings(u_long pml4ept) +ept_invalidate_mappings(u_long pml4ept, int allcpus) { struct invept_desc invept_desc = { 0 }; invept_desc.eptp = EPTP(pml4ept); - smp_rendezvous(NULL, invept_single_context, NULL, &invept_desc); + if (allcpus) + smp_rendezvous(NULL, invept_single_context, NULL, &invept_desc); + else + invept_single_context(&invept_desc); } Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/intel/ept.h ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/intel/ept.h Wed Jul 3 06:23:46 2013 (r252544) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/intel/ept.h Wed Jul 3 06:43:06 2013 (r252545) @@ -38,6 +38,6 @@ int ept_init(void); int ept_vmmmap_set(void *arg, vm_paddr_t gpa, vm_paddr_t hpa, size_t length, vm_memattr_t attr, int prot, boolean_t allow_superpage_mappings); vm_paddr_t ept_vmmmap_get(void *arg, vm_paddr_t gpa); -void ept_invalidate_mappings(u_long ept_pml4); +void ept_invalidate_mappings(u_long ept_pml4, int allcpus); void ept_vmcleanup(struct vmx *vmx); #endif Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmcs.c ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmcs.c Wed Jul 3 06:23:46 2013 (r252544) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmcs.c Wed Jul 3 06:43:06 2013 (r252545) @@ -321,7 +321,7 @@ vmcs_set_defaults(struct vmcs *vmcs, u_long host_rip, u_long host_rsp, u_long ept_pml4, 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) + uint32_t entry_ctls, u_long msr_bitmap) { int error, codesel, datasel, tsssel; u_long cr0, cr4, efer; @@ -436,10 +436,6 @@ vmcs_set_defaults(struct vmcs *vmcs, if ((error = vmwrite(VMCS_EPTP, eptp)) != 0) goto done; - /* vpid */ - if ((error = vmwrite(VMCS_VPID, vpid)) != 0) - goto done; - /* msr bitmap */ if ((error = vmwrite(VMCS_MSR_BITMAP, msr_bitmap)) != 0) goto done; @@ -494,7 +490,6 @@ DB_SHOW_COMMAND(vmcs, db_show_vmcs) return; } db_printf("VMCS: %jx\n", cur_vmcs); - db_printf("VPID: %lu\n", vmcs_read(VMCS_VPID)); db_printf("Activity: "); val = vmcs_read(VMCS_GUEST_ACTIVITY); switch (val) { Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmcs.h ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmcs.h Wed Jul 3 06:23:46 2013 (r252544) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmcs.h Wed Jul 3 06:43:06 2013 (r252545) @@ -50,8 +50,7 @@ int vmcs_set_defaults(struct vmcs *vmcs, u_long ept_pml4, 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); + uint32_t entry_ctls, u_long msr_bitmap); int vmcs_getreg(struct vmcs *vmcs, int running, int ident, uint64_t *rv); int vmcs_setreg(struct vmcs *vmcs, int running, int ident, uint64_t val); int vmcs_getdesc(struct vmcs *vmcs, int ident, Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmx.c ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmx.c Wed Jul 3 06:23:46 2013 (r252544) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmx.c Wed Jul 3 06:43:06 2013 (r252545) @@ -138,8 +138,6 @@ SYSCTL_ULONG(_hw_vmm_vmx, OID_AUTO, cr4_ SYSCTL_ULONG(_hw_vmm_vmx, OID_AUTO, cr4_zeros_mask, CTLFLAG_RD, &cr4_zeros_mask, 0, NULL); -static volatile u_int nextvpid; - static int vmx_no_patmsr; static int vmx_initialized; @@ -400,7 +398,6 @@ msr_save_area_init(struct msr_entry *g_a static void vmx_disable(void *arg __unused) { - struct invvpid_desc invvpid_desc = { 0 }; struct invept_desc invept_desc = { 0 }; if (vmxon_enabled[curcpu]) { @@ -411,7 +408,6 @@ vmx_disable(void *arg __unused) * caching structures. This prevents potential retention of * cached information in the TLB between distinct VMX episodes. */ - invvpid(INVVPID_TYPE_ALL_CONTEXTS, invvpid_desc); invept(INVEPT_TYPE_ALL_CONTEXTS, invept_desc); vmxoff(); } @@ -489,12 +485,6 @@ vmx_init(void) return (error); } - /* Check support for VPID */ - error = vmx_set_ctlreg(MSR_VMX_PROCBASED_CTLS2, MSR_VMX_PROCBASED_CTLS2, - PROCBASED2_ENABLE_VPID, 0, &tmp); - if (error == 0) - procbased_ctls2 |= PROCBASED2_ENABLE_VPID; - /* Check support for pin-based VM-execution controls */ error = vmx_set_ctlreg(MSR_VMX_PINBASED_CTLS, MSR_VMX_TRUE_PINBASED_CTLS, @@ -615,37 +605,6 @@ vmx_init(void) return (0); } -/* - * If this processor does not support VPIDs then simply return 0. - * - * Otherwise generate the next value of VPID to use. Any value is alright - * as long as it is non-zero. - * - * We always execute in VMX non-root context with EPT enabled. Thus all - * combined mappings are tagged with the (EP4TA, VPID, PCID) tuple. This - * in turn means that multiple VMs can share the same VPID as long as - * they have distinct EPT page tables. - * - * XXX - * We should optimize this so that it returns VPIDs that are not in - * use. Then we will not unnecessarily invalidate mappings in - * vmx_set_pcpu_defaults() just because two or more vcpus happen to - * use the same 'vpid'. - */ -static uint16_t -vmx_vpid(void) -{ - uint16_t vpid = 0; - - if ((procbased_ctls2 & PROCBASED2_ENABLE_VPID) != 0) { - do { - vpid = atomic_fetchadd_int(&nextvpid, 1); - } while (vpid == 0); - } - - return (vpid); -} - static int vmx_setup_cr_shadow(int which, struct vmcs *vmcs) { @@ -683,7 +642,6 @@ vmx_setup_cr_shadow(int which, struct vm static void * vmx_vminit(struct vm *vm) { - uint16_t vpid; int i, error, guest_msr_count; struct vmx *vmx; @@ -700,10 +658,9 @@ vmx_vminit(struct vm *vm) * VMX transitions are not required to invalidate any guest physical * mappings. So, it may be possible for stale guest physical mappings * to be present in the processor TLBs. - * - * Combined mappings for this EP4TA are also invalidated for all VPIDs. */ - ept_invalidate_mappings(vtophys(vmx->pml4ept)); + vmx->eptphys = vtophys(vmx->pml4ept); + ept_invalidate_mappings(vmx->eptphys, 1); msr_bitmap_initialize(vmx->msr_bitmap); @@ -754,8 +711,6 @@ vmx_vminit(struct vm *vm) error, i); } - vpid = vmx_vpid(); - error = vmcs_set_defaults(&vmx->vmcs[i], (u_long)vmx_longjmp, (u_long)&vmx->ctx[i], @@ -764,8 +719,7 @@ vmx_vminit(struct vm *vm) procbased_ctls, procbased_ctls2, exit_ctls, entry_ctls, - vtophys(vmx->msr_bitmap), - vpid); + vtophys(vmx->msr_bitmap)); if (error != 0) panic("vmx_vminit: vmcs_set_defaults error %d", error); @@ -774,7 +728,6 @@ vmx_vminit(struct vm *vm) vmx->cap[i].proc_ctls = procbased_ctls; vmx->state[i].lastcpu = -1; - vmx->state[i].vpid = vpid; msr_save_area_init(vmx->guest_msrs[i], &guest_msr_count); @@ -843,7 +796,6 @@ vmx_set_pcpu_defaults(struct vmx *vmx, i { int error, lastcpu; struct vmxstate *vmxstate; - struct invvpid_desc invvpid_desc = { 0 }; vmxstate = &vmx->state[vcpu]; lastcpu = vmxstate->lastcpu; @@ -869,24 +821,16 @@ vmx_set_pcpu_defaults(struct vmx *vmx, i goto done; /* - * If we are using VPIDs then invalidate all mappings tagged with 'vpid' + * Invalidate all mappings tagged with this EP4TA. * * We do this because this vcpu was executing on a different host - * cpu when it last ran. We do not track whether it invalidated - * mappings associated with its 'vpid' during that run. So we must - * assume that the mappings associated with 'vpid' on 'curcpu' are - * stale and invalidate them. + * cpu when it last ran. Thus the mappings on this cpu might be + * potentially out-of-date and therefore must be invalidated. * * Note that we incur this penalty only when the scheduler chooses to * move the thread associated with this vcpu between host cpus. - * - * Note also that this will invalidate mappings tagged with 'vpid' - * for "all" EP4TAs. */ - if (vmxstate->vpid != 0) { - invvpid_desc.vpid = vmxstate->vpid; - invvpid(INVVPID_TYPE_SINGLE_CONTEXT, invvpid_desc); - } + ept_invalidate_mappings(vmx->eptphys, 0); done: return (error); } Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmx.h ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmx.h Wed Jul 3 06:23:46 2013 (r252544) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmx.h Wed Jul 3 06:43:06 2013 (r252545) @@ -77,7 +77,6 @@ struct vmxcap { struct vmxstate { int lastcpu; /* host cpu that this 'vcpu' last ran on */ - uint16_t vpid; }; /* virtual machine softc */ @@ -89,6 +88,7 @@ struct vmx { struct vmxctx ctx[VM_MAXCPU]; struct vmxcap cap[VM_MAXCPU]; struct vmxstate state[VM_MAXCPU]; + vm_paddr_t eptphys; /* physical addr of pml4ept */ struct vm *vm; }; CTASSERT((offsetof(struct vmx, pml4ept) & PAGE_MASK) == 0);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201307030643.r636h65s058541>