VirtualBox

Changeset 32982 in vbox for trunk/src/VBox/Devices/PC


Ignore:
Timestamp:
Oct 7, 2010 3:12:02 PM (14 years ago)
Author:
vboxsync
Message:

DevAPIC: Addressed the cause of the div by zero problem in apicDoFrequencyHinting - it was the cause of the DSL hang on systems with an VMX preemption timer.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/PC/DevAPIC.cpp

    r32960 r32982  
    12531253        pThis->uHintedCountShift    = pThis->count_shift;
    12541254
    1255         uint64_t cTickPerPeriod = (uint64_t)pThis->initial_count << pThis->count_shift;
    1256         uint32_t uHz = cTickPerPeriod > 0
    1257                      ? TMTimerGetFreq(pThis->CTX_SUFF(pTimer)) / cTickPerPeriod
    1258                      : 100 /*whatever*/;
     1255        uint32_t uHz;
     1256        if (pThis->initial_count > 0)
     1257        {
     1258            Assert((unsigned)pThis->count_shift < 30);
     1259            uint64_t cTickPerPeriod = ((uint64_t)pThis->initial_count + 1) << pThis->count_shift;
     1260            uHz = TMTimerGetFreq(pThis->CTX_SUFF(pTimer)) / cTickPerPeriod;
     1261        }
     1262        else
     1263            uHz = 0;
    12591264        TMTimerSetFrequencyHint(pThis->CTX_SUFF(pTimer), uHz);
    12601265        Log(("apic: %u Hz\n", uHz));
     
    12781283     * a zero length one-shot timer.
    12791284     */
    1280     /** @todo check the correct behavior of setting a 0 initial_count for a one-shot
    1281      *        timer. This is just copying the behavior of the original code. */
    12821285    if (    !(pThis->lvt[APIC_LVT_TIMER] & APIC_LVT_MASKED)
    1283         &&  (   (pThis->lvt[APIC_LVT_TIMER] & APIC_LVT_TIMER_PERIODIC)
    1284              || u32NewInitialCount != 0))
     1286        &&  u32NewInitialCount > 0)
    12851287    {
    12861288        /*
     
    12961298        apicDoFrequencyHinting(pThis);
    12971299        STAM_COUNTER_INC(&pThis->StatTimerSetInitialCountArm);
     1300        Log(("apicTimerSetInitialCount: cTicksNext=%'llu (%#llx) ic=%#x sh=%#x nxt=%#llx\n", cTicksNext, cTicksNext, u32NewInitialCount, pThis->count_shift, pThis->next_time));
    12981301    }
    12991302    else
     
    13081311        }
    13091312        pThis->initial_count_load_time = TMTimerGet(pThis->CTX_SUFF(pTimer));
     1313        Log(("apicTimerSetInitialCount: ic=%#x sh=%#x iclt=%#llx\n", u32NewInitialCount, pThis->count_shift, pThis->initial_count_load_time));
    13101314    }
    13111315}
     
    13651369            STAM_COUNTER_INC(&pThis->StatTimerSetLvtArmed);
    13661370        /*
    1367          * If unmasked and not armed, we have to rearm the timer so it will
    1368          * fire at the end of the current period.
    1369          * This is code is currently RACING the virtual sync clock!
     1371         * If unmasked, not armed and with a valid initial count value (according
     1372         * to our interpretation of the spec), we will have to rearm the timer so
     1373         * it will fire at the end of the current period.
     1374         *
     1375         * N.B. This is code is currently RACING the virtual sync clock!
    13701376         */
    1371         else if (fOld & APIC_LVT_MASKED)
     1377        else if (   (fOld & APIC_LVT_MASKED)
     1378                 && pThis->initial_count > 0)
    13721379        {
    13731380            STAM_COUNTER_INC(&pThis->StatTimerSetLvtArm);
     
    13951402                    pThis->fTimerArmed = true;
    13961403                    apicDoFrequencyHinting(pThis);
     1404                    Log(("apicTimerSetLvt: ic=%#x sh=%#x nxt=%#llx\n", pThis->initial_count, pThis->count_shift, pThis->next_time));
    13971405                    break;
    13981406                }
     
    14241432        apic_set_irq(dev, pThis, pThis->lvt[APIC_LVT_TIMER] & 0xff, APIC_TRIGGER_EDGE);
    14251433
    1426         if (pThis->lvt[APIC_LVT_TIMER] & APIC_LVT_TIMER_PERIODIC) {
     1434        if (   (pThis->lvt[APIC_LVT_TIMER] & APIC_LVT_TIMER_PERIODIC)
     1435            && pThis->initial_count > 0) {
    14271436            /* new interval. */
    14281437            pThis->next_time += (((uint64_t)pThis->initial_count + 1) << pThis->count_shift);
     
    14301439            pThis->fTimerArmed = true;
    14311440            apicDoFrequencyHinting(pThis);
     1441            Log2(("apicTimerCallback: ic=%#x sh=%#x nxt=%#llx\n", pThis->initial_count, pThis->count_shift, pThis->next_time));
    14321442        } else {
    1433             /* single shot. */
     1443            /* single shot or disabled. */
    14341444            pThis->fTimerArmed = false;
    14351445            pThis->uHintedCountShift = pThis->uHintedInitialCount = 0;
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