VirtualBox

Changeset 19032 in vbox


Ignore:
Timestamp:
Apr 20, 2009 3:03:08 PM (16 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
46143
Message:

Split TM for SMP guests.

Location:
trunk
Files:
17 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/tm.h

    r13778 r19032  
    7373
    7474
    75 VMMDECL(void)     TMNotifyStartOfExecution(PVM pVM);
    76 VMMDECL(void)     TMNotifyEndOfExecution(PVM pVM);
    77 VMMDECL(void)     TMNotifyStartOfHalt(PVM pVM);
    78 VMMDECL(void)     TMNotifyEndOfHalt(PVM pVM);
     75VMMDECL(void)     TMNotifyStartOfExecution(PVMCPU pVCpu);
     76VMMDECL(void)     TMNotifyEndOfExecution(PVMCPU pVCpu);
     77VMMDECL(void)     TMNotifyStartOfHalt(PVMCPU pVCpu);
     78VMMDECL(void)     TMNotifyEndOfHalt(PVMCPU pVCpu);
    7979
    8080
     
    113113 * @{
    114114 */
    115 VMMDECL(int)      TMCpuTickResume(PVM pVM);
    116 VMMDECL(int)      TMCpuTickPause(PVM pVM);
    117 VMMDECL(uint64_t) TMCpuTickGet(PVM pVM);
    118 VMMDECL(bool)     TMCpuTickCanUseRealTSC(PVM pVM, uint64_t *poffRealTSC);
    119 VMMDECL(int)      TMCpuTickSet(PVM pVM, uint64_t u64Tick);
     115VMMDECL(int)      TMCpuTickResume(PVMCPU pVCpu);
     116VMMDECL(int)      TMCpuTickPause(PVMCPU pVCpu);
     117VMMDECL(uint64_t) TMCpuTickGet(PVMCPU pVCpu);
     118VMMDECL(bool)     TMCpuTickCanUseRealTSC(PVMCPU pVCpu, uint64_t *poffRealTSC);
     119VMMDECL(int)      TMCpuTickSet(PVMCPU pVCpu, uint64_t u64Tick);
    120120VMMDECL(uint64_t) TMCpuTicksPerSecond(PVM pVM);
    121121/** @} */
  • trunk/src/VBox/VMM/EM.cpp

    r19015 r19032  
    35093509        rc = TMVirtualResume(pVM);
    35103510        Assert(rc == VINF_SUCCESS);
    3511         rc = TMCpuTickResume(pVM);
     3511        rc = TMCpuTickResume(pVCpu);
    35123512        Assert(rc == VINF_SUCCESS);
    35133513
     
    36463646                    Log2(("EMR3ExecuteVM: returns VINF_EM_OFF (%d -> %d)\n", pVCpu->em.s.enmState, EMSTATE_TERMINATING));
    36473647                    TMVirtualPause(pVM);
    3648                     TMCpuTickPause(pVM);
     3648                    TMCpuTickPause(pVCpu);
    36493649                    VMMR3Unlock(pVM);
    36503650                    STAM_REL_PROFILE_ADV_STOP(&pVCpu->em.s.StatTotal, x);
     
    36583658                    Log(("EMR3ExecuteVM returns VINF_EM_TERMINATE (%d -> %d)\n", pVCpu->em.s.enmState, EMSTATE_TERMINATING));
    36593659                    TMVirtualPause(pVM);
    3660                     TMCpuTickPause(pVM);
     3660                    TMCpuTickPause(pVCpu);
    36613661                    STAM_REL_PROFILE_ADV_STOP(&pVCpu->em.s.StatTotal, x);
    36623662                    return rc;
     
    36703670                    pVCpu->em.s.enmState = EMSTATE_SUSPENDED;
    36713671                    TMVirtualPause(pVM);
    3672                     TMCpuTickPause(pVM);
     3672                    TMCpuTickPause(pVCpu);
    36733673                    VMMR3Unlock(pVM);
    36743674                    STAM_REL_PROFILE_ADV_STOP(&pVCpu->em.s.StatTotal, x);
     
    38063806                case EMSTATE_SUSPENDED:
    38073807                    TMVirtualPause(pVM);
    3808                     TMCpuTickPause(pVM);
     3808                    TMCpuTickPause(pVCpu);
    38093809                    VMMR3Unlock(pVM);
    38103810                    STAM_REL_PROFILE_ADV_STOP(&pVCpu->em.s.StatTotal, x);
     
    38173817                case EMSTATE_DEBUG_GUEST_RAW:
    38183818                    TMVirtualPause(pVM);
    3819                     TMCpuTickPause(pVM);
     3819                    TMCpuTickPause(pVCpu);
    38203820                    rc = emR3Debug(pVM, pVCpu, rc);
    38213821                    TMVirtualResume(pVM);
    3822                     TMCpuTickResume(pVM);
     3822                    TMCpuTickResume(pVCpu);
    38233823                    Log2(("EMR3ExecuteVM: enmr3Debug -> %Rrc (state %d)\n", rc, pVCpu->em.s.enmState));
    38243824                    break;
     
    38303830                {
    38313831                    TMVirtualPause(pVM);
    3832                     TMCpuTickPause(pVM);
     3832                    TMCpuTickPause(pVCpu);
    38333833                    STAM_REL_PROFILE_ADV_STOP(&pVCpu->em.s.StatTotal, x);
    38343834
     
    38453845                    STAM_REL_PROFILE_ADV_START(&pVCpu->em.s.StatTotal, x);
    38463846                    TMVirtualResume(pVM);
    3847                     TMCpuTickResume(pVM);
     3847                    TMCpuTickResume(pVCpu);
    38483848                    break;
    38493849                }
     
    38553855                {
    38563856                    TMVirtualPause(pVM);
    3857                     TMCpuTickPause(pVM);
     3857                    TMCpuTickPause(pVCpu);
    38583858                    VMMR3FatalDump(pVM, pVCpu, rc);
    38593859                    emR3Debug(pVM, pVCpu, rc);
     
    38723872                    pVCpu->em.s.enmState = EMSTATE_GURU_MEDITATION;
    38733873                    TMVirtualPause(pVM);
    3874                     TMCpuTickPause(pVM);
     3874                    TMCpuTickPause(pVCpu);
    38753875                    VMMR3Unlock(pVM);
    38763876                    STAM_REL_PROFILE_ADV_STOP(&pVCpu->em.s.StatTotal, x);
     
    38863886        LogFlow(("EMR3ExecuteVM: returns %Rrc (longjmp / fatal error)\n", rc));
    38873887        TMVirtualPause(pVM);
    3888         TMCpuTickPause(pVM);
     3888        TMCpuTickPause(pVCpu);
    38893889        VMMR3FatalDump(pVM, pVCpu, rc);
    38903890        emR3Debug(pVM, pVCpu, rc);
  • trunk/src/VBox/VMM/TM.cpp

    r15844 r19032  
    9191 * Each clock has its own scheduling facility, or timer queue if you like.
    9292 * There are a few factors which makes it a bit complex.  First, there is the
    93  * usual R0 vs R3 vs. RC thing.  Then there is multiple threads, and then there
     93 * usual R0 vs R3 vs. RC thing.  Then there are multiple threads, and then there
    9494 * is the timer thread that periodically checks whether any timers has expired
    9595 * without EMT noticing.  On the API level, all but the create and save APIs
     
    9898 * The design is using a doubly linked list of active timers which is ordered
    9999 * by expire date.  This list is only modified by the EMT thread.  Updates to
    100  * the list are batched in a singly linked list, which is then process by the
     100 * the list are batched in a singly linked list, which is then processed by the
    101101 * EMT thread at the first opportunity (immediately, next time EMT modifies a
    102102 * timer on that clock, or next timer timeout).  Both lists are offset based and
     
    310310    {
    311311        if (!pVM->tm.s.fTSCUseRealTSC)
    312             pVM->tm.s.fMaybeUseOffsettedHostTSC = tmR3HasFixedTSC(pVM);
     312        {
     313            /* @todo simple case for guest SMP; always emulate RDTSC */
     314            if (pVM->cCPUs == 1)
     315                pVM->tm.s.fMaybeUseOffsettedHostTSC = tmR3HasFixedTSC(pVM);
     316        }
    313317        else
    314318            pVM->tm.s.fMaybeUseOffsettedHostTSC = true;
     
    346350    /** @cfgm{TM/TSCTiedToExecution, bool, false}
    347351     * Whether the TSC should be tied to execution. This will exclude most of the
    348      * virtualization overhead, but will by default include the time spend in the
     352     * virtualization overhead, but will by default include the time spent in the
    349353     * halt state (see TM/TSCNotTiedToHalt). This setting will override all other
    350354     * TSC settings except for TSCTicksPerSecond and TSCNotTiedToHalt, which should
     
    984988static DECLCALLBACK(int) tmR3Save(PVM pVM, PSSMHANDLE pSSM)
    985989{
     990    unsigned i;
     991
    986992    LogFlow(("tmR3Save:\n"));
    987     Assert(!pVM->tm.s.fTSCTicking);
     993#ifdef VBOX_STRICT
     994    for (i=0;i<pVM->cCPUs;i++)
     995    {
     996        PVMCPU pVCpu = &pVM->aCpus[i];
     997        Assert(!pVCpu->tm.s.fTSCTicking);
     998    }
    988999    Assert(!pVM->tm.s.fVirtualTicking);
    9891000    Assert(!pVM->tm.s.fVirtualSyncTicking);
     1001#endif
    9901002
    9911003    /*
     
    10061018    SSMR3PutU64(pSSM, TMCLOCK_FREQ_REAL);
    10071019
    1008     /* the cpu tick clock. */
    1009     SSMR3PutU64(pSSM, TMCpuTickGet(pVM));
     1020    for (i=0;i<pVM->cCPUs;i++)
     1021    {
     1022        PVMCPU pVCpu = &pVM->aCpus[i];
     1023
     1024        /* the cpu tick clock. */
     1025        SSMR3PutU64(pSSM, TMCpuTickGet(pVCpu));
     1026    }
    10101027    return SSMR3PutU64(pSSM, pVM->tm.s.cTSCTicksPerSecond);
    10111028}
     
    10221039static DECLCALLBACK(int) tmR3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t u32Version)
    10231040{
     1041    unsigned i;
    10241042    LogFlow(("tmR3Load:\n"));
    1025     Assert(!pVM->tm.s.fTSCTicking);
     1043
     1044#ifdef VBOX_STRICT
     1045    for (i=0;i<pVM->cCPUs;i++)
     1046    {
     1047        PVMCPU pVCpu = &pVM->aCpus[i];
     1048        Assert(!pVCpu->tm.s.fTSCTicking);
     1049    }
    10261050    Assert(!pVM->tm.s.fVirtualTicking);
    10271051    Assert(!pVM->tm.s.fVirtualSyncTicking);
     1052#endif
    10281053
    10291054    /*
     
    10811106
    10821107    /* the cpu tick clock. */
    1083     pVM->tm.s.fTSCTicking = false;
    1084     SSMR3GetU64(pSSM, &pVM->tm.s.u64TSC);
     1108    for (i=0;i<pVM->cCPUs;i++)
     1109    {
     1110        PVMCPU pVCpu = &pVM->aCpus[i];
     1111
     1112        pVCpu->tm.s.fTSCTicking = false;
     1113        SSMR3GetU64(pSSM, &pVCpu->tm.s.u64TSC);
     1114
     1115        if (pVM->tm.s.fTSCUseRealTSC)
     1116            pVCpu->tm.s.u64TSCOffset = 0; /** @todo TSC restore stuff and HWACC. */
     1117    }
     1118
    10851119    rc = SSMR3GetU64(pSSM, &u64Hz);
    10861120    if (RT_FAILURE(rc))
    10871121        return rc;
    1088     if (pVM->tm.s.fTSCUseRealTSC)
    1089         pVM->tm.s.u64TSCOffset = 0; /** @todo TSC restore stuff and HWACC. */
    1090     else
     1122    if (!pVM->tm.s.fTSCUseRealTSC)
    10911123        pVM->tm.s.cTSCTicksPerSecond = u64Hz;
     1124
    10921125    LogRel(("TM: cTSCTicksPerSecond=%#RX64 (%RU64) fTSCVirtualized=%RTbool fTSCUseRealTSC=%RTbool (state load)\n",
    10931126            pVM->tm.s.cTSCTicksPerSecond, pVM->tm.s.cTSCTicksPerSecond, pVM->tm.s.fTSCVirtualized, pVM->tm.s.fTSCUseRealTSC));
     
    13601393        case TMCLOCK_VIRTUAL_SYNC:  return TMVirtualSyncGet(pVM);
    13611394        case TMCLOCK_REAL:          return TMRealGet(pVM);
    1362         case TMCLOCK_TSC:           return TMCpuTickGet(pVM);
     1395        case TMCLOCK_TSC:           return TMCpuTickGet(&pVM->aCpus[0] /* just take VCPU 0 */);
    13631396        default:
    13641397            AssertMsgFailed(("enmClock=%d\n", enmClock));
     
    20832116     * Read the times first to avoid more than necessary time variation.
    20842117     */
    2085     const uint64_t u64TSC = TMCpuTickGet(pVM);
    20862118    const uint64_t u64Virtual = TMVirtualGet(pVM);
    20872119    const uint64_t u64VirtualSync = TMVirtualSyncGet(pVM);
    20882120    const uint64_t u64Real = TMRealGet(pVM);
    20892121
    2090     /*
    2091      * TSC
    2092      */
    2093     pHlp->pfnPrintf(pHlp,
    2094                     "Cpu Tick: %18RU64 (%#016RX64) %RU64Hz %s%s",
    2095                     u64TSC, u64TSC, TMCpuTicksPerSecond(pVM),
    2096                     pVM->tm.s.fTSCTicking ? "ticking" : "paused",
    2097                     pVM->tm.s.fTSCVirtualized ? " - virtualized" : "");
    2098     if (pVM->tm.s.fTSCUseRealTSC)
    2099     {
    2100         pHlp->pfnPrintf(pHlp, " - real tsc");
    2101         if (pVM->tm.s.u64TSCOffset)
    2102             pHlp->pfnPrintf(pHlp, "\n          offset %RU64", pVM->tm.s.u64TSCOffset);
    2103     }
    2104     else
    2105         pHlp->pfnPrintf(pHlp, " - virtual clock");
    2106     pHlp->pfnPrintf(pHlp, "\n");
     2122    for (unsigned i=0;i<pVM->cCPUs;i++)
     2123    {
     2124        PVMCPU pVCpu = &pVM->aCpus[i];
     2125
     2126        uint64_t u64TSC = TMCpuTickGet(pVCpu);
     2127        /*
     2128         * TSC
     2129         */
     2130        pHlp->pfnPrintf(pHlp,
     2131                        "Cpu Tick: %18RU64 (%#016RX64) %RU64Hz %s%s",
     2132                        u64TSC, u64TSC, TMCpuTicksPerSecond(pVM),
     2133                        pVCpu->tm.s.fTSCTicking ? "ticking" : "paused",
     2134                        pVM->tm.s.fTSCVirtualized ? " - virtualized" : "");
     2135        if (pVM->tm.s.fTSCUseRealTSC)
     2136        {
     2137            pHlp->pfnPrintf(pHlp, " - real tsc");
     2138            if (pVCpu->tm.s.u64TSCOffset)
     2139                pHlp->pfnPrintf(pHlp, "\n          offset %RU64", pVCpu->tm.s.u64TSCOffset);
     2140        }
     2141        else
     2142            pHlp->pfnPrintf(pHlp, " - virtual clock");
     2143        pHlp->pfnPrintf(pHlp, "\n");
     2144    }
    21072145
    21082146    /*
  • trunk/src/VBox/VMM/TMInternal.h

    r13742 r19032  
    287287    RTUINT                      offVM;
    288288
    289     /** CPU timestamp ticking enabled indicator (bool). (RDTSC) */
    290     bool                        fTSCTicking;
    291289    /** Set if we fully virtualize the TSC, i.e. intercept all rdtsc instructions.
    292290     * Config variable: TSCVirtualized (bool) */
     
    307305    bool                        fTSCNotTiedToHalt;
    308306    bool                        afAlignment0[6]; /**< alignment padding */
    309     /** The offset between the host TSC and the Guest TSC.
    310      * Only valid if fTicking is set and and fTSCUseRealTSC is clear. */
    311     uint64_t                    u64TSCOffset;
    312     /** The guest TSC when fTicking is cleared. */
    313     uint64_t                    u64TSC;
    314307    /** The number of CPU clock ticks per second (TMCLOCK_TSC).
    315308     * Config variable: TSCTicksPerSecond (64-bit unsigned int)
     
    508501     * See TMCPU2VM(). */
    509502    RTUINT                      offVMCPU;
     503
     504    /** CPU timestamp ticking enabled indicator (bool). (RDTSC) */
     505    bool                        fTSCTicking;
     506    bool                        afAlignment0[3]; /**< alignment padding */
     507
     508    /** The offset between the host TSC and the Guest TSC.
     509     * Only valid if fTicking is set and and fTSCUseRealTSC is clear. */
     510    uint64_t                    u64TSCOffset;
     511
     512    /** The guest TSC when fTicking is cleared. */
     513    uint64_t                    u64TSC;
     514
    510515} TMCPU;
    511516/** Pointer to TM VMCPU instance data. */
     
    518523#endif
    519524
    520 int                     tmCpuTickPause(PVM pVM);
    521 int                     tmCpuTickResume(PVM pVM);
     525int                     tmCpuTickPause(PVM pVM, PVMCPU pVCpu);
     526int                     tmCpuTickResume(PVM pVM, PVMCPU pVCpu);
    522527
    523528DECLEXPORT(void)        tmVirtualNanoTSBad(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS);
  • trunk/src/VBox/VMM/VMEmt.cpp

    r18927 r19032  
    985985VMMR3DECL(int) VMR3WaitHalted(PVM pVM, bool fIgnoreInterrupts)
    986986{
     987    PVMCPU pVCpu = VMMGetCpu(pVM);  /* @todo SMP: get rid of this */
     988
    987989    LogFlow(("VMR3WaitHalted: fIgnoreInterrupts=%d\n", fIgnoreInterrupts));
    988990
     
    10041006     */
    10051007    VMMR3YieldSuspend(pVM);
    1006     TMNotifyStartOfHalt(pVM);
     1008    TMNotifyStartOfHalt(pVCpu);
    10071009
    10081010    /*
     
    10371039     * Notify TM and resume the yielder
    10381040     */
    1039     TMNotifyEndOfHalt(pVM);
     1041    TMNotifyEndOfHalt(pVCpu);
    10401042    VMMR3YieldResume(pVM);
    10411043
  • trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp

    r18927 r19032  
    740740    {
    741741        case MSR_IA32_TSC:
    742             u64 = TMCpuTickGet(pVCpu->CTX_SUFF(pVM));
     742            u64 = TMCpuTickGet(pVCpu);
    743743            break;
    744744
  • trunk/src/VBox/VMM/VMMAll/EMAll.cpp

    r19015 r19032  
    25552555        return VERR_EM_INTERPRETER; /* genuine #GP */
    25562556
    2557     uint64_t uTicks = TMCpuTickGet(pVM);
     2557    uint64_t uTicks = TMCpuTickGet(pVCpu);
    25582558
    25592559    /* Same behaviour in 32 & 64 bits mode */
     
    25862586        return VERR_EM_INTERPRETER; /* genuine #GP */
    25872587
    2588     uint64_t uTicks = TMCpuTickGet(pVM);
     2588    uint64_t uTicks = TMCpuTickGet(pVCpu);
    25892589
    25902590    /* Same behaviour in 32 & 64 bits mode */
     
    27992799    {
    28002800    case MSR_IA32_TSC:
    2801         val = TMCpuTickGet(pVM);
     2801        val = TMCpuTickGet(pVCpu);
    28022802        break;
    28032803
  • trunk/src/VBox/VMM/VMMAll/TMAll.cpp

    r13633 r19032  
    5353 * clocks that only ticks when we're executing guest code.
    5454 *
    55  * @param   pVM         Pointer to the shared VM structure.
    56  */
    57 VMMDECL(void) TMNotifyStartOfExecution(PVM pVM)
    58 {
     55 * @param   pVCpu       The VMCPU to operate on.
     56 */
     57VMMDECL(void) TMNotifyStartOfExecution(PVMCPU pVCpu)
     58{
     59    PVM pVM = pVCpu->CTX_SUFF(pVM);
     60
    5961    if (pVM->tm.s.fTSCTiedToExecution)
    60         tmCpuTickResume(pVM);
     62        tmCpuTickResume(pVM, pVCpu);
    6163}
    6264
     
    7072 * clocks that only ticks when we're executing guest code.
    7173 *
    72  * @param   pVM         Pointer to the shared VM structure.
    73  */
    74 VMMDECL(void) TMNotifyEndOfExecution(PVM pVM)
    75 {
     74 * @param   pVCpu       The VMCPU to operate on.
     75 */
     76VMMDECL(void) TMNotifyEndOfExecution(PVMCPU pVCpu)
     77{
     78    PVM pVM = pVCpu->CTX_SUFF(pVM);
     79
    7680    if (pVM->tm.s.fTSCTiedToExecution)
    77         tmCpuTickPause(pVM);
     81        tmCpuTickPause(pVM, pVCpu);
    7882}
    7983
     
    8791 * clocks that only ticks when we're halted.
    8892 *
    89  * @param   pVM         Pointer to the shared VM structure.
    90  */
    91 VMMDECL(void) TMNotifyStartOfHalt(PVM pVM)
    92 {
     93 * @param   pVCpu       The VMCPU to operate on.
     94 */
     95VMMDECL(void) TMNotifyStartOfHalt(PVMCPU pVCpu)
     96{
     97    PVM pVM = pVCpu->CTX_SUFF(pVM);
     98
    9399    if (    pVM->tm.s.fTSCTiedToExecution
    94100        &&  !pVM->tm.s.fTSCNotTiedToHalt)
    95         tmCpuTickResume(pVM);
     101        tmCpuTickResume(pVM, pVCpu);
    96102}
    97103
     
    105111 * clocks that only ticks when we're halted.
    106112 *
    107  * @param   pVM         Pointer to the shared VM structure.
    108  */
    109 VMMDECL(void) TMNotifyEndOfHalt(PVM pVM)
    110 {
     113 * @param   pVCpu       The VMCPU to operate on.
     114 */
     115VMMDECL(void) TMNotifyEndOfHalt(PVMCPU pVCpu)
     116{
     117    PVM pVM = pVCpu->CTX_SUFF(pVM);
     118
    111119    if (    pVM->tm.s.fTSCTiedToExecution
    112120        &&  !pVM->tm.s.fTSCNotTiedToHalt)
    113         tmCpuTickPause(pVM);
     121        tmCpuTickPause(pVM, pVCpu);
    114122}
    115123
     
    659667VMMDECL(int) TMTimerSetMillies(PTMTIMER pTimer, uint32_t cMilliesToNext)
    660668{
    661     PVM pVM = pTimer->CTX_SUFF(pVM);
     669    PVM    pVM   = pTimer->CTX_SUFF(pVM);
     670    PVMCPU pVCpu = &pVM->aCpus[0];  /* just take the first VCPU */
     671
    662672    switch (pTimer->enmClock)
    663673    {
     
    670680            return TMTimerSet(pTimer, cMilliesToNext + TMRealGet(pVM));
    671681        case TMCLOCK_TSC:
    672             return TMTimerSet(pTimer, cMilliesToNext * pVM->tm.s.cTSCTicksPerSecond / 1000 + TMCpuTickGet(pVM));
     682            return TMTimerSet(pTimer, cMilliesToNext * pVM->tm.s.cTSCTicksPerSecond / 1000 + TMCpuTickGet(pVCpu));
    673683
    674684        default:
     
    688698VMMDECL(int) TMTimerSetMicro(PTMTIMER pTimer, uint64_t cMicrosToNext)
    689699{
    690     PVM pVM = pTimer->CTX_SUFF(pVM);
     700    PVM    pVM   = pTimer->CTX_SUFF(pVM);
     701    PVMCPU pVCpu = &pVM->aCpus[0];  /* just take the first VCPU */
     702
    691703    switch (pTimer->enmClock)
    692704    {
     
    704716
    705717        case TMCLOCK_TSC:
    706             return TMTimerSet(pTimer, TMTimerFromMicro(pTimer, cMicrosToNext) + TMCpuTickGet(pVM));
     718            return TMTimerSet(pTimer, TMTimerFromMicro(pTimer, cMicrosToNext) + TMCpuTickGet(pVCpu));
    707719
    708720        default:
     
    722734VMMDECL(int) TMTimerSetNano(PTMTIMER pTimer, uint64_t cNanosToNext)
    723735{
    724     PVM pVM = pTimer->CTX_SUFF(pVM);
     736    PVM    pVM   = pTimer->CTX_SUFF(pVM);
     737    PVMCPU pVCpu = &pVM->aCpus[0];  /* just take the first VCPU */
     738
    725739    switch (pTimer->enmClock)
    726740    {
     
    738752
    739753        case TMCLOCK_TSC:
    740             return TMTimerSet(pTimer, TMTimerFromNano(pTimer, cNanosToNext) + TMCpuTickGet(pVM));
     754            return TMTimerSet(pTimer, TMTimerFromNano(pTimer, cNanosToNext) + TMCpuTickGet(pVCpu));
    741755
    742756        default:
     
    847861{
    848862    uint64_t u64;
    849     PVM pVM = pTimer->CTX_SUFF(pVM);
     863    PVM      pVM   = pTimer->CTX_SUFF(pVM);
     864
    850865    switch (pTimer->enmClock)
    851866    {
     
    860875            break;
    861876        case TMCLOCK_TSC:
    862             u64 = TMCpuTickGet(pVM);
     877        {
     878            PVMCPU pVCpu = &pVM->aCpus[0];  /* just take the first VCPU */
     879            u64 = TMCpuTickGet(pVCpu);
    863880            break;
    864 
     881        }
    865882        default:
    866883            AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));
  • trunk/src/VBox/VMM/VMMAll/TMAllCpu.cpp

    r13586 r19032  
    5454 * @returns VBox status code.
    5555 * @param   pVM         The VM to operate on.
     56 * @param   pVCpu       The VMCPU to operate on.
    5657 * @internal
    5758 */
    58 int tmCpuTickResume(PVM pVM)
    59 {
    60     if (!pVM->tm.s.fTSCTicking)
    61     {
    62         pVM->tm.s.fTSCTicking = true;
     59int tmCpuTickResume(PVM pVM, PVMCPU pVCpu)
     60{
     61    if (!pVCpu->tm.s.fTSCTicking)
     62    {
     63        pVCpu->tm.s.fTSCTicking = true;
    6364        if (pVM->tm.s.fTSCVirtualized)
    6465        {
    6566            if (pVM->tm.s.fTSCUseRealTSC)
    66                 pVM->tm.s.u64TSCOffset = ASMReadTSC() - pVM->tm.s.u64TSC;
     67                pVCpu->tm.s.u64TSCOffset = ASMReadTSC() - pVCpu->tm.s.u64TSC;
    6768            else
    68                 pVM->tm.s.u64TSCOffset = tmCpuTickGetRawVirtual(pVM, false /* don't check for pending timers */)
    69                                        - pVM->tm.s.u64TSC;
     69                pVCpu->tm.s.u64TSCOffset = tmCpuTickGetRawVirtual(pVM, false /* don't check for pending timers */)
     70                                         - pVCpu->tm.s.u64TSC;
    7071        }
    7172        return VINF_SUCCESS;
     
    8081 *
    8182 * @returns VBox status code.
    82  * @param   pVM         The VM to operate on.
     83 * @param   pVCpu       The VMCPU to operate on.
    8384 * @todo replace this with TMNotifyResume
    8485 */
    85 VMMDECL(int) TMCpuTickResume(PVM pVM)
    86 {
     86VMMDECL(int) TMCpuTickResume(PVMCPU pVCpu)
     87{
     88    PVM pVM = pVCpu->CTX_SUFF(pVM);
     89
    8790    if (!pVM->tm.s.fTSCTiedToExecution)
    88         return tmCpuTickResume(pVM);
     91        return tmCpuTickResume(pVM, pVCpu);
    8992    /* ignored */
    9093    return VINF_SUCCESS;
     
    97100 * @returns VBox status code.
    98101 * @param   pVM         The VM to operate on.
     102 * @param   pVCpu       The VMCPU to operate on.
    99103 * @internal
    100104 */
    101 int tmCpuTickPause(PVM pVM)
    102 {
    103     if (pVM->tm.s.fTSCTicking)
    104     {
    105         pVM->tm.s.u64TSC = TMCpuTickGet(pVM);
    106         pVM->tm.s.fTSCTicking = false;
     105int tmCpuTickPause(PVM pVM, PVMCPU pVCpu)
     106{
     107    if (pVCpu->tm.s.fTSCTicking)
     108    {
     109        pVCpu->tm.s.u64TSC = TMCpuTickGet(pVCpu);
     110        pVCpu->tm.s.fTSCTicking = false;
    107111        return VINF_SUCCESS;
    108112    }
     
    116120 *
    117121 * @returns VBox status code.
    118  * @param   pVM         The VM to operate on.
     122 * @param   pVCpu       The VMCPU to operate on.
    119123 * @todo replace this with TMNotifySuspend
    120124 */
    121 VMMDECL(int) TMCpuTickPause(PVM pVM)
    122 {
     125VMMDECL(int) TMCpuTickPause(PVMCPU pVCpu)
     126{
     127    PVM pVM = pVCpu->CTX_SUFF(pVM);
     128
    123129    if (!pVM->tm.s.fTSCTiedToExecution)
    124         return tmCpuTickPause(pVM);
     130        return tmCpuTickPause(pVM, pVCpu);
    125131    /* ignored */
    126132    return VINF_SUCCESS;
     
    132138 *
    133139 * @returns true/false accordingly.
    134  * @param   pVM             The VM handle.
     140 * @param   pVCpu       The VMCPU to operate on.
    135141 * @param   poffRealTSC     The offset against the TSC of the current CPU.
    136142 *                          Can be NULL.
    137143 * @thread EMT.
    138144 */
    139 VMMDECL(bool) TMCpuTickCanUseRealTSC(PVM pVM, uint64_t *poffRealTSC)
    140 {
     145VMMDECL(bool) TMCpuTickCanUseRealTSC(PVMCPU pVCpu, uint64_t *poffRealTSC)
     146{
     147    PVM pVM = pVCpu->CTX_SUFF(pVM);
     148
    141149    /*
    142150     * We require:
     
    149157     */
    150158    if (    pVM->tm.s.fMaybeUseOffsettedHostTSC
    151         &&  RT_LIKELY(pVM->tm.s.fTSCTicking)
     159        &&  RT_LIKELY(pVCpu->tm.s.fTSCTicking)
    152160        &&  (   pVM->tm.s.fTSCUseRealTSC
    153161             || (   !pVM->tm.s.fVirtualSyncCatchUp
     
    164172            {
    165173                uint64_t u64Now = tmCpuTickGetRawVirtual(pVM, false /* don't check for pending timers */)
    166                                 - pVM->tm.s.u64TSCOffset;
     174                                - pVCpu->tm.s.u64TSCOffset;
    167175                /** @todo When we start collecting statistics on how much time we spend executing
    168176                 * guest code before exiting, we should check this against the next virtual sync
     
    176184            /* The source is the real TSC. */
    177185            if (pVM->tm.s.fTSCVirtualized)
    178                 *poffRealTSC = pVM->tm.s.u64TSCOffset;
     186                *poffRealTSC = pVCpu->tm.s.u64TSCOffset;
    179187            else
    180188                *poffRealTSC = 0;
     
    188196    if (!pVM->tm.s.fMaybeUseOffsettedHostTSC)
    189197       STAM_COUNTER_INC(&pVM->tm.s.StatTSCNotFixed);
    190     else if (!pVM->tm.s.fTSCTicking)
     198    else if (!pVCpu->tm.s.fTSCTicking)
    191199       STAM_COUNTER_INC(&pVM->tm.s.StatTSCNotTicking);
    192200    else if (!pVM->tm.s.fTSCUseRealTSC)
     
    217225 *
    218226 * @returns Gets the CPU tsc.
    219  * @param   pVM         The VM to operate on.
    220  */
    221 VMMDECL(uint64_t) TMCpuTickGet(PVM pVM)
    222 {
     227 * @param   pVCpu       The VMCPU to operate on.
     228 */
     229VMMDECL(uint64_t) TMCpuTickGet(PVMCPU pVCpu)
     230{
     231    PVM      pVM = pVCpu->CTX_SUFF(pVM);
    223232    uint64_t u64;
    224     if (RT_LIKELY(pVM->tm.s.fTSCTicking))
     233
     234    if (RT_LIKELY(pVCpu->tm.s.fTSCTicking))
    225235    {
    226236        if (pVM->tm.s.fTSCVirtualized)
     
    230240            else
    231241                u64 = tmCpuTickGetRawVirtual(pVM, true /* check for pending timers */);
    232             u64 -= pVM->tm.s.u64TSCOffset;
     242            u64 -= pVCpu->tm.s.u64TSCOffset;
    233243        }
    234244        else
     
    236246    }
    237247    else
    238         u64 = pVM->tm.s.u64TSC;
     248        u64 = pVCpu->tm.s.u64TSC;
    239249    return u64;
    240250}
     
    245255 *
    246256 * @returns VBox status code.
    247  * @param   pVM         The VM to operate on.
     257 * @param   pVCpu       The VMCPU to operate on.
    248258 * @param   u64Tick     The new timestamp value.
    249259 */
    250 VMMDECL(int) TMCpuTickSet(PVM pVM, uint64_t u64Tick)
    251 {
    252     Assert(!pVM->tm.s.fTSCTicking);
    253     pVM->tm.s.u64TSC = u64Tick;
     260VMMDECL(int) TMCpuTickSet(PVMCPU pVCpu, uint64_t u64Tick)
     261{
     262    Assert(!pVCpu->tm.s.fTSCTicking);
     263    pVCpu->tm.s.u64TSC = u64Tick;
    254264    return VINF_SUCCESS;
    255265}
  • trunk/src/VBox/VMM/VMMAll/TMAllVirtual.cpp

    r14299 r19032  
    3232#include "TMInternal.h"
    3333#include <VBox/vm.h>
     34#include <VBox/vmm.h>
    3435#include <VBox/err.h>
    3536#include <VBox/log.h>
     
    682683static DECLCALLBACK(int) tmVirtualSetWarpDrive(PVM pVM, uint32_t u32Percent)
    683684{
     685    PVMCPU pVCpu = VMMGetCpu(pVM);
     686
    684687    /*
    685688     * Validate it.
     
    698701        int rc = TMVirtualPause(pVM);
    699702        AssertRCReturn(rc, rc);
    700         rc = TMCpuTickPause(pVM);
     703        rc = TMCpuTickPause(pVCpu);
    701704        AssertRCReturn(rc, rc);
    702705    }
     
    711714        int rc = TMVirtualResume(pVM);
    712715        AssertRCReturn(rc, rc);
    713         rc = TMCpuTickResume(pVM);
     716        rc = TMCpuTickResume(pVCpu);
    714717        AssertRCReturn(rc, rc);
    715718    }
  • trunk/src/VBox/VMM/VMMGC/TRPMGCHandlers.cpp

    r19016 r19032  
    798798        return trpmGCExitTrap(pVM, VINF_EM_RAW_EMULATE_INSTR, pRegFrame); /* will trap (optimize later). */
    799799
    800     uint64_t uTicks = TMCpuTickGet(pVM);
     800    uint64_t uTicks = TMCpuTickGet(pVCpu);
    801801    pRegFrame->eax = uTicks;
    802802    pRegFrame->edx = uTicks >> 32;
  • trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp

    r19015 r19032  
    792792
    793793    /* TSC offset. */
    794     if (TMCpuTickCanUseRealTSC(pVM, &pVMCB->ctrl.u64TSCOffset))
     794    if (TMCpuTickCanUseRealTSC(pVCpu, &pVMCB->ctrl.u64TSCOffset))
    795795    {
    796796        pVMCB->ctrl.u32InterceptCtrl1 &= ~SVM_CTRL1_INTERCEPT_RDTSC;
     
    10531053    Assert(idCpuCheck == RTMpCpuId());
    10541054#endif
    1055     TMNotifyStartOfExecution(pVM);
     1055    TMNotifyStartOfExecution(pVCpu);
    10561056    pVCpu->hwaccm.s.svm.pfnVMRun(pVM->hwaccm.s.svm.pVMCBHostPhys, pVCpu->hwaccm.s.svm.pVMCBPhys, pCtx, pVM, pVCpu);
    1057     TMNotifyEndOfExecution(pVM);
     1057    TMNotifyEndOfExecution(pVCpu);
    10581058    STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatInGC, x);
    10591059
  • trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp

    r19015 r19032  
    16001600    uint64_t u64TSCOffset;
    16011601
    1602     if (TMCpuTickCanUseRealTSC(pVM, &u64TSCOffset))
     1602    if (TMCpuTickCanUseRealTSC(pVCpu, &u64TSCOffset))
    16031603    {
    16041604        /* Note: VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT takes precedence over TSC_OFFSET */
     
    21922192#endif
    21932193
    2194     TMNotifyStartOfExecution(pVM);
     2194    TMNotifyStartOfExecution(pVCpu);
    21952195    rc = pVCpu->hwaccm.s.vmx.pfnStartVM(pVCpu->hwaccm.s.fResumeVM, pCtx, &pVCpu->hwaccm.s.vmx.VMCSCache, pVM, pVCpu);
    2196     TMNotifyEndOfExecution(pVM);
     2196    TMNotifyEndOfExecution(pVCpu);
    21972197
    21982198    AssertMsg(!pVCpu->hwaccm.s.vmx.VMCSCache.Write.cValidEntries, ("pVCpu->hwaccm.s.vmx.VMCSCache.Write.cValidEntries=%d\n", pVCpu->hwaccm.s.vmx.VMCSCache.Write.cValidEntries));
  • trunk/src/VBox/VMM/VMMR0/VMMR0.cpp

    r18927 r19032  
    568568                }
    569569
    570                 TMNotifyStartOfExecution(pVM);
     570                TMNotifyStartOfExecution(pVCpu);
    571571                rc = pVM->vmm.s.pfnHostToGuestR0(pVM);
    572572                pVM->vmm.s.iLastGZRc = rc;
    573                 TMNotifyEndOfExecution(pVM);
     573                TMNotifyEndOfExecution(pVCpu);
    574574
    575575                /* Re-enable VT-x if previously turned off. */
  • trunk/src/VBox/VMM/testcase/tstVMStructGC.cpp

    r19015 r19032  
    761761    //GEN_CHECK_OFF(TM, pvGIPR0);
    762762    GEN_CHECK_OFF(TM, pvGIPRC);
    763     GEN_CHECK_OFF(TM, fTSCTicking);
     763    GEN_CHECK_OFF(TMCPU, fTSCTicking);
    764764    GEN_CHECK_OFF(TM, fTSCUseRealTSC);
    765765    GEN_CHECK_OFF(TM, fTSCTiedToExecution);
    766     GEN_CHECK_OFF(TM, u64TSCOffset);
    767     GEN_CHECK_OFF(TM, u64TSC);
     766    GEN_CHECK_OFF(TMCPU, u64TSCOffset);
     767    GEN_CHECK_OFF(TMCPU, u64TSC);
    768768    GEN_CHECK_OFF(TM, cTSCTicksPerSecond);
    769769    GEN_CHECK_OFF(TM, fVirtualTicking);
  • trunk/src/recompiler_new/VBoxREMWrapper.cpp

    r19015 r19032  
    11611161    { "STAMR3Register",                         (void *)(uintptr_t)&STAMR3Register,                 &g_aArgsSTAMR3Register[0],                  RT_ELEMENTS(g_aArgsSTAMR3Register),                    REMFNDESC_FLAGS_RET_INT,    sizeof(int),        NULL },
    11621162    { "STAMR3Deregister",                       (void *)(uintptr_t)&STAMR3Deregister,               &g_aArgsSTAMR3Deregister[0],                RT_ELEMENTS(g_aArgsSTAMR3Deregister),                  REMFNDESC_FLAGS_RET_INT,    sizeof(int),        NULL },
    1163     { "TMCpuTickGet",                           (void *)(uintptr_t)&TMCpuTickGet,                   &g_aArgsVM[0],                              RT_ELEMENTS(g_aArgsVM),                                REMFNDESC_FLAGS_RET_INT,    sizeof(uint64_t),   NULL },
    1164     { "TMCpuTickPause",                         (void *)(uintptr_t)&TMCpuTickPause,                 &g_aArgsVM[0],                              RT_ELEMENTS(g_aArgsVM),                                REMFNDESC_FLAGS_RET_INT,    sizeof(int),        NULL },
    1165     { "TMCpuTickResume",                        (void *)(uintptr_t)&TMCpuTickResume,                &g_aArgsVM[0],                              RT_ELEMENTS(g_aArgsVM),                                REMFNDESC_FLAGS_RET_INT,    sizeof(int),        NULL },
    1166     { "TMNotifyEndOfExecution",                 (void *)(uintptr_t)&TMNotifyEndOfExecution,         &g_aArgsVM[0],                              RT_ELEMENTS(g_aArgsVM),                                REMFNDESC_FLAGS_RET_VOID,   0,                  NULL },
    1167     { "TMNotifyStartOfExecution",               (void *)(uintptr_t)&TMNotifyStartOfExecution,       &g_aArgsVM[0],                              RT_ELEMENTS(g_aArgsVM),                                REMFNDESC_FLAGS_RET_VOID,   0,                  NULL },
     1163    { "TMCpuTickGet",                           (void *)(uintptr_t)&TMCpuTickGet,                   &g_aArgsVMCPU[0],                           RT_ELEMENTS(g_aArgsVMCPU),                             REMFNDESC_FLAGS_RET_INT,    sizeof(uint64_t),   NULL },
     1164    { "TMCpuTickPause",                         (void *)(uintptr_t)&TMCpuTickPause,                 &g_aArgsVMCPU[0],                           RT_ELEMENTS(g_aArgsVMCPU),                             REMFNDESC_FLAGS_RET_INT,    sizeof(int),        NULL },
     1165    { "TMCpuTickResume",                        (void *)(uintptr_t)&TMCpuTickResume,                &g_aArgsVMCPU[0],                           RT_ELEMENTS(g_aArgsVMCPU),                             REMFNDESC_FLAGS_RET_INT,    sizeof(int),        NULL },
     1166    { "TMNotifyEndOfExecution",                 (void *)(uintptr_t)&TMNotifyEndOfExecution,         &g_aArgsVMCPU[0],                           RT_ELEMENTS(g_aArgsVMCPU),                             REMFNDESC_FLAGS_RET_VOID,   0,                  NULL },
     1167    { "TMNotifyStartOfExecution",               (void *)(uintptr_t)&TMNotifyStartOfExecution,       &g_aArgsVMCPU[0],                           RT_ELEMENTS(g_aArgsVMCPU),                             REMFNDESC_FLAGS_RET_VOID,   0,                  NULL },
    11681168    { "TMTimerPoll",                            (void *)(uintptr_t)&TMTimerPoll,                    &g_aArgsVM[0],                              RT_ELEMENTS(g_aArgsVM),                                REMFNDESC_FLAGS_RET_INT,    sizeof(uint64_t),   NULL },
    11691169    { "TMR3TimerQueuesDo",                      (void *)(uintptr_t)&TMR3TimerQueuesDo,              &g_aArgsVM[0],                              RT_ELEMENTS(g_aArgsVM),                                REMFNDESC_FLAGS_RET_VOID,   0,                  NULL },
  • trunk/src/recompiler_new/VBoxRecompiler.c

    r19015 r19032  
    795795    if (rc == EXCP_DEBUG)
    796796    {
    797         TMCpuTickResume(pVM);
    798         TMCpuTickPause(pVM);
     797        TMCpuTickResume(pVCpu);
     798        TMCpuTickPause(pVCpu);
    799799        TMVirtualResume(pVM);
    800800        TMVirtualPause(pVM);
     
    924924         * Now we set the execute single instruction flag and enter the cpu_exec loop.
    925925         */
    926         TMNotifyStartOfExecution(pVM);
     926        TMNotifyStartOfExecution(pVCpu);
    927927        pVM->rem.s.Env.interrupt_request = CPU_INTERRUPT_SINGLE_INSTR;
    928928        rc = cpu_exec(&pVM->rem.s.Env);
    929         TMNotifyEndOfExecution(pVM);
     929        TMNotifyEndOfExecution(pVCpu);
    930930        switch (rc)
    931931        {
     
    10511051    Assert(pVM->rem.s.fInREM);
    10521052
    1053     TMNotifyStartOfExecution(pVM);
     1053    TMNotifyStartOfExecution(pVCpu);
    10541054    rc = cpu_exec(&pVM->rem.s.Env);
    1055     TMNotifyEndOfExecution(pVM);
     1055    TMNotifyEndOfExecution(pVCpu);
    10561056    switch (rc)
    10571057    {
     
    39953995{
    39963996    STAM_COUNTER_INC(&gStatCpuGetTSC);
    3997     return TMCpuTickGet(env->pVM);
     3997    return TMCpuTickGet(env->pVCpu);
    39983998}
    39993999
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette