VirtualBox

Changeset 74755 in vbox


Ignore:
Timestamp:
Oct 11, 2018 9:23:47 AM (6 years ago)
Author:
vboxsync
Message:

VMM/IEM: Nested VMX: bugref:9180 Initialize previous and first-pause loop tick records and ensure the required case for the
first execution of pause after VM-entry at CPL 0.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h

    r74753 r74755  
    35843584    if (pVmcs->u32ProcCtls & VMX_PROC_CTLS_PAUSE_EXIT)
    35853585        fIntercept = true;
    3586     else if (pVmcs->u32ProcCtls2 & VMX_PROC_CTLS2_PAUSE_LOOP_EXIT)
     3586    else if (   (pVmcs->u32ProcCtls2 & VMX_PROC_CTLS2_PAUSE_LOOP_EXIT)
     3587             && pVCpu->iem.s.uCpl == 0)
    35873588    {
    35883589        IEM_CTX_IMPORT_RET(pVCpu, CPUMCTX_EXTRN_HWVIRT);
    35893590
    3590         uint64_t      *puFirstPauseLoopTick = &pVCpu->cpum.GstCtx.hwvirt.vmx.uFirstPauseLoopTick;
    3591         uint64_t const uPrevPauseTick       = pVCpu->cpum.GstCtx.hwvirt.vmx.uPrevPauseTick;
    3592         uint32_t const uPleGap              = pVmcs->u32PleGap;
    3593         uint32_t const uPleWindow           = pVmcs->u32PleWindow;
    3594         uint64_t const uTick                = TMCpuTickGet(pVCpu);
    3595         if (uTick - uPrevPauseTick > uPleGap)
     3591        /*
     3592         * A previous-PAUSE-tick value of 0 is used to identify the first time
     3593         * execution of a PAUSE instruction after VM-entry at CPL 0. We must
     3594         * consider this to be the first execution of PAUSE in a loop according
     3595         * to the Intel.
     3596         *
     3597         * All subsequent records for the previous-PAUSE-tick we ensure that it
     3598         * cannot be zero by OR'ing 1 to rule out the TSC wrap-around cases at 0.
     3599         */
     3600        uint64_t *puFirstPauseLoopTick = &pVCpu->cpum.GstCtx.hwvirt.vmx.uFirstPauseLoopTick;
     3601        uint64_t *puPrevPauseTick      = &pVCpu->cpum.GstCtx.hwvirt.vmx.uPrevPauseTick;
     3602        uint64_t const  uTick          = TMCpuTickGet(pVCpu);
     3603        uint32_t const  uPleGap        = pVmcs->u32PleGap;
     3604        uint32_t const  uPleWindow     = pVmcs->u32PleWindow;
     3605        if (   *puPrevPauseTick == 0
     3606            || uTick - *puPrevPauseTick > uPleGap)
    35963607            *puFirstPauseLoopTick = uTick;
    35973608        else if (uTick - *puFirstPauseLoopTick > uPleWindow)
    35983609            fIntercept = true;
     3610
     3611        *puPrevPauseTick = uTick | 1;
    35993612    }
    36003613
     
    57485761    pVCpu->cpum.GstCtx.rflags.u = pVmcs->u64GuestRFlags.u;
    57495762
     5763    /* Initialize the PAUSE-loop controls as part of VM-entry. */
     5764    pVCpu->cpum.GstCtx.hwvirt.vmx.uFirstPauseLoopTick = 0;
     5765    pVCpu->cpum.GstCtx.hwvirt.vmx.uPrevPauseTick      = 0;
     5766
    57505767    iemVmxVmentryLoadGuestNonRegState(pVCpu);
    57515768
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