VirtualBox

Changeset 24406 in vbox


Ignore:
Timestamp:
Nov 5, 2009 5:20:01 PM (15 years ago)
Author:
vboxsync
Message:

Main/CPUM: Use /CPUM/HostCPUID instead of /CPUM/CPUID since the latter is already used for the uncensored overrides. Share more code in CPUM.

Location:
trunk/src/VBox
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/ConsoleImpl2.cpp

    r24329 r24406  
    246246
    247247    /* Standard cpuid leaf overrides. */
    248     for (unsigned leaf = 0; leaf < 0xA; leaf++)
     248    for (uint32_t leaf = 0; leaf < 0xA; leaf++)
    249249    {
    250250        ULONG ulEax, ulEbx, ulEcx, ulEdx;
    251         if (pMachine->GetCpuIdLeaf(leaf, &ulEax, &ulEbx, &ulEcx, &ulEdx) == S_OK)
     251        hrc = pMachine->GetCpuIdLeaf(leaf, &ulEax, &ulEbx, &ulEcx, &ulEdx);
     252        if (SUCCEEDED(rc))
    252253        {
    253254            PCFGMNODE pLeaf;
    254             rc = CFGMR3InsertNodeF(pRoot, &pLeaf, "CPUM/CPUID/%x", leaf);               RC_CHECK();
    255 
    256             rc = CFGMR3InsertInteger(pLeaf, "eax", ulEax);                      RC_CHECK();
    257             rc = CFGMR3InsertInteger(pLeaf, "ebx", ulEbx);                      RC_CHECK();
    258             rc = CFGMR3InsertInteger(pLeaf, "ecx", ulEcx);                      RC_CHECK();
    259             rc = CFGMR3InsertInteger(pLeaf, "edx", ulEdx);                      RC_CHECK();
    260         }
     255            rc = CFGMR3InsertNodeF(pRoot, &pLeaf, "CPUM/HostCPUID/%RX32", leaf);    RC_CHECK();
     256
     257            rc = CFGMR3InsertInteger(pLeaf, "eax", ulEax);                          RC_CHECK();
     258            rc = CFGMR3InsertInteger(pLeaf, "ebx", ulEbx);                          RC_CHECK();
     259            rc = CFGMR3InsertInteger(pLeaf, "ecx", ulEcx);                          RC_CHECK();
     260            rc = CFGMR3InsertInteger(pLeaf, "edx", ulEdx);                          RC_CHECK();
     261        }
     262        else if (hrc != E_INVALIDARG)                                               H();
    261263    }
    262264
    263265    /* Extended cpuid leaf overrides. */
    264     for (unsigned leaf = 0x80000000; leaf < 0x8000000A; leaf++)
     266    for (uint32_t leaf = 0x80000000; leaf < 0x8000000A; leaf++)
    265267    {
    266268        ULONG ulEax, ulEbx, ulEcx, ulEdx;
    267         if (pMachine->GetCpuIdLeaf(leaf, &ulEax, &ulEbx, &ulEcx, &ulEdx) == S_OK)
     269        hrc = pMachine->GetCpuIdLeaf(leaf, &ulEax, &ulEbx, &ulEcx, &ulEdx);
     270        if (SUCCEEDED(rc))
    268271        {
    269272            PCFGMNODE pLeaf;
    270             rc = CFGMR3InsertNodeF(pRoot, &pLeaf, "CPUM/CPUID/%x", leaf);               RC_CHECK();
    271 
    272             rc = CFGMR3InsertInteger(pLeaf, "eax", ulEax);                      RC_CHECK();
    273             rc = CFGMR3InsertInteger(pLeaf, "ebx", ulEbx);                      RC_CHECK();
    274             rc = CFGMR3InsertInteger(pLeaf, "ecx", ulEcx);                      RC_CHECK();
    275             rc = CFGMR3InsertInteger(pLeaf, "edx", ulEdx);                      RC_CHECK();
    276         }
     273            rc = CFGMR3InsertNodeF(pRoot, &pLeaf, "CPUM/HostCPUID/%RX32", leaf);    RC_CHECK();
     274
     275            rc = CFGMR3InsertInteger(pLeaf, "eax", ulEax);                          RC_CHECK();
     276            rc = CFGMR3InsertInteger(pLeaf, "ebx", ulEbx);                          RC_CHECK();
     277            rc = CFGMR3InsertInteger(pLeaf, "ecx", ulEcx);                          RC_CHECK();
     278            rc = CFGMR3InsertInteger(pLeaf, "edx", ulEdx);                          RC_CHECK();
     279        }
     280        else if (hrc != E_INVALIDARG)                                               H();
    277281    }
    278282
     
    291295    /* hardware virtualization extensions */
    292296    BOOL fHWVirtExEnabled;
    293     hrc = pMachine->GetHWVirtExProperty(HWVirtExPropertyType_Enabled, &fHWVirtExEnabled);                  H();
     297    hrc = pMachine->GetHWVirtExProperty(HWVirtExPropertyType_Enabled, &fHWVirtExEnabled); H();
    294298    if (cCpus > 1) /** @todo SMP: This isn't nice, but things won't work on mac otherwise. */
    295299        fHWVirtExEnabled = TRUE;
  • trunk/src/VBox/VMM/CPUM.cpp

    r24328 r24406  
    104104*   Internal Functions                                                         *
    105105*******************************************************************************/
     106static CPUMCPUVENDOR cpumR3DetectVendor(uint32_t uEAX, uint32_t uEBX, uint32_t uECX, uint32_t uEDX);
    106107static int cpumR3CpuIdInit(PVM pVM);
    107108#ifdef VBOX_WITH_LIVE_MIGRATION
     
    199200    if (!pVM->cpum.s.CPUFeatures.edx.u1SEP)
    200201        Log(("The CPU doesn't support SYSENTER/SYSEXIT!\n"));
     202
     203    /*
     204     * Detech the host CPU vendor.
     205     * (The guest CPU vendor is re-detected later on.)
     206     */
     207    uint32_t uEAX, uEBX, uECX, uEDX;
     208    ASMCpuId(0, &uEAX, &uEBX, &uECX, &uEDX);
     209    pVM->cpum.s.enmHostCpuVendor = cpumR3DetectVendor(uEAX, uEBX, uECX, uEDX);
     210    pVM->cpum.s.enmGuestCpuVendor = pVM->cpum.s.enmHostCpuVendor;
    201211
    202212    /*
     
    221231        return rc;
    222232
    223     /* Query the CPU manufacturer. */
    224     uint32_t uEAX, uEBX, uECX, uEDX;
    225     ASMCpuId(0, &uEAX, &uEBX, &uECX, &uEDX);
    226     if (    uEAX >= 1
    227         &&  uEBX == X86_CPUID_VENDOR_AMD_EBX
    228         &&  uECX == X86_CPUID_VENDOR_AMD_ECX
    229         &&  uEDX == X86_CPUID_VENDOR_AMD_EDX)
    230     {
    231         pVM->cpum.s.enmGuestCpuVendor = pVM->cpum.s.enmHostCpuVendor = CPUMCPUVENDOR_AMD;
    232     }
    233     else if (    uEAX >= 1
    234              &&  uEBX == X86_CPUID_VENDOR_INTEL_EBX
    235              &&  uECX == X86_CPUID_VENDOR_INTEL_ECX
    236              &&  uEDX == X86_CPUID_VENDOR_INTEL_EDX)
    237     {
    238         pVM->cpum.s.enmGuestCpuVendor = pVM->cpum.s.enmHostCpuVendor = CPUMCPUVENDOR_INTEL;
    239     }
    240     else /** @todo Via */
    241     {
    242         pVM->cpum.s.enmGuestCpuVendor = pVM->cpum.s.enmHostCpuVendor = CPUMCPUVENDOR_UNKNOWN;
    243     }
    244 
    245233    /*
    246234     * Register info handlers.
     
    254242
    255243    /*
    256      * Initialize the Guest CPU state.
     244     * Initialize the Guest CPUID state.
    257245     */
    258246    rc = cpumR3CpuIdInit(pVM);
     
    278266
    279267/**
     268 * Detect the CPU vendor give n the
     269 *
     270 * @returns The vendor.
     271 * @param   uEAX                EAX from CPUID(0).
     272 * @param   uEBX                EBX from CPUID(0).
     273 * @param   uECX                ECX from CPUID(0).
     274 * @param   uEDX                EDX from CPUID(0).
     275 */
     276static CPUMCPUVENDOR cpumR3DetectVendor(uint32_t uEAX, uint32_t uEBX, uint32_t uECX, uint32_t uEDX)
     277{
     278    if (    uEAX >= 1
     279        &&  uEBX == X86_CPUID_VENDOR_AMD_EBX
     280        &&  uECX == X86_CPUID_VENDOR_AMD_ECX
     281        &&  uEDX == X86_CPUID_VENDOR_AMD_EDX)
     282        return CPUMCPUVENDOR_AMD;
     283
     284    if (    uEAX >= 1
     285        &&  uEBX == X86_CPUID_VENDOR_INTEL_EBX
     286        &&  uECX == X86_CPUID_VENDOR_INTEL_ECX
     287        &&  uEDX == X86_CPUID_VENDOR_INTEL_EDX)
     288        return CPUMCPUVENDOR_INTEL;
     289
     290    /** @todo detect the other buggers... */
     291    return CPUMCPUVENDOR_UNKNOWN;
     292}
     293
     294
     295/**
     296 * Fetches overrides for a CPUID leaf.
     297 *
     298 * @returns VBox status code.
     299 * @param   pLeaf               The leaf to load the overrides into.
     300 * @param   pCfgNode            The CFGM node containing the overrides
     301 *                              (/CPUM/HostCPUID/ or /CPUM/CPUID/).
     302 * @param   iLeaf               The CPUID leaf number.
     303 */
     304static int cpumR3CpuIdFetchLeafOverride(PCPUMCPUID pLeaf, PCFGMNODE pCfgNode, uint32_t iLeaf)
     305{
     306    PCFGMNODE pLeafNode = CFGMR3GetChildF(pCfgNode, "%RX32", iLeaf);
     307    if (pLeafNode)
     308    {
     309        uint32_t u32;
     310        int rc = CFGMR3QueryU32(pLeafNode, "eax", &u32);
     311        if (RT_SUCCESS(rc))
     312            pLeaf->eax = u32;
     313        else
     314            AssertReturn(rc == VERR_CFGM_VALUE_NOT_FOUND, rc);
     315
     316        rc = CFGMR3QueryU32(pLeafNode, "ebx", &u32);
     317        if (RT_SUCCESS(rc))
     318            pLeaf->ebx = u32;
     319        else
     320            AssertReturn(rc == VERR_CFGM_VALUE_NOT_FOUND, rc);
     321
     322        rc = CFGMR3QueryU32(pLeafNode, "ecx", &u32);
     323        if (RT_SUCCESS(rc))
     324            pLeaf->ecx = u32;
     325        else
     326            AssertReturn(rc == VERR_CFGM_VALUE_NOT_FOUND, rc);
     327
     328        rc = CFGMR3QueryU32(pLeafNode, "edx", &u32);
     329        if (RT_SUCCESS(rc))
     330            pLeaf->edx = u32;
     331        else
     332            AssertReturn(rc == VERR_CFGM_VALUE_NOT_FOUND, rc);
     333
     334    }
     335    return VINF_SUCCESS;
     336}
     337
     338
     339/**
     340 * Load the overrides for a set of CPUID leafs.
     341 *
     342 * @returns VBox status code.
     343 * @param   paLeafs             The leaf array.
     344 * @param   cLeafs              The number of leafs.
     345 * @param   uStart              The start leaf number.
     346 * @param   pCfgNode            The CFGM node containing the overrides
     347 *                              (/CPUM/HostCPUID/ or /CPUM/CPUID/).
     348 */
     349static int cpumR3CpuIdInitLoadOverrideSet(uint32_t uStart, PCPUMCPUID paLeafs, uint32_t cLeafs, PCFGMNODE pCfgNode)
     350{
     351    for (uint32_t i = 0; i < cLeafs; i++)
     352    {
     353        int rc = cpumR3CpuIdFetchLeafOverride(&paLeafs[i], pCfgNode, uStart + i);
     354        if (RT_FAILURE(rc))
     355            return rc;
     356    }
     357
     358    return VINF_SUCCESS;
     359}
     360
     361/**
     362 * Init a set of host CPUID leafs.
     363 *
     364 * @returns VBox status code.
     365 * @param   paLeafs             The leaf array.
     366 * @param   cLeafs              The number of leafs.
     367 * @param   uStart              The start leaf number.
     368 * @param   pCfgNode            The /CPUM/HostCPUID/ node.
     369 */
     370static int cpumR3CpuIdInitHostSet(uint32_t uStart, PCPUMCPUID paLeafs, uint32_t cLeafs, PCFGMNODE pCfgNode)
     371{
     372    /* Using the ECX variant for all of them can't hurt... */
     373    for (uint32_t i = 0; i < cLeafs; i++)
     374        ASMCpuId_Idx_ECX(uStart + i, 0, &paLeafs[i].eax, &paLeafs[i].ebx, &paLeafs[i].ecx, &paLeafs[i].edx);
     375
     376    /* Load CPUID leaf override; we currently don't care if the caller
     377       specifies features the host CPU doesn't support. */
     378    return cpumR3CpuIdInitLoadOverrideSet(uStart, paLeafs, cLeafs, pCfgNode);
     379}
     380
     381
     382/**
    280383 * Initializes the emulated CPU's cpuid information.
    281384 *
     
    285388static int cpumR3CpuIdInit(PVM pVM)
    286389{
    287     PCPUM    pCPUM = &pVM->cpum.s;
    288     uint32_t i;
    289 
    290     /*
    291      * Get the host CPUIDs.
    292      */
    293     for (i = 0; i < RT_ELEMENTS(pVM->cpum.s.aGuestCpuIdStd); i++)
    294     {
    295         ASMCpuId_Idx_ECX(i, 0,
    296                          &pCPUM->aGuestCpuIdStd[i].eax, &pCPUM->aGuestCpuIdStd[i].ebx,
    297                          &pCPUM->aGuestCpuIdStd[i].ecx, &pCPUM->aGuestCpuIdStd[i].edx);
    298 
    299         /* Load standard CPUID leaf override; we currently don't care if the caller specifies features the host CPU doesn't support. */
    300         PCFGMNODE pLeaf = CFGMR3GetChildF(CFGMR3GetRoot(pVM), "CPUM/CPUID/%x", i);
    301         if (pLeaf)
    302         {
    303             CFGMR3QueryU32(pLeaf, "eax", &pCPUM->aGuestCpuIdStd[i].eax);
    304             CFGMR3QueryU32(pLeaf, "ebx", &pCPUM->aGuestCpuIdStd[i].ebx);
    305             CFGMR3QueryU32(pLeaf, "ecx", &pCPUM->aGuestCpuIdStd[i].ecx);
    306             CFGMR3QueryU32(pLeaf, "edx", &pCPUM->aGuestCpuIdStd[i].edx);
    307         }
    308     }
    309     for (i = 0; i < RT_ELEMENTS(pCPUM->aGuestCpuIdExt); i++)
    310     {
    311         ASMCpuId(0x80000000 + i,
    312                  &pCPUM->aGuestCpuIdExt[i].eax, &pCPUM->aGuestCpuIdExt[i].ebx,
    313                  &pCPUM->aGuestCpuIdExt[i].ecx, &pCPUM->aGuestCpuIdExt[i].edx);
    314 
    315         /* Load extended CPUID leaf override; we currently don't care if the caller specifies features the host CPU doesn't support. */
    316         PCFGMNODE pLeaf = CFGMR3GetChildF(CFGMR3GetRoot(pVM), "CPUM/CPUID/%x", i);
    317         if (pLeaf)
    318         {
    319             CFGMR3QueryU32(pLeaf, "eax", &pCPUM->aGuestCpuIdExt[i].eax);
    320             CFGMR3QueryU32(pLeaf, "ebx", &pCPUM->aGuestCpuIdExt[i].ebx);
    321             CFGMR3QueryU32(pLeaf, "ecx", &pCPUM->aGuestCpuIdExt[i].ecx);
    322             CFGMR3QueryU32(pLeaf, "edx", &pCPUM->aGuestCpuIdExt[i].edx);
    323         }
    324     }
    325     for (i = 0; i < RT_ELEMENTS(pCPUM->aGuestCpuIdCentaur); i++)
    326     {
    327         ASMCpuId(0xc0000000 + i,
    328                  &pCPUM->aGuestCpuIdCentaur[i].eax, &pCPUM->aGuestCpuIdCentaur[i].ebx,
    329                  &pCPUM->aGuestCpuIdCentaur[i].ecx, &pCPUM->aGuestCpuIdCentaur[i].edx);
    330 
    331         /* Load Centaur CPUID leaf override; we currently don't care if the caller specifies features the host CPU doesn't support. */
    332         PCFGMNODE pLeaf = CFGMR3GetChildF(CFGMR3GetRoot(pVM), "CPUM/CPUID/%x", i);
    333         if (pLeaf)
    334         {
    335             CFGMR3QueryU32(pLeaf, "eax", &pCPUM->aGuestCpuIdCentaur[i].eax);
    336             CFGMR3QueryU32(pLeaf, "ebx", &pCPUM->aGuestCpuIdCentaur[i].ebx);
    337             CFGMR3QueryU32(pLeaf, "ecx", &pCPUM->aGuestCpuIdCentaur[i].ecx);
    338             CFGMR3QueryU32(pLeaf, "edx", &pCPUM->aGuestCpuIdCentaur[i].edx);
    339         }
    340     }
     390    PCPUM       pCPUM    = &pVM->cpum.s;
     391    PCFGMNODE   pCpumCfg = CFGMR3GetChild(CFGMR3GetRoot(pVM), "CPUM");
     392    uint32_t    i;
     393    int         rc;
     394
     395    /*
     396     * Get the host CPUIDs and redetect the guest CPU vendor (could've been overridden).
     397     */
     398    /** @cfgm{CPUM/HostCPUID/[000000xx|800000xx|c000000x]/[eax|ebx|ecx|edx],32-bit}
     399     * Overrides the host CPUID leaf values used for calculating the guest CPUID
     400     * leafs.  This can be used to preserve the CPUID values when moving a VM to
     401     * a different machine.  Another use is restricting (or extending) the
     402     * feature set exposed to the guest. */
     403    PCFGMNODE pHostOverrideCfg = CFGMR3GetChild(pCpumCfg, "HostCPUID");
     404    rc = cpumR3CpuIdInitHostSet(UINT32_C(0x00000000), &pCPUM->aGuestCpuIdStd[0],     RT_ELEMENTS(pCPUM->aGuestCpuIdStd),     pHostOverrideCfg);
     405    AssertRCReturn(rc, rc);
     406    rc = cpumR3CpuIdInitHostSet(UINT32_C(0x80000000), &pCPUM->aGuestCpuIdExt[0],     RT_ELEMENTS(pCPUM->aGuestCpuIdExt),     pHostOverrideCfg);
     407    AssertRCReturn(rc, rc);
     408    rc = cpumR3CpuIdInitHostSet(UINT32_C(0xc0000000), &pCPUM->aGuestCpuIdCentaur[0], RT_ELEMENTS(pCPUM->aGuestCpuIdCentaur), pHostOverrideCfg);
     409    AssertRCReturn(rc, rc);
     410
     411    pCPUM->enmGuestCpuVendor = cpumR3DetectVendor(pCPUM->aGuestCpuIdStd[0].eax, pCPUM->aGuestCpuIdStd[0].ebx,
     412                                                  pCPUM->aGuestCpuIdStd[0].ecx, pCPUM->aGuestCpuIdStd[0].edx);
    341413
    342414    /*
     
    353425                                       | X86_CPUID_FEATURE_EDX_CX8
    354426                                       //| X86_CPUID_FEATURE_EDX_APIC  - set by the APIC device if present.
    355                                        /** @note we don't report sysenter/sysexit support due to our inability to keep the IOPL part of eflags in sync while in ring 1 (see #1757) */
     427                                       /* Note! we don't report sysenter/sysexit support due to our inability to keep the IOPL part of eflags in sync while in ring 1 (see #1757) */
    356428                                       //| X86_CPUID_FEATURE_EDX_SEP
    357429                                       | X86_CPUID_FEATURE_EDX_MTRR
     
    372444                                       //| X86_CPUID_FEATURE_EDX_HTT   - no hyperthreading.
    373445                                       //| X86_CPUID_FEATURE_EDX_TM    - no thermal monitor.
    374                                        //| X86_CPUID_FEATURE_EDX_PBE   - no pneding break enabled.
     446                                       //| X86_CPUID_FEATURE_EDX_PBE   - no pending break enabled.
    375447                                       | 0;
    376448    pCPUM->aGuestCpuIdStd[1].ecx      &= 0
     
    404476                                       | X86_CPUID_AMD_FEATURE_EDX_CX8
    405477                                       //| X86_CPUID_AMD_FEATURE_EDX_APIC   - set by the APIC device if present.
    406                                        /** @note we don't report sysenter/sysexit support due to our inability to keep the IOPL part of eflags in sync while in ring 1 (see #1757) */
     478                                       /* Note! we don't report sysenter/sysexit support due to our inability to keep the IOPL part of eflags in sync while in ring 1 (see #1757) */
    407479                                       //| X86_CPUID_AMD_FEATURE_EDX_SEP
    408480                                       | X86_CPUID_AMD_FEATURE_EDX_MTRR
     
    439511                                       | 0;
    440512
    441     CFGMR3QueryBoolDef(CFGMR3GetChild(CFGMR3GetRoot(pVM), "CPUM"), "SyntheticCpu", &pCPUM->fSyntheticCpu, false);
     513    rc = CFGMR3QueryBoolDef(pCpumCfg, "SyntheticCpu", &pCPUM->fSyntheticCpu, false); AssertRCReturn(rc, rc);
    442514    if (pCPUM->fSyntheticCpu)
    443515    {
     
    533605     *      Bits 25-14: Maximum number of addressable IDs for logical processors sharing this cache (see note)**
    534606     *      Bits 31-26: Maximum number of processor cores in this physical package**
    535      * @Note These SMP values are constant regardless of ECX
     607     * Note: These SMP values are constant regardless of ECX
    536608     */
    537609    pCPUM->aGuestCpuIdStd[4].ecx = pCPUM->aGuestCpuIdStd[4].edx = 0;
     
    649721     */
    650722    bool fNt4LeafLimit;
    651     CFGMR3QueryBoolDef(CFGMR3GetChild(CFGMR3GetRoot(pVM), "CPUM"), "NT4LeafLimit", &fNt4LeafLimit, false);
     723    rc = CFGMR3QueryBoolDef(pCpumCfg, "NT4LeafLimit", &fNt4LeafLimit, false); AssertRCReturn(rc, rc);
    652724    if (fNt4LeafLimit)
    653725        pCPUM->aGuestCpuIdStd[0].eax = 3;
     
    707779    /*
    708780     * Load CPUID overrides from configuration.
    709      * @note Kind of redundant now, but allows unchanged overrides
     781     * Note: Kind of redundant now, but allows unchanged overrides
    710782     */
    711783    /** @cfgm{CPUM/CPUID/[000000xx|800000xx|c000000x]/[eax|ebx|ecx|edx],32-bit}
    712      * Overloads the CPUID leaf values. */
    713     PCPUMCPUID  pCpuId = &pCPUM->aGuestCpuIdStd[0];
    714     uint32_t    cElements = RT_ELEMENTS(pCPUM->aGuestCpuIdStd);
    715     for (i=0;; )
    716     {
    717         while (cElements-- > 0)
    718         {
    719             PCFGMNODE pNode = CFGMR3GetChildF(CFGMR3GetRoot(pVM), "CPUM/CPUID/%RX32", i);
    720             if (pNode)
    721             {
    722                 uint32_t u32;
    723                 int rc = CFGMR3QueryU32(pNode, "eax", &u32);
    724                 if (RT_SUCCESS(rc))
    725                     pCpuId->eax = u32;
    726                 else
    727                     AssertReturn(rc == VERR_CFGM_VALUE_NOT_FOUND, rc);
    728 
    729                 rc = CFGMR3QueryU32(pNode, "ebx", &u32);
    730                 if (RT_SUCCESS(rc))
    731                     pCpuId->ebx = u32;
    732                 else
    733                     AssertReturn(rc == VERR_CFGM_VALUE_NOT_FOUND, rc);
    734 
    735                 rc = CFGMR3QueryU32(pNode, "ecx", &u32);
    736                 if (RT_SUCCESS(rc))
    737                     pCpuId->ecx = u32;
    738                 else
    739                     AssertReturn(rc == VERR_CFGM_VALUE_NOT_FOUND, rc);
    740 
    741                 rc = CFGMR3QueryU32(pNode, "edx", &u32);
    742                 if (RT_SUCCESS(rc))
    743                     pCpuId->edx = u32;
    744                 else
    745                     AssertReturn(rc == VERR_CFGM_VALUE_NOT_FOUND, rc);
    746             }
    747             pCpuId++;
    748             i++;
    749         }
    750 
    751         /* next */
    752         if ((i & UINT32_C(0xc0000000)) == 0)
    753         {
    754             pCpuId = &pCPUM->aGuestCpuIdExt[0];
    755             cElements = RT_ELEMENTS(pCPUM->aGuestCpuIdExt);
    756             i = UINT32_C(0x80000000);
    757         }
    758         else if ((i & UINT32_C(0xc0000000)) == UINT32_C(0x80000000))
    759         {
    760             pCpuId = &pCPUM->aGuestCpuIdCentaur[0];
    761             cElements = RT_ELEMENTS(pCPUM->aGuestCpuIdCentaur);
    762             i = UINT32_C(0xc0000000);
    763         }
    764         else
    765             break;
    766     }
    767 
    768     /* Check if PAE was explicitely enabled by the user. */
    769     bool fEnable = false;
    770     int rc = CFGMR3QueryBool(CFGMR3GetRoot(pVM), "EnablePAE", &fEnable);
    771     if (RT_SUCCESS(rc) && fEnable)
     784     * Overrides the CPUID leaf values. */
     785    PCFGMNODE pOverrideCfg = CFGMR3GetChild(pCpumCfg, "CPUID");
     786    rc = cpumR3CpuIdInitLoadOverrideSet(UINT32_C(0x00000000), &pCPUM->aGuestCpuIdStd[0],     RT_ELEMENTS(pCPUM->aGuestCpuIdStd),     pOverrideCfg);
     787    AssertRCReturn(rc, rc);
     788    rc = cpumR3CpuIdInitLoadOverrideSet(UINT32_C(0x80000000), &pCPUM->aGuestCpuIdExt[0],     RT_ELEMENTS(pCPUM->aGuestCpuIdExt),     pOverrideCfg);
     789    AssertRCReturn(rc, rc);
     790    rc = cpumR3CpuIdInitLoadOverrideSet(UINT32_C(0xc0000000), &pCPUM->aGuestCpuIdCentaur[0], RT_ELEMENTS(pCPUM->aGuestCpuIdCentaur), pOverrideCfg);
     791    AssertRCReturn(rc, rc);
     792
     793    /*
     794     * Check if PAE was explicitely enabled by the user.
     795     */
     796    bool fEnable;
     797    rc = CFGMR3QueryBoolDef(CFGMR3GetRoot(pVM), "EnablePAE", &fEnable, false);    AssertRCReturn(rc, rc);
     798    if (fEnable)
    772799        CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_PAE);
    773800
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