VirtualBox

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


Ignore:
Timestamp:
Feb 23, 2012 11:15:37 AM (13 years ago)
Author:
vboxsync
Message:

VMM/VMMR0 SupDrv Solaris/MpNotification: Fix guru meditation/panics when host CPUs are dynamically offline'd/online'd. More flexibility if offline notifications don't fire on the desired CPU.

File:
1 edited

Legend:

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

    r38891 r40227  
    138138static void                 supdrvGipUpdatePerCpu(PSUPGLOBALINFOPAGE pGip, uint64_t u64NanoTS, uint64_t u64TSC,
    139139                                                  RTCPUID idCpu, uint8_t idApic, uint64_t iTick);
     140static void                 supdrvGipInitCpu(PSUPGLOBALINFOPAGE pGip, PSUPGIPCPU pCpu, uint64_t u64NanoTS);
    140141
    141142
     
    50395040    uint16_t    idApic = UINT16_MAX;
    50405041    uint32_t    i = 0;
     5042    uint64_t    u64NanoTS = 0;
    50415043
    50425044    AssertRelease(idCpu == RTMpCpuId());
     
    50595061     * Update the entry.
    50605062     */
     5063    u64NanoTS = RTTimeSystemNanoTS() - pGip->u32UpdateIntervalNS;
    50615064    i = supdrvGipCpuIndexFromCpuId(pGip, idCpu);
     5065    supdrvGipInitCpu(pGip, &pGip->aCPUs[i], u64NanoTS);
    50625066    idApic = ASMGetApicId();
    50635067    ASMAtomicUoWriteU16(&pGip->aCPUs[i].idApic,  idApic);
     
    51135117 * @param   idCpu       The cpu it applies to.
    51145118 * @param   pvUser      Pointer to the device extension.
     5119 *
     5120 * @remarks This function -must- fire on the newly online'd CPU for the
     5121 *          RTMPEVENT_ONLINE case and can fire on any CPU for the
     5122 *          RTMPEVENT_OFFLINE case.
    51155123 */
    51165124static DECLCALLBACK(void) supdrvGipMpEvent(RTMPEVENT enmEvent, RTCPUID idCpu, void *pvUser)
     
    51195127    PSUPGLOBALINFOPAGE  pGip    = pDevExt->pGip;
    51205128
    5121     AssertRelease(idCpu == RTMpCpuId());
    51225129    AssertRelease(!RTThreadPreemptIsEnabled(NIL_RTTHREAD));
    51235130
     
    51305137        {
    51315138            case RTMPEVENT_ONLINE:
     5139                AssertRelease(idCpu == RTMpCpuId());
    51325140                supdrvGipMpEventOnline(pGip, idCpu);
    51335141                break;
     
    53285336}
    53295337
     5338
     5339/**
     5340 * Initializes per-CPU GIP information.
     5341 *
     5342 * @param   pGip        Pointer to the read-write kernel mapping of the GIP.
     5343 * @param   pCpu        Pointer to which GIP CPU to initalize.
     5344 * @param   u64NanoTS   The current nanosecond timestamp.
     5345 */
     5346static void supdrvGipInitCpu(PSUPGLOBALINFOPAGE pGip, PSUPGIPCPU pCpu, uint64_t u64NanoTS)
     5347{
     5348    pCpu->u32TransactionId   = 2;
     5349    pCpu->u64NanoTS          = u64NanoTS;
     5350    pCpu->u64TSC             = ASMReadTSC();
     5351
     5352    pCpu->enmState           = SUPGIPCPUSTATE_INVALID;
     5353    pCpu->idCpu              = NIL_RTCPUID;
     5354    pCpu->iCpuSet            = -1;
     5355    pCpu->idApic             = UINT16_MAX;
     5356
     5357    /*
     5358     * We don't know the following values until we've executed updates.
     5359     * So, we'll just pretend it's a 4 GHz CPU and adjust the history it on
     5360     * the 2nd timer callout.
     5361     */
     5362    pCpu->u64CpuHz          = _4G + 1; /* tstGIP-2 depends on this. */
     5363    pCpu->u32UpdateIntervalTSC
     5364        = pCpu->au32TSCHistory[0]
     5365        = pCpu->au32TSCHistory[1]
     5366        = pCpu->au32TSCHistory[2]
     5367        = pCpu->au32TSCHistory[3]
     5368        = pCpu->au32TSCHistory[4]
     5369        = pCpu->au32TSCHistory[5]
     5370        = pCpu->au32TSCHistory[6]
     5371        = pCpu->au32TSCHistory[7]
     5372        = (uint32_t)(_4G / pGip->u32UpdateHz);
     5373}
    53305374
    53315375
     
    53765420
    53775421    for (i = 0; i < cCpus; i++)
    5378     {
    5379         pGip->aCPUs[i].u32TransactionId  = 2;
    5380         pGip->aCPUs[i].u64NanoTS         = u64NanoTS;
    5381         pGip->aCPUs[i].u64TSC            = ASMReadTSC();
    5382 
    5383         pGip->aCPUs[i].enmState          = SUPGIPCPUSTATE_INVALID;
    5384         pGip->aCPUs[i].idCpu             = NIL_RTCPUID;
    5385         pGip->aCPUs[i].iCpuSet           = -1;
    5386         pGip->aCPUs[i].idApic            = UINT16_MAX;
    5387 
    5388         /*
    5389          * We don't know the following values until we've executed updates.
    5390          * So, we'll just pretend it's a 4 GHz CPU and adjust the history it on
    5391          * the 2nd timer callout.
    5392          */
    5393         pGip->aCPUs[i].u64CpuHz          = _4G + 1; /* tstGIP-2 depends on this. */
    5394         pGip->aCPUs[i].u32UpdateIntervalTSC
    5395             = pGip->aCPUs[i].au32TSCHistory[0]
    5396             = pGip->aCPUs[i].au32TSCHistory[1]
    5397             = pGip->aCPUs[i].au32TSCHistory[2]
    5398             = pGip->aCPUs[i].au32TSCHistory[3]
    5399             = pGip->aCPUs[i].au32TSCHistory[4]
    5400             = pGip->aCPUs[i].au32TSCHistory[5]
    5401             = pGip->aCPUs[i].au32TSCHistory[6]
    5402             = pGip->aCPUs[i].au32TSCHistory[7]
    5403             = /*pGip->aCPUs[i].u64CpuHz*/ (uint32_t)(_4G / uUpdateHz);
    5404     }
     5422        supdrvGipInitCpu(pGip, &pGip->aCPUs[i], u64NanoTS);
    54055423
    54065424    /*
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