VirtualBox

Changeset 54270 in vbox


Ignore:
Timestamp:
Feb 18, 2015 4:11:34 PM (10 years ago)
Author:
vboxsync
Message:

IPRT,TM: Implemented the get-cpu-number optimizations for the RTTimeNanoTS code.

Location:
trunk
Files:
16 edited

Legend:

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

    r54258 r54270  
    437437    /** The TSC of the cores are non-stop and have a constant frequency. */
    438438    SUPGIPMODE_INVARIANT_TSC,
     439    /** End of valid GIP mode values (exclusive). */
     440    SUPGIPMODE_END,
    439441    /** The usual 32-bit hack. */
    440442    SUPGIPMODE_32BIT_HACK = 0x7fffffff
  • trunk/include/iprt/mangling.h

    r54202 r54270  
    17191719# define RTTimeMilliTS                                  RT_MANGLER(RTTimeMilliTS)
    17201720# define RTTimeNanoTS                                   RT_MANGLER(RTTimeNanoTS)
    1721 # define RTTimeNanoTSLegacyAsync                        RT_MANGLER(RTTimeNanoTSLegacyAsync)
    1722 # define RTTimeNanoTSLegacyAsync_EndProc                RT_MANGLER(RTTimeNanoTSLegacyAsync_EndProc)
    1723 # define RTTimeNanoTSLegacyInvariantNoDelta             RT_MANGLER(RTTimeNanoTSLegacyInvariantNoDelta)
    1724 # define RTTimeNanoTSLegacyInvariantNoDelta_EndProc     RT_MANGLER(RTTimeNanoTSLegacyInvariantNoDelta_EndProc)
    1725 # define RTTimeNanoTSLegacyInvariantWithDelta           RT_MANGLER(RTTimeNanoTSLegacyInvariantWithDelta)
    1726 # define RTTimeNanoTSLegacyInvariantWithDelta_EndProc   RT_MANGLER(RTTimeNanoTSLegacyInvariantWithDelta_EndProc)
    1727 # define RTTimeNanoTSLegacySyncNoDelta                  RT_MANGLER(RTTimeNanoTSLegacySyncNoDelta)
    1728 # define RTTimeNanoTSLegacySyncNoDelta_EndProc          RT_MANGLER(RTTimeNanoTSLegacySyncNoDelta_EndProc)
    1729 # define RTTimeNanoTSLegacySyncWithDelta                RT_MANGLER(RTTimeNanoTSLegacySyncWithDelta)
    1730 # define RTTimeNanoTSLegacySyncWithDelta_EndProc        RT_MANGLER(RTTimeNanoTSLegacySyncWithDelta_EndProc)
    1731 # define RTTimeNanoTSLFenceAsync                        RT_MANGLER(RTTimeNanoTSLFenceAsync)
    1732 # define RTTimeNanoTSLFenceAsync_EndProc                RT_MANGLER(RTTimeNanoTSLFenceAsync_EndProc)
    1733 # define RTTimeNanoTSLFenceInvariantNoDelta             RT_MANGLER(RTTimeNanoTSLFenceInvariantNoDelta)
    1734 # define RTTimeNanoTSLFenceInvariantNoDelta_EndProc     RT_MANGLER(RTTimeNanoTSLFenceInvariantNoDelta_EndProc)
    1735 # define RTTimeNanoTSLFenceInvariantWithDelta           RT_MANGLER(RTTimeNanoTSLFenceInvariantWithDelta)
    1736 # define RTTimeNanoTSLFenceInvariantWithDelta_EndProc   RT_MANGLER(RTTimeNanoTSLFenceInvariantWithDelta_EndProc)
    1737 # define RTTimeNanoTSLFenceSyncNoDelta                  RT_MANGLER(RTTimeNanoTSLFenceSyncNoDelta)
    1738 # define RTTimeNanoTSLFenceSyncNoDelta_EndProc          RT_MANGLER(RTTimeNanoTSLFenceSyncNoDelta_EndProc)
    1739 # define RTTimeNanoTSLFenceSyncWithDelta                RT_MANGLER(RTTimeNanoTSLFenceSyncWithDelta)
    1740 # define RTTimeNanoTSLFenceSyncWithDelta_EndProc        RT_MANGLER(RTTimeNanoTSLFenceSyncWithDelta_EndProc)
     1721# define RTTimeNanoTSLegacyAsync                                RT_MANGLER(RTTimeNanoTSLegacyAsync)
     1722# define RTTimeNanoTSLegacyAsync_EndProc                        RT_MANGLER(RTTimeNanoTSLegacyAsync_EndProc)
     1723# define RTTimeNanoTSLegacyAsyncUseApicId                       RT_MANGLER(RTTimeNanoTSLegacyAsyncUseApicId)
     1724# define RTTimeNanoTSLegacyAsyncUseApicId_EndProc               RT_MANGLER(RTTimeNanoTSLegacyAsyncUseApicId_EndProc)
     1725# define RTTimeNanoTSLegacyAsyncUseRdtscp                       RT_MANGLER(RTTimeNanoTSLegacyAsyncUseRdtscp)
     1726# define RTTimeNanoTSLegacyAsyncUseRdtscp_EndProc               RT_MANGLER(RTTimeNanoTSLegacyAsyncUseRdtscp_EndProc)
     1727# define RTTimeNanoTSLegacyAsyncUseIdtrLim                      RT_MANGLER(RTTimeNanoTSLegacyAsyncUseIdtrLim)
     1728# define RTTimeNanoTSLegacyAsyncUseIdtrLim_EndProc              RT_MANGLER(RTTimeNanoTSLegacyAsyncUseIdtrLim_EndProc)
     1729# define RTTimeNanoTSLegacySyncInvarNoDelta                     RT_MANGLER(RTTimeNanoTSLegacySyncInvarNoDelta)
     1730# define RTTimeNanoTSLegacySyncInvarNoDelta_EndProc             RT_MANGLER(RTTimeNanoTSLegacySyncInvarNoDelta_EndProc)
     1731# define RTTimeNanoTSLegacySyncInvarWithDelta                   RT_MANGLER(RTTimeNanoTSLegacySyncInvarWithDelta)
     1732# define RTTimeNanoTSLegacySyncInvarWithDelta_EndProc           RT_MANGLER(RTTimeNanoTSLegacySyncInvarWithDelta_EndProc)
     1733# define RTTimeNanoTSLegacySyncInvarWithDeltaUseApicId          RT_MANGLER(RTTimeNanoTSLegacySyncInvarWithDeltaUseApicId)
     1734# define RTTimeNanoTSLegacySyncInvarWithDeltaUseApicId_EndProc  RT_MANGLER(RTTimeNanoTSLegacySyncInvarWithDeltaUseApicId_EndProc)
     1735# define RTTimeNanoTSLegacySyncInvarWithDeltaUseRdtscp          RT_MANGLER(RTTimeNanoTSLegacySyncInvarWithDeltaUseRdtscp)
     1736# define RTTimeNanoTSLegacySyncInvarWithDeltaUseRdtscp_EndProc  RT_MANGLER(RTTimeNanoTSLegacySyncInvarWithDeltaUseRdtscp_EndProc)
     1737# define RTTimeNanoTSLegacySyncInvarWithDeltaUseIdtrLim         RT_MANGLER(RTTimeNanoTSLegacySyncInvarWithDeltaUseIdtrLim)
     1738# define RTTimeNanoTSLegacySyncInvarWithDeltaUseIdtrLim_EndProc RT_MANGLER(RTTimeNanoTSLegacySyncInvarWithDeltaUseIdtrLim_EndProc)
     1739# define RTTimeNanoTSLFenceAsync                                RT_MANGLER(RTTimeNanoTSLFenceAsync)
     1740# define RTTimeNanoTSLFenceAsync_EndProc                        RT_MANGLER(RTTimeNanoTSLFenceAsync_EndProc)
     1741# define RTTimeNanoTSLFenceAsyncUseApicId                       RT_MANGLER(RTTimeNanoTSLFenceAsyncUseApicId)
     1742# define RTTimeNanoTSLFenceAsyncUseApicId_EndProc               RT_MANGLER(RTTimeNanoTSLFenceAsyncUseApicId_EndProc)
     1743# define RTTimeNanoTSLFenceAsyncUseRdtscp                       RT_MANGLER(RTTimeNanoTSLFenceAsyncUseRdtscp)
     1744# define RTTimeNanoTSLFenceAsyncUseRdtscp_EndProc               RT_MANGLER(RTTimeNanoTSLFenceAsyncUseRdtscp_EndProc)
     1745# define RTTimeNanoTSLFenceAsyncUseIdtrLim                      RT_MANGLER(RTTimeNanoTSLFenceAsyncUseIdtrLim)
     1746# define RTTimeNanoTSLFenceAsyncUseIdtrLim_EndProc              RT_MANGLER(RTTimeNanoTSLFenceAsyncUseIdtrLim_EndProc)
     1747# define RTTimeNanoTSLFenceSyncInvarNoDelta                     RT_MANGLER(RTTimeNanoTSLFenceSyncInvarNoDelta)
     1748# define RTTimeNanoTSLFenceSyncInvarNoDelta_EndProc             RT_MANGLER(RTTimeNanoTSLFenceSyncInvarNoDelta_EndProc)
     1749# define RTTimeNanoTSLFenceSyncInvarWithDelta                   RT_MANGLER(RTTimeNanoTSLFenceSyncInvarWithDelta)
     1750# define RTTimeNanoTSLFenceSyncInvarWithDelta_EndProc           RT_MANGLER(RTTimeNanoTSLFenceSyncInvarWithDelta_EndProc)
     1751# define RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicId          RT_MANGLER(RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicId)
     1752# define RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicId_EndProc  RT_MANGLER(RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicId_EndProc)
     1753# define RTTimeNanoTSLFenceSyncInvarWithDeltaUseRdtscp          RT_MANGLER(RTTimeNanoTSLFenceSyncInvarWithDeltaUseRdtscp)
     1754# define RTTimeNanoTSLFenceSyncInvarWithDeltaUseRdtscp_EndProc  RT_MANGLER(RTTimeNanoTSLFenceSyncInvarWithDeltaUseRdtscp_EndProc)
     1755# define RTTimeNanoTSLFenceSyncInvarWithDeltaUseIdtrLim         RT_MANGLER(RTTimeNanoTSLFenceSyncInvarWithDeltaUseIdtrLim)
     1756# define RTTimeNanoTSLFenceSyncInvarWithDeltaUseIdtrLim_EndProc RT_MANGLER(RTTimeNanoTSLFenceSyncInvarWithDeltaUseIdtrLim_EndProc)
    17411757# define RTTimeNormalize                                RT_MANGLER(RTTimeNormalize)
    17421758# define RTTimeNow                                      RT_MANGLER(RTTimeNow)
  • trunk/include/iprt/time.h

    r54202 r54270  
    840840    DECLCALLBACKMEMBER(uint64_t, pfnRediscover)(PRTTIMENANOTSDATA pData);
    841841
    842     /** Just a dummy alignment member. */
    843     void               *pvDummy;
     842    /**
     843     * Callback for when some CPU index related stuff goes wrong.
     844     *
     845     * @returns Nanosecond timestamp.
     846     * @param   pData           Pointer to this structure.
     847     * @param   idApic          The APIC ID if available, otherwise (UINT16_MAX-1).
     848     * @param   iCpuSet         The CPU set index if available, otherwise
     849     *                          (UINT16_MAX-1).
     850     * @param   iGipCpu         The GIP CPU array index if available, otherwise
     851     *                          (UINT16_MAX-1).
     852     */
     853    DECLCALLBACKMEMBER(uint64_t, pfnBadCpuIndex)(PRTTIMENANOTSDATA pData, uint16_t idApic, uint16_t iCpuSet, uint16_t iGipCpu);
    844854
    845855    /** Number of 1ns steps because of overshooting the period. */
     
    862872    DECLR3CALLBACKMEMBER(void, pfnBad,(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS));
    863873    DECLR3CALLBACKMEMBER(uint64_t, pfnRediscover,(PRTTIMENANOTSDATA pData));
    864     RTR3PTR             pvDummy;
     874    DECLR3CALLBACKMEMBER(uint64_t, pfnBadCpuIndex,(PRTTIMENANOTSDATA pData, uint16_t idApic, uint16_t iCpuSet, uint16_t iGipCpu));
    865875    uint32_t            c1nsSteps;
    866876    uint32_t            cExpired;
     
    881891    DECLR0CALLBACKMEMBER(void, pfnBad,(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS));
    882892    DECLR0CALLBACKMEMBER(uint64_t, pfnRediscover,(PRTTIMENANOTSDATA pData));
    883     RTR0PTR             pvDummy;
     893    DECLR0CALLBACKMEMBER(uint64_t, pfnBadCpuIndex,(PRTTIMENANOTSDATA pData, uint16_t idApic, uint16_t iCpuSet, uint16_t iGipCpu));
    884894    uint32_t            c1nsSteps;
    885895    uint32_t            cExpired;
     
    900910    DECLRCCALLBACKMEMBER(void, pfnBad,(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS));
    901911    DECLRCCALLBACKMEMBER(uint64_t, pfnRediscover,(PRTTIMENANOTSDATA pData));
    902     RCPTRTYPE(void *)   pvDummy;
     912    DECLRCCALLBACKMEMBER(uint64_t, pfnBadCpuIndex,(PRTTIMENANOTSDATA pData, uint16_t idApic, uint16_t iCpuSet, uint16_t iGipCpu));
    903913    uint32_t            c1nsSteps;
    904914    uint32_t            cExpired;
     
    914924/** Pointer to an internal RTTimeNanoTS worker (assembly). */
    915925typedef FNTIMENANOTSINTERNAL *PFNTIMENANOTSINTERNAL;
    916 
     926RTDECL(uint64_t) RTTimeNanoTSLegacySyncInvarNoDelta(PRTTIMENANOTSDATA pData);
     927RTDECL(uint64_t) RTTimeNanoTSLFenceSyncInvarNoDelta(PRTTIMENANOTSDATA pData);
     928#ifdef IN_RING3
     929RTDECL(uint64_t) RTTimeNanoTSLegacyAsyncUseApicId(PRTTIMENANOTSDATA pData);
     930RTDECL(uint64_t) RTTimeNanoTSLegacyAsyncUseRdtscp(PRTTIMENANOTSDATA pData);
     931RTDECL(uint64_t) RTTimeNanoTSLegacyAsyncUseIdtrLim(PRTTIMENANOTSDATA pData);
     932RTDECL(uint64_t) RTTimeNanoTSLegacySyncInvarWithDeltaUseApicId(PRTTIMENANOTSDATA pData);
     933RTDECL(uint64_t) RTTimeNanoTSLegacySyncInvarWithDeltaUseRdtscp(PRTTIMENANOTSDATA pData);
     934RTDECL(uint64_t) RTTimeNanoTSLegacySyncInvarWithDeltaUseIdtrLim(PRTTIMENANOTSDATA pData);
     935RTDECL(uint64_t) RTTimeNanoTSLFenceAsyncUseApicId(PRTTIMENANOTSDATA pData);
     936RTDECL(uint64_t) RTTimeNanoTSLFenceAsyncUseRdtscp(PRTTIMENANOTSDATA pData);
     937RTDECL(uint64_t) RTTimeNanoTSLFenceAsyncUseIdtrLim(PRTTIMENANOTSDATA pData);
     938RTDECL(uint64_t) RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicId(PRTTIMENANOTSDATA pData);
     939RTDECL(uint64_t) RTTimeNanoTSLFenceSyncInvarWithDeltaUseRdtscp(PRTTIMENANOTSDATA pData);
     940RTDECL(uint64_t) RTTimeNanoTSLFenceSyncInvarWithDeltaUseIdtrLim(PRTTIMENANOTSDATA pData);
     941#else
    917942RTDECL(uint64_t) RTTimeNanoTSLegacyAsync(PRTTIMENANOTSDATA pData);
    918 RTDECL(uint64_t) RTTimeNanoTSLegacyInvariantNoDelta(PRTTIMENANOTSDATA pData);
    919 RTDECL(uint64_t) RTTimeNanoTSLegacyInvariantWithDelta(PRTTIMENANOTSDATA pData);
    920 RTDECL(uint64_t) RTTimeNanoTSLegacySyncNoDelta(PRTTIMENANOTSDATA pData);
    921 RTDECL(uint64_t) RTTimeNanoTSLegacySyncWithDelta(PRTTIMENANOTSDATA pData);
     943RTDECL(uint64_t) RTTimeNanoTSLegacySyncInvarWithDelta(PRTTIMENANOTSDATA pData);
    922944RTDECL(uint64_t) RTTimeNanoTSLFenceAsync(PRTTIMENANOTSDATA pData);
    923 RTDECL(uint64_t) RTTimeNanoTSLFenceInvariantNoDelta(PRTTIMENANOTSDATA pData);
    924 RTDECL(uint64_t) RTTimeNanoTSLFenceInvariantWithDelta(PRTTIMENANOTSDATA pData);
    925 RTDECL(uint64_t) RTTimeNanoTSLFenceSyncNoDelta(PRTTIMENANOTSDATA pData);
    926 RTDECL(uint64_t) RTTimeNanoTSLFenceSyncWithDelta(PRTTIMENANOTSDATA pData);
     945RTDECL(uint64_t) RTTimeNanoTSLFenceSyncInvarWithDelta(PRTTIMENANOTSDATA pData);
     946#endif
    927947
    928948/** @} */
  • trunk/src/VBox/Runtime/VBox/VBoxRTImp.def

    r54207 r54270  
    13371337    RTTimeMilliTS
    13381338    RTTimeNanoTS
    1339     RTTimeNanoTSLegacyInvariantNoDelta
    1340     RTTimeNanoTSLegacyInvariantWithDelta
    1341     RTTimeNanoTSLegacySyncNoDelta
    1342     RTTimeNanoTSLegacySyncWithDelta
    1343     RTTimeNanoTSLegacyAsync
    1344     RTTimeNanoTSLFenceInvariantNoDelta
    1345     RTTimeNanoTSLFenceInvariantWithDelta
    1346     RTTimeNanoTSLFenceSyncNoDelta
    1347     RTTimeNanoTSLFenceSyncWithDelta
    1348     RTTimeNanoTSLFenceAsync
     1339    RTTimeNanoTSLegacySyncInvarNoDelta
     1340    RTTimeNanoTSLFenceSyncInvarNoDelta
     1341    RTTimeNanoTSLegacyAsyncUseApicId
     1342    RTTimeNanoTSLegacyAsyncUseRdtscp
     1343    RTTimeNanoTSLegacyAsyncUseIdtrLim
     1344    RTTimeNanoTSLegacySyncInvarWithDeltaUseApicId
     1345    RTTimeNanoTSLegacySyncInvarWithDeltaUseRdtscp
     1346    RTTimeNanoTSLegacySyncInvarWithDeltaUseIdtrLim
     1347    RTTimeNanoTSLFenceAsyncUseApicId
     1348    RTTimeNanoTSLFenceAsyncUseRdtscp
     1349    RTTimeNanoTSLFenceAsyncUseIdtrLim
     1350    RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicId
     1351    RTTimeNanoTSLFenceSyncInvarWithDeltaUseRdtscp
     1352    RTTimeNanoTSLFenceSyncInvarWithDeltaUseIdtrLim
    13491353    RTTimeNormalize
    13501354    RTTimeNow
  • trunk/src/VBox/Runtime/common/time/timesup.cpp

    r54252 r54270  
    5252static DECLCALLBACK(uint64_t) rtTimeNanoTSInternalFallback(PRTTIMENANOTSDATA pData);
    5353static DECLCALLBACK(uint64_t) rtTimeNanoTSInternalRediscover(PRTTIMENANOTSDATA pData);
     54static DECLCALLBACK(uint64_t) rtTimeNanoTSInternalBadCpuIndex(PRTTIMENANOTSDATA pData, uint16_t idApic, uint16_t iCpuSet, uint16_t iGipCpu);
    5455#endif
    5556
     
    6566static RTTIMENANOTSDATA g_TimeNanoTSData =
    6667{
    67     /* .pu64Prev      = */ &g_TimeNanoTSPrev,
    68     /* .pfnBad        = */ rtTimeNanoTSInternalBitch,
    69     /* .pfnRediscover = */ rtTimeNanoTSInternalRediscover,
    70     /* .pvDummy       = */ NULL,
    71     /* .c1nsSteps     = */ 0,
    72     /* .cExpired      = */ 0,
    73     /* .cBadPrev      = */ 0,
    74     /* .cUpdateRaces  = */ 0
     68    /* .pu64Prev       = */ &g_TimeNanoTSPrev,
     69    /* .pfnBad         = */ rtTimeNanoTSInternalBitch,
     70    /* .pfnRediscover  = */ rtTimeNanoTSInternalRediscover,
     71    /* .pfnBadCpuIndex = */ rtTimeNanoTSInternalBadCpuIndex,
     72    /* .c1nsSteps      = */ 0,
     73    /* .cExpired       = */ 0,
     74    /* .cBadPrev       = */ 0,
     75    /* .cUpdateRaces   = */ 0
    7576};
    7677
    77 /** The index into g_apfnWorkers for the function to use.
    78  * This cannot be a pointer because that'll break down in GC due to code relocation. */
    79 static uint32_t             g_iWorker = 0;
     78# ifdef IN_RC
    8079/** Array of rtTimeNanoTSInternal worker functions.
    8180 * This array is indexed by g_iWorker. */
    8281static const PFNTIMENANOTSINTERNAL g_apfnWorkers[] =
    8382{
    84 # define RTTIMENANO_WORKER_DETECT                   0
     83#  define RTTIMENANO_WORKER_DETECT                                      0
    8584    rtTimeNanoTSInternalRediscover,
    8685
    87 # define RTTIMENANO_WORKER_LEGACY_SYNC_NO_DELTA     1
    88     RTTimeNanoTSLegacySyncNoDelta,
    89 # define RTTIMENANO_WORKER_LEGACY_SYNC_WITH_DELTA   2
    90     RTTimeNanoTSLegacySyncWithDelta,
    91 # define RTTIMENANO_WORKER_LEGACY_ASYNC             3
     86#  define RTTIMENANO_WORKER_LEGACY_SYNC_INVAR_NO_DELTA                  1
     87    RTTimeNanoTSLegacySyncInvarNoDelta,
     88#  define RTTIMENANO_WORKER_LEGACY_SYNC_INVAR_WITH_DELTA                2
     89    RTTimeNanoTSLegacySyncInvarWithDelta,
     90#  define RTTIMENANO_WORKER_LEGACY_ASYNC                                3
    9291    RTTimeNanoTSLegacyAsync,
    93 # define RTTIMENANO_WORKER_LEGACY_INVAR_NO_DELTA    4
    94     RTTimeNanoTSLFenceInvariantNoDelta,
    95 # define RTTIMENANO_WORKER_LEGACY_INVAR_WITH_DELTA  5
    96     RTTimeNanoTSLFenceInvariantWithDelta,
    97 
    98 # define RTTIMENANO_WORKER_LFENCE_SYNC_NO_DELTA     6
    99     RTTimeNanoTSLFenceSyncNoDelta,
    100 # define RTTIMENANO_WORKER_LFENCE_SYNC_WITH_DELTA   7
    101     RTTimeNanoTSLFenceSyncWithDelta,
    102 # define RTTIMENANO_WORKER_LFENCE_ASYNC             8
     92
     93#  define RTTIMENANO_WORKER_LFENCE_SYNC_INVAR_NO_DELTA                  4
     94    RTTimeNanoTSLFenceSyncInvarNoDelta,
     95#  define RTTIMENANO_WORKER_LFENCE_SYNC_INVAR_WITH_DELTA                5
     96    RTTimeNanoTSLFenceSyncInvarWithDelta,
     97#  define RTTIMENANO_WORKER_LFENCE_ASYNC                                6
    10398    RTTimeNanoTSLFenceAsync,
    104 # define RTTIMENANO_WORKER_LFENCE_INVAR_NO_DELTA    9
    105     RTTimeNanoTSLFenceInvariantNoDelta,
    106 # define RTTIMENANO_WORKER_LFENCE_INVAR_WITH_DELTA  10
    107     RTTimeNanoTSLFenceInvariantWithDelta,
    108 
    109 # define RTTIMENANO_WORKER_FALLBACK                 11
     99
     100#  define RTTIMENANO_WORKER_FALLBACK                                    7
    110101    rtTimeNanoTSInternalFallback,
    111102};
    112 
    113 
    114 /**
    115  * Helper function that's used by the assembly routines when something goes bust.
    116  *
    117  * @param   pData           Pointer to the data structure.
    118  * @param   u64NanoTS       The calculated nano ts.
    119  * @param   u64DeltaPrev    The delta relative to the previously returned timestamp.
    120  * @param   u64PrevNanoTS   The previously returned timestamp (as it was read it).
    121  */
    122 static DECLCALLBACK(void) rtTimeNanoTSInternalBitch(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS)
     103/** The index into g_apfnWorkers for the function to use.
     104 * @remarks This cannot be a pointer because that'll break down in RC due to
     105 *          code relocation. */
     106static uint32_t                 g_iWorker   = RTTIMENANO_WORKER_DETECT;
     107# else
     108/** Pointer to the worker */
     109static PFNTIMENANOTSINTERNAL    g_pfnWorker = rtTimeNanoTSInternalRediscover;
     110# endif /* IN_RC */
     111
     112
     113/**
     114 * @interface_method_impl{RTTIMENANOTSDATA, pfnBad}
     115 */
     116static DECLCALLBACK(void) rtTimeNanoTSInternalBitch(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev,
     117                                                    uint64_t u64PrevNanoTS)
    123118{
    124119    pData->cBadPrev++;
     
    130125             u64DeltaPrev, u64PrevNanoTS, u64NanoTS));
    131126}
     127
     128/**
     129 * @interface_method_impl{RTTIMENANOTSDATA, pfnBadCpuIndex}
     130 */
     131static DECLCALLBACK(uint64_t) rtTimeNanoTSInternalBadCpuIndex(PRTTIMENANOTSDATA pData, uint16_t idApic,
     132                                                              uint16_t iCpuSet, uint16_t iGipCpu)
     133{
     134# ifndef IN_RC
     135    AssertMsgFailed(("idApic=%#x iCpuSet=%#x iGipCpu=%#x\n", idApic, iCpuSet, iGipCpu));
     136    return RTTimeSystemNanoTS();
     137# else
     138    RTAssertReleasePanic();
     139    return 0;
     140# endif
     141}
     142
    132143
    133144/**
     
    147158    return RTTimeSystemNanoTS();
    148159# else
     160    RTAssertReleasePanic();
    149161    return 0;
    150162# endif
     
    158170static DECLCALLBACK(uint64_t) rtTimeNanoTSInternalRediscover(PRTTIMENANOTSDATA pData)
    159171{
    160     uint32_t iWorker;
    161     PSUPGLOBALINFOPAGE pGip = g_pSUPGlobalInfoPage;
     172    PSUPGLOBALINFOPAGE      pGip = g_pSUPGlobalInfoPage;
     173# ifdef IN_RC
     174    uint32_t                iWorker;
     175# else
     176    PFNTIMENANOTSINTERNAL   pfnWorker;
     177# endif
    162178    if (    pGip
    163179        &&  pGip->u32Magic == SUPGLOBALINFOPAGE_MAGIC
     
    167183    {
    168184        if (ASMCpuId_EDX(1) & X86_CPUID_FEATURE_EDX_SSE2)
    169             iWorker = pGip->u32Mode == SUPGIPMODE_INVARIANT_TSC
    170                     ? pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO
    171                       ? RTTIMENANO_WORKER_LFENCE_INVAR_NO_DELTA : RTTIMENANO_WORKER_LFENCE_INVAR_WITH_DELTA
    172                     : pGip->u32Mode == SUPGIPMODE_SYNC_TSC
    173                     ? pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO
    174                       ? RTTIMENANO_WORKER_LFENCE_SYNC_NO_DELTA  : RTTIMENANO_WORKER_LFENCE_SYNC_WITH_DELTA
    175                     : RTTIMENANO_WORKER_LFENCE_ASYNC;
     185        {
     186# ifdef IN_RC
     187            iWorker   = pGip->u32Mode == SUPGIPMODE_ASYNC_TSC
     188                      ? RTTIMENANO_WORKER_LFENCE_ASYNC
     189                      : pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO
     190                      ? RTTIMENANO_WORKER_LFENCE_SYNC_INVAR_NO_DELTA
     191                      : RTTIMENANO_WORKER_LFENCE_SYNC_INVAR_WITH_DELTA;
     192# elif defined(IN_RING0)
     193            pfnWorker = pGip->u32Mode == SUPGIPMODE_ASYNC_TSC
     194                      ? RTTimeNanoTSLFenceAsync
     195                      : pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO
     196                      ? RTTimeNanoTSLFenceSyncInvarNoDelta
     197                      : RTTimeNanoTSLFenceSyncInvarWithDelta;
     198# else
     199            if (pGip->u32Mode == SUPGIPMODE_ASYNC_TSC)
     200                pfnWorker = pGip->fGetGipCpu & SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS
     201                          ? RTTimeNanoTSLFenceAsyncUseIdtrLim
     202                          : pGip->fGetGipCpu & SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS
     203                          ? RTTimeNanoTSLFenceAsyncUseRdtscp
     204                          : pGip->fGetGipCpu & SUPGIPGETCPU_APIC_ID
     205                          ? RTTimeNanoTSLFenceAsyncUseApicId
     206                          : rtTimeNanoTSInternalFallback;
     207           else
     208               pfnWorker = pGip->fGetGipCpu & SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS
     209                         ? pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_PRACTICALLY_ZERO
     210                           ? RTTimeNanoTSLFenceSyncInvarNoDelta
     211                           : RTTimeNanoTSLFenceSyncInvarWithDeltaUseIdtrLim
     212                         : pGip->fGetGipCpu & SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS
     213                         ?   pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_PRACTICALLY_ZERO
     214                           ? RTTimeNanoTSLFenceSyncInvarNoDelta
     215                           : RTTimeNanoTSLFenceSyncInvarWithDeltaUseRdtscp
     216                         : pGip->fGetGipCpu & SUPGIPGETCPU_APIC_ID
     217                         ? pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO
     218                           ? RTTimeNanoTSLFenceSyncInvarNoDelta
     219                           : RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicId
     220                         : rtTimeNanoTSInternalFallback;
     221# endif
     222        }
    176223        else
    177             iWorker = pGip->u32Mode == SUPGIPMODE_INVARIANT_TSC
    178                     ? pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO
    179                       ? RTTIMENANO_WORKER_LEGACY_INVAR_NO_DELTA : RTTIMENANO_WORKER_LEGACY_INVAR_WITH_DELTA
    180                     : pGip->u32Mode == SUPGIPMODE_SYNC_TSC
    181                     ? pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO
    182                       ? RTTIMENANO_WORKER_LEGACY_SYNC_NO_DELTA  : RTTIMENANO_WORKER_LEGACY_SYNC_WITH_DELTA
    183                     : RTTIMENANO_WORKER_LEGACY_ASYNC;
     224        {
     225# ifdef IN_RC
     226            iWorker = pGip->u32Mode == SUPGIPMODE_ASYNC_TSC
     227                    ? RTTIMENANO_WORKER_LEGACY_ASYNC
     228                    : pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO
     229                    ? RTTIMENANO_WORKER_LEGACY_SYNC_INVAR_NO_DELTA :  RTTIMENANO_WORKER_LEGACY_SYNC_INVAR_WITH_DELTA;
     230# elif defined(IN_RING0)
     231            pfnWorker = pGip->u32Mode == SUPGIPMODE_ASYNC_TSC
     232                      ? RTTimeNanoTSLegacyAsync
     233                      : pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO
     234                      ? RTTimeNanoTSLegacySyncInvarNoDelta
     235                      : RTTimeNanoTSLegacySyncInvarWithDelta;
     236# else
     237            if (pGip->u32Mode == SUPGIPMODE_ASYNC_TSC)
     238                pfnWorker = pGip->fGetGipCpu & SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS
     239                          ? RTTimeNanoTSLegacyAsyncUseRdtscp
     240                          : pGip->fGetGipCpu & SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS
     241                          ? RTTimeNanoTSLegacyAsyncUseIdtrLim
     242                          : pGip->fGetGipCpu & SUPGIPGETCPU_APIC_ID
     243                          ? RTTimeNanoTSLegacyAsyncUseApicId
     244                          : rtTimeNanoTSInternalFallback;
     245           else
     246               pfnWorker = pGip->fGetGipCpu & SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS
     247                         ?   pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_PRACTICALLY_ZERO
     248                           ? RTTimeNanoTSLegacySyncInvarNoDelta
     249                           : RTTimeNanoTSLegacySyncInvarWithDeltaUseRdtscp
     250                         : pGip->fGetGipCpu & SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS
     251                         ? pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_PRACTICALLY_ZERO
     252                           ? RTTimeNanoTSLegacySyncInvarNoDelta
     253                           : RTTimeNanoTSLegacySyncInvarWithDeltaUseIdtrLim
     254                         : pGip->fGetGipCpu & SUPGIPGETCPU_APIC_ID
     255                         ? pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO
     256                           ? RTTimeNanoTSLegacySyncInvarNoDelta
     257                           : RTTimeNanoTSLegacySyncInvarWithDeltaUseApicId
     258                         : rtTimeNanoTSInternalFallback;
     259# endif
     260        }
    184261    }
    185262    else
     263# ifdef IN_RC
    186264        iWorker = RTTIMENANO_WORKER_FALLBACK;
    187 
     265# else
     266        pfnWorker = rtTimeNanoTSInternalFallback;
     267# endif
     268
     269# ifdef IN_RC
    188270    ASMAtomicWriteU32((uint32_t volatile *)&g_iWorker, iWorker);
    189271    return g_apfnWorkers[iWorker](pData);
     272# else
     273    ASMAtomicWritePtr((void * volatile *)&g_pfnWorker, (void *)(uintptr_t)pfnWorker);
     274    return pfnWorker(pData);
     275# endif
    190276}
    191277
     
    199285{
    200286#if !defined(IN_GUEST) && !defined(RT_NO_GIP)
     287# ifdef IN_RC
    201288    return g_apfnWorkers[g_iWorker](&g_TimeNanoTSData);
     289# else
     290    return g_pfnWorker(&g_TimeNanoTSData);
     291# endif
    202292#else
    203293    return RTTimeSystemNanoTS();
  • trunk/src/VBox/Runtime/common/time/timesupA.asm

    r54202 r54270  
    2929%include "iprt/asmdefs.mac"
    3030%include "VBox/sup.mac"
     31
     32;
     33; Use the C reference implementation for now.
     34;
     35%error "This is out of date, use C code.  Not worth it for a couple of ticks in some functions and equal or worse performance in others."
     36This is out of date
     37This is out of date
     38This is out of date
    3139
    3240
  • trunk/src/VBox/Runtime/common/time/timesupref.cpp

    r54202 r54270  
    3737#include <iprt/asm-amd64-x86.h>
    3838#include <VBox/sup.h>
     39#ifdef IN_RC
     40# include <VBox/vmm/vmm.h>
     41# include <VBox/vmm/vm.h>
     42#endif
    3943#include "internal/time.h"
    4044
    4145
    42 #define GIP_MODE_SYNC_NO_DELTA          1
    43 #define GIP_MODE_SYNC_WITH_DELTA        2
    44 #define GIP_MODE_ASYNC                  3
    45 #define GIP_MODE_INVARIANT_NO_DELTA     4
    46 #define GIP_MODE_INVARIANT_WITH_DELTA   5
    47 #define IS_GIP_MODE_WITH_DELTA(a_enmMode) \
    48     ((a_enmMode) == GIP_MODE_SYNC_WITH_DELTA || (a_enmMode) == GIP_MODE_INVARIANT_WITH_DELTA)
     46#define TMPL_MODE_SYNC_INVAR_NO_DELTA       1
     47#define TMPL_MODE_SYNC_INVAR_WITH_DELTA     2
     48#define TMPL_MODE_ASYNC                     3
    4949
    5050
    5151/*
    52  * Use the CPUID instruction for some kind of serialization.
    53  */
    54 #define GIP_MODE GIP_MODE_SYNC_NO_DELTA
    55 #undef  USE_LFENCE
    56 #define NEED_TRANSACTION_ID
    57 #define rtTimeNanoTSInternalRef RTTimeNanoTSLegacySyncNoDelta
     52 * Use the XCHG instruction for some kind of serialization.
     53 */
     54#define TMPL_READ_FENCE()        ASMReadFence()
     55
     56#undef  TMPL_MODE
     57#define TMPL_MODE                TMPL_MODE_SYNC_INVAR_NO_DELTA
     58#undef  TMPL_GET_CPU_METHOD
     59#define TMPL_GET_CPU_METHOD      0
     60#undef  rtTimeNanoTSInternalRef
     61#define rtTimeNanoTSInternalRef  RTTimeNanoTSLegacySyncInvarNoDelta
    5862#include "timesupref.h"
    59 RT_EXPORT_SYMBOL(RTTimeNanoTSLegacySyncNoDelta);
    60 
    61 #undef  GIP_MODE
    62 #define GIP_MODE  GIP_MODE_SYNC_NO_DELTA
    63 #undef  rtTimeNanoTSInternalRef
    64 #define rtTimeNanoTSInternalRef RTTimeNanoTSLegacySyncWithDelta
    65 #include "timesupref.h"
    66 RT_EXPORT_SYMBOL(RTTimeNanoTSLegacySyncWithDelta);
    67 
    68 #undef  GIP_MODE
    69 #define GIP_MODE GIP_MODE_ASYNC
    70 #ifdef IN_RC
    71 # undef NEED_TRANSACTION_ID
     63RT_EXPORT_SYMBOL(RTTimeNanoTSLegacySyncInvarNoDelta);
     64
     65#ifdef IN_RING3
     66
     67# undef  TMPL_MODE
     68# define TMPL_MODE               TMPL_MODE_SYNC_INVAR_WITH_DELTA
     69# undef  TMPL_GET_CPU_METHOD
     70# define TMPL_GET_CPU_METHOD     SUPGIPGETCPU_APIC_ID
     71# undef  rtTimeNanoTSInternalRef
     72# define rtTimeNanoTSInternalRef RTTimeNanoTSLegacySyncInvarWithDeltaUseApicId
     73# include "timesupref.h"
     74RT_EXPORT_SYMBOL(RTTimeNanoTSLegacySyncInvarWithDeltaUseApicId);
     75
     76# undef  TMPL_GET_CPU_METHOD
     77# define TMPL_GET_CPU_METHOD     SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS
     78# undef  rtTimeNanoTSInternalRef
     79# define rtTimeNanoTSInternalRef RTTimeNanoTSLegacySyncInvarWithDeltaUseRdtscp
     80# include "timesupref.h"
     81RT_EXPORT_SYMBOL(RTTimeNanoTSLegacySyncInvarWithDeltaUseRdtscp);
     82
     83# undef  TMPL_GET_CPU_METHOD
     84# define TMPL_GET_CPU_METHOD     SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS
     85# undef  rtTimeNanoTSInternalRef
     86# define rtTimeNanoTSInternalRef RTTimeNanoTSLegacySyncInvarWithDeltaUseIdtrLim
     87# include "timesupref.h"
     88RT_EXPORT_SYMBOL(RTTimeNanoTSLegacySyncInvarWithDeltaUseIdtrLim);
     89
     90# undef  TMPL_MODE
     91# define TMPL_MODE               TMPL_MODE_ASYNC
     92# undef  TMPL_GET_CPU_METHOD
     93# define TMPL_GET_CPU_METHOD     SUPGIPGETCPU_APIC_ID
     94# undef  rtTimeNanoTSInternalRef
     95# define rtTimeNanoTSInternalRef RTTimeNanoTSLegacyAsyncUseApicId
     96# include "timesupref.h"
     97RT_EXPORT_SYMBOL(RTTimeNanoTSLegacyAsyncUseApicId);
     98
     99# undef  TMPL_GET_CPU_METHOD
     100# define TMPL_GET_CPU_METHOD     SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS
     101# undef  rtTimeNanoTSInternalRef
     102# define rtTimeNanoTSInternalRef RTTimeNanoTSLegacyAsyncUseRdtscp
     103# include "timesupref.h"
     104RT_EXPORT_SYMBOL(RTTimeNanoTSLegacyAsyncUseRdtscp);
     105
     106# undef  TMPL_GET_CPU_METHOD
     107# define TMPL_GET_CPU_METHOD     SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS
     108# undef  rtTimeNanoTSInternalRef
     109# define rtTimeNanoTSInternalRef RTTimeNanoTSLegacyAsyncUseIdtrLim
     110# include "timesupref.h"
     111RT_EXPORT_SYMBOL(RTTimeNanoTSLegacyAsyncUseIdtrLim);
     112
     113#else  /* IN_RC || IN_RING0: Disable interrupts and call getter function. */
     114
     115# undef  TMPL_MODE
     116# define TMPL_MODE               TMPL_MODE_SYNC_INVAR_WITH_DELTA
     117# undef  TMPL_GET_CPU_METHOD
     118# define TMPL_GET_CPU_METHOD     UINT32_MAX
     119# undef  rtTimeNanoTSInternalRef
     120# define rtTimeNanoTSInternalRef RTTimeNanoTSLegacySyncInvarWithDelta
     121# include "timesupref.h"
     122RT_EXPORT_SYMBOL(RTTimeNanoTSLegacySyncInvarWithDelta);
     123
     124# undef  TMPL_MODE
     125# define TMPL_MODE TMPL_MODE_ASYNC
     126# undef  rtTimeNanoTSInternalRef
     127# define rtTimeNanoTSInternalRef RTTimeNanoTSLegacyAsync
     128# include "timesupref.h"
     129RT_EXPORT_SYMBOL(RTTimeNanoTSLegacyAsync);
     130
    72131#endif
    73 #undef  rtTimeNanoTSInternalRef
    74 #define rtTimeNanoTSInternalRef RTTimeNanoTSLegacyAsync
    75 #include "timesupref.h"
    76 RT_EXPORT_SYMBOL(RTTimeNanoTSLegacyAsync);
    77 
    78 #undef  GIP_MODE
    79 #define GIP_MODE GIP_MODE_INVARIANT_NO_DELTA
    80 #undef  NEED_TRANSACTION_ID
    81 #define NEED_TRANSACTION_ID
    82 #undef  rtTimeNanoTSInternalRef
    83 #define rtTimeNanoTSInternalRef RTTimeNanoTSLegacyInvariantNoDelta
    84 #include "timesupref.h"
    85 RT_EXPORT_SYMBOL(RTTimeNanoTSLegacyInvariantNoDelta);
    86 
    87 #undef  GIP_MODE
    88 #define GIP_MODE GIP_MODE_INVARIANT_WITH_DELTA
    89 #undef  rtTimeNanoTSInternalRef
    90 #define rtTimeNanoTSInternalRef RTTimeNanoTSLegacyInvariantWithDelta
    91 #include "timesupref.h"
    92 RT_EXPORT_SYMBOL(RTTimeNanoTSLegacyInvariantWithDelta);
    93132
    94133
     
    96135 * Use LFENCE for load serialization.
    97136 */
    98 #undef  GIP_MODE
    99 #define GIP_MODE GIP_MODE_SYNC_NO_DELTA
    100 #define USE_LFENCE
    101 #undef  NEED_TRANSACTION_ID
    102 #define NEED_TRANSACTION_ID
     137#undef  TMPL_READ_FENCE
     138#define TMPL_READ_FENCE()        ASMReadFenceSSE2()
     139
     140#undef  TMPL_MODE
     141#define TMPL_MODE                TMPL_MODE_SYNC_INVAR_NO_DELTA
     142#undef  TMPL_GET_CPU_METHOD
     143#define TMPL_GET_CPU_METHOD      0
    103144#undef  rtTimeNanoTSInternalRef
    104 #define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceSyncNoDelta
     145#define rtTimeNanoTSInternalRef  RTTimeNanoTSLFenceSyncInvarNoDelta
    105146#include "timesupref.h"
    106 RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceSyncNoDelta);
    107 
    108 #undef  GIP_MODE
    109 #define GIP_MODE GIP_MODE_SYNC_WITH_DELTA
    110 #undef  rtTimeNanoTSInternalRef
    111 #define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceSyncWithDelta
    112 #include "timesupref.h"
    113 RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceSyncWithDelta);
    114 
    115 #undef  GIP_MODE
    116 #define GIP_MODE GIP_MODE_ASYNC
    117 #ifdef IN_RC
    118 # undef NEED_TRANSACTION_ID
     147RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceSyncInvarNoDelta);
     148
     149#ifdef IN_RING3
     150
     151# undef  TMPL_MODE
     152# define TMPL_MODE               TMPL_MODE_SYNC_INVAR_WITH_DELTA
     153# undef  TMPL_GET_CPU_METHOD
     154# define TMPL_GET_CPU_METHOD     SUPGIPGETCPU_APIC_ID
     155# undef  rtTimeNanoTSInternalRef
     156# define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicId
     157# include "timesupref.h"
     158RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicId);
     159
     160# undef  TMPL_GET_CPU_METHOD
     161# define TMPL_GET_CPU_METHOD     SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS
     162# undef  rtTimeNanoTSInternalRef
     163# define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceSyncInvarWithDeltaUseRdtscp
     164# include "timesupref.h"
     165RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceSyncInvarWithDeltaUseRdtscp);
     166
     167# undef  TMPL_GET_CPU_METHOD
     168# define TMPL_GET_CPU_METHOD     SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS
     169# undef  rtTimeNanoTSInternalRef
     170# define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceSyncInvarWithDeltaUseIdtrLim
     171# include "timesupref.h"
     172RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceSyncInvarWithDeltaUseIdtrLim);
     173
     174# undef  TMPL_MODE
     175# define TMPL_MODE               TMPL_MODE_ASYNC
     176# undef  TMPL_GET_CPU_METHOD
     177# define TMPL_GET_CPU_METHOD     SUPGIPGETCPU_APIC_ID
     178# undef  rtTimeNanoTSInternalRef
     179# define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceAsyncUseApicId
     180# include "timesupref.h"
     181RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceAsyncUseApicId);
     182
     183# undef  TMPL_GET_CPU_METHOD
     184# define TMPL_GET_CPU_METHOD     SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS
     185# undef  rtTimeNanoTSInternalRef
     186# define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceAsyncUseRdtscp
     187# include "timesupref.h"
     188RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceAsyncUseRdtscp);
     189
     190# undef  TMPL_GET_CPU_METHOD
     191# define TMPL_GET_CPU_METHOD     SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS
     192# undef  rtTimeNanoTSInternalRef
     193# define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceAsyncUseIdtrLim
     194# include "timesupref.h"
     195RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceAsyncUseIdtrLim);
     196
     197#else  /* IN_RC || IN_RING0: Disable interrupts and call getter function. */
     198
     199# undef  TMPL_MODE
     200# define TMPL_MODE               TMPL_MODE_SYNC_INVAR_WITH_DELTA
     201# undef  TMPL_GET_CPU_METHOD
     202# define TMPL_GET_CPU_METHOD     UINT32_MAX
     203# undef  rtTimeNanoTSInternalRef
     204# define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceSyncInvarWithDelta
     205# include "timesupref.h"
     206RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceSyncInvarWithDelta);
     207
     208# undef  TMPL_MODE
     209# define TMPL_MODE TMPL_MODE_ASYNC
     210# undef  rtTimeNanoTSInternalRef
     211# define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceAsync
     212# include "timesupref.h"
     213RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceAsync);
     214
    119215#endif
    120 #undef  rtTimeNanoTSInternalRef
    121 #define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceAsync
    122 #include "timesupref.h"
    123 RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceAsync);
    124 
    125 #undef  GIP_MODE
    126 #define GIP_MODE GIP_MODE_INVARIANT_NO_DELTA
    127 #undef  NEED_TRANSACTION_ID
    128 #define NEED_TRANSACTION_ID
    129 #undef  rtTimeNanoTSInternalRef
    130 #define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceInvariantNoDelta
    131 #include "timesupref.h"
    132 RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceInvariantNoDelta);
    133 
    134 #undef  GIP_MODE
    135 #define GIP_MODE GIP_MODE_INVARIANT_WITH_DELTA
    136 #undef  rtTimeNanoTSInternalRef
    137 #define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceInvariantWithDelta
    138 #include "timesupref.h"
    139 RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceInvariantWithDelta);
    140216
    141217
  • trunk/src/VBox/Runtime/common/time/timesupref.h

    r54202 r54270  
    4545{
    4646    uint64_t    u64Delta;
    47 #if IS_GIP_MODE_WITH_DELTA(GIP_MODE)
     47#if TMPL_MODE == TMPL_MODE_SYNC_INVAR_WITH_DELTA
    4848    int64_t     i64TscDelta;
     49# ifdef IN_RING3
     50    PSUPGIPCPU  pGipCpuAttemptedTscRecalibration = NULL;
     51# endif
    4952#endif
    5053    uint32_t    u32NanoTSFactor0;
     
    5356    uint32_t    u32UpdateIntervalTSC;
    5457    uint64_t    u64PrevNanoTS;
     58    AssertCompile(RT_IS_POWER_OF_TWO(RTCPUSET_MAX_CPUS));
    5559
    5660    /*
     
    5963    for (;;)
    6064    {
     65#ifndef IN_RING3 /* This simplifies and improves everything. */
     66        RTCCUINTREG const  uFlags = ASMIntDisableFlags();
     67#endif
     68
     69        /*
     70         * Check that the GIP is sane and that the premises for this worker function
     71         * hasn't changed (CPU onlined with bad delta or missing features).
     72         */
    6173        PSUPGLOBALINFOPAGE pGip = g_pSUPGlobalInfoPage;
    62 #ifdef IN_RING3
    63         if (RT_UNLIKELY(!pGip || pGip->u32Magic != SUPGLOBALINFOPAGE_MAGIC))
    64             return pData->pfnRediscover(pData);
    65 #endif
    66 #if GIP_MODE == GIP_MODE_ASYNC || IS_GIP_MODE_WITH_DELTA(GIP_MODE)
    67         uint8_t const u8ApicId  = ASMGetApicId();
    68         PSUPGIPCPU pGipCpu      = &pGip->aCPUs[pGip->aiCpuFromApicId[u8ApicId]];
    69 #endif
    70 
    71 #ifdef NEED_TRANSACTION_ID
    72 # if GIP_MODE == GIP_MODE_ASYNC
    73         uint32_t u32TransactionId = pGipCpu->u32TransactionId;
     74        if (   RT_LIKELY(pGip)
     75            && RT_LIKELY(pGip->u32Magic == SUPGLOBALINFOPAGE_MAGIC)
     76#if TMPL_MODE == TMPL_MODE_SYNC_INVAR_WITH_DELTA
     77            && RT_LIKELY(pGip->enmUseTscDelta >= SUPGIPUSETSCDELTA_PRACTICALLY_ZERO)
     78#else
     79            && RT_LIKELY(pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO)
     80#endif
     81#if defined(IN_RING3) && TMPL_GET_CPU_METHOD != 0 && TMPL_GET_CPU_METHOD != SUPGIPGETCPU_APIC_ID
     82            && RT_LIKELY(pGip->fGetGipCpu & TMPL_GET_CPU_METHOD)
     83#endif
     84           )
     85        {
     86            /*
     87             * Resolve pGipCpu if needed.  If the instruction is serializing, we
     88             * read the transaction id first if possible.
     89             */
     90#if TMPL_MODE == TMPL_MODE_ASYNC || TMPL_MODE == TMPL_MODE_SYNC_INVAR_WITH_DELTA
     91# if   defined(IN_RING0)
     92            uint32_t const  iCpuSet  = RTMpCpuIdToSetIndex(RTMpCpuId());
     93            uint16_t const  iGipCpu  = iCpuSet < RT_ELEMENTS(pGip->aiCpuFromCpuSetIdx)
     94                                     ? pGip->aiCpuFromCpuSetIdx[iCpuSet] : UINT16_MAX;
     95# elif defined(IN_RC)
     96            uint32_t const  iCpuSet  = VMMGetCpu(&g_VM)->iHostCpuSet;
     97            uint16_t const  iGipCpu  = iCpuSet < RT_ELEMENTS(pGip->aiCpuFromCpuSetIdx)
     98                                     ? pGip->aiCpuFromCpuSetIdx[iCpuSet] : UINT16_MAX;
     99# elif TMPL_GET_CPU_METHOD == SUPGIPGETCPU_APIC_ID
     100#  if TMPL_MODE != TMPL_MODE_ASYNC
     101            uint32_t const  u32TransactionId = pGip->aCPUs[0].u32TransactionId;
     102#  endif
     103            uint8_t  const  idApic   = ASMGetApicId();
     104            uint16_t const  iGipCpu  = pGip->aiCpuFromApicId[idApic];
     105# elif TMPL_GET_CPU_METHOD == SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS
     106#  if TMPL_MODE != TMPL_MODE_ASYNC
     107            uint32_t const  u32TransactionId = pGip->aCPUs[0].u32TransactionId;
     108#  endif
     109            uint32_t        uAux;
     110            ASMReadTscWithAux(&uAux);
     111            uint16_t const  iCpuSet  = uAux & (RTCPUSET_MAX_CPUS - 1);
     112            uint16_t const  iGipCpu  = pGip->aiCpuFromCpuSetIdx[iCpuSet];
     113# elif TMPL_GET_CPU_METHOD == SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS
     114            uint16_t const  cbLim    = ASMGetIdtrLimit();
     115            uint16_t const  iCpuSet  = (cbLim - 256 * (ARCH_BITS == 64 ? 16 : 8)) & (RTCPUSET_MAX_CPUS - 1);
     116            uint16_t const  iGipCpu  = pGip->aiCpuFromCpuSetIdx[iCpuSet];
    74117# else
    75         uint32_t u32TransactionId = pGip->aCPUs[0].u32TransactionId;
    76 # endif
    77 # ifdef USE_LFENCE
    78         ASMReadFenceSSE2();
     118#  error "What?"
     119# endif
     120            if (RT_LIKELY(iGipCpu < pGip->cCpus))
     121            {
     122                PSUPGIPCPU pGipCpu = &pGip->aCPUs[iGipCpu];
     123#else
     124            {
     125#endif
     126                /*
     127                 * Get the transaction ID if necessary and we haven't already
     128                 * read it before a serializing instruction above.  We can skip
     129                 * this for ASYNC_TSC mode in ring-0 and raw-mode context since
     130                 * we disable interrupts.
     131                 */
     132#if TMPL_MODE == TMPL_MODE_ASYNC && defined(IN_RING3)
     133                uint32_t const u32TransactionId = pGipCpu->u32TransactionId;
     134                ASMCompilerBarrier();
     135                TMPL_READ_FENCE();
     136#elif TMPL_MODE != TMPL_MODE_ASYNC \
     137   && TMPL_GET_CPU_METHOD != SUPGIPGETCPU_APIC_ID \
     138   && TMPL_GET_CPU_METHOD != SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS
     139                uint32_t const u32TransactionId = pGip->aCPUs[0].u32TransactionId;
     140                ASMCompilerBarrier();
     141                TMPL_READ_FENCE();
     142#endif
     143
     144                /*
     145                 * Gather all the data we need.  The mess at the end is to make
     146                 * sure all loads are done before we recheck the transaction ID
     147                 * without triggering serializing twice.
     148                 */
     149                u32NanoTSFactor0        = pGip->u32UpdateIntervalNS;
     150#if TMPL_MODE == TMPL_MODE_ASYNC
     151                u32UpdateIntervalTSC    = pGipCpu->u32UpdateIntervalTSC;
     152                u64NanoTS               = pGipCpu->u64NanoTS;
     153                u64TSC                  = pGipCpu->u64TSC;
     154#else
     155                u32UpdateIntervalTSC    = pGip->aCPUs[0].u32UpdateIntervalTSC;
     156                u64NanoTS               = pGip->aCPUs[0].u64NanoTS;
     157                u64TSC                  = pGip->aCPUs[0].u64TSC;
     158# if TMPL_MODE == TMPL_MODE_SYNC_INVAR_WITH_DELTA
     159                i64TscDelta             = pGipCpu->i64TSCDelta;
     160# endif
     161#endif
     162#if TMPL_GET_CPU_METHOD == SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS
     163                u64PrevNanoTS           = ASMAtomicUoReadU64(pData->pu64Prev);
     164                ASMCompilerBarrier();
     165                uint32_t uAux2;
     166                u64Delta                = ASMReadTscWithAux(&uAux2); /* serializing */
     167#else
     168                u64Delta                = ASMReadTSC();
     169                u64PrevNanoTS           = ASMAtomicUoReadU64(pData->pu64Prev);
     170                ASMCompilerBarrier();
     171# if TMPL_GET_CPU_METHOD != SUPGIPGETCPU_APIC_ID /* getting APIC will serialize  */ \
     172  && (defined(IN_RING3) || TMPL_MODE != TMPL_MODE_ASYNC)
     173                TMPL_READ_FENCE(); /* Expensive (~30 ticks).  Would like convincing argumentation that let us remove it. */
     174# endif
     175#endif
     176
     177                /*
     178                 * Check that we didn't change CPU.
     179                 */
     180#if defined(IN_RING3) && ( TMPL_MODE == TMPL_MODE_ASYNC || TMPL_MODE == TMPL_MODE_SYNC_INVAR_WITH_DELTA )
     181# if   TMPL_GET_CPU_METHOD == SUPGIPGETCPU_APIC_ID
     182                if (RT_LIKELY(ASMGetApicId() == idApic))
     183# elif TMPL_GET_CPU_METHOD == SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS
     184                if (RT_LIKELY(uAux2 == uAux))
     185# elif TMPL_GET_CPU_METHOD == SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS
     186                if (RT_LIKELY(ASMGetIdtrLimit() == cbLim))
     187# endif
     188#endif
     189                {
     190                    /*
     191                     * Check the transaction ID (see above for R0/RC + ASYNC).
     192                     */
     193#if defined(IN_RING3) || TMPL_MODE != TMPL_MODE_ASYNC
     194# if TMPL_MODE == TMPL_MODE_ASYNC
     195                    if (RT_LIKELY(pGipCpu->u32TransactionId       == u32TransactionId && !(u32TransactionId & 1) ))
    79196# else
    80         ASMReadFence();
    81 # endif
    82 #endif
    83 
    84 #if GIP_MODE == GIP_MODE_ASYNC
    85         u32UpdateIntervalTSC    = pGipCpu->u32UpdateIntervalTSC;
    86         u64NanoTS               = pGipCpu->u64NanoTS;
    87         u64TSC                  = pGipCpu->u64TSC;
    88 #else
    89         u32UpdateIntervalTSC    = pGip->aCPUs[0].u32UpdateIntervalTSC;
    90         u64NanoTS               = pGip->aCPUs[0].u64NanoTS;
    91         u64TSC                  = pGip->aCPUs[0].u64TSC;
    92 # if IS_GIP_MODE_WITH_DELTA(GIP_MODE)
    93         i64TscDelta             = pGipCpu->i64TSCDelta;
    94 # endif
    95 #endif
    96         u32NanoTSFactor0        = pGip->u32UpdateIntervalNS;
    97         u64Delta                = ASMReadTSC();
    98         u64PrevNanoTS           = ASMAtomicReadU64(pData->pu64Prev);
    99 
    100 #ifdef NEED_TRANSACTION_ID
    101 # if GIP_MODE == GIP_MODE_ASYNC || IS_GIP_MODE_WITH_DELTA(GIP_MODE)
    102         if (RT_UNLIKELY(u8ApicId != ASMGetApicId()))
    103             continue;
    104 # elif defined(USE_LFENCE)
    105         ASMWriteFenceSSE();
     197                    if (RT_LIKELY(pGip->aCPUs[0].u32TransactionId == u32TransactionId && !(u32TransactionId & 1) ))
     198# endif
     199#endif
     200                    {
     201
     202                        /*
     203                         * Apply the TSC delta.  If the delta is invalid and the
     204                         * execution allows it, try trigger delta recalibration.
     205                         */
     206#if TMPL_MODE == TMPL_MODE_SYNC_INVAR_WITH_DELTA && defined(IN_RING3)
     207                        if (RT_LIKELY(   i64TscDelta != INT64_MAX
     208                                      || pGipCpu == pGipCpuAttemptedTscRecalibration))
     209#endif
     210                        {
     211#if TMPL_MODE == TMPL_MODE_SYNC_INVAR_WITH_DELTA
     212# ifndef IN_RING3
     213                            if (RT_LIKELY(i64TscDelta != INT64_MAX))
     214# endif
     215                                u64Delta -= i64TscDelta;
     216#endif
     217
     218                            /*
     219                             * Bingo! We've got a consistent set of data.
     220                             */
     221#ifndef IN_RING3
     222                            ASMSetFlags(uFlags);
     223#endif
     224                            break;
     225                        }
     226#if TMPL_MODE == TMPL_MODE_SYNC_INVAR_WITH_DELTA && defined(IN_RING3)
     227                        /*
     228                         * Call into the support driver to try make it recalculate the delta. We
     229                         * remember which GIP CPU structure we're probably working on so we won't
     230                         * end up in a loop if the driver for some reason cannot get the job done.
     231                         */
     232                        else /* else is unecessary, but helps checking the preprocessor spaghetti. */
     233                        {
     234                            pGipCpuAttemptedTscRecalibration = pGipCpu;
     235                            uint64_t u64TscTmp;
     236                            uint16_t idApicUpdate;
     237                            int rc = SUPR3ReadTsc(&u64TscTmp, &idApicUpdate);
     238                            if (RT_SUCCESS(rc) && idApicUpdate <= RT_ELEMENTS(pGip->aiCpuFromApicId))
     239                            {
     240                                uint32_t iUpdateGipCpu = pGip->aiCpuFromApicId[idApicUpdate];
     241                                if (iUpdateGipCpu < pGip->cCpus)
     242                                    pGipCpuAttemptedTscRecalibration = &pGip->aCPUs[iUpdateGipCpu];
     243                            }
     244                        }
     245#endif
     246                    }
     247                }
     248
     249                /*
     250                 * No joy must try again.
     251                 */
     252#ifndef IN_RING3
     253                ASMSetFlags(uFlags);
     254#endif
     255                ASMNopPause();
     256                continue;
     257            }
     258
     259#if TMPL_MODE == TMPL_MODE_ASYNC || TMPL_MODE == TMPL_MODE_SYNC_INVAR_WITH_DELTA
     260            /*
     261             * We've got a bad CPU or APIC index of some kind.
     262             */
     263            else /* else is unecessary, but helps checking the preprocessor spaghetti. */
     264            {
     265# ifndef IN_RING3
     266                ASMSetFlags(uFlags);
     267# endif
     268# if defined(IN_RING0) || defined(IN_RC) || TMPL_GET_CPU_METHOD != SUPGIPGETCPU_APIC_ID
     269                return pData->pfnBadCpuIndex(pData, UINT16_MAX-1, iCpuSet, iGipCpu);
    106270# else
    107         ASMWriteFence();
    108 # endif
    109 # if GIP_MODE == GIP_MODE_ASYNC
    110         if (RT_UNLIKELY(   pGipCpu->u32TransactionId != u32TransactionId
    111                         || (u32TransactionId & 1)))
    112             continue;
    113 # else
    114         if (RT_UNLIKELY(   pGip->aCPUs[0].u32TransactionId != u32TransactionId
    115                         || (u32TransactionId & 1)))
    116             continue;
    117 # endif
    118 #endif
    119         break;
     271                return pData->pfnBadCpuIndex(pData, idApic, UINT16_MAX-1, iGipCpu);
     272# endif
     273            }
     274#endif
     275        }
     276
     277        /*
     278         * Something changed in the GIP config or it was unmapped, figure out
     279         * the right worker function to use now.
     280         */
     281#ifndef IN_RING3
     282        ASMSetFlags(uFlags);
     283#endif
     284        return pData->pfnRediscover(pData);
    120285    }
    121286
     
    124289     */
    125290    u64Delta -= u64TSC;
    126 #if IS_GIP_MODE_WITH_DELTA(GIP_MODE)
    127     if (RT_LIKELY(i64TscDelta != INT64_MAX))
    128         u64Delta -= i64TscDelta;
    129 #endif
    130291    if (RT_UNLIKELY(u64Delta > u32UpdateIntervalTSC))
    131292    {
  • trunk/src/VBox/Runtime/r3/win/VBoxRT-win32.def

    r54207 r54270  
    2828    ASMMultU64ByU32DivByU32
    2929
    30     RTTimeNanoTSLegacyInvariantNoDelta
    31     RTTimeNanoTSLegacyInvariantWithDelta
    32     RTTimeNanoTSLegacySyncNoDelta
    33     RTTimeNanoTSLegacySyncWithDelta
    34     RTTimeNanoTSLegacyAsync
    35     RTTimeNanoTSLFenceInvariantNoDelta
    36     RTTimeNanoTSLFenceInvariantWithDelta
    37     RTTimeNanoTSLFenceSyncNoDelta
    38     RTTimeNanoTSLFenceSyncWithDelta
    39     RTTimeNanoTSLFenceAsync
     30    RTTimeNanoTSLegacySyncInvarNoDelta
     31    RTTimeNanoTSLFenceSyncInvarNoDelta
     32    RTTimeNanoTSLegacyAsyncUseApicId
     33    RTTimeNanoTSLegacyAsyncUseRdtscp
     34    RTTimeNanoTSLegacyAsyncUseIdtrLim
     35    RTTimeNanoTSLegacySyncInvarWithDeltaUseApicId
     36    RTTimeNanoTSLegacySyncInvarWithDeltaUseRdtscp
     37    RTTimeNanoTSLegacySyncInvarWithDeltaUseIdtrLim
     38    RTTimeNanoTSLFenceAsyncUseApicId
     39    RTTimeNanoTSLFenceAsyncUseRdtscp
     40    RTTimeNanoTSLFenceAsyncUseIdtrLim
     41    RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicId
     42    RTTimeNanoTSLFenceSyncInvarWithDeltaUseRdtscp
     43    RTTimeNanoTSLFenceSyncInvarWithDeltaUseIdtrLim
    4044
  • trunk/src/VBox/Runtime/r3/win/VBoxRT-win64.def

    r54207 r54270  
    4040    ASMNopPause
    4141
    42     RTTimeNanoTSLegacyInvariantNoDelta
    43     RTTimeNanoTSLegacyInvariantWithDelta
    44     RTTimeNanoTSLegacySyncNoDelta
    45     RTTimeNanoTSLegacySyncWithDelta
    46     RTTimeNanoTSLegacyAsync
    47     RTTimeNanoTSLFenceInvariantNoDelta
    48     RTTimeNanoTSLFenceInvariantWithDelta
    49     RTTimeNanoTSLFenceSyncNoDelta
    50     RTTimeNanoTSLFenceSyncWithDelta
    51     RTTimeNanoTSLFenceAsync
     42    RTTimeNanoTSLegacySyncInvarNoDelta
     43    RTTimeNanoTSLFenceSyncInvarNoDelta
     44    RTTimeNanoTSLegacyAsyncUseApicId
     45    RTTimeNanoTSLegacyAsyncUseRdtscp
     46    RTTimeNanoTSLegacyAsyncUseIdtrLim
     47    RTTimeNanoTSLegacySyncInvarWithDeltaUseApicId
     48    RTTimeNanoTSLegacySyncInvarWithDeltaUseRdtscp
     49    RTTimeNanoTSLegacySyncInvarWithDeltaUseIdtrLim
     50    RTTimeNanoTSLFenceAsyncUseApicId
     51    RTTimeNanoTSLFenceAsyncUseRdtscp
     52    RTTimeNanoTSLFenceAsyncUseIdtrLim
     53    RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicId
     54    RTTimeNanoTSLFenceSyncInvarWithDeltaUseRdtscp
     55    RTTimeNanoTSLFenceSyncInvarWithDeltaUseIdtrLim
    5256
  • trunk/src/VBox/Runtime/testcase/Makefile.kmk

    r52297 r54270  
    371371        $(PATH_STAGE_LIB)/DisasmRC$(VBOX_SUFF_LIB) \
    372372        $(PATH_STAGE_LIB)/RuntimeRC$(VBOX_SUFF_LIB)
    373  ifeq ($(VBOX_LDR_FMT32),pe)
     373 if1of ($(VBOX_LDR_FMT32),lx pe)
    374374 tstLdrObj_LIBS += \
    375         $(PATH_STAGE_LIB)/VMMRCBuiltin$(VBOX_SUFF_LIB)
    376  endif # PE
    377  ifeq ($(VBOX_LDR_FMT32),lx)
    378  tstLdrObj_LIBS += \
    379         $(PATH_STAGE_LIB)/VMMRCBuiltin$(VBOX_SUFF_LIB)
     375        $(PATH_STAGE_LIB)/VMMRCBuiltin$(VBOX_SUFF_LIB) \
     376        $(PATH_STAGE_LIB)/VMMRCImp$(VBOX_SUFF_LIB)
    380377 endif
    381378endif # VBOX_WITH_RAW_MODE
  • trunk/src/VBox/VMM/VMMAll/TMAllVirtual.cpp

    r53789 r54270  
    4444
    4545/**
    46  * Helper function that's used by the assembly routines when something goes bust.
    47  *
    48  * @param   pData           Pointer to the data structure.
    49  * @param   u64NanoTS       The calculated nano ts.
    50  * @param   u64DeltaPrev    The delta relative to the previously returned timestamp.
    51  * @param   u64PrevNanoTS   The previously returned timestamp (as it was read it).
    52  */
    53 DECLEXPORT(void) tmVirtualNanoTSBad(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS)
    54 {
    55     //PVM pVM = (PVM)((uint8_t *)pData - RT_OFFSETOF(VM, CTXALLSUFF(s.tm.VirtualGetRawData)));
     46 * @interface_method_impl{RTTIMENANOTSDATA, pfnBadPrev}
     47 */
     48DECLEXPORT(void) tmVirtualNanoTSBadPrev(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev,
     49                                        uint64_t u64PrevNanoTS)
     50{
     51    PVM pVM = RT_FROM_MEMBER(pData, VM, CTX_SUFF(tm.s.VirtualGetRawData));
    5652    pData->cBadPrev++;
    5753    if ((int64_t)u64DeltaPrev < 0)
    58         LogRel(("TM: u64DeltaPrev=%RI64 u64PrevNanoTS=0x%016RX64 u64NanoTS=0x%016RX64\n",
    59                 u64DeltaPrev, u64PrevNanoTS, u64NanoTS));
     54        LogRel(("TM: u64DeltaPrev=%RI64 u64PrevNanoTS=0x%016RX64 u64NanoTS=0x%016RX64 pVM=%p\n",
     55                u64DeltaPrev, u64PrevNanoTS, u64NanoTS, pVM));
    6056    else
    61         Log(("TM: u64DeltaPrev=%RI64 u64PrevNanoTS=0x%016RX64 u64NanoTS=0x%016RX64 (debugging?)\n",
    62              u64DeltaPrev, u64PrevNanoTS, u64NanoTS));
    63 }
    64 
    65 
    66 /**
    67  * Called the first time somebody asks for the time or when the GIP
    68  * is mapped/unmapped.
    69  *
    70  * This should never ever happen.
     57        Log(("TM: u64DeltaPrev=%RI64 u64PrevNanoTS=0x%016RX64 u64NanoTS=0x%016RX64 pVM=%p (debugging?)\n",
     58             u64DeltaPrev, u64PrevNanoTS, u64NanoTS, pVM));
     59}
     60
     61
     62/**
     63 * @interface_method_impl{RTTIMENANOTSDATA, pfnRediscover}
     64 *
     65 * This is the initial worker, so the first call in each context ends up here.
     66 * It is also used should the delta rating of the host CPUs change or if the
     67 * fGetGipCpu feature the current worker relies upon becomes unavailable.  The
     68 * last two events may occur as CPUs are taken online.
    7169 */
    7270DECLEXPORT(uint64_t) tmVirtualNanoTSRediscover(PRTTIMENANOTSDATA pData)
    7371{
    74     NOREF(pData);
    75     //PVM pVM = (PVM)((uint8_t *)pData - RT_OFFSETOF(VM, CTXALLSUFF(s.tm.VirtualGetRawData)));
     72    PVM pVM = RT_FROM_MEMBER(pData, VM, CTX_SUFF(tm.s.VirtualGetRawData));
     73
     74    /*
     75     * We require a valid GIP for the selection below.  Invalid GIP is fatal.
     76     */
    7677    PSUPGLOBALINFOPAGE pGip = g_pSUPGlobalInfoPage;
    77     AssertFatalMsgFailed(("pGip=%p u32Magic=%#x\n", pGip, VALID_PTR(pGip) ? pGip->u32Magic : 0));
     78    AssertFatalMsg(RT_VALID_PTR(pGip), ("pVM=%p pGip=%p\n", pVM, pGip));
     79    AssertFatalMsg(pGip->u32Magic == SUPGLOBALINFOPAGE_MAGIC, ("pVM=%p pGip=%p u32Magic=%#x\n", pVM, pGip, pGip->u32Magic));
     80    AssertFatalMsg(pGip->u32Mode > SUPGIPMODE_INVALID && pGip->u32Mode < SUPGIPMODE_END,
     81                   ("pVM=%p pGip=%p u32Mode=%#x\n", pVM, pGip, pGip->u32Mode));
     82
     83    /*
     84     * Determine the new worker.
     85     */
     86    PFNTIMENANOTSINTERNAL   pfnWorker;
     87    bool const              fLFence = RT_BOOL(ASMCpuId_EDX(1) & X86_CPUID_FEATURE_EDX_SSE2);
     88    switch (pGip->u32Mode)
     89    {
     90        case SUPGIPMODE_SYNC_TSC:
     91        case SUPGIPMODE_INVARIANT_TSC:
     92#if defined(IN_RC) || defined(IN_RING0)
     93            if (pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO)
     94                pfnWorker = fLFence ? RTTimeNanoTSLFenceSyncInvarNoDelta    : RTTimeNanoTSLegacySyncInvarNoDelta;
     95            else
     96                pfnWorker = fLFence ? RTTimeNanoTSLFenceSyncInvarWithDelta  : RTTimeNanoTSLegacySyncInvarWithDelta;
     97#else
     98            if (pGip->fGetGipCpu & SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS)
     99                pfnWorker = pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_PRACTICALLY_ZERO
     100                          ? fLFence ? RTTimeNanoTSLFenceSyncInvarNoDelta    : RTTimeNanoTSLegacySyncInvarNoDelta
     101                          : fLFence ? RTTimeNanoTSLFenceSyncInvarWithDeltaUseIdtrLim : RTTimeNanoTSLegacySyncInvarWithDeltaUseIdtrLim;
     102            else if (pGip->fGetGipCpu & SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS)
     103                pfnWorker = pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_PRACTICALLY_ZERO
     104                          ? fLFence ? RTTimeNanoTSLFenceSyncInvarNoDelta    : RTTimeNanoTSLegacySyncInvarNoDelta
     105                          : fLFence ? RTTimeNanoTSLFenceSyncInvarWithDeltaUseRdtscp : RTTimeNanoTSLegacySyncInvarWithDeltaUseRdtscp;
     106            else
     107                pfnWorker = pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO
     108                          ? fLFence ? RTTimeNanoTSLFenceSyncInvarNoDelta    : RTTimeNanoTSLegacySyncInvarNoDelta
     109                          : fLFence ? RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicId : RTTimeNanoTSLegacySyncInvarWithDeltaUseApicId;
     110#endif
     111            break;
     112
     113        case SUPGIPMODE_ASYNC_TSC:
     114#if defined(IN_RC) || defined(IN_RING0)
     115            pfnWorker = fLFence ? RTTimeNanoTSLFenceAsync : RTTimeNanoTSLegacyAsync;
     116#else
     117            if (pGip->fGetGipCpu & SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS)
     118                pfnWorker = fLFence ? RTTimeNanoTSLFenceAsyncUseIdtrLim     : RTTimeNanoTSLegacyAsyncUseIdtrLim;
     119            else if (pGip->fGetGipCpu & SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS)
     120                pfnWorker = fLFence ? RTTimeNanoTSLFenceAsyncUseRdtscp      : RTTimeNanoTSLegacyAsyncUseRdtscp;
     121            else
     122                pfnWorker = fLFence ? RTTimeNanoTSLFenceAsyncUseApicId      : RTTimeNanoTSLegacyAsyncUseApicId;
     123#endif
     124            break;
     125
     126        default:
     127            AssertFatalMsgFailed(("pVM=%p pGip=%p u32Mode=%#x\n", pVM, pGip, pGip->u32Mode));
     128    }
     129
     130    /*
     131     * Update the pfnVirtualGetRaw pointer and call the worker we selected.
     132     */
     133    ASMAtomicWritePtr((void * volatile *)&CTX_SUFF(pVM->tm.s.pfnVirtualGetRaw), (void *)(uintptr_t)pfnWorker);
     134    return pfnWorker(pData);
     135}
     136
     137
     138/**
     139 * @interface_method_impl{RTTIMENANOTSDATA, pfnBadGipIndex}
     140 */
     141DECLEXPORT(uint64_t) tmVirtualNanoTSBadCpuIndex(PRTTIMENANOTSDATA pData, uint16_t idApic, uint16_t iCpuSet, uint16_t iGipCpu)
     142{
     143    PVM pVM = RT_FROM_MEMBER(pData, VM, CTX_SUFF(tm.s.VirtualGetRawData));
     144    AssertFatalMsgFailed(("pVM=%p idApic=%#x iCpuSet=%#x iGipCpu=%#x\n", pVM, idApic, iCpuSet, iGipCpu));
    78145#ifndef _MSC_VER
    79     return 0; /* gcc false positive warning */
     146    return UINT64_MAX;
    80147#endif
    81148}
    82149
    83 
    84 #if 1
    85150
    86151/**
     
    100165    return u64;
    101166}
    102 
    103 #else
    104 
    105 /**
    106  * This is (mostly) the same as rtTimeNanoTSInternal() except
    107  * for the two globals which live in TM.
    108  *
    109  * @returns Nanosecond timestamp.
    110  * @param   pVM     Pointer to the VM.
    111  */
    112 static uint64_t tmVirtualGetRawNanoTS(PVM pVM)
    113 {
    114     uint64_t    u64Delta;
    115     uint32_t    u32NanoTSFactor0;
    116     uint64_t    u64TSC;
    117     uint64_t    u64NanoTS;
    118     uint32_t    u32UpdateIntervalTSC;
    119     uint64_t    u64PrevNanoTS;
    120 
    121     /*
    122      * Read the GIP data and the previous value.
    123      */
    124     for (;;)
    125     {
    126         uint32_t u32TransactionId;
    127         PSUPGLOBALINFOPAGE pGip = g_pSUPGlobalInfoPage;
    128 #ifdef IN_RING3
    129         if (RT_UNLIKELY(!pGip || pGip->u32Magic != SUPGLOBALINFOPAGE_MAGIC))
    130             return RTTimeSystemNanoTS();
    131 #endif
    132 
    133         if (pGip->u32Mode != SUPGIPMODE_ASYNC_TSC)
    134         {
    135             u32TransactionId = pGip->aCPUs[0].u32TransactionId;
    136 #ifdef RT_OS_L4
    137             Assert((u32TransactionId & 1) == 0);
    138 #endif
    139             u32UpdateIntervalTSC = pGip->aCPUs[0].u32UpdateIntervalTSC;
    140             u64NanoTS = pGip->aCPUs[0].u64NanoTS;
    141             u64TSC = pGip->aCPUs[0].u64TSC;
    142             u32NanoTSFactor0 = pGip->u32UpdateIntervalNS;
    143             u64Delta = ASMReadTSC();
    144             u64PrevNanoTS = ASMAtomicReadU64(&pVM->tm.s.u64VirtualRawPrev);
    145             if (RT_UNLIKELY(    pGip->aCPUs[0].u32TransactionId != u32TransactionId
    146                             ||  (u32TransactionId & 1)))
    147                 continue;
    148         }
    149         else
    150         {
    151             /* SUPGIPMODE_ASYNC_TSC */
    152             PSUPGIPCPU pGipCpu;
    153 
    154             uint8_t u8ApicId = ASMGetApicId();
    155             if (RT_LIKELY(u8ApicId < RT_ELEMENTS(pGip->aCPUs)))
    156                 pGipCpu = &pGip->aCPUs[u8ApicId];
    157             else
    158             {
    159                 AssertMsgFailed(("%x\n", u8ApicId));
    160                 pGipCpu = &pGip->aCPUs[0];
    161             }
    162 
    163             u32TransactionId = pGipCpu->u32TransactionId;
    164 #ifdef RT_OS_L4
    165             Assert((u32TransactionId & 1) == 0);
    166 #endif
    167             u32UpdateIntervalTSC = pGipCpu->u32UpdateIntervalTSC;
    168             u64NanoTS = pGipCpu->u64NanoTS;
    169             u64TSC = pGipCpu->u64TSC;
    170             u32NanoTSFactor0 = pGip->u32UpdateIntervalNS;
    171             u64Delta = ASMReadTSC();
    172             u64PrevNanoTS = ASMAtomicReadU64(&pVM->tm.s.u64VirtualRawPrev);
    173 #ifdef IN_RC
    174             Assert(!(ASMGetFlags() & X86_EFL_IF));
    175 #else
    176             if (RT_UNLIKELY(u8ApicId != ASMGetApicId()))
    177                 continue;
    178             if (RT_UNLIKELY(    pGipCpu->u32TransactionId != u32TransactionId
    179                             ||  (u32TransactionId & 1)))
    180                 continue;
    181 #endif
    182         }
    183         break;
    184     }
    185 
    186     /*
    187      * Calc NanoTS delta.
    188      */
    189     u64Delta -= u64TSC;
    190     if (u64Delta > u32UpdateIntervalTSC)
    191     {
    192         /*
    193          * We've expired the interval, cap it. If we're here for the 2nd
    194          * time without any GIP update in-between, the checks against
    195          * pVM->tm.s.u64VirtualRawPrev below will force 1ns stepping.
    196          */
    197         u64Delta = u32UpdateIntervalTSC;
    198     }
    199 #if !defined(_MSC_VER) || defined(RT_ARCH_AMD64) /* GCC makes very pretty code from these two inline calls, while MSC cannot. */
    200     u64Delta = ASMMult2xU32RetU64((uint32_t)u64Delta, u32NanoTSFactor0);
    201     u64Delta = ASMDivU64ByU32RetU32(u64Delta, u32UpdateIntervalTSC);
    202 #else
    203     __asm
    204     {
    205         mov     eax, dword ptr [u64Delta]
    206         mul     dword ptr [u32NanoTSFactor0]
    207         div     dword ptr [u32UpdateIntervalTSC]
    208         mov     dword ptr [u64Delta], eax
    209         xor     edx, edx
    210         mov     dword ptr [u64Delta + 4], edx
    211     }
    212 #endif
    213 
    214     /*
    215      * Calculate the time and compare it with the previously returned value.
    216      *
    217      * Since this function is called *very* frequently when the VM is running
    218      * and then mostly on EMT, we can restrict the valid range of the delta
    219      * (-1s to 2*GipUpdates) and simplify/optimize the default path.
    220      */
    221     u64NanoTS += u64Delta;
    222     uint64_t u64DeltaPrev = u64NanoTS - u64PrevNanoTS;
    223     if (RT_LIKELY(u64DeltaPrev < 1000000000 /* 1s */))
    224         /* frequent - less than 1s since last call. */;
    225     else if (   (int64_t)u64DeltaPrev < 0
    226              && (int64_t)u64DeltaPrev + u32NanoTSFactor0 * 2 > 0)
    227     {
    228         /* occasional - u64NanoTS is in the 'past' relative to previous returns. */
    229         ASMAtomicIncU32(&pVM->tm.s.CTX_SUFF(VirtualGetRawData).c1nsSteps);
    230         u64NanoTS = u64PrevNanoTS + 1;
    231 #ifndef IN_RING3
    232         VM_FF_SET(pVM, VM_FF_TO_R3); /* S10 hack */
    233 #endif
    234     }
    235     else if (u64PrevNanoTS)
    236     {
    237         /* Something has gone bust, if negative offset it's real bad. */
    238         ASMAtomicIncU32(&pVM->tm.s.CTX_SUFF(VirtualGetRawData).cBadPrev);
    239         if ((int64_t)u64DeltaPrev < 0)
    240             LogRel(("TM: u64DeltaPrev=%RI64 u64PrevNanoTS=0x%016RX64 u64NanoTS=0x%016RX64 u64Delta=%#RX64\n",
    241                     u64DeltaPrev, u64PrevNanoTS, u64NanoTS, u64Delta));
    242         else
    243             Log(("TM: u64DeltaPrev=%RI64 u64PrevNanoTS=0x%016RX64 u64NanoTS=0x%016RX64 u64Delta=%#RX64 (debugging?)\n",
    244                  u64DeltaPrev, u64PrevNanoTS, u64NanoTS, u64Delta));
    245 #ifdef DEBUG_bird
    246         /** @todo there are some hickups during boot and reset that can cause 2-5 seconds delays. Investigate... */
    247         AssertMsg(u64PrevNanoTS > UINT64_C(100000000000) /* 100s */,
    248                   ("u64DeltaPrev=%RI64 u64PrevNanoTS=0x%016RX64 u64NanoTS=0x%016RX64 u64Delta=%#RX64\n",
    249                   u64DeltaPrev, u64PrevNanoTS, u64NanoTS, u64Delta));
    250 #endif
    251     }
    252     /* else: We're resuming (see TMVirtualResume). */
    253     if (RT_LIKELY(ASMAtomicCmpXchgU64(&pVM->tm.s.u64VirtualRawPrev, u64NanoTS, u64PrevNanoTS)))
    254         return u64NanoTS;
    255 
    256     /*
    257      * Attempt updating the previous value, provided we're still ahead of it.
    258      *
    259      * There is no point in recalculating u64NanoTS because we got preempted or if
    260      * we raced somebody while the GIP was updated, since these are events
    261      * that might occur at any point in the return path as well.
    262      */
    263     for (int cTries = 50;;)
    264     {
    265         u64PrevNanoTS = ASMAtomicReadU64(&pVM->tm.s.u64VirtualRawPrev);
    266         if (u64PrevNanoTS >= u64NanoTS)
    267             break;
    268         if (ASMAtomicCmpXchgU64(&pVM->tm.s.u64VirtualRawPrev, u64NanoTS, u64PrevNanoTS))
    269             break;
    270         AssertBreak(--cTries <= 0);
    271         if (cTries < 25 && !VM_IS_EMT(pVM)) /* give up early */
    272             break;
    273     }
    274 
    275     return u64NanoTS;
    276 }
    277 
    278 #endif
    279167
    280168
  • trunk/src/VBox/VMM/VMMR0/VMMR0.def

    r54207 r54270  
    8888    RTCrc32
    8989    RTOnceSlow
    90     RTTimeNanoTSLegacyInvariantNoDelta
    91     RTTimeNanoTSLegacyInvariantWithDelta
    92     RTTimeNanoTSLegacySyncNoDelta
    93     RTTimeNanoTSLegacySyncWithDelta
     90    RTTimeNanoTSLegacySyncInvarNoDelta
     91    RTTimeNanoTSLegacySyncInvarWithDelta
    9492    RTTimeNanoTSLegacyAsync
    95     RTTimeNanoTSLFenceInvariantNoDelta
    96     RTTimeNanoTSLFenceInvariantWithDelta
    97     RTTimeNanoTSLFenceSyncNoDelta
    98     RTTimeNanoTSLFenceSyncWithDelta
     93    RTTimeNanoTSLFenceSyncInvarNoDelta
     94    RTTimeNanoTSLFenceSyncInvarWithDelta
    9995    RTTimeNanoTSLFenceAsync
    10096    RTTimeSystemNanoTS
  • trunk/src/VBox/VMM/VMMR3/TM.cpp

    r54252 r54270  
    271271     * Setup the VirtualGetRaw backend.
    272272     */
    273     pVM->tm.s.VirtualGetRawDataR3.pu64Prev = &pVM->tm.s.u64VirtualRawPrev;
    274     pVM->tm.s.VirtualGetRawDataR3.pfnBad = tmVirtualNanoTSBad;
    275     pVM->tm.s.VirtualGetRawDataR3.pfnRediscover = tmVirtualNanoTSRediscover;
    276     if (ASMCpuId_EDX(1) & X86_CPUID_FEATURE_EDX_SSE2)
    277     {
    278         if (pGip->u32Mode == SUPGIPMODE_INVARIANT_TSC)
    279             pVM->tm.s.pfnVirtualGetRawR3 = pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO
    280                                          ? RTTimeNanoTSLFenceInvariantNoDelta : RTTimeNanoTSLFenceInvariantWithDelta;
    281         else if (pGip->u32Mode == SUPGIPMODE_SYNC_TSC)
    282             pVM->tm.s.pfnVirtualGetRawR3 = pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO
    283                                          ? RTTimeNanoTSLFenceSyncNoDelta      : RTTimeNanoTSLFenceSyncWithDelta;
    284         else
    285             pVM->tm.s.pfnVirtualGetRawR3 = RTTimeNanoTSLFenceAsync;
    286     }
    287     else
    288     {
    289         if (pGip->u32Mode == SUPGIPMODE_INVARIANT_TSC)
    290             pVM->tm.s.pfnVirtualGetRawR3 = pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO
    291                                          ? RTTimeNanoTSLegacyInvariantNoDelta   : RTTimeNanoTSLegacyInvariantWithDelta;
    292         else if (pGip->u32Mode == SUPGIPMODE_SYNC_TSC)
    293             pVM->tm.s.pfnVirtualGetRawR3 = pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO
    294                                          ? RTTimeNanoTSLegacySyncNoDelta        : RTTimeNanoTSLegacySyncWithDelta;
    295         else
    296             pVM->tm.s.pfnVirtualGetRawR3 = RTTimeNanoTSLegacyAsync;
    297     }
    298 
    299     pVM->tm.s.VirtualGetRawDataRC.pu64Prev = MMHyperR3ToRC(pVM, (void *)&pVM->tm.s.u64VirtualRawPrev);
    300     pVM->tm.s.VirtualGetRawDataR0.pu64Prev = MMHyperR3ToR0(pVM, (void *)&pVM->tm.s.u64VirtualRawPrev);
     273    pVM->tm.s.pfnVirtualGetRawR3                 = tmVirtualNanoTSRediscover;
     274    pVM->tm.s.VirtualGetRawDataR3.pfnRediscover  = tmVirtualNanoTSRediscover;
     275    pVM->tm.s.VirtualGetRawDataR3.pfnBad         = tmVirtualNanoTSBadPrev;
     276    pVM->tm.s.VirtualGetRawDataR3.pfnBadCpuIndex = tmVirtualNanoTSBadCpuIndex;
     277    pVM->tm.s.VirtualGetRawDataR3.pu64Prev       = &pVM->tm.s.u64VirtualRawPrev;
     278    pVM->tm.s.VirtualGetRawDataRC.pu64Prev       = MMHyperR3ToRC(pVM, (void *)&pVM->tm.s.u64VirtualRawPrev);
     279    pVM->tm.s.VirtualGetRawDataR0.pu64Prev       = MMHyperR3ToR0(pVM, (void *)&pVM->tm.s.u64VirtualRawPrev);
    301280    AssertRelease(pVM->tm.s.VirtualGetRawDataR0.pu64Prev);
    302281    /* The rest is done in TMR3InitFinalize since it's too early to call PDM. */
     
    10381017
    10391018/**
    1040  * Translation of pfnVirtualGetRawR3 to symbol names.
    1041  *
    1042  * @remarks This is a global variable because some gcc versions have their
    1043  *          attribute/visibility warnings messed up.
    1044  */
    1045 static const struct
    1046 {
    1047     PFNTIMENANOTSINTERNAL   pfnR3Worker;
    1048     const char             *pszName;
    1049 } g_aNanoTsWorkers[] =
    1050 {
    1051 #define ENTRY(a) { a, #a }
    1052     ENTRY(RTTimeNanoTSLegacyAsync),
    1053     ENTRY(RTTimeNanoTSLegacyInvariantNoDelta),
    1054     ENTRY(RTTimeNanoTSLegacyInvariantWithDelta),
    1055     ENTRY(RTTimeNanoTSLegacySyncNoDelta),
    1056     ENTRY(RTTimeNanoTSLegacySyncWithDelta),
    1057     ENTRY(RTTimeNanoTSLFenceAsync),
    1058     ENTRY(RTTimeNanoTSLFenceInvariantNoDelta),
    1059     ENTRY(RTTimeNanoTSLFenceInvariantWithDelta),
    1060     ENTRY(RTTimeNanoTSLFenceSyncNoDelta),
    1061     ENTRY(RTTimeNanoTSLFenceSyncWithDelta),
    1062 #undef ENTRY
    1063 };
    1064 
    1065 
    1066 /**
    1067  * Translates TM::pfnVirtualGetRawR3 to a symbol name that we can find in ring-0
    1068  * and raw-mode context.
    1069  *
    1070  * @returns Symbol name.
    1071  * @param   pfnWorkerR3         The TM::pfnVirtualGetRawR3 value.
    1072  */
    1073 static const char *tmR3GetRTTimeNanoName(PFNTIMENANOTSINTERNAL pfnR3Worker)
    1074 {
    1075     for (uint32_t iNanoTs = 0; iNanoTs < RT_ELEMENTS(g_aNanoTsWorkers); iNanoTs++)
    1076         if (pfnR3Worker == g_aNanoTsWorkers[iNanoTs].pfnR3Worker)
    1077             return g_aNanoTsWorkers[iNanoTs].pszName;
    1078     AssertFatalFailed();
    1079     return NULL;
    1080 }
    1081 
    1082 
    1083 /**
    10841019 * Finalizes the TM initialization.
    10851020 *
     
    10941029     * Resolve symbols.
    10951030     */
    1096     const char *pszRTTimeNanoTS = tmR3GetRTTimeNanoName(pVM->tm.s.pfnVirtualGetRawR3);
    10971031    if (!HMIsEnabled(pVM))
    10981032    {
    1099         rc = PDMR3LdrGetSymbolRC(pVM, NULL, "tmVirtualNanoTSBad",           &pVM->tm.s.VirtualGetRawDataRC.pfnBad);
     1033        rc = PDMR3LdrGetSymbolRC(pVM, NULL, "tmVirtualNanoTSBadPrev",       &pVM->tm.s.VirtualGetRawDataRC.pfnBad);
     1034        AssertRCReturn(rc, rc);
     1035        rc = PDMR3LdrGetSymbolRC(pVM, NULL, "tmVirtualNanoTSBadCpuIndex",   &pVM->tm.s.VirtualGetRawDataRC.pfnBadCpuIndex);
    11001036        AssertRCReturn(rc, rc);
    11011037        rc = PDMR3LdrGetSymbolRC(pVM, NULL, "tmVirtualNanoTSRediscover",    &pVM->tm.s.VirtualGetRawDataRC.pfnRediscover);
    11021038        AssertRCReturn(rc, rc);
    1103         rc = PDMR3LdrGetSymbolRC(pVM, NULL, pszRTTimeNanoTS,                &pVM->tm.s.pfnVirtualGetRawRC);
    1104         AssertRCReturn(rc, rc);
    1105     }
    1106 
    1107     rc = PDMR3LdrGetSymbolR0(pVM, NULL, "tmVirtualNanoTSBad",           &pVM->tm.s.VirtualGetRawDataR0.pfnBad);
     1039        pVM->tm.s.pfnVirtualGetRawRC = pVM->tm.s.VirtualGetRawDataRC.pfnRediscover;
     1040    }
     1041
     1042    rc = PDMR3LdrGetSymbolR0(pVM, NULL, "tmVirtualNanoTSBadPrev",       &pVM->tm.s.VirtualGetRawDataR0.pfnBad);
     1043    AssertRCReturn(rc, rc);
     1044    rc = PDMR3LdrGetSymbolR0(pVM, NULL, "tmVirtualNanoTSBadCpuIndex",   &pVM->tm.s.VirtualGetRawDataR0.pfnBadCpuIndex);
    11081045    AssertRCReturn(rc, rc);
    11091046    rc = PDMR3LdrGetSymbolR0(pVM, NULL, "tmVirtualNanoTSRediscover",    &pVM->tm.s.VirtualGetRawDataR0.pfnRediscover);
    11101047    AssertRCReturn(rc, rc);
    1111     rc = PDMR3LdrGetSymbolR0(pVM, NULL, pszRTTimeNanoTS,                &pVM->tm.s.pfnVirtualGetRawR0);
    1112     AssertRCReturn(rc, rc);
     1048    pVM->tm.s.pfnVirtualGetRawR0 = pVM->tm.s.VirtualGetRawDataR0.pfnRediscover;
    11131049
    11141050#ifndef VBOX_WITHOUT_NS_ACCOUNTING
     
    11401076VMM_INT_DECL(void) TMR3Relocate(PVM pVM, RTGCINTPTR offDelta)
    11411077{
    1142     int rc;
    11431078    LogFlow(("TMR3Relocate\n"));
    1144     NOREF(offDelta);
    11451079
    11461080    pVM->tm.s.paTimerQueuesR0 = MMHyperR3ToR0(pVM, pVM->tm.s.paTimerQueuesR3);
     
    11481082    if (!HMIsEnabled(pVM))
    11491083    {
    1150         pVM->tm.s.pvGIPRC = MMHyperR3ToRC(pVM, pVM->tm.s.pvGIPR3);
    1151         pVM->tm.s.paTimerQueuesRC = MMHyperR3ToRC(pVM, pVM->tm.s.paTimerQueuesR3);
    1152         pVM->tm.s.VirtualGetRawDataRC.pu64Prev = MMHyperR3ToRC(pVM, (void *)&pVM->tm.s.u64VirtualRawPrev);
    1153         AssertFatal(pVM->tm.s.VirtualGetRawDataRC.pu64Prev);
    1154         rc = PDMR3LdrGetSymbolRC(pVM, NULL, "tmVirtualNanoTSBad",           &pVM->tm.s.VirtualGetRawDataRC.pfnBad);
    1155         AssertFatalRC(rc);
    1156         rc = PDMR3LdrGetSymbolRC(pVM, NULL, "tmVirtualNanoTSRediscover",    &pVM->tm.s.VirtualGetRawDataRC.pfnRediscover);
    1157         AssertFatalRC(rc);
    1158         const char *pszRTTimeNanoTS = tmR3GetRTTimeNanoName(pVM->tm.s.pfnVirtualGetRawR3);
    1159         rc = PDMR3LdrGetSymbolRC(pVM, NULL, pszRTTimeNanoTS,                &pVM->tm.s.pfnVirtualGetRawRC);
    1160         AssertFatalRC(rc);
     1084        pVM->tm.s.pvGIPRC           = MMHyperR3ToRC(pVM, pVM->tm.s.pvGIPR3);
     1085        pVM->tm.s.paTimerQueuesRC   = MMHyperR3ToRC(pVM, pVM->tm.s.paTimerQueuesR3);
     1086        pVM->tm.s.VirtualGetRawDataRC.pu64Prev       += offDelta;
     1087        pVM->tm.s.VirtualGetRawDataRC.pfnBad         += offDelta;
     1088        pVM->tm.s.VirtualGetRawDataRC.pfnBadCpuIndex += offDelta;
     1089        pVM->tm.s.VirtualGetRawDataRC.pfnRediscover  += offDelta;
     1090        pVM->tm.s.pfnVirtualGetRawRC                 += offDelta;
    11611091    }
    11621092
  • trunk/src/VBox/VMM/VMMRC/VMMRC.def

    r54207 r54270  
    6565    MMGCRamWriteNoTrapHandler
    6666    MMGCRamReadNoTrapHandler
     67    VMMGetCpu
    6768    VMMGetSvnRev
    6869    VMMRCProbeFire
     
    9293    RTAssertShouldPanic
    9394    RTLogDefaultInstance
    94     RTTimeNanoTSLegacyInvariantNoDelta
    95     RTTimeNanoTSLegacyInvariantWithDelta
    96     RTTimeNanoTSLegacySyncNoDelta
    97     RTTimeNanoTSLegacySyncWithDelta
     95    RTTimeNanoTSLegacySyncInvarNoDelta
     96    RTTimeNanoTSLegacySyncInvarWithDelta
    9897    RTTimeNanoTSLegacyAsync
    99     RTTimeNanoTSLFenceInvariantNoDelta
    100     RTTimeNanoTSLFenceInvariantWithDelta
    101     RTTimeNanoTSLFenceSyncNoDelta
    102     RTTimeNanoTSLFenceSyncWithDelta
     98    RTTimeNanoTSLFenceSyncInvarNoDelta
     99    RTTimeNanoTSLFenceSyncInvarWithDelta
    103100    RTTimeNanoTSLFenceAsync
    104101    RTTimeNanoTS
  • trunk/src/VBox/VMM/include/TMInternal.h

    r54202 r54270  
    766766int                     tmVirtualPauseLocked(PVM pVM);
    767767int                     tmVirtualResumeLocked(PVM pVM);
    768 DECLEXPORT(void)        tmVirtualNanoTSBad(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS);
     768DECLEXPORT(void)        tmVirtualNanoTSBadPrev(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS,
     769                                               uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS);
    769770DECLEXPORT(uint64_t)    tmVirtualNanoTSRediscover(PRTTIMENANOTSDATA pData);
     771DECLEXPORT(uint64_t)    tmVirtualNanoTSBadCpuIndex(PRTTIMENANOTSDATA pData, uint16_t idApic, uint16_t iCpuSet, uint16_t iGipCpu);
    770772
    771773#ifdef IN_RING3
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