VirtualBox

Changeset 104131 in vbox for trunk/src/VBox/VMM/VMMR3


Ignore:
Timestamp:
Apr 3, 2024 8:02:36 AM (10 months ago)
Author:
vboxsync
Message:

VMM/TM: Allow linear scaling of the guest TSC; primarily required for scaling up a 24MHz tickrate on ARM64 hosts.

File:
1 edited

Legend:

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

    r100000 r104131  
    335335                              "TSCTiedToExecution|"
    336336                              "TSCNotTiedToHalt|"
     337                              "TSCMultiplier|"
    337338                              "ScheduleSlack|"
    338339                              "CatchUpStopThreshold|"
     
    420421    }
    421422
     423    /** @cfgm{/TM/TSCMultiplier, uint8_t}
     424     * This is a multiplier to apply to the host TSC while calculating the guest
     425     * TSC.  It's recommended to avoid using a power-of-two value to reduce number
     426     * of zeros in least-significant-bits of the scaled TSC.  Defaults to 43 on
     427     * ARM64 and 1 on all other hosts. */
     428#ifdef RT_ARCH_ARM64
     429    pVM->tm.s.u8TSCMultiplier = 43; /* 125/3 + some fudge to get us >= 1GHz from 24MHz */
     430#else
     431    pVM->tm.s.u8TSCMultiplier = 1;
     432#endif
     433    rc = CFGMR3QueryU8Def(pCfgHandle, "TSCMultiplier", &pVM->tm.s.u8TSCMultiplier, pVM->tm.s.u8TSCMultiplier);
     434    if (RT_FAILURE(rc))
     435        return VMSetError(pVM, rc, RT_SRC_POS,
     436                          N_("Configuration error: Failed to query 8-bit value \"TSCMultiplier\""));
     437    if (pVM->tm.s.u8TSCMultiplier == 0)
     438        return VMSetError(pVM, rc, RT_SRC_POS, N_("Configuration error: \"TSCMultiplier\" must not be zero!"));
     439
    422440    /** @cfgm{/TM/TSCTicksPerSecond, uint32_t, Current TSC frequency from GIP}
    423441     * The number of TSC ticks per second (i.e. the TSC frequency). This will
     
    428446    if (rc == VERR_CFGM_VALUE_NOT_FOUND)
    429447    {
    430         pVM->tm.s.cTSCTicksPerSecond = pVM->tm.s.cTSCTicksPerSecondHost;
     448        pVM->tm.s.cTSCTicksPerSecond = pVM->tm.s.cTSCTicksPerSecondHost * pVM->tm.s.u8TSCMultiplier;
    431449        if (   (   pVM->tm.s.enmTSCMode == TMTSCMODE_DYNAMIC
    432450                || pVM->tm.s.enmTSCMode == TMTSCMODE_VIRT_TSC_EMULATED)
     
    450468    {
    451469        LogRel(("TM: NEM overrides the /TM/TSCTicksPerSecond=%RU64 setting.\n", pVM->tm.s.cTSCTicksPerSecond));
    452         pVM->tm.s.cTSCTicksPerSecond = pVM->tm.s.cTSCTicksPerSecondHost;
     470        pVM->tm.s.cTSCTicksPerSecond = pVM->tm.s.cTSCTicksPerSecondHost * pVM->tm.s.u8TSCMultiplier;
    453471    }
    454472
     
    641659    CPUMR3SetCR4Feature(pVM, X86_CR4_TSD, ~X86_CR4_TSD);
    642660#endif
    643     LogRel(("TM:     cTSCTicksPerSecond=%'RU64 (%#RX64) enmTSCMode=%d (%s)\n"
     661    LogRel(("TM:     cTSCTicksPerSecond=%'RU64 (%#RX64) enmTSCMode=%d (%s) TSCMultiplier=%u\n"
    644662            "TM: cTSCTicksPerSecondHost=%'RU64 (%#RX64)\n"
    645663            "TM: TSCTiedToExecution=%RTbool TSCNotTiedToHalt=%RTbool\n",
    646             pVM->tm.s.cTSCTicksPerSecond, pVM->tm.s.cTSCTicksPerSecond, pVM->tm.s.enmTSCMode, tmR3GetTSCModeName(pVM),
     664            pVM->tm.s.cTSCTicksPerSecond, pVM->tm.s.cTSCTicksPerSecond, pVM->tm.s.enmTSCMode, tmR3GetTSCModeName(pVM), pVM->tm.s.u8TSCMultiplier,
    647665            pVM->tm.s.cTSCTicksPerSecondHost, pVM->tm.s.cTSCTicksPerSecondHost,
    648666            pVM->tm.s.fTSCTiedToExecution, pVM->tm.s.fTSCNotTiedToHalt));
     
    12501268    {
    12511269        case TMTSCMODE_REAL_TSC_OFFSET:
    1252             offTscRawSrc = SUPReadTsc();
     1270            offTscRawSrc = SUPReadTsc() * pVM->tm.s.u8TSCMultiplier;
    12531271            break;
    12541272        case TMTSCMODE_DYNAMIC:
     
    37423760         */
    37433761        uint64_t uRawOldTsc = tmR3CpuTickGetRawVirtualNoCheck(pVM);
    3744         uint64_t uRawNewTsc = SUPReadTsc();
     3762        uint64_t uRawNewTsc = SUPReadTsc() * pVM->tm.s.u8TSCMultiplier;
    37453763        uint32_t cCpus = pVM->cCpus;
    37463764        for (uint32_t i = 0; i < cCpus; i++)
     
    37963814         * See tmR3CpuTickParavirtEnable for an explanation of the conversion math.
    37973815         */
    3798         uint64_t uRawOldTsc = SUPReadTsc();
     3816        uint64_t uRawOldTsc = SUPReadTsc() * pVM->tm.s.u8TSCMultiplier;
    37993817        uint64_t uRawNewTsc = tmR3CpuTickGetRawVirtualNoCheck(pVM);
    38003818        uint32_t cCpus = pVM->cCpus;
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