VirtualBox

Changeset 54799 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Mar 16, 2015 9:23:03 PM (10 years ago)
Author:
vboxsync
Message:

CPUM: Fixed two problems with the CPUID code. cLeaves wasn't updated in cpumR3CpuIdInstallAndExplodeLeaves leading to garbage entries at the end of the array. And when the CPUID insertion code had a bug when inserting subleafs that triggered when doing the cache leaf (4) fake up during old saved state loading.

Location:
trunk/src/VBox/VMM
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/Makefile.kmk

    r54763 r54799  
    109109ifdef VBOX_WITH_VMM_R0_SWITCH_STACK
    110110 VBoxVMM_DEFS   += VMM_R0_SWITCH_STACK
     111endif
     112if "$(KBUILD_TYPE)" == "debug" && "$(USERNAME)" == "bird"
     113 VBoxVMM_DEFS   += RTMEM_WRAP_TO_EF_APIS
    111114endif
    112115VBoxVMM_DEFS.darwin = VMM_R0_SWITCH_STACK
  • trunk/src/VBox/VMM/VMMR3/CPUMR3CpuId.cpp

    r54797 r54799  
    679679
    680680/**
     681 * Checks that we've updated the CPUID leaves array correctly.
     682 *
     683 * This is a no-op in non-strict builds.
     684 *
     685 * @param   paLeaves            The leaves array.
     686 * @param   cLeaves             The number of leaves.
     687 */
     688static void cpumR3CpuIdAssertOrder(PCPUMCPUIDLEAF paLeaves, uint32_t cLeaves)
     689{
     690#ifdef VBOX_STRICT
     691    for (uint32_t i = 1; i < cLeaves; i++)
     692        if (paLeaves[i].uLeaf != paLeaves[i - 1].uLeaf)
     693            AssertMsg(paLeaves[i].uLeaf > paLeaves[i - 1].uLeaf, ("%#x vs %#x\n", paLeaves[i].uLeaf, paLeaves[i - 1].uLeaf));
     694        else
     695        {
     696            AssertMsg(paLeaves[i].uSubLeaf > paLeaves[i - 1].uSubLeaf,
     697                      ("%#x: %#x vs %#x\n", paLeaves[i].uLeaf, paLeaves[i].uSubLeaf, paLeaves[i - 1].uSubLeaf));
     698            AssertMsg(paLeaves[i].fSubLeafMask == paLeaves[i - 1].fSubLeafMask,
     699                      ("%#x/%#x: %#x vs %#x\n", paLeaves[i].uLeaf, paLeaves[i].uSubLeaf, paLeaves[i].fSubLeafMask, paLeaves[i - 1].fSubLeafMask));
     700            AssertMsg(paLeaves[i].fFlags == paLeaves[i - 1].fFlags,
     701                      ("%#x/%#x: %#x vs %#x\n", paLeaves[i].uLeaf, paLeaves[i].uSubLeaf, paLeaves[i].fFlags, paLeaves[i - 1].fFlags));
     702        }
     703#else
     704    NOREF(paLeaves);
     705    NOREF(cLeaves);
     706#endif
     707}
     708
     709
     710/**
    681711 * Inserts a CPU ID leaf, replacing any existing ones.
    682712 *
     
    782812
    783813            paLeaves[i] = *pNewLeaf;
     814            cpumR3CpuIdAssertOrder(*ppaLeaves, *pcLeaves);
    784815            return VINF_SUCCESS;
    785816        }
     
    787818        /* Find sub-leaf insertion point. */
    788819        while (   i < cLeaves
    789                && paLeaves[i].uSubLeaf < pNewLeaf->uSubLeaf)
     820               && paLeaves[i].uSubLeaf < pNewLeaf->uSubLeaf
     821               && paLeaves[i].uLeaf == pNewLeaf->uLeaf)
    790822            i++;
    791823
     
    793825         * If we've got an exactly matching leaf, replace it.
    794826         */
    795         if (   paLeaves[i].uLeaf    == pNewLeaf->uLeaf
     827        if (   i < cLeaves
     828            && paLeaves[i].uLeaf    == pNewLeaf->uLeaf
    796829            && paLeaves[i].uSubLeaf == pNewLeaf->uSubLeaf)
    797830        {
    798831            paLeaves[i] = *pNewLeaf;
     832            cpumR3CpuIdAssertOrder(*ppaLeaves, *pcLeaves);
    799833            return VINF_SUCCESS;
    800834        }
     
    813847    *pcLeaves += 1;
    814848    paLeaves[i] = *pNewLeaf;
     849
     850    cpumR3CpuIdAssertOrder(*ppaLeaves, *pcLeaves);
    815851    return VINF_SUCCESS;
    816852}
     
    858894        *pcLeaves = cLeaves -= (iEnd - iFirst);
    859895    }
     896
     897    cpumR3CpuIdAssertOrder(paLeaves, *pcLeaves);
    860898}
    861899
     
    11911229    }
    11921230
     1231    cpumR3CpuIdAssertOrder(*ppaLeaves, *pcLeaves);
    11931232    return VINF_SUCCESS;
    11941233}
     
    18591898static int cpumR3CpuIdInstallAndExplodeLeaves(PVM pVM, PCPUM pCpum, PCPUMCPUIDLEAF paLeaves, uint32_t cLeaves)
    18601899{
     1900    cpumR3CpuIdAssertOrder(paLeaves, cLeaves);
     1901
    18611902    /*
    18621903     * Install the CPUID information.
     
    18661907
    18671908    AssertLogRelRCReturn(rc, rc);
    1868 
    1869 
     1909    pCpum->GuestInfo.cCpuIdLeaves = cLeaves;
    18701910    pCpum->GuestInfo.paCpuIdLeavesR0 = MMHyperR3ToR0(pVM, pCpum->GuestInfo.paCpuIdLeavesR3);
    18711911    pCpum->GuestInfo.paCpuIdLeavesRC = MMHyperR3ToRC(pVM, pCpum->GuestInfo.paCpuIdLeavesR3);
     
    34713511                    /*
    34723512                     * Load the leaves one by one.
     3513                     *
     3514                     * The uPrev stuff is a kludge for working around a week worth of bad saved
     3515                     * states during the CPUID revamp in March 2015.  We saved too many leaves
     3516                     * due to a bug in cpumR3CpuIdInstallAndExplodeLeaves, thus ending up with
     3517                     * garbage entires at the end of the array when restoring.  We also had
     3518                     * a subleaf insertion bug that triggered with the leaf 4 stuff below,
     3519                     * this kludge doesn't deal correctly with that, but who cares...
    34733520                     */
     3521                    uint32_t uPrev = 0;
    34743522                    for (uint32_t i = 0; i < cLeaves && RT_SUCCESS(rc); i++)
    34753523                    {
     
    34773525                        rc = SSMR3GetMem(pSSM, &Leaf, sizeof(Leaf));
    34783526                        if (RT_SUCCESS(rc))
    3479                             rc = cpumR3CpuIdInsert(NULL /* pVM */, ppaLeaves, pcLeaves, &Leaf);
     3527                        {
     3528                            if (   uVersion != CPUM_SAVED_STATE_VERSION_BAD_CPUID_COUNT
     3529                                || Leaf.uLeaf >= uPrev)
     3530                            {
     3531                                rc = cpumR3CpuIdInsert(NULL /* pVM */, ppaLeaves, pcLeaves, &Leaf);
     3532                                uPrev = Leaf.uLeaf;
     3533                            }
     3534                            else
     3535                                uPrev = UINT32_MAX;
     3536                        }
    34803537                    }
    34813538                }
  • trunk/src/VBox/VMM/include/CPUMInternal.h

    r54737 r54799  
    123123 * @{ */
    124124/** The current saved state version. */
    125 #define CPUM_SAVED_STATE_VERSION                15
     125#define CPUM_SAVED_STATE_VERSION                16
     126/** CPUID changes with explode forgetting to update the leaf count on
     127 * restore, resulting in garbage being saved restoring+saving old states). */
     128#define CPUM_SAVED_STATE_VERSION_BAD_CPUID_COUNT 15
    126129/** The saved state version before the CPUIDs changes. */
    127130#define CPUM_SAVED_STATE_VERSION_PUT_STRUCT     14
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