VirtualBox

Changeset 22241 in vbox


Ignore:
Timestamp:
Aug 13, 2009 3:05:24 PM (15 years ago)
Author:
vboxsync
Message:

Attempt to get rid of decreasing rdtsc return values.

Location:
trunk/src/VBox/VMM
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/HWACCM.cpp

    r22040 r22241  
    507507        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatTSCOffset,              "/HWACCM/CPU%d/TSC/Offset");
    508508        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatTSCIntercept,           "/HWACCM/CPU%d/TSC/Intercept");
    509 
     509        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatTSCInterceptOverFlow,   "/HWACCM/CPU%d/TSC/InterceptOverflow");
     510        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatTSCOverFlow,            "/HWACCM/CPU%d/TSC/Overflow");
     511       
    510512        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatDRxArmed,               "/HWACCM/CPU%d/Debug/Armed");
    511513        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatDRxContextSwitch,       "/HWACCM/CPU%d/Debug/ContextSwitch");
  • trunk/src/VBox/VMM/HWACCMInternal.h

    r22079 r22241  
    556556    /* Current ASID in use by the VM */
    557557    RTUINT                      uCurrentASID;
     558
     559    /* Last seen TSC by the guest when in offsetted mode. */
     560    uint64_t                    u64LastTSC;
     561    /* Last use TSC offset value. (cached) */
     562    uint64_t                    u64TSCOffset;
    558563
    559564    struct
     
    814819    STAMCOUNTER             StatTSCOffset;
    815820    STAMCOUNTER             StatTSCIntercept;
     821    STAMCOUNTER             StatTSCOverFlow;
     822    STAMCOUNTER             StatTSCInterceptOverFlow;
    816823
    817824    STAMCOUNTER             StatExitReasonNPF;
  • trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp

    r22079 r22241  
    18081808    if (TMCpuTickCanUseRealTSC(pVCpu, &u64TSCOffset))
    18091809    {
    1810         /* Note: VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT takes precedence over TSC_OFFSET */
    1811         rc = VMXWriteVMCS64(VMX_VMCS_CTRL_TSC_OFFSET_FULL, u64TSCOffset);
    1812         AssertRC(rc);
    1813 
    1814         pVCpu->hwaccm.s.vmx.proc_ctls &= ~VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT;
    1815         rc = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hwaccm.s.vmx.proc_ctls);
    1816         AssertRC(rc);
    1817         STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatTSCOffset);
     1810        uint64_t u64CurTSC = ASMReadTSC();
     1811        pVCpu->hwaccm.s.u64TSCOffset = u64TSCOffset;
     1812        if (u64CurTSC + u64TSCOffset >= pVCpu->hwaccm.s.u64LastTSC)
     1813        {
     1814            /* Note: VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT takes precedence over TSC_OFFSET */
     1815            rc = VMXWriteVMCS64(VMX_VMCS_CTRL_TSC_OFFSET_FULL, u64TSCOffset);
     1816            AssertRC(rc);
     1817
     1818            pVCpu->hwaccm.s.vmx.proc_ctls &= ~VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT;
     1819            rc = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hwaccm.s.vmx.proc_ctls);
     1820            AssertRC(rc);
     1821            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatTSCOffset);
     1822        }
     1823        else
     1824        {
     1825            /* Fall back to rdtsc emulation as we would otherwise pass decreasing tsc values to the guest. */
     1826            Log(("TSC %RX64 offset %RX64 time=%RX64 last=%RX64 (diff=%RX64, virt_tsc=%RX64)\n", u64CurTSC, u64TSCOffset, u64CurTSC + u64TSCOffset, pVCpu->hwaccm.s.u64LastTSC, pVCpu->hwaccm.s.u64LastTSC - u64CurTSC - u64TSCOffset, TMCpuTickGet(pVCpu)));
     1827            pVCpu->hwaccm.s.vmx.proc_ctls |= VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT;
     1828            rc = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hwaccm.s.vmx.proc_ctls);
     1829            AssertRC(rc);
     1830            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatTSCInterceptOverFlow);
     1831        }
    18181832    }
    18191833    else
     
    25802594    rc = pVCpu->hwaccm.s.vmx.pfnStartVM(pVCpu->hwaccm.s.fResumeVM, pCtx, &pVCpu->hwaccm.s.vmx.VMCSCache, pVM, pVCpu);
    25812595#endif
     2596    /* Possibly the last TSC value seen by the guest (too high) (only when we're in tsc offset mode). */
     2597    if (!(pVCpu->hwaccm.s.vmx.proc_ctls & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT))
     2598        pVCpu->hwaccm.s.u64LastTSC = ASMReadTSC() + pVCpu->hwaccm.s.u64TSCOffset - 0x1000 /* guestimate of world switch overhead */;
     2599
    25822600    TMNotifyEndOfExecution(pVCpu);
    25832601    VMCPU_SET_STATE(pVCpu, VMCPUSTATE_STARTED);
     
    33813399        if (rc == VINF_SUCCESS)
    33823400        {
     3401            uint64_t u64CurrentTSC = (uint64_t)pCtx->edx << 32ULL;
     3402            u64CurrentTSC += pCtx->eax;
     3403
     3404            if (u64CurrentTSC < pVCpu->hwaccm.s.u64LastTSC)
     3405            {
     3406                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatTSCOverFlow);
     3407                Log(("invalid tsc %RX64 vs %RX64 (diff %RX64)\n", u64CurrentTSC, pVCpu->hwaccm.s.u64LastTSC, pVCpu->hwaccm.s.u64LastTSC - u64CurrentTSC));
     3408                pVCpu->hwaccm.s.u64LastTSC += 64;
     3409                pCtx->edx = (pVCpu->hwaccm.s.u64LastTSC >> 32ULL);
     3410                pCtx->eax = (pVCpu->hwaccm.s.u64LastTSC & 0xffffffff);
     3411            }
     3412
    33833413            /* Update EIP and continue execution. */
    33843414            Assert(cbInstr == 2);
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