VirtualBox

Changeset 76722 in vbox for trunk


Ignore:
Timestamp:
Jan 9, 2019 8:15:04 AM (6 years ago)
Author:
vboxsync
Message:

VMM: Nested VMX: bugref:9180 Fix VMLAUNCH/VMRESUME and VMPTRLD caching of the VMCS. We cache VMCS on VMPTRLD, so do not reload it again during VMLAUNCH/VMRESUME.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/hm_vmx.h

    r76638 r76722  
    40484048    kVmxVDiag_Vmentry_ProcCtls2Disallowed0,
    40494049    kVmxVDiag_Vmentry_PtrInvalid,
    4050     kVmxVDiag_Vmentry_PtrReadPhys,
    40514050    kVmxVDiag_Vmentry_RealOrV86Mode,
    40524051    kVmxVDiag_Vmentry_SavePreemptTimer,
  • trunk/src/VBox/VMM/VMMAll/HMVMXAll.cpp

    r76694 r76722  
    328328    VMXV_DIAG_DESC(kVmxVDiag_Vmentry_ProcCtls2Disallowed0     , "ProcCtls2Disallowed0"      ),
    329329    VMXV_DIAG_DESC(kVmxVDiag_Vmentry_PtrInvalid               , "PtrInvalid"                ),
    330     VMXV_DIAG_DESC(kVmxVDiag_Vmentry_PtrReadPhys              , "PtrReadPhys"               ),
    331330    VMXV_DIAG_DESC(kVmxVDiag_Vmentry_RealOrV86Mode            , "RealOrV86Mode"             ),
    332331    VMXV_DIAG_DESC(kVmxVDiag_Vmentry_SavePreemptTimer         , "SavePreemptTimer"          ),
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h

    r76652 r76722  
    72207220
    72217221    /*
    7222      * Load the current VMCS.
    7223      */
    7224     Assert(pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs));
    7225     int rc = PGMPhysSimpleReadGCPhys(pVCpu->CTX_SUFF(pVM), pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs),
    7226                                      IEM_VMX_GET_CURRENT_VMCS(pVCpu), VMX_V_VMCS_SIZE);
    7227     if (RT_FAILURE(rc))
    7228     {
    7229         Log(("%s: Failed to read VMCS at %#RGp, rc=%Rrc\n", pszInstr, IEM_VMX_GET_CURRENT_VMCS(pVCpu), rc));
    7230         pVCpu->cpum.GstCtx.hwvirt.vmx.enmDiag = kVmxVDiag_Vmentry_PtrReadPhys;
    7231         return rc;
    7232     }
    7233 
    7234     /*
    72357222     * We are allowed to cache VMCS related data structures (such as I/O bitmaps, MSR bitmaps)
    72367223     * while entering VMX non-root mode. We do some of this while checking VM-execution
     
    72427229     * See Intel spec. 24.11.4 "Software Access to Related Structures".
    72437230     */
    7244     rc = iemVmxVmentryCheckExecCtls(pVCpu, pszInstr);
     7231    Assert(pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs));
     7232    Assert(IEM_VMX_HAS_CURRENT_VMCS(pVCpu));
     7233    int rc = iemVmxVmentryCheckExecCtls(pVCpu, pszInstr);
    72457234    if (RT_SUCCESS(rc))
    72467235    {
     
    80998088
    81008089    /*
    8101      * We maintain only the cache of the current VMCS in CPUMCTX. Therefore, VMPTRLD shall
    8102      * always flush the cache contents of any existing, current VMCS back to guest memory
    8103      * before loading a new VMCS as current.
    8104      */
    8105     if (   IEM_VMX_HAS_CURRENT_VMCS(pVCpu)
    8106         && IEM_VMX_GET_CURRENT_VMCS(pVCpu) != GCPhysVmcs)
    8107     {
    8108         iemVmxCommitCurrentVmcsToMemory(pVCpu);
    8109         Assert(!IEM_VMX_HAS_CURRENT_VMCS(pVCpu));
    8110     }
    8111 
    8112     /* Finally, cache the new VMCS from guest memory and mark it as the current VMCS. */
    8113     rc = PGMPhysSimpleReadGCPhys(pVCpu->CTX_SUFF(pVM), (void *)pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs), GCPhysVmcs,
    8114                                  sizeof(VMXVVMCS));
    8115     if (RT_FAILURE(rc))
    8116     {
    8117         Log(("vmptrld: Failed to read VMCS at %#RGp, rc=%Rrc\n", GCPhysVmcs, rc));
    8118         pVCpu->cpum.GstCtx.hwvirt.vmx.enmDiag = kVmxVDiag_Vmptrld_PtrReadPhys;
    8119         return rc;
    8120     }
    8121 
    8122     IEM_VMX_SET_CURRENT_VMCS(pVCpu, GCPhysVmcs);
    8123 
     8090     * We cache only the current VMCS in CPUMCTX. Therefore, VMPTRLD should always flush
     8091     * the cache of an existing, current VMCS back to guest memory before loading a new,
     8092     * different current VMCS.
     8093     */
     8094    bool fLoadVmcsFromMem;
     8095    if (IEM_VMX_HAS_CURRENT_VMCS(pVCpu))
     8096    {
     8097        if (IEM_VMX_GET_CURRENT_VMCS(pVCpu) != GCPhysVmcs)
     8098        {
     8099            iemVmxCommitCurrentVmcsToMemory(pVCpu);
     8100            Assert(!IEM_VMX_HAS_CURRENT_VMCS(pVCpu));
     8101            fLoadVmcsFromMem = true;
     8102        }
     8103        else
     8104            fLoadVmcsFromMem = false;
     8105    }
     8106    else
     8107        fLoadVmcsFromMem = true;
     8108
     8109    if (fLoadVmcsFromMem)
     8110    {
     8111        /* Finally, cache the new VMCS from guest memory and mark it as the current VMCS. */
     8112        rc = PGMPhysSimpleReadGCPhys(pVCpu->CTX_SUFF(pVM), (void *)pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs), GCPhysVmcs,
     8113                                     sizeof(VMXVVMCS));
     8114        if (RT_FAILURE(rc))
     8115        {
     8116            Log(("vmptrld: Failed to read VMCS at %#RGp, rc=%Rrc\n", GCPhysVmcs, rc));
     8117            pVCpu->cpum.GstCtx.hwvirt.vmx.enmDiag = kVmxVDiag_Vmptrld_PtrReadPhys;
     8118            return rc;
     8119        }
     8120        IEM_VMX_SET_CURRENT_VMCS(pVCpu, GCPhysVmcs);
     8121    }
     8122
     8123    Assert(IEM_VMX_HAS_CURRENT_VMCS(pVCpu));
    81248124    iemVmxVmSucceed(pVCpu);
    81258125    iemRegAddToRipAndClearRF(pVCpu, cbInstr);
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