VirtualBox

Changeset 61776 in vbox for trunk/src/VBox/VMM/VMMAll


Ignore:
Timestamp:
Jun 20, 2016 11:25:06 PM (9 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
108168
Message:

CPUM,APIC: Per-CPU APIC CPUID feature bit and MSR_IA32_APICBASE GP mask adjustments.

  • Changed the PDMAPICHLPR3::pfnChangeFeature to pfnSetFeatureLevel, removing the RC and R0 versions.
  • Only use pfnSetFeatureLevel from the APIC constructor to communicate to CPUM the max APIC feature level, not to globally flip CPUID[1].EDX[9].
  • Renamed APIC enmOriginalMode to enmMaxMode, changing the type of it and the corresponding config values to PDMAPICMODE. This makes the above simpler and eliminates two conversion functions. It also makes APICMODE private to the APIC again.
  • Introduced CPUMSetGuestCpuIdPerCpuApicFeature for the per-CPU APIC feature bit management.
  • Introduced CPUMCPUIDLEAF_F_CONTAINS_APIC which works same as CPUMCPUIDLEAF_F_CONTAINS_OSXSAVE and CPUMCPUIDLEAF_F_CONTAINS_APIC_ID. Updated existing CPU profiles with this.
  • Made the patch manager helper function actually handle CPUMCPUIDLEAF_F_CONTAINS_APIC and CPUMCPUIDLEAF_F_CONTAINS_OSXSAVE (the latter previously relied on CPUMSetGuestCpuIdFeature/CPUMClearGuestCpuIdFeature from CPUMSetGuestCR4).
  • Pushed CPUMSetGuestCpuIdFeature, CPUMGetGuestCpuIdFeature and CPUMClearGuestCpuIdFeature down to ring-3 only (now CPUMR3*). The latter two function are deprecated.
  • Added call to CPUMSetGuestCpuIdPerCpuApicFeature from load function just in case the APIC is disabled by the guest at the time of saving.
  • CPUMSetGuestCpuIdFeature ensures we've got a MSR_IA32_APICBASE register when enabling the APIC.
  • CPUMSetGuestCpuIdFeature adjust the MSR_IA32_APICBASE GP mask when enabling x2APIC so setting MSR_IA32_APICBASE_EXTD does not trap.
Location:
trunk/src/VBox/VMM/VMMAll
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/APICAll.cpp

    r61736 r61776  
    20682068
    20692069    /* Don't allow enabling xAPIC/x2APIC if the VM is configured with the APIC disabled. */
    2070     if (pApic->enmOriginalMode == APICMODE_DISABLED)
     2070    if (pApic->enmMaxMode == PDMAPICMODE_NONE)
    20712071    {
    20722072        LogRel(("APIC%u: Disallowing APIC base MSR write as the VM is configured with APIC disabled!\n",
    2073                pVCpu->idCpu));
     2073                pVCpu->idCpu));
    20742074        return apicMsrAccessError(pVCpu, MSR_IA32_APICBASE, APICMSRACCESS_WRITE_DISALLOWED_CONFIG);
    20752075    }
     
    20782078     * Act on state transition.
    20792079     */
    2080     /** @todo We need to update the CPUID according to the state, which we
    2081      *        currently don't do as CPUMSetGuestCpuIdFeature() is setting
    2082      *        per-VM CPUID bits while we need per-VCPU specific bits. */
    20832080    if (enmNewMode != enmOldMode)
    20842081    {
     
    20992096                APICR3Reset(pVCpu, false /* fResetApicBaseMsr */);
    21002097                uBaseMsr &= ~(MSR_IA32_APICBASE_EN | MSR_IA32_APICBASE_EXTD);
    2101                 CPUMClearGuestCpuIdFeature(pVCpu->CTX_SUFF(pVM), CPUMCPUIDFEATURE_APIC);
     2098                CPUMSetGuestCpuIdPerCpuApicFeature(pVCpu, false /*fVisible*/);
    21022099                LogRel(("APIC%u: Switched mode to disabled\n", pVCpu->idCpu));
    21032100                break;
     
    21132110
    21142111                uBaseMsr |= MSR_IA32_APICBASE_EN;
    2115                 CPUMSetGuestCpuIdFeature(pVCpu->CTX_SUFF(pVM), CPUMCPUIDFEATURE_APIC);
     2112                CPUMSetGuestCpuIdPerCpuApicFeature(pVCpu, true /*fVisible*/);
    21162113                LogRel(("APIC%u: Switched mode to xAPIC\n", pVCpu->idCpu));
    21172114                break;
     
    21202117            case APICMODE_X2APIC:
    21212118            {
    2122                 if (pApic->enmOriginalMode != APICMODE_X2APIC)
     2119                if (pApic->enmMaxMode != PDMAPICMODE_X2APIC)
    21232120                {
    21242121                    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  
    734734VMMDECL(int) CPUMSetGuestCR4(PVMCPU pVCpu, uint64_t cr4)
    735735{
    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. */
    748737
    749738    if (   (cr4                     & (X86_CR4_PGE | X86_CR4_PAE | X86_CR4_PSE))
     
    12881277
    12891278            /*
    1290              * Deal with CPU specific information (currently only APIC ID).
     1279             * Deal with CPU specific information.
    12911280             */
    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 ))
    12931284            {
    12941285                if (uLeaf == 1)
     
    12981289                    AssertMsg((pLeaf->uEbx >> 24) == 0, ("%#x\n", pLeaf->uEbx)); /* raw-mode assumption */
    12991290                    *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;
    13001295
    13011296                    /* ECX: Bit 27: CR4.OSXSAVE mirror. */
     
    13081303                    AssertMsg(pLeaf->uEdx == 0, ("%#x\n", pLeaf->uEdx)); /* raw-mode assumption */
    13091304                    *pEdx = pVCpu->idCpu;
     1305                    Assert(!(pLeaf->fFlags & ~(CPUMCPUIDLEAF_F_CONTAINS_APIC_ID | CPUMCPUIDLEAF_F_INTEL_TOPOLOGY_SUBLEAVES)));
    13101306                }
    13111307                else if (uLeaf == UINT32_C(0x8000001e))
     
    13141310                    AssertMsg(pLeaf->uEax == 0, ("%#x\n", pLeaf->uEax)); /* raw-mode assumption */
    13151311                    *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));
    13161320                }
    13171321                else
     
    13631367
    13641368/**
    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 */
     1377VMM_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)
    13751389    {
    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    }
    14361404#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;
    17891407}
    17901408
  • trunk/src/VBox/VMM/VMMAll/EMAll.cpp

    r60915 r61776  
    12741274    uint32_t uCR4 = CPUMGetGuestCR4(pVCpu);
    12751275
    1276     if (!CPUMGetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_RDTSCP))
     1276    if (!pVM->cpum.ro.GuestFeatures.fRdTscP)
    12771277    {
    12781278        AssertFailed();
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette