Changeset 24406 in vbox
- Timestamp:
- Nov 5, 2009 5:20:01 PM (15 years ago)
- Location:
- trunk/src/VBox
- Files:
-
- 2 edited
-
Main/ConsoleImpl2.cpp (modified) (2 diffs)
-
VMM/CPUM.cpp (modified) (13 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/ConsoleImpl2.cpp
r24329 r24406 246 246 247 247 /* Standard cpuid leaf overrides. */ 248 for (u nsignedleaf = 0; leaf < 0xA; leaf++)248 for (uint32_t leaf = 0; leaf < 0xA; leaf++) 249 249 { 250 250 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)) 252 253 { 253 254 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(); 261 263 } 262 264 263 265 /* Extended cpuid leaf overrides. */ 264 for (u nsignedleaf = 0x80000000; leaf < 0x8000000A; leaf++)266 for (uint32_t leaf = 0x80000000; leaf < 0x8000000A; leaf++) 265 267 { 266 268 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)) 268 271 { 269 272 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(); 277 281 } 278 282 … … 291 295 /* hardware virtualization extensions */ 292 296 BOOL fHWVirtExEnabled; 293 hrc = pMachine->GetHWVirtExProperty(HWVirtExPropertyType_Enabled, &fHWVirtExEnabled); H();297 hrc = pMachine->GetHWVirtExProperty(HWVirtExPropertyType_Enabled, &fHWVirtExEnabled); H(); 294 298 if (cCpus > 1) /** @todo SMP: This isn't nice, but things won't work on mac otherwise. */ 295 299 fHWVirtExEnabled = TRUE; -
trunk/src/VBox/VMM/CPUM.cpp
r24328 r24406 104 104 * Internal Functions * 105 105 *******************************************************************************/ 106 static CPUMCPUVENDOR cpumR3DetectVendor(uint32_t uEAX, uint32_t uEBX, uint32_t uECX, uint32_t uEDX); 106 107 static int cpumR3CpuIdInit(PVM pVM); 107 108 #ifdef VBOX_WITH_LIVE_MIGRATION … … 199 200 if (!pVM->cpum.s.CPUFeatures.edx.u1SEP) 200 201 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; 201 211 202 212 /* … … 221 231 return rc; 222 232 223 /* Query the CPU manufacturer. */224 uint32_t uEAX, uEBX, uECX, uEDX;225 ASMCpuId(0, &uEAX, &uEBX, &uECX, &uEDX);226 if ( uEAX >= 1227 && uEBX == X86_CPUID_VENDOR_AMD_EBX228 && uECX == X86_CPUID_VENDOR_AMD_ECX229 && uEDX == X86_CPUID_VENDOR_AMD_EDX)230 {231 pVM->cpum.s.enmGuestCpuVendor = pVM->cpum.s.enmHostCpuVendor = CPUMCPUVENDOR_AMD;232 }233 else if ( uEAX >= 1234 && uEBX == X86_CPUID_VENDOR_INTEL_EBX235 && uECX == X86_CPUID_VENDOR_INTEL_ECX236 && 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 245 233 /* 246 234 * Register info handlers. … … 254 242 255 243 /* 256 * Initialize the Guest CPU state.244 * Initialize the Guest CPUID state. 257 245 */ 258 246 rc = cpumR3CpuIdInit(pVM); … … 278 266 279 267 /** 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 */ 276 static 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 */ 304 static 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 */ 349 static 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 */ 370 static 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 /** 280 383 * Initializes the emulated CPU's cpuid information. 281 384 * … … 285 388 static int cpumR3CpuIdInit(PVM pVM) 286 389 { 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); 341 413 342 414 /* … … 353 425 | X86_CPUID_FEATURE_EDX_CX8 354 426 //| X86_CPUID_FEATURE_EDX_APIC - set by the APIC device if present. 355 /* * @notewe 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) */ 356 428 //| X86_CPUID_FEATURE_EDX_SEP 357 429 | X86_CPUID_FEATURE_EDX_MTRR … … 372 444 //| X86_CPUID_FEATURE_EDX_HTT - no hyperthreading. 373 445 //| X86_CPUID_FEATURE_EDX_TM - no thermal monitor. 374 //| X86_CPUID_FEATURE_EDX_PBE - no p neding break enabled.446 //| X86_CPUID_FEATURE_EDX_PBE - no pending break enabled. 375 447 | 0; 376 448 pCPUM->aGuestCpuIdStd[1].ecx &= 0 … … 404 476 | X86_CPUID_AMD_FEATURE_EDX_CX8 405 477 //| X86_CPUID_AMD_FEATURE_EDX_APIC - set by the APIC device if present. 406 /* * @notewe 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) */ 407 479 //| X86_CPUID_AMD_FEATURE_EDX_SEP 408 480 | X86_CPUID_AMD_FEATURE_EDX_MTRR … … 439 511 | 0; 440 512 441 CFGMR3QueryBoolDef(CFGMR3GetChild(CFGMR3GetRoot(pVM), "CPUM"), "SyntheticCpu", &pCPUM->fSyntheticCpu, false);513 rc = CFGMR3QueryBoolDef(pCpumCfg, "SyntheticCpu", &pCPUM->fSyntheticCpu, false); AssertRCReturn(rc, rc); 442 514 if (pCPUM->fSyntheticCpu) 443 515 { … … 533 605 * Bits 25-14: Maximum number of addressable IDs for logical processors sharing this cache (see note)** 534 606 * Bits 31-26: Maximum number of processor cores in this physical package** 535 * @NoteThese SMP values are constant regardless of ECX607 * Note: These SMP values are constant regardless of ECX 536 608 */ 537 609 pCPUM->aGuestCpuIdStd[4].ecx = pCPUM->aGuestCpuIdStd[4].edx = 0; … … 649 721 */ 650 722 bool fNt4LeafLimit; 651 CFGMR3QueryBoolDef(CFGMR3GetChild(CFGMR3GetRoot(pVM), "CPUM"), "NT4LeafLimit", &fNt4LeafLimit, false);723 rc = CFGMR3QueryBoolDef(pCpumCfg, "NT4LeafLimit", &fNt4LeafLimit, false); AssertRCReturn(rc, rc); 652 724 if (fNt4LeafLimit) 653 725 pCPUM->aGuestCpuIdStd[0].eax = 3; … … 707 779 /* 708 780 * Load CPUID overrides from configuration. 709 * @noteKind of redundant now, but allows unchanged overrides781 * Note: Kind of redundant now, but allows unchanged overrides 710 782 */ 711 783 /** @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) 772 799 CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_PAE); 773 800
Note:
See TracChangeset
for help on using the changeset viewer.

