Changeset 51643 in vbox for trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp
- Timestamp:
- Jun 18, 2014 11:06:06 AM (11 years ago)
- svn:sync-xref-src-repo-rev:
- 94404
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp
r51244 r51643 34 34 #include <VBox/vmm/selm.h> 35 35 #include <VBox/vmm/tm.h> 36 #include <VBox/vmm/gim.h> 36 37 #ifdef VBOX_WITH_REM 37 38 # include <VBox/vmm/rem.h> … … 336 337 * Internal Functions * 337 338 *******************************************************************************/ 338 static void hmR0VmxFlushEpt(PVMCPU pVCpu, VMX _FLUSH_EPT enmFlush);339 static void hmR0VmxFlushVpid(PVM pVM, PVMCPU pVCpu, VMX _FLUSH_VPID enmFlush, RTGCPTR GCPtr);339 static void hmR0VmxFlushEpt(PVMCPU pVCpu, VMXFLUSHEPT enmFlush); 340 static void hmR0VmxFlushVpid(PVM pVM, PVMCPU pVCpu, VMXFLUSHVPID enmFlush, RTGCPTR GCPtr); 340 341 static int hmR0VmxInjectEventVmcs(PVMCPU pVCpu, PCPUMCTX pMixedCtx, uint64_t u64IntInfo, uint32_t cbInstr, 341 342 uint32_t u32ErrCode, RTGCUINTREG GCPtrFaultAddress, uint32_t *puIntState); … … 1067 1068 if (pMsrs->u64EptVpidCaps & MSR_IA32_VMX_EPT_VPID_CAP_INVEPT_ALL_CONTEXTS) 1068 1069 { 1069 hmR0VmxFlushEpt(NULL /* pVCpu */, VMX _FLUSH_EPT_ALL_CONTEXTS);1070 hmR0VmxFlushEpt(NULL /* pVCpu */, VMXFLUSHEPT_ALL_CONTEXTS); 1070 1071 pCpu->fFlushAsidBeforeUse = false; 1071 1072 } … … 1698 1699 * @remarks Can be called with interrupts disabled. 1699 1700 */ 1700 static void hmR0VmxFlushEpt(PVMCPU pVCpu, VMX _FLUSH_EPT enmFlush)1701 static void hmR0VmxFlushEpt(PVMCPU pVCpu, VMXFLUSHEPT enmFlush) 1701 1702 { 1702 1703 uint64_t au64Descriptor[2]; 1703 if (enmFlush == VMX _FLUSH_EPT_ALL_CONTEXTS)1704 if (enmFlush == VMXFLUSHEPT_ALL_CONTEXTS) 1704 1705 au64Descriptor[0] = 0; 1705 1706 else … … 1734 1735 * @remarks Can be called with interrupts disabled. 1735 1736 */ 1736 static void hmR0VmxFlushVpid(PVM pVM, PVMCPU pVCpu, VMX _FLUSH_VPID enmFlush, RTGCPTR GCPtr)1737 static void hmR0VmxFlushVpid(PVM pVM, PVMCPU pVCpu, VMXFLUSHVPID enmFlush, RTGCPTR GCPtr) 1737 1738 { 1738 1739 NOREF(pVM); … … 1741 1742 1742 1743 uint64_t au64Descriptor[2]; 1743 if (enmFlush == VMX _FLUSH_VPID_ALL_CONTEXTS)1744 if (enmFlush == VMXFLUSHVPID_ALL_CONTEXTS) 1744 1745 { 1745 1746 au64Descriptor[0] = 0; … … 1795 1796 if (pVM->hm.s.vmx.Msrs.u64EptVpidCaps & MSR_IA32_VMX_EPT_VPID_CAP_INVVPID_INDIV_ADDR) 1796 1797 { 1797 hmR0VmxFlushVpid(pVM, pVCpu, VMX _FLUSH_VPID_INDIV_ADDR, GCVirt);1798 hmR0VmxFlushVpid(pVM, pVCpu, VMXFLUSHVPID_INDIV_ADDR, GCVirt); 1798 1799 STAM_COUNTER_INC(&pVCpu->hm.s.StatFlushTlbInvlpgVirt); 1799 1800 } … … 1961 1962 { 1962 1963 for (uint32_t i = 0; i < pVCpu->hm.s.TlbShootdown.cPages; i++) 1963 hmR0VmxFlushVpid(pVM, pVCpu, VMX _FLUSH_VPID_INDIV_ADDR, pVCpu->hm.s.TlbShootdown.aPages[i]);1964 hmR0VmxFlushVpid(pVM, pVCpu, VMXFLUSHVPID_INDIV_ADDR, pVCpu->hm.s.TlbShootdown.aPages[i]); 1964 1965 } 1965 1966 else … … 2120 2121 if (pCpu->fFlushAsidBeforeUse) 2121 2122 { 2122 if (pVM->hm.s.vmx.enmFlushVpid == VMX _FLUSH_VPID_SINGLE_CONTEXT)2123 hmR0VmxFlushVpid(pVM, pVCpu, VMX _FLUSH_VPID_SINGLE_CONTEXT, 0 /* GCPtr */);2124 else if (pVM->hm.s.vmx.enmFlushVpid == VMX _FLUSH_VPID_ALL_CONTEXTS)2123 if (pVM->hm.s.vmx.enmFlushVpid == VMXFLUSHVPID_SINGLE_CONTEXT) 2124 hmR0VmxFlushVpid(pVM, pVCpu, VMXFLUSHVPID_SINGLE_CONTEXT, 0 /* GCPtr */); 2125 else if (pVM->hm.s.vmx.enmFlushVpid == VMXFLUSHVPID_ALL_CONTEXTS) 2125 2126 { 2126 hmR0VmxFlushVpid(pVM, pVCpu, VMX _FLUSH_VPID_ALL_CONTEXTS, 0 /* GCPtr */);2127 hmR0VmxFlushVpid(pVM, pVCpu, VMXFLUSHVPID_ALL_CONTEXTS, 0 /* GCPtr */); 2127 2128 pCpu->fFlushAsidBeforeUse = false; 2128 2129 } … … 2151 2152 { 2152 2153 for (uint32_t i = 0; i < pVCpu->hm.s.TlbShootdown.cPages; i++) 2153 hmR0VmxFlushVpid(pVM, pVCpu, VMX _FLUSH_VPID_INDIV_ADDR, pVCpu->hm.s.TlbShootdown.aPages[i]);2154 hmR0VmxFlushVpid(pVM, pVCpu, VMXFLUSHVPID_INDIV_ADDR, pVCpu->hm.s.TlbShootdown.aPages[i]); 2154 2155 } 2155 2156 else … … 2226 2227 { 2227 2228 if (pVM->hm.s.vmx.Msrs.u64EptVpidCaps & MSR_IA32_VMX_EPT_VPID_CAP_INVEPT_SINGLE_CONTEXT) 2228 pVM->hm.s.vmx.enmFlushEpt = VMX _FLUSH_EPT_SINGLE_CONTEXT;2229 pVM->hm.s.vmx.enmFlushEpt = VMXFLUSHEPT_SINGLE_CONTEXT; 2229 2230 else if (pVM->hm.s.vmx.Msrs.u64EptVpidCaps & MSR_IA32_VMX_EPT_VPID_CAP_INVEPT_ALL_CONTEXTS) 2230 pVM->hm.s.vmx.enmFlushEpt = VMX _FLUSH_EPT_ALL_CONTEXTS;2231 pVM->hm.s.vmx.enmFlushEpt = VMXFLUSHEPT_ALL_CONTEXTS; 2231 2232 else 2232 2233 { 2233 2234 /* Shouldn't happen. EPT is supported but no suitable flush-types supported. */ 2234 pVM->hm.s.vmx.enmFlushEpt = VMX _FLUSH_EPT_NOT_SUPPORTED;2235 pVM->hm.s.vmx.enmFlushEpt = VMXFLUSHEPT_NOT_SUPPORTED; 2235 2236 return VERR_HM_UNSUPPORTED_CPU_FEATURE_COMBO; 2236 2237 } … … 2240 2241 { 2241 2242 LogRel(("hmR0VmxSetupTaggedTlb: Unsupported EPTP memory type %#x.\n", pVM->hm.s.vmx.Msrs.u64EptVpidCaps)); 2242 pVM->hm.s.vmx.enmFlushEpt = VMX _FLUSH_EPT_NOT_SUPPORTED;2243 pVM->hm.s.vmx.enmFlushEpt = VMXFLUSHEPT_NOT_SUPPORTED; 2243 2244 return VERR_HM_UNSUPPORTED_CPU_FEATURE_COMBO; 2244 2245 } … … 2247 2248 { 2248 2249 /* Shouldn't happen. EPT is supported but INVEPT instruction is not supported. */ 2249 pVM->hm.s.vmx.enmFlushEpt = VMX _FLUSH_EPT_NOT_SUPPORTED;2250 pVM->hm.s.vmx.enmFlushEpt = VMXFLUSHEPT_NOT_SUPPORTED; 2250 2251 return VERR_HM_UNSUPPORTED_CPU_FEATURE_COMBO; 2251 2252 } … … 2260 2261 { 2261 2262 if (pVM->hm.s.vmx.Msrs.u64EptVpidCaps & MSR_IA32_VMX_EPT_VPID_CAP_INVVPID_SINGLE_CONTEXT) 2262 pVM->hm.s.vmx.enmFlushVpid = VMX _FLUSH_VPID_SINGLE_CONTEXT;2263 pVM->hm.s.vmx.enmFlushVpid = VMXFLUSHVPID_SINGLE_CONTEXT; 2263 2264 else if (pVM->hm.s.vmx.Msrs.u64EptVpidCaps & MSR_IA32_VMX_EPT_VPID_CAP_INVVPID_ALL_CONTEXTS) 2264 pVM->hm.s.vmx.enmFlushVpid = VMX _FLUSH_VPID_ALL_CONTEXTS;2265 pVM->hm.s.vmx.enmFlushVpid = VMXFLUSHVPID_ALL_CONTEXTS; 2265 2266 else 2266 2267 { … … 2270 2271 if (pVM->hm.s.vmx.Msrs.u64EptVpidCaps & MSR_IA32_VMX_EPT_VPID_CAP_INVVPID_SINGLE_CONTEXT_RETAIN_GLOBALS) 2271 2272 LogRel(("hmR0VmxSetupTaggedTlb: Only SINGLE_CONTEXT_RETAIN_GLOBALS supported. Ignoring VPID.\n")); 2272 pVM->hm.s.vmx.enmFlushVpid = VMX _FLUSH_VPID_NOT_SUPPORTED;2273 pVM->hm.s.vmx.enmFlushVpid = VMXFLUSHVPID_NOT_SUPPORTED; 2273 2274 pVM->hm.s.vmx.fVpid = false; 2274 2275 } … … 2278 2279 /* Shouldn't happen. VPID is supported but INVVPID is not supported by the CPU. Ignore VPID capability. */ 2279 2280 Log4(("hmR0VmxSetupTaggedTlb: VPID supported without INVEPT support. Ignoring VPID.\n")); 2280 pVM->hm.s.vmx.enmFlushVpid = VMX _FLUSH_VPID_NOT_SUPPORTED;2281 pVM->hm.s.vmx.enmFlushVpid = VMXFLUSHVPID_NOT_SUPPORTED; 2281 2282 pVM->hm.s.vmx.fVpid = false; 2282 2283 } … … 2728 2729 2729 2730 /* Initialize these always, see hmR3InitFinalizeR0().*/ 2730 pVM->hm.s.vmx.enmFlushEpt = VMX _FLUSH_EPT_NONE;2731 pVM->hm.s.vmx.enmFlushVpid = VMX _FLUSH_VPID_NONE;2731 pVM->hm.s.vmx.enmFlushEpt = VMXFLUSHEPT_NONE; 2732 pVM->hm.s.vmx.enmFlushVpid = VMXFLUSHVPID_NONE; 2732 2733 2733 2734 /* Setup the tagged-TLB flush handlers. */ … … 5565 5566 int rc = VERR_INTERNAL_ERROR_5; 5566 5567 bool fOffsettedTsc = false; 5568 bool fParavirtTsc = false; 5567 5569 PVM pVM = pVCpu->CTX_SUFF(pVM); 5568 5570 if (pVM->hm.s.vmx.fUsePreemptTimer) 5569 5571 { 5570 uint64_t cTicksToDeadline = TMCpuTickGetDeadlineAndTscOffset(pVCpu, &fOffsettedTsc, &pVCpu->hm.s.vmx.u64TSCOffset); 5572 uint64_t cTicksToDeadline = TMCpuTickGetDeadlineAndTscOffset(pVCpu, &fOffsettedTsc, &fParavirtTsc, 5573 &pVCpu->hm.s.vmx.u64TSCOffset); 5571 5574 5572 5575 /* Make sure the returned values have sane upper and lower boundaries. */ … … 5580 5583 } 5581 5584 else 5582 fOffsettedTsc = TMCpuTickCanUseRealTSC(pVCpu, &pVCpu->hm.s.vmx.u64TSCOffset); 5585 fOffsettedTsc = TMCpuTickCanUseRealTSC(pVCpu, &pVCpu->hm.s.vmx.u64TSCOffset, &fParavirtTsc); 5586 5587 if (fParavirtTsc) 5588 { 5589 uint64_t const u64CurTsc = ASMReadTSC(); 5590 uint64_t const u64LastTick = TMCpuTickGetLastSeen(pVCpu); 5591 if (u64CurTsc + pVCpu->hm.s.vmx.u64TSCOffset < u64LastTick) 5592 { 5593 pVCpu->hm.s.vmx.u64TSCOffset = (u64LastTick - u64CurTsc); 5594 STAM_COUNTER_INC(&pVCpu->hm.s.StatTscOffsetAdjusted); 5595 } 5596 5597 Assert(u64CurTsc + pVCpu->hm.s.vmx.u64TSCOffset >= u64LastTick); 5598 rc = GIMR0UpdateParavirtTsc(pVM, pVCpu->hm.s.vmx.u64TSCOffset); 5599 if (RT_SUCCESS(rc)) 5600 { 5601 /* Note: VMX_VMCS_CTRL_PROC_EXEC_RDTSC_EXIT takes precedence over TSC_OFFSET, applies to RDTSCP too. */ 5602 rc = VMXWriteVmcs64(VMX_VMCS64_CTRL_TSC_OFFSET_FULL, 0); AssertRC(rc); 5603 5604 pVCpu->hm.s.vmx.u32ProcCtls &= ~VMX_VMCS_CTRL_PROC_EXEC_RDTSC_EXIT; 5605 rc = VMXWriteVmcs32(VMX_VMCS32_CTRL_PROC_EXEC, pVCpu->hm.s.vmx.u32ProcCtls); AssertRC(rc); 5606 STAM_COUNTER_INC(&pVCpu->hm.s.StatTscParavirt); 5607 return; 5608 } 5609 /* else: Shouldn't really fail. If it does, fallback to offsetted TSC mode. */ 5610 } 5583 5611 5584 5612 if (fOffsettedTsc) … … 10358 10386 ("hmR0VmxExitRdmsr: failed, invalid error code %Rrc\n", rc)); 10359 10387 STAM_COUNTER_INC(&pVCpu->hm.s.StatExitRdmsr); 10360 10361 10388 if (RT_LIKELY(rc == VINF_SUCCESS)) 10362 10389 {
Note:
See TracChangeset
for help on using the changeset viewer.