Changeset 72855 in vbox for trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp
- Timestamp:
- Jul 4, 2018 8:36:12 AM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp
r72852 r72855 371 371 * Internal Functions * 372 372 *********************************************************************************************************************************/ 373 static void hmR0VmxFlushEpt(PVMCPU pVCpu, VMX FLUSHEPT enmFlush);374 static void hmR0VmxFlushVpid(PVMCPU pVCpu, VMX FLUSHVPID enmFlush, RTGCPTR GCPtr);373 static void hmR0VmxFlushEpt(PVMCPU pVCpu, VMXTLBFLUSHEPT enmTlbFlush); 374 static void hmR0VmxFlushVpid(PVMCPU pVCpu, VMXTLBFLUSHVPID enmTlbFlush, RTGCPTR GCPtr); 375 375 static void hmR0VmxClearIntNmiWindowsVmcs(PVMCPU pVCpu); 376 376 static int hmR0VmxImportGuestState(PVMCPU pVCpu, uint64_t fWhat); … … 1122 1122 if (pMsrs->u64EptVpidCaps & MSR_IA32_VMX_EPT_VPID_CAP_INVEPT_ALL_CONTEXTS) 1123 1123 { 1124 hmR0VmxFlushEpt(NULL /* pVCpu */, VMX FLUSHEPT_ALL_CONTEXTS);1124 hmR0VmxFlushEpt(NULL /* pVCpu */, VMXTLBFLUSHEPT_ALL_CONTEXTS); 1125 1125 pHostCpu->fFlushAsidBeforeUse = false; 1126 1126 } … … 1748 1748 * 1749 1749 * @returns VBox status code. 1750 * @param pVCpu The cross context virtual CPU structure of the calling1751 * EMT. Can be NULL depending on @a enmFlush.1752 * @param enm FlushType of flush.1750 * @param pVCpu The cross context virtual CPU structure of the calling 1751 * EMT. Can be NULL depending on @a enmTlbFlush. 1752 * @param enmTlbFlush Type of flush. 1753 1753 * 1754 1754 * @remarks Caller is responsible for making sure this function is called only 1755 * when NestedPaging is supported and providing @a enm Flush that is1755 * when NestedPaging is supported and providing @a enmTlbFlush that is 1756 1756 * supported by the CPU. 1757 1757 * @remarks Can be called with interrupts disabled. 1758 1758 */ 1759 static void hmR0VmxFlushEpt(PVMCPU pVCpu, VMX FLUSHEPT enmFlush)1759 static void hmR0VmxFlushEpt(PVMCPU pVCpu, VMXTLBFLUSHEPT enmTlbFlush) 1760 1760 { 1761 1761 uint64_t au64Descriptor[2]; 1762 if (enm Flush == VMXFLUSHEPT_ALL_CONTEXTS)1762 if (enmTlbFlush == VMXTLBFLUSHEPT_ALL_CONTEXTS) 1763 1763 au64Descriptor[0] = 0; 1764 1764 else … … 1769 1769 au64Descriptor[1] = 0; /* MBZ. Intel spec. 33.3 "VMX Instructions" */ 1770 1770 1771 int rc = VMXR0InvEPT(enmFlush, &au64Descriptor[0]); 1772 AssertMsg(rc == VINF_SUCCESS, ("VMXR0InvEPT %#x %RGv failed with %Rrc\n", enmFlush, pVCpu ? pVCpu->hm.s.vmx.HCPhysEPTP : 0, 1773 rc)); 1771 int rc = VMXR0InvEPT(enmTlbFlush, &au64Descriptor[0]); 1772 AssertMsg(rc == VINF_SUCCESS, 1773 ("VMXR0InvEPT %#x %RGv failed with %Rrc\n", enmTlbFlush, pVCpu ? pVCpu->hm.s.vmx.HCPhysEPTP : 0, rc)); 1774 1774 1775 if ( RT_SUCCESS(rc) 1775 1776 && pVCpu) 1776 {1777 1777 STAM_COUNTER_INC(&pVCpu->hm.s.StatFlushNestedPaging); 1778 }1779 1778 } 1780 1779 … … 1784 1783 * 1785 1784 * @returns VBox status code. 1786 * @param pVCpu The cross context virtual CPU structure of the calling1787 * EMT. Can be NULL depending on @a enmFlush.1788 * @param enm FlushType of flush.1789 * @param GCPtr Virtual address of the page to flush (can be 0 depending1790 * on @a enmFlush).1785 * @param pVCpu The cross context virtual CPU structure of the calling 1786 * EMT. Can be NULL depending on @a enmTlbFlush. 1787 * @param enmTlbFlush Type of flush. 1788 * @param GCPtr Virtual address of the page to flush (can be 0 depending 1789 * on @a enmTlbFlush). 1791 1790 * 1792 1791 * @remarks Can be called with interrupts disabled. 1793 1792 */ 1794 static void hmR0VmxFlushVpid(PVMCPU pVCpu, VMX FLUSHVPID enmFlush, RTGCPTR GCPtr)1793 static void hmR0VmxFlushVpid(PVMCPU pVCpu, VMXTLBFLUSHVPID enmTlbFlush, RTGCPTR GCPtr) 1795 1794 { 1796 1795 Assert(pVCpu->CTX_SUFF(pVM)->hm.s.vmx.fVpid); 1797 1796 1798 1797 uint64_t au64Descriptor[2]; 1799 if (enm Flush == VMXFLUSHVPID_ALL_CONTEXTS)1798 if (enmTlbFlush == VMXTLBFLUSHVPID_ALL_CONTEXTS) 1800 1799 { 1801 1800 au64Descriptor[0] = 0; … … 1811 1810 } 1812 1811 1813 int rc = VMXR0InvVPID(enmFlush, &au64Descriptor[0]); 1814 AssertMsg(rc == VINF_SUCCESS, ("VMXR0InvVPID %#x %u %RGv failed with %Rrc\n", enmFlush, 1815 pVCpu ? pVCpu->hm.s.uCurrentAsid : 0, GCPtr, rc)); 1812 int rc = VMXR0InvVPID(enmTlbFlush, &au64Descriptor[0]); 1813 AssertMsg(rc == VINF_SUCCESS, 1814 ("VMXR0InvVPID %#x %u %RGv failed with %Rrc\n", enmTlbFlush, pVCpu ? pVCpu->hm.s.uCurrentAsid : 0, GCPtr, rc)); 1815 1816 1816 if ( RT_SUCCESS(rc) 1817 1817 && pVCpu) 1818 {1819 1818 STAM_COUNTER_INC(&pVCpu->hm.s.StatFlushAsid); 1820 }1821 1819 NOREF(rc); 1822 1820 } … … 1863 1861 if (fVpidFlush) 1864 1862 { 1865 hmR0VmxFlushVpid(pVCpu, VMX FLUSHVPID_INDIV_ADDR, GCVirt);1863 hmR0VmxFlushVpid(pVCpu, VMXTLBFLUSHVPID_INDIV_ADDR, GCVirt); 1866 1864 STAM_COUNTER_INC(&pVCpu->hm.s.StatFlushTlbInvlpgVirt); 1867 1865 } … … 1961 1959 * invalidated. We don't need to flush-by-VPID here as flushing by EPT covers it. See @bugref{6568}. 1962 1960 */ 1963 hmR0VmxFlushEpt(pVCpu, pVM->hm.s.vmx.enm FlushEpt);1961 hmR0VmxFlushEpt(pVCpu, pVM->hm.s.vmx.enmTlbFlushEpt); 1964 1962 STAM_COUNTER_INC(&pVCpu->hm.s.StatFlushTlbWorldSwitch); 1965 1963 HMVMX_SET_TAGGED_TLB_FLUSHED(); … … 1979 1977 * See Intel spec. 28.3.2 "Creating and Using Cached Translation Information". 1980 1978 */ 1981 hmR0VmxFlushEpt(pVCpu, pVM->hm.s.vmx.enm FlushEpt);1979 hmR0VmxFlushEpt(pVCpu, pVM->hm.s.vmx.enmTlbFlushEpt); 1982 1980 STAM_COUNTER_INC(&pVCpu->hm.s.StatFlushTlb); 1983 1981 HMVMX_SET_TAGGED_TLB_FLUSHED(); … … 2045 2043 if (pVCpu->hm.s.fForceTLBFlush) 2046 2044 { 2047 hmR0VmxFlushEpt(pVCpu, pVCpu->CTX_SUFF(pVM)->hm.s.vmx.enm FlushEpt);2045 hmR0VmxFlushEpt(pVCpu, pVCpu->CTX_SUFF(pVM)->hm.s.vmx.enmTlbFlushEpt); 2048 2046 pVCpu->hm.s.fForceTLBFlush = false; 2049 2047 } … … 2111 2109 if (pCpu->fFlushAsidBeforeUse) 2112 2110 { 2113 if (pVM->hm.s.vmx.enm FlushVpid == VMXFLUSHVPID_SINGLE_CONTEXT)2114 hmR0VmxFlushVpid(pVCpu, VMX FLUSHVPID_SINGLE_CONTEXT, 0 /* GCPtr */);2115 else if (pVM->hm.s.vmx.enm FlushVpid == VMXFLUSHVPID_ALL_CONTEXTS)2111 if (pVM->hm.s.vmx.enmTlbFlushVpid == VMXTLBFLUSHVPID_SINGLE_CONTEXT) 2112 hmR0VmxFlushVpid(pVCpu, VMXTLBFLUSHVPID_SINGLE_CONTEXT, 0 /* GCPtr */); 2113 else if (pVM->hm.s.vmx.enmTlbFlushVpid == VMXTLBFLUSHVPID_ALL_CONTEXTS) 2116 2114 { 2117 hmR0VmxFlushVpid(pVCpu, VMX FLUSHVPID_ALL_CONTEXTS, 0 /* GCPtr */);2115 hmR0VmxFlushVpid(pVCpu, VMXTLBFLUSHVPID_ALL_CONTEXTS, 0 /* GCPtr */); 2118 2116 pCpu->fFlushAsidBeforeUse = false; 2119 2117 } … … 2151 2149 #endif 2152 2150 PVM pVM = pVCpu->CTX_SUFF(pVM); 2153 switch (pVM->hm.s.vmx. uFlushTaggedTlb)2154 { 2155 case HMVMX_FLUSH_TAGGED_TLB_EPT_VPID: hmR0VmxFlushTaggedTlbBoth(pVCpu, pCpu); break;2156 case HMVMX_FLUSH_TAGGED_TLB_EPT: hmR0VmxFlushTaggedTlbEpt(pVCpu, pCpu); break;2157 case HMVMX_FLUSH_TAGGED_TLB_VPID: hmR0VmxFlushTaggedTlbVpid(pVCpu, pCpu); break;2158 case HMVMX_FLUSH_TAGGED_TLB_NONE: hmR0VmxFlushTaggedTlbNone(pVCpu, pCpu); break;2151 switch (pVM->hm.s.vmx.enmTlbFlushType) 2152 { 2153 case VMXTLBFLUSHTYPE_EPT_VPID: hmR0VmxFlushTaggedTlbBoth(pVCpu, pCpu); break; 2154 case VMXTLBFLUSHTYPE_EPT: hmR0VmxFlushTaggedTlbEpt(pVCpu, pCpu); break; 2155 case VMXTLBFLUSHTYPE_VPID: hmR0VmxFlushTaggedTlbVpid(pVCpu, pCpu); break; 2156 case VMXTLBFLUSHTYPE_NONE: hmR0VmxFlushTaggedTlbNone(pVCpu, pCpu); break; 2159 2157 default: 2160 2158 AssertMsgFailed(("Invalid flush-tag function identifier\n")); … … 2184 2182 { 2185 2183 if (pVM->hm.s.vmx.Msrs.u64EptVpidCaps & MSR_IA32_VMX_EPT_VPID_CAP_INVEPT_SINGLE_CONTEXT) 2186 pVM->hm.s.vmx.enm FlushEpt = VMXFLUSHEPT_SINGLE_CONTEXT;2184 pVM->hm.s.vmx.enmTlbFlushEpt = VMXTLBFLUSHEPT_SINGLE_CONTEXT; 2187 2185 else if (pVM->hm.s.vmx.Msrs.u64EptVpidCaps & MSR_IA32_VMX_EPT_VPID_CAP_INVEPT_ALL_CONTEXTS) 2188 pVM->hm.s.vmx.enm FlushEpt = VMXFLUSHEPT_ALL_CONTEXTS;2186 pVM->hm.s.vmx.enmTlbFlushEpt = VMXTLBFLUSHEPT_ALL_CONTEXTS; 2189 2187 else 2190 2188 { 2191 2189 /* Shouldn't happen. EPT is supported but no suitable flush-types supported. */ 2192 pVM->hm.s.vmx.enm FlushEpt = VMXFLUSHEPT_NOT_SUPPORTED;2190 pVM->hm.s.vmx.enmTlbFlushEpt = VMXTLBFLUSHEPT_NOT_SUPPORTED; 2193 2191 pVM->aCpus[0].hm.s.u32HMError = VMX_UFC_EPT_FLUSH_TYPE_UNSUPPORTED; 2194 2192 return VERR_HM_UNSUPPORTED_CPU_FEATURE_COMBO; … … 2198 2196 if (RT_UNLIKELY(!(pVM->hm.s.vmx.Msrs.u64EptVpidCaps & MSR_IA32_VMX_EPT_VPID_CAP_EMT_WB))) 2199 2197 { 2200 pVM->hm.s.vmx.enm FlushEpt = VMXFLUSHEPT_NOT_SUPPORTED;2198 pVM->hm.s.vmx.enmTlbFlushEpt = VMXTLBFLUSHEPT_NOT_SUPPORTED; 2201 2199 pVM->aCpus[0].hm.s.u32HMError = VMX_UFC_EPT_MEM_TYPE_NOT_WB; 2202 2200 return VERR_HM_UNSUPPORTED_CPU_FEATURE_COMBO; … … 2206 2204 if (RT_UNLIKELY(!(pVM->hm.s.vmx.Msrs.u64EptVpidCaps & MSR_IA32_VMX_EPT_VPID_CAP_PAGE_WALK_LENGTH_4))) 2207 2205 { 2208 pVM->hm.s.vmx.enm FlushEpt = VMXFLUSHEPT_NOT_SUPPORTED;2206 pVM->hm.s.vmx.enmTlbFlushEpt = VMXTLBFLUSHEPT_NOT_SUPPORTED; 2209 2207 pVM->aCpus[0].hm.s.u32HMError = VMX_UFC_EPT_PAGE_WALK_LENGTH_UNSUPPORTED; 2210 2208 return VERR_HM_UNSUPPORTED_CPU_FEATURE_COMBO; … … 2214 2212 { 2215 2213 /* Shouldn't happen. EPT is supported but INVEPT instruction is not supported. */ 2216 pVM->hm.s.vmx.enm FlushEpt = VMXFLUSHEPT_NOT_SUPPORTED;2214 pVM->hm.s.vmx.enmTlbFlushEpt = VMXTLBFLUSHEPT_NOT_SUPPORTED; 2217 2215 pVM->aCpus[0].hm.s.u32HMError = VMX_UFC_EPT_INVEPT_UNAVAILABLE; 2218 2216 return VERR_HM_UNSUPPORTED_CPU_FEATURE_COMBO; … … 2228 2226 { 2229 2227 if (pVM->hm.s.vmx.Msrs.u64EptVpidCaps & MSR_IA32_VMX_EPT_VPID_CAP_INVVPID_SINGLE_CONTEXT) 2230 pVM->hm.s.vmx.enm FlushVpid = VMXFLUSHVPID_SINGLE_CONTEXT;2228 pVM->hm.s.vmx.enmTlbFlushVpid = VMXTLBFLUSHVPID_SINGLE_CONTEXT; 2231 2229 else if (pVM->hm.s.vmx.Msrs.u64EptVpidCaps & MSR_IA32_VMX_EPT_VPID_CAP_INVVPID_ALL_CONTEXTS) 2232 pVM->hm.s.vmx.enm FlushVpid = VMXFLUSHVPID_ALL_CONTEXTS;2230 pVM->hm.s.vmx.enmTlbFlushVpid = VMXTLBFLUSHVPID_ALL_CONTEXTS; 2233 2231 else 2234 2232 { … … 2238 2236 if (pVM->hm.s.vmx.Msrs.u64EptVpidCaps & MSR_IA32_VMX_EPT_VPID_CAP_INVVPID_SINGLE_CONTEXT_RETAIN_GLOBALS) 2239 2237 LogRelFunc(("Only SINGLE_CONTEXT_RETAIN_GLOBALS supported. Ignoring VPID.\n")); 2240 pVM->hm.s.vmx.enm FlushVpid = VMXFLUSHVPID_NOT_SUPPORTED;2238 pVM->hm.s.vmx.enmTlbFlushVpid = VMXTLBFLUSHVPID_NOT_SUPPORTED; 2241 2239 pVM->hm.s.vmx.fVpid = false; 2242 2240 } … … 2246 2244 /* Shouldn't happen. VPID is supported but INVVPID is not supported by the CPU. Ignore VPID capability. */ 2247 2245 Log4Func(("VPID supported without INVEPT support. Ignoring VPID.\n")); 2248 pVM->hm.s.vmx.enm FlushVpid = VMXFLUSHVPID_NOT_SUPPORTED;2246 pVM->hm.s.vmx.enmTlbFlushVpid = VMXTLBFLUSHVPID_NOT_SUPPORTED; 2249 2247 pVM->hm.s.vmx.fVpid = false; 2250 2248 } … … 2255 2253 */ 2256 2254 if (pVM->hm.s.fNestedPaging && pVM->hm.s.vmx.fVpid) 2257 pVM->hm.s.vmx. uFlushTaggedTlb = HMVMX_FLUSH_TAGGED_TLB_EPT_VPID;2255 pVM->hm.s.vmx.enmTlbFlushType = VMXTLBFLUSHTYPE_EPT_VPID; 2258 2256 else if (pVM->hm.s.fNestedPaging) 2259 pVM->hm.s.vmx. uFlushTaggedTlb = HMVMX_FLUSH_TAGGED_TLB_EPT;2257 pVM->hm.s.vmx.enmTlbFlushType = VMXTLBFLUSHTYPE_EPT; 2260 2258 else if (pVM->hm.s.vmx.fVpid) 2261 pVM->hm.s.vmx. uFlushTaggedTlb = HMVMX_FLUSH_TAGGED_TLB_VPID;2259 pVM->hm.s.vmx.enmTlbFlushType = VMXTLBFLUSHTYPE_VPID; 2262 2260 else 2263 pVM->hm.s.vmx. uFlushTaggedTlb = HMVMX_FLUSH_TAGGED_TLB_NONE;2261 pVM->hm.s.vmx.enmTlbFlushType = VMXTLBFLUSHTYPE_NONE; 2264 2262 return VINF_SUCCESS; 2265 2263 } … … 2734 2732 2735 2733 /* Initialize these always, see hmR3InitFinalizeR0().*/ 2736 pVM->hm.s.vmx.enm FlushEpt = VMXFLUSHEPT_NONE;2737 pVM->hm.s.vmx.enm FlushVpid = VMXFLUSHVPID_NONE;2734 pVM->hm.s.vmx.enmTlbFlushEpt = VMXTLBFLUSHEPT_NONE; 2735 pVM->hm.s.vmx.enmTlbFlushVpid = VMXTLBFLUSHVPID_NONE; 2738 2736 2739 2737 /* Setup the tagged-TLB flush handlers. */
Note:
See TracChangeset
for help on using the changeset viewer.