VirtualBox

Changeset 36254 in vbox for trunk/src/VBox/HostDrivers


Ignore:
Timestamp:
Mar 10, 2011 5:22:08 PM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
70492
Message:

GIP,++: Lots of CPUs (disabled).

Location:
trunk/src/VBox/HostDrivers/Support
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/Support/SUPDrv.c

    r36239 r36254  
    131131static DECLCALLBACK(void)   supdrvGipAsyncTimer(PRTTIMER pTimer, void *pvUser, uint64_t iTick);
    132132static DECLCALLBACK(void)   supdrvGipMpEvent(RTMPEVENT enmEvent, RTCPUID idCpu, void *pvUser);
    133 static void                 supdrvGipInit(PSUPDRVDEVEXT pDevExt, PSUPGLOBALINFOPAGE pGip, RTHCPHYS HCPhys, uint64_t u64NanoTS, unsigned uUpdateHz);
     133static void                 supdrvGipInit(PSUPDRVDEVEXT pDevExt, PSUPGLOBALINFOPAGE pGip, RTHCPHYS HCPhys,
     134                                          uint64_t u64NanoTS, unsigned uUpdateHz, unsigned cCpus);
     135static DECLCALLBACK(void)   supdrvGipInitOnCpu(RTCPUID idCpu, void *pvUser1, void *pvUser2);
    134136static void                 supdrvGipTerm(PSUPGLOBALINFOPAGE pGip);
    135 static void                 supdrvGipUpdate(PSUPGLOBALINFOPAGE pGip, uint64_t u64NanoTS, uint64_t u64TSC, uint64_t iTick);
    136 static void                 supdrvGipUpdatePerCpu(PSUPGLOBALINFOPAGE pGip, uint64_t u64NanoTS, uint64_t u64TSC, unsigned iCpu, uint64_t iTick);
     137static void                 supdrvGipUpdate(PSUPGLOBALINFOPAGE pGip, uint64_t u64NanoTS, uint64_t u64TSC, RTCPUID idCpu, uint64_t iTick);
     138static void                 supdrvGipUpdatePerCpu(PSUPGLOBALINFOPAGE pGip, uint64_t u64NanoTS, uint64_t u64TSC,
     139                                                  RTCPUID idCpu, uint8_t idApic, uint64_t iTick);
    137140
    138141
     
    289292    { "RTThreadUserWait",                       (void *)RTThreadUserWait },
    290293    { "RTThreadUserWaitNoResume",               (void *)RTThreadUserWaitNoResume },
    291 #else 
    292     /** 
    293      * @todo: remove me, once above code enabled. 
    294      * We need RTThreadCreate/RTThreadWait in the PCI driver. 
    295      */ 
    296     { "RTThreadCreate",                         (void *)RTThreadCreate }, 
    297     { "RTThreadWait",                           (void *)RTThreadWait }, 
     294#else
     295    /**
     296     * @todo: remove me, once above code enabled.
     297     * We need RTThreadCreate/RTThreadWait in the PCI driver.
     298     */
     299    { "RTThreadCreate",                         (void *)RTThreadCreate },
     300    { "RTThreadWait",                           (void *)RTThreadWait },
    298301#endif
    299302    { "RTThreadPreemptIsEnabled",               (void *)RTThreadPreemptIsEnabled },
     
    32133216{
    32143217    PSUPGLOBALINFOPAGE  pGip = (PSUPGLOBALINFOPAGE)pvUser1;
     3218#ifdef SUP_WITH_LOTS_OF_CPUS
     3219    unsigned            iCpu = pGip->aiCpuFromApicId[ASMGetApicId()];
     3220#else
    32153221    unsigned            iCpu = ASMGetApicId();
    3216 
     3222#endif
     3223
     3224#ifdef SUP_WITH_LOTS_OF_CPUS
     3225    if (RT_LIKELY(iCpu < pGip->cCpus && pGip->aCPUs[iCpu].idCpu == idCpu))
     3226#else
    32173227    if (RT_LIKELY(iCpu < RT_ELEMENTS(pGip->aCPUs)))
     3228#endif
    32183229        supdrvGipReInitCpu(&pGip->aCPUs[iCpu], *(uint64_t *)pvUser2);
    32193230
     
    48074818static int supdrvGipCreate(PSUPDRVDEVEXT pDevExt)
    48084819{
    4809     PSUPGLOBALINFOPAGE pGip;
    4810     RTHCPHYS HCPhysGip;
    4811     uint32_t u32SystemResolution;
    4812     uint32_t u32Interval;
    4813     int rc;
     4820    PSUPGLOBALINFOPAGE  pGip;
     4821    RTHCPHYS            HCPhysGip;
     4822    uint32_t            u32SystemResolution;
     4823    uint32_t            u32Interval;
     4824    unsigned            cCpus;
     4825    int                 rc;
     4826
    48144827
    48154828    LogFlow(("supdrvGipCreate:\n"));
     
    48214834
    48224835    /*
    4823      * Allocate a suitable page with a default kernel mapping.
    4824      */
    4825     rc = RTR0MemObjAllocLow(&pDevExt->GipMemObj, PAGE_SIZE, false);
     4836     * Check the CPU count.
     4837     */
     4838    cCpus = RTMpGetArraySize();
     4839#ifdef SUP_WITH_LOTS_OF_CPUS
     4840    if (   cCpus > RTCPUSET_MAX_CPUS
     4841        || cCpus > 256 /*uint8_t is used for the mappings*/)
     4842#else
     4843    if (cCpus > RT_ELEMENTS(pGip->aCPUs))
     4844#endif
     4845    {
     4846#ifdef SUP_WITH_LOTS_OF_CPUS
     4847        SUPR0Printf("VBoxDrv: Too many CPUs (%u) for the GIP (max %u)\n", cCpus, RT_MIN(RTCPUSET_MAX_CPUS, 256));
     4848#else
     4849        SUPR0Printf("VBoxDrv: Too many CPUs (%u) for the GIP (max %u)\n", cCpus, RT_MIN(RT_ELEMENTS(pGip->aCPUs), 256));
     4850#endif
     4851        return VERR_TOO_MANY_CPUS;
     4852    }
     4853
     4854    /*
     4855     * Allocate a contiguous set of pages with a default kernel mapping.
     4856     */
     4857#ifdef SUP_WITH_LOTS_OF_CPUS
     4858    rc = RTR0MemObjAllocCont(&pDevExt->GipMemObj, RT_UOFFSETOF(SUPGLOBALINFOPAGE, aCPUs[cCpus]), false /*fExecutable*/);
     4859#else
     4860    cCpus = RT_ELEMENTS(pGip->aCPUs);
     4861    rc = RTR0MemObjAllocLow(&pDevExt->GipMemObj, PAGE_SIZE, false /*fExecutable*/);
     4862#endif
    48264863    if (RT_FAILURE(rc))
    48274864    {
     
    48394876        u32Interval += u32SystemResolution;
    48404877
    4841     supdrvGipInit(pDevExt, pGip, HCPhysGip, RTTimeSystemNanoTS(), 1000000000 / u32Interval /*=Hz*/);
     4878    supdrvGipInit(pDevExt, pGip, HCPhysGip, RTTimeSystemNanoTS(), 1000000000 / u32Interval /*=Hz*/, cCpus);
    48424879
    48434880    /*
     
    48584895    if (RT_SUCCESS(rc))
    48594896    {
    4860         if (pGip->u32Mode == SUPGIPMODE_ASYNC_TSC)
    4861             rc = RTMpNotificationRegister(supdrvGipMpEvent, pDevExt);
     4897        rc = RTMpNotificationRegister(supdrvGipMpEvent, pDevExt);
    48624898        if (RT_SUCCESS(rc))
    48634899        {
    4864             /*
    4865              * We're good.
    4866              */
    4867             Log(("supdrvGipCreate: %ld ns interval.\n", (long)u32Interval));
    4868             g_pSUPGlobalInfoPage = pGip;
    4869             return VINF_SUCCESS;
    4870         }
    4871 
    4872         OSDBGPRINT(("supdrvGipCreate: failed register MP event notfication. rc=%d\n", rc));
     4900            rc = RTMpOnAll(supdrvGipInitOnCpu, pDevExt, pGip);
     4901            if (RT_SUCCESS(rc))
     4902            {
     4903                /*
     4904                 * We're good.
     4905                 */
     4906                Log(("supdrvGipCreate: %u ns interval.\n", u32Interval));
     4907                g_pSUPGlobalInfoPage = pGip;
     4908                return VINF_SUCCESS;
     4909            }
     4910
     4911            OSDBGPRINT(("supdrvGipCreate: RTMpOnAll failed with rc=%Rrc\n", rc));
     4912            RTMpNotificationDeregister(supdrvGipMpEvent, pDevExt);
     4913
     4914        }
     4915        else
     4916            OSDBGPRINT(("supdrvGipCreate: failed to register MP event notfication. rc=%Rrc\n", rc));
    48734917    }
    48744918    else
    48754919    {
    4876         OSDBGPRINT(("supdrvGipCreate: failed create GIP timer at %ld ns interval. rc=%d\n", (long)u32Interval, rc));
     4920        OSDBGPRINT(("supdrvGipCreate: failed create GIP timer at %u ns interval. rc=%Rrc\n", u32Interval, rc));
    48774921        Assert(!pDevExt->pGipTimer);
    48784922    }
     
    49454989    uint64_t        NanoTS    = RTTimeSystemNanoTS();
    49464990
    4947     supdrvGipUpdate(pDevExt->pGip, NanoTS, u64TSC, iTick);
     4991    supdrvGipUpdate(pDevExt->pGip, NanoTS, u64TSC, NIL_RTCPUID, iTick);
    49484992
    49494993    ASMSetFlags(fOldFlags);
     
    49665010    /** @todo reset the transaction number and whatnot when iTick == 1. */
    49675011    if (pDevExt->idGipMaster == idCpu)
    4968         supdrvGipUpdate(pDevExt->pGip, NanoTS, u64TSC, iTick);
     5012        supdrvGipUpdate(pDevExt->pGip, NanoTS, u64TSC, idCpu, iTick);
    49695013    else
    4970         supdrvGipUpdatePerCpu(pDevExt->pGip, NanoTS, u64TSC, ASMGetApicId(), iTick);
     5014        supdrvGipUpdatePerCpu(pDevExt->pGip, NanoTS, u64TSC, idCpu, ASMGetApicId(), iTick);
    49715015
    49725016    ASMSetFlags(fOldFlags);
     
    49755019
    49765020/**
     5021 * The calling CPU should be accounted as online, update GIP accordingly.
     5022 *
     5023 * This is used by supdrvGipMpEvent as well as the supdrvGipCreate.
     5024 *
     5025 * @param   pGip                The GIP.
     5026 * @param   idCpu               The CPU ID.
     5027 */
     5028static void supdrvGipMpEventOnline(PSUPGLOBALINFOPAGE pGip, RTCPUID idCpu)
     5029{
     5030#ifdef SUP_WITH_LOTS_OF_CPUS
     5031    int         iCpuSet;
     5032    uint8_t     idApic;
     5033    uint32_t    i;
     5034
     5035    Assert(idCpu == RTMpCpuId());
     5036    Assert(pGip->cPossibleCpus == RTMpGetCount());
     5037
     5038    /*
     5039     * Update the globals.
     5040     */
     5041    ASMAtomicWriteU32(&pGip->cPresentCpus,  RTMpGetPresentCount());
     5042    ASMAtomicWriteU32(&pGip->cOnlineCpus,   RTMpGetOnlineCount());
     5043    iCpuSet = RTMpCpuIdToSetIndex(idCpu);
     5044    if (iCpuSet >= 0)
     5045    {
     5046        Assert(RTCpuSetIsMemberByIndex(&pGip->PossibleCpuSet, iCpuSet));
     5047        RTCpuSetAddByIndex(&pGip->OnlineCpuSet, iCpuSet);
     5048        RTCpuSetAddByIndex(&pGip->PresentCpuSet, iCpuSet);
     5049    }
     5050
     5051    /*
     5052     * Find our entry, or allocate one if not found.
     5053     * ASSUMES that CPU IDs are constant.
     5054     */
     5055    for (i = 0; i < pGip->cCpus; i++)
     5056        if (pGip->aCPUs[i].idCpu == idCpu)
     5057            break;
     5058
     5059    if (i >= pGip->cCpus)
     5060        for (i = 0; i < pGip->cCpus; i++)
     5061        {
     5062            bool fRc;
     5063            ASMAtomicCmpXchgSize(&pGip->aCPUs[i].idCpu, idCpu, NIL_RTCPUID, fRc);
     5064            if (fRc)
     5065                break;
     5066        }
     5067
     5068    AssertReturnVoid(i < pGip->cCpus);
     5069
     5070    /*
     5071     * Update the entry.
     5072     */
     5073    idApic = ASMGetApicId();
     5074    ASMAtomicUoWriteU16(&pGip->aCPUs[i].idApic,  idApic);
     5075    ASMAtomicUoWriteS16(&pGip->aCPUs[i].iCpuSet, (int16_t)iCpuSet);
     5076    ASMAtomicUoWriteSize(&pGip->aCPUs[i].idCpu,  idCpu);
     5077    ASMAtomicWriteSize(&pGip->aCPUs[i].enmState, SUPGIPCPUSTATE_ONLINE);
     5078
     5079    /*
     5080     * Update the APIC ID and CPU set index mappings.
     5081     */
     5082    ASMAtomicWriteU16(&pGip->aiCpuFromApicId[idApic],     i);
     5083    ASMAtomicWriteU16(&pGip->aiCpuFromCpuSetIdx[iCpuSet], i);
     5084#endif
     5085}
     5086
     5087
     5088/**
     5089 * The CPU should be accounted as offline, update the GIP accordingly.
     5090 *
     5091 * This is used by supdrvGipMpEvent.
     5092 *
     5093 * @param   pGip                The GIP.
     5094 * @param   idCpu               The CPU ID.
     5095 */
     5096static void supdrvGipMpEventOffline(PSUPGLOBALINFOPAGE pGip, RTCPUID idCpu)
     5097{
     5098#ifdef SUP_WITH_LOTS_OF_CPUS
     5099    int         iCpuSet;
     5100    unsigned    i;
     5101
     5102    iCpuSet = RTMpCpuIdToSetIndex(idCpu);
     5103    AssertReturnVoid(iCpuSet >= 0);
     5104
     5105    i = pGip->aiCpuFromCpuSetIdx[iCpuSet];
     5106    AssertReturnVoid(i < pGip->cCpus);
     5107    AssertReturnVoid(pGip->aCPUs[i].idCpu == idCpu);
     5108
     5109    Assert(RTCpuSetIsMemberByIndex(&pGip->PossibleCpuSet, iCpuSet));
     5110    ASMAtomicWriteSize(&pGip->aCPUs[i].enmState, SUPGIPCPUSTATE_OFFLINE);
     5111    RTCpuSetDelByIndex(&pGip->OnlineCpuSet, iCpuSet);
     5112#endif
     5113}
     5114
     5115
     5116/**
    49775117 * Multiprocessor event notification callback.
    49785118 *
    4979  * This is used to make sue that the GIP master gets passed on to
    4980  * another CPU.
     5119 * This is used to make sure that the GIP master gets passed on to
     5120 * another CPU.  It also updates the associated CPU data.
    49815121 *
    49825122 * @param   enmEvent    The event.
     
    49865126static DECLCALLBACK(void) supdrvGipMpEvent(RTMPEVENT enmEvent, RTCPUID idCpu, void *pvUser)
    49875127{
    4988     PSUPDRVDEVEXT   pDevExt = (PSUPDRVDEVEXT)pvUser;
     5128    PSUPDRVDEVEXT       pDevExt = (PSUPDRVDEVEXT)pvUser;
     5129    PSUPGLOBALINFOPAGE  pGip    = pDevExt->pGip;
     5130
     5131    /*
     5132     * Update the GIP CPU data.
     5133     */
     5134    if (pGip)
     5135    {
     5136        switch (enmEvent)
     5137        {
     5138            case RTMPEVENT_ONLINE:
     5139                supdrvGipMpEventOnline(pGip, idCpu);
     5140                break;
     5141            case RTMPEVENT_OFFLINE:
     5142                supdrvGipMpEventOffline(pGip, idCpu);
     5143                break;
     5144
     5145        }
     5146    }
     5147
     5148    /*
     5149     * Make sure there is a master GIP.
     5150     */
    49895151    if (enmEvent == RTMPEVENT_OFFLINE)
    49905152    {
     
    51845346 * @param   u64NanoTS   The current nanosecond timestamp.
    51855347 * @param   uUpdateHz   The update frequency.
    5186  */
    5187 static void supdrvGipInit(PSUPDRVDEVEXT pDevExt, PSUPGLOBALINFOPAGE pGip, RTHCPHYS HCPhys, uint64_t u64NanoTS, unsigned uUpdateHz)
    5188 {
    5189     unsigned i;
     5348 * @param   cCpus       The CPU count.
     5349 */
     5350static void supdrvGipInit(PSUPDRVDEVEXT pDevExt, PSUPGLOBALINFOPAGE pGip, RTHCPHYS HCPhys,
     5351                          uint64_t u64NanoTS, unsigned uUpdateHz, unsigned cCpus)
     5352{
     5353    size_t const    cbGip = RT_ALIGN_Z(RT_OFFSETOF(SUPGLOBALINFOPAGE, aCPUs[cCpus]), PAGE_SIZE);
     5354    unsigned        i;
    51905355#ifdef DEBUG_DARWIN_GIP
    5191     OSDBGPRINT(("supdrvGipInit: pGip=%p HCPhys=%lx u64NanoTS=%llu uUpdateHz=%d\n", pGip, (long)HCPhys, u64NanoTS, uUpdateHz));
     5356    OSDBGPRINT(("supdrvGipInit: pGip=%p HCPhys=%lx u64NanoTS=%llu uUpdateHz=%d cCpus=%u\n", pGip, (long)HCPhys, u64NanoTS, uUpdateHz, cCpus));
    51925357#else
    5193     LogFlow(("supdrvGipInit: pGip=%p HCPhys=%lx u64NanoTS=%llu uUpdateHz=%d\n", pGip, (long)HCPhys, u64NanoTS, uUpdateHz));
     5358    LogFlow(("supdrvGipInit: pGip=%p HCPhys=%lx u64NanoTS=%llu uUpdateHz=%d cCpus=%u\n", pGip, (long)HCPhys, u64NanoTS, uUpdateHz, cCpus));
    51945359#endif
    51955360
     
    51975362     * Initialize the structure.
    51985363     */
    5199     memset(pGip, 0, PAGE_SIZE);
    5200     pGip->u32Magic          = SUPGLOBALINFOPAGE_MAGIC;
    5201     pGip->u32Version        = SUPGLOBALINFOPAGE_VERSION;
    5202     pGip->u32Mode           = supdrvGipDeterminTscMode(pDevExt);
    5203     pGip->u32UpdateHz       = uUpdateHz;
    5204     pGip->u32UpdateIntervalNS = 1000000000 / uUpdateHz;
     5364    memset(pGip, 0, cbGip);
     5365    pGip->u32Magic              = SUPGLOBALINFOPAGE_MAGIC;
     5366    pGip->u32Version            = SUPGLOBALINFOPAGE_VERSION;
     5367    pGip->u32Mode               = supdrvGipDeterminTscMode(pDevExt);
     5368#ifdef SUP_WITH_LOTS_OF_CPUS
     5369    pGip->cCpus                 = (uint16_t)cCpus;
     5370    pGip->cPages                = (uint16_t)(cbGip / PAGE_SIZE);
     5371#endif
     5372    pGip->u32UpdateHz           = uUpdateHz;
     5373    pGip->u32UpdateIntervalNS   = 1000000000 / uUpdateHz;
    52055374    pGip->u64NanoTSLastUpdateHz = u64NanoTS;
    5206 
    5207     for (i = 0; i < RT_ELEMENTS(pGip->aCPUs); i++)
     5375#ifdef SUP_WITH_LOTS_OF_CPUS
     5376    RTCpuSetEmpty(&pGip->OnlineCpuSet);
     5377    pGip->cOnlineCpus           = RTMpGetOnlineCount();
     5378    pGip->cPresentCpus          = RTMpGetPresentCount();
     5379    RTCpuSetEmpty(&pGip->PresentCpuSet);
     5380    RTMpGetSet(&pGip->PossibleCpuSet);
     5381    pGip->cPossibleCpus         = RTMpGetCount();
     5382    pGip->idCpuMax              = RTMpGetMaxCpuId();
     5383    for (i = 0; i < RT_ELEMENTS(pGip->aiCpuFromApicId); i++)
     5384        pGip->aiCpuFromApicId[i]    = 0;
     5385    for (i = 0; i < RT_ELEMENTS(pGip->aiCpuFromCpuSetIdx); i++)
     5386        pGip->aiCpuFromCpuSetIdx[i] = UINT16_MAX;
     5387#endif
     5388
     5389    for (i = 0; i < cCpus; i++)
    52085390    {
    52095391        pGip->aCPUs[i].u32TransactionId  = 2;
    52105392        pGip->aCPUs[i].u64NanoTS         = u64NanoTS;
    52115393        pGip->aCPUs[i].u64TSC            = ASMReadTSC();
     5394
     5395#ifdef SUP_WITH_LOTS_OF_CPUS
     5396        pGip->aCPUs[i].enmState          = SUPGIPCPUSTATE_INVALID;
     5397        pGip->aCPUs[i].idCpu             = NIL_RTCPUID;
     5398        pGip->aCPUs[i].iCpuSet           = -1;
     5399        pGip->aCPUs[i].idApic            = UINT8_MAX;
     5400#endif
    52125401
    52135402        /*
     
    52325421     * Link it to the device extension.
    52335422     */
    5234     pDevExt->pGip = pGip;
     5423    pDevExt->pGip      = pGip;
    52355424    pDevExt->HCPhysGip = HCPhys;
    52365425    pDevExt->cGipUsers = 0;
     5426}
     5427
     5428
     5429/**
     5430 * On CPU initialization callback for RTMpOnAll.
     5431 *
     5432 * @param   idCpu               The CPU ID.
     5433 * @param   pvUser1             The device extension.
     5434 * @param   pvUser2             The GIP.
     5435 */
     5436static DECLCALLBACK(void) supdrvGipInitOnCpu(RTCPUID idCpu, void *pvUser1, void *pvUser2)
     5437{
     5438    /* This is good enough, even though it will update some of the globals a
     5439       bit to much. */
     5440    supdrvGipMpEventOnline((PSUPGLOBALINFOPAGE)pvUser2, idCpu);
    52375441}
    52385442
     
    52815485     * Update the NanoTS.
    52825486     */
    5283     ASMAtomicXchgU64(&pGipCpu->u64NanoTS, u64NanoTS);
     5487    ASMAtomicWriteU64(&pGipCpu->u64NanoTS, u64NanoTS);
    52845488
    52855489    /*
     
    52885492    /** @todo validate the NanoTS delta, don't trust the OS to call us when it should... */
    52895493    u64TSCDelta = u64TSC - pGipCpu->u64TSC;
    5290     ASMAtomicXchgU64(&pGipCpu->u64TSC, u64TSC);
     5494    ASMAtomicWriteU64(&pGipCpu->u64TSC, u64TSC);
    52915495
    52925496    if (u64TSCDelta >> 32)
     
    53185522    Assert(RT_ELEMENTS(pGipCpu->au32TSCHistory) == 8);
    53195523    iTSCHistoryHead = (pGipCpu->iTSCHistoryHead + 1) & 7;
    5320     ASMAtomicXchgU32(&pGipCpu->iTSCHistoryHead, iTSCHistoryHead);
    5321     ASMAtomicXchgU32(&pGipCpu->au32TSCHistory[iTSCHistoryHead], (uint32_t)u64TSCDelta);
     5524    ASMAtomicWriteU32(&pGipCpu->iTSCHistoryHead, iTSCHistoryHead);
     5525    ASMAtomicWriteU32(&pGipCpu->au32TSCHistory[iTSCHistoryHead], (uint32_t)u64TSCDelta);
    53225526
    53235527    /*
     
    53595563        u32UpdateIntervalTSCSlack = u32UpdateIntervalTSC >> 6;
    53605564    }
    5361     ASMAtomicXchgU32(&pGipCpu->u32UpdateIntervalTSC, u32UpdateIntervalTSC + u32UpdateIntervalTSCSlack);
     5565    ASMAtomicWriteU32(&pGipCpu->u32UpdateIntervalTSC, u32UpdateIntervalTSC + u32UpdateIntervalTSCSlack);
    53625566
    53635567    /*
     
    53655569     */
    53665570    u64CpuHz = ASMMult2xU32RetU64(u32UpdateIntervalTSC, pGip->u32UpdateHz);
    5367     ASMAtomicXchgU64(&pGipCpu->u64CpuHz, u64CpuHz);
     5571    ASMAtomicWriteU64(&pGipCpu->u64CpuHz, u64CpuHz);
    53685572}
    53695573
     
    53755579 * @param   u64NanoTS       The current nanosecond timesamp.
    53765580 * @param   u64TSC          The current TSC timesamp.
     5581 * @param   idCpu           The CPU ID.
    53775582 * @param   iTick           The current timer tick.
    53785583 */
    5379 static void supdrvGipUpdate(PSUPGLOBALINFOPAGE pGip, uint64_t u64NanoTS, uint64_t u64TSC, uint64_t iTick)
     5584static void supdrvGipUpdate(PSUPGLOBALINFOPAGE pGip, uint64_t u64NanoTS, uint64_t u64TSC, RTCPUID idCpu, uint64_t iTick)
    53805585{
    53815586    /*
     
    53875592    else
    53885593    {
     5594#ifdef SUP_WITH_LOTS_OF_CPUS
     5595        unsigned iCpu = pGip->aiCpuFromApicId[ASMGetApicId()];
     5596        if (RT_UNLIKELY(iCpu >= pGip->cCpus))
     5597            return;
     5598        pGipCpu = &pGip->aCPUs[iCpu];
     5599        if (RT_UNLIKELY(pGipCpu->idCpu != idCpu))
     5600            return;
     5601#else
    53895602        unsigned iCpu = ASMGetApicId();
    53905603        if (RT_UNLIKELY(iCpu >= RT_ELEMENTS(pGip->aCPUs)))
    53915604            return;
    53925605        pGipCpu = &pGip->aCPUs[iCpu];
     5606#endif
    53935607    }
    53945608
     
    54175631            if (u32UpdateHz <= 2000 && u32UpdateHz >= 30)
    54185632            {
    5419                 ASMAtomicXchgU32(&pGip->u32UpdateHz, u32UpdateHz);
    5420                 ASMAtomicXchgU32(&pGip->u32UpdateIntervalNS, 1000000000 / u32UpdateHz);
     5633                ASMAtomicWriteU32(&pGip->u32UpdateHz, u32UpdateHz);
     5634                ASMAtomicWriteU32(&pGip->u32UpdateIntervalNS, 1000000000 / u32UpdateHz);
    54215635            }
    54225636#endif
    54235637        }
    5424         ASMAtomicXchgU64(&pGip->u64NanoTSLastUpdateHz, u64NanoTS);
     5638        ASMAtomicWriteU64(&pGip->u64NanoTSLastUpdateHz, u64NanoTS);
    54255639    }
    54265640
     
    54435657 * @param   u64NanoTS       The current nanosecond timesamp.
    54445658 * @param   u64TSC          The current TSC timesamp.
    5445  * @param   iCpu            The CPU index.
     5659 * @param   idCpu           The CPU ID.
     5660 * @param   idApic          The APIC id for the CPU index.
    54465661 * @param   iTick           The current timer tick.
    54475662 */
    5448 static void supdrvGipUpdatePerCpu(PSUPGLOBALINFOPAGE pGip, uint64_t u64NanoTS, uint64_t u64TSC, unsigned iCpu, uint64_t iTick)
    5449 {
    5450     PSUPGIPCPU  pGipCpu;
     5663static void supdrvGipUpdatePerCpu(PSUPGLOBALINFOPAGE pGip, uint64_t u64NanoTS, uint64_t u64TSC,
     5664                                  RTCPUID idCpu, uint8_t idApic, uint64_t iTick)
     5665{
     5666#ifdef SUP_WITH_LOTS_OF_CPUS
     5667    unsigned iCpu = pGip->aiCpuFromApicId[idApic];
     5668
     5669    if (RT_LIKELY(iCpu < pGip->cCpus))
     5670#else
     5671    unsigned iCpu = idApic;
    54515672
    54525673    if (RT_LIKELY(iCpu < RT_ELEMENTS(pGip->aCPUs)))
    5453     {
    5454         pGipCpu = &pGip->aCPUs[iCpu];
    5455 
    5456         /*
    5457          * Start update transaction.
    5458          */
    5459         if (!(ASMAtomicIncU32(&pGipCpu->u32TransactionId) & 1))
    5460         {
    5461             AssertMsgFailed(("Invalid transaction id, %#x, not odd!\n", pGipCpu->u32TransactionId));
     5674#endif
     5675    {
     5676        PSUPGIPCPU pGipCpu = &pGip->aCPUs[iCpu];
     5677#ifdef SUP_WITH_LOTS_OF_CPUS
     5678        if (pGipCpu->idCpu == idCpu)
     5679#endif
     5680        {
     5681
     5682            /*
     5683             * Start update transaction.
     5684             */
     5685            if (!(ASMAtomicIncU32(&pGipCpu->u32TransactionId) & 1))
     5686            {
     5687                AssertMsgFailed(("Invalid transaction id, %#x, not odd!\n", pGipCpu->u32TransactionId));
     5688                ASMAtomicIncU32(&pGipCpu->u32TransactionId);
     5689                pGipCpu->cErrors++;
     5690                return;
     5691            }
     5692
     5693            /*
     5694             * Update the data.
     5695             */
     5696            supdrvGipDoUpdateCpu(pGip, pGipCpu, u64NanoTS, u64TSC, iTick);
     5697
     5698            /*
     5699             * Complete transaction.
     5700             */
    54625701            ASMAtomicIncU32(&pGipCpu->u32TransactionId);
    5463             pGipCpu->cErrors++;
    5464             return;
    5465         }
    5466 
    5467         /*
    5468          * Update the data.
    5469          */
    5470         supdrvGipDoUpdateCpu(pGip, pGipCpu, u64NanoTS, u64TSC, iTick);
    5471 
    5472         /*
    5473          * Complete transaction.
    5474          */
    5475         ASMAtomicIncU32(&pGipCpu->u32TransactionId);
    5476     }
    5477 }
     5702        }
     5703    }
     5704}
  • trunk/src/VBox/HostDrivers/Support/freebsd/Makefile

    r33379 r36254  
    133133        RTSemEventMultiWaitNoResume-2-ex-generic.c \
    134134        RTTimerCreate-generic.c \
    135         timer-generic.c \
    136         mppresent-generic.c
     135        mppresent-generic.c \
     136        timer-generic.c
    137137
    138138.PATH:  ${.CURDIR}/r0drv
  • trunk/src/VBox/HostDrivers/Support/freebsd/files_vboxdrv

    r36190 r36254  
    158158    ${PATH_ROOT}/src/VBox/Runtime/generic/RTTimerCreate-generic.cpp=>generic/RTTimerCreate-generic.c \
    159159    ${PATH_ROOT}/src/VBox/Runtime/generic/RTMpGetArraySize-generic.cpp=>generic/RTMpGetArraySize-generic.c \
     160    ${PATH_ROOT}/src/VBox/Runtime/generic/mppresent-generic.cpp=>generic/mppresent-generic.c \
    160161    ${PATH_ROOT}/src/VBox/Runtime/generic/timer-generic.cpp=>generic/timer-generic.c \
    161     ${PATH_ROOT}/src/VBox/Runtime/generic/mppresent-generic.cpp=>generic/mppresent-generic.c \
    162162    ${PATH_ROOT}/src/VBox/Runtime/r0drv/alloc-r0drv.cpp=>r0drv/alloc-r0drv.c \
    163163    ${PATH_ROOT}/src/VBox/Runtime/r0drv/alloc-r0drv.h=>r0drv/alloc-r0drv.h \
  • trunk/src/VBox/HostDrivers/Support/linux/Makefile

    r36233 r36254  
    138138        generic/RTSemEventMultiWaitNoResume-2-ex-generic.o \
    139139        generic/RTTimerCreate-generic.o \
     140        generic/mppresent-generic.o \
    140141        generic/uuid-generic.o \
    141142        VBox/log-vbox.o
  • trunk/src/VBox/HostDrivers/Support/linux/files_vboxdrv

    r36233 r36254  
    146146    ${PATH_ROOT}/src/VBox/Runtime/generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp=>generic/RTSemEventMultiWaitNoResume-2-ex-generic.c \
    147147    ${PATH_ROOT}/src/VBox/Runtime/generic/RTTimerCreate-generic.cpp=>generic/RTTimerCreate-generic.c \
     148    ${PATH_ROOT}/src/VBox/Runtime/generic/mppresent-generic.cpp=>generic/mppresent-generic.c \
    148149    ${PATH_ROOT}/src/VBox/Runtime/generic/uuid-generic.cpp=>generic/uuid-generic.c \
    149150    ${PATH_ROOT}/src/VBox/Runtime/r0drv/alloc-r0drv.cpp=>r0drv/alloc-r0drv.c \
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