VirtualBox

Ignore:
Timestamp:
Jul 4, 2018 8:36:12 AM (6 years ago)
Author:
vboxsync
Message:

VMM/HM: Use enum for Tagged-TLB flush types, and related cleanup.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp

    r72852 r72855  
    371371*   Internal Functions                                                                                                           *
    372372*********************************************************************************************************************************/
    373 static void               hmR0VmxFlushEpt(PVMCPU pVCpu, VMXFLUSHEPT enmFlush);
    374 static void               hmR0VmxFlushVpid(PVMCPU pVCpu, VMXFLUSHVPID enmFlush, RTGCPTR GCPtr);
     373static void               hmR0VmxFlushEpt(PVMCPU pVCpu, VMXTLBFLUSHEPT enmTlbFlush);
     374static void               hmR0VmxFlushVpid(PVMCPU pVCpu, VMXTLBFLUSHVPID enmTlbFlush, RTGCPTR GCPtr);
    375375static void               hmR0VmxClearIntNmiWindowsVmcs(PVMCPU pVCpu);
    376376static int                hmR0VmxImportGuestState(PVMCPU pVCpu, uint64_t fWhat);
     
    11221122    if (pMsrs->u64EptVpidCaps & MSR_IA32_VMX_EPT_VPID_CAP_INVEPT_ALL_CONTEXTS)
    11231123    {
    1124         hmR0VmxFlushEpt(NULL /* pVCpu */, VMXFLUSHEPT_ALL_CONTEXTS);
     1124        hmR0VmxFlushEpt(NULL /* pVCpu */, VMXTLBFLUSHEPT_ALL_CONTEXTS);
    11251125        pHostCpu->fFlushAsidBeforeUse = false;
    11261126    }
     
    17481748 *
    17491749 * @returns VBox status code.
    1750  * @param   pVCpu       The cross context virtual CPU structure of the calling
    1751  *                      EMT.  Can be NULL depending on @a enmFlush.
    1752  * @param   enmFlush    Type 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.
    17531753 *
    17541754 * @remarks Caller is responsible for making sure this function is called only
    1755  *          when NestedPaging is supported and providing @a enmFlush that is
     1755 *          when NestedPaging is supported and providing @a enmTlbFlush that is
    17561756 *          supported by the CPU.
    17571757 * @remarks Can be called with interrupts disabled.
    17581758 */
    1759 static void hmR0VmxFlushEpt(PVMCPU pVCpu, VMXFLUSHEPT enmFlush)
     1759static void hmR0VmxFlushEpt(PVMCPU pVCpu, VMXTLBFLUSHEPT enmTlbFlush)
    17601760{
    17611761    uint64_t au64Descriptor[2];
    1762     if (enmFlush == VMXFLUSHEPT_ALL_CONTEXTS)
     1762    if (enmTlbFlush == VMXTLBFLUSHEPT_ALL_CONTEXTS)
    17631763        au64Descriptor[0] = 0;
    17641764    else
     
    17691769    au64Descriptor[1] = 0;                       /* MBZ. Intel spec. 33.3 "VMX Instructions" */
    17701770
    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
    17741775    if (   RT_SUCCESS(rc)
    17751776        && pVCpu)
    1776     {
    17771777        STAM_COUNTER_INC(&pVCpu->hm.s.StatFlushNestedPaging);
    1778     }
    17791778}
    17801779
     
    17841783 *
    17851784 * @returns VBox status code.
    1786  * @param   pVCpu       The cross context virtual CPU structure of the calling
    1787  *                      EMT.  Can be NULL depending on @a enmFlush.
    1788  * @param   enmFlush    Type of flush.
    1789  * @param   GCPtr       Virtual address of the page to flush (can be 0 depending
    1790  *                      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).
    17911790 *
    17921791 * @remarks Can be called with interrupts disabled.
    17931792 */
    1794 static void hmR0VmxFlushVpid(PVMCPU pVCpu, VMXFLUSHVPID enmFlush, RTGCPTR GCPtr)
     1793static void hmR0VmxFlushVpid(PVMCPU pVCpu, VMXTLBFLUSHVPID enmTlbFlush, RTGCPTR GCPtr)
    17951794{
    17961795    Assert(pVCpu->CTX_SUFF(pVM)->hm.s.vmx.fVpid);
    17971796
    17981797    uint64_t au64Descriptor[2];
    1799     if (enmFlush == VMXFLUSHVPID_ALL_CONTEXTS)
     1798    if (enmTlbFlush == VMXTLBFLUSHVPID_ALL_CONTEXTS)
    18001799    {
    18011800        au64Descriptor[0] = 0;
     
    18111810    }
    18121811
    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
    18161816    if (   RT_SUCCESS(rc)
    18171817        && pVCpu)
    1818     {
    18191818        STAM_COUNTER_INC(&pVCpu->hm.s.StatFlushAsid);
    1820     }
    18211819    NOREF(rc);
    18221820}
     
    18631861            if (fVpidFlush)
    18641862            {
    1865                 hmR0VmxFlushVpid(pVCpu, VMXFLUSHVPID_INDIV_ADDR, GCVirt);
     1863                hmR0VmxFlushVpid(pVCpu, VMXTLBFLUSHVPID_INDIV_ADDR, GCVirt);
    18661864                STAM_COUNTER_INC(&pVCpu->hm.s.StatFlushTlbInvlpgVirt);
    18671865            }
     
    19611959         * invalidated. We don't need to flush-by-VPID here as flushing by EPT covers it. See @bugref{6568}.
    19621960         */
    1963         hmR0VmxFlushEpt(pVCpu, pVM->hm.s.vmx.enmFlushEpt);
     1961        hmR0VmxFlushEpt(pVCpu, pVM->hm.s.vmx.enmTlbFlushEpt);
    19641962        STAM_COUNTER_INC(&pVCpu->hm.s.StatFlushTlbWorldSwitch);
    19651963        HMVMX_SET_TAGGED_TLB_FLUSHED();
     
    19791977         * See Intel spec. 28.3.2 "Creating and Using Cached Translation Information".
    19801978         */
    1981         hmR0VmxFlushEpt(pVCpu, pVM->hm.s.vmx.enmFlushEpt);
     1979        hmR0VmxFlushEpt(pVCpu, pVM->hm.s.vmx.enmTlbFlushEpt);
    19821980        STAM_COUNTER_INC(&pVCpu->hm.s.StatFlushTlb);
    19831981        HMVMX_SET_TAGGED_TLB_FLUSHED();
     
    20452043    if (pVCpu->hm.s.fForceTLBFlush)
    20462044    {
    2047         hmR0VmxFlushEpt(pVCpu, pVCpu->CTX_SUFF(pVM)->hm.s.vmx.enmFlushEpt);
     2045        hmR0VmxFlushEpt(pVCpu, pVCpu->CTX_SUFF(pVM)->hm.s.vmx.enmTlbFlushEpt);
    20482046        pVCpu->hm.s.fForceTLBFlush = false;
    20492047    }
     
    21112109        if (pCpu->fFlushAsidBeforeUse)
    21122110        {
    2113             if (pVM->hm.s.vmx.enmFlushVpid == VMXFLUSHVPID_SINGLE_CONTEXT)
    2114                 hmR0VmxFlushVpid(pVCpu, VMXFLUSHVPID_SINGLE_CONTEXT, 0 /* GCPtr */);
    2115             else if (pVM->hm.s.vmx.enmFlushVpid == 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)
    21162114            {
    2117                 hmR0VmxFlushVpid(pVCpu, VMXFLUSHVPID_ALL_CONTEXTS, 0 /* GCPtr */);
     2115                hmR0VmxFlushVpid(pVCpu, VMXTLBFLUSHVPID_ALL_CONTEXTS, 0 /* GCPtr */);
    21182116                pCpu->fFlushAsidBeforeUse = false;
    21192117            }
     
    21512149#endif
    21522150    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;
    21592157        default:
    21602158            AssertMsgFailed(("Invalid flush-tag function identifier\n"));
     
    21842182        {
    21852183            if (pVM->hm.s.vmx.Msrs.u64EptVpidCaps & MSR_IA32_VMX_EPT_VPID_CAP_INVEPT_SINGLE_CONTEXT)
    2186                 pVM->hm.s.vmx.enmFlushEpt = VMXFLUSHEPT_SINGLE_CONTEXT;
     2184                pVM->hm.s.vmx.enmTlbFlushEpt = VMXTLBFLUSHEPT_SINGLE_CONTEXT;
    21872185            else if (pVM->hm.s.vmx.Msrs.u64EptVpidCaps & MSR_IA32_VMX_EPT_VPID_CAP_INVEPT_ALL_CONTEXTS)
    2188                 pVM->hm.s.vmx.enmFlushEpt = VMXFLUSHEPT_ALL_CONTEXTS;
     2186                pVM->hm.s.vmx.enmTlbFlushEpt = VMXTLBFLUSHEPT_ALL_CONTEXTS;
    21892187            else
    21902188            {
    21912189                /* Shouldn't happen. EPT is supported but no suitable flush-types supported. */
    2192                 pVM->hm.s.vmx.enmFlushEpt = VMXFLUSHEPT_NOT_SUPPORTED;
     2190                pVM->hm.s.vmx.enmTlbFlushEpt = VMXTLBFLUSHEPT_NOT_SUPPORTED;
    21932191                pVM->aCpus[0].hm.s.u32HMError = VMX_UFC_EPT_FLUSH_TYPE_UNSUPPORTED;
    21942192                return VERR_HM_UNSUPPORTED_CPU_FEATURE_COMBO;
     
    21982196            if (RT_UNLIKELY(!(pVM->hm.s.vmx.Msrs.u64EptVpidCaps & MSR_IA32_VMX_EPT_VPID_CAP_EMT_WB)))
    21992197            {
    2200                 pVM->hm.s.vmx.enmFlushEpt = VMXFLUSHEPT_NOT_SUPPORTED;
     2198                pVM->hm.s.vmx.enmTlbFlushEpt = VMXTLBFLUSHEPT_NOT_SUPPORTED;
    22012199                pVM->aCpus[0].hm.s.u32HMError = VMX_UFC_EPT_MEM_TYPE_NOT_WB;
    22022200                return VERR_HM_UNSUPPORTED_CPU_FEATURE_COMBO;
     
    22062204            if (RT_UNLIKELY(!(pVM->hm.s.vmx.Msrs.u64EptVpidCaps & MSR_IA32_VMX_EPT_VPID_CAP_PAGE_WALK_LENGTH_4)))
    22072205            {
    2208                 pVM->hm.s.vmx.enmFlushEpt = VMXFLUSHEPT_NOT_SUPPORTED;
     2206                pVM->hm.s.vmx.enmTlbFlushEpt = VMXTLBFLUSHEPT_NOT_SUPPORTED;
    22092207                pVM->aCpus[0].hm.s.u32HMError = VMX_UFC_EPT_PAGE_WALK_LENGTH_UNSUPPORTED;
    22102208                return VERR_HM_UNSUPPORTED_CPU_FEATURE_COMBO;
     
    22142212        {
    22152213            /* Shouldn't happen. EPT is supported but INVEPT instruction is not supported. */
    2216             pVM->hm.s.vmx.enmFlushEpt = VMXFLUSHEPT_NOT_SUPPORTED;
     2214            pVM->hm.s.vmx.enmTlbFlushEpt = VMXTLBFLUSHEPT_NOT_SUPPORTED;
    22172215            pVM->aCpus[0].hm.s.u32HMError = VMX_UFC_EPT_INVEPT_UNAVAILABLE;
    22182216            return VERR_HM_UNSUPPORTED_CPU_FEATURE_COMBO;
     
    22282226        {
    22292227            if (pVM->hm.s.vmx.Msrs.u64EptVpidCaps & MSR_IA32_VMX_EPT_VPID_CAP_INVVPID_SINGLE_CONTEXT)
    2230                 pVM->hm.s.vmx.enmFlushVpid = VMXFLUSHVPID_SINGLE_CONTEXT;
     2228                pVM->hm.s.vmx.enmTlbFlushVpid = VMXTLBFLUSHVPID_SINGLE_CONTEXT;
    22312229            else if (pVM->hm.s.vmx.Msrs.u64EptVpidCaps & MSR_IA32_VMX_EPT_VPID_CAP_INVVPID_ALL_CONTEXTS)
    2232                 pVM->hm.s.vmx.enmFlushVpid = VMXFLUSHVPID_ALL_CONTEXTS;
     2230                pVM->hm.s.vmx.enmTlbFlushVpid = VMXTLBFLUSHVPID_ALL_CONTEXTS;
    22332231            else
    22342232            {
     
    22382236                if (pVM->hm.s.vmx.Msrs.u64EptVpidCaps & MSR_IA32_VMX_EPT_VPID_CAP_INVVPID_SINGLE_CONTEXT_RETAIN_GLOBALS)
    22392237                    LogRelFunc(("Only SINGLE_CONTEXT_RETAIN_GLOBALS supported. Ignoring VPID.\n"));
    2240                 pVM->hm.s.vmx.enmFlushVpid = VMXFLUSHVPID_NOT_SUPPORTED;
     2238                pVM->hm.s.vmx.enmTlbFlushVpid = VMXTLBFLUSHVPID_NOT_SUPPORTED;
    22412239                pVM->hm.s.vmx.fVpid = false;
    22422240            }
     
    22462244            /*  Shouldn't happen. VPID is supported but INVVPID is not supported by the CPU. Ignore VPID capability. */
    22472245            Log4Func(("VPID supported without INVEPT support. Ignoring VPID.\n"));
    2248             pVM->hm.s.vmx.enmFlushVpid = VMXFLUSHVPID_NOT_SUPPORTED;
     2246            pVM->hm.s.vmx.enmTlbFlushVpid = VMXTLBFLUSHVPID_NOT_SUPPORTED;
    22492247            pVM->hm.s.vmx.fVpid = false;
    22502248        }
     
    22552253     */
    22562254    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;
    22582256    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;
    22602258    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;
    22622260    else
    2263         pVM->hm.s.vmx.uFlushTaggedTlb = HMVMX_FLUSH_TAGGED_TLB_NONE;
     2261        pVM->hm.s.vmx.enmTlbFlushType = VMXTLBFLUSHTYPE_NONE;
    22642262    return VINF_SUCCESS;
    22652263}
     
    27342732
    27352733    /* Initialize these always, see hmR3InitFinalizeR0().*/
    2736     pVM->hm.s.vmx.enmFlushEpt  = VMXFLUSHEPT_NONE;
    2737     pVM->hm.s.vmx.enmFlushVpid = VMXFLUSHVPID_NONE;
     2734    pVM->hm.s.vmx.enmTlbFlushEpt  = VMXTLBFLUSHEPT_NONE;
     2735    pVM->hm.s.vmx.enmTlbFlushVpid = VMXTLBFLUSHVPID_NONE;
    27382736
    27392737    /* Setup the tagged-TLB flush handlers. */
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette