Changeset 61776 in vbox for trunk/src/VBox/VMM/VMMAll
- Timestamp:
- Jun 20, 2016 11:25:06 PM (9 years ago)
- svn:sync-xref-src-repo-rev:
- 108168
- Location:
- trunk/src/VBox/VMM/VMMAll
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/APICAll.cpp
r61736 r61776 2068 2068 2069 2069 /* Don't allow enabling xAPIC/x2APIC if the VM is configured with the APIC disabled. */ 2070 if (pApic->enm OriginalMode == APICMODE_DISABLED)2070 if (pApic->enmMaxMode == PDMAPICMODE_NONE) 2071 2071 { 2072 2072 LogRel(("APIC%u: Disallowing APIC base MSR write as the VM is configured with APIC disabled!\n", 2073 pVCpu->idCpu));2073 pVCpu->idCpu)); 2074 2074 return apicMsrAccessError(pVCpu, MSR_IA32_APICBASE, APICMSRACCESS_WRITE_DISALLOWED_CONFIG); 2075 2075 } … … 2078 2078 * Act on state transition. 2079 2079 */ 2080 /** @todo We need to update the CPUID according to the state, which we2081 * currently don't do as CPUMSetGuestCpuIdFeature() is setting2082 * per-VM CPUID bits while we need per-VCPU specific bits. */2083 2080 if (enmNewMode != enmOldMode) 2084 2081 { … … 2099 2096 APICR3Reset(pVCpu, false /* fResetApicBaseMsr */); 2100 2097 uBaseMsr &= ~(MSR_IA32_APICBASE_EN | MSR_IA32_APICBASE_EXTD); 2101 CPUM ClearGuestCpuIdFeature(pVCpu->CTX_SUFF(pVM), CPUMCPUIDFEATURE_APIC);2098 CPUMSetGuestCpuIdPerCpuApicFeature(pVCpu, false /*fVisible*/); 2102 2099 LogRel(("APIC%u: Switched mode to disabled\n", pVCpu->idCpu)); 2103 2100 break; … … 2113 2110 2114 2111 uBaseMsr |= MSR_IA32_APICBASE_EN; 2115 CPUMSetGuestCpuId Feature(pVCpu->CTX_SUFF(pVM), CPUMCPUIDFEATURE_APIC);2112 CPUMSetGuestCpuIdPerCpuApicFeature(pVCpu, true /*fVisible*/); 2116 2113 LogRel(("APIC%u: Switched mode to xAPIC\n", pVCpu->idCpu)); 2117 2114 break; … … 2120 2117 case APICMODE_X2APIC: 2121 2118 { 2122 if (pApic->enm OriginalMode !=APICMODE_X2APIC)2119 if (pApic->enmMaxMode != PDMAPICMODE_X2APIC) 2123 2120 { 2124 2121 LogRel(("APIC%u: Disallowing transition to x2APIC mode as the VM is configured with the x2APIC disabled!\n", -
trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp
r61071 r61776 734 734 VMMDECL(int) CPUMSetGuestCR4(PVMCPU pVCpu, uint64_t cr4) 735 735 { 736 /* 737 * The CR4.OSXSAVE bit is reflected in CPUID(1).ECX[27]. 738 */ 739 if ( (cr4 & X86_CR4_OSXSAVE) 740 != (pVCpu->cpum.s.Guest.cr4 & X86_CR4_OSXSAVE) ) 741 { 742 PVM pVM = pVCpu->CTX_SUFF(pVM); 743 if (cr4 & X86_CR4_OSXSAVE) 744 CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_OSXSAVE); 745 else 746 CPUMClearGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_OSXSAVE); 747 } 736 /* Note! We don't bother with OSXSAVE and legacy CPUID patches. */ 748 737 749 738 if ( (cr4 & (X86_CR4_PGE | X86_CR4_PAE | X86_CR4_PSE)) … … 1288 1277 1289 1278 /* 1290 * Deal with CPU specific information (currently only APIC ID).1279 * Deal with CPU specific information. 1291 1280 */ 1292 if (pLeaf->fFlags & (CPUMCPUIDLEAF_F_CONTAINS_APIC_ID | CPUMCPUIDLEAF_F_CONTAINS_OSXSAVE)) 1281 if (pLeaf->fFlags & ( CPUMCPUIDLEAF_F_CONTAINS_APIC_ID 1282 | CPUMCPUIDLEAF_F_CONTAINS_OSXSAVE 1283 | CPUMCPUIDLEAF_F_CONTAINS_APIC )) 1293 1284 { 1294 1285 if (uLeaf == 1) … … 1298 1289 AssertMsg((pLeaf->uEbx >> 24) == 0, ("%#x\n", pLeaf->uEbx)); /* raw-mode assumption */ 1299 1290 *pEbx = (pLeaf->uEbx & UINT32_C(0x00ffffff)) | (pVCpu->idCpu << 24); 1291 1292 /* EDX: Bit 9: AND with APICBASE.EN. */ 1293 if (!pVCpu->cpum.s.fCpuIdApicFeatureVisible && (pLeaf->fFlags & CPUMCPUIDLEAF_F_CONTAINS_APIC)) 1294 *pEdx &= ~X86_CPUID_FEATURE_EDX_APIC; 1300 1295 1301 1296 /* ECX: Bit 27: CR4.OSXSAVE mirror. */ … … 1308 1303 AssertMsg(pLeaf->uEdx == 0, ("%#x\n", pLeaf->uEdx)); /* raw-mode assumption */ 1309 1304 *pEdx = pVCpu->idCpu; 1305 Assert(!(pLeaf->fFlags & ~(CPUMCPUIDLEAF_F_CONTAINS_APIC_ID | CPUMCPUIDLEAF_F_INTEL_TOPOLOGY_SUBLEAVES))); 1310 1306 } 1311 1307 else if (uLeaf == UINT32_C(0x8000001e)) … … 1314 1310 AssertMsg(pLeaf->uEax == 0, ("%#x\n", pLeaf->uEax)); /* raw-mode assumption */ 1315 1311 *pEax = pVCpu->idCpu; 1312 Assert(!(pLeaf->fFlags & ~CPUMCPUIDLEAF_F_CONTAINS_APIC_ID)); 1313 } 1314 else if (uLeaf == UINT32_C(0x80000001)) 1315 { 1316 /* EDX: Bit 9: AND with APICBASE.EN. */ 1317 if (!pVCpu->cpum.s.fCpuIdApicFeatureVisible) 1318 *pEdx &= ~X86_CPUID_AMD_FEATURE_EDX_APIC; 1319 Assert(!(pLeaf->fFlags & ~CPUMCPUIDLEAF_F_CONTAINS_APIC)); 1316 1320 } 1317 1321 else … … 1363 1367 1364 1368 /** 1365 * Sets a CPUID feature bit. 1366 * 1367 * @param pVM The cross context VM structure. 1368 * @param enmFeature The feature to set. 1369 */ 1370 VMMDECL(void) CPUMSetGuestCpuIdFeature(PVM pVM, CPUMCPUIDFEATURE enmFeature) 1371 { 1372 PCPUMCPUIDLEAF pLeaf; 1373 1374 switch (enmFeature) 1369 * Sets the visibility of the X86_CPUID_FEATURE_EDX_APIC and 1370 * X86_CPUID_AMD_FEATURE_EDX_APIC CPUID bits. 1371 * 1372 * @returns Previous value. 1373 * @param pVCpu The cross context virtual CPU structure to make the 1374 * change on. Usually the calling EMT. 1375 * @param fVisible Whether to make it visible (true) or hide it (false). 1376 */ 1377 VMM_INT_DECL(bool) CPUMSetGuestCpuIdPerCpuApicFeature(PVMCPU pVCpu, bool fVisible) 1378 { 1379 bool fOld = pVCpu->cpum.s.fCpuIdApicFeatureVisible; 1380 pVCpu->cpum.s.fCpuIdApicFeatureVisible = fVisible; 1381 1382 #ifdef VBOX_WITH_RAW_MODE_NOT_R0 1383 /* 1384 * Patch manager saved state legacy pain. 1385 */ 1386 PVM pVM = pVCpu->CTX_SUFF(pVM); 1387 PCPUMCPUIDLEAF pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000001)); 1388 if (pLeaf) 1375 1389 { 1376 /* 1377 * Set the APIC bit in both feature masks. 1378 */ 1379 case CPUMCPUIDFEATURE_APIC: 1380 pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000001)); 1381 if (pLeaf) 1382 pVM->cpum.s.aGuestCpuIdPatmStd[1].uEdx = pLeaf->uEdx |= X86_CPUID_FEATURE_EDX_APIC; 1383 1384 pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001)); 1385 if ( pLeaf 1386 && pVM->cpum.s.GuestFeatures.enmCpuVendor == CPUMCPUVENDOR_AMD) 1387 pVM->cpum.s.aGuestCpuIdPatmExt[1].uEdx = pLeaf->uEdx |= X86_CPUID_AMD_FEATURE_EDX_APIC; 1388 1389 pVM->cpum.s.GuestFeatures.fApic = 1; 1390 LogRel(("CPUM: SetGuestCpuIdFeature: Enabled xAPIC\n")); 1391 break; 1392 1393 /* 1394 * Set the x2APIC bit in the standard feature mask. 1395 */ 1396 case CPUMCPUIDFEATURE_X2APIC: 1397 pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000001)); 1398 if (pLeaf) 1399 pVM->cpum.s.aGuestCpuIdPatmStd[1].uEcx = pLeaf->uEcx |= X86_CPUID_FEATURE_ECX_X2APIC; 1400 pVM->cpum.s.GuestFeatures.fX2Apic = 1; 1401 LogRel(("CPUM: SetGuestCpuIdFeature: Enabled x2APIC\n")); 1402 break; 1403 1404 /* 1405 * Set the sysenter/sysexit bit in the standard feature mask. 1406 * Assumes the caller knows what it's doing! (host must support these) 1407 */ 1408 case CPUMCPUIDFEATURE_SEP: 1409 if (!pVM->cpum.s.HostFeatures.fSysEnter) 1410 { 1411 AssertMsgFailed(("ERROR: Can't turn on SEP when the host doesn't support it!!\n")); 1412 return; 1413 } 1414 1415 pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000001)); 1416 if (pLeaf) 1417 pVM->cpum.s.aGuestCpuIdPatmStd[1].uEdx = pLeaf->uEdx |= X86_CPUID_FEATURE_EDX_SEP; 1418 pVM->cpum.s.GuestFeatures.fSysEnter = 1; 1419 LogRel(("CPUM: SetGuestCpuIdFeature: Enabled SYSENTER/EXIT\n")); 1420 break; 1421 1422 /* 1423 * Set the syscall/sysret bit in the extended feature mask. 1424 * Assumes the caller knows what it's doing! (host must support these) 1425 */ 1426 case CPUMCPUIDFEATURE_SYSCALL: 1427 pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001)); 1428 if ( !pLeaf 1429 || !pVM->cpum.s.HostFeatures.fSysCall) 1430 { 1431 #if HC_ARCH_BITS == 32 1432 /* X86_CPUID_EXT_FEATURE_EDX_SYSCALL not set it seems in 32-bit 1433 mode by Intel, even when the cpu is capable of doing so in 1434 64-bit mode. Long mode requires syscall support. */ 1435 if (!pVM->cpum.s.HostFeatures.fLongMode) 1390 if (fVisible || (pLeaf->fFlags & CPUMCPUIDLEAF_F_CONTAINS_APIC)) 1391 pVM->cpum.s.aGuestCpuIdPatmStd[1].uEdx = pLeaf->uEdx; 1392 else 1393 pVM->cpum.s.aGuestCpuIdPatmStd[1].uEdx = pLeaf->uEdx & ~X86_CPUID_FEATURE_EDX_APIC; 1394 } 1395 1396 pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001)); 1397 if (pLeaf) 1398 { 1399 if (fVisible || (pLeaf->fFlags & CPUMCPUIDLEAF_F_CONTAINS_APIC)) 1400 pVM->cpum.s.aGuestCpuIdPatmExt[1].uEdx = pLeaf->uEdx; 1401 else 1402 pVM->cpum.s.aGuestCpuIdPatmExt[1].uEdx = pLeaf->uEdx & ~X86_CPUID_AMD_FEATURE_EDX_APIC; 1403 } 1436 1404 #endif 1437 { 1438 LogRel(("CPUM: WARNING! Can't turn on SYSCALL/SYSRET when the host doesn't support it!\n")); 1439 return; 1440 } 1441 } 1442 1443 /* Valid for both Intel and AMD CPUs, although only in 64 bits mode for Intel. */ 1444 pVM->cpum.s.aGuestCpuIdPatmExt[1].uEdx = pLeaf->uEdx |= X86_CPUID_EXT_FEATURE_EDX_SYSCALL; 1445 pVM->cpum.s.GuestFeatures.fSysCall = 1; 1446 LogRel(("CPUM: SetGuestCpuIdFeature: Enabled SYSCALL/RET\n")); 1447 break; 1448 1449 /* 1450 * Set the PAE bit in both feature masks. 1451 * Assumes the caller knows what it's doing! (host must support these) 1452 */ 1453 case CPUMCPUIDFEATURE_PAE: 1454 if (!pVM->cpum.s.HostFeatures.fPae) 1455 { 1456 LogRel(("CPUM: WARNING! Can't turn on PAE when the host doesn't support it!\n")); 1457 return; 1458 } 1459 1460 pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000001)); 1461 if (pLeaf) 1462 pVM->cpum.s.aGuestCpuIdPatmStd[1].uEdx = pLeaf->uEdx |= X86_CPUID_FEATURE_EDX_PAE; 1463 1464 pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001)); 1465 if ( pLeaf 1466 && pVM->cpum.s.GuestFeatures.enmCpuVendor == CPUMCPUVENDOR_AMD) 1467 pVM->cpum.s.aGuestCpuIdPatmExt[1].uEdx = pLeaf->uEdx |= X86_CPUID_AMD_FEATURE_EDX_PAE; 1468 1469 pVM->cpum.s.GuestFeatures.fPae = 1; 1470 LogRel(("CPUM: SetGuestCpuIdFeature: Enabled PAE\n")); 1471 break; 1472 1473 /* 1474 * Set the LONG MODE bit in the extended feature mask. 1475 * Assumes the caller knows what it's doing! (host must support these) 1476 */ 1477 case CPUMCPUIDFEATURE_LONG_MODE: 1478 pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001)); 1479 if ( !pLeaf 1480 || !pVM->cpum.s.HostFeatures.fLongMode) 1481 { 1482 LogRel(("CPUM: WARNING! Can't turn on LONG MODE when the host doesn't support it!\n")); 1483 return; 1484 } 1485 1486 /* Valid for both Intel and AMD. */ 1487 pVM->cpum.s.aGuestCpuIdPatmExt[1].uEdx = pLeaf->uEdx |= X86_CPUID_EXT_FEATURE_EDX_LONG_MODE; 1488 pVM->cpum.s.GuestFeatures.fLongMode = 1; 1489 LogRel(("CPUM: SetGuestCpuIdFeature: Enabled LONG MODE\n")); 1490 break; 1491 1492 /* 1493 * Set the NX/XD bit in the extended feature mask. 1494 * Assumes the caller knows what it's doing! (host must support these) 1495 */ 1496 case CPUMCPUIDFEATURE_NX: 1497 pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001)); 1498 if ( !pLeaf 1499 || !pVM->cpum.s.HostFeatures.fNoExecute) 1500 { 1501 LogRel(("CPUM: WARNING! Can't turn on NX/XD when the host doesn't support it!\n")); 1502 return; 1503 } 1504 1505 /* Valid for both Intel and AMD. */ 1506 pVM->cpum.s.aGuestCpuIdPatmExt[1].uEdx = pLeaf->uEdx |= X86_CPUID_EXT_FEATURE_EDX_NX; 1507 pVM->cpum.s.GuestFeatures.fNoExecute = 1; 1508 LogRel(("CPUM: SetGuestCpuIdFeature: Enabled NX\n")); 1509 break; 1510 1511 1512 /* 1513 * Set the LAHF/SAHF support in 64-bit mode. 1514 * Assumes the caller knows what it's doing! (host must support this) 1515 */ 1516 case CPUMCPUIDFEATURE_LAHF: 1517 pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001)); 1518 if ( !pLeaf 1519 || !pVM->cpum.s.HostFeatures.fLahfSahf) 1520 { 1521 LogRel(("CPUM: WARNING! Can't turn on LAHF/SAHF when the host doesn't support it!\n")); 1522 return; 1523 } 1524 1525 /* Valid for both Intel and AMD. */ 1526 pVM->cpum.s.aGuestCpuIdPatmExt[1].uEcx = pLeaf->uEcx |= X86_CPUID_EXT_FEATURE_ECX_LAHF_SAHF; 1527 pVM->cpum.s.GuestFeatures.fLahfSahf = 1; 1528 LogRel(("CPUM: SetGuestCpuIdFeature: Enabled LAHF/SAHF\n")); 1529 break; 1530 1531 /* 1532 * Set the page attribute table bit. This is alternative page level 1533 * cache control that doesn't much matter when everything is 1534 * virtualized, though it may when passing thru device memory. 1535 */ 1536 case CPUMCPUIDFEATURE_PAT: 1537 pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000001)); 1538 if (pLeaf) 1539 pVM->cpum.s.aGuestCpuIdPatmStd[1].uEdx = pLeaf->uEdx |= X86_CPUID_FEATURE_EDX_PAT; 1540 1541 pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001)); 1542 if ( pLeaf 1543 && pVM->cpum.s.GuestFeatures.enmCpuVendor == CPUMCPUVENDOR_AMD) 1544 pVM->cpum.s.aGuestCpuIdPatmExt[1].uEdx = pLeaf->uEdx |= X86_CPUID_AMD_FEATURE_EDX_PAT; 1545 1546 pVM->cpum.s.GuestFeatures.fPat = 1; 1547 LogRel(("CPUM: SetGuestCpuIdFeature: Enabled PAT\n")); 1548 break; 1549 1550 /* 1551 * Set the RDTSCP support bit. 1552 * Assumes the caller knows what it's doing! (host must support this) 1553 */ 1554 case CPUMCPUIDFEATURE_RDTSCP: 1555 pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001)); 1556 if ( !pLeaf 1557 || !pVM->cpum.s.HostFeatures.fRdTscP 1558 || pVM->cpum.s.u8PortableCpuIdLevel > 0) 1559 { 1560 if (!pVM->cpum.s.u8PortableCpuIdLevel) 1561 LogRel(("CPUM: WARNING! Can't turn on RDTSCP when the host doesn't support it!\n")); 1562 return; 1563 } 1564 1565 /* Valid for both Intel and AMD. */ 1566 pVM->cpum.s.aGuestCpuIdPatmExt[1].uEdx = pLeaf->uEdx |= X86_CPUID_EXT_FEATURE_EDX_RDTSCP; 1567 pVM->cpum.s.HostFeatures.fRdTscP = 1; 1568 LogRel(("CPUM: SetGuestCpuIdFeature: Enabled RDTSCP.\n")); 1569 break; 1570 1571 /* 1572 * Set the Hypervisor Present bit in the standard feature mask. 1573 */ 1574 case CPUMCPUIDFEATURE_HVP: 1575 pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000001)); 1576 if (pLeaf) 1577 pVM->cpum.s.aGuestCpuIdPatmStd[1].uEcx = pLeaf->uEcx |= X86_CPUID_FEATURE_ECX_HVP; 1578 pVM->cpum.s.GuestFeatures.fHypervisorPresent = 1; 1579 LogRel(("CPUM: SetGuestCpuIdFeature: Enabled Hypervisor Present bit\n")); 1580 break; 1581 1582 /* 1583 * Set the MWAIT Extensions Present bit in the MWAIT/MONITOR leaf. 1584 * This currently includes the Present bit and MWAITBREAK bit as well. 1585 */ 1586 case CPUMCPUIDFEATURE_MWAIT_EXTS: 1587 pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000005)); 1588 if ( !pLeaf 1589 || !pVM->cpum.s.HostFeatures.fMWaitExtensions) 1590 { 1591 LogRel(("CPUM: WARNING! Can't turn on MWAIT Extensions when the host doesn't support it!\n")); 1592 return; 1593 } 1594 1595 /* Valid for both Intel and AMD. */ 1596 pVM->cpum.s.aGuestCpuIdPatmStd[5].uEcx = pLeaf->uEcx |= X86_CPUID_MWAIT_ECX_EXT | X86_CPUID_MWAIT_ECX_BREAKIRQIF0; 1597 pVM->cpum.s.GuestFeatures.fMWaitExtensions = 1; 1598 LogRel(("CPUM: SetGuestCpuIdFeature: Enabled MWAIT Extensions.\n")); 1599 break; 1600 1601 /* 1602 * OSXSAVE - only used from CPUMSetGuestCR4. 1603 */ 1604 case CPUMCPUIDFEATURE_OSXSAVE: 1605 AssertLogRelReturnVoid(pVM->cpum.s.HostFeatures.fXSaveRstor && pVM->cpum.s.HostFeatures.fOpSysXSaveRstor); 1606 1607 pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000001)); 1608 AssertLogRelReturnVoid(pLeaf); 1609 1610 /* UNI: Special case for single CPU to make life simple for CPUMPatchHlpCpuId. */ 1611 if (pVM->cCpus == 1) 1612 pVM->cpum.s.aGuestCpuIdPatmStd[1].uEcx = pLeaf->uEcx |= X86_CPUID_FEATURE_ECX_OSXSAVE; 1613 /* SMP: Set flag indicating OSXSAVE updating (superfluous because of the APIC ID, but that's fine). */ 1614 else 1615 ASMAtomicOrU32(&pLeaf->fFlags, CPUMCPUIDLEAF_F_CONTAINS_OSXSAVE); 1616 break; 1617 1618 default: 1619 AssertMsgFailed(("enmFeature=%d\n", enmFeature)); 1620 break; 1621 } 1622 1623 for (VMCPUID i = 0; i < pVM->cCpus; i++) 1624 { 1625 PVMCPU pVCpu = &pVM->aCpus[i]; 1626 pVCpu->cpum.s.fChanged |= CPUM_CHANGED_CPUID; 1627 } 1628 } 1629 1630 1631 /** 1632 * Queries a CPUID feature bit. 1633 * 1634 * @returns boolean for feature presence 1635 * @param pVM The cross context VM structure. 1636 * @param enmFeature The feature to query. 1637 */ 1638 VMMDECL(bool) CPUMGetGuestCpuIdFeature(PVM pVM, CPUMCPUIDFEATURE enmFeature) 1639 { 1640 switch (enmFeature) 1641 { 1642 case CPUMCPUIDFEATURE_APIC: return pVM->cpum.s.GuestFeatures.fApic; 1643 case CPUMCPUIDFEATURE_X2APIC: return pVM->cpum.s.GuestFeatures.fX2Apic; 1644 case CPUMCPUIDFEATURE_SYSCALL: return pVM->cpum.s.GuestFeatures.fSysCall; 1645 case CPUMCPUIDFEATURE_SEP: return pVM->cpum.s.GuestFeatures.fSysEnter; 1646 case CPUMCPUIDFEATURE_PAE: return pVM->cpum.s.GuestFeatures.fPae; 1647 case CPUMCPUIDFEATURE_NX: return pVM->cpum.s.GuestFeatures.fNoExecute; 1648 case CPUMCPUIDFEATURE_LAHF: return pVM->cpum.s.GuestFeatures.fLahfSahf; 1649 case CPUMCPUIDFEATURE_LONG_MODE: return pVM->cpum.s.GuestFeatures.fLongMode; 1650 case CPUMCPUIDFEATURE_PAT: return pVM->cpum.s.GuestFeatures.fPat; 1651 case CPUMCPUIDFEATURE_RDTSCP: return pVM->cpum.s.GuestFeatures.fRdTscP; 1652 case CPUMCPUIDFEATURE_HVP: return pVM->cpum.s.GuestFeatures.fHypervisorPresent; 1653 case CPUMCPUIDFEATURE_MWAIT_EXTS: return pVM->cpum.s.GuestFeatures.fMWaitExtensions; 1654 1655 case CPUMCPUIDFEATURE_OSXSAVE: 1656 case CPUMCPUIDFEATURE_INVALID: 1657 case CPUMCPUIDFEATURE_32BIT_HACK: 1658 break; 1659 } 1660 AssertFailed(); 1661 return false; 1662 } 1663 1664 1665 /** 1666 * Clears a CPUID feature bit. 1667 * 1668 * @param pVM The cross context VM structure. 1669 * @param enmFeature The feature to clear. 1670 */ 1671 VMMDECL(void) CPUMClearGuestCpuIdFeature(PVM pVM, CPUMCPUIDFEATURE enmFeature) 1672 { 1673 PCPUMCPUIDLEAF pLeaf; 1674 switch (enmFeature) 1675 { 1676 case CPUMCPUIDFEATURE_APIC: 1677 pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000001)); 1678 if (pLeaf) 1679 pVM->cpum.s.aGuestCpuIdPatmStd[1].uEdx = pLeaf->uEdx &= ~X86_CPUID_FEATURE_EDX_APIC; 1680 1681 pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001)); 1682 if ( pLeaf 1683 && pVM->cpum.s.GuestFeatures.enmCpuVendor == CPUMCPUVENDOR_AMD) 1684 pVM->cpum.s.aGuestCpuIdPatmExt[1].uEdx = pLeaf->uEdx &= ~X86_CPUID_AMD_FEATURE_EDX_APIC; 1685 1686 pVM->cpum.s.GuestFeatures.fApic = 0; 1687 Log(("CPUM: ClearGuestCpuIdFeature: Disabled xAPIC\n")); 1688 break; 1689 1690 case CPUMCPUIDFEATURE_X2APIC: 1691 pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000001)); 1692 if (pLeaf) 1693 pVM->cpum.s.aGuestCpuIdPatmStd[1].uEcx = pLeaf->uEcx &= ~X86_CPUID_FEATURE_ECX_X2APIC; 1694 pVM->cpum.s.GuestFeatures.fX2Apic = 0; 1695 Log(("CPUM: ClearGuestCpuIdFeature: Disabled x2APIC\n")); 1696 break; 1697 1698 case CPUMCPUIDFEATURE_PAE: 1699 pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000001)); 1700 if (pLeaf) 1701 pVM->cpum.s.aGuestCpuIdPatmStd[1].uEdx = pLeaf->uEdx &= ~X86_CPUID_FEATURE_EDX_PAE; 1702 1703 pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001)); 1704 if ( pLeaf 1705 && pVM->cpum.s.GuestFeatures.enmCpuVendor == CPUMCPUVENDOR_AMD) 1706 pVM->cpum.s.aGuestCpuIdPatmExt[1].uEdx = pLeaf->uEdx &= ~X86_CPUID_AMD_FEATURE_EDX_PAE; 1707 1708 pVM->cpum.s.GuestFeatures.fPae = 0; 1709 Log(("CPUM: ClearGuestCpuIdFeature: Disabled PAE!\n")); 1710 break; 1711 1712 case CPUMCPUIDFEATURE_PAT: 1713 pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000001)); 1714 if (pLeaf) 1715 pVM->cpum.s.aGuestCpuIdPatmStd[1].uEdx = pLeaf->uEdx &= ~X86_CPUID_FEATURE_EDX_PAT; 1716 1717 pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001)); 1718 if ( pLeaf 1719 && pVM->cpum.s.GuestFeatures.enmCpuVendor == CPUMCPUVENDOR_AMD) 1720 pVM->cpum.s.aGuestCpuIdPatmExt[1].uEdx = pLeaf->uEdx &= ~X86_CPUID_AMD_FEATURE_EDX_PAT; 1721 1722 pVM->cpum.s.GuestFeatures.fPat = 0; 1723 Log(("CPUM: ClearGuestCpuIdFeature: Disabled PAT!\n")); 1724 break; 1725 1726 case CPUMCPUIDFEATURE_LONG_MODE: 1727 pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001)); 1728 if (pLeaf) 1729 pVM->cpum.s.aGuestCpuIdPatmExt[1].uEdx = pLeaf->uEdx &= ~X86_CPUID_EXT_FEATURE_EDX_LONG_MODE; 1730 pVM->cpum.s.GuestFeatures.fLongMode = 0; 1731 break; 1732 1733 case CPUMCPUIDFEATURE_LAHF: 1734 pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001)); 1735 if (pLeaf) 1736 pVM->cpum.s.aGuestCpuIdPatmExt[1].uEcx = pLeaf->uEcx &= ~X86_CPUID_EXT_FEATURE_ECX_LAHF_SAHF; 1737 pVM->cpum.s.GuestFeatures.fLahfSahf = 0; 1738 break; 1739 1740 case CPUMCPUIDFEATURE_RDTSCP: 1741 pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001)); 1742 if (pLeaf) 1743 pVM->cpum.s.aGuestCpuIdPatmExt[1].uEdx = pLeaf->uEdx &= ~X86_CPUID_EXT_FEATURE_EDX_RDTSCP; 1744 pVM->cpum.s.GuestFeatures.fRdTscP = 0; 1745 Log(("CPUM: ClearGuestCpuIdFeature: Disabled RDTSCP!\n")); 1746 break; 1747 1748 case CPUMCPUIDFEATURE_HVP: 1749 pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000001)); 1750 if (pLeaf) 1751 pVM->cpum.s.aGuestCpuIdPatmStd[1].uEcx = pLeaf->uEcx &= ~X86_CPUID_FEATURE_ECX_HVP; 1752 pVM->cpum.s.GuestFeatures.fHypervisorPresent = 0; 1753 break; 1754 1755 case CPUMCPUIDFEATURE_MWAIT_EXTS: 1756 pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000005)); 1757 if (pLeaf) 1758 pVM->cpum.s.aGuestCpuIdPatmStd[5].uEcx = pLeaf->uEcx &= ~(X86_CPUID_MWAIT_ECX_EXT | X86_CPUID_MWAIT_ECX_BREAKIRQIF0); 1759 pVM->cpum.s.GuestFeatures.fMWaitExtensions = 0; 1760 Log(("CPUM: ClearGuestCpuIdFeature: Disabled MWAIT Extensions!\n")); 1761 break; 1762 1763 /* 1764 * OSXSAVE - only used from CPUMSetGuestCR4. 1765 */ 1766 case CPUMCPUIDFEATURE_OSXSAVE: 1767 AssertLogRelReturnVoid(pVM->cpum.s.HostFeatures.fXSaveRstor && pVM->cpum.s.HostFeatures.fOpSysXSaveRstor); 1768 1769 pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000001)); 1770 AssertLogRelReturnVoid(pLeaf); 1771 1772 /* UNI: Special case for single CPU to make life easy for CPUMPatchHlpCpuId. */ 1773 if (pVM->cCpus == 1) 1774 pVM->cpum.s.aGuestCpuIdPatmStd[1].uEcx = pLeaf->uEcx &= ~X86_CPUID_FEATURE_ECX_OSXSAVE; 1775 /* else: SMP: We never set the OSXSAVE bit and leaving the CONTAINS_OSXSAVE flag is fine. */ 1776 break; 1777 1778 1779 default: 1780 AssertMsgFailed(("enmFeature=%d\n", enmFeature)); 1781 break; 1782 } 1783 1784 for (VMCPUID i = 0; i < pVM->cCpus; i++) 1785 { 1786 PVMCPU pVCpu = &pVM->aCpus[i]; 1787 pVCpu->cpum.s.fChanged |= CPUM_CHANGED_CPUID; 1788 } 1405 1406 return fOld; 1789 1407 } 1790 1408 -
trunk/src/VBox/VMM/VMMAll/EMAll.cpp
r60915 r61776 1274 1274 uint32_t uCR4 = CPUMGetGuestCR4(pVCpu); 1275 1275 1276 if (! CPUMGetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_RDTSCP))1276 if (!pVM->cpum.ro.GuestFeatures.fRdTscP) 1277 1277 { 1278 1278 AssertFailed();
Note:
See TracChangeset
for help on using the changeset viewer.