VirtualBox

Changeset 54202 in vbox


Ignore:
Timestamp:
Feb 13, 2015 5:13:44 PM (10 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
98264
Message:

IPRT,TM: Implemented GIP TSC delta processing in the RTTimeNanoTS code.

Location:
trunk
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/mangling.h

    r53901 r54202  
    17201720# define RTTimeNanoTS                                   RT_MANGLER(RTTimeNanoTS)
    17211721# define RTTimeNanoTSLegacyAsync                        RT_MANGLER(RTTimeNanoTSLegacyAsync)
    1722 # define RTTimeNanoTSLegacySync                         RT_MANGLER(RTTimeNanoTSLegacySync)
     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)
    17231731# define RTTimeNanoTSLFenceAsync                        RT_MANGLER(RTTimeNanoTSLFenceAsync)
    1724 # define RTTimeNanoTSLFenceSync                         RT_MANGLER(RTTimeNanoTSLFenceSync)
     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)
    17251741# define RTTimeNormalize                                RT_MANGLER(RTTimeNormalize)
    17261742# define RTTimeNow                                      RT_MANGLER(RTTimeNow)
  • trunk/include/iprt/time.h

    r51770 r54202  
    44
    55/*
    6  * Copyright (C) 2006-2012 Oracle Corporation
     6 * Copyright (C) 2006-2015 Oracle Corporation
    77 *
    88 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    915915typedef FNTIMENANOTSINTERNAL *PFNTIMENANOTSINTERNAL;
    916916
    917 RTDECL(uint64_t) RTTimeNanoTSLegacySync(PRTTIMENANOTSDATA pData);
    918917RTDECL(uint64_t) RTTimeNanoTSLegacyAsync(PRTTIMENANOTSDATA pData);
    919 RTDECL(uint64_t) RTTimeNanoTSLFenceSync(PRTTIMENANOTSDATA pData);
     918RTDECL(uint64_t) RTTimeNanoTSLegacyInvariantNoDelta(PRTTIMENANOTSDATA pData);
     919RTDECL(uint64_t) RTTimeNanoTSLegacyInvariantWithDelta(PRTTIMENANOTSDATA pData);
     920RTDECL(uint64_t) RTTimeNanoTSLegacySyncNoDelta(PRTTIMENANOTSDATA pData);
     921RTDECL(uint64_t) RTTimeNanoTSLegacySyncWithDelta(PRTTIMENANOTSDATA pData);
    920922RTDECL(uint64_t) RTTimeNanoTSLFenceAsync(PRTTIMENANOTSDATA pData);
     923RTDECL(uint64_t) RTTimeNanoTSLFenceInvariantNoDelta(PRTTIMENANOTSDATA pData);
     924RTDECL(uint64_t) RTTimeNanoTSLFenceInvariantWithDelta(PRTTIMENANOTSDATA pData);
     925RTDECL(uint64_t) RTTimeNanoTSLFenceSyncNoDelta(PRTTIMENANOTSDATA pData);
     926RTDECL(uint64_t) RTTimeNanoTSLFenceSyncWithDelta(PRTTIMENANOTSDATA pData);
     927
    921928/** @} */
    922929
  • trunk/src/VBox/Runtime/common/time/timesup.cpp

    r53430 r54202  
    55
    66/*
    7  * Copyright (C) 2006-2014 Oracle Corporation
     7 * Copyright (C) 2006-2015 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    8282static const PFNTIMENANOTSINTERNAL g_apfnWorkers[] =
    8383{
    84 # define RTTIMENANO_WORKER_DETECT        0
     84# define RTTIMENANO_WORKER_DETECT                   0
    8585    rtTimeNanoTSInternalRediscover,
    86 # define RTTIMENANO_WORKER_SYNC_CPUID    1
    87     RTTimeNanoTSLegacySync,
    88 # define RTTIMENANO_WORKER_ASYNC_CPUID   2
     86
     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
    8992    RTTimeNanoTSLegacyAsync,
    90 # define RTTIMENANO_WORKER_SYNC_LFENCE   3
    91     RTTimeNanoTSLFenceSync,
    92 # define RTTIMENANO_WORKER_ASYNC_LFENCE  4
     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
    93103    RTTimeNanoTSLFenceAsync,
    94 # define RTTIMENANO_WORKER_FALLBACK      5
     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
    95110    rtTimeNanoTSInternalFallback,
    96111};
     
    138153
    139154/**
     155 * Checks if we really need to apply the delta values.
     156 *
     157 * Getting the delta for a CPU is _very_ expensive, it more than doubles the
     158 * execution time for RTTimeNanoTS.
     159 *
     160 * @returns true if deltas needs to be applied, false if not.
     161 * @param   pGip                The GIP.
     162 */
     163static bool rtTimeNanoTsInternalReallyNeedDeltas(PSUPGLOBALINFOPAGE pGip)
     164{
     165    if (!pGip->fOsTscDeltasInSync)
     166    {
     167        uint32_t i = pGip->cCpus;
     168        while (i-- > 0)
     169            if (   pGip->aCPUs[i].enmState == SUPGIPCPUSTATE_ONLINE
     170                && (   pGip->aCPUs[i].i64TSCDelta > 384
     171                    || pGip->aCPUs[i].i64TSCDelta < -384) )
     172                return true;
     173    }
     174    return false;
     175}
     176
     177
     178/**
    140179 * Called the first time somebody asks for the time or when the GIP
    141180 * is mapped/unmapped.
     
    152191    {
    153192        if (ASMCpuId_EDX(1) & X86_CPUID_FEATURE_EDX_SSE2)
    154             iWorker = pGip->u32Mode == SUPGIPMODE_INVARIANT_TSC || pGip->u32Mode == SUPGIPMODE_SYNC_TSC
    155                     ? RTTIMENANO_WORKER_SYNC_LFENCE
    156                     : RTTIMENANO_WORKER_ASYNC_LFENCE;
     193            iWorker = pGip->u32Mode == SUPGIPMODE_INVARIANT_TSC
     194                    ? rtTimeNanoTsInternalReallyNeedDeltas(pGip)
     195                      ? RTTIMENANO_WORKER_LFENCE_INVAR_WITH_DELTA : RTTIMENANO_WORKER_LFENCE_INVAR_NO_DELTA
     196                    : pGip->u32Mode == SUPGIPMODE_SYNC_TSC
     197                    ? false /** @todo !rtTimeNanoTsInternalReallyNeedDeltas(pGip) */
     198                      ? RTTIMENANO_WORKER_LFENCE_SYNC_WITH_DELTA  : RTTIMENANO_WORKER_LFENCE_SYNC_NO_DELTA
     199                    : RTTIMENANO_WORKER_LFENCE_ASYNC;
    157200        else
    158             iWorker = pGip->u32Mode == SUPGIPMODE_INVARIANT_TSC || pGip->u32Mode == SUPGIPMODE_SYNC_TSC
    159                     ? RTTIMENANO_WORKER_SYNC_CPUID
    160                     : RTTIMENANO_WORKER_ASYNC_CPUID;
     201            iWorker = pGip->u32Mode == SUPGIPMODE_INVARIANT_TSC
     202                    ? rtTimeNanoTsInternalReallyNeedDeltas(pGip)
     203                      ? RTTIMENANO_WORKER_LEGACY_INVAR_WITH_DELTA : RTTIMENANO_WORKER_LEGACY_INVAR_NO_DELTA
     204                    : pGip->u32Mode == SUPGIPMODE_SYNC_TSC
     205                    ? false /** @todo rtTimeNanoTsInternalReallyNeedDeltas(pGip) */
     206                      ? RTTIMENANO_WORKER_LEGACY_SYNC_WITH_DELTA  : RTTIMENANO_WORKER_LEGACY_SYNC_NO_DELTA
     207                    : RTTIMENANO_WORKER_LEGACY_ASYNC;
    161208    }
    162209    else
    163210        iWorker = RTTIMENANO_WORKER_FALLBACK;
    164211
    165     ASMAtomicXchgU32((uint32_t volatile *)&g_iWorker, iWorker);
     212    ASMAtomicWriteU32((uint32_t volatile *)&g_iWorker, iWorker);
    166213    return g_apfnWorkers[iWorker](pData);
    167214}
  • trunk/src/VBox/Runtime/common/time/timesupA.asm

    r53470 r54202  
    7474%endif
    7575
    76 
    7776BEGINCODE
    7877
     
    8382%undef  ASYNC_GIP
    8483%undef  USE_LFENCE
     84%undef  WITH_TSC_DELTA
     85%undef  NEED_APIC_ID
    8586%define NEED_TRANSACTION_ID
    86 %define NEED_TO_SAVE_REGS
    87 %define rtTimeNanoTSInternalAsm    RTTimeNanoTSLegacySync
     87%define rtTimeNanoTSInternalAsm    RTTimeNanoTSLegacySyncNoDelta
     88%include "timesupA.mac"
     89
     90%define rtTimeNanoTSInternalAsm    RTTimeNanoTSLegacyInvariantNoDelta
     91%include "timesupA.mac"
     92
     93%define WITH_TSC_DELTA
     94%define NEED_APIC_ID
     95%define rtTimeNanoTSInternalAsm    RTTimeNanoTSLegacySyncWithDelta
     96%include "timesupA.mac"
     97
     98%define rtTimeNanoTSInternalAsm    RTTimeNanoTSLegacyInvariantWithDelta
    8899%include "timesupA.mac"
    89100
    90101%define ASYNC_GIP
     102%undef  WITH_TSC_DELTA
     103%define NEED_APIC_ID
    91104%ifdef IN_RC
    92105 %undef NEED_TRANSACTION_ID
     
    95108%include "timesupA.mac"
    96109
    97 %undef ASYNC_GIP
    98 %define INVARIANT_GIP
    99 %ifdef IN_RC
    100  %undef NEED_TRANSACTION_ID
    101 %endif
    102 %define rtTimeNanoTSInternalAsm    RTTimeNanoTSLegacyInvariant
    103 ;%include "timesupA.mac"
    104 ;; @todo r=bird: later.
    105110
    106111;
    107112; Alternative implementation that employs lfence instead of cpuid.
    108113;
    109 %undef  INVARIANT_GIP
     114%undef  ASYNC_GIP
    110115%define USE_LFENCE
     116%undef  WITH_TSC_DELTA
     117%undef  NEED_APIC_ID
    111118%define NEED_TRANSACTION_ID
    112 %undef  NEED_TO_SAVE_REGS
    113 %define rtTimeNanoTSInternalAsm    RTTimeNanoTSLFenceSync
     119%define rtTimeNanoTSInternalAsm    RTTimeNanoTSLFenceSyncNoDelta
     120%include "timesupA.mac"
     121
     122%define rtTimeNanoTSInternalAsm    RTTimeNanoTSLFenceInvariantNoDelta
     123%include "timesupA.mac"
     124
     125%define WITH_TSC_DELTA
     126%define NEED_APIC_ID
     127%define rtTimeNanoTSInternalAsm    RTTimeNanoTSLFenceSyncWithDelta
     128%include "timesupA.mac"
     129
     130%define rtTimeNanoTSInternalAsm    RTTimeNanoTSLFenceInvariantWithDelta
    114131%include "timesupA.mac"
    115132
    116133%define ASYNC_GIP
     134%undef  WITH_TSC_DELTA
     135%define NEED_APIC_ID
    117136%ifdef IN_RC
    118137 %undef NEED_TRANSACTION_ID
     
    121140%include "timesupA.mac"
    122141
    123 %undef  ASYNC_GIP
    124 %define INVARIANT_GIP
    125 %define NEED_TRANSACTION_ID
    126 %define rtTimeNanoTSInternalAsm    RTTimeNanoTSLFenceInvariant
    127 ;%include "timesupA.mac"
    128 ;; @todo r=bird: later.
    129 
    130142
    131143%endif ; !IN_GUEST
  • trunk/src/VBox/Runtime/common/time/timesupA.mac

    r53470 r54202  
    7272
    7373    ;
    74     ; Load pGip and calc pGipCPU, setting u32ApicIdPlus if necessary.
     74    ; Load pGip.
    7575    ;
    7676%ifdef IMPORTED_SUPLIB
     
    8888    cmp     dword [esi + SUPGLOBALINFOPAGE.u32Magic], SUPGLOBALINFOPAGE_MAGIC
    8989    jne     .Rediscover
    90 %ifdef ASYNC_GIP
     90
     91    ;
     92    ; Calc pGipCPU, setting u32ApicIdPlus if necessary.
     93    ;
     94%ifdef NEED_APIC_ID
    9195    ; u8ApicId = ASMGetApicId();
    9296    mov     eax, 1
     
    9599    mov     u32ApicIdPlus, ebx
    96100 %endif
    97     ; pGipCpu = &pGip->aCPU[pGip->aiCpuFromApicId[u8ApicId]];
     101    ; pGipCpu/pGipCpuDelta = &pGip->aCPU[pGip->aiCpuFromApicId[u8ApicId]];
    98102    shr     ebx, 24
    99103    movzx   ebx, word [esi + ebx * 2 + SUPGLOBALINFOPAGE.aiCpuFromApicId]
     
    101105    mul     ebx
    102106    lea     edi, [esi + eax + SUPGLOBALINFOPAGE.aCPUs]  ; edi == &pGip->aCPU[u8ApicId];
    103 %else
    104     lea     edi, [esi + SUPGLOBALINFOPAGE.aCPUs]        ; edi == &pGip->aCPU[0];
    105107%endif
    106108
     
    109111    ; Serialized loading of u32TransactionId.
    110112    ;
     113 %ifdef ASYNC_GIP
    111114    mov     ebx, [edi + SUPGIPCPU.u32TransactionId]
     115 %else
     116    mov     ebx, [esi + SUPGLOBALINFOPAGE.aCPUs + SUPGIPCPU.u32TransactionId]
     117 %endif
    112118    mov     u32TransactionId, ebx
    113119 %ifdef USE_LFENCE
     
    119125
    120126    ;
    121     ; Load the data and TSC.
     127    ; Load the data and TSC with delta applied.
    122128    ;
    123129    mov     eax, [esi + SUPGLOBALINFOPAGE.u32UpdateIntervalNS]
    124     mov     u32UpdateIntervalNS, eax    ; esi is now free
     130    mov     u32UpdateIntervalNS, eax
     131%ifdef ASYNC_GIP                        ; esi is now free.
    125132    mov     edx, [edi + SUPGIPCPU.u32UpdateIntervalTSC]
     133%else
     134    mov     edx, [esi + SUPGLOBALINFOPAGE.aCPUs + SUPGIPCPU.u32UpdateIntervalTSC]
     135%endif
    126136    mov     u32UpdateIntervalTSC, edx
     137
    127138    rdtsc
    128 ;; @todo r-bird: Deltas are only valid in INVARIANT mode according to SUPDrv.c macro.
    129 ;; edi is pointing to aCpu[0] in INVARIANT and SYNC.  Code does more harm than good atm => disabled.
    130 ;; (Just drop the SUPTscDeltaApply macro btw.)  Sketched what is needed for invariant in timesupA.asm, more work .cpp files in IPRT and VMM.
    131 ;    SUPTscDeltaApply edi        ; Apply inter-cpu TSC-delta to have the normalized TSC value in edx:eax
     139%ifdef WITH_TSC_DELTA
     140    cmp     dword [edi + SUPGIPCPU.i64TSCDelta], 0xffffffff
     141    je      .TscDeltaPossiblyInvalid
     142.TscDeltaValid:
     143    sub     eax, dword [edi + SUPGIPCPU.i64TSCDelta]
     144    sbb     edx, dword [edi + SUPGIPCPU.i64TSCDelta + 4]
     145.TscDeltaNotValid:                      ; edi is now free.
     146%endif
     147
     148%ifdef ASYNC_GIP
    132149    mov     ecx, [edi + SUPGIPCPU.u64NanoTS]
     150    mov     esi, [edi + SUPGIPCPU.u64NanoTS + 4]
     151%else
     152    mov     ecx, [esi + SUPGLOBALINFOPAGE.aCPUs + SUPGIPCPU.u64NanoTS]
     153    mov     ebx, [esi + SUPGLOBALINFOPAGE.aCPUs + SUPGIPCPU.u64NanoTS + 4]
     154%endif
    133155    mov     u64CurNanoTS, ecx
    134     mov     esi, [edi + SUPGIPCPU.u64NanoTS + 4]
    135     mov     u64CurNanoTS_Hi, esi
    136     mov     ebx, [edi + SUPGIPCPU.u64TSC]
    137     mov     u64TSC, ebx
    138     mov     ecx, [edi + SUPGIPCPU.u64TSC + 4]
    139     mov     u64TSC_Hi, ecx
     156    mov     u64CurNanoTS_Hi, ebx
     157%ifdef ASYNC_GIP
     158    mov     ecx, [edi + SUPGIPCPU.u64TSC]
     159    mov     ebx, [edi + SUPGIPCPU.u64TSC + 4]
     160%else
     161    mov     ecx, [esi + SUPGLOBALINFOPAGE.aCPUs + SUPGIPCPU.u64TSC]
     162    mov     ebx, [esi + SUPGLOBALINFOPAGE.aCPUs + SUPGIPCPU.u64TSC + 4]
     163%endif
     164    mov     u64TSC, ecx
     165    mov     u64TSC_Hi, ebx
    140166
    141167    ; u64PrevNanoTS = ASMAtomicReadU64(pu64Prev);
    142168    ;   This serializes load/save. And with the dependency on the
    143169    ;   RDTSC result, we try to make sure it has completed as well.
     170%ifdef ASYNC_GIP
    144171    mov     esi, pData
    145172    mov     esi, [esi + RTTIMENANOTSDATA.pu64Prev]
     173%else
     174    mov     edi, pData
     175    mov     edi, [esi + RTTIMENANOTSDATA.pu64Prev]
     176%endif
    146177    mov     ebx, eax
    147178    mov     ecx, edx
     179%ifdef ASYNC_GIP
    148180    lock cmpxchg8b [esi]
     181%else
     182    lock cmpxchg8b [edi]
     183%endif
    149184    mov     u64PrevNanoTS, eax
    150185    mov     u64PrevNanoTS_Hi, edx
     
    156191    ; We've already serialized all the loads and stores at this point.
    157192    ;
    158  %ifdef ASYNC_GIP
     193 %ifdef NEED_APIC_ID
    159194    mov     u64RetNanoTS, ebx
    160195    mov     u64RetNanoTS_Hi, ecx
     
    165200    jne     .ReadGip
    166201 %endif
     202 %ifdef ASYNC_GIP
    167203    mov     esi, [edi + SUPGIPCPU.u32TransactionId]
     204 %else
     205    mov     esi, [esi + SUPGLOBALINFOPAGE.aCPUs + SUPGIPCPU.u32TransactionId]
     206 %endif
    168207    cmp     esi, u32TransactionId
    169208    jne     .ReadGip
     
    386425    jmp     .Done
    387426
     427
     428%ifdef WITH_TSC_DELTA
     429    ;;
     430    ;; Unlikely branch for when we think the TSC delta might be invalid.
     431    ;;
     432.TscDeltaPossiblyInvalid:
     433    cmp     dword [edi + SUPGIPCPU.i64TSCDelta + 4], 0x7fffffff
     434    jne     .TscDeltaValid
     435    jmp     .TscDeltaNotValid
     436%endif
     437
    388438    ;
    389439    ; Cleanup variables
     
    423473%define TmpVar2                 [rbp - 38h]
    424474%ifdef NEED_TRANSACTION_ID
    425  %ifdef ASYNC_GIP
     475 %ifdef NEED_APIC_ID
    426476  %define SavedR14              [rbp - 40h]
    427477  %define SavedR15              [rbp - 48h]
     
    431481%define pData                   rdi
    432482
    433 %define u64TSC                  rsi
    434 %define pGip                    rsi
    435 %define pGipCPU                 r8
     483%ifdef ASYNC_GIP
     484 %define u64TSC                 rsi
     485 %define pGip                   rsi
     486 %ifdef NEED_APIC_ID
     487  %define pGipCPU               r8
     488 %endif
     489%else
     490 %define u64TSC                 r8
     491 %define pGip                   rsi
     492 %ifdef NEED_APIC_ID
     493  %define pGipCPU               r8
     494 %endif
     495%endif
    436496%define u32TransactionId        r9d
    437497%define u64CurNanoTS            r10
     
    444504%undef u32ApicIdPlus
    445505%ifdef NEED_TRANSACTION_ID
    446  %ifdef ASYNC_GIP
     506 %ifdef NEED_APIC_ID
    447507  %define u64SavedRetNanoTS     r14
    448508  %define u32ApicIdPlus         r15d
     
    485545
    486546    ;
    487     ; Load pGip and calc pGipCPU, setting u32ApicIdPlus if necessary.
    488     ; Finding the GIP is fun...
     547    ; Load pGip - finding the GIP is fun...
    489548    ;
    490549%ifdef RT_OS_WINDOWS
     
    514573    jne     .Rediscover
    515574
    516 %ifdef ASYNC_GIP
     575    ;
     576    ; pGipCPU, setting u32ApicIdPlus if necessary.
     577    ;
     578%ifdef NEED_APIC_ID
    517579    ; u8ApicId = ASMGetApicId();
    518580    mov     eax, 1
     
    521583    mov     u32ApicIdPlus, ebx
    522584 %endif
    523     ; pGipCpu = &pGip->aCPU[pGip->aiCpuFromApicId[u8ApicId]];
     585    ; pGipCPU = &pGip->aCPU[pGip->aiCpuFromApicId[u8ApicId]];
    524586    shr     ebx, 24
    525587    movzx   eax, word [pGip + rbx * 2 + SUPGLOBALINFOPAGE.aiCpuFromApicId]
    526588    imul    eax, SUPGIPCPU_size
    527589    lea     pGipCPU, [pGip + rax + SUPGLOBALINFOPAGE.aCPUs]
    528 %else
    529     lea     pGipCPU, [pGip + SUPGLOBALINFOPAGE.aCPUs]
    530590%endif
    531591
     
    534594    ; Serialized loading of u32TransactionId.
    535595    ;
     596 %ifdef ASYNC_GIP
    536597    mov     u32TransactionId, [pGipCPU + SUPGIPCPU.u32TransactionId]
     598 %else
     599    mov     u32TransactionId, [pGip + SUPGLOBALINFOPAGE.aCPUs + SUPGIPCPU.u32TransactionId]
     600 %endif
    537601 %ifdef USE_LFENCE
    538602    lfence
     
    545609    ; Load the data and TSC.
    546610    ;
    547     mov     u32UpdateIntervalNS,  [pGip + SUPGLOBALINFOPAGE.u32UpdateIntervalNS] ; before u64TSC
     611    mov     u32UpdateIntervalNS,  [pGip + SUPGLOBALINFOPAGE.u32UpdateIntervalNS]
     612%ifdef ASYNC_GIP
    548613    mov     u32UpdateIntervalTSC, [pGipCPU + SUPGIPCPU.u32UpdateIntervalTSC]
     614%else
     615    mov     u32UpdateIntervalTSC, [pGip + SUPGLOBALINFOPAGE.aCPUs + SUPGIPCPU.u32UpdateIntervalTSC]
     616%endif
     617
    549618    rdtsc
    550 ;; @todo r-bird: Deltas are only valid in INVARIANT mode according to SUPDrv.c macro.
    551 ;; pGipCPU is pointing to aCpu[0] in INVARIANT and SYNC.  Code is 32-bit, i.e. inefficient. Code does more harm than good atm => disabled.
    552 ;; (Just drop the SUPTscDeltaApply macro btw.)  Sketched what is needed for invariant in timesupA.asm, more work .cpp files in IPRT and VMM.
    553 ;    SUPTscDeltaApply pGipCPU
    554619    mov     u64PrevNanoTS,        [pData + RTTIMENANOTSDATA.pu64Prev]
    555620    mov     u64PrevNanoTS,        [u64PrevNanoTS]
    556621    shl     rdx, 32
    557  %ifdef u64SavedRetNanoTS               ; doing this here saves a tick or so.
     622    or      rax, rdx                    ; rax is u64RetNanoTS.
     623%ifdef WITH_TSC_DELTA
     624    mov     rdx, [pGipCPU + SUPGIPCPU.i64TSCDelta]
     625    mov     u64CurNanoTS, 0x7fffffffffffffff ; INT64_MAX - temporarily borrowing u64CurNanoTS
     626    cmp     rdx, u64CurNanoTS
     627    je      .TscDeltaNotValid
     628    sub     rax, rdx
     629.TscDeltaNotValid:
     630%endif
     631%ifdef u64SavedRetNanoTS                ; doing this here may save a tick or so?
    558632    mov     u64SavedRetNanoTS, rax
    559     or      u64SavedRetNanoTS, rdx
    560  %else
    561     or      rax, rdx                    ; rax is u64RetNanoTS.
    562  %endif
     633%endif
     634
     635%ifdef ASYNC_GIP
    563636    mov     u64CurNanoTS,         [pGipCPU + SUPGIPCPU.u64NanoTS]
    564     mov     u64TSC,               [pGipCPU + SUPGIPCPU.u64TSC]
     637    mov     u64TSC,               [pGipCPU + SUPGIPCPU.u64TSC]                              ; transhes pGIP!
     638%else
     639    mov     u64CurNanoTS,         [pGip + SUPGLOBALINFOPAGE.aCPUs + SUPGIPCPU.u64NanoTS]
     640    mov     u64TSC,               [pGip + SUPGLOBALINFOPAGE.aCPUs + SUPGIPCPU.u64TSC]       ; trashes pGipCPU!
     641%endif
     642
    565643
    566644%ifdef NEED_TRANSACTION_ID
     
    573651    ; CPUID is serializing, so the async path is safe by default.
    574652    ;
    575  %ifdef ASYNC_GIP
     653 %ifdef NEED_APIC_ID
    576654    mov     eax, 1
    577655    cpuid
     
    581659    lock xor qword TmpVar, rax
    582660 %endif
     661 %ifdef ASYNC_GIP
    583662    cmp     u32TransactionId, [pGipCPU + SUPGIPCPU.u32TransactionId]
     663 %else
     664    cmp     u32TransactionId, [pGip + SUPGLOBALINFOPAGE.aCPUs + SUPGIPCPU.u32TransactionId]
     665 %endif
    584666    jne     .ReadGip
    585667    test    u32TransactionId, 1
  • trunk/src/VBox/Runtime/common/time/timesupref.cpp

    r48935 r54202  
    55
    66/*
    7  * Copyright (C) 2006-2010 Oracle Corporation
     7 * Copyright (C) 2006-2015 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    4040
    4141
     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)
     49
     50
    4251/*
    4352 * Use the CPUID instruction for some kind of serialization.
    4453 */
    45 #undef  ASYNC_GIP
     54#define GIP_MODE GIP_MODE_SYNC_NO_DELTA
    4655#undef  USE_LFENCE
    4756#define NEED_TRANSACTION_ID
    48 #define rtTimeNanoTSInternalRef RTTimeNanoTSLegacySync
     57#define rtTimeNanoTSInternalRef RTTimeNanoTSLegacySyncNoDelta
    4958#include "timesupref.h"
    50 RT_EXPORT_SYMBOL(RTTimeNanoTSLegacySync);
     59RT_EXPORT_SYMBOL(RTTimeNanoTSLegacySyncNoDelta);
    5160
    52 #define ASYNC_GIP
     61#undef  GIP_MODE
     62#define GIP_MODE  GIP_MODE_SYNC_NO_DELTA
     63#undef  rtTimeNanoTSInternalRef
     64#define rtTimeNanoTSInternalRef RTTimeNanoTSLegacySyncWithDelta
     65#include "timesupref.h"
     66RT_EXPORT_SYMBOL(RTTimeNanoTSLegacySyncWithDelta);
     67
     68#undef  GIP_MODE
     69#define GIP_MODE GIP_MODE_ASYNC
    5370#ifdef IN_RC
    5471# undef NEED_TRANSACTION_ID
     
    5976RT_EXPORT_SYMBOL(RTTimeNanoTSLegacyAsync);
    6077
     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"
     85RT_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"
     92RT_EXPORT_SYMBOL(RTTimeNanoTSLegacyInvariantWithDelta);
     93
    6194
    6295/*
    6396 * Use LFENCE for load serialization.
    6497 */
    65 #undef  ASYNC_GIP
     98#undef  GIP_MODE
     99#define GIP_MODE GIP_MODE_SYNC_NO_DELTA
    66100#define USE_LFENCE
    67101#undef  NEED_TRANSACTION_ID
    68102#define NEED_TRANSACTION_ID
    69103#undef  rtTimeNanoTSInternalRef
    70 #define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceSync
     104#define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceSyncNoDelta
    71105#include "timesupref.h"
    72 RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceSync);
     106RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceSyncNoDelta);
    73107
    74 #define ASYNC_GIP
     108#undef  GIP_MODE
     109#define GIP_MODE GIP_MODE_SYNC_WITH_DELTA
     110#undef  rtTimeNanoTSInternalRef
     111#define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceSyncWithDelta
     112#include "timesupref.h"
     113RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceSyncWithDelta);
     114
     115#undef  GIP_MODE
     116#define GIP_MODE GIP_MODE_ASYNC
    75117#ifdef IN_RC
    76118# undef NEED_TRANSACTION_ID
     
    81123RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceAsync);
    82124
     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"
     132RT_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"
     139RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceInvariantWithDelta);
     140
    83141
    84142#endif /* !IN_GUEST && !RT_NO_GIP */
  • trunk/src/VBox/Runtime/common/time/timesupref.h

    r53430 r54202  
    55
    66/*
    7  * Copyright (C) 2006-2014 Oracle Corporation
     7 * Copyright (C) 2006-2015 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    4545{
    4646    uint64_t    u64Delta;
     47#if IS_GIP_MODE_WITH_DELTA(GIP_MODE)
     48    int64_t     i64TscDelta;
     49#endif
    4750    uint32_t    u32NanoTSFactor0;
    4851    uint64_t    u64TSC;
     
    6164            return pData->pfnRediscover(pData);
    6265#endif
    63 
    64 #ifdef ASYNC_GIP
    65         uint8_t    u8ApicId = ASMGetApicId();
    66         PSUPGIPCPU pGipCpu = &pGip->aCPUs[pGip->aiCpuFromApicId[u8ApicId]];
     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# else
     75        uint32_t u32TransactionId = pGip->aCPUs[0].u32TransactionId;
     76# endif
     77# ifdef USE_LFENCE
     78        ASMReadFenceSSE2();
     79# 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;
    6788#else
    68         PSUPGIPCPU pGipCpu = &pGip->aCPUs[0];
    69 #endif
     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);
    7099
    71100#ifdef NEED_TRANSACTION_ID
    72         uint32_t u32TransactionId = pGipCpu->u32TransactionId;
    73         uint32_t volatile Tmp1;
    74         ASMAtomicXchgU32(&Tmp1, u32TransactionId);
    75 #endif
    76 
    77         u32UpdateIntervalTSC = pGipCpu->u32UpdateIntervalTSC;
    78         u64NanoTS = pGipCpu->u64NanoTS;
    79         u64TSC = pGipCpu->u64TSC;
    80         u32NanoTSFactor0 = pGip->u32UpdateIntervalNS;
    81         u64Delta = ASMReadTSC();
    82         u64PrevNanoTS = ASMAtomicReadU64(pData->pu64Prev);
    83 
    84 #ifdef NEED_TRANSACTION_ID
    85 # ifdef ASYNC_GIP
     101# if GIP_MODE == GIP_MODE_ASYNC || IS_GIP_MODE_WITH_DELTA(GIP_MODE)
    86102        if (RT_UNLIKELY(u8ApicId != ASMGetApicId()))
    87103            continue;
    88 # elif !defined(RT_ARCH_X86)
    89         uint32_t volatile Tmp2;
    90         ASMAtomicXchgU32(&Tmp2, u64Delta);
    91 # endif
    92         if (RT_UNLIKELY(    pGipCpu->u32TransactionId != u32TransactionId
    93                         ||  (u32TransactionId & 1)))
     104# elif defined(USE_LFENCE)
     105        ASMWriteFenceSSE();
     106# else
     107        ASMWriteFence();
     108# endif
     109# if GIP_MODE == GIP_MODE_ASYNC
     110        if (RT_UNLIKELY(   pGipCpu->u32TransactionId != u32TransactionId
     111                        || (u32TransactionId & 1)))
    94112            continue;
     113# else
     114        if (RT_UNLIKELY(   pGip->aCPUs[0].u32TransactionId != u32TransactionId
     115                        || (u32TransactionId & 1)))
     116            continue;
     117# endif
    95118#endif
    96119        break;
     
    101124     */
    102125    u64Delta -= u64TSC;
     126#if IS_GIP_MODE_WITH_DELTA(GIP_MODE)
     127    if (RT_LIKELY(i64TscDelta != INT64_MAX))
     128        u64Delta -= i64TscDelta;
     129#endif
    103130    if (RT_UNLIKELY(u64Delta > u32UpdateIntervalTSC))
    104131    {
  • trunk/src/VBox/VMM/VMMR3/TM.cpp

    r54195 r54202  
    168168*******************************************************************************/
    169169static bool                 tmR3HasFixedTSC(PVM pVM);
     170static bool                 tmR3ReallyNeedDeltas(PSUPGLOBALINFOPAGE pGip);
    170171static const char *         tmR3GetTSCModeName(PVM pVM);
    171172static uint64_t             tmR3CalibrateTSC(PVM pVM);
     
    274275    if (ASMCpuId_EDX(1) & X86_CPUID_FEATURE_EDX_SSE2)
    275276    {
    276         if (   g_pSUPGlobalInfoPage->u32Mode == SUPGIPMODE_INVARIANT_TSC
    277             || g_pSUPGlobalInfoPage->u32Mode == SUPGIPMODE_SYNC_TSC)
    278             pVM->tm.s.pfnVirtualGetRawR3 = RTTimeNanoTSLFenceSync;
     277        if (g_pSUPGlobalInfoPage->u32Mode == SUPGIPMODE_INVARIANT_TSC)
     278            pVM->tm.s.pfnVirtualGetRawR3 = tmR3ReallyNeedDeltas(g_pSUPGlobalInfoPage)
     279                                         ? RTTimeNanoTSLFenceInvariantWithDelta : RTTimeNanoTSLFenceInvariantNoDelta;
     280        else if (g_pSUPGlobalInfoPage->u32Mode == SUPGIPMODE_SYNC_TSC)
     281            pVM->tm.s.pfnVirtualGetRawR3 = false /** @todo tmR3ReallyNeedDeltas(g_pSUPGlobalInfoPage) */
     282                                         ? RTTimeNanoTSLFenceSyncWithDelta      : RTTimeNanoTSLFenceSyncNoDelta;
    279283        else
    280284            pVM->tm.s.pfnVirtualGetRawR3 = RTTimeNanoTSLFenceAsync;
     
    282286    else
    283287    {
    284         if (   g_pSUPGlobalInfoPage->u32Mode == SUPGIPMODE_INVARIANT_TSC
    285             || g_pSUPGlobalInfoPage->u32Mode == SUPGIPMODE_SYNC_TSC)
    286             pVM->tm.s.pfnVirtualGetRawR3 = RTTimeNanoTSLegacySync;
     288        if (g_pSUPGlobalInfoPage->u32Mode == SUPGIPMODE_INVARIANT_TSC)
     289            pVM->tm.s.pfnVirtualGetRawR3 = tmR3ReallyNeedDeltas(g_pSUPGlobalInfoPage)
     290                                         ? RTTimeNanoTSLegacyInvariantWithDelta : RTTimeNanoTSLegacyInvariantNoDelta;
     291        else if (g_pSUPGlobalInfoPage->u32Mode == SUPGIPMODE_SYNC_TSC)
     292            pVM->tm.s.pfnVirtualGetRawR3 = false /** @todo tmR3ReallyNeedDeltas(g_pSUPGlobalInfoPage) */
     293                                         ? RTTimeNanoTSLegacySyncWithDelta      : RTTimeNanoTSLegacySyncNoDelta;
    287294        else
    288295            pVM->tm.s.pfnVirtualGetRawR3 = RTTimeNanoTSLegacyAsync;
     
    937944
    938945/**
     946 * Checks if we really need to apply the delta values when calculating time.
     947 *
     948 * Getting the delta for a CPU is _very_ expensive, it more than doubles the
     949 * execution time for RTTimeNanoTS.
     950 *
     951 * @returns true if deltas needs to be applied, false if not.
     952 * @param   pGip                The GIP.
     953 */
     954static bool tmR3ReallyNeedDeltas(PSUPGLOBALINFOPAGE pGip)
     955{
     956    if (!pGip->fOsTscDeltasInSync)
     957    {
     958        uint32_t i = pGip->cCpus;
     959        while (i-- > 0)
     960            if (   pGip->aCPUs[i].enmState == SUPGIPCPUSTATE_ONLINE
     961                && (   pGip->aCPUs[i].i64TSCDelta > 384
     962                    || pGip->aCPUs[i].i64TSCDelta < -384) )
     963                return true;
     964    }
     965    return false;
     966}
     967
     968
     969/**
    939970 * Calibrate the CPU tick.
    940971 *
     
    10291060
    10301061/**
     1062 * Translates TM::pfnVirtualGetRawR3 to a symbol name that we can find in ring-0
     1063 * and raw-mode context.
     1064 *
     1065 * @returns Symbol name.
     1066 * @param   pfnWorkerR3         The TM::pfnVirtualGetRawR3 value.
     1067 */
     1068static const char *tmR3GetRTTimeNanoName(PFNTIMENANOTSINTERNAL pfnWorkerR3)
     1069{
     1070    /*
     1071     * Translation of pfnVirtualGetRawR3 to symbol names.
     1072     */
     1073    static const struct
     1074    {
     1075        PFNTIMENANOTSINTERNAL   pfnR3Worker;
     1076        const char             *pszName;
     1077    } s_aNanoTsWorkers[] =
     1078    {
     1079#define ENTRY(a) { a, #a }
     1080        ENTRY(RTTimeNanoTSLegacyAsync),
     1081        ENTRY(RTTimeNanoTSLegacyInvariantNoDelta),
     1082        ENTRY(RTTimeNanoTSLegacyInvariantWithDelta),
     1083        ENTRY(RTTimeNanoTSLegacySyncNoDelta),
     1084        ENTRY(RTTimeNanoTSLegacySyncWithDelta),
     1085        ENTRY(RTTimeNanoTSLFenceAsync),
     1086        ENTRY(RTTimeNanoTSLFenceInvariantNoDelta),
     1087        ENTRY(RTTimeNanoTSLFenceInvariantWithDelta),
     1088        ENTRY(RTTimeNanoTSLFenceSyncNoDelta),
     1089        ENTRY(RTTimeNanoTSLFenceSyncWithDelta),
     1090#undef ENTRY
     1091    };
     1092    uint32_t iNanoTs;
     1093    for (iNanoTs = 0; iNanoTs < RT_ELEMENTS(s_aNanoTsWorkers); iNanoTs++)
     1094        if (pfnWorkerR3 == s_aNanoTsWorkers[iNanoTs].pfnR3Worker)
     1095            return s_aNanoTsWorkers[iNanoTs].pszName;
     1096    AssertFatal(iNanoTs < RT_ELEMENTS(s_aNanoTsWorkers));
     1097    return NULL;
     1098}
     1099
     1100
     1101/**
    10311102 * Finalizes the TM initialization.
    10321103 *
     
    10411112     * Resolve symbols.
    10421113     */
     1114    const char *pszRTTimeNanoTS = tmR3GetRTTimeNanoName(pVM->tm.s.pfnVirtualGetRawR3);
    10431115    if (!HMIsEnabled(pVM))
    10441116    {
    1045         rc = PDMR3LdrGetSymbolRC(pVM, NULL, "tmVirtualNanoTSBad",          &pVM->tm.s.VirtualGetRawDataRC.pfnBad);
     1117        rc = PDMR3LdrGetSymbolRC(pVM, NULL, "tmVirtualNanoTSBad",           &pVM->tm.s.VirtualGetRawDataRC.pfnBad);
    10461118        AssertRCReturn(rc, rc);
    1047         rc = PDMR3LdrGetSymbolRC(pVM, NULL, "tmVirtualNanoTSRediscover",   &pVM->tm.s.VirtualGetRawDataRC.pfnRediscover);
     1119        rc = PDMR3LdrGetSymbolRC(pVM, NULL, "tmVirtualNanoTSRediscover",    &pVM->tm.s.VirtualGetRawDataRC.pfnRediscover);
    10481120        AssertRCReturn(rc, rc);
    1049         if (pVM->tm.s.pfnVirtualGetRawR3       == RTTimeNanoTSLFenceSync)
    1050             rc = PDMR3LdrGetSymbolRC(pVM, NULL, "RTTimeNanoTSLFenceSync",  &pVM->tm.s.pfnVirtualGetRawRC);
    1051         else if (pVM->tm.s.pfnVirtualGetRawR3  == RTTimeNanoTSLFenceAsync)
    1052             rc = PDMR3LdrGetSymbolRC(pVM, NULL, "RTTimeNanoTSLFenceAsync", &pVM->tm.s.pfnVirtualGetRawRC);
    1053         else if (pVM->tm.s.pfnVirtualGetRawR3  == RTTimeNanoTSLegacySync)
    1054             rc = PDMR3LdrGetSymbolRC(pVM, NULL, "RTTimeNanoTSLegacySync",  &pVM->tm.s.pfnVirtualGetRawRC);
    1055         else if (pVM->tm.s.pfnVirtualGetRawR3  == RTTimeNanoTSLegacyAsync)
    1056             rc = PDMR3LdrGetSymbolRC(pVM, NULL, "RTTimeNanoTSLegacyAsync", &pVM->tm.s.pfnVirtualGetRawRC);
    1057         else
    1058             AssertFatalFailed();
     1121        rc = PDMR3LdrGetSymbolRC(pVM, NULL, pszRTTimeNanoTS,                &pVM->tm.s.pfnVirtualGetRawRC);
    10591122        AssertRCReturn(rc, rc);
    10601123    }
    10611124
    1062     rc = PDMR3LdrGetSymbolR0(pVM, NULL, "tmVirtualNanoTSBad",          &pVM->tm.s.VirtualGetRawDataR0.pfnBad);
     1125    rc = PDMR3LdrGetSymbolR0(pVM, NULL, "tmVirtualNanoTSBad",           &pVM->tm.s.VirtualGetRawDataR0.pfnBad);
    10631126    AssertRCReturn(rc, rc);
    1064     rc = PDMR3LdrGetSymbolR0(pVM, NULL, "tmVirtualNanoTSRediscover",   &pVM->tm.s.VirtualGetRawDataR0.pfnRediscover);
     1127    rc = PDMR3LdrGetSymbolR0(pVM, NULL, "tmVirtualNanoTSRediscover",    &pVM->tm.s.VirtualGetRawDataR0.pfnRediscover);
    10651128    AssertRCReturn(rc, rc);
    1066     if (pVM->tm.s.pfnVirtualGetRawR3       == RTTimeNanoTSLFenceSync)
    1067         rc = PDMR3LdrGetSymbolR0(pVM, NULL, "RTTimeNanoTSLFenceSync",  &pVM->tm.s.pfnVirtualGetRawR0);
    1068     else if (pVM->tm.s.pfnVirtualGetRawR3  == RTTimeNanoTSLFenceAsync)
    1069         rc = PDMR3LdrGetSymbolR0(pVM, NULL, "RTTimeNanoTSLFenceAsync", &pVM->tm.s.pfnVirtualGetRawR0);
    1070     else if (pVM->tm.s.pfnVirtualGetRawR3  == RTTimeNanoTSLegacySync)
    1071         rc = PDMR3LdrGetSymbolR0(pVM, NULL, "RTTimeNanoTSLegacySync",  &pVM->tm.s.pfnVirtualGetRawR0);
    1072     else if (pVM->tm.s.pfnVirtualGetRawR3  == RTTimeNanoTSLegacyAsync)
    1073         rc = PDMR3LdrGetSymbolR0(pVM, NULL, "RTTimeNanoTSLegacyAsync", &pVM->tm.s.pfnVirtualGetRawR0);
    1074     else
    1075         AssertFatalFailed();
     1129    rc = PDMR3LdrGetSymbolR0(pVM, NULL, pszRTTimeNanoTS,                &pVM->tm.s.pfnVirtualGetRawR0);
    10761130    AssertRCReturn(rc, rc);
    10771131
     
    11161170        pVM->tm.s.VirtualGetRawDataRC.pu64Prev = MMHyperR3ToRC(pVM, (void *)&pVM->tm.s.u64VirtualRawPrev);
    11171171        AssertFatal(pVM->tm.s.VirtualGetRawDataRC.pu64Prev);
    1118         rc = PDMR3LdrGetSymbolRC(pVM, NULL, "tmVirtualNanoTSBad",          &pVM->tm.s.VirtualGetRawDataRC.pfnBad);
     1172        rc = PDMR3LdrGetSymbolRC(pVM, NULL, "tmVirtualNanoTSBad",           &pVM->tm.s.VirtualGetRawDataRC.pfnBad);
    11191173        AssertFatalRC(rc);
    1120         rc = PDMR3LdrGetSymbolRC(pVM, NULL, "tmVirtualNanoTSRediscover",   &pVM->tm.s.VirtualGetRawDataRC.pfnRediscover);
     1174        rc = PDMR3LdrGetSymbolRC(pVM, NULL, "tmVirtualNanoTSRediscover",    &pVM->tm.s.VirtualGetRawDataRC.pfnRediscover);
    11211175        AssertFatalRC(rc);
    1122 
    1123         if (pVM->tm.s.pfnVirtualGetRawR3       == RTTimeNanoTSLFenceSync)
    1124             rc = PDMR3LdrGetSymbolRC(pVM, NULL, "RTTimeNanoTSLFenceSync",  &pVM->tm.s.pfnVirtualGetRawRC);
    1125         else if (pVM->tm.s.pfnVirtualGetRawR3  == RTTimeNanoTSLFenceAsync)
    1126             rc = PDMR3LdrGetSymbolRC(pVM, NULL, "RTTimeNanoTSLFenceAsync", &pVM->tm.s.pfnVirtualGetRawRC);
    1127         else if (pVM->tm.s.pfnVirtualGetRawR3  == RTTimeNanoTSLegacySync)
    1128             rc = PDMR3LdrGetSymbolRC(pVM, NULL, "RTTimeNanoTSLegacySync",  &pVM->tm.s.pfnVirtualGetRawRC);
    1129         else if (pVM->tm.s.pfnVirtualGetRawR3  == RTTimeNanoTSLegacyAsync)
    1130             rc = PDMR3LdrGetSymbolRC(pVM, NULL, "RTTimeNanoTSLegacyAsync", &pVM->tm.s.pfnVirtualGetRawRC);
    1131         else
    1132             AssertFatalFailed();
     1176        const char *pszRTTimeNanoTS = tmR3GetRTTimeNanoName(pVM->tm.s.pfnVirtualGetRawR3);
     1177        rc = PDMR3LdrGetSymbolRC(pVM, NULL, pszRTTimeNanoTS,                &pVM->tm.s.pfnVirtualGetRawRC);
    11331178        AssertFatalRC(rc);
    11341179    }
  • trunk/src/VBox/VMM/include/TMInternal.h

    r54195 r54202  
    420420    /** Pointer to the ring-3 tmVirtualGetRawNanoTS worker function. */
    421421    R3PTRTYPE(PFNTIMENANOTSINTERNAL) pfnVirtualGetRawR3;
    422     /** Pointer to the ring-3 tmVirtualGetRawNanoTS worker function. */
     422    /** Pointer to the ring-0 tmVirtualGetRawNanoTS worker function. */
    423423    R0PTRTYPE(PFNTIMENANOTSINTERNAL) pfnVirtualGetRawR0;
    424     /** Pointer to the ring-3 tmVirtualGetRawNanoTS worker function. */
     424    /** Pointer to the raw-mode tmVirtualGetRawNanoTS worker function. */
    425425    RCPTRTYPE(PFNTIMENANOTSINTERNAL) pfnVirtualGetRawRC;
    426426    /** Alignment. */
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