VirtualBox

Changeset 54085 in vbox


Ignore:
Timestamp:
Feb 5, 2015 2:05:47 PM (10 years ago)
Author:
vboxsync
Message:

VMM/TM: Only switch to real-tsc-offset mode when host is capable.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/TM.cpp

    r54065 r54085  
    31563156        if (pVM->tm.s.enmTSCMode != TMTSCMODE_REAL_TSC_OFFSET)
    31573157        {
    3158             uint64_t u64NowVirtSync = TMVirtualSyncGetNoCheck(pVM);
    3159             uint64_t u64Now = ASMMultU64ByU32DivByU32(u64NowVirtSync, pVM->tm.s.cTSCTicksPerSecond, TMCLOCK_FREQ_VIRTUAL);
    3160             uint32_t cCpus  = pVM->cCpus;
    3161             uint64_t u64RealTSC = ASMReadTSC();
    3162             for (uint32_t i = 0; i < cCpus; i++)
     3158            if (tmR3HasFixedTSC(pVM))
    31633159            {
    3164                 PVMCPU   pVCpu = &pVM->aCpus[i];
    3165                 uint64_t u64TickOld = u64Now - pVCpu->tm.s.offTSCRawSrc;
    3166 
    3167                 /*
    3168                  * The return value of TMCpuTickGet() and the guest's TSC value (u64Tick) must
    3169                  * remain constant across the TM TSC mode-switch.
    3170                  * OldTick = VrSync - CurOff
    3171                  * NewTick = RealTsc - NewOff
    3172                  * NewTick = OldTick
    3173                  *  => RealTsc - NewOff = VrSync - CurOff
    3174                  *  => NewOff = CurOff + RealTsc - VrSync
    3175                  */
    3176                 pVCpu->tm.s.offTSCRawSrc = pVCpu->tm.s.offTSCRawSrc + u64RealTSC  - u64Now;
    3177 
    3178                 /* If the new offset results in the TSC going backwards, re-adjust the offset. */
    3179                 if (u64RealTSC - pVCpu->tm.s.offTSCRawSrc < u64TickOld)
    3180                     pVCpu->tm.s.offTSCRawSrc += u64TickOld - u64RealTSC;
    3181                 Assert(u64RealTSC - pVCpu->tm.s.offTSCRawSrc >= u64TickOld);
     3160                uint64_t u64NowVirtSync = TMVirtualSyncGetNoCheck(pVM);
     3161                uint64_t u64Now = ASMMultU64ByU32DivByU32(u64NowVirtSync, pVM->tm.s.cTSCTicksPerSecond, TMCLOCK_FREQ_VIRTUAL);
     3162                uint32_t cCpus  = pVM->cCpus;
     3163                uint64_t u64RealTSC = ASMReadTSC();
     3164                for (uint32_t i = 0; i < cCpus; i++)
     3165                {
     3166                    PVMCPU   pVCpu = &pVM->aCpus[i];
     3167                    uint64_t u64TickOld = u64Now - pVCpu->tm.s.offTSCRawSrc;
     3168
     3169                    /*
     3170                     * The return value of TMCpuTickGet() and the guest's TSC value (u64Tick) must
     3171                     * remain constant across the TM TSC mode-switch.
     3172                     * OldTick = VrSync - CurOff
     3173                     * NewTick = RealTsc - NewOff
     3174                     * NewTick = OldTick
     3175                     *  => RealTsc - NewOff = VrSync - CurOff
     3176                     *  => NewOff = CurOff + RealTsc - VrSync
     3177                     */
     3178                    pVCpu->tm.s.offTSCRawSrc = pVCpu->tm.s.offTSCRawSrc + u64RealTSC  - u64Now;
     3179
     3180                    /* If the new offset results in the TSC going backwards, re-adjust the offset. */
     3181                    if (u64RealTSC - pVCpu->tm.s.offTSCRawSrc < u64TickOld)
     3182                        pVCpu->tm.s.offTSCRawSrc += u64TickOld - u64RealTSC;
     3183                    Assert(u64RealTSC - pVCpu->tm.s.offTSCRawSrc >= u64TickOld);
     3184                }
     3185                pVM->tm.s.enmTSCMode = TMTSCMODE_REAL_TSC_OFFSET;
     3186                LogRel(("TM: Switched TSC mode. New enmTSCMode=%d (%s)\n", pVM->tm.s.enmTSCMode, tmR3GetTSCModeName(pVM)));
    31823187            }
    3183             pVM->tm.s.enmTSCMode = TMTSCMODE_REAL_TSC_OFFSET;
    3184             LogRel(("TM: Switched TSC mode. New enmTSCMode=%d (%s)\n", pVM->tm.s.enmTSCMode, tmR3GetTSCModeName(pVM)));
     3188            else
     3189                LogRel(("TM: Host is not suitable for using TSC mode (%d - %s). Request to change TSC mode ignored.\n",
     3190                        TMTSCMODE_REAL_TSC_OFFSET, tmR3GetTSCModeNameEx(TMTSCMODE_REAL_TSC_OFFSET)));
    31853191        }
    31863192    }
     
    34683474}
    34693475
     3476
     3477/**
     3478 * Gets the descriptive TM TSC mode name given the enum value.
     3479 *
     3480 * @returns The name.
     3481 * @param   pVM      Pointer to the VM.
     3482 */
     3483static const char *tmR3GetTSCModeNameEx(TMTSCMODE enmMode)
     3484{
     3485    switch (enmMode)
     3486    {
     3487        case TMTSCMODE_REAL_TSC_OFFSET:    return "RealTscOffset";
     3488        case TMTSCMODE_VIRT_TSC_EMULATED:  return "VirtTscEmulated";
     3489        case TMTSCMODE_DYNAMIC:            return "Dynamic";
     3490        default:                           return "???";
     3491    }
     3492}
     3493
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