VirtualBox

Changeset 54737 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Mar 12, 2015 9:02:21 PM (10 years ago)
Author:
vboxsync
Message:

VMM,REM: CPUID revamp - almost there now.

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

Legend:

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

    r54714 r54737  
    29862986static DECLCALLBACK(VBOXSTRICTRC) cpumMsrRd_AmdK8CpuNameN(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t *puValue)
    29872987{
    2988     PCPUMCPUIDLEAF pLeaf = cpumCpuIdGetLeaf(pVCpu->CTX_SUFF(pVM), pRange->uValue / 2 + 0x80000001, 0);
     2988    PCPUMCPUIDLEAF pLeaf = cpumCpuIdGetLeaf(pVCpu->CTX_SUFF(pVM), pRange->uValue / 2 + 0x80000001);
    29892989    if (pLeaf)
    29902990    {
     
    36363636static DECLCALLBACK(VBOXSTRICTRC) cpumMsrRd_AmdK8CpuIdCtlStd07hEbax(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t *puValue)
    36373637{
    3638     PCPUMCPUIDLEAF pLeaf = cpumCpuIdGetLeaf(pVCpu->CTX_SUFF(pVM), 0x00000007, 0);
     3638    bool           fIgnored;
     3639    PCPUMCPUIDLEAF pLeaf = cpumCpuIdGetLeafEx(pVCpu->CTX_SUFF(pVM), 0x00000007, 0, &fIgnored);
    36393640    if (pLeaf)
    36403641        *puValue = RT_MAKE_U64(pLeaf->uEbx, pLeaf->uEax);
     
    36563657static DECLCALLBACK(VBOXSTRICTRC) cpumMsrRd_AmdK8CpuIdCtlStd06hEcx(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t *puValue)
    36573658{
    3658     PCPUMCPUIDLEAF pLeaf = cpumCpuIdGetLeaf(pVCpu->CTX_SUFF(pVM), 0x00000006, 0);
     3659    PCPUMCPUIDLEAF pLeaf = cpumCpuIdGetLeaf(pVCpu->CTX_SUFF(pVM), 0x00000006);
    36593660    if (pLeaf)
    36603661        *puValue = pLeaf->uEcx;
     
    36763677static DECLCALLBACK(VBOXSTRICTRC) cpumMsrRd_AmdK8CpuIdCtlStd01hEdcx(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t *puValue)
    36773678{
    3678     PCPUMCPUIDLEAF pLeaf = cpumCpuIdGetLeaf(pVCpu->CTX_SUFF(pVM), 0x00000001, 0);
     3679    PCPUMCPUIDLEAF pLeaf = cpumCpuIdGetLeaf(pVCpu->CTX_SUFF(pVM), 0x00000001);
    36793680    if (pLeaf)
    36803681        *puValue = RT_MAKE_U64(pLeaf->uEdx, pLeaf->uEcx);
     
    36963697static DECLCALLBACK(VBOXSTRICTRC) cpumMsrRd_AmdK8CpuIdCtlExt01hEdcx(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t *puValue)
    36973698{
    3698     PCPUMCPUIDLEAF pLeaf = cpumCpuIdGetLeaf(pVCpu->CTX_SUFF(pVM), 0x80000001, 0);
     3699    PCPUMCPUIDLEAF pLeaf = cpumCpuIdGetLeaf(pVCpu->CTX_SUFF(pVM), 0x80000001);
    36993700    if (pLeaf)
    37003701        *puValue = RT_MAKE_U64(pLeaf->uEdx, pLeaf->uEcx);
  • trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp

    r54714 r54737  
    11381138
    11391139/**
     1140 * Looks up a CPUID leaf in the CPUID leaf array, no subleaf.
     1141 *
     1142 * @returns Pointer to the leaf if found, NULL if not.
     1143 *
     1144 * @param   pVM                 Pointer to the cross context VM structure.
     1145 * @param   uLeaf               The leaf to get.
     1146 */
     1147PCPUMCPUIDLEAF cpumCpuIdGetLeaf(PVM pVM, uint32_t uLeaf)
     1148{
     1149    unsigned            iEnd     = pVM->cpum.s.GuestInfo.cCpuIdLeaves;
     1150    if (iEnd)
     1151    {
     1152        unsigned        iStart   = 0;
     1153        PCPUMCPUIDLEAF  paLeaves = pVM->cpum.s.GuestInfo.CTX_SUFF(paCpuIdLeaves);
     1154        for (;;)
     1155        {
     1156            unsigned i = iStart + (iEnd - iStart) / 2U;
     1157            if (uLeaf < paLeaves[i].uLeaf)
     1158            {
     1159                if (i <= iStart)
     1160                    return NULL;
     1161                iEnd = i;
     1162            }
     1163            else if (uLeaf > paLeaves[i].uLeaf)
     1164            {
     1165                i += 1;
     1166                if (i >= iEnd)
     1167                    return NULL;
     1168                iStart = i;
     1169            }
     1170            else
     1171            {
     1172                if (RT_LIKELY(paLeaves[i].fSubLeafMask == 0 && paLeaves[i].uSubLeaf == 0))
     1173                    return &paLeaves[i];
     1174
     1175                /* This shouldn't normally happen. But in case the it does due
     1176                   to user configuration overrids or something, just return the
     1177                   first sub-leaf. */
     1178                AssertMsgFailed(("uLeaf=%#x fSubLeafMask=%#x uSubLeaf=%#x\n",
     1179                                 uLeaf, paLeaves[i].fSubLeafMask, paLeaves[i].uSubLeaf));
     1180                while (   paLeaves[i].uSubLeaf != 0
     1181                       && i > 0
     1182                       && uLeaf == paLeaves[i - 1].uLeaf)
     1183                    i--;
     1184                return &paLeaves[i];
     1185            }
     1186        }
     1187    }
     1188
     1189    return NULL;
     1190}
     1191
     1192
     1193/**
    11401194 * Looks up a CPUID leaf in the CPUID leaf array.
    11411195 *
     
    11461200 * @param   uSubLeaf            The subleaf, if applicable.  Just pass 0 if it
    11471201 *                              isn't.
    1148  */
    1149 PCPUMCPUIDLEAF cpumCpuIdGetLeaf(PVM pVM, uint32_t uLeaf, uint32_t uSubLeaf)
     1202 * @param   pfExactSubLeafHit   Whether we've got an exact subleaf hit or not.
     1203 */
     1204PCPUMCPUIDLEAF cpumCpuIdGetLeafEx(PVM pVM, uint32_t uLeaf, uint32_t uSubLeaf, bool *pfExactSubLeafHit)
    11501205{
    11511206    unsigned            iEnd     = pVM->cpum.s.GuestInfo.cCpuIdLeaves;
     
    11731228            {
    11741229                uSubLeaf &= paLeaves[i].fSubLeafMask;
    1175                 if (uSubLeaf != paLeaves[i].uSubLeaf)
     1230                if (uSubLeaf == paLeaves[i].uSubLeaf)
     1231                    *pfExactSubLeafHit = true;
     1232                else
    11761233                {
    11771234                    /* Find the right subleaf.  We return the last one before
     
    11871244                               && uSubLeaf >= paLeaves[i + 1].uSubLeaf)
    11881245                            i++;
     1246                    *pfExactSubLeafHit = uSubLeaf == paLeaves[i].uSubLeaf;
    11891247                }
    11901248                return &paLeaves[i];
     
    11931251    }
    11941252
     1253    *pfExactSubLeafHit = false;
    11951254    return NULL;
    11961255}
     
    12001259 * Gets a CPUID leaf.
    12011260 *
    1202  * @param   pVCpu   Pointer to the VMCPU.
    1203  * @param   iLeaf   The CPUID leaf to get.
    1204  * @param   pEax    Where to store the EAX value.
    1205  * @param   pEbx    Where to store the EBX value.
    1206  * @param   pEcx    Where to store the ECX value.
    1207  * @param   pEdx    Where to store the EDX value.
    1208  */
    1209 VMMDECL(void) CPUMGetGuestCpuId(PVMCPU pVCpu, uint32_t iLeaf, uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx)
    1210 {
    1211     PVM pVM = pVCpu->CTX_SUFF(pVM);
    1212 
    1213     PCCPUMCPUID pCpuId;
    1214     if (iLeaf < RT_ELEMENTS(pVM->cpum.s.aGuestCpuIdPatmStd))
    1215         pCpuId = &pVM->cpum.s.aGuestCpuIdPatmStd[iLeaf];
    1216     else if (iLeaf - UINT32_C(0x80000000) < RT_ELEMENTS(pVM->cpum.s.aGuestCpuIdPatmExt))
    1217         pCpuId = &pVM->cpum.s.aGuestCpuIdPatmExt[iLeaf - UINT32_C(0x80000000)];
    1218     else if (   iLeaf - UINT32_C(0x40000000) < 0x100   /** @todo Fix this later: Hyper-V says 0x400000FF is the last valid leaf. */
    1219              && (pVCpu->CTX_SUFF(pVM)->cpum.s.aGuestCpuIdPatmStd[1].uEcx & X86_CPUID_FEATURE_ECX_HVP)) /* Only report if HVP bit set. */
     1261 * @param   pVCpu       Pointer to the VMCPU.
     1262 * @param   uLeaf       The CPUID leaf to get.
     1263 * @param   uSubLeaf    The CPUID sub-leaf to get, if applicable.
     1264 * @param   pEax        Where to store the EAX value.
     1265 * @param   pEbx        Where to store the EBX value.
     1266 * @param   pEcx        Where to store the ECX value.
     1267 * @param   pEdx        Where to store the EDX value.
     1268 */
     1269VMMDECL(void) CPUMGetGuestCpuId(PVMCPU pVCpu, uint32_t uLeaf, uint32_t uSubLeaf,
     1270                                uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx)
     1271{
     1272    bool           fExactSubLeafHit;
     1273    PVM            pVM   = pVCpu->CTX_SUFF(pVM);
     1274    PCPUMCPUIDLEAF pLeaf = cpumCpuIdGetLeafEx(pVM, uLeaf, uSubLeaf, &fExactSubLeafHit);
     1275    if (pLeaf)
    12201276    {
    1221         PCPUMCPUIDLEAF pHyperLeaf = cpumCpuIdGetLeaf(pVM, iLeaf, 0 /* uSubLeaf */);
    1222         if (RT_LIKELY(pHyperLeaf))
     1277        if (fExactSubLeafHit)
    12231278        {
    1224             *pEax = pHyperLeaf->uEax;
    1225             *pEbx = pHyperLeaf->uEbx;
    1226             *pEcx = pHyperLeaf->uEcx;
    1227             *pEdx = pHyperLeaf->uEdx;
     1279            *pEax = pLeaf->uEax;
     1280            *pEbx = pLeaf->uEbx;
     1281            *pEcx = pLeaf->uEcx;
     1282            *pEdx = pLeaf->uEdx;
     1283
     1284            /*
     1285             * Deal with CPU specific information (currently only APIC ID).
     1286             */
     1287            if (pLeaf->fFlags & CPUMCPUIDLEAF_F_CONTAINS_APIC_ID)
     1288            {
     1289                if (uLeaf == 1)
     1290                {
     1291                    /* Bits 31-24: Initial APIC ID */
     1292                    Assert(pVCpu->idCpu <= 255);
     1293                    Assert((*pEbx >> 24) == 0); /* raw-mode assumption */
     1294                    *pEbx = (*pEbx & UINT32_C(0x00ffffff)) | (pVCpu->idCpu << 24);
     1295                }
     1296                else if (uLeaf == 0xb)
     1297                {
     1298                    /* EDX: Initial extended APIC ID. */
     1299                    Assert(*pEdx == 0); /* raw-mode assumption */
     1300                    *pEdx = pVCpu->idCpu;
     1301                }
     1302                else if (uLeaf == UINT32_C(0x8000001e))
     1303                {
     1304                    /* EAX: Initial extended APIC ID. */
     1305                    Assert(*pEax == 0); /* raw-mode assumption */
     1306                    *pEax = pVCpu->idCpu;
     1307                }
     1308                else
     1309                    AssertMsgFailed(("uLeaf=%#x\n", uLeaf));
     1310            }
    12281311        }
     1312        /*
     1313         * Out of range sub-leaves aren't quite as easy and pretty as we emulate
     1314         * them here, but we do the best we can here...
     1315         */
    12291316        else
    12301317        {
    12311318            *pEax = *pEbx = *pEcx = *pEdx = 0;
     1319            if (pLeaf->fFlags & CPUMCPUIDLEAF_F_INTEL_TOPOLOGY_SUBLEAVES)
     1320            {
     1321                *pEcx = uSubLeaf & 0xff;
     1322                *pEdx = pVCpu->idCpu;
     1323            }
    12321324        }
    1233         return;
    12341325    }
    1235     else if (iLeaf - UINT32_C(0xc0000000) < RT_ELEMENTS(pVM->cpum.s.aGuestCpuIdPatmCentaur))
    1236         pCpuId = &pVM->cpum.s.aGuestCpuIdPatmCentaur[iLeaf - UINT32_C(0xc0000000)];
    12371326    else
    1238         pCpuId = &pVM->cpum.s.GuestCpuIdPatmDef;
    1239 
    1240     uint32_t cCurrentCacheIndex = *pEcx;
    1241 
    1242     *pEax = pCpuId->uEax;
    1243     *pEbx = pCpuId->uEbx;
    1244     *pEcx = pCpuId->uEcx;
    1245     *pEdx = pCpuId->uEdx;
    1246 
    1247     if (    iLeaf == 1)
    12481327    {
    1249         /* Bits 31-24: Initial APIC ID */
    1250         Assert(pVCpu->idCpu <= 255);
    1251         *pEbx |= (pVCpu->idCpu << 24);
    1252    }
    1253 
    1254     if (    iLeaf == 4
    1255         &&  cCurrentCacheIndex < 3
    1256         &&  pVM->cpum.s.GuestFeatures.enmCpuVendor == CPUMCPUVENDOR_INTEL)
    1257     {
    1258         uint32_t type, level, sharing, linesize,
    1259                  partitions, associativity, sets, cores;
    1260 
    1261         /* For type: 1 - data cache, 2 - i-cache, 3 - unified */
    1262         partitions = 1;
    1263         /* Those are only to shut up compiler, as they will always
    1264            get overwritten, and compiler should be able to figure that out */
    1265         sets = associativity = sharing = level = 1;
    1266         cores = pVM->cCpus > 32 ? 32 : pVM->cCpus;
    1267         switch (cCurrentCacheIndex)
     1328        /*
     1329         * Different CPUs have different ways of dealing with unknown CPUID leaves.
     1330         */
     1331        switch (pVM->cpum.s.GuestInfo.enmUnknownCpuIdMethod)
    12681332        {
    1269             case 0:
    1270                 type = 1;
    1271                 level = 1;
    1272                 sharing = 1;
    1273                 linesize = 64;
    1274                 associativity = 8;
    1275                 sets = 64;
     1333            default:
     1334                AssertFailed();
     1335            case CPUMUNKNOWNCPUID_DEFAULTS:
     1336            case CPUMUNKNOWNCPUID_LAST_STD_LEAF: /* ASSUME this is executed */
     1337            case CPUMUNKNOWNCPUID_LAST_STD_LEAF_WITH_ECX: /** @todo Implement CPUMUNKNOWNCPUID_LAST_STD_LEAF_WITH_ECX */
     1338                *pEax = pVM->cpum.s.GuestInfo.DefCpuId.uEax;
     1339                *pEbx = pVM->cpum.s.GuestInfo.DefCpuId.uEbx;
     1340                *pEcx = pVM->cpum.s.GuestInfo.DefCpuId.uEcx;
     1341                *pEdx = pVM->cpum.s.GuestInfo.DefCpuId.uEdx;
    12761342                break;
    1277             case 1:
    1278                 level = 1;
    1279                 type = 2;
    1280                 sharing = 1;
    1281                 linesize = 64;
    1282                 associativity = 8;
    1283                 sets = 64;
    1284                 break;
    1285             default:            /* shut up gcc.*/
    1286                 AssertFailed();
    1287             case 2:
    1288                 level = 2;
    1289                 type = 3;
    1290                 sharing = cores; /* our L2 cache is modelled as shared between all cores */
    1291                 linesize = 64;
    1292                 associativity = 24;
    1293                 sets = 4096;
     1343            case CPUMUNKNOWNCPUID_PASSTHRU:
     1344                *pEax = uLeaf;
     1345                *pEbx = 0;
     1346                *pEcx = uSubLeaf;
     1347                *pEdx = 0;
    12941348                break;
    12951349        }
    1296 
    1297         NOREF(type);
    1298         *pEax |= ((cores - 1) << 26)        |
    1299                  ((sharing - 1) << 14)      |
    1300                  (level << 5)               |
    1301                  1;
    1302         *pEbx = (linesize - 1)               |
    1303                 ((partitions - 1) << 12)     |
    1304                 ((associativity - 1) << 22); /* -1 encoding */
    1305         *pEcx = sets - 1;
    13061350    }
    1307 
    1308     Log2(("CPUMGetGuestCpuId: iLeaf=%#010x %RX32 %RX32 %RX32 %RX32\n", iLeaf, *pEax, *pEbx, *pEcx, *pEdx));
     1351    Log2(("CPUMGetGuestCpuId: uLeaf=%#010x/%#010x %RX32 %RX32 %RX32 %RX32\n", uLeaf, uSubLeaf, *pEax, *pEbx, *pEcx, *pEdx));
    13091352}
    13101353
     
    13261369         */
    13271370        case CPUMCPUIDFEATURE_APIC:
    1328             pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000001), 0);
     1371            pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000001));
    13291372            if (pLeaf)
    13301373                pVM->cpum.s.aGuestCpuIdPatmStd[1].uEdx = pLeaf->uEdx |= X86_CPUID_FEATURE_EDX_APIC;
    13311374
    1332             pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001), 0);
     1375            pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001));
    13331376            if (   pLeaf
    13341377                && pVM->cpum.s.GuestFeatures.enmCpuVendor == CPUMCPUVENDOR_AMD)
     
    13431386        */
    13441387        case CPUMCPUIDFEATURE_X2APIC:
    1345             pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000001), 0);
     1388            pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000001));
    13461389            if (pLeaf)
    13471390                pVM->cpum.s.aGuestCpuIdPatmStd[1].uEcx = pLeaf->uEcx |= X86_CPUID_FEATURE_ECX_X2APIC;
     
    13611404            }
    13621405
    1363             pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000001), 0);
     1406            pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000001));
    13641407            if (pLeaf)
    13651408                pVM->cpum.s.aGuestCpuIdPatmStd[1].uEdx = pLeaf->uEdx |= X86_CPUID_FEATURE_EDX_SEP;
     
    13731416         */
    13741417        case CPUMCPUIDFEATURE_SYSCALL:
    1375             pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001), 0);
     1418            pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001));
    13761419            if (   !pLeaf
    13771420                || !pVM->cpum.s.HostFeatures.fSysCall)
     
    14061449            }
    14071450
    1408             pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000001), 0);
     1451            pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000001));
    14091452            if (pLeaf)
    14101453                pVM->cpum.s.aGuestCpuIdPatmStd[1].uEdx = pLeaf->uEdx |= X86_CPUID_FEATURE_EDX_PAE;
    14111454
    1412             pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001), 0);
     1455            pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001));
    14131456            if (    pLeaf
    14141457                &&  pVM->cpum.s.GuestFeatures.enmCpuVendor == CPUMCPUVENDOR_AMD)
     
    14241467         */
    14251468        case CPUMCPUIDFEATURE_LONG_MODE:
    1426             pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001), 0);
     1469            pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001));
    14271470            if (   !pLeaf
    14281471                || !pVM->cpum.s.HostFeatures.fLongMode)
     
    14431486         */
    14441487        case CPUMCPUIDFEATURE_NX:
    1445             pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001), 0);
     1488            pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001));
    14461489            if (   !pLeaf
    14471490                || !pVM->cpum.s.HostFeatures.fNoExecute)
     
    14631506         */
    14641507        case CPUMCPUIDFEATURE_LAHF:
    1465             pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001), 0);
     1508            pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001));
    14661509            if (   !pLeaf
    14671510                || !pVM->cpum.s.HostFeatures.fLahfSahf)
     
    14831526         */
    14841527        case CPUMCPUIDFEATURE_PAT:
    1485             pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000001), 0);
     1528            pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000001));
    14861529            if (pLeaf)
    14871530                pVM->cpum.s.aGuestCpuIdPatmStd[1].uEdx = pLeaf->uEdx |= X86_CPUID_FEATURE_EDX_PAT;
    14881531
    1489             pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001), 0);
     1532            pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001));
    14901533            if (   pLeaf
    14911534                && pVM->cpum.s.GuestFeatures.enmCpuVendor == CPUMCPUVENDOR_AMD)
     
    15011544         */
    15021545        case CPUMCPUIDFEATURE_RDTSCP:
    1503             pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001), 0);
     1546            pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001));
    15041547            if (   !pLeaf
    15051548                || !pVM->cpum.s.HostFeatures.fRdTscP
     
    15211564        */
    15221565        case CPUMCPUIDFEATURE_HVP:
    1523             pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000001), 0);
     1566            pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000001));
    15241567            if (pLeaf)
    15251568                pVM->cpum.s.aGuestCpuIdPatmStd[1].uEcx = pLeaf->uEcx |= X86_CPUID_FEATURE_ECX_HVP;
     
    15331576         */
    15341577        case CPUMCPUIDFEATURE_MWAIT_EXTS:
    1535             pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000005), 0);
     1578            pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000005));
    15361579            if (   !pLeaf
    15371580                || !pVM->cpum.s.HostFeatures.fMWaitExtensions)
     
    16051648    {
    16061649        case CPUMCPUIDFEATURE_APIC:
    1607             pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000001), 0);
     1650            pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000001));
    16081651            if (pLeaf)
    16091652                pVM->cpum.s.aGuestCpuIdPatmStd[1].uEdx = pLeaf->uEdx &= ~X86_CPUID_FEATURE_EDX_APIC;
    16101653
    1611             pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001), 0);
     1654            pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001));
    16121655            if (   pLeaf
    16131656                && pVM->cpum.s.GuestFeatures.enmCpuVendor == CPUMCPUVENDOR_AMD)
     
    16191662
    16201663        case CPUMCPUIDFEATURE_X2APIC:
    1621             pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000001), 0);
     1664            pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000001));
    16221665            if (pLeaf)
    16231666                pVM->cpum.s.aGuestCpuIdPatmStd[1].uEcx = pLeaf->uEcx &= ~X86_CPUID_FEATURE_ECX_X2APIC;
     
    16271670
    16281671        case CPUMCPUIDFEATURE_PAE:
    1629             pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000001), 0);
     1672            pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000001));
    16301673            if (pLeaf)
    16311674                pVM->cpum.s.aGuestCpuIdPatmStd[1].uEdx = pLeaf->uEdx &= ~X86_CPUID_FEATURE_EDX_PAE;
    16321675
    1633             pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001), 0);
     1676            pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001));
    16341677            if (   pLeaf
    16351678                && pVM->cpum.s.GuestFeatures.enmCpuVendor == CPUMCPUVENDOR_AMD)
     
    16411684
    16421685        case CPUMCPUIDFEATURE_PAT:
    1643             pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000001), 0);
     1686            pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000001));
    16441687            if (pLeaf)
    16451688                pVM->cpum.s.aGuestCpuIdPatmStd[1].uEdx = pLeaf->uEdx &= ~X86_CPUID_FEATURE_EDX_PAT;
    16461689
    1647             pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001), 0);
     1690            pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001));
    16481691            if (   pLeaf
    16491692                && pVM->cpum.s.GuestFeatures.enmCpuVendor == CPUMCPUVENDOR_AMD)
     
    16551698
    16561699        case CPUMCPUIDFEATURE_LONG_MODE:
    1657             pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001), 0);
     1700            pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001));
    16581701            if (pLeaf)
    16591702                pVM->cpum.s.aGuestCpuIdPatmExt[1].uEdx = pLeaf->uEdx &= ~X86_CPUID_EXT_FEATURE_EDX_LONG_MODE;
     
    16621705
    16631706        case CPUMCPUIDFEATURE_LAHF:
    1664             pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001), 0);
     1707            pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001));
    16651708            if (pLeaf)
    16661709                pVM->cpum.s.aGuestCpuIdPatmExt[1].uEcx = pLeaf->uEcx &= ~X86_CPUID_EXT_FEATURE_ECX_LAHF_SAHF;
     
    16691712
    16701713        case CPUMCPUIDFEATURE_RDTSCP:
    1671             pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001), 0);
     1714            pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x80000001));
    16721715            if (pLeaf)
    16731716                pVM->cpum.s.aGuestCpuIdPatmExt[1].uEdx = pLeaf->uEdx &= ~X86_CPUID_EXT_FEATURE_EDX_RDTSCP;
     
    16771720
    16781721        case CPUMCPUIDFEATURE_HVP:
    1679             pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000001), 0);
     1722            pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000001));
    16801723            if (pLeaf)
    16811724                pVM->cpum.s.aGuestCpuIdPatmStd[1].uEcx = pLeaf->uEcx &= ~X86_CPUID_FEATURE_ECX_HVP;
     
    16841727
    16851728        case CPUMCPUIDFEATURE_MWAIT_EXTS:
    1686             pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000005), 0);
     1729            pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000005));
    16871730            if (pLeaf)
    16881731                pVM->cpum.s.aGuestCpuIdPatmStd[5].uEcx = pLeaf->uEcx &= ~(X86_CPUID_MWAIT_ECX_EXT | X86_CPUID_MWAIT_ECX_BREAKIRQIF0);
  • trunk/src/VBox/VMM/VMMAll/EMAll.cpp

    r53466 r54737  
    12141214{
    12151215    Assert(pRegFrame == CPUMGetGuestCtxCore(pVCpu));
    1216     uint32_t iLeaf = pRegFrame->eax;
     1216    uint32_t iLeaf    = pRegFrame->eax;
     1217    uint32_t iSubLeaf = pRegFrame->ecx;
    12171218    NOREF(pVM);
    12181219
     
    12201221    pRegFrame->rax = 0;
    12211222    pRegFrame->rbx = 0;
    1222     pRegFrame->rcx &= UINT64_C(0x00000000ffffffff);
     1223    pRegFrame->rcx = 0;
    12231224    pRegFrame->rdx = 0;
    12241225
    12251226    /* Note: operates the same in 64 and non-64 bits mode. */
    1226     CPUMGetGuestCpuId(pVCpu, iLeaf, &pRegFrame->eax, &pRegFrame->ebx, &pRegFrame->ecx, &pRegFrame->edx);
     1227    CPUMGetGuestCpuId(pVCpu, iLeaf, iSubLeaf, &pRegFrame->eax, &pRegFrame->ebx, &pRegFrame->ecx, &pRegFrame->edx);
    12271228    Log(("Emulate: CPUID %x -> %08x %08x %08x %08x\n", iLeaf, pRegFrame->eax, pRegFrame->ebx, pRegFrame->ecx, pRegFrame->edx));
    12281229    return VINF_SUCCESS;
     
    13451346        return VERR_EM_INTERPRETER; /* supervisor only */
    13461347
    1347     CPUMGetGuestCpuId(pVCpu, 1, &u32Dummy, &u32Dummy, &u32ExtFeatures, &u32Dummy);
     1348    CPUMGetGuestCpuId(pVCpu, 1, 0, &u32Dummy, &u32Dummy, &u32ExtFeatures, &u32Dummy);
    13481349    if (!(u32ExtFeatures & X86_CPUID_FEATURE_ECX_MONITOR))
    13491350        return VERR_EM_INTERPRETER; /* not supported */
     
    13531354     * CPUID.05H.ECX[1] defines support for interrupts as break events for mwait even when IF=0
    13541355     */
    1355     CPUMGetGuestCpuId(pVCpu, 5, &u32Dummy, &u32Dummy, &u32MWaitFeatures, &u32Dummy);
     1356    CPUMGetGuestCpuId(pVCpu, 5, 0, &u32Dummy, &u32Dummy, &u32MWaitFeatures, &u32Dummy);
    13561357    if (pRegFrame->ecx > 1)
    13571358    {
     
    13901391        return VERR_EM_INTERPRETER; /* supervisor only */
    13911392
    1392     CPUMGetGuestCpuId(pVCpu, 1, &u32Dummy, &u32Dummy, &u32ExtFeatures, &u32Dummy);
     1393    CPUMGetGuestCpuId(pVCpu, 1, 0, &u32Dummy, &u32Dummy, &u32ExtFeatures, &u32Dummy);
    13931394    if (!(u32ExtFeatures & X86_CPUID_FEATURE_ECX_MONITOR))
    13941395        return VERR_EM_INTERPRETER; /* not supported */
  • trunk/src/VBox/VMM/VMMAll/IEMAll.cpp

    r53466 r54737  
    51435143{
    51445144    uint32_t uEax, uEbx, uEcx, uEdx;
    5145     CPUMGetGuestCpuId(IEMCPU_TO_VMCPU(pIemCpu), 0x00000001, &uEax, &uEbx, &uEcx, &uEdx);
     5145    CPUMGetGuestCpuId(IEMCPU_TO_VMCPU(pIemCpu), 0x00000001, 0, &uEax, &uEbx, &uEcx, &uEdx);
    51465146    return (fEcx && (uEcx & fEcx))
    51475147        || (fEdx && (uEdx & fEdx));
     
    51635163{
    51645164    uint32_t uEax, uEbx, uEcx, uEdx;
    5165     CPUMGetGuestCpuId(IEMCPU_TO_VMCPU(pIemCpu), 0x80000001, &uEax, &uEbx, &uEcx, &uEdx);
     5165    CPUMGetGuestCpuId(IEMCPU_TO_VMCPU(pIemCpu), 0x80000001, 0, &uEax, &uEbx, &uEcx, &uEdx);
    51665166    return (fEcx && (uEcx & fEcx))
    51675167        || (fEdx && (uEdx & fEdx));
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h

    r54203 r54737  
    57995799        uint32_t fMWaitFeatures = 0;
    58005800        uint32_t uIgnore = 0;
    5801         CPUMGetGuestCpuId(IEMCPU_TO_VMCPU(pIemCpu), 5, &uIgnore, &uIgnore, &fMWaitFeatures, &uIgnore);
     5801        CPUMGetGuestCpuId(IEMCPU_TO_VMCPU(pIemCpu), 5, 0, &uIgnore, &uIgnore, &fMWaitFeatures, &uIgnore);
    58025802        if (    (fMWaitFeatures & (X86_CPUID_MWAIT_ECX_EXT | X86_CPUID_MWAIT_ECX_BREAKIRQIF0))
    58035803            !=                    (X86_CPUID_MWAIT_ECX_EXT | X86_CPUID_MWAIT_ECX_BREAKIRQIF0))
     
    58545854    PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
    58555855
    5856     CPUMGetGuestCpuId(IEMCPU_TO_VMCPU(pIemCpu), pCtx->eax, &pCtx->eax, &pCtx->ebx, &pCtx->ecx, &pCtx->edx);
     5856    CPUMGetGuestCpuId(IEMCPU_TO_VMCPU(pIemCpu), pCtx->eax, pCtx->ecx, &pCtx->eax, &pCtx->ebx, &pCtx->ecx, &pCtx->edx);
    58575857    pCtx->rax &= UINT32_C(0xffffffff);
    58585858    pCtx->rbx &= UINT32_C(0xffffffff);
  • trunk/src/VBox/VMM/VMMR0/CPUMR0.cpp

    r54714 r54737  
    286286        for (uint32_t i = 0; i < RT_ELEMENTS(g_aCpuidUnifyBits); i++)
    287287        {
     288            bool            fIgnored;
    288289            uint32_t        uLeaf = g_aCpuidUnifyBits[i].uLeaf;
    289             PCPUMCPUIDLEAF  pLeaf = cpumCpuIdGetLeaf(pVM, uLeaf, 0);
     290            PCPUMCPUIDLEAF  pLeaf = cpumCpuIdGetLeafEx(pVM, uLeaf, 0, &fIgnored);
    290291            if (pLeaf)
    291292            {
  • trunk/src/VBox/VMM/VMMR3/CFGM.cpp

    r53574 r54737  
    893893    {
    894894        /*
    895          * Enumerate the leafs and check them against pszValidValues.
     895         * Enumerate the leaves and check them against pszValidValues.
    896896         */
    897897        for (PCFGMLEAF pLeaf = pNode->pFirstLeaf; pLeaf; pLeaf = pLeaf->pNext)
     
    14701470    /*
    14711471     * Use CFGMR3InsertNode to create a new node and then
    1472      * re-attach the children and leafs of the subtree to it.
     1472     * re-attach the children and leaves of the subtree to it.
    14731473     */
    14741474    PCFGMNODE pNewChild;
     
    19401940
    19411941        /*
    1942          * Free leafs.
     1942         * Free leaves.
    19431943         */
    19441944        while (pNode->pFirstLeaf)
  • trunk/src/VBox/VMM/VMMR3/CPUM.cpp

    r54714 r54737  
    106106static DECLCALLBACK(void) cpumR3InfoHyper(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs);
    107107static DECLCALLBACK(void) cpumR3InfoHost(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs);
    108 static DECLCALLBACK(void) cpumR3CpuIdInfo(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs);
    109108
    110109
     
    677676
    678677    /*
    679      * Initialize the Guest CPUID state.
    680      */
    681     rc = cpumR3CpuIdInit(pVM);
     678     * Initialize the Guest CPUID and MSR states.
     679     */
     680    rc = cpumR3InitCpuIdAndMsrs(pVM);
    682681    if (RT_FAILURE(rc))
    683682        return rc;
     
    718717{
    719718    /*
    720      * Workaround for missing cpuid(0) patches when leaf 4 returns GuestCpuIdPatmDef:
     719     * Workaround for missing cpuid(0) patches when leaf 4 returns GuestInfo.DefCpuId:
    721720     * If we miss to patch a cpuid(0).eax then Linux tries to determine the number
    722721     * of processors from (cpuid(4).eax >> 26) + 1.
     
    997996     */
    998997    if (    uVersion != CPUM_SAVED_STATE_VERSION
     998        &&  uVersion != CPUM_SAVED_STATE_VERSION_PUT_STRUCT
    999999        &&  uVersion != CPUM_SAVED_STATE_VERSION_MEM
    10001000        &&  uVersion != CPUM_SAVED_STATE_VERSION_NO_MSR_SIZE
     
    11801180    SSMR3GetMem(pSSM, &pVM->cpum.s.aGuestCpuIdPatmCentaur[0], sizeof(pVM->cpum.s.aGuestCpuIdPatmCentaur));
    11811181
    1182     SSMR3GetMem(pSSM, &pVM->cpum.s.GuestCpuIdPatmDef, sizeof(pVM->cpum.s.GuestCpuIdPatmDef));
     1182    SSMR3GetMem(pSSM, &pVM->cpum.s.GuestInfo.DefCpuId, sizeof(pVM->cpum.s.GuestInfo.DefCpuId));
    11831183
    11841184    /*
     
    18001800}
    18011801
    1802 
    1803 /**
    1804  * Get L1 cache / TLS associativity.
    1805  */
    1806 static const char *getCacheAss(unsigned u, char *pszBuf)
    1807 {
    1808     if (u == 0)
    1809         return "res0  ";
    1810     if (u == 1)
    1811         return "direct";
    1812     if (u == 255)
    1813         return "fully";
    1814     if (u >= 256)
    1815         return "???";
    1816 
    1817     RTStrPrintf(pszBuf, 16, "%d way", u);
    1818     return pszBuf;
    1819 }
    1820 
    1821 
    1822 /**
    1823  * Get L2 cache associativity.
    1824  */
    1825 const char *getL2CacheAss(unsigned u)
    1826 {
    1827     switch (u)
    1828     {
    1829         case 0:  return "off   ";
    1830         case 1:  return "direct";
    1831         case 2:  return "2 way ";
    1832         case 3:  return "res3  ";
    1833         case 4:  return "4 way ";
    1834         case 5:  return "res5  ";
    1835         case 6:  return "8 way ";
    1836         case 7:  return "res7  ";
    1837         case 8:  return "16 way";
    1838         case 9:  return "res9  ";
    1839         case 10: return "res10 ";
    1840         case 11: return "res11 ";
    1841         case 12: return "res12 ";
    1842         case 13: return "res13 ";
    1843         case 14: return "res14 ";
    1844         case 15: return "fully ";
    1845         default: return "????";
    1846     }
    1847 }
    1848 
    1849 
    1850 /**
    1851  * Display the guest CpuId leaves.
    1852  *
    1853  * @param   pVM         Pointer to the VM.
    1854  * @param   pHlp        The info helper functions.
    1855  * @param   pszArgs     "terse", "default" or "verbose".
    1856  */
    1857 static DECLCALLBACK(void) cpumR3CpuIdInfo(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs)
    1858 {
    1859     /*
    1860      * Parse the argument.
    1861      */
    1862     unsigned iVerbosity = 1;
    1863     if (pszArgs)
    1864     {
    1865         pszArgs = RTStrStripL(pszArgs);
    1866         if (!strcmp(pszArgs, "terse"))
    1867             iVerbosity--;
    1868         else if (!strcmp(pszArgs, "verbose"))
    1869             iVerbosity++;
    1870     }
    1871 
    1872     /*
    1873      * Start cracking.
    1874      */
    1875     CPUMCPUID   Host;
    1876     CPUMCPUID   Guest;
    1877     unsigned    cStdMax = pVM->cpum.s.aGuestCpuIdPatmStd[0].uEax;
    1878 
    1879     uint32_t    cStdHstMax;
    1880     uint32_t    dummy;
    1881     ASMCpuIdExSlow(0, 0, 0, 0, &cStdHstMax, &dummy, &dummy, &dummy);
    1882 
    1883     unsigned    cStdLstMax = RT_MAX(RT_ELEMENTS(pVM->cpum.s.aGuestCpuIdPatmStd), cStdHstMax);
    1884 
    1885     pHlp->pfnPrintf(pHlp,
    1886                     "         RAW Standard CPUIDs\n"
    1887                     "     Function  eax      ebx      ecx      edx\n");
    1888     for (unsigned i = 0; i <= cStdLstMax ; i++)
    1889     {
    1890         if (i < RT_ELEMENTS(pVM->cpum.s.aGuestCpuIdPatmStd))
    1891         {
    1892             Guest = pVM->cpum.s.aGuestCpuIdPatmStd[i];
    1893             ASMCpuIdExSlow(i, 0, 0, 0, &Host.uEax, &Host.uEbx, &Host.uEcx, &Host.uEdx);
    1894 
    1895             pHlp->pfnPrintf(pHlp,
    1896                             "Gst: %08x  %08x %08x %08x %08x%s\n"
    1897                             "Hst:           %08x %08x %08x %08x\n",
    1898                             i, Guest.uEax, Guest.uEbx, Guest.uEcx, Guest.uEdx,
    1899                             i <= cStdMax ? "" : "*",
    1900                             Host.uEax, Host.uEbx, Host.uEcx, Host.uEdx);
    1901         }
    1902         else
    1903         {
    1904             ASMCpuIdExSlow(i, 0, 0, 0, &Host.uEax, &Host.uEbx, &Host.uEcx, &Host.uEdx);
    1905 
    1906             pHlp->pfnPrintf(pHlp,
    1907                             "Hst: %08x  %08x %08x %08x %08x\n",
    1908                             i, Host.uEax, Host.uEbx, Host.uEcx, Host.uEdx);
    1909         }
    1910     }
    1911 
    1912     /*
    1913      * If verbose, decode it.
    1914      */
    1915     if (iVerbosity)
    1916     {
    1917         Guest = pVM->cpum.s.aGuestCpuIdPatmStd[0];
    1918         pHlp->pfnPrintf(pHlp,
    1919                         "Name:                            %.04s%.04s%.04s\n"
    1920                         "Supports:                        0-%x\n",
    1921                         &Guest.uEbx, &Guest.uEdx, &Guest.uEcx, Guest.uEax);
    1922     }
    1923 
    1924     /*
    1925      * Get Features.
    1926      */
    1927     bool const fIntel = ASMIsIntelCpuEx(pVM->cpum.s.aGuestCpuIdPatmStd[0].uEbx,
    1928                                         pVM->cpum.s.aGuestCpuIdPatmStd[0].uEcx,
    1929                                         pVM->cpum.s.aGuestCpuIdPatmStd[0].uEdx);
    1930     if (cStdMax >= 1 && iVerbosity)
    1931     {
    1932         static const char * const s_apszTypes[4] = { "primary", "overdrive", "MP", "reserved" };
    1933 
    1934         Guest = pVM->cpum.s.aGuestCpuIdPatmStd[1];
    1935         uint32_t uEAX = Guest.uEax;
    1936 
    1937         pHlp->pfnPrintf(pHlp,
    1938                         "Family:                          %d  \tExtended: %d \tEffective: %d\n"
    1939                         "Model:                           %d  \tExtended: %d \tEffective: %d\n"
    1940                         "Stepping:                        %d\n"
    1941                         "Type:                            %d (%s)\n"
    1942                         "APIC ID:                         %#04x\n"
    1943                         "Logical CPUs:                    %d\n"
    1944                         "CLFLUSH Size:                    %d\n"
    1945                         "Brand ID:                        %#04x\n",
    1946                         (uEAX >> 8) & 0xf, (uEAX >> 20) & 0x7f, ASMGetCpuFamily(uEAX),
    1947                         (uEAX >> 4) & 0xf, (uEAX >> 16) & 0x0f, ASMGetCpuModel(uEAX, fIntel),
    1948                         ASMGetCpuStepping(uEAX),
    1949                         (uEAX >> 12) & 3, s_apszTypes[(uEAX >> 12) & 3],
    1950                         (Guest.uEbx >> 24) & 0xff,
    1951                         (Guest.uEbx >> 16) & 0xff,
    1952                         (Guest.uEbx >>  8) & 0xff,
    1953                         (Guest.uEbx >>  0) & 0xff);
    1954         if (iVerbosity == 1)
    1955         {
    1956             uint32_t uEDX = Guest.uEdx;
    1957             pHlp->pfnPrintf(pHlp, "Features EDX:                   ");
    1958             if (uEDX & RT_BIT(0))   pHlp->pfnPrintf(pHlp, " FPU");
    1959             if (uEDX & RT_BIT(1))   pHlp->pfnPrintf(pHlp, " VME");
    1960             if (uEDX & RT_BIT(2))   pHlp->pfnPrintf(pHlp, " DE");
    1961             if (uEDX & RT_BIT(3))   pHlp->pfnPrintf(pHlp, " PSE");
    1962             if (uEDX & RT_BIT(4))   pHlp->pfnPrintf(pHlp, " TSC");
    1963             if (uEDX & RT_BIT(5))   pHlp->pfnPrintf(pHlp, " MSR");
    1964             if (uEDX & RT_BIT(6))   pHlp->pfnPrintf(pHlp, " PAE");
    1965             if (uEDX & RT_BIT(7))   pHlp->pfnPrintf(pHlp, " MCE");
    1966             if (uEDX & RT_BIT(8))   pHlp->pfnPrintf(pHlp, " CX8");
    1967             if (uEDX & RT_BIT(9))   pHlp->pfnPrintf(pHlp, " APIC");
    1968             if (uEDX & RT_BIT(10))  pHlp->pfnPrintf(pHlp, " 10");
    1969             if (uEDX & RT_BIT(11))  pHlp->pfnPrintf(pHlp, " SEP");
    1970             if (uEDX & RT_BIT(12))  pHlp->pfnPrintf(pHlp, " MTRR");
    1971             if (uEDX & RT_BIT(13))  pHlp->pfnPrintf(pHlp, " PGE");
    1972             if (uEDX & RT_BIT(14))  pHlp->pfnPrintf(pHlp, " MCA");
    1973             if (uEDX & RT_BIT(15))  pHlp->pfnPrintf(pHlp, " CMOV");
    1974             if (uEDX & RT_BIT(16))  pHlp->pfnPrintf(pHlp, " PAT");
    1975             if (uEDX & RT_BIT(17))  pHlp->pfnPrintf(pHlp, " PSE36");
    1976             if (uEDX & RT_BIT(18))  pHlp->pfnPrintf(pHlp, " PSN");
    1977             if (uEDX & RT_BIT(19))  pHlp->pfnPrintf(pHlp, " CLFSH");
    1978             if (uEDX & RT_BIT(20))  pHlp->pfnPrintf(pHlp, " 20");
    1979             if (uEDX & RT_BIT(21))  pHlp->pfnPrintf(pHlp, " DS");
    1980             if (uEDX & RT_BIT(22))  pHlp->pfnPrintf(pHlp, " ACPI");
    1981             if (uEDX & RT_BIT(23))  pHlp->pfnPrintf(pHlp, " MMX");
    1982             if (uEDX & RT_BIT(24))  pHlp->pfnPrintf(pHlp, " FXSR");
    1983             if (uEDX & RT_BIT(25))  pHlp->pfnPrintf(pHlp, " SSE");
    1984             if (uEDX & RT_BIT(26))  pHlp->pfnPrintf(pHlp, " SSE2");
    1985             if (uEDX & RT_BIT(27))  pHlp->pfnPrintf(pHlp, " SS");
    1986             if (uEDX & RT_BIT(28))  pHlp->pfnPrintf(pHlp, " HTT");
    1987             if (uEDX & RT_BIT(29))  pHlp->pfnPrintf(pHlp, " TM");
    1988             if (uEDX & RT_BIT(30))  pHlp->pfnPrintf(pHlp, " 30");
    1989             if (uEDX & RT_BIT(31))  pHlp->pfnPrintf(pHlp, " PBE");
    1990             pHlp->pfnPrintf(pHlp, "\n");
    1991 
    1992             uint32_t uECX = Guest.uEcx;
    1993             pHlp->pfnPrintf(pHlp, "Features ECX:                   ");
    1994             if (uECX & RT_BIT(0))   pHlp->pfnPrintf(pHlp, " SSE3");
    1995             if (uECX & RT_BIT(1))   pHlp->pfnPrintf(pHlp, " PCLMUL");
    1996             if (uECX & RT_BIT(2))   pHlp->pfnPrintf(pHlp, " DTES64");
    1997             if (uECX & RT_BIT(3))   pHlp->pfnPrintf(pHlp, " MONITOR");
    1998             if (uECX & RT_BIT(4))   pHlp->pfnPrintf(pHlp, " DS-CPL");
    1999             if (uECX & RT_BIT(5))   pHlp->pfnPrintf(pHlp, " VMX");
    2000             if (uECX & RT_BIT(6))   pHlp->pfnPrintf(pHlp, " SMX");
    2001             if (uECX & RT_BIT(7))   pHlp->pfnPrintf(pHlp, " EST");
    2002             if (uECX & RT_BIT(8))   pHlp->pfnPrintf(pHlp, " TM2");
    2003             if (uECX & RT_BIT(9))   pHlp->pfnPrintf(pHlp, " SSSE3");
    2004             if (uECX & RT_BIT(10))  pHlp->pfnPrintf(pHlp, " CNXT-ID");
    2005             if (uECX & RT_BIT(11))  pHlp->pfnPrintf(pHlp, " 11");
    2006             if (uECX & RT_BIT(12))  pHlp->pfnPrintf(pHlp, " FMA");
    2007             if (uECX & RT_BIT(13))  pHlp->pfnPrintf(pHlp, " CX16");
    2008             if (uECX & RT_BIT(14))  pHlp->pfnPrintf(pHlp, " TPRUPDATE");
    2009             if (uECX & RT_BIT(15))  pHlp->pfnPrintf(pHlp, " PDCM");
    2010             if (uECX & RT_BIT(16))  pHlp->pfnPrintf(pHlp, " 16");
    2011             if (uECX & RT_BIT(17))  pHlp->pfnPrintf(pHlp, " PCID");
    2012             if (uECX & RT_BIT(18))  pHlp->pfnPrintf(pHlp, " DCA");
    2013             if (uECX & RT_BIT(19))  pHlp->pfnPrintf(pHlp, " SSE4.1");
    2014             if (uECX & RT_BIT(20))  pHlp->pfnPrintf(pHlp, " SSE4.2");
    2015             if (uECX & RT_BIT(21))  pHlp->pfnPrintf(pHlp, " X2APIC");
    2016             if (uECX & RT_BIT(22))  pHlp->pfnPrintf(pHlp, " MOVBE");
    2017             if (uECX & RT_BIT(23))  pHlp->pfnPrintf(pHlp, " POPCNT");
    2018             if (uECX & RT_BIT(24))  pHlp->pfnPrintf(pHlp, " TSCDEADL");
    2019             if (uECX & RT_BIT(25))  pHlp->pfnPrintf(pHlp, " AES");
    2020             if (uECX & RT_BIT(26))  pHlp->pfnPrintf(pHlp, " XSAVE");
    2021             if (uECX & RT_BIT(27))  pHlp->pfnPrintf(pHlp, " OSXSAVE");
    2022             if (uECX & RT_BIT(28))  pHlp->pfnPrintf(pHlp, " AVX");
    2023             if (uECX & RT_BIT(29))  pHlp->pfnPrintf(pHlp, " F16C");
    2024             if (uECX & RT_BIT(30))  pHlp->pfnPrintf(pHlp, " RDRAND");
    2025             if (uECX & RT_BIT(31))  pHlp->pfnPrintf(pHlp, " HVP");
    2026             pHlp->pfnPrintf(pHlp, "\n");
    2027         }
    2028         else
    2029         {
    2030             ASMCpuIdExSlow(1, 0, 0, 0, &Host.uEax, &Host.uEbx, &Host.uEcx, &Host.uEdx);
    2031 
    2032             X86CPUIDFEATEDX EdxHost  = *(PX86CPUIDFEATEDX)&Host.uEdx;
    2033             X86CPUIDFEATECX EcxHost  = *(PX86CPUIDFEATECX)&Host.uEcx;
    2034             X86CPUIDFEATEDX EdxGuest = *(PX86CPUIDFEATEDX)&Guest.uEdx;
    2035             X86CPUIDFEATECX EcxGuest = *(PX86CPUIDFEATECX)&Guest.uEcx;
    2036 
    2037             pHlp->pfnPrintf(pHlp, "Mnemonic - Description                 = guest (host)\n");
    2038             pHlp->pfnPrintf(pHlp, "FPU - x87 FPU on Chip                  = %d (%d)\n",  EdxGuest.u1FPU,        EdxHost.u1FPU);
    2039             pHlp->pfnPrintf(pHlp, "VME - Virtual 8086 Mode Enhancements   = %d (%d)\n",  EdxGuest.u1VME,        EdxHost.u1VME);
    2040             pHlp->pfnPrintf(pHlp, "DE - Debugging extensions              = %d (%d)\n",  EdxGuest.u1DE,         EdxHost.u1DE);
    2041             pHlp->pfnPrintf(pHlp, "PSE - Page Size Extension              = %d (%d)\n",  EdxGuest.u1PSE,        EdxHost.u1PSE);
    2042             pHlp->pfnPrintf(pHlp, "TSC - Time Stamp Counter               = %d (%d)\n",  EdxGuest.u1TSC,        EdxHost.u1TSC);
    2043             pHlp->pfnPrintf(pHlp, "MSR - Model Specific Registers         = %d (%d)\n",  EdxGuest.u1MSR,        EdxHost.u1MSR);
    2044             pHlp->pfnPrintf(pHlp, "PAE - Physical Address Extension       = %d (%d)\n",  EdxGuest.u1PAE,        EdxHost.u1PAE);
    2045             pHlp->pfnPrintf(pHlp, "MCE - Machine Check Exception          = %d (%d)\n",  EdxGuest.u1MCE,        EdxHost.u1MCE);
    2046             pHlp->pfnPrintf(pHlp, "CX8 - CMPXCHG8B instruction            = %d (%d)\n",  EdxGuest.u1CX8,        EdxHost.u1CX8);
    2047             pHlp->pfnPrintf(pHlp, "APIC - APIC On-Chip                    = %d (%d)\n",  EdxGuest.u1APIC,       EdxHost.u1APIC);
    2048             pHlp->pfnPrintf(pHlp, "10 - Reserved                          = %d (%d)\n",  EdxGuest.u1Reserved1,  EdxHost.u1Reserved1);
    2049             pHlp->pfnPrintf(pHlp, "SEP - SYSENTER and SYSEXIT             = %d (%d)\n",  EdxGuest.u1SEP,        EdxHost.u1SEP);
    2050             pHlp->pfnPrintf(pHlp, "MTRR - Memory Type Range Registers     = %d (%d)\n",  EdxGuest.u1MTRR,       EdxHost.u1MTRR);
    2051             pHlp->pfnPrintf(pHlp, "PGE - PTE Global Bit                   = %d (%d)\n",  EdxGuest.u1PGE,        EdxHost.u1PGE);
    2052             pHlp->pfnPrintf(pHlp, "MCA - Machine Check Architecture       = %d (%d)\n",  EdxGuest.u1MCA,        EdxHost.u1MCA);
    2053             pHlp->pfnPrintf(pHlp, "CMOV - Conditional Move Instructions   = %d (%d)\n",  EdxGuest.u1CMOV,       EdxHost.u1CMOV);
    2054             pHlp->pfnPrintf(pHlp, "PAT - Page Attribute Table             = %d (%d)\n",  EdxGuest.u1PAT,        EdxHost.u1PAT);
    2055             pHlp->pfnPrintf(pHlp, "PSE-36 - 36-bit Page Size Extention    = %d (%d)\n",  EdxGuest.u1PSE36,      EdxHost.u1PSE36);
    2056             pHlp->pfnPrintf(pHlp, "PSN - Processor Serial Number          = %d (%d)\n",  EdxGuest.u1PSN,        EdxHost.u1PSN);
    2057             pHlp->pfnPrintf(pHlp, "CLFSH - CLFLUSH Instruction.           = %d (%d)\n",  EdxGuest.u1CLFSH,      EdxHost.u1CLFSH);
    2058             pHlp->pfnPrintf(pHlp, "20 - Reserved                          = %d (%d)\n",  EdxGuest.u1Reserved2,  EdxHost.u1Reserved2);
    2059             pHlp->pfnPrintf(pHlp, "DS - Debug Store                       = %d (%d)\n",  EdxGuest.u1DS,         EdxHost.u1DS);
    2060             pHlp->pfnPrintf(pHlp, "ACPI - Thermal Mon. & Soft. Clock Ctrl.= %d (%d)\n",  EdxGuest.u1ACPI,       EdxHost.u1ACPI);
    2061             pHlp->pfnPrintf(pHlp, "MMX - Intel MMX Technology             = %d (%d)\n",  EdxGuest.u1MMX,        EdxHost.u1MMX);
    2062             pHlp->pfnPrintf(pHlp, "FXSR - FXSAVE and FXRSTOR Instructions = %d (%d)\n",  EdxGuest.u1FXSR,       EdxHost.u1FXSR);
    2063             pHlp->pfnPrintf(pHlp, "SSE - SSE Support                      = %d (%d)\n",  EdxGuest.u1SSE,        EdxHost.u1SSE);
    2064             pHlp->pfnPrintf(pHlp, "SSE2 - SSE2 Support                    = %d (%d)\n",  EdxGuest.u1SSE2,       EdxHost.u1SSE2);
    2065             pHlp->pfnPrintf(pHlp, "SS - Self Snoop                        = %d (%d)\n",  EdxGuest.u1SS,         EdxHost.u1SS);
    2066             pHlp->pfnPrintf(pHlp, "HTT - Hyper-Threading Technology       = %d (%d)\n",  EdxGuest.u1HTT,        EdxHost.u1HTT);
    2067             pHlp->pfnPrintf(pHlp, "TM - Thermal Monitor                   = %d (%d)\n",  EdxGuest.u1TM,         EdxHost.u1TM);
    2068             pHlp->pfnPrintf(pHlp, "30 - Reserved                          = %d (%d)\n",  EdxGuest.u1Reserved3,  EdxHost.u1Reserved3);
    2069             pHlp->pfnPrintf(pHlp, "PBE - Pending Break Enable             = %d (%d)\n",  EdxGuest.u1PBE,        EdxHost.u1PBE);
    2070 
    2071             pHlp->pfnPrintf(pHlp, "Supports SSE3                          = %d (%d)\n",  EcxGuest.u1SSE3,       EcxHost.u1SSE3);
    2072             pHlp->pfnPrintf(pHlp, "PCLMULQDQ                              = %d (%d)\n",  EcxGuest.u1PCLMULQDQ,  EcxHost.u1PCLMULQDQ);
    2073             pHlp->pfnPrintf(pHlp, "DS Area 64-bit layout                  = %d (%d)\n",  EcxGuest.u1DTE64,      EcxHost.u1DTE64);
    2074             pHlp->pfnPrintf(pHlp, "Supports MONITOR/MWAIT                 = %d (%d)\n",  EcxGuest.u1Monitor,    EcxHost.u1Monitor);
    2075             pHlp->pfnPrintf(pHlp, "CPL-DS - CPL Qualified Debug Store     = %d (%d)\n",  EcxGuest.u1CPLDS,      EcxHost.u1CPLDS);
    2076             pHlp->pfnPrintf(pHlp, "VMX - Virtual Machine Technology       = %d (%d)\n",  EcxGuest.u1VMX,        EcxHost.u1VMX);
    2077             pHlp->pfnPrintf(pHlp, "SMX - Safer Mode Extensions            = %d (%d)\n",  EcxGuest.u1SMX,        EcxHost.u1SMX);
    2078             pHlp->pfnPrintf(pHlp, "Enhanced SpeedStep Technology          = %d (%d)\n",  EcxGuest.u1EST,        EcxHost.u1EST);
    2079             pHlp->pfnPrintf(pHlp, "Terminal Monitor 2                     = %d (%d)\n",  EcxGuest.u1TM2,        EcxHost.u1TM2);
    2080             pHlp->pfnPrintf(pHlp, "Supplemental SSE3 instructions         = %d (%d)\n",  EcxGuest.u1SSSE3,      EcxHost.u1SSSE3);
    2081             pHlp->pfnPrintf(pHlp, "L1 Context ID                          = %d (%d)\n",  EcxGuest.u1CNTXID,     EcxHost.u1CNTXID);
    2082             pHlp->pfnPrintf(pHlp, "11 - Reserved                          = %d (%d)\n",  EcxGuest.u1Reserved1,  EcxHost.u1Reserved1);
    2083             pHlp->pfnPrintf(pHlp, "FMA extensions using YMM state         = %d (%d)\n",  EcxGuest.u1FMA,        EcxHost.u1FMA);
    2084             pHlp->pfnPrintf(pHlp, "CMPXCHG16B instruction                 = %d (%d)\n",  EcxGuest.u1CX16,       EcxHost.u1CX16);
    2085             pHlp->pfnPrintf(pHlp, "xTPR Update Control                    = %d (%d)\n",  EcxGuest.u1TPRUpdate,  EcxHost.u1TPRUpdate);
    2086             pHlp->pfnPrintf(pHlp, "Perf/Debug Capability MSR              = %d (%d)\n",  EcxGuest.u1PDCM,       EcxHost.u1PDCM);
    2087             pHlp->pfnPrintf(pHlp, "16 - Reserved                          = %d (%d)\n",  EcxGuest.u1Reserved2,  EcxHost.u1Reserved2);
    2088             pHlp->pfnPrintf(pHlp, "PCID - Process-context identifiers     = %d (%d)\n",  EcxGuest.u1PCID,       EcxHost.u1PCID);
    2089             pHlp->pfnPrintf(pHlp, "DCA - Direct Cache Access              = %d (%d)\n",  EcxGuest.u1DCA,        EcxHost.u1DCA);
    2090             pHlp->pfnPrintf(pHlp, "SSE4.1 instruction extensions          = %d (%d)\n",  EcxGuest.u1SSE4_1,     EcxHost.u1SSE4_1);
    2091             pHlp->pfnPrintf(pHlp, "SSE4.2 instruction extensions          = %d (%d)\n",  EcxGuest.u1SSE4_2,     EcxHost.u1SSE4_2);
    2092             pHlp->pfnPrintf(pHlp, "Supports the x2APIC extensions         = %d (%d)\n",  EcxGuest.u1x2APIC,     EcxHost.u1x2APIC);
    2093             pHlp->pfnPrintf(pHlp, "MOVBE instruction                      = %d (%d)\n",  EcxGuest.u1MOVBE,      EcxHost.u1MOVBE);
    2094             pHlp->pfnPrintf(pHlp, "POPCNT instruction                     = %d (%d)\n",  EcxGuest.u1POPCNT,     EcxHost.u1POPCNT);
    2095             pHlp->pfnPrintf(pHlp, "TSC-Deadline LAPIC timer mode          = %d (%d)\n",  EcxGuest.u1TSCDEADLINE,EcxHost.u1TSCDEADLINE);
    2096             pHlp->pfnPrintf(pHlp, "AESNI instruction extensions           = %d (%d)\n",  EcxGuest.u1AES,        EcxHost.u1AES);
    2097             pHlp->pfnPrintf(pHlp, "XSAVE/XRSTOR extended state feature    = %d (%d)\n",  EcxGuest.u1XSAVE,      EcxHost.u1XSAVE);
    2098             pHlp->pfnPrintf(pHlp, "Supports OSXSAVE                       = %d (%d)\n",  EcxGuest.u1OSXSAVE,    EcxHost.u1OSXSAVE);
    2099             pHlp->pfnPrintf(pHlp, "AVX instruction extensions             = %d (%d)\n",  EcxGuest.u1AVX,        EcxHost.u1AVX);
    2100             pHlp->pfnPrintf(pHlp, "16-bit floating point conversion instr = %d (%d)\n",  EcxGuest.u1F16C,       EcxHost.u1F16C);
    2101             pHlp->pfnPrintf(pHlp, "RDRAND instruction                     = %d (%d)\n",  EcxGuest.u1RDRAND,     EcxHost.u1RDRAND);
    2102             pHlp->pfnPrintf(pHlp, "Hypervisor Present (we're a guest)     = %d (%d)\n",  EcxGuest.u1HVP,        EcxHost.u1HVP);
    2103         }
    2104     }
    2105     if (cStdMax >= 2 && iVerbosity)
    2106     {
    2107         /** @todo */
    2108     }
    2109 
    2110     /*
    2111      * Extended.
    2112      * Implemented after AMD specs.
    2113      */
    2114     unsigned    cExtMax = pVM->cpum.s.aGuestCpuIdPatmExt[0].uEax & 0xffff;
    2115 
    2116     pHlp->pfnPrintf(pHlp,
    2117                     "\n"
    2118                     "         RAW Extended CPUIDs\n"
    2119                     "     Function  eax      ebx      ecx      edx\n");
    2120     bool fSupportsInvariantTsc = false;
    2121     for (unsigned i = 0; i < RT_ELEMENTS(pVM->cpum.s.aGuestCpuIdPatmExt); i++)
    2122     {
    2123         Guest = pVM->cpum.s.aGuestCpuIdPatmExt[i];
    2124         ASMCpuIdExSlow(0x80000000 | i, 0, 0, 0, &Host.uEax, &Host.uEbx, &Host.uEcx, &Host.uEdx);
    2125 
    2126         if (   i == 7
    2127             && (Host.uEdx & X86_CPUID_AMD_ADVPOWER_EDX_TSCINVAR))
    2128         {
    2129             fSupportsInvariantTsc = true;
    2130         }
    2131         pHlp->pfnPrintf(pHlp,
    2132                         "Gst: %08x  %08x %08x %08x %08x%s\n"
    2133                         "Hst:           %08x %08x %08x %08x\n",
    2134                         0x80000000 | i, Guest.uEax, Guest.uEbx, Guest.uEcx, Guest.uEdx,
    2135                         i <= cExtMax ? "" : "*",
    2136                         Host.uEax, Host.uEbx, Host.uEcx, Host.uEdx);
    2137     }
    2138 
    2139     /*
    2140      * Understandable output
    2141      */
    2142     if (iVerbosity)
    2143     {
    2144         Guest = pVM->cpum.s.aGuestCpuIdPatmExt[0];
    2145         pHlp->pfnPrintf(pHlp,
    2146                         "Ext Name:                        %.4s%.4s%.4s\n"
    2147                         "Ext Supports:                    0x80000000-%#010x\n",
    2148                         &Guest.uEbx, &Guest.uEdx, &Guest.uEcx, Guest.uEax);
    2149     }
    2150 
    2151     if (iVerbosity && cExtMax >= 1)
    2152     {
    2153         Guest = pVM->cpum.s.aGuestCpuIdPatmExt[1];
    2154         uint32_t uEAX = Guest.uEax;
    2155         pHlp->pfnPrintf(pHlp,
    2156                         "Family:                          %d  \tExtended: %d \tEffective: %d\n"
    2157                         "Model:                           %d  \tExtended: %d \tEffective: %d\n"
    2158                         "Stepping:                        %d\n"
    2159                         "Brand ID:                        %#05x\n",
    2160                         (uEAX >> 8) & 0xf, (uEAX >> 20) & 0x7f, ASMGetCpuFamily(uEAX),
    2161                         (uEAX >> 4) & 0xf, (uEAX >> 16) & 0x0f, ASMGetCpuModel(uEAX, fIntel),
    2162                         ASMGetCpuStepping(uEAX),
    2163                         Guest.uEbx & 0xfff);
    2164 
    2165         if (iVerbosity == 1)
    2166         {
    2167             uint32_t uEDX = Guest.uEdx;
    2168             pHlp->pfnPrintf(pHlp, "Features EDX:                   ");
    2169             if (uEDX & RT_BIT(0))   pHlp->pfnPrintf(pHlp, " FPU");
    2170             if (uEDX & RT_BIT(1))   pHlp->pfnPrintf(pHlp, " VME");
    2171             if (uEDX & RT_BIT(2))   pHlp->pfnPrintf(pHlp, " DE");
    2172             if (uEDX & RT_BIT(3))   pHlp->pfnPrintf(pHlp, " PSE");
    2173             if (uEDX & RT_BIT(4))   pHlp->pfnPrintf(pHlp, " TSC");
    2174             if (uEDX & RT_BIT(5))   pHlp->pfnPrintf(pHlp, " MSR");
    2175             if (uEDX & RT_BIT(6))   pHlp->pfnPrintf(pHlp, " PAE");
    2176             if (uEDX & RT_BIT(7))   pHlp->pfnPrintf(pHlp, " MCE");
    2177             if (uEDX & RT_BIT(8))   pHlp->pfnPrintf(pHlp, " CX8");
    2178             if (uEDX & RT_BIT(9))   pHlp->pfnPrintf(pHlp, " APIC");
    2179             if (uEDX & RT_BIT(10))  pHlp->pfnPrintf(pHlp, " 10");
    2180             if (uEDX & RT_BIT(11))  pHlp->pfnPrintf(pHlp, " SCR");
    2181             if (uEDX & RT_BIT(12))  pHlp->pfnPrintf(pHlp, " MTRR");
    2182             if (uEDX & RT_BIT(13))  pHlp->pfnPrintf(pHlp, " PGE");
    2183             if (uEDX & RT_BIT(14))  pHlp->pfnPrintf(pHlp, " MCA");
    2184             if (uEDX & RT_BIT(15))  pHlp->pfnPrintf(pHlp, " CMOV");
    2185             if (uEDX & RT_BIT(16))  pHlp->pfnPrintf(pHlp, " PAT");
    2186             if (uEDX & RT_BIT(17))  pHlp->pfnPrintf(pHlp, " PSE36");
    2187             if (uEDX & RT_BIT(18))  pHlp->pfnPrintf(pHlp, " 18");
    2188             if (uEDX & RT_BIT(19))  pHlp->pfnPrintf(pHlp, " 19");
    2189             if (uEDX & RT_BIT(20))  pHlp->pfnPrintf(pHlp, " NX");
    2190             if (uEDX & RT_BIT(21))  pHlp->pfnPrintf(pHlp, " 21");
    2191             if (uEDX & RT_BIT(22))  pHlp->pfnPrintf(pHlp, " ExtMMX");
    2192             if (uEDX & RT_BIT(23))  pHlp->pfnPrintf(pHlp, " MMX");
    2193             if (uEDX & RT_BIT(24))  pHlp->pfnPrintf(pHlp, " FXSR");
    2194             if (uEDX & RT_BIT(25))  pHlp->pfnPrintf(pHlp, " FastFXSR");
    2195             if (uEDX & RT_BIT(26))  pHlp->pfnPrintf(pHlp, " Page1GB");
    2196             if (uEDX & RT_BIT(27))  pHlp->pfnPrintf(pHlp, " RDTSCP");
    2197             if (uEDX & RT_BIT(28))  pHlp->pfnPrintf(pHlp, " 28");
    2198             if (uEDX & RT_BIT(29))  pHlp->pfnPrintf(pHlp, " LongMode");
    2199             if (uEDX & RT_BIT(30))  pHlp->pfnPrintf(pHlp, " Ext3DNow");
    2200             if (uEDX & RT_BIT(31))  pHlp->pfnPrintf(pHlp, " 3DNow");
    2201             pHlp->pfnPrintf(pHlp, "\n");
    2202 
    2203             uint32_t uECX = Guest.uEcx;
    2204             pHlp->pfnPrintf(pHlp, "Features ECX:                   ");
    2205             if (uECX & RT_BIT(0))   pHlp->pfnPrintf(pHlp, " LAHF/SAHF");
    2206             if (uECX & RT_BIT(1))   pHlp->pfnPrintf(pHlp, " CMPL");
    2207             if (uECX & RT_BIT(2))   pHlp->pfnPrintf(pHlp, " SVM");
    2208             if (uECX & RT_BIT(3))   pHlp->pfnPrintf(pHlp, " ExtAPIC");
    2209             if (uECX & RT_BIT(4))   pHlp->pfnPrintf(pHlp, " CR8L");
    2210             if (uECX & RT_BIT(5))   pHlp->pfnPrintf(pHlp, " ABM");
    2211             if (uECX & RT_BIT(6))   pHlp->pfnPrintf(pHlp, " SSE4A");
    2212             if (uECX & RT_BIT(7))   pHlp->pfnPrintf(pHlp, " MISALNSSE");
    2213             if (uECX & RT_BIT(8))   pHlp->pfnPrintf(pHlp, " 3DNOWPRF");
    2214             if (uECX & RT_BIT(9))   pHlp->pfnPrintf(pHlp, " OSVW");
    2215             if (uECX & RT_BIT(10))  pHlp->pfnPrintf(pHlp, " IBS");
    2216             if (uECX & RT_BIT(11))  pHlp->pfnPrintf(pHlp, " SSE5");
    2217             if (uECX & RT_BIT(12))  pHlp->pfnPrintf(pHlp, " SKINIT");
    2218             if (uECX & RT_BIT(13))  pHlp->pfnPrintf(pHlp, " WDT");
    2219             for (unsigned iBit = 5; iBit < 32; iBit++)
    2220                 if (uECX & RT_BIT(iBit))
    2221                     pHlp->pfnPrintf(pHlp, " %d", iBit);
    2222             pHlp->pfnPrintf(pHlp, "\n");
    2223         }
    2224         else
    2225         {
    2226             ASMCpuIdExSlow(0x80000001, 0, 0, 0, &Host.uEax, &Host.uEbx, &Host.uEcx, &Host.uEdx);
    2227 
    2228             uint32_t uEdxGst = Guest.uEdx;
    2229             uint32_t uEdxHst = Host.uEdx;
    2230             pHlp->pfnPrintf(pHlp, "Mnemonic - Description                 = guest (host)\n");
    2231             pHlp->pfnPrintf(pHlp, "FPU - x87 FPU on Chip                  = %d (%d)\n",  !!(uEdxGst & RT_BIT( 0)),  !!(uEdxHst & RT_BIT( 0)));
    2232             pHlp->pfnPrintf(pHlp, "VME - Virtual 8086 Mode Enhancements   = %d (%d)\n",  !!(uEdxGst & RT_BIT( 1)),  !!(uEdxHst & RT_BIT( 1)));
    2233             pHlp->pfnPrintf(pHlp, "DE - Debugging extensions              = %d (%d)\n",  !!(uEdxGst & RT_BIT( 2)),  !!(uEdxHst & RT_BIT( 2)));
    2234             pHlp->pfnPrintf(pHlp, "PSE - Page Size Extension              = %d (%d)\n",  !!(uEdxGst & RT_BIT( 3)),  !!(uEdxHst & RT_BIT( 3)));
    2235             pHlp->pfnPrintf(pHlp, "TSC - Time Stamp Counter               = %d (%d)\n",  !!(uEdxGst & RT_BIT( 4)),  !!(uEdxHst & RT_BIT( 4)));
    2236             pHlp->pfnPrintf(pHlp, "MSR - K86 Model Specific Registers     = %d (%d)\n",  !!(uEdxGst & RT_BIT( 5)),  !!(uEdxHst & RT_BIT( 5)));
    2237             pHlp->pfnPrintf(pHlp, "PAE - Physical Address Extension       = %d (%d)\n",  !!(uEdxGst & RT_BIT( 6)),  !!(uEdxHst & RT_BIT( 6)));
    2238             pHlp->pfnPrintf(pHlp, "MCE - Machine Check Exception          = %d (%d)\n",  !!(uEdxGst & RT_BIT( 7)),  !!(uEdxHst & RT_BIT( 7)));
    2239             pHlp->pfnPrintf(pHlp, "CX8 - CMPXCHG8B instruction            = %d (%d)\n",  !!(uEdxGst & RT_BIT( 8)),  !!(uEdxHst & RT_BIT( 8)));
    2240             pHlp->pfnPrintf(pHlp, "APIC - APIC On-Chip                    = %d (%d)\n",  !!(uEdxGst & RT_BIT( 9)),  !!(uEdxHst & RT_BIT( 9)));
    2241             pHlp->pfnPrintf(pHlp, "10 - Reserved                          = %d (%d)\n",  !!(uEdxGst & RT_BIT(10)),  !!(uEdxHst & RT_BIT(10)));
    2242             pHlp->pfnPrintf(pHlp, "SEP - SYSCALL and SYSRET               = %d (%d)\n",  !!(uEdxGst & RT_BIT(11)),  !!(uEdxHst & RT_BIT(11)));
    2243             pHlp->pfnPrintf(pHlp, "MTRR - Memory Type Range Registers     = %d (%d)\n",  !!(uEdxGst & RT_BIT(12)),  !!(uEdxHst & RT_BIT(12)));
    2244             pHlp->pfnPrintf(pHlp, "PGE - PTE Global Bit                   = %d (%d)\n",  !!(uEdxGst & RT_BIT(13)),  !!(uEdxHst & RT_BIT(13)));
    2245             pHlp->pfnPrintf(pHlp, "MCA - Machine Check Architecture       = %d (%d)\n",  !!(uEdxGst & RT_BIT(14)),  !!(uEdxHst & RT_BIT(14)));
    2246             pHlp->pfnPrintf(pHlp, "CMOV - Conditional Move Instructions   = %d (%d)\n",  !!(uEdxGst & RT_BIT(15)),  !!(uEdxHst & RT_BIT(15)));
    2247             pHlp->pfnPrintf(pHlp, "PAT - Page Attribute Table             = %d (%d)\n",  !!(uEdxGst & RT_BIT(16)),  !!(uEdxHst & RT_BIT(16)));
    2248             pHlp->pfnPrintf(pHlp, "PSE-36 - 36-bit Page Size Extention    = %d (%d)\n",  !!(uEdxGst & RT_BIT(17)),  !!(uEdxHst & RT_BIT(17)));
    2249             pHlp->pfnPrintf(pHlp, "18 - Reserved                          = %d (%d)\n",  !!(uEdxGst & RT_BIT(18)),  !!(uEdxHst & RT_BIT(18)));
    2250             pHlp->pfnPrintf(pHlp, "19 - Reserved                          = %d (%d)\n",  !!(uEdxGst & RT_BIT(19)),  !!(uEdxHst & RT_BIT(19)));
    2251             pHlp->pfnPrintf(pHlp, "NX - No-Execute Page Protection        = %d (%d)\n",  !!(uEdxGst & RT_BIT(20)),  !!(uEdxHst & RT_BIT(20)));
    2252             pHlp->pfnPrintf(pHlp, "DS - Debug Store                       = %d (%d)\n",  !!(uEdxGst & RT_BIT(21)),  !!(uEdxHst & RT_BIT(21)));
    2253             pHlp->pfnPrintf(pHlp, "AXMMX - AMD Extensions to MMX Instr.   = %d (%d)\n",  !!(uEdxGst & RT_BIT(22)),  !!(uEdxHst & RT_BIT(22)));
    2254             pHlp->pfnPrintf(pHlp, "MMX - Intel MMX Technology             = %d (%d)\n",  !!(uEdxGst & RT_BIT(23)),  !!(uEdxHst & RT_BIT(23)));
    2255             pHlp->pfnPrintf(pHlp, "FXSR - FXSAVE and FXRSTOR Instructions = %d (%d)\n",  !!(uEdxGst & RT_BIT(24)),  !!(uEdxHst & RT_BIT(24)));
    2256             pHlp->pfnPrintf(pHlp, "25 - AMD fast FXSAVE and FXRSTOR Instr.= %d (%d)\n",  !!(uEdxGst & RT_BIT(25)),  !!(uEdxHst & RT_BIT(25)));
    2257             pHlp->pfnPrintf(pHlp, "26 - 1 GB large page support           = %d (%d)\n",  !!(uEdxGst & RT_BIT(26)),  !!(uEdxHst & RT_BIT(26)));
    2258             pHlp->pfnPrintf(pHlp, "27 - RDTSCP instruction                = %d (%d)\n",  !!(uEdxGst & RT_BIT(27)),  !!(uEdxHst & RT_BIT(27)));
    2259             pHlp->pfnPrintf(pHlp, "28 - Reserved                          = %d (%d)\n",  !!(uEdxGst & RT_BIT(28)),  !!(uEdxHst & RT_BIT(28)));
    2260             pHlp->pfnPrintf(pHlp, "29 - AMD Long Mode                     = %d (%d)\n",  !!(uEdxGst & RT_BIT(29)),  !!(uEdxHst & RT_BIT(29)));
    2261             pHlp->pfnPrintf(pHlp, "30 - AMD Extensions to 3DNow!          = %d (%d)\n",  !!(uEdxGst & RT_BIT(30)),  !!(uEdxHst & RT_BIT(30)));
    2262             pHlp->pfnPrintf(pHlp, "31 - AMD 3DNow!                        = %d (%d)\n",  !!(uEdxGst & RT_BIT(31)),  !!(uEdxHst & RT_BIT(31)));
    2263 
    2264             uint32_t uEcxGst = Guest.uEcx;
    2265             uint32_t uEcxHst = Host.uEcx;
    2266             pHlp->pfnPrintf(pHlp, "LahfSahf - LAHF/SAHF in 64-bit mode    = %d (%d)\n",  !!(uEcxGst & RT_BIT( 0)),  !!(uEcxHst & RT_BIT( 0)));
    2267             pHlp->pfnPrintf(pHlp, "CmpLegacy - Core MP legacy mode (depr) = %d (%d)\n",  !!(uEcxGst & RT_BIT( 1)),  !!(uEcxHst & RT_BIT( 1)));
    2268             pHlp->pfnPrintf(pHlp, "SVM - AMD VM Extensions                = %d (%d)\n",  !!(uEcxGst & RT_BIT( 2)),  !!(uEcxHst & RT_BIT( 2)));
    2269             pHlp->pfnPrintf(pHlp, "APIC registers starting at 0x400       = %d (%d)\n",  !!(uEcxGst & RT_BIT( 3)),  !!(uEcxHst & RT_BIT( 3)));
    2270             pHlp->pfnPrintf(pHlp, "AltMovCR8 - LOCK MOV CR0 means MOV CR8 = %d (%d)\n",  !!(uEcxGst & RT_BIT( 4)),  !!(uEcxHst & RT_BIT( 4)));
    2271             pHlp->pfnPrintf(pHlp, "5  - Advanced bit manipulation         = %d (%d)\n",  !!(uEcxGst & RT_BIT( 5)),  !!(uEcxHst & RT_BIT( 5)));
    2272             pHlp->pfnPrintf(pHlp, "6  - SSE4A instruction support         = %d (%d)\n",  !!(uEcxGst & RT_BIT( 6)),  !!(uEcxHst & RT_BIT( 6)));
    2273             pHlp->pfnPrintf(pHlp, "7  - Misaligned SSE mode               = %d (%d)\n",  !!(uEcxGst & RT_BIT( 7)),  !!(uEcxHst & RT_BIT( 7)));
    2274             pHlp->pfnPrintf(pHlp, "8  - PREFETCH and PREFETCHW instruction= %d (%d)\n",  !!(uEcxGst & RT_BIT( 8)),  !!(uEcxHst & RT_BIT( 8)));
    2275             pHlp->pfnPrintf(pHlp, "9  - OS visible workaround             = %d (%d)\n",  !!(uEcxGst & RT_BIT( 9)),  !!(uEcxHst & RT_BIT( 9)));
    2276             pHlp->pfnPrintf(pHlp, "10 - Instruction based sampling        = %d (%d)\n",  !!(uEcxGst & RT_BIT(10)),  !!(uEcxHst & RT_BIT(10)));
    2277             pHlp->pfnPrintf(pHlp, "11 - SSE5 support                      = %d (%d)\n",  !!(uEcxGst & RT_BIT(11)),  !!(uEcxHst & RT_BIT(11)));
    2278             pHlp->pfnPrintf(pHlp, "12 - SKINIT, STGI, and DEV support     = %d (%d)\n",  !!(uEcxGst & RT_BIT(12)),  !!(uEcxHst & RT_BIT(12)));
    2279             pHlp->pfnPrintf(pHlp, "13 - Watchdog timer support.           = %d (%d)\n",  !!(uEcxGst & RT_BIT(13)),  !!(uEcxHst & RT_BIT(13)));
    2280             pHlp->pfnPrintf(pHlp, "31:14 - Reserved                       = %#x (%#x)\n",   uEcxGst >> 14,          uEcxHst >> 14);
    2281         }
    2282     }
    2283 
    2284     if (iVerbosity && cExtMax >= 2)
    2285     {
    2286         char szString[4*4*3+1] = {0};
    2287         uint32_t *pu32 = (uint32_t *)szString;
    2288         *pu32++ = pVM->cpum.s.aGuestCpuIdPatmExt[2].uEax;
    2289         *pu32++ = pVM->cpum.s.aGuestCpuIdPatmExt[2].uEbx;
    2290         *pu32++ = pVM->cpum.s.aGuestCpuIdPatmExt[2].uEcx;
    2291         *pu32++ = pVM->cpum.s.aGuestCpuIdPatmExt[2].uEdx;
    2292         if (cExtMax >= 3)
    2293         {
    2294             *pu32++ = pVM->cpum.s.aGuestCpuIdPatmExt[3].uEax;
    2295             *pu32++ = pVM->cpum.s.aGuestCpuIdPatmExt[3].uEbx;
    2296             *pu32++ = pVM->cpum.s.aGuestCpuIdPatmExt[3].uEcx;
    2297             *pu32++ = pVM->cpum.s.aGuestCpuIdPatmExt[3].uEdx;
    2298         }
    2299         if (cExtMax >= 4)
    2300         {
    2301             *pu32++ = pVM->cpum.s.aGuestCpuIdPatmExt[4].uEax;
    2302             *pu32++ = pVM->cpum.s.aGuestCpuIdPatmExt[4].uEbx;
    2303             *pu32++ = pVM->cpum.s.aGuestCpuIdPatmExt[4].uEcx;
    2304             *pu32++ = pVM->cpum.s.aGuestCpuIdPatmExt[4].uEdx;
    2305         }
    2306         pHlp->pfnPrintf(pHlp, "Full Name:                       %s\n", szString);
    2307     }
    2308 
    2309     if (iVerbosity && cExtMax >= 5)
    2310     {
    2311         uint32_t uEAX = pVM->cpum.s.aGuestCpuIdPatmExt[5].uEax;
    2312         uint32_t uEBX = pVM->cpum.s.aGuestCpuIdPatmExt[5].uEbx;
    2313         uint32_t uECX = pVM->cpum.s.aGuestCpuIdPatmExt[5].uEcx;
    2314         uint32_t uEDX = pVM->cpum.s.aGuestCpuIdPatmExt[5].uEdx;
    2315         char sz1[32];
    2316         char sz2[32];
    2317 
    2318         pHlp->pfnPrintf(pHlp,
    2319                         "TLB 2/4M Instr/Uni:              %s %3d entries\n"
    2320                         "TLB 2/4M Data:                   %s %3d entries\n",
    2321                         getCacheAss((uEAX >>  8) & 0xff, sz1), (uEAX >>  0) & 0xff,
    2322                         getCacheAss((uEAX >> 24) & 0xff, sz2), (uEAX >> 16) & 0xff);
    2323         pHlp->pfnPrintf(pHlp,
    2324                         "TLB 4K Instr/Uni:                %s %3d entries\n"
    2325                         "TLB 4K Data:                     %s %3d entries\n",
    2326                         getCacheAss((uEBX >>  8) & 0xff, sz1), (uEBX >>  0) & 0xff,
    2327                         getCacheAss((uEBX >> 24) & 0xff, sz2), (uEBX >> 16) & 0xff);
    2328         pHlp->pfnPrintf(pHlp, "L1 Instr Cache Line Size:        %d bytes\n"
    2329                         "L1 Instr Cache Lines Per Tag:    %d\n"
    2330                         "L1 Instr Cache Associativity:    %s\n"
    2331                         "L1 Instr Cache Size:             %d KB\n",
    2332                         (uEDX >> 0) & 0xff,
    2333                         (uEDX >> 8) & 0xff,
    2334                         getCacheAss((uEDX >> 16) & 0xff, sz1),
    2335                         (uEDX >> 24) & 0xff);
    2336         pHlp->pfnPrintf(pHlp,
    2337                         "L1 Data Cache Line Size:         %d bytes\n"
    2338                         "L1 Data Cache Lines Per Tag:     %d\n"
    2339                         "L1 Data Cache Associativity:     %s\n"
    2340                         "L1 Data Cache Size:              %d KB\n",
    2341                         (uECX >> 0) & 0xff,
    2342                         (uECX >> 8) & 0xff,
    2343                         getCacheAss((uECX >> 16) & 0xff, sz1),
    2344                         (uECX >> 24) & 0xff);
    2345     }
    2346 
    2347     if (iVerbosity && cExtMax >= 6)
    2348     {
    2349         uint32_t uEAX = pVM->cpum.s.aGuestCpuIdPatmExt[6].uEax;
    2350         uint32_t uEBX = pVM->cpum.s.aGuestCpuIdPatmExt[6].uEbx;
    2351         uint32_t uEDX = pVM->cpum.s.aGuestCpuIdPatmExt[6].uEdx;
    2352 
    2353         pHlp->pfnPrintf(pHlp,
    2354                         "L2 TLB 2/4M Instr/Uni:           %s %4d entries\n"
    2355                         "L2 TLB 2/4M Data:                %s %4d entries\n",
    2356                         getL2CacheAss((uEAX >> 12) & 0xf),  (uEAX >>  0) & 0xfff,
    2357                         getL2CacheAss((uEAX >> 28) & 0xf),  (uEAX >> 16) & 0xfff);
    2358         pHlp->pfnPrintf(pHlp,
    2359                         "L2 TLB 4K Instr/Uni:             %s %4d entries\n"
    2360                         "L2 TLB 4K Data:                  %s %4d entries\n",
    2361                         getL2CacheAss((uEBX >> 12) & 0xf),  (uEBX >>  0) & 0xfff,
    2362                         getL2CacheAss((uEBX >> 28) & 0xf),  (uEBX >> 16) & 0xfff);
    2363         pHlp->pfnPrintf(pHlp,
    2364                         "L2 Cache Line Size:              %d bytes\n"
    2365                         "L2 Cache Lines Per Tag:          %d\n"
    2366                         "L2 Cache Associativity:          %s\n"
    2367                         "L2 Cache Size:                   %d KB\n",
    2368                         (uEDX >> 0) & 0xff,
    2369                         (uEDX >> 8) & 0xf,
    2370                         getL2CacheAss((uEDX >> 12) & 0xf),
    2371                         (uEDX >> 16) & 0xffff);
    2372     }
    2373 
    2374     if (iVerbosity && cExtMax >= 7)
    2375     {
    2376         uint32_t uEDX = pVM->cpum.s.aGuestCpuIdPatmExt[7].uEdx;
    2377 
    2378         pHlp->pfnPrintf(pHlp, "Host Invariant-TSC support:      %RTbool\n", fSupportsInvariantTsc);
    2379         pHlp->pfnPrintf(pHlp, "APM Features:                   ");
    2380         if (uEDX & RT_BIT(0))   pHlp->pfnPrintf(pHlp, " TS");
    2381         if (uEDX & RT_BIT(1))   pHlp->pfnPrintf(pHlp, " FID");
    2382         if (uEDX & RT_BIT(2))   pHlp->pfnPrintf(pHlp, " VID");
    2383         if (uEDX & RT_BIT(3))   pHlp->pfnPrintf(pHlp, " TTP");
    2384         if (uEDX & RT_BIT(4))   pHlp->pfnPrintf(pHlp, " TM");
    2385         if (uEDX & RT_BIT(5))   pHlp->pfnPrintf(pHlp, " STC");
    2386         for (unsigned iBit = 6; iBit < 32; iBit++)
    2387         {
    2388             if (uEDX & X86_CPUID_AMD_ADVPOWER_EDX_TSCINVAR)
    2389                 pHlp->pfnPrintf(pHlp, " TSCINVARIANT");
    2390             else if (uEDX & RT_BIT(iBit))
    2391                 pHlp->pfnPrintf(pHlp, " %d", iBit);
    2392         }
    2393         pHlp->pfnPrintf(pHlp, "\n");
    2394     }
    2395 
    2396     if (iVerbosity && cExtMax >= 8)
    2397     {
    2398         uint32_t uEAX = pVM->cpum.s.aGuestCpuIdPatmExt[8].uEax;
    2399         uint32_t uECX = pVM->cpum.s.aGuestCpuIdPatmExt[8].uEcx;
    2400 
    2401         pHlp->pfnPrintf(pHlp,
    2402                         "Physical Address Width:          %d bits\n"
    2403                         "Virtual Address Width:           %d bits\n"
    2404                         "Guest Physical Address Width:    %d bits\n",
    2405                         (uEAX >> 0) & 0xff,
    2406                         (uEAX >> 8) & 0xff,
    2407                         (uEAX >> 16) & 0xff);
    2408         pHlp->pfnPrintf(pHlp,
    2409                         "Physical Core Count:             %d\n",
    2410                         (uECX >> 0) & 0xff);
    2411     }
    2412 
    2413 
    2414     /*
    2415      * Hypervisor leaves.
    2416      *
    2417      * Unlike most of the other leaves reported, the guest hypervisor leaves
    2418      * aren't a subset of the host CPUID bits.
    2419      */
    2420     RT_ZERO(Host);
    2421     if (cStdHstMax >= 1)
    2422         ASMCpuIdExSlow(1, 0, 0, 0, &Host.uEax, &Host.uEbx, &Host.uEcx, &Host.uEdx);
    2423     bool fHostHvp  = RT_BOOL(Host.uEcx & X86_CPUID_FEATURE_ECX_HVP);
    2424     bool fGuestHvp = false;
    2425     if (cStdMax >= 1)
    2426     {
    2427         Guest     = pVM->cpum.s.aGuestCpuIdPatmStd[1];
    2428         fGuestHvp = RT_BOOL(Guest.uEcx & X86_CPUID_FEATURE_ECX_HVP);
    2429     }
    2430 
    2431     if (   fHostHvp
    2432         || fGuestHvp)
    2433     {
    2434         uint32_t const uHyperLeaf = 0x40000000;
    2435         pHlp->pfnPrintf(pHlp,
    2436                         "\n"
    2437                         "         Hypervisor CPUIDs\n"
    2438                         "     Function  eax      ebx      ecx      edx\n");
    2439 
    2440         PCCPUMCPUIDLEAF pHyperLeafGst = NULL;
    2441         if (fGuestHvp)
    2442         {
    2443             pHyperLeafGst = cpumR3CpuIdGetLeaf(pVM->cpum.s.GuestInfo.paCpuIdLeavesR3, pVM->cpum.s.GuestInfo.cCpuIdLeaves,
    2444                                                uHyperLeaf, 0 /* uSubLeaf */);
    2445         }
    2446 
    2447         RT_ZERO(Host);
    2448         if (fHostHvp)
    2449             ASMCpuIdExSlow(uHyperLeaf, 0, 0, 0, &Host.uEax, &Host.uEbx, &Host.uEcx, &Host.uEdx);
    2450 
    2451         CPUMCPUIDLEAF  GuestLeaf;
    2452         uint32_t const cHyperGstMax = pHyperLeafGst ? pHyperLeafGst->uEax : 0;
    2453         uint32_t const cHyperHstMax = Host.uEax;
    2454         uint32_t const cHyperMax    = RT_MAX(cHyperHstMax, cHyperGstMax);
    2455         for (uint32_t i = uHyperLeaf; i <= cHyperMax; i++)
    2456         {
    2457             RT_ZERO(Host);
    2458             RT_ZERO(GuestLeaf);
    2459             if (i <= cHyperHstMax)
    2460                 ASMCpuIdExSlow(i, 0, 0, 0, &Host.uEax, &Host.uEbx, &Host.uEcx, &Host.uEdx);
    2461             CPUMR3CpuIdGetLeaf(pVM, &GuestLeaf, i, 0 /* uSubLeaf */);
    2462             if (!fHostHvp)
    2463             {
    2464                 pHlp->pfnPrintf(pHlp,
    2465                                 "Gst: %08x  %08x %08x %08x %08x\n",
    2466                                 i, GuestLeaf.uEax, GuestLeaf.uEbx, GuestLeaf.uEcx, GuestLeaf.uEdx);
    2467             }
    2468             else
    2469             {
    2470                 pHlp->pfnPrintf(pHlp,
    2471                                 "Gst: %08x  %08x %08x %08x %08x%s\n"
    2472                                 "Hst:           %08x %08x %08x %08x%s\n",
    2473                                 i, GuestLeaf.uEax, GuestLeaf.uEbx, GuestLeaf.uEcx, GuestLeaf.uEdx,
    2474                                 i <= cHyperGstMax ? "" : "*",
    2475                                 Host.uEax, Host.uEbx, Host.uEcx, Host.uEdx, i <= cHyperHstMax ? "" : "*");
    2476             }
    2477         }
    2478     }
    2479 
    2480     /*
    2481      * Centaur.
    2482      */
    2483     unsigned cCentaurMax = pVM->cpum.s.aGuestCpuIdPatmCentaur[0].uEax & 0xffff;
    2484 
    2485     pHlp->pfnPrintf(pHlp,
    2486                     "\n"
    2487                     "         RAW Centaur CPUIDs\n"
    2488                     "     Function  eax      ebx      ecx      edx\n");
    2489     for (unsigned i = 0; i < RT_ELEMENTS(pVM->cpum.s.aGuestCpuIdPatmCentaur); i++)
    2490     {
    2491         Guest = pVM->cpum.s.aGuestCpuIdPatmCentaur[i];
    2492         ASMCpuIdExSlow(0xc0000000 | i, 0, 0, 0, &Host.uEax, &Host.uEbx, &Host.uEcx, &Host.uEdx);
    2493 
    2494         pHlp->pfnPrintf(pHlp,
    2495                         "Gst: %08x  %08x %08x %08x %08x%s\n"
    2496                         "Hst:           %08x %08x %08x %08x\n",
    2497                         0xc0000000 | i, Guest.uEax, Guest.uEbx, Guest.uEcx, Guest.uEdx,
    2498                         i <= cCentaurMax ? "" : "*",
    2499                         Host.uEax, Host.uEbx, Host.uEcx, Host.uEdx);
    2500     }
    2501 
    2502     /*
    2503      * Understandable output
    2504      */
    2505     if (iVerbosity)
    2506     {
    2507         Guest = pVM->cpum.s.aGuestCpuIdPatmCentaur[0];
    2508         pHlp->pfnPrintf(pHlp,
    2509                         "Centaur Supports:                0xc0000000-%#010x\n",
    2510                         Guest.uEax);
    2511     }
    2512 
    2513     if (iVerbosity && cCentaurMax >= 1)
    2514     {
    2515         ASMCpuIdExSlow(0xc0000001, 0, 0, 0, &Host.uEax, &Host.uEbx, &Host.uEcx, &Host.uEdx);
    2516         uint32_t uEdxGst = pVM->cpum.s.aGuestCpuIdPatmCentaur[1].uEdx;
    2517         uint32_t uEdxHst = Host.uEdx;
    2518 
    2519         if (iVerbosity == 1)
    2520         {
    2521             pHlp->pfnPrintf(pHlp, "Centaur Features EDX:           ");
    2522             if (uEdxGst & RT_BIT(0))   pHlp->pfnPrintf(pHlp, " AIS");
    2523             if (uEdxGst & RT_BIT(1))   pHlp->pfnPrintf(pHlp, " AIS-E");
    2524             if (uEdxGst & RT_BIT(2))   pHlp->pfnPrintf(pHlp, " RNG");
    2525             if (uEdxGst & RT_BIT(3))   pHlp->pfnPrintf(pHlp, " RNG-E");
    2526             if (uEdxGst & RT_BIT(4))   pHlp->pfnPrintf(pHlp, " LH");
    2527             if (uEdxGst & RT_BIT(5))   pHlp->pfnPrintf(pHlp, " FEMMS");
    2528             if (uEdxGst & RT_BIT(6))   pHlp->pfnPrintf(pHlp, " ACE");
    2529             if (uEdxGst & RT_BIT(7))   pHlp->pfnPrintf(pHlp, " ACE-E");
    2530             /* possibly indicating MM/HE and MM/HE-E on older chips... */
    2531             if (uEdxGst & RT_BIT(8))   pHlp->pfnPrintf(pHlp, " ACE2");
    2532             if (uEdxGst & RT_BIT(9))   pHlp->pfnPrintf(pHlp, " ACE2-E");
    2533             if (uEdxGst & RT_BIT(10))  pHlp->pfnPrintf(pHlp, " PHE");
    2534             if (uEdxGst & RT_BIT(11))  pHlp->pfnPrintf(pHlp, " PHE-E");
    2535             if (uEdxGst & RT_BIT(12))  pHlp->pfnPrintf(pHlp, " PMM");
    2536             if (uEdxGst & RT_BIT(13))  pHlp->pfnPrintf(pHlp, " PMM-E");
    2537             for (unsigned iBit = 14; iBit < 32; iBit++)
    2538                 if (uEdxGst & RT_BIT(iBit))
    2539                     pHlp->pfnPrintf(pHlp, " %d", iBit);
    2540             pHlp->pfnPrintf(pHlp, "\n");
    2541         }
    2542         else
    2543         {
    2544             pHlp->pfnPrintf(pHlp, "Mnemonic - Description                 = guest (host)\n");
    2545             pHlp->pfnPrintf(pHlp, "AIS - Alternate Instruction Set        = %d (%d)\n",  !!(uEdxGst & RT_BIT( 0)),  !!(uEdxHst & RT_BIT( 0)));
    2546             pHlp->pfnPrintf(pHlp, "AIS-E - AIS enabled                    = %d (%d)\n",  !!(uEdxGst & RT_BIT( 1)),  !!(uEdxHst & RT_BIT( 1)));
    2547             pHlp->pfnPrintf(pHlp, "RNG - Random Number Generator          = %d (%d)\n",  !!(uEdxGst & RT_BIT( 2)),  !!(uEdxHst & RT_BIT( 2)));
    2548             pHlp->pfnPrintf(pHlp, "RNG-E - RNG enabled                    = %d (%d)\n",  !!(uEdxGst & RT_BIT( 3)),  !!(uEdxHst & RT_BIT( 3)));
    2549             pHlp->pfnPrintf(pHlp, "LH - LongHaul MSR 0000_110Ah           = %d (%d)\n",  !!(uEdxGst & RT_BIT( 4)),  !!(uEdxHst & RT_BIT( 4)));
    2550             pHlp->pfnPrintf(pHlp, "FEMMS - FEMMS                          = %d (%d)\n",  !!(uEdxGst & RT_BIT( 5)),  !!(uEdxHst & RT_BIT( 5)));
    2551             pHlp->pfnPrintf(pHlp, "ACE - Advanced Cryptography Engine     = %d (%d)\n",  !!(uEdxGst & RT_BIT( 6)),  !!(uEdxHst & RT_BIT( 6)));
    2552             pHlp->pfnPrintf(pHlp, "ACE-E - ACE enabled                    = %d (%d)\n",  !!(uEdxGst & RT_BIT( 7)),  !!(uEdxHst & RT_BIT( 7)));
    2553             /* possibly indicating MM/HE and MM/HE-E on older chips... */
    2554             pHlp->pfnPrintf(pHlp, "ACE2 - Advanced Cryptography Engine 2  = %d (%d)\n",  !!(uEdxGst & RT_BIT( 8)),  !!(uEdxHst & RT_BIT( 8)));
    2555             pHlp->pfnPrintf(pHlp, "ACE2-E - ACE enabled                   = %d (%d)\n",  !!(uEdxGst & RT_BIT( 9)),  !!(uEdxHst & RT_BIT( 9)));
    2556             pHlp->pfnPrintf(pHlp, "PHE - Padlock Hash Engine              = %d (%d)\n",  !!(uEdxGst & RT_BIT(10)),  !!(uEdxHst & RT_BIT(10)));
    2557             pHlp->pfnPrintf(pHlp, "PHE-E - PHE enabled                    = %d (%d)\n",  !!(uEdxGst & RT_BIT(11)),  !!(uEdxHst & RT_BIT(11)));
    2558             pHlp->pfnPrintf(pHlp, "PMM - Montgomery Multiplier            = %d (%d)\n",  !!(uEdxGst & RT_BIT(12)),  !!(uEdxHst & RT_BIT(12)));
    2559             pHlp->pfnPrintf(pHlp, "PMM-E - PMM enabled                    = %d (%d)\n",  !!(uEdxGst & RT_BIT(13)),  !!(uEdxHst & RT_BIT(13)));
    2560             pHlp->pfnPrintf(pHlp, "14 - Reserved                          = %d (%d)\n",  !!(uEdxGst & RT_BIT(14)),  !!(uEdxHst & RT_BIT(14)));
    2561             pHlp->pfnPrintf(pHlp, "15 - Reserved                          = %d (%d)\n",  !!(uEdxGst & RT_BIT(15)),  !!(uEdxHst & RT_BIT(15)));
    2562             pHlp->pfnPrintf(pHlp, "Parallax                               = %d (%d)\n",  !!(uEdxGst & RT_BIT(16)),  !!(uEdxHst & RT_BIT(16)));
    2563             pHlp->pfnPrintf(pHlp, "Parallax enabled                       = %d (%d)\n",  !!(uEdxGst & RT_BIT(17)),  !!(uEdxHst & RT_BIT(17)));
    2564             pHlp->pfnPrintf(pHlp, "Overstress                             = %d (%d)\n",  !!(uEdxGst & RT_BIT(18)),  !!(uEdxHst & RT_BIT(18)));
    2565             pHlp->pfnPrintf(pHlp, "Overstress enabled                     = %d (%d)\n",  !!(uEdxGst & RT_BIT(19)),  !!(uEdxHst & RT_BIT(19)));
    2566             pHlp->pfnPrintf(pHlp, "TM3 - Temperature Monitoring 3         = %d (%d)\n",  !!(uEdxGst & RT_BIT(20)),  !!(uEdxHst & RT_BIT(20)));
    2567             pHlp->pfnPrintf(pHlp, "TM3-E - TM3 enabled                    = %d (%d)\n",  !!(uEdxGst & RT_BIT(21)),  !!(uEdxHst & RT_BIT(21)));
    2568             pHlp->pfnPrintf(pHlp, "RNG2 - Random Number Generator 2       = %d (%d)\n",  !!(uEdxGst & RT_BIT(22)),  !!(uEdxHst & RT_BIT(22)));
    2569             pHlp->pfnPrintf(pHlp, "RNG2-E - RNG2 enabled                  = %d (%d)\n",  !!(uEdxGst & RT_BIT(23)),  !!(uEdxHst & RT_BIT(23)));
    2570             pHlp->pfnPrintf(pHlp, "24 - Reserved                          = %d (%d)\n",  !!(uEdxGst & RT_BIT(24)),  !!(uEdxHst & RT_BIT(24)));
    2571             pHlp->pfnPrintf(pHlp, "PHE2 - Padlock Hash Engine 2           = %d (%d)\n",  !!(uEdxGst & RT_BIT(25)),  !!(uEdxHst & RT_BIT(25)));
    2572             pHlp->pfnPrintf(pHlp, "PHE2-E - PHE2 enabled                  = %d (%d)\n",  !!(uEdxGst & RT_BIT(26)),  !!(uEdxHst & RT_BIT(26)));
    2573             for (unsigned iBit = 27; iBit < 32; iBit++)
    2574                 if ((uEdxGst | uEdxHst) & RT_BIT(iBit))
    2575                     pHlp->pfnPrintf(pHlp, "Bit %d                                 = %d (%d)\n", iBit, !!(uEdxGst & RT_BIT(iBit)), !!(uEdxHst & RT_BIT(iBit)));
    2576             pHlp->pfnPrintf(pHlp, "\n");
    2577         }
    2578     }
    2579 }
    2580 
    2581 
    25821802/**
    25831803 * Structure used when disassembling and instructions in DBGF.
  • trunk/src/VBox/VMM/VMMR3/CPUMR3CpuId.cpp

    r54714 r54737  
    2121#define LOG_GROUP LOG_GROUP_CPUM
    2222#include <VBox/vmm/cpum.h>
     23#include <VBox/vmm/dbgf.h>
    2324#include <VBox/vmm/hm.h>
    2425#include <VBox/vmm/ssm.h>
     
    3233#include <iprt/mem.h>
    3334#include <iprt/string.h>
     35
     36
     37/*******************************************************************************
     38*   Defined Constants And Macros                                               *
     39*******************************************************************************/
     40/** For sanity and avoid wasting hyper heap on buggy config / saved state. */
     41#define CPUM_CPUID_MAX_LEAVES       2048
    3442
    3543
     
    514522 * @param   uSubLeaf            The subleaf to locate.  Pass 0 if no subleaves.
    515523 */
    516 PCPUMCPUIDLEAF cpumR3CpuIdGetLeaf(PCPUMCPUIDLEAF paLeaves, uint32_t cLeaves, uint32_t uLeaf, uint32_t uSubLeaf)
     524static PCPUMCPUIDLEAF cpumR3CpuIdGetLeaf(PCPUMCPUIDLEAF paLeaves, uint32_t cLeaves, uint32_t uLeaf, uint32_t uSubLeaf)
    517525{
    518526    /* Lazy bird does linear lookup here since this is only used for the
     
    536544 * @param   pLegacy             The legacy output leaf.
    537545 */
    538 bool cpumR3CpuIdGetLeafLegacy(PCPUMCPUIDLEAF paLeaves, uint32_t cLeaves, uint32_t uLeaf, uint32_t uSubLeaf, PCPUMCPUID pLegacy)
     546static bool cpumR3CpuIdGetLeafLegacy(PCPUMCPUIDLEAF paLeaves, uint32_t cLeaves, uint32_t uLeaf, uint32_t uSubLeaf,
     547                                     PCPUMCPUID pLegacy)
    539548{
    540549    PCPUMCPUIDLEAF pLeaf = cpumR3CpuIdGetLeaf(paLeaves, cLeaves, uLeaf, uSubLeaf);
     
    569578static PCPUMCPUIDLEAF cpumR3CpuIdEnsureSpace(PVM pVM, PCPUMCPUIDLEAF *ppaLeaves, uint32_t cLeaves)
    570579{
     580    /*
     581     * If pVM is not specified, we're on the regular heap and can waste a
     582     * little space to speed things up.
     583     */
    571584    uint32_t cAllocated;
    572585    if (!pVM)
     586    {
    573587        cAllocated = RT_ALIGN(cLeaves, 16);
    574     else
    575     {
    576         /*
    577          * We're using the hyper heap now, but when the arrays were copied over to it from
    578          * the host-context heap, we only copy the exact size and not the ensured size.
    579          * See @bugref{7270}.
    580          */
    581         cAllocated = cLeaves;
    582     }
    583 
    584     if (cLeaves + 1 > cAllocated)
    585     {
    586         void *pvNew;
    587 #ifndef IN_VBOX_CPU_REPORT
    588         if (pVM)
    589         {
    590             Assert(ppaLeaves == &pVM->cpum.s.GuestInfo.paCpuIdLeavesR3);
    591             Assert(cLeaves == pVM->cpum.s.GuestInfo.cCpuIdLeaves);
    592 
    593             size_t cb    = cAllocated * sizeof(**ppaLeaves);
    594             size_t cbNew = (cAllocated + 16) * sizeof(**ppaLeaves);
    595             int rc = MMR3HyperRealloc(pVM, *ppaLeaves, cb, 32, MM_TAG_CPUM_CPUID, cbNew, &pvNew);
    596             if (RT_FAILURE(rc))
    597             {
    598                 *ppaLeaves = NULL;
    599                 pVM->cpum.s.GuestInfo.paCpuIdLeavesR0 = NIL_RTR0PTR;
    600                 pVM->cpum.s.GuestInfo.paCpuIdLeavesRC = NIL_RTRCPTR;
    601                 LogRel(("CPUM: cpumR3CpuIdEnsureSpace: MMR3HyperRealloc failed. rc=%Rrc\n", rc));
    602                 return NULL;
    603             }
    604             *ppaLeaves = (PCPUMCPUIDLEAF)pvNew;
    605         }
    606         else
    607 #endif
    608         {
    609             pvNew = RTMemRealloc(*ppaLeaves, (cAllocated + 16) * sizeof(**ppaLeaves));
    610             if (!pvNew)
     588        if (cLeaves + 1 > cAllocated)
     589        {
     590            void *pvNew = RTMemRealloc(*ppaLeaves, (cAllocated + 16) * sizeof(**ppaLeaves));
     591            if (pvNew)
     592                *ppaLeaves = (PCPUMCPUIDLEAF)pvNew;
     593            else
    611594            {
    612595                RTMemFree(*ppaLeaves);
    613596                *ppaLeaves = NULL;
    614                 return NULL;
    615597            }
    616             *ppaLeaves = (PCPUMCPUIDLEAF)pvNew;
    617         }
    618     }
    619 
    620 #ifndef IN_VBOX_CPU_REPORT
    621     /* Update the R0 and RC pointers. */
    622     if (pVM)
    623     {
     598        }
     599    }
     600    /*
     601     * Otherwise, we're on the hyper heap and are probably just inserting
     602     * one or two leaves and should conserve space.
     603     */
     604    else
     605    {
     606#ifdef IN_VBOX_CPU_REPORT
     607        AssertReleaseFailed();
     608#else
    624609        Assert(ppaLeaves == &pVM->cpum.s.GuestInfo.paCpuIdLeavesR3);
    625         pVM->cpum.s.GuestInfo.paCpuIdLeavesR0 = MMHyperR3ToR0(pVM, *ppaLeaves);
    626         pVM->cpum.s.GuestInfo.paCpuIdLeavesRC = MMHyperR3ToRC(pVM, *ppaLeaves);
    627     }
     610        Assert(cLeaves == pVM->cpum.s.GuestInfo.cCpuIdLeaves);
     611
     612        size_t cb    = cLeaves       * sizeof(**ppaLeaves);
     613        size_t cbNew = (cLeaves + 1) * sizeof(**ppaLeaves);
     614        int rc = MMR3HyperRealloc(pVM, *ppaLeaves, cb, 32, MM_TAG_CPUM_CPUID, cbNew, (void **)ppaLeaves);
     615        if (RT_SUCCESS(rc))
     616        {
     617            /* Update the R0 and RC pointers. */
     618            pVM->cpum.s.GuestInfo.paCpuIdLeavesR0 = MMHyperR3ToR0(pVM, *ppaLeaves);
     619            pVM->cpum.s.GuestInfo.paCpuIdLeavesRC = MMHyperR3ToRC(pVM, *ppaLeaves);
     620        }
     621        else
     622        {
     623            *ppaLeaves = NULL;
     624            pVM->cpum.s.GuestInfo.paCpuIdLeavesR0 = NIL_RTR0PTR;
     625            pVM->cpum.s.GuestInfo.paCpuIdLeavesRC = NIL_RTRCPTR;
     626            LogRel(("CPUM: cpumR3CpuIdEnsureSpace: MMR3HyperRealloc failed. rc=%Rrc\n", rc));
     627        }
    628628#endif
    629 
     629    }
    630630    return *ppaLeaves;
    631631}
     
    700700 *                          insert.
    701701 */
    702 int cpumR3CpuIdInsert(PVM pVM, PCPUMCPUIDLEAF *ppaLeaves, uint32_t *pcLeaves, PCPUMCPUIDLEAF pNewLeaf)
     702static int cpumR3CpuIdInsert(PVM pVM, PCPUMCPUIDLEAF *ppaLeaves, uint32_t *pcLeaves, PCPUMCPUIDLEAF pNewLeaf)
    703703{
    704704    /*
     
    720720     * Validate the new leaf a little.
    721721     */
    722     AssertReturn(!(pNewLeaf->fFlags & ~CPUMCPUIDLEAF_F_SUBLEAVES_ECX_UNCHANGED), VERR_INVALID_FLAGS);
     722    AssertReturn(!(pNewLeaf->fFlags & ~CPUMCPUIDLEAF_F_VALID_MASK), VERR_INVALID_FLAGS);
    723723    AssertReturn(pNewLeaf->fSubLeafMask != 0 || pNewLeaf->uSubLeaf == 0, VERR_INVALID_PARAMETER);
    724724    AssertReturn(RT_IS_POWER_OF_TWO(pNewLeaf->fSubLeafMask + 1), VERR_INVALID_PARAMETER);
     
    726726
    727727    /*
    728      * Find insertion point. The lazy bird uses the same excuse as in
    729      * cpumR3CpuIdGetLeaf().
    730      */
    731     uint32_t i = 0;
    732     while (   i < cLeaves
    733            && paLeaves[i].uLeaf < pNewLeaf->uLeaf)
    734         i++;
     728     * Find insertion point.  The lazy bird uses the same excuse as in
     729     * cpumR3CpuIdGetLeaf(), but optimizes for linear insertion (saved state).
     730     */
     731    uint32_t i;
     732    if (   cLeaves > 0
     733        && paLeaves[cLeaves - 1].uLeaf < pNewLeaf->uLeaf)
     734    {
     735        /* Add at end. */
     736        i = cLeaves;
     737    }
     738    else if (   cLeaves > 0
     739             && paLeaves[cLeaves - 1].uLeaf == pNewLeaf->uLeaf)
     740    {
     741        /* Either replacing the last leaf or dealing with sub-leaves. Spool
     742           back to the first sub-leaf to pretend we did the linear search. */
     743        i = cLeaves - 1;
     744        while (   i > 0
     745               && paLeaves[i - 1].uLeaf == pNewLeaf->uLeaf)
     746            i--;
     747    }
     748    else
     749    {
     750        /* Linear search from the start. */
     751        i = 0;
     752        while (   i < cLeaves
     753                  && paLeaves[i].uLeaf < pNewLeaf->uLeaf)
     754            i++;
     755    }
    735756    if (   i < cLeaves
    736757        && paLeaves[i].uLeaf == pNewLeaf->uLeaf)
     
    739760        {
    740761            /*
    741              * The subleaf mask differs, replace all existing leaves with the
     762             * The sub-leaf mask differs, replace all existing leaves with the
    742763             * same leaf number.
    743764             */
    744765            uint32_t c = 1;
    745766            while (   i + c < cLeaves
    746                    && paLeaves[i + c].uSubLeaf == pNewLeaf->uLeaf)
     767                   && paLeaves[i + c].uLeaf == pNewLeaf->uLeaf)
    747768                c++;
    748769            if (c > 1 && i + c < cLeaves)
     
    756777        }
    757778
    758         /* Find subleaf insertion point. */
     779        /* Find sub-leaf insertion point. */
    759780        while (   i < cLeaves
    760781               && paLeaves[i].uSubLeaf < pNewLeaf->uSubLeaf)
     
    775796     * Adding a new leaf at 'i'.
    776797     */
     798    AssertLogRelReturn(cLeaves < CPUM_CPUID_MAX_LEAVES, VERR_TOO_MANY_CPUID_LEAVES);
    777799    paLeaves = cpumR3CpuIdEnsureSpace(pVM, ppaLeaves, cLeaves);
    778800    if (!paLeaves)
     
    797819 * @param   uLast           The last leaf.
    798820 */
    799 void cpumR3CpuIdRemoveRange(PCPUMCPUIDLEAF paLeaves, uint32_t *pcLeaves, uint32_t uFirst, uint32_t uLast)
     821static void cpumR3CpuIdRemoveRange(PCPUMCPUIDLEAF paLeaves, uint32_t *pcLeaves, uint32_t uFirst, uint32_t uLast)
    800822{
    801823    uint32_t cLeaves = *pcLeaves;
     
    839861 * @param   pcSubLeaves         Number of sub-leaves accessible via ECX.
    840862 * @param   pfFinalEcxUnchanged Whether ECX is passed thru when going beyond the
    841  *                              final sub-leaf.
     863 *                              final sub-leaf (for leaf 0xb only).
    842864 */
    843865static bool cpumR3IsEcxRelevantForCpuIdLeaf(uint32_t uLeaf, uint32_t *pcSubLeaves, bool *pfFinalEcxUnchanged)
     
    919941            if (cDocLimit != UINT32_MAX)
    920942            {
    921                 *pfFinalEcxUnchanged = auCur[2] == uSubLeaf;
     943                *pfFinalEcxUnchanged = auCur[2] == uSubLeaf && uLeaf == 0xb;
    922944                *pcSubLeaves = cDocLimit + 3;
    923945                return true;
     
    934956
    935957    /* Standard exit. */
    936     *pfFinalEcxUnchanged = auCur[2] == uSubLeaf;
     958    *pfFinalEcxUnchanged = auCur[2] == uSubLeaf && uLeaf == 0xb;
    937959    *pcSubLeaves = uSubLeaf + 1 - cRepeats;
    938960    return true;
     
    9841006     */
    9851007    if (   pNewLeaf->uLeaf == UINT32_C(0x00000000)  /* Standard */
     1008        || pNewLeaf->uLeaf == UINT32_C(0x00000001)
    9861009        || pNewLeaf->uLeaf == UINT32_C(0x80000000)  /* Extended */
    987         || pNewLeaf->uLeaf == UINT32_C(0xc0000000)) /* Centaur */
     1010        || pNewLeaf->uLeaf == UINT32_C(0x80000001)
     1011        || pNewLeaf->uLeaf == UINT32_C(0xc0000000)  /* Centaur */
     1012        || pNewLeaf->uLeaf == UINT32_C(0xc0000001) )
    9881013    {
    9891014        return VERR_NOT_SUPPORTED;
     
    10491074            while (cLeaves-- > 0)
    10501075            {
     1076                ASMCpuIdExSlow(uLeaf, 0, 0, 0, &uEax, &uEbx, &uEcx, &uEdx);
     1077
     1078                uint32_t fFlags = 0;
     1079
     1080                /* There are currently three known leaves containing an APIC ID
     1081                   that needs EMT specific attention */
     1082                if (uLeaf == 1)
     1083                    fFlags |= CPUMCPUIDLEAF_F_CONTAINS_APIC_ID;
     1084                else if (uLeaf == 0xb && uEcx != 0)
     1085                    fFlags |= CPUMCPUIDLEAF_F_CONTAINS_APIC_ID;
     1086                else if (   uLeaf == UINT32_C(0x8000001e)
     1087                         && (   uEax
     1088                             || uEbx
     1089                             || uEdx
     1090                             || ASMIsAmdCpuEx((*ppaLeaves)[0].uEbx, (*ppaLeaves)[0].uEcx, (*ppaLeaves)[0].uEdx)) )
     1091                    fFlags |= CPUMCPUIDLEAF_F_CONTAINS_APIC_ID;
     1092
     1093
    10511094                /* Check three times here to reduce the chance of CPU migration
    10521095                   resulting in false positives with things like the APIC ID. */
     
    10791122                    }
    10801123
     1124                    if (fFinalEcxUnchanged)
     1125                        fFlags |= CPUMCPUIDLEAF_F_INTEL_TOPOLOGY_SUBLEAVES;
     1126
    10811127                    for (uint32_t uSubLeaf = 0; uSubLeaf < cSubLeaves; uSubLeaf++)
    10821128                    {
    10831129                        ASMCpuIdExSlow(uLeaf, 0, uSubLeaf, 0, &uEax, &uEbx, &uEcx, &uEdx);
    10841130                        int rc = cpumR3CollectCpuIdInfoAddOne(ppaLeaves, pcLeaves,
    1085                                                               uLeaf, uSubLeaf, UINT32_MAX, uEax, uEbx, uEcx, uEdx,
    1086                                                               uSubLeaf + 1 == cSubLeaves && fFinalEcxUnchanged
    1087                                                               ? CPUMCPUIDLEAF_F_SUBLEAVES_ECX_UNCHANGED : 0);
     1131                                                              uLeaf, uSubLeaf, UINT32_MAX, uEax, uEbx, uEcx, uEdx, fFlags);
    10881132                        if (RT_FAILURE(rc))
    10891133                            return rc;
     
    10921136                else
    10931137                {
    1094                     ASMCpuIdExSlow(uLeaf, 0, 0, 0, &uEax, &uEbx, &uEcx, &uEdx);
    10951138                    int rc = cpumR3CollectCpuIdInfoAddOne(ppaLeaves, pcLeaves,
    1096                                                           uLeaf, 0, 0, uEax, uEbx, uEcx, uEdx, 0);
     1139                                                          uLeaf, 0, 0, uEax, uEbx, uEcx, uEdx, fFlags);
    10971140                    if (RT_FAILURE(rc))
    10981141                        return rc;
     
    11531196 *                              doesn't actually needs it.
    11541197 */
    1155 VMMR3DECL(int) CPUMR3CpuIdDetectUnknownLeafMethod(PCPUMUKNOWNCPUID penmUnknownMethod, PCPUMCPUID pDefUnknown)
     1198VMMR3DECL(int) CPUMR3CpuIdDetectUnknownLeafMethod(PCPUMUNKNOWNCPUID penmUnknownMethod, PCPUMCPUID pDefUnknown)
    11561199{
    11571200    uint32_t uLastStd = ASMCpuId_EAX(0);
     
    11941237     * Simple method, all zeros.
    11951238     */
    1196     *penmUnknownMethod = CPUMUKNOWNCPUID_DEFAULTS;
     1239    *penmUnknownMethod = CPUMUNKNOWNCPUID_DEFAULTS;
    11971240    pDefUnknown->uEax = 0;
    11981241    pDefUnknown->uEbx = 0;
     
    12531296        Log(("CPUM: cNeither=%d cSame=%d cLastWithEcx=%d cTotal=%d\n", cNeither, cSame, cLastWithEcx, cTotal));
    12541297        if (cSame == cTotal)
    1255             *penmUnknownMethod = CPUMUKNOWNCPUID_LAST_STD_LEAF;
     1298            *penmUnknownMethod = CPUMUNKNOWNCPUID_LAST_STD_LEAF;
    12561299        else if (cLastWithEcx == cTotal)
    1257             *penmUnknownMethod = CPUMUKNOWNCPUID_LAST_STD_LEAF_WITH_ECX;
     1300            *penmUnknownMethod = CPUMUNKNOWNCPUID_LAST_STD_LEAF_WITH_ECX;
    12581301        else
    1259             *penmUnknownMethod = CPUMUKNOWNCPUID_LAST_STD_LEAF;
     1302            *penmUnknownMethod = CPUMUNKNOWNCPUID_LAST_STD_LEAF;
    12601303        pDefUnknown->uEax = auLast[0];
    12611304        pDefUnknown->uEbx = auLast[1];
     
    12911334    if (cChecks == 0)
    12921335    {
    1293         *penmUnknownMethod = CPUMUKNOWNCPUID_PASSTHRU;
     1336        *penmUnknownMethod = CPUMUNKNOWNCPUID_PASSTHRU;
    12941337        return VINF_SUCCESS;
    12951338    }
     
    13081351 * @param   enmUnknownMethod    The method to translate.
    13091352 */
    1310 VMMR3DECL(const char *) CPUMR3CpuIdUnknownLeafMethodName(CPUMUKNOWNCPUID enmUnknownMethod)
     1353VMMR3DECL(const char *) CPUMR3CpuIdUnknownLeafMethodName(CPUMUNKNOWNCPUID enmUnknownMethod)
    13111354{
    13121355    switch (enmUnknownMethod)
    13131356    {
    1314         case CPUMUKNOWNCPUID_DEFAULTS:                  return "DEFAULTS";
    1315         case CPUMUKNOWNCPUID_LAST_STD_LEAF:             return "LAST_STD_LEAF";
    1316         case CPUMUKNOWNCPUID_LAST_STD_LEAF_WITH_ECX:    return "LAST_STD_LEAF_WITH_ECX";
    1317         case CPUMUKNOWNCPUID_PASSTHRU:                  return "PASSTHRU";
    1318 
    1319         case CPUMUKNOWNCPUID_INVALID:
    1320         case CPUMUKNOWNCPUID_END:
    1321         case CPUMUKNOWNCPUID_32BIT_HACK:
     1357        case CPUMUNKNOWNCPUID_DEFAULTS:                  return "DEFAULTS";
     1358        case CPUMUNKNOWNCPUID_LAST_STD_LEAF:             return "LAST_STD_LEAF";
     1359        case CPUMUNKNOWNCPUID_LAST_STD_LEAF_WITH_ECX:    return "LAST_STD_LEAF_WITH_ECX";
     1360        case CPUMUNKNOWNCPUID_PASSTHRU:                  return "PASSTHRU";
     1361
     1362        case CPUMUNKNOWNCPUID_INVALID:
     1363        case CPUMUNKNOWNCPUID_END:
     1364        case CPUMUNKNOWNCPUID_32BIT_HACK:
    13221365            break;
    13231366    }
     
    15001543#ifdef VBOX_IN_VMM
    15011544
     1545
     1546/**
     1547 * Gets an exactly matching leaf + sub-leaf in the CPUID leaf array.
     1548 *
     1549 * This ignores the fSubLeafMask.
     1550 *
     1551 * @returns Pointer to the matching leaf, or NULL if not found.
     1552 * @param   paLeaves            The CPUID leaves to search.  This is sorted.
     1553 * @param   cLeaves             The number of leaves in the array.
     1554 * @param   uLeaf               The leaf to locate.
     1555 * @param   uSubLeaf            The subleaf to locate.
     1556 */
     1557static PCPUMCPUIDLEAF cpumR3CpuIdGetExactLeaf(PCPUM pCpum, uint32_t uLeaf, uint32_t uSubLeaf)
     1558{
     1559    uint64_t        uNeedle   = RT_MAKE_U64(uSubLeaf, uLeaf);
     1560    PCPUMCPUIDLEAF  paLeaves  = pCpum->GuestInfo.paCpuIdLeavesR3;
     1561    uint32_t        iEnd      = pCpum->GuestInfo.cCpuIdLeaves;
     1562    if (iEnd)
     1563    {
     1564        uint32_t    iBegin   = 0;
     1565        for (;;)
     1566        {
     1567            uint32_t const i    = (iEnd - iBegin) / 2 + iBegin;
     1568            uint64_t const uCur = RT_MAKE_U64(paLeaves[i].uSubLeaf, paLeaves[i].uLeaf);
     1569            if (uNeedle < uCur)
     1570            {
     1571                if (i > iBegin)
     1572                    iEnd = i;
     1573                else
     1574                    break;
     1575            }
     1576            else if (uNeedle > uCur)
     1577            {
     1578                if (i + 1 < iEnd)
     1579                    iBegin = i + 1;
     1580                else
     1581                    break;
     1582            }
     1583            else
     1584                return &paLeaves[i];
     1585        }
     1586    }
     1587    return NULL;
     1588}
     1589
     1590
    15021591/**
    15031592 * Loads MSR range overrides.
     
    16321721         * register, without needing to know the other values.
    16331722         */
    1634         PCCPUMCPUIDLEAF pLeaf = cpumR3CpuIdGetLeaf(pVM->cpum.s.GuestInfo.paCpuIdLeavesR3, pVM->cpum.s.GuestInfo.cCpuIdLeaves,
    1635                                                    uLeaf, uSubLeaf);
     1723        PCCPUMCPUIDLEAF pLeaf = cpumR3CpuIdGetExactLeaf(&pVM->cpum.s, uLeaf, uSubLeaf);
    16361724        CPUMCPUIDLEAF   Leaf;
    16371725        if (pLeaf)
     
    17611849
    17621850
    1763 static int cpumR3CpuIdInstallAndExplodeLeaves(PVM pVM, PCPUM pCPUM, PCPUMCPUIDLEAF paLeaves, uint32_t cLeaves)
     1851static int cpumR3CpuIdInstallAndExplodeLeaves(PVM pVM, PCPUM pCpum, PCPUMCPUIDLEAF paLeaves, uint32_t cLeaves)
    17641852{
    17651853    /*
     
    17671855     */
    17681856    int rc = MMHyperDupMem(pVM, paLeaves, sizeof(paLeaves[0]) * cLeaves, 32,
    1769                            MM_TAG_CPUM_CPUID, (void **)&pCPUM->GuestInfo.paCpuIdLeavesR3);
     1857                           MM_TAG_CPUM_CPUID, (void **)&pCpum->GuestInfo.paCpuIdLeavesR3);
    17701858
    17711859    AssertLogRelRCReturn(rc, rc);
    17721860
    17731861
    1774     pCPUM->GuestInfo.paCpuIdLeavesR0 = MMHyperR3ToR0(pVM, pCPUM->GuestInfo.paCpuIdLeavesR3);
    1775     pCPUM->GuestInfo.paCpuIdLeavesRC = MMHyperR3ToRC(pVM, pCPUM->GuestInfo.paCpuIdLeavesR3);
    1776     Assert(MMHyperR0ToR3(pVM, pCPUM->GuestInfo.paCpuIdLeavesR0) == (void *)pCPUM->GuestInfo.paCpuIdLeavesR3);
    1777     Assert(MMHyperRCToR3(pVM, pCPUM->GuestInfo.paCpuIdLeavesRC) == (void *)pCPUM->GuestInfo.paCpuIdLeavesR3);
     1862    pCpum->GuestInfo.paCpuIdLeavesR0 = MMHyperR3ToR0(pVM, pCpum->GuestInfo.paCpuIdLeavesR3);
     1863    pCpum->GuestInfo.paCpuIdLeavesRC = MMHyperR3ToRC(pVM, pCpum->GuestInfo.paCpuIdLeavesR3);
     1864    Assert(MMHyperR0ToR3(pVM, pCpum->GuestInfo.paCpuIdLeavesR0) == (void *)pCpum->GuestInfo.paCpuIdLeavesR3);
     1865    Assert(MMHyperRCToR3(pVM, pCpum->GuestInfo.paCpuIdLeavesRC) == (void *)pCpum->GuestInfo.paCpuIdLeavesR3);
     1866
     1867    /*
     1868     * Update the default CPUID leaf if necessary.
     1869     */
     1870    switch (pCpum->GuestInfo.enmUnknownCpuIdMethod)
     1871    {
     1872        case CPUMUNKNOWNCPUID_LAST_STD_LEAF:
     1873        case CPUMUNKNOWNCPUID_LAST_STD_LEAF_WITH_ECX:
     1874        {
     1875            /* We don't use CPUID(0).eax here because of the NT hack that only
     1876               changes that value without actually removing any leaves. */
     1877            uint32_t i = 0;
     1878            if (   pCpum->GuestInfo.cCpuIdLeaves > 0
     1879                && pCpum->GuestInfo.paCpuIdLeavesR3[0].uEax <= UINT32_C(0xff))
     1880            {
     1881                while (   i + 1 < pCpum->GuestInfo.cCpuIdLeaves
     1882                       && pCpum->GuestInfo.paCpuIdLeavesR3[i + 1].uEax <= UINT32_C(0xff))
     1883                    i++;
     1884                pCpum->GuestInfo.DefCpuId.uEax = pCpum->GuestInfo.paCpuIdLeavesR3[i].uEax;
     1885                pCpum->GuestInfo.DefCpuId.uEbx = pCpum->GuestInfo.paCpuIdLeavesR3[i].uEbx;
     1886                pCpum->GuestInfo.DefCpuId.uEcx = pCpum->GuestInfo.paCpuIdLeavesR3[i].uEcx;
     1887                pCpum->GuestInfo.DefCpuId.uEdx = pCpum->GuestInfo.paCpuIdLeavesR3[i].uEdx;
     1888            }
     1889            break;
     1890        }
     1891        default:
     1892            break;
     1893    }
    17781894
    17791895    /*
    17801896     * Explode the guest CPU features.
    17811897     */
    1782     rc = cpumR3CpuIdExplodeFeatures(pCPUM->GuestInfo.paCpuIdLeavesR3, pCPUM->GuestInfo.cCpuIdLeaves, &pCPUM->GuestFeatures);
     1898    rc = cpumR3CpuIdExplodeFeatures(pCpum->GuestInfo.paCpuIdLeavesR3, pCpum->GuestInfo.cCpuIdLeaves, &pCpum->GuestFeatures);
    17831899    AssertLogRelRCReturn(rc, rc);
    17841900
     
    17881904     */
    17891905    if (CPUMMICROARCH_IS_INTEL_CORE7(pVM->cpum.s.GuestFeatures.enmMicroarch))
    1790         pCPUM->GuestInfo.uScalableBusFreq = pCPUM->GuestFeatures.enmMicroarch >= kCpumMicroarch_Intel_Core7_SandyBridge
     1906        pCpum->GuestInfo.uScalableBusFreq = pCpum->GuestFeatures.enmMicroarch >= kCpumMicroarch_Intel_Core7_SandyBridge
    17911907                                          ? UINT64_C(100000000)  /* 100MHz */
    17921908                                          : UINT64_C(133333333); /* 133MHz */
     
    17981914    struct { PCPUMCPUID paCpuIds; uint32_t cCpuIds, uBase; } aOldRanges[] =
    17991915    {
    1800         { pCPUM->aGuestCpuIdPatmStd,        RT_ELEMENTS(pCPUM->aGuestCpuIdPatmStd),     0x00000000 },
    1801         { pCPUM->aGuestCpuIdPatmExt,        RT_ELEMENTS(pCPUM->aGuestCpuIdPatmExt),     0x80000000 },
    1802         { pCPUM->aGuestCpuIdPatmCentaur,    RT_ELEMENTS(pCPUM->aGuestCpuIdPatmCentaur), 0xc0000000 },
     1916        { pCpum->aGuestCpuIdPatmStd,        RT_ELEMENTS(pCpum->aGuestCpuIdPatmStd),     0x00000000 },
     1917        { pCpum->aGuestCpuIdPatmExt,        RT_ELEMENTS(pCpum->aGuestCpuIdPatmExt),     0x80000000 },
     1918        { pCpum->aGuestCpuIdPatmCentaur,    RT_ELEMENTS(pCpum->aGuestCpuIdPatmCentaur), 0xc0000000 },
    18031919    };
    18041920    for (uint32_t i = 0; i < RT_ELEMENTS(aOldRanges); i++)
     
    18121928            pLegacyLeaf--;
    18131929
    1814             PCCPUMCPUIDLEAF pLeaf = cpumR3CpuIdGetLeaf(pCPUM->GuestInfo.paCpuIdLeavesR3, pCPUM->GuestInfo.cCpuIdLeaves, uLeaf,
    1815                                                        0 /* uSubLeaf */);
     1930            PCCPUMCPUIDLEAF pLeaf = cpumR3CpuIdGetExactLeaf(pCpum, uLeaf, 0 /* uSubLeaf */);
    18161931            if (pLeaf)
    18171932            {
     
    18221937            }
    18231938            else
    1824                 *pLegacyLeaf = pCPUM->GuestInfo.DefCpuId;
    1825         }
    1826     }
    1827 
    1828     pCPUM->GuestCpuIdPatmDef = pCPUM->GuestInfo.DefCpuId;
     1939                *pLegacyLeaf = pCpum->GuestInfo.DefCpuId;
     1940        }
     1941    }
    18291942
    18301943    return VINF_SUCCESS;
     
    18331946
    18341947/**
    1835  * Initializes the emulated CPU's cpuid information.
     1948 * CPUID Configuration (from CFGM).
     1949 *
     1950 * @remarks  The members aren't document since we would only be duplicating the
     1951 *           \@cfgm entries in cpumR3CpuIdReadConfig.
     1952 */
     1953typedef struct CPUMCPUIDCONFIG
     1954{
     1955    bool        fSyntheticCpu;
     1956    bool        fCmpXchg16b;
     1957    bool        fMonitor;
     1958    bool        fMWaitExtensions;
     1959    bool        fSse41;
     1960    bool        fSse42;
     1961    bool        fNt4LeafLimit;
     1962    bool        fInvariantTsc;
     1963    uint32_t    uMaxIntelFamilyModelStep;
     1964    char        szCpuName[128];
     1965} CPUMCPUIDCONFIG;
     1966/** Pointer to CPUID config (from CFGM). */
     1967typedef CPUMCPUIDCONFIG *PCPUMCPUIDCONFIG;
     1968
     1969
     1970/**
     1971 * Insert hypervisor identification leaves.
     1972 *
     1973 * We only return minimal information, primarily ensuring that the
     1974 * 0x40000000 function returns 0x40000001 and identifying ourselves.
     1975 * Hypervisor-specific interface is supported through GIM which will
     1976 * modify these leaves if required depending on the GIM provider.
    18361977 *
    18371978 * @returns VBox status code.
    1838  * @param   pVM          Pointer to the VM.
    1839  */
    1840 int cpumR3CpuIdInit(PVM pVM)
     1979 * @param   pCpum       The CPUM instance data.
     1980 * @param   pConfig     The CPUID configuration we've read from CFGM.
     1981 */
     1982static int cpumR3CpuIdPlantHypervisorLeaves(PCPUM pCpum, PCPUMCPUIDCONFIG pConfig)
    18411983{
    1842     PCPUM       pCPUM    = &pVM->cpum.s;
    1843     PCFGMNODE   pCpumCfg = CFGMR3GetChild(CFGMR3GetRoot(pVM), "CPUM");
    1844     int         rc;
    1845 
     1984    CPUMCPUIDLEAF NewLeaf;
     1985    NewLeaf.uLeaf        = UINT32_C(0x40000000);
     1986    NewLeaf.uSubLeaf     = 0;
     1987    NewLeaf.fSubLeafMask = 0;
     1988    NewLeaf.uEax         = UINT32_C(0x40000001);
     1989    NewLeaf.uEbx         = 0x786f4256 /* 'VBox' */;
     1990    NewLeaf.uEcx         = 0x786f4256 /* 'VBox' */;
     1991    NewLeaf.uEdx         = 0x786f4256 /* 'VBox' */;
     1992    NewLeaf.fFlags       = 0;
     1993    int rc = cpumR3CpuIdInsert(NULL /* pVM */, &pCpum->GuestInfo.paCpuIdLeavesR3, &pCpum->GuestInfo.cCpuIdLeaves, &NewLeaf);
     1994    AssertLogRelRCReturn(rc, rc);
     1995
     1996    NewLeaf.uLeaf        = UINT32_C(0x40000001);
     1997    NewLeaf.uEax         = 0x656e6f6e;                            /* 'none' */
     1998    NewLeaf.uEbx         = 0;
     1999    NewLeaf.uEcx         = 0;
     2000    NewLeaf.uEdx         = 0;
     2001    NewLeaf.fFlags       = 0;
     2002    rc = cpumR3CpuIdInsert(NULL /* pVM */, &pCpum->GuestInfo.paCpuIdLeavesR3, &pCpum->GuestInfo.cCpuIdLeaves, &NewLeaf);
     2003    AssertLogRelRCReturn(rc, rc);
     2004
     2005    return VINF_SUCCESS;
     2006}
     2007
     2008
     2009/**
     2010 * Mini CPU selection support for making Mac OS X happy.
     2011 *
     2012 * Executes the  /CPUM/MaxIntelFamilyModelStep config.
     2013 *
     2014 * @param   pCpum       The CPUM instance data.
     2015 * @param   pConfig     The CPUID configuration we've read from CFGM.
     2016 */
     2017static void cpumR3CpuIdLimitIntelFamModStep(PCPUM pCpum, PCPUMCPUIDCONFIG pConfig)
     2018{
     2019    if (pCpum->GuestFeatures.enmCpuVendor == CPUMCPUVENDOR_INTEL)
     2020    {
     2021        PCPUMCPUIDLEAF pStdFeatureLeaf = cpumR3CpuIdGetExactLeaf(pCpum, 1, 0);
     2022        uint32_t uCurIntelFamilyModelStep = RT_MAKE_U32_FROM_U8(ASMGetCpuStepping(pStdFeatureLeaf->uEax),
     2023                                                                ASMGetCpuModelIntel(pStdFeatureLeaf->uEax),
     2024                                                                ASMGetCpuFamily(pStdFeatureLeaf->uEax),
     2025                                                                0);
     2026        uint32_t uMaxIntelFamilyModelStep = pConfig->uMaxIntelFamilyModelStep;
     2027        if (pConfig->uMaxIntelFamilyModelStep < uCurIntelFamilyModelStep)
     2028        {
     2029            uint32_t uNew = pStdFeatureLeaf->uEax & UINT32_C(0xf0003000);
     2030            uNew |= RT_BYTE1(uMaxIntelFamilyModelStep) & 0xf; /* stepping */
     2031            uNew |= (RT_BYTE2(uMaxIntelFamilyModelStep) & 0xf) << 4; /* 4 low model bits */
     2032            uNew |= (RT_BYTE2(uMaxIntelFamilyModelStep) >> 4) << 16; /* 4 high model bits */
     2033            uNew |= (RT_BYTE3(uMaxIntelFamilyModelStep) & 0xf) << 8; /* 4 low family bits */
     2034            if (RT_BYTE3(uMaxIntelFamilyModelStep) > 0xf) /* 8 high family bits, using intel's suggested calculation. */
     2035                uNew |= ( (RT_BYTE3(uMaxIntelFamilyModelStep) - (RT_BYTE3(uMaxIntelFamilyModelStep) & 0xf)) & 0xff ) << 20;
     2036            LogRel(("CPU: CPUID(0).EAX %#x -> %#x (uMaxIntelFamilyModelStep=%#x, uCurIntelFamilyModelStep=%#x\n",
     2037                    pStdFeatureLeaf->uEax, uNew, uMaxIntelFamilyModelStep, uCurIntelFamilyModelStep));
     2038            pStdFeatureLeaf->uEax = uNew;
     2039        }
     2040    }
     2041}
     2042
     2043
     2044
     2045/**
     2046 * Limit it the number of entries, zapping the remainder.
     2047 *
     2048 * The limits are masking off stuff about power saving and similar, this
     2049 * is perhaps a bit crudely done as there is probably some relatively harmless
     2050 * info too in these leaves (like words about having a constant TSC).
     2051 *
     2052 * @param   pCpum       The CPUM instance data.
     2053 * @param   pConfig     The CPUID configuration we've read from CFGM.
     2054 */
     2055static void cpumR3CpuIdLimitLeaves(PCPUM pCpum, PCPUMCPUIDCONFIG pConfig)
     2056{
     2057    /*
     2058     * Standard leaves.
     2059     */
     2060    uint32_t       uSubLeaf = 0;
     2061    PCPUMCPUIDLEAF pCurLeaf = cpumR3CpuIdGetExactLeaf(pCpum, 0, uSubLeaf);
     2062    if (pCurLeaf)
     2063    {
     2064        uint32_t uLimit = pCurLeaf->uEax;
     2065        if (   uLimit >= UINT32_C(0x00000000)
     2066            && uLimit <= UINT32_C(0x000fffff))
     2067        {
     2068            /** @todo raise the limits! */
     2069            if (pCurLeaf->uEax > 5)
     2070            {
     2071                pCurLeaf->uEax = uLimit = 5;
     2072                cpumR3CpuIdRemoveRange(pCpum->GuestInfo.paCpuIdLeavesR3, &pCpum->GuestInfo.cCpuIdLeaves,
     2073                                       uLimit + 1, UINT32_C(0x000fffff));
     2074            }
     2075
     2076            /* NT4 hack, no zapping of extra leaves here. */
     2077            if (pConfig->fNt4LeafLimit && uLimit > 3)
     2078                pCurLeaf->uEax = uLimit = 3;
     2079
     2080            while ((pCurLeaf = cpumR3CpuIdGetExactLeaf(pCpum, UINT32_C(0x00000000), ++uSubLeaf)) != NULL)
     2081                pCurLeaf->uEax = uLimit;
     2082        }
     2083        else
     2084        {
     2085            LogRel(("CPUID: Invalid standard range: %#x\n", uLimit));
     2086            cpumR3CpuIdRemoveRange(pCpum->GuestInfo.paCpuIdLeavesR3, &pCpum->GuestInfo.cCpuIdLeaves,
     2087                                   UINT32_C(0x00000000), UINT32_C(0x0fffffff));
     2088        }
     2089    }
     2090
     2091    /*
     2092     * Extended leaves.
     2093     */
     2094    uSubLeaf = 0;
     2095    pCurLeaf = cpumR3CpuIdGetExactLeaf(pCpum, UINT32_C(0x80000000), uSubLeaf);
     2096    if (pCurLeaf)
     2097    {
     2098        uint32_t uLimit = pCurLeaf->uEax;
     2099        if (   uLimit >= UINT32_C(0x80000000)
     2100            && uLimit <= UINT32_C(0x800fffff))
     2101        {
     2102            /** @todo raise the limits! */
     2103            if (pCurLeaf->uEax > UINT32_C(0x80000008))
     2104            {
     2105                pCurLeaf->uEax = uLimit = UINT32_C(0x80000008);
     2106                cpumR3CpuIdRemoveRange(pCpum->GuestInfo.paCpuIdLeavesR3, &pCpum->GuestInfo.cCpuIdLeaves,
     2107                                       uLimit + 1, UINT32_C(0x800fffff));
     2108            }
     2109
     2110            while ((pCurLeaf = cpumR3CpuIdGetExactLeaf(pCpum, UINT32_C(0x80000000), ++uSubLeaf)) != NULL)
     2111                pCurLeaf->uEax = uLimit;
     2112        }
     2113        else
     2114        {
     2115            LogRel(("CPUID: Invalid extended range: %#x\n", uLimit));
     2116            cpumR3CpuIdRemoveRange(pCpum->GuestInfo.paCpuIdLeavesR3, &pCpum->GuestInfo.cCpuIdLeaves,
     2117                                   UINT32_C(0x80000000), UINT32_C(0x8ffffffd));
     2118        }
     2119    }
     2120
     2121    /*
     2122     * Centaur leaves (VIA).
     2123     */
     2124    uSubLeaf = 0;
     2125    pCurLeaf = cpumR3CpuIdGetExactLeaf(pCpum, UINT32_C(0xc0000000), uSubLeaf);
     2126    if (pCurLeaf)
     2127    {
     2128        uint32_t uLimit = pCurLeaf->uEax;
     2129        if (   uLimit >= UINT32_C(0xc0000000)
     2130            && uLimit <= UINT32_C(0xc00fffff))
     2131        {
     2132            pCurLeaf->uEax = RT_MIN(uLimit, UINT32_C(0xc0000004));
     2133            cpumR3CpuIdRemoveRange(pCpum->GuestInfo.paCpuIdLeavesR3, &pCpum->GuestInfo.cCpuIdLeaves,
     2134                                   uLimit + 1, UINT32_C(0xcfffffff));
     2135
     2136            while ((pCurLeaf = cpumR3CpuIdGetExactLeaf(pCpum, UINT32_C(0xc0000000), ++uSubLeaf)) != NULL)
     2137                pCurLeaf->uEax = uLimit;
     2138        }
     2139        else
     2140        {
     2141            LogRel(("CPUID: Invalid centaur range: %#x\n", uLimit));
     2142            cpumR3CpuIdRemoveRange(pCpum->GuestInfo.paCpuIdLeavesR3, &pCpum->GuestInfo.cCpuIdLeaves,
     2143                                   UINT32_C(0xc0000000), UINT32_C(0xcfffffff));
     2144        }
     2145    }
     2146}
     2147
     2148
     2149/**
     2150 * Clears a CPUID leaf and all sub-leaves (to zero).
     2151 *
     2152 * @param   pCpum       The CPUM instance data.
     2153 * @param   uLeaf       The leaf to clear.
     2154 */
     2155static void cpumR3CpuIdZeroLeaf(PCPUM pCpum, uint32_t uLeaf)
     2156{
     2157    uint32_t       uSubLeaf = 0;
     2158    PCPUMCPUIDLEAF pCurLeaf;
     2159    while ((pCurLeaf = cpumR3CpuIdGetExactLeaf(pCpum, uLeaf, uSubLeaf)) != NULL)
     2160    {
     2161        pCurLeaf->uEax = 0;
     2162        pCurLeaf->uEbx = 0;
     2163        pCurLeaf->uEcx = 0;
     2164        pCurLeaf->uEdx = 0;
     2165        uSubLeaf++;
     2166    }
     2167}
     2168
     2169
     2170/**
     2171 * Sanitizes and adjust the CPUID leaves.
     2172 *
     2173 * Drop features that aren't virtualized (or virtualizable).  Adjust information
     2174 * and capabilities to fit the virtualized hardware.  Remove information the
     2175 * guest shouldn't have (because it's wrong in the virtual world or because it
     2176 * gives away host details) or that we don't have documentation for and no idea
     2177 * what means.
     2178 *
     2179 * @returns VBox status code.
     2180 * @param   pVM         Pointer to the cross context VM structure (for cCpus).
     2181 * @param   pCpum       The CPUM instance data.
     2182 * @param   pConfig     The CPUID configuration we've read from CFGM.
     2183 */
     2184static int cpumR3CpuIdSanitize(PVM pVM, PCPUM pCpum, PCPUMCPUIDCONFIG pConfig)
     2185{
    18462186#define PORTABLE_CLEAR_BITS_WHEN(Lvl, a_pLeafReg, FeatNm, fMask, uValue) \
    1847     if ( pCPUM->u8PortableCpuIdLevel >= (Lvl) && ((a_pLeafReg) & (fMask)) == (uValue) ) \
     2187    if ( pCpum->u8PortableCpuIdLevel >= (Lvl) && ((a_pLeafReg) & (fMask)) == (uValue) ) \
    18482188    { \
    18492189        LogRel(("PortableCpuId: " #a_pLeafReg "[" #FeatNm "]: %#x -> 0\n", (a_pLeafReg) & (fMask))); \
     
    18512191    }
    18522192#define PORTABLE_DISABLE_FEATURE_BIT(Lvl, a_pLeafReg, FeatNm, fBitMask) \
    1853     if ( pCPUM->u8PortableCpuIdLevel >= (Lvl) && ((a_pLeafReg) & (fBitMask)) ) \
     2193    if ( pCpum->u8PortableCpuIdLevel >= (Lvl) && ((a_pLeafReg) & (fBitMask)) ) \
    18542194    { \
    18552195        LogRel(("PortableCpuId: " #a_pLeafReg "[" #FeatNm "]: 1 -> 0\n")); \
    18562196        (a_pLeafReg) &= ~(uint32_t)(fBitMask); \
    18572197    }
    1858 
    1859     /*
    1860      * Read the configuration.
    1861      */
    1862     /** @cfgm{/CPUM/SyntheticCpu, boolean, false}
    1863      * Enables the Synthetic CPU.  The Vendor ID and Processor Name are
    1864      * completely overridden by VirtualBox custom strings.  Some
    1865      * CPUID information is withheld, like the cache info.
     2198    Assert(pCpum->GuestFeatures.enmCpuVendor != CPUMCPUVENDOR_INVALID);
     2199
     2200    /* Cpuid 1:
     2201     * EAX: CPU model, family and stepping.
    18662202     *
    1867      * This is obsoleted by PortableCpuIdLevel. */
    1868     bool fSyntheticCpu;
    1869     rc = CFGMR3QueryBoolDef(pCpumCfg, "SyntheticCpu",  &fSyntheticCpu, false);
    1870     AssertRCReturn(rc, rc);
    1871 
    1872     /** @cfgm{/CPUM/PortableCpuIdLevel, 8-bit, 0, 3, 0}
    1873      * When non-zero CPUID features that could cause portability issues will be
    1874      * stripped.  The higher the value the more features gets stripped.  Higher
    1875      * values should only be used when older CPUs are involved since it may
    1876      * harm performance and maybe also cause problems with specific guests. */
    1877     rc = CFGMR3QueryU8Def(pCpumCfg, "PortableCpuIdLevel", &pCPUM->u8PortableCpuIdLevel, fSyntheticCpu ? 1 : 0);
    1878     AssertLogRelRCReturn(rc, rc);
    1879 
    1880     /** @cfgm{/CPUM/GuestCpuName, string}
    1881      * The name of the CPU we're to emulate.  The default is the host CPU.
    1882      * Note! CPUs other than "host" one is currently unsupported. */
    1883     char szCpuName[128];
    1884     rc = CFGMR3QueryStringDef(pCpumCfg, "GuestCpuName", szCpuName, sizeof(szCpuName), "host");
    1885     AssertLogRelRCReturn(rc, rc);
    1886 
    1887     /** @cfgm{/CPUM/CMPXCHG16B, boolean, false}
    1888      * Expose CMPXCHG16B to the guest if supported by the host.
    1889      */
    1890     bool fCmpXchg16b;
    1891     rc = CFGMR3QueryBoolDef(pCpumCfg, "CMPXCHG16B", &fCmpXchg16b, false);
    1892     AssertLogRelRCReturn(rc, rc);
    1893 
    1894     /** @cfgm{/CPUM/MONITOR, boolean, true}
    1895      * Expose MONITOR/MWAIT instructions to the guest.
    1896      */
    1897     bool fMonitor;
    1898     rc = CFGMR3QueryBoolDef(pCpumCfg, "MONITOR", &fMonitor, true);
    1899     AssertLogRelRCReturn(rc, rc);
    1900 
    1901     /** @cfgm{/CPUM/MWaitExtensions, boolean, false}
    1902      * Expose MWAIT extended features to the guest.  For now we expose just MWAIT
    1903      * break on interrupt feature (bit 1).
    1904      */
    1905     bool fMWaitExtensions;
    1906     rc = CFGMR3QueryBoolDef(pCpumCfg, "MWaitExtensions", &fMWaitExtensions, false);
    1907     AssertLogRelRCReturn(rc, rc);
    1908 
    1909     /** @cfgm{/CPUM/SSE4.1, boolean, true}
    1910      * Expose SSE4.1 to the guest if available.
    1911      */
    1912     bool fSse41;
    1913     rc = CFGMR3QueryBoolDef(pCpumCfg, "SSE4.1", &fSse41, true);
    1914     AssertLogRelRCReturn(rc, rc);
    1915 
    1916     /** @cfgm{/CPUM/SSE4.2, boolean, true}
    1917      * Expose SSE4.2 to the guest if available.
    1918      */
    1919     bool fSse42;
    1920     rc = CFGMR3QueryBoolDef(pCpumCfg, "SSE4.2", &fSse42, true);
    1921     AssertLogRelRCReturn(rc, rc);
    1922 
    1923     /** @cfgm{/CPUM/NT4LeafLimit, boolean, false}
    1924      * Limit the number of standard CPUID leaves to 0..3 to prevent NT4 from
    1925      * bugchecking with MULTIPROCESSOR_CONFIGURATION_NOT_SUPPORTED (0x3e).
    1926      * This option corresponds somewhat to IA32_MISC_ENABLES.BOOT_NT4[bit 22].
    1927      */
    1928     bool fNt4LeafLimit;
    1929     rc = CFGMR3QueryBoolDef(pCpumCfg, "NT4LeafLimit", &fNt4LeafLimit, false);
    1930     AssertLogRelRCReturn(rc, rc);
    1931 
    1932     /** @cfgm{/CPUM/MaxIntelFamilyModelStep, uint32_t, UINT32_MAX}
    1933      * Restrict the reported CPU family+model+stepping of intel CPUs.  This is
    1934      * probably going to be a temporary hack, so don't depend on this.
    1935      * The 1st byte of the value is the stepping, the 2nd byte value is the model
    1936      * number and the 3rd byte value is the family, and the 4th value must be zero.
    1937      */
    1938     uint32_t uMaxIntelFamilyModelStep;
    1939     rc = CFGMR3QueryU32Def(pCpumCfg, "MaxIntelFamilyModelStep", &uMaxIntelFamilyModelStep, UINT32_MAX);
    1940     AssertLogRelRCReturn(rc, rc);
    1941 
    1942     /*
    1943      * Get the guest CPU data from the database and/or the host.
    1944      */
    1945     rc = cpumR3DbGetCpuInfo(szCpuName, &pCPUM->GuestInfo);
    1946     if (RT_FAILURE(rc))
    1947         return rc == VERR_CPUM_DB_CPU_NOT_FOUND
    1948              ? VMSetError(pVM, rc, RT_SRC_POS,
    1949                           "Info on guest CPU '%s' could not be found. Please, select a different CPU.", szCpuName)
    1950              : rc;
    1951 
    1952     /** @cfgm{/CPUM/MSRs/[Name]/[First|Last|Type|Value|...],}
    1953      * Overrides the guest MSRs.
    1954      */
    1955     rc = cpumR3LoadMsrOverrides(pVM, CFGMR3GetChild(pCpumCfg, "MSRs"));
    1956 
    1957     /** @cfgm{/CPUM/HostCPUID/[000000xx|800000xx|c000000x]/[eax|ebx|ecx|edx],32-bit}
    1958      * Overrides the CPUID leaf values (from the host CPU usually) used for
    1959      * calculating the guest CPUID leaves.  This can be used to preserve the CPUID
    1960      * values when moving a VM to a different machine.  Another use is restricting
    1961      * (or extending) the feature set exposed to the guest. */
    1962     if (RT_SUCCESS(rc))
    1963         rc = cpumR3LoadCpuIdOverrides(pVM, CFGMR3GetChild(pCpumCfg, "HostCPUID"), "HostCPUID");
    1964 
    1965     if (RT_SUCCESS(rc) && CFGMR3GetChild(pCpumCfg, "CPUID")) /* 2nd override, now discontinued. */
    1966         rc = VMSetError(pVM, VERR_CFGM_CONFIG_UNKNOWN_NODE, RT_SRC_POS,
    1967                         "Found unsupported configuration node '/CPUM/CPUID/'. "
    1968                         "Please use IMachine::setCPUIDLeaf() instead.");
    1969 
    1970     /*
    1971      * Pre-explode the CPUID info.
    1972      */
    1973     if (RT_SUCCESS(rc))
    1974         rc = cpumR3CpuIdExplodeFeatures(pCPUM->GuestInfo.paCpuIdLeavesR3, pCPUM->GuestInfo.cCpuIdLeaves, &pCPUM->GuestFeatures);
    1975     if (RT_FAILURE(rc))
    1976     {
    1977         RTMemFree(pCPUM->GuestInfo.paCpuIdLeavesR3);
    1978         pCPUM->GuestInfo.paCpuIdLeavesR3 = NULL;
    1979         RTMemFree(pCPUM->GuestInfo.paMsrRangesR3);
    1980         pCPUM->GuestInfo.paMsrRangesR3 = NULL;
    1981         return rc;
    1982     }
    1983 
    1984 
    1985     /* ... split this function about here ... */
    1986 
    1987 
    1988     /* Cpuid 1:
    1989      * Only report features we can support.
    1990      *
    1991      * Note! When enabling new features the Synthetic CPU and Portable CPUID
    1992      *       options may require adjusting (i.e. stripping what was enabled).
    1993      */
    1994     PCPUMCPUIDLEAF pStdFeatureLeaf = cpumR3CpuIdGetLeaf(pCPUM->GuestInfo.paCpuIdLeavesR3, pCPUM->GuestInfo.cCpuIdLeaves,
    1995                                                         1, 0); /* Note! Must refetch when used later. */
    1996     AssertLogRelReturn(pStdFeatureLeaf, VERR_CPUM_IPE_2);
    1997     pStdFeatureLeaf->uEdx        &= X86_CPUID_FEATURE_EDX_FPU
    1998                                   | X86_CPUID_FEATURE_EDX_VME
    1999                                   | X86_CPUID_FEATURE_EDX_DE
    2000                                   | X86_CPUID_FEATURE_EDX_PSE
    2001                                   | X86_CPUID_FEATURE_EDX_TSC
    2002                                   | X86_CPUID_FEATURE_EDX_MSR
    2003                                   //| X86_CPUID_FEATURE_EDX_PAE   - set later if configured.
    2004                                   | X86_CPUID_FEATURE_EDX_MCE
    2005                                   | X86_CPUID_FEATURE_EDX_CX8
    2006                                   //| X86_CPUID_FEATURE_EDX_APIC  - set by the APIC device if present.
    2007                                   /* 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 @bugref{1757}) */
    2008                                   //| X86_CPUID_FEATURE_EDX_SEP
    2009                                   | X86_CPUID_FEATURE_EDX_MTRR
    2010                                   | X86_CPUID_FEATURE_EDX_PGE
    2011                                   | X86_CPUID_FEATURE_EDX_MCA
    2012                                   | X86_CPUID_FEATURE_EDX_CMOV
    2013                                   | X86_CPUID_FEATURE_EDX_PAT
    2014                                   | X86_CPUID_FEATURE_EDX_PSE36
    2015                                   //| X86_CPUID_FEATURE_EDX_PSN   - no serial number.
    2016                                   | X86_CPUID_FEATURE_EDX_CLFSH
    2017                                   //| X86_CPUID_FEATURE_EDX_DS    - no debug store.
    2018                                   //| X86_CPUID_FEATURE_EDX_ACPI  - not virtualized yet.
    2019                                   | X86_CPUID_FEATURE_EDX_MMX
    2020                                   | X86_CPUID_FEATURE_EDX_FXSR
    2021                                   | X86_CPUID_FEATURE_EDX_SSE
    2022                                   | X86_CPUID_FEATURE_EDX_SSE2
    2023                                   //| X86_CPUID_FEATURE_EDX_SS    - no self snoop.
    2024                                   //| X86_CPUID_FEATURE_EDX_HTT   - no hyperthreading.
    2025                                   //| X86_CPUID_FEATURE_EDX_TM    - no thermal monitor.
    2026                                   //| X86_CPUID_FEATURE_EDX_PBE   - no pending break enabled.
    2027                                   | 0;
    2028     pStdFeatureLeaf->uEcx        &= 0
    2029                                   | X86_CPUID_FEATURE_ECX_SSE3
    2030                                   /* Can't properly emulate monitor & mwait with guest SMP; force the guest to use hlt for idling VCPUs. */
    2031                                   | ((fMonitor && pVM->cCpus == 1) ? X86_CPUID_FEATURE_ECX_MONITOR : 0)
    2032                                   //| X86_CPUID_FEATURE_ECX_CPLDS - no CPL qualified debug store.
    2033                                   //| X86_CPUID_FEATURE_ECX_VMX   - not virtualized.
    2034                                   //| X86_CPUID_FEATURE_ECX_EST   - no extended speed step.
    2035                                   //| X86_CPUID_FEATURE_ECX_TM2   - no thermal monitor 2.
    2036                                     | X86_CPUID_FEATURE_ECX_SSSE3
    2037                                   //| X86_CPUID_FEATURE_ECX_CNTXID - no L1 context id (MSR++).
    2038                                     | (fCmpXchg16b ? X86_CPUID_FEATURE_ECX_CX16 : 0)
    2039                                   /* ECX Bit 14 - xTPR Update Control. Processor supports changing IA32_MISC_ENABLES[bit 23]. */
    2040                                   //| X86_CPUID_FEATURE_ECX_TPRUPDATE
    2041                                   | (fSse41 ? X86_CPUID_FEATURE_ECX_SSE4_1 : 0)
    2042                                   | (fSse42 ? X86_CPUID_FEATURE_ECX_SSE4_2 : 0)
    2043                                   /* ECX Bit 21 - x2APIC support - not yet. */
    2044                                   // | X86_CPUID_FEATURE_ECX_X2APIC
    2045                                   /* ECX Bit 23 - POPCNT instruction. */
    2046                                   //| X86_CPUID_FEATURE_ECX_POPCNT
    2047                                   | 0;
    2048     if (pCPUM->u8PortableCpuIdLevel > 0)
    2049     {
    2050         PORTABLE_CLEAR_BITS_WHEN(1, pStdFeatureLeaf->uEax, ProcessorType, (UINT32_C(3) << 12), (UINT32_C(2) << 12));
    2051         PORTABLE_DISABLE_FEATURE_BIT(1, pStdFeatureLeaf->uEcx, SSSE3, X86_CPUID_FEATURE_ECX_SSSE3);
    2052         PORTABLE_DISABLE_FEATURE_BIT(1, pStdFeatureLeaf->uEcx, SSE3,  X86_CPUID_FEATURE_ECX_SSE3);
    2053         PORTABLE_DISABLE_FEATURE_BIT(1, pStdFeatureLeaf->uEcx, SSE4_1, X86_CPUID_FEATURE_ECX_SSE4_1);
    2054         PORTABLE_DISABLE_FEATURE_BIT(1, pStdFeatureLeaf->uEcx, SSE4_2, X86_CPUID_FEATURE_ECX_SSE4_2);
    2055         PORTABLE_DISABLE_FEATURE_BIT(1, pStdFeatureLeaf->uEcx, CX16,  X86_CPUID_FEATURE_ECX_CX16);
    2056         PORTABLE_DISABLE_FEATURE_BIT(2, pStdFeatureLeaf->uEdx, SSE2,  X86_CPUID_FEATURE_EDX_SSE2);
    2057         PORTABLE_DISABLE_FEATURE_BIT(3, pStdFeatureLeaf->uEdx, SSE,   X86_CPUID_FEATURE_EDX_SSE);
    2058         PORTABLE_DISABLE_FEATURE_BIT(3, pStdFeatureLeaf->uEdx, CLFSH, X86_CPUID_FEATURE_EDX_CLFSH);
    2059         PORTABLE_DISABLE_FEATURE_BIT(3, pStdFeatureLeaf->uEdx, CMOV,  X86_CPUID_FEATURE_EDX_CMOV);
    2060 
    2061         Assert(!(pStdFeatureLeaf->uEdx        & (  X86_CPUID_FEATURE_EDX_SEP
    2062                                                  | X86_CPUID_FEATURE_EDX_PSN
    2063                                                  | X86_CPUID_FEATURE_EDX_DS
    2064                                                  | X86_CPUID_FEATURE_EDX_ACPI
    2065                                                  | X86_CPUID_FEATURE_EDX_SS
    2066                                                  | X86_CPUID_FEATURE_EDX_TM
    2067                                                  | X86_CPUID_FEATURE_EDX_PBE
    2068                                                  )));
    2069         Assert(!(pStdFeatureLeaf->uEcx        & (  X86_CPUID_FEATURE_ECX_PCLMUL
    2070                                                  | X86_CPUID_FEATURE_ECX_DTES64
    2071                                                  | X86_CPUID_FEATURE_ECX_CPLDS
    2072                                                  | X86_CPUID_FEATURE_ECX_VMX
    2073                                                  | X86_CPUID_FEATURE_ECX_SMX
    2074                                                  | X86_CPUID_FEATURE_ECX_EST
    2075                                                  | X86_CPUID_FEATURE_ECX_TM2
    2076                                                  | X86_CPUID_FEATURE_ECX_CNTXID
    2077                                                  | X86_CPUID_FEATURE_ECX_FMA
    2078                                                  | X86_CPUID_FEATURE_ECX_CX16
    2079                                                  | X86_CPUID_FEATURE_ECX_TPRUPDATE
    2080                                                  | X86_CPUID_FEATURE_ECX_PDCM
    2081                                                  | X86_CPUID_FEATURE_ECX_DCA
    2082                                                  | X86_CPUID_FEATURE_ECX_MOVBE
    2083                                                  | X86_CPUID_FEATURE_ECX_AES
    2084                                                  | X86_CPUID_FEATURE_ECX_POPCNT
    2085                                                  | X86_CPUID_FEATURE_ECX_XSAVE
    2086                                                  | X86_CPUID_FEATURE_ECX_OSXSAVE
    2087                                                  | X86_CPUID_FEATURE_ECX_AVX
    2088                                                  )));
    2089     }
    2090 
    2091     /* Cpuid 0x80000001:
    2092      * Only report features we can support.
    2093      *
     2203     * ECX + EDX: Supported features.  Only report features we can support.
    20942204     * Note! When enabling new features the Synthetic CPU and Portable CPUID
    20952205     *       options may require adjusting (i.e. stripping what was enabled).
    20962206     *
    2097      * ASSUMES that this is ALWAYS the AMD defined feature set if present.
    2098      */
    2099     PCPUMCPUIDLEAF pExtFeatureLeaf = cpumR3CpuIdGetLeaf(pCPUM->GuestInfo.paCpuIdLeavesR3, pCPUM->GuestInfo.cCpuIdLeaves,
    2100                                                         UINT32_C(0x80000001), 0); /* Note! Must refetch when used later. */
     2207     * EBX: Branding, CLFLUSH line size, logical processors per package and
     2208     *      initial APIC ID.
     2209     */
     2210    PCPUMCPUIDLEAF pStdFeatureLeaf = cpumR3CpuIdGetExactLeaf(pCpum, 1, 0); /* Note! Must refetch when used later. */
     2211    AssertLogRelReturn(pStdFeatureLeaf, VERR_CPUM_IPE_2);
     2212    AssertLogRelReturn(pStdFeatureLeaf->fSubLeafMask == 0, VERR_CPUM_IPE_2);
     2213
     2214    pStdFeatureLeaf->uEdx &= X86_CPUID_FEATURE_EDX_FPU
     2215                           | X86_CPUID_FEATURE_EDX_VME
     2216                           | X86_CPUID_FEATURE_EDX_DE
     2217                           | X86_CPUID_FEATURE_EDX_PSE
     2218                           | X86_CPUID_FEATURE_EDX_TSC
     2219                           | X86_CPUID_FEATURE_EDX_MSR
     2220                           //| X86_CPUID_FEATURE_EDX_PAE   - set later if configured.
     2221                           | X86_CPUID_FEATURE_EDX_MCE
     2222                           | X86_CPUID_FEATURE_EDX_CX8
     2223                           //| X86_CPUID_FEATURE_EDX_APIC  - set by the APIC device if present.
     2224                           //| RT_BIT_32(10)               - not defined
     2225                           /* 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 @bugref{1757}) */
     2226                           //| X86_CPUID_FEATURE_EDX_SEP
     2227                           | X86_CPUID_FEATURE_EDX_MTRR
     2228                           | X86_CPUID_FEATURE_EDX_PGE
     2229                           | X86_CPUID_FEATURE_EDX_MCA
     2230                           | X86_CPUID_FEATURE_EDX_CMOV
     2231                           | X86_CPUID_FEATURE_EDX_PAT     /* 16 */
     2232                           | X86_CPUID_FEATURE_EDX_PSE36
     2233                           //| X86_CPUID_FEATURE_EDX_PSN   - no serial number.
     2234                           | X86_CPUID_FEATURE_EDX_CLFSH
     2235                           //| RT_BIT_32(20)               - not defined
     2236                           //| X86_CPUID_FEATURE_EDX_DS    - no debug store.
     2237                           //| X86_CPUID_FEATURE_EDX_ACPI  - not supported (not DevAcpi, right?).
     2238                           | X86_CPUID_FEATURE_EDX_MMX
     2239                           | X86_CPUID_FEATURE_EDX_FXSR
     2240                           | X86_CPUID_FEATURE_EDX_SSE
     2241                           | X86_CPUID_FEATURE_EDX_SSE2
     2242                           //| X86_CPUID_FEATURE_EDX_SS    - no self snoop.
     2243                           //| X86_CPUID_FEATURE_EDX_HTT   - no hyperthreading/cores - see below.
     2244                           //| X86_CPUID_FEATURE_EDX_TM    - no thermal monitor.
     2245                           //| RT_BIT_32(30)               - not defined
     2246                           //| X86_CPUID_FEATURE_EDX_PBE   - no pending break enabled.
     2247                           ;
     2248    pStdFeatureLeaf->uEcx &= 0
     2249                           | X86_CPUID_FEATURE_ECX_SSE3
     2250                           //| X86_CPUID_FEATURE_ECX_PCLMUL - not implemented yet.
     2251                           //| X86_CPUID_FEATURE_ECX_DTES64 - not implemented yet.
     2252                           /* Can't properly emulate monitor & mwait with guest SMP; force the guest to use hlt for idling VCPUs. */
     2253                           | ((pConfig->fMonitor && pVM->cCpus == 1) ? X86_CPUID_FEATURE_ECX_MONITOR : 0)
     2254                           //| X86_CPUID_FEATURE_ECX_CPLDS - no CPL qualified debug store.
     2255                           //| X86_CPUID_FEATURE_ECX_VMX   - not virtualized yet.
     2256                           //| X86_CPUID_FEATURE_ECX_SMX   - not virtualized yet.
     2257                           //| X86_CPUID_FEATURE_ECX_EST   - no extended speed step.
     2258                           //| X86_CPUID_FEATURE_ECX_TM2   - no thermal monitor 2.
     2259                           | X86_CPUID_FEATURE_ECX_SSSE3
     2260                           //| X86_CPUID_FEATURE_ECX_CNTXID - no L1 context id (MSR++).
     2261                           //| X86_CPUID_FEATURE_ECX_FMA   - not implemented yet.
     2262                           | (pConfig->fCmpXchg16b ? X86_CPUID_FEATURE_ECX_CX16 : 0)
     2263                           /* ECX Bit 14 - xTPR Update Control. Processor supports changing IA32_MISC_ENABLES[bit 23]. */
     2264                           //| X86_CPUID_FEATURE_ECX_TPRUPDATE
     2265                           //| X86_CPUID_FEATURE_ECX_PDCM  - not implemented yet.
     2266                           //| X86_CPUID_FEATURE_ECX_PCID  - not implemented yet.
     2267                           //| X86_CPUID_FEATURE_ECX_DCA   - not implemented yet.
     2268                           | (pConfig->fSse41 ? X86_CPUID_FEATURE_ECX_SSE4_1 : 0)
     2269                           | (pConfig->fSse42 ? X86_CPUID_FEATURE_ECX_SSE4_2 : 0)
     2270                           //| X86_CPUID_FEATURE_ECX_X2APIC - turned on later by the device if enabled.
     2271                           //| X86_CPUID_FEATURE_ECX_MOVBE - not implemented yet.
     2272                           //| X86_CPUID_FEATURE_ECX_POPCNT
     2273                           //| X86_CPUID_FEATURE_ECX_TSCDEADL - not implemented yet.
     2274                           //| X86_CPUID_FEATURE_ECX_AES   - not implemented yet.
     2275                           //| X86_CPUID_FEATURE_ECX_XSAVE - not implemented yet.
     2276                           //| X86_CPUID_FEATURE_ECX_OSXSAVE - not implemented yet.
     2277                           //| X86_CPUID_FEATURE_ECX_AVX   - not implemented yet.
     2278                           //| X86_CPUID_FEATURE_ECX_F16C  - not implemented yet.
     2279                           //| X86_CPUID_FEATURE_ECX_RDRAND - not implemented yet.
     2280                           //| X86_CPUID_FEATURE_ECX_HVP   - Set explicitly later.
     2281                           ;
     2282
     2283    if (pCpum->u8PortableCpuIdLevel > 0)
     2284    {
     2285        PORTABLE_CLEAR_BITS_WHEN(1, pStdFeatureLeaf->uEax, ProcessorType, (UINT32_C(3) << 12), (UINT32_C(2) << 12));
     2286        PORTABLE_DISABLE_FEATURE_BIT(1, pStdFeatureLeaf->uEcx, SSSE3,  X86_CPUID_FEATURE_ECX_SSSE3);
     2287        PORTABLE_DISABLE_FEATURE_BIT(1, pStdFeatureLeaf->uEcx, SSE3,   X86_CPUID_FEATURE_ECX_SSE3);
     2288        PORTABLE_DISABLE_FEATURE_BIT(1, pStdFeatureLeaf->uEcx, SSE4_1, X86_CPUID_FEATURE_ECX_SSE4_1);
     2289        PORTABLE_DISABLE_FEATURE_BIT(1, pStdFeatureLeaf->uEcx, SSE4_2, X86_CPUID_FEATURE_ECX_SSE4_2);
     2290        PORTABLE_DISABLE_FEATURE_BIT(1, pStdFeatureLeaf->uEcx, CX16,   X86_CPUID_FEATURE_ECX_CX16);
     2291        PORTABLE_DISABLE_FEATURE_BIT(2, pStdFeatureLeaf->uEdx, SSE2,   X86_CPUID_FEATURE_EDX_SSE2);
     2292        PORTABLE_DISABLE_FEATURE_BIT(3, pStdFeatureLeaf->uEdx, SSE,    X86_CPUID_FEATURE_EDX_SSE);
     2293        PORTABLE_DISABLE_FEATURE_BIT(3, pStdFeatureLeaf->uEdx, CLFSH,  X86_CPUID_FEATURE_EDX_CLFSH);
     2294        PORTABLE_DISABLE_FEATURE_BIT(3, pStdFeatureLeaf->uEdx, CMOV,   X86_CPUID_FEATURE_EDX_CMOV);
     2295
     2296        Assert(!(pStdFeatureLeaf->uEdx & (  X86_CPUID_FEATURE_EDX_SEP
     2297                                          | X86_CPUID_FEATURE_EDX_PSN
     2298                                          | X86_CPUID_FEATURE_EDX_DS
     2299                                          | X86_CPUID_FEATURE_EDX_ACPI
     2300                                          | X86_CPUID_FEATURE_EDX_SS
     2301                                          | X86_CPUID_FEATURE_EDX_TM
     2302                                          | X86_CPUID_FEATURE_EDX_PBE
     2303                                          )));
     2304        Assert(!(pStdFeatureLeaf->uEcx & (  X86_CPUID_FEATURE_ECX_PCLMUL
     2305                                          | X86_CPUID_FEATURE_ECX_DTES64
     2306                                          | X86_CPUID_FEATURE_ECX_CPLDS
     2307                                          | X86_CPUID_FEATURE_ECX_VMX
     2308                                          | X86_CPUID_FEATURE_ECX_SMX
     2309                                          | X86_CPUID_FEATURE_ECX_EST
     2310                                          | X86_CPUID_FEATURE_ECX_TM2
     2311                                          | X86_CPUID_FEATURE_ECX_CNTXID
     2312                                          | X86_CPUID_FEATURE_ECX_FMA
     2313                                          | X86_CPUID_FEATURE_ECX_CX16
     2314                                          | X86_CPUID_FEATURE_ECX_TPRUPDATE
     2315                                          | X86_CPUID_FEATURE_ECX_PDCM
     2316                                          | X86_CPUID_FEATURE_ECX_DCA
     2317                                          | X86_CPUID_FEATURE_ECX_MOVBE
     2318                                          | X86_CPUID_FEATURE_ECX_AES
     2319                                          | X86_CPUID_FEATURE_ECX_POPCNT
     2320                                          | X86_CPUID_FEATURE_ECX_XSAVE
     2321                                          | X86_CPUID_FEATURE_ECX_OSXSAVE
     2322                                          | X86_CPUID_FEATURE_ECX_AVX
     2323                                          )));
     2324    }
     2325
     2326    /* Set up APIC ID for CPU 0, configure multi core/threaded smp. */
     2327    pStdFeatureLeaf->uEbx &= UINT32_C(0x0000ffff); /* (APIC-ID := 0 and #LogCpus := 0) */
     2328#ifdef VBOX_WITH_MULTI_CORE
     2329    if (pVM->cCpus > 1)
     2330    {
     2331        /* If CPUID Fn0000_0001_EDX[HTT] = 1 then LogicalProcessorCount is the number of threads per CPU
     2332           core times the number of CPU cores per processor */
     2333        pStdFeatureLeaf->uEbx |= pVM->cCpus <= 0xff ? (pVM->cCpus << 16) : UINT32_C(0x00ff0000);
     2334        pStdFeatureLeaf->uEdx |= X86_CPUID_FEATURE_EDX_HTT;  /* necessary for hyper-threading *or* multi-core CPUs */
     2335    }
     2336#endif
     2337    pStdFeatureLeaf = NULL; /* Must refetch! */
     2338
     2339
     2340    /* Cpuid 0x80000001: (Similar, but in no way identical to 0x00000001.)
     2341     * AMD:
     2342     *  EAX: CPU model, family and stepping.
     2343     *
     2344     *  ECX + EDX: Supported features.  Only report features we can support.
     2345     *  Note! When enabling new features the Synthetic CPU and Portable CPUID
     2346     *        options may require adjusting (i.e. stripping what was enabled).
     2347     *  ASSUMES that this is ALWAYS the AMD defined feature set if present.
     2348     *
     2349     *  EBX: Branding ID and package type (or reserved).
     2350     *
     2351     * Intel and probably most others:
     2352     *  EAX: 0
     2353     *  EBX: 0
     2354     *  ECX + EDX: Subset of AMD features, mainly for AMD64 support.
     2355     */
     2356    PCPUMCPUIDLEAF pExtFeatureLeaf = cpumR3CpuIdGetExactLeaf(pCpum, UINT32_C(0x80000001), 0);
    21012357    if (pExtFeatureLeaf)
    21022358    {
    2103         pExtFeatureLeaf->uEdx    &= X86_CPUID_AMD_FEATURE_EDX_FPU
    2104                                   | X86_CPUID_AMD_FEATURE_EDX_VME
    2105                                   | X86_CPUID_AMD_FEATURE_EDX_DE
    2106                                   | X86_CPUID_AMD_FEATURE_EDX_PSE
    2107                                   | X86_CPUID_AMD_FEATURE_EDX_TSC
    2108                                   | X86_CPUID_AMD_FEATURE_EDX_MSR //?? this means AMD MSRs..
    2109                                   //| X86_CPUID_AMD_FEATURE_EDX_PAE    - not implemented yet.
    2110                                   //| X86_CPUID_AMD_FEATURE_EDX_MCE    - not virtualized yet.
    2111                                   | X86_CPUID_AMD_FEATURE_EDX_CX8
    2112                                   //| X86_CPUID_AMD_FEATURE_EDX_APIC   - set by the APIC device if present.
    2113                                   /* 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 @bugref{1757}) */
    2114                                   //| X86_CPUID_EXT_FEATURE_EDX_SEP
    2115                                   | X86_CPUID_AMD_FEATURE_EDX_MTRR
    2116                                   | X86_CPUID_AMD_FEATURE_EDX_PGE
    2117                                   | X86_CPUID_AMD_FEATURE_EDX_MCA
    2118                                   | X86_CPUID_AMD_FEATURE_EDX_CMOV
    2119                                   | X86_CPUID_AMD_FEATURE_EDX_PAT
    2120                                   | X86_CPUID_AMD_FEATURE_EDX_PSE36
    2121                                   //| X86_CPUID_EXT_FEATURE_EDX_NX     - not virtualized, requires PAE.
    2122                                   //| X86_CPUID_AMD_FEATURE_EDX_AXMMX
    2123                                   | X86_CPUID_AMD_FEATURE_EDX_MMX
    2124                                   | X86_CPUID_AMD_FEATURE_EDX_FXSR
    2125                                   | X86_CPUID_AMD_FEATURE_EDX_FFXSR
    2126                                   //| X86_CPUID_EXT_FEATURE_EDX_PAGE1GB
    2127                                   | X86_CPUID_EXT_FEATURE_EDX_RDTSCP
    2128                                   //| X86_CPUID_EXT_FEATURE_EDX_LONG_MODE - turned on when necessary
    2129                                   | X86_CPUID_AMD_FEATURE_EDX_3DNOW_EX
    2130                                   | X86_CPUID_AMD_FEATURE_EDX_3DNOW
    2131                                   | 0;
    2132         pExtFeatureLeaf->uEcx    &= 0
    2133                                   //| X86_CPUID_EXT_FEATURE_ECX_LAHF_SAHF
    2134                                   //| X86_CPUID_AMD_FEATURE_ECX_CMPL
    2135                                   //| X86_CPUID_AMD_FEATURE_ECX_SVM    - not virtualized.
    2136                                   //| X86_CPUID_AMD_FEATURE_ECX_EXT_APIC
    2137                                   /* Note: This could prevent teleporting from AMD to Intel CPUs! */
    2138                                   | X86_CPUID_AMD_FEATURE_ECX_CR8L         /* expose lock mov cr0 = mov cr8 hack for guests that can use this feature to access the TPR. */
    2139                                   //| X86_CPUID_AMD_FEATURE_ECX_ABM
    2140                                   //| X86_CPUID_AMD_FEATURE_ECX_SSE4A
    2141                                   //| X86_CPUID_AMD_FEATURE_ECX_MISALNSSE
    2142                                   //| X86_CPUID_AMD_FEATURE_ECX_3DNOWPRF
    2143                                   //| X86_CPUID_AMD_FEATURE_ECX_OSVW
    2144                                   //| X86_CPUID_AMD_FEATURE_ECX_IBS
    2145                                   //| X86_CPUID_AMD_FEATURE_ECX_SSE5
    2146                                   //| X86_CPUID_AMD_FEATURE_ECX_SKINIT
    2147                                   //| X86_CPUID_AMD_FEATURE_ECX_WDT
    2148                                   | 0;
    2149         if (pCPUM->u8PortableCpuIdLevel > 0)
     2359        AssertLogRelReturn(pExtFeatureLeaf->fSubLeafMask == 0, VERR_CPUM_IPE_2);
     2360
     2361        pExtFeatureLeaf->uEdx &= X86_CPUID_AMD_FEATURE_EDX_FPU
     2362                               | X86_CPUID_AMD_FEATURE_EDX_VME
     2363                               | X86_CPUID_AMD_FEATURE_EDX_DE
     2364                               | X86_CPUID_AMD_FEATURE_EDX_PSE
     2365                               | X86_CPUID_AMD_FEATURE_EDX_TSC
     2366                               | X86_CPUID_AMD_FEATURE_EDX_MSR //?? this means AMD MSRs..
     2367                               //| X86_CPUID_AMD_FEATURE_EDX_PAE    - turned on when necessary
     2368                               //| X86_CPUID_AMD_FEATURE_EDX_MCE    - not virtualized yet.
     2369                               | X86_CPUID_AMD_FEATURE_EDX_CX8
     2370                               //| X86_CPUID_AMD_FEATURE_EDX_APIC   - set by the APIC device if present.
     2371                               //| RT_BIT_32(10)                    - reserved
     2372                               /* Note! We don't report sysenter/sysexit support due to our inability to keep the IOPL part of
     2373                                        eflags in sync while in ring 1 (see @bugref{1757}). HM enables them later. */
     2374                               //| X86_CPUID_EXT_FEATURE_EDX_SYSCALL
     2375                               | X86_CPUID_AMD_FEATURE_EDX_MTRR
     2376                               | X86_CPUID_AMD_FEATURE_EDX_PGE
     2377                               | X86_CPUID_AMD_FEATURE_EDX_MCA
     2378                               | X86_CPUID_AMD_FEATURE_EDX_CMOV
     2379                               | X86_CPUID_AMD_FEATURE_EDX_PAT
     2380                               | X86_CPUID_AMD_FEATURE_EDX_PSE36
     2381                               //| RT_BIT_32(18)                    - reserved
     2382                               //| RT_BIT_32(19)                    - reserved
     2383                               //| X86_CPUID_EXT_FEATURE_EDX_NX     - enabled later by PGM
     2384                               //| RT_BIT_32(21)                    - reserved
     2385                               //| X86_CPUID_AMD_FEATURE_EDX_AXMMX
     2386                               | X86_CPUID_AMD_FEATURE_EDX_MMX
     2387                               | X86_CPUID_AMD_FEATURE_EDX_FXSR
     2388                               | X86_CPUID_AMD_FEATURE_EDX_FFXSR
     2389                               //| X86_CPUID_EXT_FEATURE_EDX_PAGE1GB
     2390                               | X86_CPUID_EXT_FEATURE_EDX_RDTSCP
     2391                               //| RT_BIT_32(28)                    - reserved
     2392                               //| X86_CPUID_EXT_FEATURE_EDX_LONG_MODE - turned on when necessary
     2393                               | X86_CPUID_AMD_FEATURE_EDX_3DNOW_EX
     2394                               | X86_CPUID_AMD_FEATURE_EDX_3DNOW
     2395                               ;
     2396        pExtFeatureLeaf->uEcx &= 0
     2397                               //| X86_CPUID_EXT_FEATURE_ECX_LAHF_SAHF
     2398                               //| X86_CPUID_AMD_FEATURE_ECX_CMPL   - set below if applicable.
     2399                               //| X86_CPUID_AMD_FEATURE_ECX_SVM    - not virtualized.
     2400                               //| X86_CPUID_AMD_FEATURE_ECX_EXT_APIC
     2401                               /* Note: This could prevent teleporting from AMD to Intel CPUs! */
     2402                               | X86_CPUID_AMD_FEATURE_ECX_CR8L         /* expose lock mov cr0 = mov cr8 hack for guests that can use this feature to access the TPR. */
     2403                               //| X86_CPUID_AMD_FEATURE_ECX_ABM
     2404                               //| X86_CPUID_AMD_FEATURE_ECX_SSE4A
     2405                               //| X86_CPUID_AMD_FEATURE_ECX_MISALNSSE
     2406                               //| X86_CPUID_AMD_FEATURE_ECX_3DNOWPRF
     2407                               //| X86_CPUID_AMD_FEATURE_ECX_OSVW
     2408                               //| X86_CPUID_AMD_FEATURE_ECX_IBS
     2409                               //| X86_CPUID_AMD_FEATURE_ECX_SSE5
     2410                               //| X86_CPUID_AMD_FEATURE_ECX_SKINIT
     2411                               //| X86_CPUID_AMD_FEATURE_ECX_WDT
     2412                               //| RT_BIT_32(14)                    - reserved
     2413                               //| X86_CPUID_AMD_FEATURE_ECX_LWP    - not supported
     2414                               //| X86_CPUID_AMD_FEATURE_ECX_FMA4   - not yet virtualized.
     2415                               //| RT_BIT_32(17)                    - reserved
     2416                               //| RT_BIT_32(18)                    - reserved
     2417                               //| X86_CPUID_AMD_FEATURE_ECX_NODEID - not yet virtualized.
     2418                               //| RT_BIT_32(20)                    - reserved
     2419                               //| X86_CPUID_AMD_FEATURE_ECX_TBM    - not yet virtualized.
     2420                               //| X86_CPUID_AMD_FEATURE_ECX_TOPOEXT - not yet virtualized.
     2421                               //| RT_BIT_32(23)                    - reserved
     2422                               //| RT_BIT_32(24)                    - reserved
     2423                               //| RT_BIT_32(25)                    - reserved
     2424                               //| RT_BIT_32(26)                    - reserved
     2425                               //| RT_BIT_32(27)                    - reserved
     2426                               //| RT_BIT_32(28)                    - reserved
     2427                               //| RT_BIT_32(29)                    - reserved
     2428                               //| RT_BIT_32(30)                    - reserved
     2429                               //| RT_BIT_32(31)                    - reserved
     2430                               ;
     2431#ifdef VBOX_WITH_MULTI_CORE
     2432        if (   pVM->cCpus > 1
     2433            && pCpum->GuestFeatures.enmCpuVendor == CPUMCPUVENDOR_AMD)
     2434            pExtFeatureLeaf->uEcx |= X86_CPUID_AMD_FEATURE_ECX_CMPL; /* CmpLegacy */
     2435#endif
     2436
     2437        if (pCpum->u8PortableCpuIdLevel > 0)
    21502438        {
    21512439            PORTABLE_DISABLE_FEATURE_BIT(1, pExtFeatureLeaf->uEcx, CR8L,       X86_CPUID_AMD_FEATURE_ECX_CR8L);
     
    21572445            PORTABLE_DISABLE_FEATURE_BIT(3, pExtFeatureLeaf->uEcx, CMOV,       X86_CPUID_AMD_FEATURE_EDX_CMOV);
    21582446
    2159             Assert(!(pExtFeatureLeaf->uEcx & (  X86_CPUID_AMD_FEATURE_ECX_CMPL
    2160                                               | X86_CPUID_AMD_FEATURE_ECX_SVM
     2447            Assert(!(pExtFeatureLeaf->uEcx & (  X86_CPUID_AMD_FEATURE_ECX_SVM
    21612448                                              | X86_CPUID_AMD_FEATURE_ECX_EXT_APIC
    21622449                                              | X86_CPUID_AMD_FEATURE_ECX_CR8L
     
    21832470        }
    21842471    }
    2185 
    2186     /*
    2187      * Hide HTT, multicode, SMP, whatever.
    2188      * (APIC-ID := 0 and #LogCpus := 0)
    2189      */
    2190     pStdFeatureLeaf->uEbx &= 0x0000ffff;
    2191 #ifdef VBOX_WITH_MULTI_CORE
    2192     if (pVM->cCpus > 1)
    2193     {
    2194         /* If CPUID Fn0000_0001_EDX[HTT] = 1 then LogicalProcessorCount is the number of threads per CPU core times the number of CPU cores per processor */
    2195         pStdFeatureLeaf->uEbx |= (pVM->cCpus << 16);
    2196         pStdFeatureLeaf->uEdx |= X86_CPUID_FEATURE_EDX_HTT;  /* necessary for hyper-threading *or* multi-core CPUs */
    2197     }
    2198 #endif
     2472    pExtFeatureLeaf = NULL; /* Must refetch! */
     2473
    21992474
    22002475    /* Cpuid 2:
    2201      * Intel: Cache and TLB information
     2476     * Intel: (Nondeterministic) Cache and TLB information
    22022477     * AMD:   Reserved
    22032478     * VIA:   Reserved
    2204      * Safe to expose; restrict the number of calls to 1 for the portable case.
    2205      */
    2206     PCPUMCPUIDLEAF pCurLeaf = cpumR3CpuIdGetLeaf(pCPUM->GuestInfo.paCpuIdLeavesR3, pCPUM->GuestInfo.cCpuIdLeaves, 2, 0);
    2207     if (   pCPUM->u8PortableCpuIdLevel > 0
    2208         && pCurLeaf
    2209         && (pCurLeaf->uEax & 0xff) > 1)
    2210     {
    2211         LogRel(("PortableCpuId: Std[2].al: %d -> 1\n", pCurLeaf->uEax & 0xff));
    2212         pCurLeaf->uEax &= UINT32_C(0xfffffffe);
     2479     * Safe to expose.  Restrict the number of calls to 1 since we don't
     2480     * implement this kind of subleaves (is there hardware that does??).
     2481     */
     2482    uint32_t        uSubLeaf = 0;
     2483    PCPUMCPUIDLEAF  pCurLeaf;
     2484    while ((pCurLeaf = cpumR3CpuIdGetExactLeaf(pCpum, 2, uSubLeaf)) != NULL)
     2485    {
     2486        if ((pCurLeaf->uEax & 0xff) > 1)
     2487        {
     2488            LogRel(("CpuId: Std[2].al: %d -> 1\n", pCurLeaf->uEax & 0xff));
     2489            pCurLeaf->uEax &= UINT32_C(0xffffff01);
     2490        }
     2491        uSubLeaf++;
    22132492    }
    22142493
     
    22202499     * Safe to expose
    22212500     */
    2222     pCurLeaf = cpumR3CpuIdGetLeaf(pCPUM->GuestInfo.paCpuIdLeavesR3, pCPUM->GuestInfo.cCpuIdLeaves, 3, 0);
    2223     pStdFeatureLeaf = cpumR3CpuIdGetLeaf(pCPUM->GuestInfo.paCpuIdLeavesR3, pCPUM->GuestInfo.cCpuIdLeaves, 1, 0);
    2224     if (   !(pStdFeatureLeaf->uEdx & X86_CPUID_FEATURE_EDX_PSN)
    2225         && pCurLeaf)
    2226     {
    2227         pCurLeaf->uEcx = pCurLeaf->uEdx = 0;
    2228         if (pCPUM->u8PortableCpuIdLevel > 0)
    2229             pCurLeaf->uEax = pCurLeaf->uEbx = 0;
    2230     }
    2231 
    2232     /* Cpuid 4:
    2233      * Intel: Deterministic Cache Parameters Leaf
    2234      *        Note: Depends on the ECX input! -> Feeling rather lazy now, so we just return 0
     2501    pStdFeatureLeaf = cpumR3CpuIdGetExactLeaf(pCpum, 1, 0);
     2502    if (!(pStdFeatureLeaf->uEdx & X86_CPUID_FEATURE_EDX_PSN))
     2503    {
     2504        uSubLeaf = 0;
     2505        while ((pCurLeaf = cpumR3CpuIdGetExactLeaf(pCpum, 3, uSubLeaf)) != NULL)
     2506        {
     2507            pCurLeaf->uEcx = pCurLeaf->uEdx = 0;
     2508            if (pCpum->u8PortableCpuIdLevel > 0)
     2509                pCurLeaf->uEax = pCurLeaf->uEbx = 0;
     2510            uSubLeaf++;
     2511        }
     2512    }
     2513
     2514    /* Cpuid 4 + ECX:
     2515     * Intel: Deterministic Cache Parameters Leaf.
    22352516     * AMD:   Reserved
    22362517     * VIA:   Reserved
     
    22402521     * Note: These SMP values are constant regardless of ECX
    22412522     */
    2242     CPUMCPUIDLEAF NewLeaf;
    2243     pCurLeaf = cpumR3CpuIdGetLeaf(pCPUM->GuestInfo.paCpuIdLeavesR3, pCPUM->GuestInfo.cCpuIdLeaves, 4, 0);
    2244     if (pCurLeaf)
    2245     {
    2246         NewLeaf.uLeaf        = 4;
    2247         NewLeaf.uSubLeaf     = 0;
    2248         NewLeaf.fSubLeafMask = 0;
    2249         NewLeaf.uEax         = 0;
    2250         NewLeaf.uEbx         = 0;
    2251         NewLeaf.uEcx         = 0;
    2252         NewLeaf.uEdx         = 0;
    2253         NewLeaf.fFlags       = 0;
     2523    uSubLeaf = 0;
     2524    while ((pCurLeaf = cpumR3CpuIdGetExactLeaf(pCpum, 4, uSubLeaf)) != NULL)
     2525    {
     2526        pCurLeaf->uEax &= UINT32_C(0xffffc000); /* Clear the #maxcores, #threads-sharing-cache (both are #-1).*/
    22542527#ifdef VBOX_WITH_MULTI_CORE
    22552528        if (   pVM->cCpus > 1
    2256             && pCPUM->GuestFeatures.enmCpuVendor == CPUMCPUVENDOR_INTEL)
     2529            && pCpum->GuestFeatures.enmCpuVendor == CPUMCPUVENDOR_INTEL)
    22572530        {
    22582531            AssertReturn(pVM->cCpus <= 64, VERR_TOO_MANY_CPUS);
    22592532            /* One logical processor with possibly multiple cores. */
    22602533            /* See  http://www.intel.com/Assets/PDF/appnote/241618.pdf p. 29 */
    2261             NewLeaf.uEax |= ((pVM->cCpus - 1) << 26);  /* 6 bits only -> 64 cores! */
     2534            pCurLeaf->uEax |= pVM->cCpus <= 0x40 ? ((pVM->cCpus - 1) << 26) : UINT32_C(0xfc000000); /* 6 bits only -> 64 cores! */
    22622535        }
    22632536#endif
    2264         rc = cpumR3CpuIdInsert(NULL /* pVM */, &pCPUM->GuestInfo.paCpuIdLeavesR3, &pCPUM->GuestInfo.cCpuIdLeaves, &NewLeaf);
    2265         AssertLogRelRCReturn(rc, rc);
     2537        uSubLeaf++;
    22662538    }
    22672539
     
    22752547     * Safe to expose
    22762548     */
    2277     pCurLeaf = cpumR3CpuIdGetLeaf(pCPUM->GuestInfo.paCpuIdLeavesR3, pCPUM->GuestInfo.cCpuIdLeaves, 5, 0);
    2278     if (pCurLeaf)
    2279     {
    2280         pStdFeatureLeaf = cpumR3CpuIdGetLeaf(pCPUM->GuestInfo.paCpuIdLeavesR3, pCPUM->GuestInfo.cCpuIdLeaves, 1, 0);
     2549    uSubLeaf = 0;
     2550    while ((pCurLeaf = cpumR3CpuIdGetExactLeaf(pCpum, 5, uSubLeaf)) != NULL)
     2551    {
     2552        pStdFeatureLeaf = cpumR3CpuIdGetExactLeaf(pCpum, 1, 0);
    22812553        if (!(pStdFeatureLeaf->uEcx & X86_CPUID_FEATURE_ECX_MONITOR))
    22822554            pCurLeaf->uEax = pCurLeaf->uEbx = 0;
    22832555
    22842556        pCurLeaf->uEcx = pCurLeaf->uEdx = 0;
    2285         if (fMWaitExtensions)
     2557        if (pConfig->fMWaitExtensions)
    22862558        {
    22872559            pCurLeaf->uEcx = X86_CPUID_MWAIT_ECX_EXT | X86_CPUID_MWAIT_ECX_BREAKIRQIF0;
     
    23012573        else
    23022574            pCurLeaf->uEcx = pCurLeaf->uEdx = 0;
    2303     }
     2575        uSubLeaf++;
     2576    }
     2577
     2578    /* Cpuid 6: Digital Thermal Sensor and Power Management Paramenters.
     2579     * Intel: Various stuff.
     2580     * AMD: EAX, EBX, EDX - reserved.
     2581     *      ECX - Bit zero is EffFreq, indicating MSR_0000_00e7 and MSR_0000_00e8
     2582     *            present.  Same as intel.
     2583     * VIA: ??
     2584     *
     2585     * We clear everything here for now.
     2586     */
     2587    cpumR3CpuIdZeroLeaf(pCpum, 6);
     2588
     2589    /* Cpuid 7 + ECX: Structured Extended Feature Flags Enumeration
     2590     * EAX: Number of sub leaves.
     2591     * EBX+ECX+EDX: Feature flags
     2592     *
     2593     * We only have documentation for one sub-leaf, so clear all other (no need
     2594     * to remove them as such, just set them to zero).
     2595     *
     2596     * Note! When enabling new features the Synthetic CPU and Portable CPUID
     2597     *       options may require adjusting (i.e. stripping what was enabled).
     2598     */
     2599    uSubLeaf = 0;
     2600    while ((pCurLeaf = cpumR3CpuIdGetExactLeaf(pCpum, 7, uSubLeaf)) != NULL)
     2601    {
     2602        switch (uSubLeaf)
     2603        {
     2604            case 0:
     2605            {
     2606                pCurLeaf->uEax  = 0;    /* Max ECX input is 0. */
     2607                pCurLeaf->uEbx &= 0
     2608                               //| X86_CPUID_STEXT_FEATURE_EBX_FSGSBASE          RT_BIT(0)
     2609                               //| X86_CPUID_STEXT_FEATURE_EBX_TSC_ADJUST        RT_BIT(1)
     2610                               //| RT_BIT(2) - reserved
     2611                               //| X86_CPUID_STEXT_FEATURE_EBX_BMI1              RT_BIT(3)
     2612                               //| X86_CPUID_STEXT_FEATURE_EBX_HLE               RT_BIT(4)
     2613                               //| X86_CPUID_STEXT_FEATURE_EBX_AVX2              RT_BIT(5)
     2614                               //| RT_BIT(6) - reserved
     2615                               //| X86_CPUID_STEXT_FEATURE_EBX_SMEP              RT_BIT(7)
     2616                               //| X86_CPUID_STEXT_FEATURE_EBX_BMI2              RT_BIT(8)
     2617                               //| X86_CPUID_STEXT_FEATURE_EBX_ERMS              RT_BIT(9)
     2618                               //| X86_CPUID_STEXT_FEATURE_EBX_INVPCID           RT_BIT(10)
     2619                               //| X86_CPUID_STEXT_FEATURE_EBX_RTM               RT_BIT(11)
     2620                               //| X86_CPUID_STEXT_FEATURE_EBX_PQM               RT_BIT(12)
     2621                               //| X86_CPUID_STEXT_FEATURE_EBX_DEPR_FPU_CS_DS    RT_BIT(13)
     2622                               //| X86_CPUID_STEXT_FEATURE_EBX_MPE               RT_BIT(14)
     2623                               //| X86_CPUID_STEXT_FEATURE_EBX_PQE               RT_BIT(15)
     2624                               //| X86_CPUID_STEXT_FEATURE_EBX_AVX512F           RT_BIT(16)
     2625                               //| RT_BIT(17) - reserved
     2626                               //| X86_CPUID_STEXT_FEATURE_EBX_RDSEED            RT_BIT(18)
     2627                               //| X86_CPUID_STEXT_FEATURE_EBX_ADX               RT_BIT(19)
     2628                               //| X86_CPUID_STEXT_FEATURE_EBX_SMAP              RT_BIT(20)
     2629                               //| RT_BIT(21) - reserved
     2630                               //| RT_BIT(22) - reserved
     2631                               //| X86_CPUID_STEXT_FEATURE_EBX_CLFLUSHOPT        RT_BIT(23)
     2632                               //| RT_BIT(24) - reserved
     2633                               //| X86_CPUID_STEXT_FEATURE_EBX_INTEL_PT          RT_BIT(25)
     2634                               //| X86_CPUID_STEXT_FEATURE_EBX_AVX512PF          RT_BIT(26)
     2635                               //| X86_CPUID_STEXT_FEATURE_EBX_AVX512ER          RT_BIT(27)
     2636                               //| X86_CPUID_STEXT_FEATURE_EBX_AVX512CD          RT_BIT(28)
     2637                               //| X86_CPUID_STEXT_FEATURE_EBX_SHA               RT_BIT(29)
     2638                               //| RT_BIT(30) - reserved
     2639                               //| RT_BIT(31) - reserved
     2640                               ;
     2641                pCurLeaf->uEcx &= 0
     2642                               //| X86_CPUID_STEXT_FEATURE_ECX_PREFETCHWT1 - we do not do vector functions yet.
     2643                               ;
     2644                pCurLeaf->uEdx &= 0;
     2645
     2646                if (pCpum->u8PortableCpuIdLevel > 0)
     2647                {
     2648                    PORTABLE_DISABLE_FEATURE_BIT(2, pCurLeaf->uEcx, PREFETCHWT1, X86_CPUID_STEXT_FEATURE_ECX_PREFETCHWT1);
     2649                }
     2650                break;
     2651            }
     2652
     2653            default:
     2654                /* Invalid index, all values are zero. */
     2655                pCurLeaf->uEax = 0;
     2656                pCurLeaf->uEbx = 0;
     2657                pCurLeaf->uEcx = 0;
     2658                pCurLeaf->uEdx = 0;
     2659                break;
     2660        }
     2661        uSubLeaf++;
     2662    }
     2663
     2664    /* Cpuid 8: Marked as reserved by Intel and AMD.
     2665     * We zero this since we don't know what it may have been used for.
     2666     */
     2667    cpumR3CpuIdZeroLeaf(pCpum, 8);
     2668
     2669    /* Cpuid 9: Direct Cache Access (DCA) Parameters
     2670     * Intel: EAX - Value of PLATFORM_DCA_CAP bits.
     2671     *        EBX, ECX, EDX - reserved.
     2672     * AMD:   Reserved
     2673     * VIA:   ??
     2674     *
     2675     * We zero this.
     2676     */
     2677    cpumR3CpuIdZeroLeaf(pCpum, 9);
     2678
     2679    /* Cpuid 0xa: Architectural Performance Monitor Features
     2680     * Intel: EAX - Value of PLATFORM_DCA_CAP bits.
     2681     *        EBX, ECX, EDX - reserved.
     2682     * AMD:   Reserved
     2683     * VIA:   ??
     2684     *
     2685     * We zero this, for now at least.
     2686     */
     2687    cpumR3CpuIdZeroLeaf(pCpum, 10);
     2688
     2689    /* Cpuid 0xb+ECX: x2APIC Features / Processor Topology.
     2690     * Intel: EAX - APCI ID shift right for next level.
     2691     *        EBX - Factory configured cores/threads at this level.
     2692     *        ECX - Level number (same as input) and level type (1,2,0).
     2693     *        EDX - Extended initial APIC ID.
     2694     * AMD:   Reserved
     2695     * VIA:   ??
     2696     */
     2697    uSubLeaf = 0;
     2698    while ((pCurLeaf = cpumR3CpuIdGetExactLeaf(pCpum, 11, uSubLeaf)) != NULL)
     2699    {
     2700        if (pCurLeaf->fFlags & CPUMCPUIDLEAF_F_CONTAINS_APIC_ID)
     2701        {
     2702            uint8_t bLevelType = RT_BYTE2(pCurLeaf->uEcx);
     2703            if (bLevelType == 1)
     2704            {
     2705                /* Thread level - we don't do threads at the moment. */
     2706                pCurLeaf->uEax = 0; /** @todo is this correct? Real CPUs never do 0 here, I think... */
     2707                pCurLeaf->uEbx = 1;
     2708            }
     2709            else if (bLevelType == 2)
     2710            {
     2711                /* Core level. */
     2712                pCurLeaf->uEax = 1; /** @todo real CPUs are supposed to be in the 4-6 range, not 1.  Our APIC ID assignments are a little special... */
     2713#ifdef VBOX_WITH_MULTI_CORE
     2714                while (RT_BIT_32(pCurLeaf->uEax) < pVM->cCpus)
     2715                    pCurLeaf->uEax++;
     2716#endif
     2717                pCurLeaf->uEbx = pVM->cCpus;
     2718            }
     2719            else
     2720            {
     2721                AssertLogRelMsg(bLevelType == 0, ("bLevelType=%#x uSubLeaf=%#x\n", bLevelType, uSubLeaf));
     2722                pCurLeaf->uEax = 0;
     2723                pCurLeaf->uEbx = 0;
     2724                pCurLeaf->uEcx = 0;
     2725            }
     2726            pCurLeaf->uEcx = (pCurLeaf->uEcx & UINT32_C(0xffffff00)) | (uSubLeaf & 0xff);
     2727            pCurLeaf->uEdx = 0;  /* APIC ID is filled in by CPUMGetGuestCpuId() at runtime.  Init for EMT(0) as usual. */
     2728        }
     2729        else
     2730        {
     2731            Assert(pCpum->GuestFeatures.enmCpuVendor != CPUMCPUVENDOR_INTEL);
     2732            pCurLeaf->uEax = 0;
     2733            pCurLeaf->uEbx = 0;
     2734            pCurLeaf->uEcx = 0;
     2735            pCurLeaf->uEdx = 0;
     2736        }
     2737        uSubLeaf++;
     2738    }
     2739
     2740    /* Cpuid 0xc: Marked as reserved by Intel and AMD.
     2741     * We zero this since we don't know what it may have been used for.
     2742     */
     2743    cpumR3CpuIdZeroLeaf(pCpum, 12);
     2744
     2745    /* Cpuid 0xd + ECX: Processor Extended State Enumeration
     2746     * ECX=0:   EAX - Valid bits in XCR0[31:0].
     2747     *          EBX - Maximum state size as per current XCR0 value.
     2748     *          ECX - Maximum state size for all supported features.
     2749     *          EDX - Valid bits in XCR0[63:32].
     2750     * ECX=1:   EAX - Various X-features.
     2751     *          EBX - Maximum state size as per current XCR0|IA32_XSS value.
     2752     *          ECX - Valid bits in IA32_XSS[31:0].
     2753     *          EDX - Valid bits in IA32_XSS[63:32].
     2754     * ECX=N, where N in 2..63 and indicates a bit in XCR0 and/or IA32_XSS,
     2755     *        if the bit invalid all four registers are set to zero.
     2756     *          EAX - The state size for this feature.
     2757     *          EBX - The state byte offset of this feature.
     2758     *          ECX - Bit 0 indicates whether this sub-leaf maps to a valid IA32_XSS bit (=1) or a valid XCR0 bit (=0).
     2759     *          EDX - Reserved, but is set to zero if invalid sub-leaf index.
     2760     *
     2761     * Clear them all as we don't currently implement extended CPU state.
     2762     */
     2763    uSubLeaf = 0;
     2764    while ((pCurLeaf = cpumR3CpuIdGetExactLeaf(pCpum, 13, uSubLeaf)) != NULL)
     2765    {
     2766        pCurLeaf->uEax = 0;
     2767        pCurLeaf->uEbx = 0;
     2768        pCurLeaf->uEcx = 0;
     2769        pCurLeaf->uEdx = 0;
     2770        uSubLeaf++;
     2771    }
     2772
     2773    /* Cpuid 0xe: Marked as reserved by Intel and AMD.
     2774     * We zero this since we don't know what it may have been used for.
     2775     */
     2776    cpumR3CpuIdZeroLeaf(pCpum, 14);
     2777
     2778    /* Cpuid 0xf + ECX: Platform qualifity of service monitoring (PQM).
     2779     * We zero this as we don't currently virtualize PQM.
     2780     */
     2781    cpumR3CpuIdZeroLeaf(pCpum, 15);
     2782
     2783    /* Cpuid 0x10 + ECX: Platform qualifity of service enforcement (PQE).
     2784     * We zero this as we don't currently virtualize PQE.
     2785     */
     2786    cpumR3CpuIdZeroLeaf(pCpum, 16);
     2787
     2788    /* Cpuid 0x11: Marked as reserved by Intel and AMD.
     2789     * We zero this since we don't know what it may have been used for.
     2790     */
     2791    cpumR3CpuIdZeroLeaf(pCpum, 17);
     2792
     2793    /* Cpuid 0x12 + ECX: SGX resource enumeration.
     2794     * We zero this as we don't currently virtualize this.
     2795     */
     2796    cpumR3CpuIdZeroLeaf(pCpum, 18);
     2797
     2798    /* Cpuid 0x13: Marked as reserved by Intel and AMD.
     2799     * We zero this since we don't know what it may have been used for.
     2800     */
     2801    cpumR3CpuIdZeroLeaf(pCpum, 19);
     2802
     2803    /* Cpuid 0x14 + ECX: Processor Trace (PT) capability enumeration.
     2804     * We zero this as we don't currently virtualize this.
     2805     */
     2806    cpumR3CpuIdZeroLeaf(pCpum, 20);
     2807
     2808    /* Cpuid 0x15: Timestamp Counter / Core Crystal Clock info.
     2809     * Intel: uTscFrequency = uCoreCrystalClockFrequency * EBX / EAX.
     2810     *        EAX - denominator (unsigned).
     2811     *        EBX - numerator (unsigned).
     2812     *        ECX, EDX - reserved.
     2813     * AMD:   Reserved / undefined / not implemented.
     2814     * VIA:   Reserved / undefined / not implemented.
     2815     * We zero this as we don't currently virtualize this.
     2816     */
     2817    cpumR3CpuIdZeroLeaf(pCpum, 21);
     2818
     2819    /* Cpuid 0x16: Processor frequency info
     2820     * Intel: EAX - Core base frequency in MHz.
     2821     *        EBX - Core maximum frequency in MHz.
     2822     *        ECX - Bus (reference) frequency in MHz.
     2823     *        EDX - Reserved.
     2824     * AMD:   Reserved / undefined / not implemented.
     2825     * VIA:   Reserved / undefined / not implemented.
     2826     * We zero this as we don't currently virtualize this.
     2827     */
     2828    cpumR3CpuIdZeroLeaf(pCpum, 22);
     2829
     2830    /* Cpuid 0x17..0x10000000: Unknown.
     2831     * We don't know these and what they mean, so remove them. */
     2832    cpumR3CpuIdRemoveRange(pCpum->GuestInfo.paCpuIdLeavesR3, &pCpum->GuestInfo.cCpuIdLeaves,
     2833                           UINT32_C(0x00000017), UINT32_C(0x0fffffff));
     2834
     2835
     2836    /* CpuId 0x40000000..0x4fffffff: Reserved for hypervisor/emulator.
     2837     * We remove all these as we're a hypervisor and must provide our own.
     2838     */
     2839    cpumR3CpuIdRemoveRange(pCpum->GuestInfo.paCpuIdLeavesR3, &pCpum->GuestInfo.cCpuIdLeaves,
     2840                           UINT32_C(0x40000000), UINT32_C(0x4fffffff));
     2841
     2842
     2843    /* Cpuid 0x80000000 is harmless. */
     2844
     2845    /* Cpuid 0x80000001 is handled with cpuid 1 way up above. */
     2846
     2847    /* Cpuid 0x80000002...0x80000004 contains the processor name and is considered harmless. */
    23042848
    23052849    /* Cpuid 0x800000005 & 0x800000006 contain information about L1, L2 & L3 cache and TLB identifiers.
    23062850     * Safe to pass on to the guest.
    23072851     *
     2852     * AMD:   0x800000005 L1 cache information
     2853     *        0x800000006 L2/L3 cache information
    23082854     * Intel: 0x800000005 reserved
    23092855     *        0x800000006 L2 cache information
    2310      * AMD:   0x800000005 L1 cache information
    2311      *        0x800000006 L2/L3 cache information
    23122856     * VIA:   0x800000005 TLB and L1 cache information
    23132857     *        0x800000006 L2 cache information
    23142858     */
    23152859
    2316     /* Cpuid 0x800000007:
    2317      * Intel:             Reserved
    2318      * AMD:               EAX, EBX, ECX - reserved
    2319      *                    EDX: Advanced Power Management Information
    2320      * VIA:               Reserved
    2321      */
    2322     pCurLeaf = cpumR3CpuIdGetLeaf(pCPUM->GuestInfo.paCpuIdLeavesR3, pCPUM->GuestInfo.cCpuIdLeaves, UINT32_C(0x80000007), 0);
    2323     if (pCurLeaf)
    2324     {
    2325         Assert(pCPUM->GuestFeatures.enmCpuVendor != CPUMCPUVENDOR_INVALID);
    2326 
     2860    /* Cpuid 0x800000007: Advanced Power Management Information.
     2861     * AMD:   EAX: Processor feedback capabilities.
     2862     *        EBX: RAS capabilites.
     2863     *        ECX: Advanced power monitoring interface.
     2864     *        EDX: Enhanced power management capabilities.
     2865     * Intel: EAX, EBX, ECX - reserved.
     2866     *        EDX - Invariant TSC indicator supported (bit 8), the rest is reserved.
     2867     * VIA:   Reserved
     2868     * We let the guest see EDX_TSCINVAR (and later maybe EDX_EFRO). Actually, we should set EDX_TSCINVAR.
     2869     */
     2870    uSubLeaf = 0;
     2871    while ((pCurLeaf = cpumR3CpuIdGetExactLeaf(pCpum, UINT32_C(0x80000007), uSubLeaf)) != NULL)
     2872    {
    23272873        pCurLeaf->uEax = pCurLeaf->uEbx = pCurLeaf->uEcx = 0;
    2328 
    2329         if (pCPUM->GuestFeatures.enmCpuVendor == CPUMCPUVENDOR_AMD)
    2330         {
    2331             /* Only expose the TSC invariant capability bit to the guest. */
    2332             pCurLeaf->uEdx                  &= 0
    2333                                             //| X86_CPUID_AMD_ADVPOWER_EDX_TS
    2334                                             //| X86_CPUID_AMD_ADVPOWER_EDX_FID
    2335                                             //| X86_CPUID_AMD_ADVPOWER_EDX_VID
    2336                                             //| X86_CPUID_AMD_ADVPOWER_EDX_TTP
    2337                                             //| X86_CPUID_AMD_ADVPOWER_EDX_TM
    2338                                             //| X86_CPUID_AMD_ADVPOWER_EDX_STC
    2339                                             //| X86_CPUID_AMD_ADVPOWER_EDX_MC
    2340                                             //| X86_CPUID_AMD_ADVPOWER_EDX_HWPSTATE
    2341 #if 0
    2342         /*
     2874        if (pCpum->GuestFeatures.enmCpuVendor == CPUMCPUVENDOR_AMD)
     2875        {
     2876            pCurLeaf->uEdx &= 0
     2877                           //| X86_CPUID_AMD_ADVPOWER_EDX_TS
     2878                           //| X86_CPUID_AMD_ADVPOWER_EDX_FID
     2879                           //| X86_CPUID_AMD_ADVPOWER_EDX_VID
     2880                           //| X86_CPUID_AMD_ADVPOWER_EDX_TTP
     2881                           //| X86_CPUID_AMD_ADVPOWER_EDX_TM
     2882                           //| X86_CPUID_AMD_ADVPOWER_EDX_STC
     2883                           //| X86_CPUID_AMD_ADVPOWER_EDX_MC
     2884                           //| X86_CPUID_AMD_ADVPOWER_EDX_HWPSTATE
     2885#if 0   /*
    23432886         * We don't expose X86_CPUID_AMD_ADVPOWER_EDX_TSCINVAR, because newer
    23442887         * Linux kernels blindly assume that the AMD performance counters work
     
    23462889         * bit for them though.)
    23472890         */
    2348                                             | X86_CPUID_AMD_ADVPOWER_EDX_TSCINVAR
     2891        /** @todo need to recheck this with new MSR emulation. */
     2892                           | X86_CPUID_AMD_ADVPOWER_EDX_TSCINVAR
    23492893#endif
    2350                                             | 0;
     2894                           //| X86_CPUID_AMD_ADVPOWER_EDX_CPB       RT_BIT(9)
     2895                           //| X86_CPUID_AMD_ADVPOWER_EDX_EFRO      RT_BIT(10)
     2896                           //| X86_CPUID_AMD_ADVPOWER_EDX_PFI       RT_BIT(11)
     2897                           //| X86_CPUID_AMD_ADVPOWER_EDX_PA        RT_BIT(12)
     2898                           | 0;
    23512899        }
    23522900        else
    2353             pCurLeaf->uEdx = 0;
    2354     }
    2355 
    2356     /* Cpuid 0x800000008:
    2357      * Intel:             EAX: Virtual/Physical address Size
    2358      *                    EBX, ECX, EDX - reserved
     2901            pCurLeaf->uEdx &= X86_CPUID_AMD_ADVPOWER_EDX_TSCINVAR;
     2902        if (pConfig->fInvariantTsc)
     2903            pCurLeaf->uEdx |= X86_CPUID_AMD_ADVPOWER_EDX_TSCINVAR;
     2904        uSubLeaf++;
     2905    }
     2906
     2907    /* Cpuid 0x80000008:
    23592908     * AMD:               EBX, EDX - reserved
    23602909     *                    EAX: Virtual/Physical/Guest address Size
    23612910     *                    ECX: Number of cores + APICIdCoreIdSize
     2911     * Intel:             EAX: Virtual/Physical address Size
     2912     *                    EBX, ECX, EDX - reserved
    23622913     * VIA:               EAX: Virtual/Physical address Size
    23632914     *                    EBX, ECX, EDX - reserved
    2364      */
    2365     pCurLeaf = cpumR3CpuIdGetLeaf(pCPUM->GuestInfo.paCpuIdLeavesR3, pCPUM->GuestInfo.cCpuIdLeaves, UINT32_C(0x80000008), 0);
    2366     if (pCurLeaf)
    2367     {
    2368         /* Only expose the virtual and physical address sizes to the guest. */
    2369         pCurLeaf->uEax &= UINT32_C(0x0000ffff);
    2370         pCurLeaf->uEbx = pCurLeaf->uEdx = 0;  /* reserved */
    2371         /* Set APICIdCoreIdSize to zero (use legacy method to determine the number of cores per cpu)
    2372          * NC (0-7) Number of cores; 0 equals 1 core */
     2915     *
     2916     * We only expose the virtual+pysical address size to the guest atm.
     2917     * On AMD we set the core count, but not the apic id stuff as we're
     2918     * currently not doing the apic id assignments in a complatible manner.
     2919     */
     2920    uSubLeaf = 0;
     2921    while ((pCurLeaf = cpumR3CpuIdGetExactLeaf(pCpum, UINT32_C(0x80000008), uSubLeaf)) != NULL)
     2922    {
     2923        pCurLeaf->uEax &= UINT32_C(0x0000ffff); /* Virtual & physical address sizes only. */
     2924        pCurLeaf->uEbx  = 0;  /* reserved */
     2925        pCurLeaf->uEdx  = 0;  /* reserved */
     2926
     2927        /* Set APICIdCoreIdSize to zero (use legacy method to determine the number of cores per cpu).
     2928         * Set core count to 0, indicating 1 core. Adjust if we're in multi core mode on AMD. */
    23732929        pCurLeaf->uEcx = 0;
    23742930#ifdef VBOX_WITH_MULTI_CORE
    2375         if (    pVM->cCpus > 1
    2376             &&  pCPUM->GuestFeatures.enmCpuVendor == CPUMCPUVENDOR_AMD)
    2377         {
    2378             /* Legacy method to determine the number of cores. */
    2379             pCurLeaf->uEcx |= (pVM->cCpus - 1); /* NC: Number of CPU cores - 1; 8 bits */
    2380             pExtFeatureLeaf = cpumR3CpuIdGetLeaf(pCPUM->GuestInfo.paCpuIdLeavesR3, pCPUM->GuestInfo.cCpuIdLeaves,
    2381                                                  UINT32_C(0x80000001), 0);
    2382             if (pExtFeatureLeaf)
    2383                 pExtFeatureLeaf->uEcx |= X86_CPUID_AMD_FEATURE_ECX_CMPL;
    2384         }
     2931        if (   pVM->cCpus > 1
     2932            && pCpum->GuestFeatures.enmCpuVendor == CPUMCPUVENDOR_AMD)
     2933            pCurLeaf->uEcx |= (pVM->cCpus - 1) & UINT32_C(0xff);
    23852934#endif
    2386     }
    2387 
     2935        uSubLeaf++;
     2936    }
     2937
     2938    /* Cpuid 0x80000009: Reserved
     2939     * We zero this since we don't know what it may have been used for.
     2940     */
     2941    cpumR3CpuIdZeroLeaf(pCpum, UINT32_C(0x80000009));
     2942
     2943    /* Cpuid 0x8000000a: SVM Information
     2944     * AMD: EAX - SVM revision.
     2945     *      EBX - Number of ASIDs.
     2946     *      ECX - Reserved.
     2947     *      EDX - SVM Feature identification.
     2948     * We clear all as we currently does not virtualize SVM.
     2949     */
     2950    cpumR3CpuIdZeroLeaf(pCpum, UINT32_C(0x8000000a));
     2951
     2952    /* Cpuid 0x8000000b thru 0x80000018: Reserved
     2953     * We clear these as we don't know what purpose they might have. */
     2954    for (uint32_t uLeaf = UINT32_C(0x8000000b); uLeaf <= UINT32_C(0x80000018); uLeaf++)
     2955        cpumR3CpuIdZeroLeaf(pCpum, uLeaf);
     2956
     2957    /* Cpuid 0x80000019: TLB configuration
     2958     * Seems to be harmless, pass them thru as is. */
     2959
     2960    /* Cpuid 0x8000001a: Peformance optimization identifiers.
     2961     * Strip anything we don't know what is or addresses feature we don't implement. */
     2962    uSubLeaf = 0;
     2963    while ((pCurLeaf = cpumR3CpuIdGetExactLeaf(pCpum, UINT32_C(0x8000001a), uSubLeaf)) != NULL)
     2964    {
     2965        pCurLeaf->uEax &= RT_BIT_32(0) /* FP128 - use 1x128-bit instead of 2x64-bit. */
     2966                        | RT_BIT_32(1) /* MOVU - Prefere unaligned MOV over MOVL + MOVH. */
     2967                        //| RT_BIT_32(2) /* FP256 - use 1x256-bit instead of 2x128-bit. */
     2968                        ;
     2969        pCurLeaf->uEbx  = 0;  /* reserved */
     2970        pCurLeaf->uEcx  = 0;  /* reserved */
     2971        pCurLeaf->uEdx  = 0;  /* reserved */
     2972        uSubLeaf++;
     2973    }
     2974
     2975    /* Cpuid 0x8000001b: Instruct based sampling (IBS) information.
     2976     * Clear this as we don't currently virtualize this feature. */
     2977    cpumR3CpuIdZeroLeaf(pCpum, UINT32_C(0x8000001b));
     2978
     2979    /* Cpuid 0x8000001c: Lightweight profiling (LWP) information.
     2980     * Clear this as we don't currently virtualize this feature. */
     2981    cpumR3CpuIdZeroLeaf(pCpum, UINT32_C(0x8000001c));
     2982
     2983    /* Cpuid 0x8000001d+ECX: Get cache configuration descriptors.
     2984     * We need to sanitize the cores per cache (EAX[25:14]).
     2985     *
     2986     * This is very much the same as Intel's CPUID(4) leaf, except EAX[31:26]
     2987     * and EDX[2] are reserved here, and EAX[14:25] is documented having a
     2988     * slightly different meaning.
     2989     */
     2990    uSubLeaf = 0;
     2991    while ((pCurLeaf = cpumR3CpuIdGetExactLeaf(pCpum, UINT32_C(0x8000001d), uSubLeaf)) != NULL)
     2992    {
     2993#ifdef VBOX_WITH_MULTI_CORE
     2994        uint32_t cCores = ((pCurLeaf->uEax >> 14) & 0xfff) + 1;
     2995        if (cCores > pVM->cCpus)
     2996            cCores = pVM->cCpus;
     2997        pCurLeaf->uEax &= UINT32_C(0x00003fff);
     2998        pCurLeaf->uEax |= ((cCores - 1) & 0xfff) << 14;
     2999#else
     3000        pCurLeaf->uEax &= UINT32_C(0x00003fff);
     3001#endif
     3002        uSubLeaf++;
     3003    }
     3004
     3005    /* Cpuid 0x8000001e: Get APIC / unit / node information.
     3006     * If AMD, we configure it for our layout (on EMT(0)).  In the multi-core
     3007     * setup, we have one compute unit with all the cores in it.  Single node.
     3008     */
     3009    uSubLeaf = 0;
     3010    while ((pCurLeaf = cpumR3CpuIdGetExactLeaf(pCpum, UINT32_C(0x8000001e), uSubLeaf)) != NULL)
     3011    {
     3012        pCurLeaf->uEax = 0; /* Extended APIC ID = EMT(0).idApic (== 0).  */
     3013        if (pCurLeaf->fFlags & CPUMCPUIDLEAF_F_CONTAINS_APIC_ID)
     3014        {
     3015#ifdef VBOX_WITH_MULTI_CORE
     3016            pCurLeaf->uEbx = pVM->cCpus < 0x100
     3017                           ? (pVM->cCpus - 1) << 8 : UINT32_C(0x0000ff00); /* Compute unit ID 0, core per unit. */
     3018#else
     3019            pCurLeaf->uEbx = 0; /* Compute unit ID 0, 1 core per unit. */
     3020#endif
     3021            pCurLeaf->uEcx = 0; /* Node ID 0, 1 node per CPU. */
     3022        }
     3023        else
     3024        {
     3025            Assert(pCpum->GuestFeatures.enmCpuVendor != CPUMCPUVENDOR_AMD);
     3026            pCurLeaf->uEbx = 0; /* Reserved. */
     3027            pCurLeaf->uEcx = 0; /* Reserved. */
     3028        }
     3029        pCurLeaf->uEdx = 0; /* Reserved. */
     3030        uSubLeaf++;
     3031    }
     3032
     3033    /* Cpuid 0x8000001f...0x8ffffffd: Unknown.
     3034     * We don't know these and what they mean, so remove them. */
     3035    cpumR3CpuIdRemoveRange(pCpum->GuestInfo.paCpuIdLeavesR3, &pCpum->GuestInfo.cCpuIdLeaves,
     3036                           UINT32_C(0x8000001f), UINT32_C(0x8ffffffd));
     3037
     3038    /* Cpuid 0x8ffffffe: Mystery AMD K6 leaf.
     3039     * Just pass it thru for now. */
     3040
     3041    /* Cpuid 0x8fffffff: Mystery hammer time leaf!
     3042     * Just pass it thru for now. */
     3043
     3044    /* Cpuid 0xc0000000: Centaur stuff.
     3045     * Harmless, pass it thru. */
     3046
     3047    /* Cpuid 0xc0000001: Centaur features.
     3048     * VIA: EAX - Family, model, stepping.
     3049     *      EDX - Centaur extended feature flags.  Nothing interesting, except may
     3050     *            FEMMS (bit 5), but VIA marks it as 'reserved', so never mind.
     3051     *      EBX, ECX - reserved.
     3052     * We keep EAX but strips the rest.
     3053     */
     3054    uSubLeaf = 0;
     3055    while ((pCurLeaf = cpumR3CpuIdGetExactLeaf(pCpum, UINT32_C(0xc0000001), uSubLeaf)) != NULL)
     3056    {
     3057        pCurLeaf->uEbx = 0;
     3058        pCurLeaf->uEcx = 0;
     3059        pCurLeaf->uEdx = 0; /* Bits 0 thru 9 are documented on sandpil.org, but we don't want them, except maybe 5 (FEMMS). */
     3060        uSubLeaf++;
     3061    }
     3062
     3063    /* Cpuid 0xc0000002: Old Centaur Current Performance Data.
     3064     * We only have fixed stale values, but should be harmless. */
     3065
     3066    /* Cpuid 0xc0000003: Reserved.
     3067     * We zero this since we don't know what it may have been used for.
     3068     */
     3069    cpumR3CpuIdZeroLeaf(pCpum, UINT32_C(0xc0000003));
     3070
     3071    /* Cpuid 0xc0000004: Centaur Performance Info.
     3072     * We only have fixed stale values, but should be harmless. */
     3073
     3074
     3075    /* Cpuid 0xc0000005...0xcfffffff: Unknown.
     3076     * We don't know these and what they mean, so remove them. */
     3077    cpumR3CpuIdRemoveRange(pCpum->GuestInfo.paCpuIdLeavesR3, &pCpum->GuestInfo.cCpuIdLeaves,
     3078                           UINT32_C(0xc0000005), UINT32_C(0xcfffffff));
     3079
     3080    return VINF_SUCCESS;
     3081#undef PORTABLE_DISABLE_FEATURE_BIT
     3082#undef PORTABLE_CLEAR_BITS_WHEN
     3083}
     3084
     3085
     3086static int cpumR3CpuIdReadConfig(PCPUM pCpum, PCPUMCPUIDCONFIG pConfig, PCFGMNODE pCpumCfg)
     3087{
     3088    int rc;
     3089
     3090    /** @cfgm{/CPUM/SyntheticCpu, boolean, false}
     3091     * Enables the Synthetic CPU.  The Vendor ID and Processor Name are
     3092     * completely overridden by VirtualBox custom strings.  Some
     3093     * CPUID information is withheld, like the cache info.
     3094     *
     3095     * This is obsoleted by PortableCpuIdLevel. */
     3096    rc = CFGMR3QueryBoolDef(pCpumCfg, "SyntheticCpu", &pConfig->fSyntheticCpu, false);
     3097    AssertRCReturn(rc, rc);
     3098
     3099    /** @cfgm{/CPUM/PortableCpuIdLevel, 8-bit, 0, 3, 0}
     3100     * When non-zero CPUID features that could cause portability issues will be
     3101     * stripped.  The higher the value the more features gets stripped.  Higher
     3102     * values should only be used when older CPUs are involved since it may
     3103     * harm performance and maybe also cause problems with specific guests. */
     3104    rc = CFGMR3QueryU8Def(pCpumCfg, "PortableCpuIdLevel", &pCpum->u8PortableCpuIdLevel, pConfig->fSyntheticCpu ? 1 : 0);
     3105    AssertLogRelRCReturn(rc, rc);
     3106
     3107    /** @cfgm{/CPUM/GuestCpuName, string}
     3108     * The name of the CPU we're to emulate.  The default is the host CPU.
     3109     * Note! CPUs other than "host" one is currently unsupported. */
     3110    rc = CFGMR3QueryStringDef(pCpumCfg, "GuestCpuName", pConfig->szCpuName, sizeof(pConfig->szCpuName), "host");
     3111    AssertLogRelRCReturn(rc, rc);
     3112
     3113    /** @cfgm{/CPUM/CMPXCHG16B, boolean, false}
     3114     * Expose CMPXCHG16B to the guest if supported by the host.
     3115     */
     3116    rc = CFGMR3QueryBoolDef(pCpumCfg, "CMPXCHG16B", &pConfig->fCmpXchg16b, false);
     3117    AssertLogRelRCReturn(rc, rc);
     3118
     3119    /** @cfgm{/CPUM/MONITOR, boolean, true}
     3120     * Expose MONITOR/MWAIT instructions to the guest.
     3121     */
     3122    rc = CFGMR3QueryBoolDef(pCpumCfg, "MONITOR", &pConfig->fMonitor, true);
     3123    AssertLogRelRCReturn(rc, rc);
     3124
     3125    /** @cfgm{/CPUM/MWaitExtensions, boolean, false}
     3126     * Expose MWAIT extended features to the guest.  For now we expose just MWAIT
     3127     * break on interrupt feature (bit 1).
     3128     */
     3129    rc = CFGMR3QueryBoolDef(pCpumCfg, "MWaitExtensions", &pConfig->fMWaitExtensions, false);
     3130    AssertLogRelRCReturn(rc, rc);
     3131
     3132    /** @cfgm{/CPUM/SSE4.1, boolean, true}
     3133     * Expose SSE4.1 to the guest if available.
     3134     */
     3135    rc = CFGMR3QueryBoolDef(pCpumCfg, "SSE4.1", &pConfig->fSse41, true);
     3136    AssertLogRelRCReturn(rc, rc);
     3137
     3138    /** @cfgm{/CPUM/SSE4.2, boolean, true}
     3139     * Expose SSE4.2 to the guest if available.
     3140     */
     3141    rc = CFGMR3QueryBoolDef(pCpumCfg, "SSE4.2", &pConfig->fSse42, true);
     3142    AssertLogRelRCReturn(rc, rc);
     3143
     3144    /** @cfgm{/CPUM/NT4LeafLimit, boolean, false}
     3145     * Limit the number of standard CPUID leaves to 0..3 to prevent NT4 from
     3146     * bugchecking with MULTIPROCESSOR_CONFIGURATION_NOT_SUPPORTED (0x3e).
     3147     * This option corresponds somewhat to IA32_MISC_ENABLES.BOOT_NT4[bit 22].
     3148     */
     3149    rc = CFGMR3QueryBoolDef(pCpumCfg, "NT4LeafLimit", &pConfig->fNt4LeafLimit, false);
     3150    AssertLogRelRCReturn(rc, rc);
     3151
     3152    /** @cfgm{/CPUM/InvariantTsc, boolean, complicated}
     3153     * Set the invariant TSC flag in 0x80000007 if true, otherwas take default
     3154     * action.  By default the flag is passed thru as is from the host CPU, except
     3155     * on AMD CPUs where it's suppressed to avoid trouble from linux assuming we
     3156     * virtualize performance counters.
     3157     */
     3158    rc = CFGMR3QueryBoolDef(pCpumCfg, "InvariantTsc", &pConfig->fInvariantTsc, false);
     3159    AssertLogRelRCReturn(rc, rc);
     3160
     3161    /** @cfgm{/CPUM/MaxIntelFamilyModelStep, uint32_t, UINT32_MAX}
     3162     * Restrict the reported CPU family+model+stepping of intel CPUs.  This is
     3163     * probably going to be a temporary hack, so don't depend on this.
     3164     * The 1st byte of the value is the stepping, the 2nd byte value is the model
     3165     * number and the 3rd byte value is the family, and the 4th value must be zero.
     3166     */
     3167    rc = CFGMR3QueryU32Def(pCpumCfg, "MaxIntelFamilyModelStep", &pConfig->uMaxIntelFamilyModelStep, UINT32_MAX);
     3168    AssertLogRelRCReturn(rc, rc);
     3169
     3170    return VINF_SUCCESS;
     3171}
     3172
     3173
     3174/**
     3175 * Initializes the emulated CPU's CPUID & MSR information.
     3176 *
     3177 * @returns VBox status code.
     3178 * @param   pVM          Pointer to the VM.
     3179 */
     3180int cpumR3InitCpuIdAndMsrs(PVM pVM)
     3181{
     3182    PCPUM       pCpum    = &pVM->cpum.s;
     3183    PCFGMNODE   pCpumCfg = CFGMR3GetChild(CFGMR3GetRoot(pVM), "CPUM");
    23883184
    23893185    /*
    2390      * Limit it the number of entries, zapping the remainder.
     3186     * Read the configuration.
     3187     */
     3188    CPUMCPUIDCONFIG Config;
     3189    RT_ZERO(Config);
     3190    int rc = cpumR3CpuIdReadConfig(pCpum, &Config, pCpumCfg);
     3191    AssertRCReturn(rc, rc);
     3192
     3193    /*
     3194     * Get the guest CPU data from the database and/or the host.
    23913195     *
    2392      * The limits are masking off stuff about power saving and similar, this
    2393      * is perhaps a bit crudely done as there is probably some relatively harmless
    2394      * info too in these leaves (like words about having a constant TSC).
    2395      */
    2396     pCurLeaf = cpumR3CpuIdGetLeaf(pCPUM->GuestInfo.paCpuIdLeavesR3, pCPUM->GuestInfo.cCpuIdLeaves, 0, 0);
    2397     if (pCurLeaf)
    2398     {
    2399         if (pCurLeaf->uEax > 5)
    2400         {
    2401             pCurLeaf->uEax = 5;
    2402             cpumR3CpuIdRemoveRange(pCPUM->GuestInfo.paCpuIdLeavesR3, &pCPUM->GuestInfo.cCpuIdLeaves,
    2403                                    pCurLeaf->uEax + 1, UINT32_C(0x000fffff));
    2404         }
    2405 
    2406         /* NT4 hack, no zapping of extra leaves here. */
    2407         if (fNt4LeafLimit && pCurLeaf->uEax > 3)
    2408             pCurLeaf->uEax = 3;
    2409     }
    2410 
    2411     pCurLeaf = cpumR3CpuIdGetLeaf(pCPUM->GuestInfo.paCpuIdLeavesR3, pCPUM->GuestInfo.cCpuIdLeaves, UINT32_C(0x80000000), 0);
    2412     if (pCurLeaf)
    2413     {
    2414         if (pCurLeaf->uEax > UINT32_C(0x80000008))
    2415         {
    2416             pCurLeaf->uEax = UINT32_C(0x80000008);
    2417             cpumR3CpuIdRemoveRange(pCPUM->GuestInfo.paCpuIdLeavesR3, &pCPUM->GuestInfo.cCpuIdLeaves,
    2418                                    pCurLeaf->uEax + 1, UINT32_C(0x800fffff));
    2419         }
    2420     }
     3196     * The CPUID and MSRs are currently living on the regular heap to avoid
     3197     * fragmenting the hyper heap (and because there isn't/wasn't any realloc
     3198     * API for the hyper heap).  This means special cleanup considerations.
     3199     */
     3200    rc = cpumR3DbGetCpuInfo(Config.szCpuName, &pCpum->GuestInfo);
     3201    if (RT_FAILURE(rc))
     3202        return rc == VERR_CPUM_DB_CPU_NOT_FOUND
     3203             ? VMSetError(pVM, rc, RT_SRC_POS,
     3204                          "Info on guest CPU '%s' could not be found. Please, select a different CPU.", Config.szCpuName)
     3205             : rc;
     3206
     3207    /** @cfgm{/CPUM/MSRs/[Name]/[First|Last|Type|Value|...],}
     3208     * Overrides the guest MSRs.
     3209     */
     3210    rc = cpumR3LoadMsrOverrides(pVM, CFGMR3GetChild(pCpumCfg, "MSRs"));
     3211
     3212    /** @cfgm{/CPUM/HostCPUID/[000000xx|800000xx|c000000x]/[eax|ebx|ecx|edx],32-bit}
     3213     * Overrides the CPUID leaf values (from the host CPU usually) used for
     3214     * calculating the guest CPUID leaves.  This can be used to preserve the CPUID
     3215     * values when moving a VM to a different machine.  Another use is restricting
     3216     * (or extending) the feature set exposed to the guest. */
     3217    if (RT_SUCCESS(rc))
     3218        rc = cpumR3LoadCpuIdOverrides(pVM, CFGMR3GetChild(pCpumCfg, "HostCPUID"), "HostCPUID");
     3219
     3220    if (RT_SUCCESS(rc) && CFGMR3GetChild(pCpumCfg, "CPUID")) /* 2nd override, now discontinued. */
     3221        rc = VMSetError(pVM, VERR_CFGM_CONFIG_UNKNOWN_NODE, RT_SRC_POS,
     3222                        "Found unsupported configuration node '/CPUM/CPUID/'. "
     3223                        "Please use IMachine::setCPUIDLeaf() instead.");
    24213224
    24223225    /*
    2423      * Centaur stuff (VIA).
    2424      *
    2425      * The important part here (we think) is to make sure the 0xc0000000
    2426      * function returns 0xc0000001. As for the features, we don't currently
    2427      * let on about any of those... 0xc0000002 seems to be some
    2428      * temperature/hz/++ stuff, include it as well (static).
    2429      */
    2430     pCurLeaf = cpumR3CpuIdGetLeaf(pCPUM->GuestInfo.paCpuIdLeavesR3, pCPUM->GuestInfo.cCpuIdLeaves, UINT32_C(0xc0000000), 0);
    2431     if (pCurLeaf)
    2432     {
    2433         if (   pCurLeaf->uEax >= UINT32_C(0xc0000000)
    2434             && pCurLeaf->uEax <= UINT32_C(0xc0000004))
    2435         {
    2436             pCurLeaf->uEax = RT_MIN(pCurLeaf->uEax, UINT32_C(0xc0000002));
    2437             cpumR3CpuIdRemoveRange(pCPUM->GuestInfo.paCpuIdLeavesR3, &pCPUM->GuestInfo.cCpuIdLeaves,
    2438                                    UINT32_C(0xc0000002), UINT32_C(0xc00fffff));
    2439 
    2440             pCurLeaf = cpumR3CpuIdGetLeaf(pCPUM->GuestInfo.paCpuIdLeavesR3, pCPUM->GuestInfo.cCpuIdLeaves,
    2441                                           UINT32_C(0xc0000001), 0);
    2442             if (pCurLeaf)
    2443                 pCurLeaf->uEdx = 0; /* all features hidden */
    2444         }
    2445         else
    2446             cpumR3CpuIdRemoveRange(pCPUM->GuestInfo.paCpuIdLeavesR3, &pCPUM->GuestInfo.cCpuIdLeaves,
    2447                                    UINT32_C(0xc0000000), UINT32_C(0xc00fffff));
    2448     }
     3226     * Pre-explode the CPUID info.
     3227     */
     3228    if (RT_SUCCESS(rc))
     3229        rc = cpumR3CpuIdExplodeFeatures(pCpum->GuestInfo.paCpuIdLeavesR3, pCpum->GuestInfo.cCpuIdLeaves, &pCpum->GuestFeatures);
    24493230
    24503231    /*
    2451      * Hypervisor identification.
    2452      *
    2453      * We only return minimal information, primarily ensuring that the
    2454      * 0x40000000 function returns 0x40000001 and identifying ourselves.
    2455      * Hypervisor-specific interface is supported through GIM which will
    2456      * modify these leaves if required depending on the GIM provider.
    2457      */
    2458     NewLeaf.uLeaf        = UINT32_C(0x40000000);
    2459     NewLeaf.uSubLeaf     = 0;
    2460     NewLeaf.fSubLeafMask = 0;
    2461     NewLeaf.uEax         = UINT32_C(0x40000001);
    2462     NewLeaf.uEbx         = 0x786f4256 /* 'VBox' */;
    2463     NewLeaf.uEcx         = 0x786f4256 /* 'VBox' */;
    2464     NewLeaf.uEdx         = 0x786f4256 /* 'VBox' */;
    2465     NewLeaf.fFlags       = 0;
    2466     rc = cpumR3CpuIdInsert(NULL /* pVM */, &pCPUM->GuestInfo.paCpuIdLeavesR3, &pCPUM->GuestInfo.cCpuIdLeaves, &NewLeaf);
    2467     AssertLogRelRCReturn(rc, rc);
    2468 
    2469     NewLeaf.uLeaf        = UINT32_C(0x40000001);
    2470     NewLeaf.uEax         = 0x656e6f6e;                            /* 'none' */
    2471     NewLeaf.uEbx         = 0;
    2472     NewLeaf.uEcx         = 0;
    2473     NewLeaf.uEdx         = 0;
    2474     NewLeaf.fFlags       = 0;
    2475     rc = cpumR3CpuIdInsert(NULL /* pVM */, &pCPUM->GuestInfo.paCpuIdLeavesR3, &pCPUM->GuestInfo.cCpuIdLeaves, &NewLeaf);
    2476     AssertLogRelRCReturn(rc, rc);
     3232     * Sanitize the cpuid information passed on to the guest.
     3233     */
     3234    if (RT_SUCCESS(rc))
     3235    {
     3236        rc = cpumR3CpuIdSanitize(pVM, pCpum, &Config);
     3237        if (RT_SUCCESS(rc))
     3238        {
     3239            cpumR3CpuIdLimitLeaves(pCpum, &Config);
     3240            cpumR3CpuIdLimitIntelFamModStep(pCpum, &Config);
     3241        }
     3242    }
    24773243
    24783244    /*
    2479      * Mini CPU selection support for making Mac OS X happy.
    2480      */
    2481     if (pCPUM->GuestFeatures.enmCpuVendor == CPUMCPUVENDOR_INTEL)
    2482     {
    2483         pStdFeatureLeaf = cpumR3CpuIdGetLeaf(pCPUM->GuestInfo.paCpuIdLeavesR3, pCPUM->GuestInfo.cCpuIdLeaves, 1, 0);
    2484         uint32_t uCurIntelFamilyModelStep = RT_MAKE_U32_FROM_U8(ASMGetCpuStepping(pStdFeatureLeaf->uEax),
    2485                                                                 ASMGetCpuModelIntel(pStdFeatureLeaf->uEax),
    2486                                                                 ASMGetCpuFamily(pStdFeatureLeaf->uEax),
    2487                                                                 0);
    2488         if (uMaxIntelFamilyModelStep < uCurIntelFamilyModelStep)
    2489         {
    2490             uint32_t uNew = pStdFeatureLeaf->uEax & UINT32_C(0xf0003000);
    2491             uNew |= RT_BYTE1(uMaxIntelFamilyModelStep) & 0xf; /* stepping */
    2492             uNew |= (RT_BYTE2(uMaxIntelFamilyModelStep) & 0xf) << 4; /* 4 low model bits */
    2493             uNew |= (RT_BYTE2(uMaxIntelFamilyModelStep) >> 4) << 16; /* 4 high model bits */
    2494             uNew |= (RT_BYTE3(uMaxIntelFamilyModelStep) & 0xf) << 8; /* 4 low family bits */
    2495             if (RT_BYTE3(uMaxIntelFamilyModelStep) > 0xf) /* 8 high family bits, using intel's suggested calculation. */
    2496                 uNew |= ( (RT_BYTE3(uMaxIntelFamilyModelStep) - (RT_BYTE3(uMaxIntelFamilyModelStep) & 0xf)) & 0xff ) << 20;
    2497             LogRel(("CPU: CPUID(0).EAX %#x -> %#x (uMaxIntelFamilyModelStep=%#x, uCurIntelFamilyModelStep=%#x\n",
    2498                     pStdFeatureLeaf->uEax, uNew, uMaxIntelFamilyModelStep, uCurIntelFamilyModelStep));
    2499             pStdFeatureLeaf->uEax = uNew;
    2500         }
    2501     }
     3245     * Plant our own hypervisor CPUID leaves.
     3246     */
     3247    if (RT_SUCCESS(rc))
     3248        rc = cpumR3CpuIdPlantHypervisorLeaves(pCpum, &Config);
    25023249
    25033250    /*
    25043251     * MSR fudging.
    25053252     */
    2506     /** @cfgm{/CPUM/FudgeMSRs, boolean, true}
    2507      * Fudges some common MSRs if not present in the selected CPU database entry.
    2508      * This is for trying to keep VMs running when moved between different hosts
    2509      * and different CPU vendors. */
    2510     bool fEnable;
    2511     rc = CFGMR3QueryBoolDef(pCpumCfg, "FudgeMSRs", &fEnable, true);       AssertRCReturn(rc, rc);
    2512     if (fEnable)
    2513     {
    2514         rc = cpumR3MsrApplyFudge(pVM);
    2515         AssertLogRelRCReturn(rc, rc);
     3253    if (RT_SUCCESS(rc))
     3254    {
     3255        /** @cfgm{/CPUM/FudgeMSRs, boolean, true}
     3256         * Fudges some common MSRs if not present in the selected CPU database entry.
     3257         * This is for trying to keep VMs running when moved between different hosts
     3258         * and different CPU vendors. */
     3259        bool fEnable;
     3260        rc = CFGMR3QueryBoolDef(pCpumCfg, "FudgeMSRs", &fEnable, true); AssertRC(rc);
     3261        if (RT_SUCCESS(rc) && fEnable)
     3262        {
     3263            rc = cpumR3MsrApplyFudge(pVM);
     3264            AssertLogRelRC(rc);
     3265        }
     3266    }
     3267    if (RT_SUCCESS(rc))
     3268    {
     3269        /*
     3270         * Move the MSR and CPUID arrays over on the hypervisor heap, and explode
     3271         * guest CPU features again.
     3272         */
     3273        void *pvFree = pCpum->GuestInfo.paCpuIdLeavesR3;
     3274        int rc1 = cpumR3CpuIdInstallAndExplodeLeaves(pVM, pCpum, pCpum->GuestInfo.paCpuIdLeavesR3,
     3275                                                     pCpum->GuestInfo.cCpuIdLeaves);
     3276        RTMemFree(pvFree);
     3277
     3278        pvFree = pCpum->GuestInfo.paMsrRangesR3;
     3279        int rc2 = MMHyperDupMem(pVM, pvFree,
     3280                                sizeof(pCpum->GuestInfo.paMsrRangesR3[0]) * pCpum->GuestInfo.cMsrRanges, 32,
     3281                                MM_TAG_CPUM_MSRS, (void **)&pCpum->GuestInfo.paMsrRangesR3);
     3282        RTMemFree(pvFree);
     3283        AssertLogRelRCReturn(rc1, rc1);
     3284        AssertLogRelRCReturn(rc2, rc2);
     3285
     3286        pCpum->GuestInfo.paMsrRangesR0 = MMHyperR3ToR0(pVM, pCpum->GuestInfo.paMsrRangesR3);
     3287        pCpum->GuestInfo.paMsrRangesRC = MMHyperR3ToRC(pVM, pCpum->GuestInfo.paMsrRangesR3);
     3288        cpumR3MsrRegStats(pVM);
     3289
     3290
     3291        /*
     3292         * Some more configuration that we're applying at the end of everything
     3293         * via the CPUMSetGuestCpuIdFeature API.
     3294         */
     3295
     3296        /* Check if PAE was explicitely enabled by the user. */
     3297        bool fEnable;
     3298        rc = CFGMR3QueryBoolDef(CFGMR3GetRoot(pVM), "EnablePAE", &fEnable, false);
     3299        AssertRCReturn(rc, rc);
     3300        if (fEnable)
     3301            CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_PAE);
     3302
     3303        /* We don't normally enable NX for raw-mode, so give the user a chance to force it on. */
     3304        rc = CFGMR3QueryBoolDef(pCpumCfg, "EnableNX", &fEnable, false);
     3305        AssertRCReturn(rc, rc);
     3306        if (fEnable)
     3307            CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_NX);
     3308
     3309        /* We don't enable the Hypervisor Present bit by default, but it may be needed by some guests. */
     3310        rc = CFGMR3QueryBoolDef(pCpumCfg, "EnableHVP", &fEnable, false);
     3311        AssertRCReturn(rc, rc);
     3312        if (fEnable)
     3313            CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_HVP);
     3314
     3315        return VINF_SUCCESS;
    25163316    }
    25173317
    25183318    /*
    2519      * Move the MSR and CPUID arrays over on the hypervisor heap, and explode
    2520      * guest CPU features again.
    2521      */
    2522     void *pvFree = pCPUM->GuestInfo.paCpuIdLeavesR3;
    2523     int rc1 = cpumR3CpuIdInstallAndExplodeLeaves(pVM, pCPUM, pCPUM->GuestInfo.paCpuIdLeavesR3, pCPUM->GuestInfo.cCpuIdLeaves);
    2524     RTMemFree(pvFree);
    2525 
    2526     pvFree = pCPUM->GuestInfo.paMsrRangesR3;
    2527     int rc2 = MMHyperDupMem(pVM, pvFree,
    2528                             sizeof(pCPUM->GuestInfo.paMsrRangesR3[0]) * pCPUM->GuestInfo.cMsrRanges, 32,
    2529                             MM_TAG_CPUM_MSRS, (void **)&pCPUM->GuestInfo.paMsrRangesR3);
    2530     RTMemFree(pvFree);
    2531     AssertLogRelRCReturn(rc1, rc1);
    2532     AssertLogRelRCReturn(rc2, rc2);
    2533 
    2534     pCPUM->GuestInfo.paMsrRangesR0 = MMHyperR3ToR0(pVM, pCPUM->GuestInfo.paMsrRangesR3);
    2535     pCPUM->GuestInfo.paMsrRangesRC = MMHyperR3ToRC(pVM, pCPUM->GuestInfo.paMsrRangesR3);
    2536     cpumR3MsrRegStats(pVM);
    2537 
    2538     /*
    2539      * Some more configuration that we're applying at the end of everything
    2540      * via the CPUMSetGuestCpuIdFeature API.
    2541      */
    2542 
    2543     /* Check if PAE was explicitely enabled by the user. */
    2544     rc = CFGMR3QueryBoolDef(CFGMR3GetRoot(pVM), "EnablePAE", &fEnable, false);      AssertRCReturn(rc, rc);
    2545     if (fEnable)
    2546         CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_PAE);
    2547 
    2548     /* We don't normally enable NX for raw-mode, so give the user a chance to force it on. */
    2549     rc = CFGMR3QueryBoolDef(pCpumCfg, "EnableNX", &fEnable, false);                 AssertRCReturn(rc, rc);
    2550     if (fEnable)
    2551         CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_NX);
    2552 
    2553     /* We don't enable the Hypervisor Present bit by default, but it may be needed by some guests. */
    2554     rc = CFGMR3QueryBoolDef(pCpumCfg, "EnableHVP", &fEnable, false);                AssertRCReturn(rc, rc);
    2555     if (fEnable)
    2556         CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_HVP);
    2557 
    2558 #undef PORTABLE_DISABLE_FEATURE_BIT
    2559 #undef PORTABLE_CLEAR_BITS_WHEN
    2560 
    2561     return VINF_SUCCESS;
     3319     * Failed before switching to hyper heap.
     3320     */
     3321    RTMemFree(pCpum->GuestInfo.paCpuIdLeavesR3);
     3322    pCpum->GuestInfo.paCpuIdLeavesR3 = NULL;
     3323    RTMemFree(pCpum->GuestInfo.paMsrRangesR3);
     3324    pCpum->GuestInfo.paMsrRangesR3 = NULL;
     3325    return rc;
    25623326}
    25633327
     
    25833347{
    25843348    /*
    2585      * Save all the CPU ID leaves here so we can check them for compatibility
    2586      * upon loading.
    2587      */
    2588     SSMR3PutU32(pSSM, RT_ELEMENTS(pVM->cpum.s.aGuestCpuIdPatmStd));
    2589     SSMR3PutMem(pSSM, &pVM->cpum.s.aGuestCpuIdPatmStd[0], sizeof(pVM->cpum.s.aGuestCpuIdPatmStd));
    2590 
    2591     SSMR3PutU32(pSSM, RT_ELEMENTS(pVM->cpum.s.aGuestCpuIdPatmExt));
    2592     SSMR3PutMem(pSSM, &pVM->cpum.s.aGuestCpuIdPatmExt[0], sizeof(pVM->cpum.s.aGuestCpuIdPatmExt));
    2593 
    2594     SSMR3PutU32(pSSM, RT_ELEMENTS(pVM->cpum.s.aGuestCpuIdPatmCentaur));
    2595     SSMR3PutMem(pSSM, &pVM->cpum.s.aGuestCpuIdPatmCentaur[0], sizeof(pVM->cpum.s.aGuestCpuIdPatmCentaur));
    2596 
    2597     SSMR3PutMem(pSSM, &pVM->cpum.s.GuestCpuIdPatmDef, sizeof(pVM->cpum.s.GuestCpuIdPatmDef));
     3349     * Save all the CPU ID leaves.
     3350     */
     3351    SSMR3PutU32(pSSM, sizeof(pVM->cpum.s.GuestInfo.paCpuIdLeavesR3[0]));
     3352    SSMR3PutU32(pSSM, pVM->cpum.s.GuestInfo.cCpuIdLeaves);
     3353    SSMR3PutMem(pSSM, pVM->cpum.s.GuestInfo.paCpuIdLeavesR3,
     3354                sizeof(pVM->cpum.s.GuestInfo.paCpuIdLeavesR3[0]) * pVM->cpum.s.GuestInfo.cCpuIdLeaves);
     3355
     3356    SSMR3PutMem(pSSM, &pVM->cpum.s.GuestInfo.DefCpuId, sizeof(pVM->cpum.s.GuestInfo.DefCpuId));
    25983357
    25993358    /*
     
    26153374
    26163375
    2617 static int cpumR3LoadCpuIdOneGuestArray(PSSMHANDLE pSSM, uint32_t uBase, PCPUMCPUIDLEAF *ppaLeaves, uint32_t *pcLeaves)
     3376static int cpumR3LoadOneOldGuestCpuIdArray(PSSMHANDLE pSSM, uint32_t uBase, PCPUMCPUIDLEAF *ppaLeaves, uint32_t *pcLeaves)
    26183377{
    26193378    uint32_t cCpuIds;
     
    26553414
    26563415
    2657 static int cpumR3LoadCpuIdGuestArrays(PSSMHANDLE pSSM, uint32_t uVersion, PCPUMCPUIDLEAF *ppaLeaves, uint32_t *pcLeaves)
     3416static int cpumR3LoadGuestCpuIdArray(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, PCPUMCPUIDLEAF *ppaLeaves, uint32_t *pcLeaves)
    26583417{
    26593418    *ppaLeaves = NULL;
    26603419    *pcLeaves = 0;
    26613420
    2662     int rc = cpumR3LoadCpuIdOneGuestArray(pSSM, UINT32_C(0x00000000), ppaLeaves, pcLeaves);
    2663     if (RT_SUCCESS(rc))
    2664         rc = cpumR3LoadCpuIdOneGuestArray(pSSM, UINT32_C(0x80000000), ppaLeaves, pcLeaves);
    2665     if (RT_SUCCESS(rc))
    2666         rc = cpumR3LoadCpuIdOneGuestArray(pSSM, UINT32_C(0xc0000000), ppaLeaves, pcLeaves);
    2667 
     3421    int rc;
     3422    if (uVersion > CPUM_SAVED_STATE_VERSION_PUT_STRUCT)
     3423    {
     3424        /*
     3425         * The new format. Starts by declaring the leave size and count.
     3426         */
     3427        uint32_t cbLeaf;
     3428        SSMR3GetU32(pSSM, &cbLeaf);
     3429        uint32_t cLeaves;
     3430        rc = SSMR3GetU32(pSSM, &cLeaves);
     3431        if (RT_SUCCESS(rc))
     3432        {
     3433            if (cbLeaf == sizeof(**ppaLeaves))
     3434            {
     3435                if (cLeaves <= CPUM_CPUID_MAX_LEAVES)
     3436                {
     3437                    /*
     3438                     * Load the leaves one by one.
     3439                     */
     3440                    for (uint32_t i = 0; i < cLeaves && RT_SUCCESS(rc); i++)
     3441                    {
     3442                        CPUMCPUIDLEAF Leaf;
     3443                        rc = SSMR3GetMem(pSSM, &Leaf, sizeof(Leaf));
     3444                        if (RT_SUCCESS(rc))
     3445                            rc = cpumR3CpuIdInsert(NULL /* pVM */, ppaLeaves, pcLeaves, &Leaf);
     3446                    }
     3447                }
     3448                else
     3449                    rc = SSMR3SetLoadError(pSSM, VERR_TOO_MANY_CPUID_LEAVES, RT_SRC_POS,
     3450                                           "Too many CPUID leaves: %#x, max %#x", cLeaves, CPUM_CPUID_MAX_LEAVES);
     3451            }
     3452            else
     3453                rc = SSMR3SetLoadError(pSSM, VERR_SSM_DATA_UNIT_FORMAT_CHANGED, RT_SRC_POS,
     3454                                       "CPUMCPUIDLEAF size differs: saved=%#x, our=%#x", cbLeaf, sizeof(**ppaLeaves));
     3455        }
     3456    }
     3457    else
     3458    {
     3459        /*
     3460         * The old format with its three inflexible arrays.
     3461         */
     3462        rc = cpumR3LoadOneOldGuestCpuIdArray(pSSM, UINT32_C(0x00000000), ppaLeaves, pcLeaves);
     3463        if (RT_SUCCESS(rc))
     3464            rc = cpumR3LoadOneOldGuestCpuIdArray(pSSM, UINT32_C(0x80000000), ppaLeaves, pcLeaves);
     3465        if (RT_SUCCESS(rc))
     3466            rc = cpumR3LoadOneOldGuestCpuIdArray(pSSM, UINT32_C(0xc0000000), ppaLeaves, pcLeaves);
     3467        if (RT_SUCCESS(rc))
     3468        {
     3469            /*
     3470             * Fake up leaf 4 on intel like we used to do in CPUMGetGuestCpuId earlier.
     3471             */
     3472            PCPUMCPUIDLEAF pLeaf = cpumR3CpuIdGetLeaf(*ppaLeaves, *pcLeaves, 0, 0);
     3473            if (   pLeaf
     3474                && ASMIsIntelCpuEx(pLeaf->uEbx, pLeaf->uEcx, pLeaf->uEdx))
     3475            {
     3476                CPUMCPUIDLEAF Leaf;
     3477                Leaf.uLeaf        = 4;
     3478                Leaf.fSubLeafMask = UINT32_MAX;
     3479                Leaf.uSubLeaf     = 0;
     3480                Leaf.uEdx = UINT32_C(0);          /* 3 flags, 0 is fine. */
     3481                Leaf.uEcx = UINT32_C(63);         /* sets - 1 */
     3482                Leaf.uEbx = (UINT32_C(7) << 22)   /* associativity -1 */
     3483                          | (UINT32_C(0) << 12)   /* phys line partitions - 1 */
     3484                          | UINT32_C(63);         /* system coherency line size - 1 */
     3485                Leaf.uEax = (RT_MIN(pVM->cCpus - 1, UINT32_C(0x3f)) << 26)  /* cores per package - 1 */
     3486                          | (UINT32_C(0) << 14)   /* threads per cache - 1 */
     3487                          | (UINT32_C(1) << 5)    /* cache level */
     3488                          | UINT32_C(1);          /* cache type (data) */
     3489                rc = cpumR3CpuIdInsert(NULL /* pVM */, ppaLeaves, pcLeaves, &Leaf);
     3490                if (RT_SUCCESS(rc))
     3491                {
     3492                    Leaf.uSubLeaf = 1; /* Should've been cache type 2 (code), but buggy code made it data. */
     3493                    rc = cpumR3CpuIdInsert(NULL /* pVM */, ppaLeaves, pcLeaves, &Leaf);
     3494                }
     3495                if (RT_SUCCESS(rc))
     3496                {
     3497                    Leaf.uSubLeaf = 2; /* Should've been cache type 3 (unified), but buggy code made it data. */
     3498                    Leaf.uEcx = 4095;                   /* sets - 1 */
     3499                    Leaf.uEbx &= UINT32_C(0x003fffff);  /* associativity - 1 */
     3500                    Leaf.uEbx |= UINT32_C(23) << 22;
     3501                    Leaf.uEax &= UINT32_C(0xfc003fff);  /* threads per cache - 1 */
     3502                    Leaf.uEax |= RT_MIN(pVM->cCpus - 1, UINT32_C(0xfff)) << 14;
     3503                    Leaf.uEax &= UINT32_C(0xffffff1f);  /* level */
     3504                    Leaf.uEax |= UINT32_C(2) << 5;
     3505                    rc = cpumR3CpuIdInsert(NULL /* pVM */, ppaLeaves, pcLeaves, &Leaf);
     3506                }
     3507            }
     3508        }
     3509    }
    26683510    return rc;
    26693511}
     
    26713513
    26723514/**
    2673  * Loads the CPU ID leaves saved by pass 0.
     3515 * Loads the CPU ID leaves saved by pass 0, inner worker.
    26743516 *
    26753517 * @returns VBox status code.
     
    26773519 * @param   pSSM                The saved state handle.
    26783520 * @param   uVersion            The format version.
    2679  */
    2680 int cpumR3LoadCpuId(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion)
     3521 * @param   paLeaves            Guest CPUID leaves loaded from the state.
     3522 * @param   cLeaves             The number of leaves in @a paLeaves.
     3523 */
     3524int cpumR3LoadCpuIdInner(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, PCPUMCPUIDLEAF paLeaves, uint32_t cLeaves)
    26813525{
    26823526    AssertMsgReturn(uVersion >= CPUM_SAVED_STATE_VERSION_VER3_2, ("%u\n", uVersion), VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION);
    26833527
    26843528    /*
    2685      * Define a bunch of macros for simplifying the code.
     3529     * Continue loading the state into stack buffers.
     3530     */
     3531    CPUMCPUID   GuestDefCpuId;
     3532    int rc = SSMR3GetMem(pSSM, &GuestDefCpuId, sizeof(GuestDefCpuId));
     3533    AssertRCReturn(rc, rc);
     3534
     3535    CPUMCPUID   aRawStd[16];
     3536    uint32_t    cRawStd;
     3537    rc = SSMR3GetU32(pSSM, &cRawStd); AssertRCReturn(rc, rc);
     3538    if (cRawStd > RT_ELEMENTS(aRawStd))
     3539        return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
     3540    rc = SSMR3GetMem(pSSM, &aRawStd[0], cRawStd * sizeof(aRawStd[0]));
     3541    AssertRCReturn(rc, rc);
     3542    for (uint32_t i = cRawStd; i < RT_ELEMENTS(aRawStd); i++)
     3543        ASMCpuIdExSlow(i, 0, 0, 0, &aRawStd[i].uEax, &aRawStd[i].uEbx, &aRawStd[i].uEcx, &aRawStd[i].uEdx);
     3544
     3545    CPUMCPUID   aRawExt[32];
     3546    uint32_t    cRawExt;
     3547    rc = SSMR3GetU32(pSSM, &cRawExt); AssertRCReturn(rc, rc);
     3548    if (cRawExt > RT_ELEMENTS(aRawExt))
     3549        return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
     3550    rc = SSMR3GetMem(pSSM, &aRawExt[0], cRawExt * sizeof(aRawExt[0]));
     3551    AssertRCReturn(rc, rc);
     3552    for (uint32_t i = cRawExt; i < RT_ELEMENTS(aRawExt); i++)
     3553        ASMCpuIdExSlow(i | UINT32_C(0x80000000), 0, 0, 0, &aRawExt[i].uEax, &aRawExt[i].uEbx, &aRawExt[i].uEcx, &aRawExt[i].uEdx);
     3554
     3555    /*
     3556     * Get the raw CPU IDs for the current host.
     3557     */
     3558    CPUMCPUID   aHostRawStd[16];
     3559    for (unsigned i = 0; i < RT_ELEMENTS(aHostRawStd); i++)
     3560        ASMCpuIdExSlow(i, 0, 0, 0, &aHostRawStd[i].uEax, &aHostRawStd[i].uEbx, &aHostRawStd[i].uEcx, &aHostRawStd[i].uEdx);
     3561
     3562    CPUMCPUID   aHostRawExt[32];
     3563    for (unsigned i = 0; i < RT_ELEMENTS(aHostRawExt); i++)
     3564        ASMCpuIdExSlow(i | UINT32_C(0x80000000), 0, 0, 0,
     3565                       &aHostRawExt[i].uEax, &aHostRawExt[i].uEbx, &aHostRawExt[i].uEcx, &aHostRawExt[i].uEdx);
     3566
     3567    /*
     3568     * Get the host and guest overrides so we don't reject the state because
     3569     * some feature was enabled thru these interfaces.
     3570     * Note! We currently only need the feature leaves, so skip rest.
     3571     */
     3572    PCFGMNODE   pOverrideCfg = CFGMR3GetChild(CFGMR3GetRoot(pVM), "CPUM/HostCPUID");
     3573    CPUMCPUID   aHostOverrideStd[2];
     3574    memcpy(&aHostOverrideStd[0], &aHostRawStd[0], sizeof(aHostOverrideStd));
     3575    cpumR3CpuIdInitLoadOverrideSet(UINT32_C(0x00000000), &aHostOverrideStd[0], RT_ELEMENTS(aHostOverrideStd), pOverrideCfg);
     3576
     3577    CPUMCPUID   aHostOverrideExt[2];
     3578    memcpy(&aHostOverrideExt[0], &aHostRawExt[0], sizeof(aHostOverrideExt));
     3579    cpumR3CpuIdInitLoadOverrideSet(UINT32_C(0x80000000), &aHostOverrideExt[0], RT_ELEMENTS(aHostOverrideExt), pOverrideCfg);
     3580
     3581    /*
     3582     * This can be skipped.
     3583     */
     3584    bool fStrictCpuIdChecks;
     3585    CFGMR3QueryBoolDef(CFGMR3GetChild(CFGMR3GetRoot(pVM), "CPUM"), "StrictCpuIdChecks", &fStrictCpuIdChecks, true);
     3586
     3587    /*
     3588     * Define a bunch of macros for simplifying the santizing/checking code below.
    26863589     */
    26873590    /* Generic expression + failure message. */
     
    28523755
    28533756    /*
    2854      * Load them into stack buffers first.
    2855      */
    2856     PCPUMCPUIDLEAF paLeaves;
    2857     uint32_t       cLeaves;
    2858     int rc = cpumR3LoadCpuIdGuestArrays(pSSM, uVersion, &paLeaves, &cLeaves);
    2859     AssertRCReturn(rc, rc);
    2860 
    2861     /** @todo we'll be leaking paLeaves on error return... */
    2862 
    2863     CPUMCPUID   GuestCpuIdPatmDef;
    2864     rc = SSMR3GetMem(pSSM, &GuestCpuIdPatmDef, sizeof(GuestCpuIdPatmDef));
    2865     AssertRCReturn(rc, rc);
    2866 
    2867     CPUMCPUID   aRawStd[16];
    2868     uint32_t    cRawStd;
    2869     rc = SSMR3GetU32(pSSM, &cRawStd); AssertRCReturn(rc, rc);
    2870     if (cRawStd > RT_ELEMENTS(aRawStd))
    2871         return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
    2872     rc = SSMR3GetMem(pSSM, &aRawStd[0], cRawStd * sizeof(aRawStd[0]));
    2873     AssertRCReturn(rc, rc);
    2874     for (uint32_t i = cRawStd; i < RT_ELEMENTS(aRawStd); i++)
    2875         ASMCpuIdExSlow(i, 0, 0, 0, &aRawStd[i].uEax, &aRawStd[i].uEbx, &aRawStd[i].uEcx, &aRawStd[i].uEdx);
    2876 
    2877     CPUMCPUID   aRawExt[32];
    2878     uint32_t    cRawExt;
    2879     rc = SSMR3GetU32(pSSM, &cRawExt); AssertRCReturn(rc, rc);
    2880     if (cRawExt > RT_ELEMENTS(aRawExt))
    2881         return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
    2882     rc = SSMR3GetMem(pSSM, &aRawExt[0], cRawExt * sizeof(aRawExt[0]));
    2883     AssertRCReturn(rc, rc);
    2884     for (uint32_t i = cRawExt; i < RT_ELEMENTS(aRawExt); i++)
    2885         ASMCpuIdExSlow(i | UINT32_C(0x80000000), 0, 0, 0, &aRawExt[i].uEax, &aRawExt[i].uEbx, &aRawExt[i].uEcx, &aRawExt[i].uEdx);
    2886 
    2887     /*
    2888      * Get the raw CPU IDs for the current host.
    2889      */
    2890     CPUMCPUID   aHostRawStd[16];
    2891     for (unsigned i = 0; i < RT_ELEMENTS(aHostRawStd); i++)
    2892         ASMCpuIdExSlow(i, 0, 0, 0, &aHostRawStd[i].uEax, &aHostRawStd[i].uEbx, &aHostRawStd[i].uEcx, &aHostRawStd[i].uEdx);
    2893 
    2894     CPUMCPUID   aHostRawExt[32];
    2895     for (unsigned i = 0; i < RT_ELEMENTS(aHostRawExt); i++)
    2896         ASMCpuIdExSlow(i | UINT32_C(0x80000000), 0, 0, 0,
    2897                        &aHostRawExt[i].uEax, &aHostRawExt[i].uEbx, &aHostRawExt[i].uEcx, &aHostRawExt[i].uEdx);
    2898 
    2899     /*
    2900      * Get the host and guest overrides so we don't reject the state because
    2901      * some feature was enabled thru these interfaces.
    2902      * Note! We currently only need the feature leaves, so skip rest.
    2903      */
    2904     PCFGMNODE   pOverrideCfg = CFGMR3GetChild(CFGMR3GetRoot(pVM), "CPUM/HostCPUID");
    2905     CPUMCPUID   aHostOverrideStd[2];
    2906     memcpy(&aHostOverrideStd[0], &aHostRawStd[0], sizeof(aHostOverrideStd));
    2907     cpumR3CpuIdInitLoadOverrideSet(UINT32_C(0x00000000), &aHostOverrideStd[0], RT_ELEMENTS(aHostOverrideStd), pOverrideCfg);
    2908 
    2909     CPUMCPUID   aHostOverrideExt[2];
    2910     memcpy(&aHostOverrideExt[0], &aHostRawExt[0], sizeof(aHostOverrideExt));
    2911     cpumR3CpuIdInitLoadOverrideSet(UINT32_C(0x80000000), &aHostOverrideExt[0], RT_ELEMENTS(aHostOverrideExt), pOverrideCfg);
    2912 
    2913     /*
    2914      * This can be skipped.
    2915      */
    2916     bool fStrictCpuIdChecks;
    2917     CFGMR3QueryBoolDef(CFGMR3GetChild(CFGMR3GetRoot(pVM), "CPUM"), "StrictCpuIdChecks", &fStrictCpuIdChecks, true);
    2918 
    2919 
    2920 
    2921     /*
    29223757     * For raw-mode we'll require that the CPUs are very similar since we don't
    29233758     * intercept CPUID instructions for user mode applications.
     
    33034138    }
    33044139
    3305     /*
    3306      * We're good, commit the CPU ID leaves.
    3307      */
    3308     MMHyperFree(pVM, pVM->cpum.s.GuestInfo.paCpuIdLeavesR3);
    3309     pVM->cpum.s.GuestInfo.paCpuIdLeavesR0 = NIL_RTR0PTR;
    3310     pVM->cpum.s.GuestInfo.paCpuIdLeavesRC = NIL_RTRCPTR;
    3311     pVM->cpum.s.GuestInfo.DefCpuId = GuestCpuIdPatmDef;
    3312     rc = cpumR3CpuIdInstallAndExplodeLeaves(pVM, &pVM->cpum.s, paLeaves, cLeaves);
    3313     RTMemFree(paLeaves);
    3314     AssertLogRelRCReturn(rc, rc);
    3315 
    3316 
    33174140#undef CPUID_CHECK_RET
    33184141#undef CPUID_CHECK_WRN
     
    33354158#undef CPUID_GST_AMD_FEATURE_IGN
    33364159
     4160    /*
     4161     * We're good, commit the CPU ID leaves.
     4162     */
     4163    MMHyperFree(pVM, pVM->cpum.s.GuestInfo.paCpuIdLeavesR3);
     4164    pVM->cpum.s.GuestInfo.paCpuIdLeavesR3 = NULL;
     4165    pVM->cpum.s.GuestInfo.paCpuIdLeavesR0 = NIL_RTR0PTR;
     4166    pVM->cpum.s.GuestInfo.paCpuIdLeavesRC = NIL_RTRCPTR;
     4167    pVM->cpum.s.GuestInfo.DefCpuId = GuestDefCpuId;
     4168    rc = cpumR3CpuIdInstallAndExplodeLeaves(pVM, &pVM->cpum.s, paLeaves, cLeaves);
     4169    AssertLogRelRCReturn(rc, rc);
     4170
    33374171    return VINF_SUCCESS;
    33384172}
    33394173
     4174
     4175/**
     4176 * Loads the CPU ID leaves saved by pass 0.
     4177 *
     4178 * @returns VBox status code.
     4179 * @param   pVM                 Pointer to the VM.
     4180 * @param   pSSM                The saved state handle.
     4181 * @param   uVersion            The format version.
     4182 */
     4183int cpumR3LoadCpuId(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion)
     4184{
     4185    AssertMsgReturn(uVersion >= CPUM_SAVED_STATE_VERSION_VER3_2, ("%u\n", uVersion), VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION);
     4186
     4187    /*
     4188     * Load the CPUID leaves array first and call worker to do the rest, just so
     4189     * we can free the memory when we need to without ending up in column 1000.
     4190     */
     4191    PCPUMCPUIDLEAF paLeaves;
     4192    uint32_t       cLeaves;
     4193    int rc = cpumR3LoadGuestCpuIdArray(pVM, pSSM, uVersion, &paLeaves, &cLeaves);
     4194    AssertRC(rc);
     4195    if (RT_SUCCESS(rc))
     4196    {
     4197        rc = cpumR3LoadCpuIdInner(pVM, pSSM, uVersion, paLeaves, cLeaves);
     4198        RTMemFree(paLeaves);
     4199    }
     4200    return rc;
     4201}
     4202
     4203
     4204
     4205
     4206/*
     4207 *
     4208 *
     4209 * CPUID Info Handler.
     4210 * CPUID Info Handler.
     4211 * CPUID Info Handler.
     4212 *
     4213 *
     4214 */
     4215
     4216
     4217
     4218/**
     4219 * Get L1 cache / TLS associativity.
     4220 */
     4221static const char *getCacheAss(unsigned u, char *pszBuf)
     4222{
     4223    if (u == 0)
     4224        return "res0  ";
     4225    if (u == 1)
     4226        return "direct";
     4227    if (u == 255)
     4228        return "fully";
     4229    if (u >= 256)
     4230        return "???";
     4231
     4232    RTStrPrintf(pszBuf, 16, "%d way", u);
     4233    return pszBuf;
     4234}
     4235
     4236
     4237/**
     4238 * Get L2 cache associativity.
     4239 */
     4240const char *getL2CacheAss(unsigned u)
     4241{
     4242    switch (u)
     4243    {
     4244        case 0:  return "off   ";
     4245        case 1:  return "direct";
     4246        case 2:  return "2 way ";
     4247        case 3:  return "res3  ";
     4248        case 4:  return "4 way ";
     4249        case 5:  return "res5  ";
     4250        case 6:  return "8 way ";
     4251        case 7:  return "res7  ";
     4252        case 8:  return "16 way";
     4253        case 9:  return "res9  ";
     4254        case 10: return "res10 ";
     4255        case 11: return "res11 ";
     4256        case 12: return "res12 ";
     4257        case 13: return "res13 ";
     4258        case 14: return "res14 ";
     4259        case 15: return "fully ";
     4260        default: return "????";
     4261    }
     4262}
     4263
     4264
     4265/**
     4266 * Display the guest CpuId leaves.
     4267 *
     4268 * @param   pVM         Pointer to the VM.
     4269 * @param   pHlp        The info helper functions.
     4270 * @param   pszArgs     "terse", "default" or "verbose".
     4271 */
     4272DECLCALLBACK(void) cpumR3CpuIdInfo(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs)
     4273{
     4274    /*
     4275     * Parse the argument.
     4276     */
     4277    unsigned iVerbosity = 1;
     4278    if (pszArgs)
     4279    {
     4280        pszArgs = RTStrStripL(pszArgs);
     4281        if (!strcmp(pszArgs, "terse"))
     4282            iVerbosity--;
     4283        else if (!strcmp(pszArgs, "verbose"))
     4284            iVerbosity++;
     4285    }
     4286
     4287    /*
     4288     * Start cracking.
     4289     */
     4290    CPUMCPUID   Host;
     4291    CPUMCPUID   Guest;
     4292    unsigned    cStdMax = pVM->cpum.s.aGuestCpuIdPatmStd[0].uEax;
     4293
     4294    uint32_t    cStdHstMax;
     4295    uint32_t    dummy;
     4296    ASMCpuIdExSlow(0, 0, 0, 0, &cStdHstMax, &dummy, &dummy, &dummy);
     4297
     4298    unsigned    cStdLstMax = RT_MAX(RT_ELEMENTS(pVM->cpum.s.aGuestCpuIdPatmStd), cStdHstMax);
     4299
     4300    pHlp->pfnPrintf(pHlp,
     4301                    "         RAW Standard CPUIDs\n"
     4302                    "     Function  eax      ebx      ecx      edx\n");
     4303    for (unsigned i = 0; i <= cStdLstMax ; i++)
     4304    {
     4305        if (i < RT_ELEMENTS(pVM->cpum.s.aGuestCpuIdPatmStd))
     4306        {
     4307            Guest = pVM->cpum.s.aGuestCpuIdPatmStd[i];
     4308            ASMCpuIdExSlow(i, 0, 0, 0, &Host.uEax, &Host.uEbx, &Host.uEcx, &Host.uEdx);
     4309
     4310            pHlp->pfnPrintf(pHlp,
     4311                            "Gst: %08x  %08x %08x %08x %08x%s\n"
     4312                            "Hst:           %08x %08x %08x %08x\n",
     4313                            i, Guest.uEax, Guest.uEbx, Guest.uEcx, Guest.uEdx,
     4314                            i <= cStdMax ? "" : "*",
     4315                            Host.uEax, Host.uEbx, Host.uEcx, Host.uEdx);
     4316        }
     4317        else
     4318        {
     4319            ASMCpuIdExSlow(i, 0, 0, 0, &Host.uEax, &Host.uEbx, &Host.uEcx, &Host.uEdx);
     4320
     4321            pHlp->pfnPrintf(pHlp,
     4322                            "Hst: %08x  %08x %08x %08x %08x\n",
     4323                            i, Host.uEax, Host.uEbx, Host.uEcx, Host.uEdx);
     4324        }
     4325    }
     4326
     4327    /*
     4328     * If verbose, decode it.
     4329     */
     4330    if (iVerbosity)
     4331    {
     4332        Guest = pVM->cpum.s.aGuestCpuIdPatmStd[0];
     4333        pHlp->pfnPrintf(pHlp,
     4334                        "Name:                            %.04s%.04s%.04s\n"
     4335                        "Supports:                        0-%x\n",
     4336                        &Guest.uEbx, &Guest.uEdx, &Guest.uEcx, Guest.uEax);
     4337    }
     4338
     4339    /*
     4340     * Get Features.
     4341     */
     4342    bool const fIntel = ASMIsIntelCpuEx(pVM->cpum.s.aGuestCpuIdPatmStd[0].uEbx,
     4343                                        pVM->cpum.s.aGuestCpuIdPatmStd[0].uEcx,
     4344                                        pVM->cpum.s.aGuestCpuIdPatmStd[0].uEdx);
     4345    if (cStdMax >= 1 && iVerbosity)
     4346    {
     4347        static const char * const s_apszTypes[4] = { "primary", "overdrive", "MP", "reserved" };
     4348
     4349        Guest = pVM->cpum.s.aGuestCpuIdPatmStd[1];
     4350        uint32_t uEAX = Guest.uEax;
     4351
     4352        pHlp->pfnPrintf(pHlp,
     4353                        "Family:                          %d  \tExtended: %d \tEffective: %d\n"
     4354                        "Model:                           %d  \tExtended: %d \tEffective: %d\n"
     4355                        "Stepping:                        %d\n"
     4356                        "Type:                            %d (%s)\n"
     4357                        "APIC ID:                         %#04x\n"
     4358                        "Logical CPUs:                    %d\n"
     4359                        "CLFLUSH Size:                    %d\n"
     4360                        "Brand ID:                        %#04x\n",
     4361                        (uEAX >> 8) & 0xf, (uEAX >> 20) & 0x7f, ASMGetCpuFamily(uEAX),
     4362                        (uEAX >> 4) & 0xf, (uEAX >> 16) & 0x0f, ASMGetCpuModel(uEAX, fIntel),
     4363                        ASMGetCpuStepping(uEAX),
     4364                        (uEAX >> 12) & 3, s_apszTypes[(uEAX >> 12) & 3],
     4365                        (Guest.uEbx >> 24) & 0xff,
     4366                        (Guest.uEbx >> 16) & 0xff,
     4367                        (Guest.uEbx >>  8) & 0xff,
     4368                        (Guest.uEbx >>  0) & 0xff);
     4369        if (iVerbosity == 1)
     4370        {
     4371            uint32_t uEDX = Guest.uEdx;
     4372            pHlp->pfnPrintf(pHlp, "Features EDX:                   ");
     4373            if (uEDX & RT_BIT(0))   pHlp->pfnPrintf(pHlp, " FPU");
     4374            if (uEDX & RT_BIT(1))   pHlp->pfnPrintf(pHlp, " VME");
     4375            if (uEDX & RT_BIT(2))   pHlp->pfnPrintf(pHlp, " DE");
     4376            if (uEDX & RT_BIT(3))   pHlp->pfnPrintf(pHlp, " PSE");
     4377            if (uEDX & RT_BIT(4))   pHlp->pfnPrintf(pHlp, " TSC");
     4378            if (uEDX & RT_BIT(5))   pHlp->pfnPrintf(pHlp, " MSR");
     4379            if (uEDX & RT_BIT(6))   pHlp->pfnPrintf(pHlp, " PAE");
     4380            if (uEDX & RT_BIT(7))   pHlp->pfnPrintf(pHlp, " MCE");
     4381            if (uEDX & RT_BIT(8))   pHlp->pfnPrintf(pHlp, " CX8");
     4382            if (uEDX & RT_BIT(9))   pHlp->pfnPrintf(pHlp, " APIC");
     4383            if (uEDX & RT_BIT(10))  pHlp->pfnPrintf(pHlp, " 10");
     4384            if (uEDX & RT_BIT(11))  pHlp->pfnPrintf(pHlp, " SEP");
     4385            if (uEDX & RT_BIT(12))  pHlp->pfnPrintf(pHlp, " MTRR");
     4386            if (uEDX & RT_BIT(13))  pHlp->pfnPrintf(pHlp, " PGE");
     4387            if (uEDX & RT_BIT(14))  pHlp->pfnPrintf(pHlp, " MCA");
     4388            if (uEDX & RT_BIT(15))  pHlp->pfnPrintf(pHlp, " CMOV");
     4389            if (uEDX & RT_BIT(16))  pHlp->pfnPrintf(pHlp, " PAT");
     4390            if (uEDX & RT_BIT(17))  pHlp->pfnPrintf(pHlp, " PSE36");
     4391            if (uEDX & RT_BIT(18))  pHlp->pfnPrintf(pHlp, " PSN");
     4392            if (uEDX & RT_BIT(19))  pHlp->pfnPrintf(pHlp, " CLFSH");
     4393            if (uEDX & RT_BIT(20))  pHlp->pfnPrintf(pHlp, " 20");
     4394            if (uEDX & RT_BIT(21))  pHlp->pfnPrintf(pHlp, " DS");
     4395            if (uEDX & RT_BIT(22))  pHlp->pfnPrintf(pHlp, " ACPI");
     4396            if (uEDX & RT_BIT(23))  pHlp->pfnPrintf(pHlp, " MMX");
     4397            if (uEDX & RT_BIT(24))  pHlp->pfnPrintf(pHlp, " FXSR");
     4398            if (uEDX & RT_BIT(25))  pHlp->pfnPrintf(pHlp, " SSE");
     4399            if (uEDX & RT_BIT(26))  pHlp->pfnPrintf(pHlp, " SSE2");
     4400            if (uEDX & RT_BIT(27))  pHlp->pfnPrintf(pHlp, " SS");
     4401            if (uEDX & RT_BIT(28))  pHlp->pfnPrintf(pHlp, " HTT");
     4402            if (uEDX & RT_BIT(29))  pHlp->pfnPrintf(pHlp, " TM");
     4403            if (uEDX & RT_BIT(30))  pHlp->pfnPrintf(pHlp, " 30");
     4404            if (uEDX & RT_BIT(31))  pHlp->pfnPrintf(pHlp, " PBE");
     4405            pHlp->pfnPrintf(pHlp, "\n");
     4406
     4407            uint32_t uECX = Guest.uEcx;
     4408            pHlp->pfnPrintf(pHlp, "Features ECX:                   ");
     4409            if (uECX & RT_BIT(0))   pHlp->pfnPrintf(pHlp, " SSE3");
     4410            if (uECX & RT_BIT(1))   pHlp->pfnPrintf(pHlp, " PCLMUL");
     4411            if (uECX & RT_BIT(2))   pHlp->pfnPrintf(pHlp, " DTES64");
     4412            if (uECX & RT_BIT(3))   pHlp->pfnPrintf(pHlp, " MONITOR");
     4413            if (uECX & RT_BIT(4))   pHlp->pfnPrintf(pHlp, " DS-CPL");
     4414            if (uECX & RT_BIT(5))   pHlp->pfnPrintf(pHlp, " VMX");
     4415            if (uECX & RT_BIT(6))   pHlp->pfnPrintf(pHlp, " SMX");
     4416            if (uECX & RT_BIT(7))   pHlp->pfnPrintf(pHlp, " EST");
     4417            if (uECX & RT_BIT(8))   pHlp->pfnPrintf(pHlp, " TM2");
     4418            if (uECX & RT_BIT(9))   pHlp->pfnPrintf(pHlp, " SSSE3");
     4419            if (uECX & RT_BIT(10))  pHlp->pfnPrintf(pHlp, " CNXT-ID");
     4420            if (uECX & RT_BIT(11))  pHlp->pfnPrintf(pHlp, " 11");
     4421            if (uECX & RT_BIT(12))  pHlp->pfnPrintf(pHlp, " FMA");
     4422            if (uECX & RT_BIT(13))  pHlp->pfnPrintf(pHlp, " CX16");
     4423            if (uECX & RT_BIT(14))  pHlp->pfnPrintf(pHlp, " TPRUPDATE");
     4424            if (uECX & RT_BIT(15))  pHlp->pfnPrintf(pHlp, " PDCM");
     4425            if (uECX & RT_BIT(16))  pHlp->pfnPrintf(pHlp, " 16");
     4426            if (uECX & RT_BIT(17))  pHlp->pfnPrintf(pHlp, " PCID");
     4427            if (uECX & RT_BIT(18))  pHlp->pfnPrintf(pHlp, " DCA");
     4428            if (uECX & RT_BIT(19))  pHlp->pfnPrintf(pHlp, " SSE4.1");
     4429            if (uECX & RT_BIT(20))  pHlp->pfnPrintf(pHlp, " SSE4.2");
     4430            if (uECX & RT_BIT(21))  pHlp->pfnPrintf(pHlp, " X2APIC");
     4431            if (uECX & RT_BIT(22))  pHlp->pfnPrintf(pHlp, " MOVBE");
     4432            if (uECX & RT_BIT(23))  pHlp->pfnPrintf(pHlp, " POPCNT");
     4433            if (uECX & RT_BIT(24))  pHlp->pfnPrintf(pHlp, " TSCDEADL");
     4434            if (uECX & RT_BIT(25))  pHlp->pfnPrintf(pHlp, " AES");
     4435            if (uECX & RT_BIT(26))  pHlp->pfnPrintf(pHlp, " XSAVE");
     4436            if (uECX & RT_BIT(27))  pHlp->pfnPrintf(pHlp, " OSXSAVE");
     4437            if (uECX & RT_BIT(28))  pHlp->pfnPrintf(pHlp, " AVX");
     4438            if (uECX & RT_BIT(29))  pHlp->pfnPrintf(pHlp, " F16C");
     4439            if (uECX & RT_BIT(30))  pHlp->pfnPrintf(pHlp, " RDRAND");
     4440            if (uECX & RT_BIT(31))  pHlp->pfnPrintf(pHlp, " HVP");
     4441            pHlp->pfnPrintf(pHlp, "\n");
     4442        }
     4443        else
     4444        {
     4445            ASMCpuIdExSlow(1, 0, 0, 0, &Host.uEax, &Host.uEbx, &Host.uEcx, &Host.uEdx);
     4446
     4447            X86CPUIDFEATEDX EdxHost  = *(PX86CPUIDFEATEDX)&Host.uEdx;
     4448            X86CPUIDFEATECX EcxHost  = *(PX86CPUIDFEATECX)&Host.uEcx;
     4449            X86CPUIDFEATEDX EdxGuest = *(PX86CPUIDFEATEDX)&Guest.uEdx;
     4450            X86CPUIDFEATECX EcxGuest = *(PX86CPUIDFEATECX)&Guest.uEcx;
     4451
     4452            pHlp->pfnPrintf(pHlp, "Mnemonic - Description                 = guest (host)\n");
     4453            pHlp->pfnPrintf(pHlp, "FPU - x87 FPU on Chip                  = %d (%d)\n",  EdxGuest.u1FPU,        EdxHost.u1FPU);
     4454            pHlp->pfnPrintf(pHlp, "VME - Virtual 8086 Mode Enhancements   = %d (%d)\n",  EdxGuest.u1VME,        EdxHost.u1VME);
     4455            pHlp->pfnPrintf(pHlp, "DE - Debugging extensions              = %d (%d)\n",  EdxGuest.u1DE,         EdxHost.u1DE);
     4456            pHlp->pfnPrintf(pHlp, "PSE - Page Size Extension              = %d (%d)\n",  EdxGuest.u1PSE,        EdxHost.u1PSE);
     4457            pHlp->pfnPrintf(pHlp, "TSC - Time Stamp Counter               = %d (%d)\n",  EdxGuest.u1TSC,        EdxHost.u1TSC);
     4458            pHlp->pfnPrintf(pHlp, "MSR - Model Specific Registers         = %d (%d)\n",  EdxGuest.u1MSR,        EdxHost.u1MSR);
     4459            pHlp->pfnPrintf(pHlp, "PAE - Physical Address Extension       = %d (%d)\n",  EdxGuest.u1PAE,        EdxHost.u1PAE);
     4460            pHlp->pfnPrintf(pHlp, "MCE - Machine Check Exception          = %d (%d)\n",  EdxGuest.u1MCE,        EdxHost.u1MCE);
     4461            pHlp->pfnPrintf(pHlp, "CX8 - CMPXCHG8B instruction            = %d (%d)\n",  EdxGuest.u1CX8,        EdxHost.u1CX8);
     4462            pHlp->pfnPrintf(pHlp, "APIC - APIC On-Chip                    = %d (%d)\n",  EdxGuest.u1APIC,       EdxHost.u1APIC);
     4463            pHlp->pfnPrintf(pHlp, "10 - Reserved                          = %d (%d)\n",  EdxGuest.u1Reserved1,  EdxHost.u1Reserved1);
     4464            pHlp->pfnPrintf(pHlp, "SEP - SYSENTER and SYSEXIT             = %d (%d)\n",  EdxGuest.u1SEP,        EdxHost.u1SEP);
     4465            pHlp->pfnPrintf(pHlp, "MTRR - Memory Type Range Registers     = %d (%d)\n",  EdxGuest.u1MTRR,       EdxHost.u1MTRR);
     4466            pHlp->pfnPrintf(pHlp, "PGE - PTE Global Bit                   = %d (%d)\n",  EdxGuest.u1PGE,        EdxHost.u1PGE);
     4467            pHlp->pfnPrintf(pHlp, "MCA - Machine Check Architecture       = %d (%d)\n",  EdxGuest.u1MCA,        EdxHost.u1MCA);
     4468            pHlp->pfnPrintf(pHlp, "CMOV - Conditional Move Instructions   = %d (%d)\n",  EdxGuest.u1CMOV,       EdxHost.u1CMOV);
     4469            pHlp->pfnPrintf(pHlp, "PAT - Page Attribute Table             = %d (%d)\n",  EdxGuest.u1PAT,        EdxHost.u1PAT);
     4470            pHlp->pfnPrintf(pHlp, "PSE-36 - 36-bit Page Size Extention    = %d (%d)\n",  EdxGuest.u1PSE36,      EdxHost.u1PSE36);
     4471            pHlp->pfnPrintf(pHlp, "PSN - Processor Serial Number          = %d (%d)\n",  EdxGuest.u1PSN,        EdxHost.u1PSN);
     4472            pHlp->pfnPrintf(pHlp, "CLFSH - CLFLUSH Instruction.           = %d (%d)\n",  EdxGuest.u1CLFSH,      EdxHost.u1CLFSH);
     4473            pHlp->pfnPrintf(pHlp, "20 - Reserved                          = %d (%d)\n",  EdxGuest.u1Reserved2,  EdxHost.u1Reserved2);
     4474            pHlp->pfnPrintf(pHlp, "DS - Debug Store                       = %d (%d)\n",  EdxGuest.u1DS,         EdxHost.u1DS);
     4475            pHlp->pfnPrintf(pHlp, "ACPI - Thermal Mon. & Soft. Clock Ctrl.= %d (%d)\n",  EdxGuest.u1ACPI,       EdxHost.u1ACPI);
     4476            pHlp->pfnPrintf(pHlp, "MMX - Intel MMX Technology             = %d (%d)\n",  EdxGuest.u1MMX,        EdxHost.u1MMX);
     4477            pHlp->pfnPrintf(pHlp, "FXSR - FXSAVE and FXRSTOR Instructions = %d (%d)\n",  EdxGuest.u1FXSR,       EdxHost.u1FXSR);
     4478            pHlp->pfnPrintf(pHlp, "SSE - SSE Support                      = %d (%d)\n",  EdxGuest.u1SSE,        EdxHost.u1SSE);
     4479            pHlp->pfnPrintf(pHlp, "SSE2 - SSE2 Support                    = %d (%d)\n",  EdxGuest.u1SSE2,       EdxHost.u1SSE2);
     4480            pHlp->pfnPrintf(pHlp, "SS - Self Snoop                        = %d (%d)\n",  EdxGuest.u1SS,         EdxHost.u1SS);
     4481            pHlp->pfnPrintf(pHlp, "HTT - Hyper-Threading Technology       = %d (%d)\n",  EdxGuest.u1HTT,        EdxHost.u1HTT);
     4482            pHlp->pfnPrintf(pHlp, "TM - Thermal Monitor                   = %d (%d)\n",  EdxGuest.u1TM,         EdxHost.u1TM);
     4483            pHlp->pfnPrintf(pHlp, "30 - Reserved                          = %d (%d)\n",  EdxGuest.u1Reserved3,  EdxHost.u1Reserved3);
     4484            pHlp->pfnPrintf(pHlp, "PBE - Pending Break Enable             = %d (%d)\n",  EdxGuest.u1PBE,        EdxHost.u1PBE);
     4485
     4486            pHlp->pfnPrintf(pHlp, "Supports SSE3                          = %d (%d)\n",  EcxGuest.u1SSE3,       EcxHost.u1SSE3);
     4487            pHlp->pfnPrintf(pHlp, "PCLMULQDQ                              = %d (%d)\n",  EcxGuest.u1PCLMULQDQ,  EcxHost.u1PCLMULQDQ);
     4488            pHlp->pfnPrintf(pHlp, "DS Area 64-bit layout                  = %d (%d)\n",  EcxGuest.u1DTE64,      EcxHost.u1DTE64);
     4489            pHlp->pfnPrintf(pHlp, "Supports MONITOR/MWAIT                 = %d (%d)\n",  EcxGuest.u1Monitor,    EcxHost.u1Monitor);
     4490            pHlp->pfnPrintf(pHlp, "CPL-DS - CPL Qualified Debug Store     = %d (%d)\n",  EcxGuest.u1CPLDS,      EcxHost.u1CPLDS);
     4491            pHlp->pfnPrintf(pHlp, "VMX - Virtual Machine Technology       = %d (%d)\n",  EcxGuest.u1VMX,        EcxHost.u1VMX);
     4492            pHlp->pfnPrintf(pHlp, "SMX - Safer Mode Extensions            = %d (%d)\n",  EcxGuest.u1SMX,        EcxHost.u1SMX);
     4493            pHlp->pfnPrintf(pHlp, "Enhanced SpeedStep Technology          = %d (%d)\n",  EcxGuest.u1EST,        EcxHost.u1EST);
     4494            pHlp->pfnPrintf(pHlp, "Terminal Monitor 2                     = %d (%d)\n",  EcxGuest.u1TM2,        EcxHost.u1TM2);
     4495            pHlp->pfnPrintf(pHlp, "Supplemental SSE3 instructions         = %d (%d)\n",  EcxGuest.u1SSSE3,      EcxHost.u1SSSE3);
     4496            pHlp->pfnPrintf(pHlp, "L1 Context ID                          = %d (%d)\n",  EcxGuest.u1CNTXID,     EcxHost.u1CNTXID);
     4497            pHlp->pfnPrintf(pHlp, "11 - Reserved                          = %d (%d)\n",  EcxGuest.u1Reserved1,  EcxHost.u1Reserved1);
     4498            pHlp->pfnPrintf(pHlp, "FMA extensions using YMM state         = %d (%d)\n",  EcxGuest.u1FMA,        EcxHost.u1FMA);
     4499            pHlp->pfnPrintf(pHlp, "CMPXCHG16B instruction                 = %d (%d)\n",  EcxGuest.u1CX16,       EcxHost.u1CX16);
     4500            pHlp->pfnPrintf(pHlp, "xTPR Update Control                    = %d (%d)\n",  EcxGuest.u1TPRUpdate,  EcxHost.u1TPRUpdate);
     4501            pHlp->pfnPrintf(pHlp, "Perf/Debug Capability MSR              = %d (%d)\n",  EcxGuest.u1PDCM,       EcxHost.u1PDCM);
     4502            pHlp->pfnPrintf(pHlp, "16 - Reserved                          = %d (%d)\n",  EcxGuest.u1Reserved2,  EcxHost.u1Reserved2);
     4503            pHlp->pfnPrintf(pHlp, "PCID - Process-context identifiers     = %d (%d)\n",  EcxGuest.u1PCID,       EcxHost.u1PCID);
     4504            pHlp->pfnPrintf(pHlp, "DCA - Direct Cache Access              = %d (%d)\n",  EcxGuest.u1DCA,        EcxHost.u1DCA);
     4505            pHlp->pfnPrintf(pHlp, "SSE4.1 instruction extensions          = %d (%d)\n",  EcxGuest.u1SSE4_1,     EcxHost.u1SSE4_1);
     4506            pHlp->pfnPrintf(pHlp, "SSE4.2 instruction extensions          = %d (%d)\n",  EcxGuest.u1SSE4_2,     EcxHost.u1SSE4_2);
     4507            pHlp->pfnPrintf(pHlp, "Supports the x2APIC extensions         = %d (%d)\n",  EcxGuest.u1x2APIC,     EcxHost.u1x2APIC);
     4508            pHlp->pfnPrintf(pHlp, "MOVBE instruction                      = %d (%d)\n",  EcxGuest.u1MOVBE,      EcxHost.u1MOVBE);
     4509            pHlp->pfnPrintf(pHlp, "POPCNT instruction                     = %d (%d)\n",  EcxGuest.u1POPCNT,     EcxHost.u1POPCNT);
     4510            pHlp->pfnPrintf(pHlp, "TSC-Deadline LAPIC timer mode          = %d (%d)\n",  EcxGuest.u1TSCDEADLINE,EcxHost.u1TSCDEADLINE);
     4511            pHlp->pfnPrintf(pHlp, "AESNI instruction extensions           = %d (%d)\n",  EcxGuest.u1AES,        EcxHost.u1AES);
     4512            pHlp->pfnPrintf(pHlp, "XSAVE/XRSTOR extended state feature    = %d (%d)\n",  EcxGuest.u1XSAVE,      EcxHost.u1XSAVE);
     4513            pHlp->pfnPrintf(pHlp, "Supports OSXSAVE                       = %d (%d)\n",  EcxGuest.u1OSXSAVE,    EcxHost.u1OSXSAVE);
     4514            pHlp->pfnPrintf(pHlp, "AVX instruction extensions             = %d (%d)\n",  EcxGuest.u1AVX,        EcxHost.u1AVX);
     4515            pHlp->pfnPrintf(pHlp, "16-bit floating point conversion instr = %d (%d)\n",  EcxGuest.u1F16C,       EcxHost.u1F16C);
     4516            pHlp->pfnPrintf(pHlp, "RDRAND instruction                     = %d (%d)\n",  EcxGuest.u1RDRAND,     EcxHost.u1RDRAND);
     4517            pHlp->pfnPrintf(pHlp, "Hypervisor Present (we're a guest)     = %d (%d)\n",  EcxGuest.u1HVP,        EcxHost.u1HVP);
     4518        }
     4519    }
     4520    if (cStdMax >= 2 && iVerbosity)
     4521    {
     4522        /** @todo */
     4523    }
     4524
     4525    /*
     4526     * Extended.
     4527     * Implemented after AMD specs.
     4528     */
     4529    unsigned    cExtMax = pVM->cpum.s.aGuestCpuIdPatmExt[0].uEax & 0xffff;
     4530
     4531    pHlp->pfnPrintf(pHlp,
     4532                    "\n"
     4533                    "         RAW Extended CPUIDs\n"
     4534                    "     Function  eax      ebx      ecx      edx\n");
     4535    bool fSupportsInvariantTsc = false;
     4536    for (unsigned i = 0; i < RT_ELEMENTS(pVM->cpum.s.aGuestCpuIdPatmExt); i++)
     4537    {
     4538        Guest = pVM->cpum.s.aGuestCpuIdPatmExt[i];
     4539        ASMCpuIdExSlow(0x80000000 | i, 0, 0, 0, &Host.uEax, &Host.uEbx, &Host.uEcx, &Host.uEdx);
     4540
     4541        if (   i == 7
     4542            && (Host.uEdx & X86_CPUID_AMD_ADVPOWER_EDX_TSCINVAR))
     4543        {
     4544            fSupportsInvariantTsc = true;
     4545        }
     4546        pHlp->pfnPrintf(pHlp,
     4547                        "Gst: %08x  %08x %08x %08x %08x%s\n"
     4548                        "Hst:           %08x %08x %08x %08x\n",
     4549                        0x80000000 | i, Guest.uEax, Guest.uEbx, Guest.uEcx, Guest.uEdx,
     4550                        i <= cExtMax ? "" : "*",
     4551                        Host.uEax, Host.uEbx, Host.uEcx, Host.uEdx);
     4552    }
     4553
     4554    /*
     4555     * Understandable output
     4556     */
     4557    if (iVerbosity)
     4558    {
     4559        Guest = pVM->cpum.s.aGuestCpuIdPatmExt[0];
     4560        pHlp->pfnPrintf(pHlp,
     4561                        "Ext Name:                        %.4s%.4s%.4s\n"
     4562                        "Ext Supports:                    0x80000000-%#010x\n",
     4563                        &Guest.uEbx, &Guest.uEdx, &Guest.uEcx, Guest.uEax);
     4564    }
     4565
     4566    if (iVerbosity && cExtMax >= 1)
     4567    {
     4568        Guest = pVM->cpum.s.aGuestCpuIdPatmExt[1];
     4569        uint32_t uEAX = Guest.uEax;
     4570        pHlp->pfnPrintf(pHlp,
     4571                        "Family:                          %d  \tExtended: %d \tEffective: %d\n"
     4572                        "Model:                           %d  \tExtended: %d \tEffective: %d\n"
     4573                        "Stepping:                        %d\n"
     4574                        "Brand ID:                        %#05x\n",
     4575                        (uEAX >> 8) & 0xf, (uEAX >> 20) & 0x7f, ASMGetCpuFamily(uEAX),
     4576                        (uEAX >> 4) & 0xf, (uEAX >> 16) & 0x0f, ASMGetCpuModel(uEAX, fIntel),
     4577                        ASMGetCpuStepping(uEAX),
     4578                        Guest.uEbx & 0xfff);
     4579
     4580        if (iVerbosity == 1)
     4581        {
     4582            uint32_t uEDX = Guest.uEdx;
     4583            pHlp->pfnPrintf(pHlp, "Features EDX:                   ");
     4584            if (uEDX & RT_BIT(0))   pHlp->pfnPrintf(pHlp, " FPU");
     4585            if (uEDX & RT_BIT(1))   pHlp->pfnPrintf(pHlp, " VME");
     4586            if (uEDX & RT_BIT(2))   pHlp->pfnPrintf(pHlp, " DE");
     4587            if (uEDX & RT_BIT(3))   pHlp->pfnPrintf(pHlp, " PSE");
     4588            if (uEDX & RT_BIT(4))   pHlp->pfnPrintf(pHlp, " TSC");
     4589            if (uEDX & RT_BIT(5))   pHlp->pfnPrintf(pHlp, " MSR");
     4590            if (uEDX & RT_BIT(6))   pHlp->pfnPrintf(pHlp, " PAE");
     4591            if (uEDX & RT_BIT(7))   pHlp->pfnPrintf(pHlp, " MCE");
     4592            if (uEDX & RT_BIT(8))   pHlp->pfnPrintf(pHlp, " CX8");
     4593            if (uEDX & RT_BIT(9))   pHlp->pfnPrintf(pHlp, " APIC");
     4594            if (uEDX & RT_BIT(10))  pHlp->pfnPrintf(pHlp, " 10");
     4595            if (uEDX & RT_BIT(11))  pHlp->pfnPrintf(pHlp, " SCR");
     4596            if (uEDX & RT_BIT(12))  pHlp->pfnPrintf(pHlp, " MTRR");
     4597            if (uEDX & RT_BIT(13))  pHlp->pfnPrintf(pHlp, " PGE");
     4598            if (uEDX & RT_BIT(14))  pHlp->pfnPrintf(pHlp, " MCA");
     4599            if (uEDX & RT_BIT(15))  pHlp->pfnPrintf(pHlp, " CMOV");
     4600            if (uEDX & RT_BIT(16))  pHlp->pfnPrintf(pHlp, " PAT");
     4601            if (uEDX & RT_BIT(17))  pHlp->pfnPrintf(pHlp, " PSE36");
     4602            if (uEDX & RT_BIT(18))  pHlp->pfnPrintf(pHlp, " 18");
     4603            if (uEDX & RT_BIT(19))  pHlp->pfnPrintf(pHlp, " 19");
     4604            if (uEDX & RT_BIT(20))  pHlp->pfnPrintf(pHlp, " NX");
     4605            if (uEDX & RT_BIT(21))  pHlp->pfnPrintf(pHlp, " 21");
     4606            if (uEDX & RT_BIT(22))  pHlp->pfnPrintf(pHlp, " ExtMMX");
     4607            if (uEDX & RT_BIT(23))  pHlp->pfnPrintf(pHlp, " MMX");
     4608            if (uEDX & RT_BIT(24))  pHlp->pfnPrintf(pHlp, " FXSR");
     4609            if (uEDX & RT_BIT(25))  pHlp->pfnPrintf(pHlp, " FastFXSR");
     4610            if (uEDX & RT_BIT(26))  pHlp->pfnPrintf(pHlp, " Page1GB");
     4611            if (uEDX & RT_BIT(27))  pHlp->pfnPrintf(pHlp, " RDTSCP");
     4612            if (uEDX & RT_BIT(28))  pHlp->pfnPrintf(pHlp, " 28");
     4613            if (uEDX & RT_BIT(29))  pHlp->pfnPrintf(pHlp, " LongMode");
     4614            if (uEDX & RT_BIT(30))  pHlp->pfnPrintf(pHlp, " Ext3DNow");
     4615            if (uEDX & RT_BIT(31))  pHlp->pfnPrintf(pHlp, " 3DNow");
     4616            pHlp->pfnPrintf(pHlp, "\n");
     4617
     4618            uint32_t uECX = Guest.uEcx;
     4619            pHlp->pfnPrintf(pHlp, "Features ECX:                   ");
     4620            if (uECX & RT_BIT(0))   pHlp->pfnPrintf(pHlp, " LAHF/SAHF");
     4621            if (uECX & RT_BIT(1))   pHlp->pfnPrintf(pHlp, " CMPL");
     4622            if (uECX & RT_BIT(2))   pHlp->pfnPrintf(pHlp, " SVM");
     4623            if (uECX & RT_BIT(3))   pHlp->pfnPrintf(pHlp, " ExtAPIC");
     4624            if (uECX & RT_BIT(4))   pHlp->pfnPrintf(pHlp, " CR8L");
     4625            if (uECX & RT_BIT(5))   pHlp->pfnPrintf(pHlp, " ABM");
     4626            if (uECX & RT_BIT(6))   pHlp->pfnPrintf(pHlp, " SSE4A");
     4627            if (uECX & RT_BIT(7))   pHlp->pfnPrintf(pHlp, " MISALNSSE");
     4628            if (uECX & RT_BIT(8))   pHlp->pfnPrintf(pHlp, " 3DNOWPRF");
     4629            if (uECX & RT_BIT(9))   pHlp->pfnPrintf(pHlp, " OSVW");
     4630            if (uECX & RT_BIT(10))  pHlp->pfnPrintf(pHlp, " IBS");
     4631            if (uECX & RT_BIT(11))  pHlp->pfnPrintf(pHlp, " SSE5");
     4632            if (uECX & RT_BIT(12))  pHlp->pfnPrintf(pHlp, " SKINIT");
     4633            if (uECX & RT_BIT(13))  pHlp->pfnPrintf(pHlp, " WDT");
     4634            for (unsigned iBit = 5; iBit < 32; iBit++)
     4635                if (uECX & RT_BIT(iBit))
     4636                    pHlp->pfnPrintf(pHlp, " %d", iBit);
     4637            pHlp->pfnPrintf(pHlp, "\n");
     4638        }
     4639        else
     4640        {
     4641            ASMCpuIdExSlow(0x80000001, 0, 0, 0, &Host.uEax, &Host.uEbx, &Host.uEcx, &Host.uEdx);
     4642
     4643            uint32_t uEdxGst = Guest.uEdx;
     4644            uint32_t uEdxHst = Host.uEdx;
     4645            pHlp->pfnPrintf(pHlp, "Mnemonic - Description                 = guest (host)\n");
     4646            pHlp->pfnPrintf(pHlp, "FPU - x87 FPU on Chip                  = %d (%d)\n",  !!(uEdxGst & RT_BIT( 0)),  !!(uEdxHst & RT_BIT( 0)));
     4647            pHlp->pfnPrintf(pHlp, "VME - Virtual 8086 Mode Enhancements   = %d (%d)\n",  !!(uEdxGst & RT_BIT( 1)),  !!(uEdxHst & RT_BIT( 1)));
     4648            pHlp->pfnPrintf(pHlp, "DE - Debugging extensions              = %d (%d)\n",  !!(uEdxGst & RT_BIT( 2)),  !!(uEdxHst & RT_BIT( 2)));
     4649            pHlp->pfnPrintf(pHlp, "PSE - Page Size Extension              = %d (%d)\n",  !!(uEdxGst & RT_BIT( 3)),  !!(uEdxHst & RT_BIT( 3)));
     4650            pHlp->pfnPrintf(pHlp, "TSC - Time Stamp Counter               = %d (%d)\n",  !!(uEdxGst & RT_BIT( 4)),  !!(uEdxHst & RT_BIT( 4)));
     4651            pHlp->pfnPrintf(pHlp, "MSR - K86 Model Specific Registers     = %d (%d)\n",  !!(uEdxGst & RT_BIT( 5)),  !!(uEdxHst & RT_BIT( 5)));
     4652            pHlp->pfnPrintf(pHlp, "PAE - Physical Address Extension       = %d (%d)\n",  !!(uEdxGst & RT_BIT( 6)),  !!(uEdxHst & RT_BIT( 6)));
     4653            pHlp->pfnPrintf(pHlp, "MCE - Machine Check Exception          = %d (%d)\n",  !!(uEdxGst & RT_BIT( 7)),  !!(uEdxHst & RT_BIT( 7)));
     4654            pHlp->pfnPrintf(pHlp, "CX8 - CMPXCHG8B instruction            = %d (%d)\n",  !!(uEdxGst & RT_BIT( 8)),  !!(uEdxHst & RT_BIT( 8)));
     4655            pHlp->pfnPrintf(pHlp, "APIC - APIC On-Chip                    = %d (%d)\n",  !!(uEdxGst & RT_BIT( 9)),  !!(uEdxHst & RT_BIT( 9)));
     4656            pHlp->pfnPrintf(pHlp, "10 - Reserved                          = %d (%d)\n",  !!(uEdxGst & RT_BIT(10)),  !!(uEdxHst & RT_BIT(10)));
     4657            pHlp->pfnPrintf(pHlp, "SEP - SYSCALL and SYSRET               = %d (%d)\n",  !!(uEdxGst & RT_BIT(11)),  !!(uEdxHst & RT_BIT(11)));
     4658            pHlp->pfnPrintf(pHlp, "MTRR - Memory Type Range Registers     = %d (%d)\n",  !!(uEdxGst & RT_BIT(12)),  !!(uEdxHst & RT_BIT(12)));
     4659            pHlp->pfnPrintf(pHlp, "PGE - PTE Global Bit                   = %d (%d)\n",  !!(uEdxGst & RT_BIT(13)),  !!(uEdxHst & RT_BIT(13)));
     4660            pHlp->pfnPrintf(pHlp, "MCA - Machine Check Architecture       = %d (%d)\n",  !!(uEdxGst & RT_BIT(14)),  !!(uEdxHst & RT_BIT(14)));
     4661            pHlp->pfnPrintf(pHlp, "CMOV - Conditional Move Instructions   = %d (%d)\n",  !!(uEdxGst & RT_BIT(15)),  !!(uEdxHst & RT_BIT(15)));
     4662            pHlp->pfnPrintf(pHlp, "PAT - Page Attribute Table             = %d (%d)\n",  !!(uEdxGst & RT_BIT(16)),  !!(uEdxHst & RT_BIT(16)));
     4663            pHlp->pfnPrintf(pHlp, "PSE-36 - 36-bit Page Size Extention    = %d (%d)\n",  !!(uEdxGst & RT_BIT(17)),  !!(uEdxHst & RT_BIT(17)));
     4664            pHlp->pfnPrintf(pHlp, "18 - Reserved                          = %d (%d)\n",  !!(uEdxGst & RT_BIT(18)),  !!(uEdxHst & RT_BIT(18)));
     4665            pHlp->pfnPrintf(pHlp, "19 - Reserved                          = %d (%d)\n",  !!(uEdxGst & RT_BIT(19)),  !!(uEdxHst & RT_BIT(19)));
     4666            pHlp->pfnPrintf(pHlp, "NX - No-Execute Page Protection        = %d (%d)\n",  !!(uEdxGst & RT_BIT(20)),  !!(uEdxHst & RT_BIT(20)));
     4667            pHlp->pfnPrintf(pHlp, "DS - Debug Store                       = %d (%d)\n",  !!(uEdxGst & RT_BIT(21)),  !!(uEdxHst & RT_BIT(21)));
     4668            pHlp->pfnPrintf(pHlp, "AXMMX - AMD Extensions to MMX Instr.   = %d (%d)\n",  !!(uEdxGst & RT_BIT(22)),  !!(uEdxHst & RT_BIT(22)));
     4669            pHlp->pfnPrintf(pHlp, "MMX - Intel MMX Technology             = %d (%d)\n",  !!(uEdxGst & RT_BIT(23)),  !!(uEdxHst & RT_BIT(23)));
     4670            pHlp->pfnPrintf(pHlp, "FXSR - FXSAVE and FXRSTOR Instructions = %d (%d)\n",  !!(uEdxGst & RT_BIT(24)),  !!(uEdxHst & RT_BIT(24)));
     4671            pHlp->pfnPrintf(pHlp, "25 - AMD fast FXSAVE and FXRSTOR Instr.= %d (%d)\n",  !!(uEdxGst & RT_BIT(25)),  !!(uEdxHst & RT_BIT(25)));
     4672            pHlp->pfnPrintf(pHlp, "26 - 1 GB large page support           = %d (%d)\n",  !!(uEdxGst & RT_BIT(26)),  !!(uEdxHst & RT_BIT(26)));
     4673            pHlp->pfnPrintf(pHlp, "27 - RDTSCP instruction                = %d (%d)\n",  !!(uEdxGst & RT_BIT(27)),  !!(uEdxHst & RT_BIT(27)));
     4674            pHlp->pfnPrintf(pHlp, "28 - Reserved                          = %d (%d)\n",  !!(uEdxGst & RT_BIT(28)),  !!(uEdxHst & RT_BIT(28)));
     4675            pHlp->pfnPrintf(pHlp, "29 - AMD Long Mode                     = %d (%d)\n",  !!(uEdxGst & RT_BIT(29)),  !!(uEdxHst & RT_BIT(29)));
     4676            pHlp->pfnPrintf(pHlp, "30 - AMD Extensions to 3DNow!          = %d (%d)\n",  !!(uEdxGst & RT_BIT(30)),  !!(uEdxHst & RT_BIT(30)));
     4677            pHlp->pfnPrintf(pHlp, "31 - AMD 3DNow!                        = %d (%d)\n",  !!(uEdxGst & RT_BIT(31)),  !!(uEdxHst & RT_BIT(31)));
     4678
     4679            uint32_t uEcxGst = Guest.uEcx;
     4680            uint32_t uEcxHst = Host.uEcx;
     4681            pHlp->pfnPrintf(pHlp, "LahfSahf - LAHF/SAHF in 64-bit mode    = %d (%d)\n",  !!(uEcxGst & RT_BIT( 0)),  !!(uEcxHst & RT_BIT( 0)));
     4682            pHlp->pfnPrintf(pHlp, "CmpLegacy - Core MP legacy mode (depr) = %d (%d)\n",  !!(uEcxGst & RT_BIT( 1)),  !!(uEcxHst & RT_BIT( 1)));
     4683            pHlp->pfnPrintf(pHlp, "SVM - AMD VM Extensions                = %d (%d)\n",  !!(uEcxGst & RT_BIT( 2)),  !!(uEcxHst & RT_BIT( 2)));
     4684            pHlp->pfnPrintf(pHlp, "APIC registers starting at 0x400       = %d (%d)\n",  !!(uEcxGst & RT_BIT( 3)),  !!(uEcxHst & RT_BIT( 3)));
     4685            pHlp->pfnPrintf(pHlp, "AltMovCR8 - LOCK MOV CR0 means MOV CR8 = %d (%d)\n",  !!(uEcxGst & RT_BIT( 4)),  !!(uEcxHst & RT_BIT( 4)));
     4686            pHlp->pfnPrintf(pHlp, "5  - Advanced bit manipulation         = %d (%d)\n",  !!(uEcxGst & RT_BIT( 5)),  !!(uEcxHst & RT_BIT( 5)));
     4687            pHlp->pfnPrintf(pHlp, "6  - SSE4A instruction support         = %d (%d)\n",  !!(uEcxGst & RT_BIT( 6)),  !!(uEcxHst & RT_BIT( 6)));
     4688            pHlp->pfnPrintf(pHlp, "7  - Misaligned SSE mode               = %d (%d)\n",  !!(uEcxGst & RT_BIT( 7)),  !!(uEcxHst & RT_BIT( 7)));
     4689            pHlp->pfnPrintf(pHlp, "8  - PREFETCH and PREFETCHW instruction= %d (%d)\n",  !!(uEcxGst & RT_BIT( 8)),  !!(uEcxHst & RT_BIT( 8)));
     4690            pHlp->pfnPrintf(pHlp, "9  - OS visible workaround             = %d (%d)\n",  !!(uEcxGst & RT_BIT( 9)),  !!(uEcxHst & RT_BIT( 9)));
     4691            pHlp->pfnPrintf(pHlp, "10 - Instruction based sampling        = %d (%d)\n",  !!(uEcxGst & RT_BIT(10)),  !!(uEcxHst & RT_BIT(10)));
     4692            pHlp->pfnPrintf(pHlp, "11 - SSE5 support                      = %d (%d)\n",  !!(uEcxGst & RT_BIT(11)),  !!(uEcxHst & RT_BIT(11)));
     4693            pHlp->pfnPrintf(pHlp, "12 - SKINIT, STGI, and DEV support     = %d (%d)\n",  !!(uEcxGst & RT_BIT(12)),  !!(uEcxHst & RT_BIT(12)));
     4694            pHlp->pfnPrintf(pHlp, "13 - Watchdog timer support.           = %d (%d)\n",  !!(uEcxGst & RT_BIT(13)),  !!(uEcxHst & RT_BIT(13)));
     4695            pHlp->pfnPrintf(pHlp, "31:14 - Reserved                       = %#x (%#x)\n",   uEcxGst >> 14,          uEcxHst >> 14);
     4696        }
     4697    }
     4698
     4699    if (iVerbosity && cExtMax >= 2)
     4700    {
     4701        char szString[4*4*3+1] = {0};
     4702        uint32_t *pu32 = (uint32_t *)szString;
     4703        *pu32++ = pVM->cpum.s.aGuestCpuIdPatmExt[2].uEax;
     4704        *pu32++ = pVM->cpum.s.aGuestCpuIdPatmExt[2].uEbx;
     4705        *pu32++ = pVM->cpum.s.aGuestCpuIdPatmExt[2].uEcx;
     4706        *pu32++ = pVM->cpum.s.aGuestCpuIdPatmExt[2].uEdx;
     4707        if (cExtMax >= 3)
     4708        {
     4709            *pu32++ = pVM->cpum.s.aGuestCpuIdPatmExt[3].uEax;
     4710            *pu32++ = pVM->cpum.s.aGuestCpuIdPatmExt[3].uEbx;
     4711            *pu32++ = pVM->cpum.s.aGuestCpuIdPatmExt[3].uEcx;
     4712            *pu32++ = pVM->cpum.s.aGuestCpuIdPatmExt[3].uEdx;
     4713        }
     4714        if (cExtMax >= 4)
     4715        {
     4716            *pu32++ = pVM->cpum.s.aGuestCpuIdPatmExt[4].uEax;
     4717            *pu32++ = pVM->cpum.s.aGuestCpuIdPatmExt[4].uEbx;
     4718            *pu32++ = pVM->cpum.s.aGuestCpuIdPatmExt[4].uEcx;
     4719            *pu32++ = pVM->cpum.s.aGuestCpuIdPatmExt[4].uEdx;
     4720        }
     4721        pHlp->pfnPrintf(pHlp, "Full Name:                       %s\n", szString);
     4722    }
     4723
     4724    if (iVerbosity && cExtMax >= 5)
     4725    {
     4726        uint32_t uEAX = pVM->cpum.s.aGuestCpuIdPatmExt[5].uEax;
     4727        uint32_t uEBX = pVM->cpum.s.aGuestCpuIdPatmExt[5].uEbx;
     4728        uint32_t uECX = pVM->cpum.s.aGuestCpuIdPatmExt[5].uEcx;
     4729        uint32_t uEDX = pVM->cpum.s.aGuestCpuIdPatmExt[5].uEdx;
     4730        char sz1[32];
     4731        char sz2[32];
     4732
     4733        pHlp->pfnPrintf(pHlp,
     4734                        "TLB 2/4M Instr/Uni:              %s %3d entries\n"
     4735                        "TLB 2/4M Data:                   %s %3d entries\n",
     4736                        getCacheAss((uEAX >>  8) & 0xff, sz1), (uEAX >>  0) & 0xff,
     4737                        getCacheAss((uEAX >> 24) & 0xff, sz2), (uEAX >> 16) & 0xff);
     4738        pHlp->pfnPrintf(pHlp,
     4739                        "TLB 4K Instr/Uni:                %s %3d entries\n"
     4740                        "TLB 4K Data:                     %s %3d entries\n",
     4741                        getCacheAss((uEBX >>  8) & 0xff, sz1), (uEBX >>  0) & 0xff,
     4742                        getCacheAss((uEBX >> 24) & 0xff, sz2), (uEBX >> 16) & 0xff);
     4743        pHlp->pfnPrintf(pHlp, "L1 Instr Cache Line Size:        %d bytes\n"
     4744                        "L1 Instr Cache Lines Per Tag:    %d\n"
     4745                        "L1 Instr Cache Associativity:    %s\n"
     4746                        "L1 Instr Cache Size:             %d KB\n",
     4747                        (uEDX >> 0) & 0xff,
     4748                        (uEDX >> 8) & 0xff,
     4749                        getCacheAss((uEDX >> 16) & 0xff, sz1),
     4750                        (uEDX >> 24) & 0xff);
     4751        pHlp->pfnPrintf(pHlp,
     4752                        "L1 Data Cache Line Size:         %d bytes\n"
     4753                        "L1 Data Cache Lines Per Tag:     %d\n"
     4754                        "L1 Data Cache Associativity:     %s\n"
     4755                        "L1 Data Cache Size:              %d KB\n",
     4756                        (uECX >> 0) & 0xff,
     4757                        (uECX >> 8) & 0xff,
     4758                        getCacheAss((uECX >> 16) & 0xff, sz1),
     4759                        (uECX >> 24) & 0xff);
     4760    }
     4761
     4762    if (iVerbosity && cExtMax >= 6)
     4763    {
     4764        uint32_t uEAX = pVM->cpum.s.aGuestCpuIdPatmExt[6].uEax;
     4765        uint32_t uEBX = pVM->cpum.s.aGuestCpuIdPatmExt[6].uEbx;
     4766        uint32_t uEDX = pVM->cpum.s.aGuestCpuIdPatmExt[6].uEdx;
     4767
     4768        pHlp->pfnPrintf(pHlp,
     4769                        "L2 TLB 2/4M Instr/Uni:           %s %4d entries\n"
     4770                        "L2 TLB 2/4M Data:                %s %4d entries\n",
     4771                        getL2CacheAss((uEAX >> 12) & 0xf),  (uEAX >>  0) & 0xfff,
     4772                        getL2CacheAss((uEAX >> 28) & 0xf),  (uEAX >> 16) & 0xfff);
     4773        pHlp->pfnPrintf(pHlp,
     4774                        "L2 TLB 4K Instr/Uni:             %s %4d entries\n"
     4775                        "L2 TLB 4K Data:                  %s %4d entries\n",
     4776                        getL2CacheAss((uEBX >> 12) & 0xf),  (uEBX >>  0) & 0xfff,
     4777                        getL2CacheAss((uEBX >> 28) & 0xf),  (uEBX >> 16) & 0xfff);
     4778        pHlp->pfnPrintf(pHlp,
     4779                        "L2 Cache Line Size:              %d bytes\n"
     4780                        "L2 Cache Lines Per Tag:          %d\n"
     4781                        "L2 Cache Associativity:          %s\n"
     4782                        "L2 Cache Size:                   %d KB\n",
     4783                        (uEDX >> 0) & 0xff,
     4784                        (uEDX >> 8) & 0xf,
     4785                        getL2CacheAss((uEDX >> 12) & 0xf),
     4786                        (uEDX >> 16) & 0xffff);
     4787    }
     4788
     4789    if (iVerbosity && cExtMax >= 7)
     4790    {
     4791        uint32_t uEDX = pVM->cpum.s.aGuestCpuIdPatmExt[7].uEdx;
     4792
     4793        pHlp->pfnPrintf(pHlp, "Host Invariant-TSC support:      %RTbool\n", fSupportsInvariantTsc);
     4794        pHlp->pfnPrintf(pHlp, "APM Features:                   ");
     4795        if (uEDX & RT_BIT(0))   pHlp->pfnPrintf(pHlp, " TS");
     4796        if (uEDX & RT_BIT(1))   pHlp->pfnPrintf(pHlp, " FID");
     4797        if (uEDX & RT_BIT(2))   pHlp->pfnPrintf(pHlp, " VID");
     4798        if (uEDX & RT_BIT(3))   pHlp->pfnPrintf(pHlp, " TTP");
     4799        if (uEDX & RT_BIT(4))   pHlp->pfnPrintf(pHlp, " TM");
     4800        if (uEDX & RT_BIT(5))   pHlp->pfnPrintf(pHlp, " STC");
     4801        if (uEDX & RT_BIT(6))   pHlp->pfnPrintf(pHlp, " MC");
     4802        if (uEDX & RT_BIT(7))   pHlp->pfnPrintf(pHlp, " HWPSTATE");
     4803        if (uEDX & RT_BIT(8))   pHlp->pfnPrintf(pHlp, " TscInvariant");
     4804        if (uEDX & RT_BIT(9))   pHlp->pfnPrintf(pHlp, " CPB");
     4805        if (uEDX & RT_BIT(10))  pHlp->pfnPrintf(pHlp, " EffFreqRO");
     4806        if (uEDX & RT_BIT(11))  pHlp->pfnPrintf(pHlp, " PFI");
     4807        if (uEDX & RT_BIT(12))  pHlp->pfnPrintf(pHlp, " PA");
     4808        for (unsigned iBit = 13; iBit < 32; iBit++)
     4809            if (uEDX & RT_BIT(iBit))
     4810                pHlp->pfnPrintf(pHlp, " %d", iBit);
     4811        pHlp->pfnPrintf(pHlp, "\n");
     4812    }
     4813
     4814    if (iVerbosity && cExtMax >= 8)
     4815    {
     4816        uint32_t uEAX = pVM->cpum.s.aGuestCpuIdPatmExt[8].uEax;
     4817        uint32_t uECX = pVM->cpum.s.aGuestCpuIdPatmExt[8].uEcx;
     4818
     4819        pHlp->pfnPrintf(pHlp,
     4820                        "Physical Address Width:          %d bits\n"
     4821                        "Virtual Address Width:           %d bits\n"
     4822                        "Guest Physical Address Width:    %d bits\n",
     4823                        (uEAX >> 0) & 0xff,
     4824                        (uEAX >> 8) & 0xff,
     4825                        (uEAX >> 16) & 0xff);
     4826        pHlp->pfnPrintf(pHlp,
     4827                        "Physical Core Count:             %d\n",
     4828                        (uECX >> 0) & 0xff);
     4829    }
     4830
     4831
     4832    /*
     4833     * Hypervisor leaves.
     4834     *
     4835     * Unlike most of the other leaves reported, the guest hypervisor leaves
     4836     * aren't a subset of the host CPUID bits.
     4837     */
     4838    RT_ZERO(Host);
     4839    if (cStdHstMax >= 1)
     4840        ASMCpuIdExSlow(1, 0, 0, 0, &Host.uEax, &Host.uEbx, &Host.uEcx, &Host.uEdx);
     4841    bool fHostHvp  = RT_BOOL(Host.uEcx & X86_CPUID_FEATURE_ECX_HVP);
     4842    bool fGuestHvp = false;
     4843    if (cStdMax >= 1)
     4844    {
     4845        Guest     = pVM->cpum.s.aGuestCpuIdPatmStd[1];
     4846        fGuestHvp = RT_BOOL(Guest.uEcx & X86_CPUID_FEATURE_ECX_HVP);
     4847    }
     4848
     4849    if (   fHostHvp
     4850        || fGuestHvp)
     4851    {
     4852        uint32_t const uHyperLeaf = 0x40000000;
     4853        pHlp->pfnPrintf(pHlp,
     4854                        "\n"
     4855                        "         Hypervisor CPUIDs\n"
     4856                        "     Function  eax      ebx      ecx      edx\n");
     4857
     4858        PCCPUMCPUIDLEAF pHyperLeafGst = NULL;
     4859        if (fGuestHvp)
     4860        {
     4861            pHyperLeafGst = cpumR3CpuIdGetLeaf(pVM->cpum.s.GuestInfo.paCpuIdLeavesR3, pVM->cpum.s.GuestInfo.cCpuIdLeaves,
     4862                                               uHyperLeaf, 0 /* uSubLeaf */);
     4863        }
     4864
     4865        RT_ZERO(Host);
     4866        if (fHostHvp)
     4867            ASMCpuIdExSlow(uHyperLeaf, 0, 0, 0, &Host.uEax, &Host.uEbx, &Host.uEcx, &Host.uEdx);
     4868
     4869        CPUMCPUIDLEAF  GuestLeaf;
     4870        uint32_t const cHyperGstMax = pHyperLeafGst ? pHyperLeafGst->uEax : 0;
     4871        uint32_t const cHyperHstMax = Host.uEax;
     4872        uint32_t const cHyperMax    = RT_MAX(cHyperHstMax, cHyperGstMax);
     4873        for (uint32_t i = uHyperLeaf; i <= cHyperMax; i++)
     4874        {
     4875            RT_ZERO(Host);
     4876            RT_ZERO(GuestLeaf);
     4877            if (i <= cHyperHstMax)
     4878                ASMCpuIdExSlow(i, 0, 0, 0, &Host.uEax, &Host.uEbx, &Host.uEcx, &Host.uEdx);
     4879            CPUMR3CpuIdGetLeaf(pVM, &GuestLeaf, i, 0 /* uSubLeaf */);
     4880            if (!fHostHvp)
     4881            {
     4882                pHlp->pfnPrintf(pHlp,
     4883                                "Gst: %08x  %08x %08x %08x %08x\n",
     4884                                i, GuestLeaf.uEax, GuestLeaf.uEbx, GuestLeaf.uEcx, GuestLeaf.uEdx);
     4885            }
     4886            else
     4887            {
     4888                pHlp->pfnPrintf(pHlp,
     4889                                "Gst: %08x  %08x %08x %08x %08x%s\n"
     4890                                "Hst:           %08x %08x %08x %08x%s\n",
     4891                                i, GuestLeaf.uEax, GuestLeaf.uEbx, GuestLeaf.uEcx, GuestLeaf.uEdx,
     4892                                i <= cHyperGstMax ? "" : "*",
     4893                                Host.uEax, Host.uEbx, Host.uEcx, Host.uEdx, i <= cHyperHstMax ? "" : "*");
     4894            }
     4895        }
     4896    }
     4897
     4898    /*
     4899     * Centaur.
     4900     */
     4901    unsigned cCentaurMax = pVM->cpum.s.aGuestCpuIdPatmCentaur[0].uEax & 0xffff;
     4902
     4903    pHlp->pfnPrintf(pHlp,
     4904                    "\n"
     4905                    "         RAW Centaur CPUIDs\n"
     4906                    "     Function  eax      ebx      ecx      edx\n");
     4907    for (unsigned i = 0; i < RT_ELEMENTS(pVM->cpum.s.aGuestCpuIdPatmCentaur); i++)
     4908    {
     4909        Guest = pVM->cpum.s.aGuestCpuIdPatmCentaur[i];
     4910        ASMCpuIdExSlow(0xc0000000 | i, 0, 0, 0, &Host.uEax, &Host.uEbx, &Host.uEcx, &Host.uEdx);
     4911
     4912        pHlp->pfnPrintf(pHlp,
     4913                        "Gst: %08x  %08x %08x %08x %08x%s\n"
     4914                        "Hst:           %08x %08x %08x %08x\n",
     4915                        0xc0000000 | i, Guest.uEax, Guest.uEbx, Guest.uEcx, Guest.uEdx,
     4916                        i <= cCentaurMax ? "" : "*",
     4917                        Host.uEax, Host.uEbx, Host.uEcx, Host.uEdx);
     4918    }
     4919
     4920    /*
     4921     * Understandable output
     4922     */
     4923    if (iVerbosity)
     4924    {
     4925        Guest = pVM->cpum.s.aGuestCpuIdPatmCentaur[0];
     4926        pHlp->pfnPrintf(pHlp,
     4927                        "Centaur Supports:                0xc0000000-%#010x\n",
     4928                        Guest.uEax);
     4929    }
     4930
     4931    if (iVerbosity && cCentaurMax >= 1)
     4932    {
     4933        ASMCpuIdExSlow(0xc0000001, 0, 0, 0, &Host.uEax, &Host.uEbx, &Host.uEcx, &Host.uEdx);
     4934        uint32_t uEdxGst = pVM->cpum.s.aGuestCpuIdPatmCentaur[1].uEdx;
     4935        uint32_t uEdxHst = Host.uEdx;
     4936
     4937        if (iVerbosity == 1)
     4938        {
     4939            pHlp->pfnPrintf(pHlp, "Centaur Features EDX:           ");
     4940            if (uEdxGst & RT_BIT(0))   pHlp->pfnPrintf(pHlp, " AIS");
     4941            if (uEdxGst & RT_BIT(1))   pHlp->pfnPrintf(pHlp, " AIS-E");
     4942            if (uEdxGst & RT_BIT(2))   pHlp->pfnPrintf(pHlp, " RNG");
     4943            if (uEdxGst & RT_BIT(3))   pHlp->pfnPrintf(pHlp, " RNG-E");
     4944            if (uEdxGst & RT_BIT(4))   pHlp->pfnPrintf(pHlp, " LH");
     4945            if (uEdxGst & RT_BIT(5))   pHlp->pfnPrintf(pHlp, " FEMMS");
     4946            if (uEdxGst & RT_BIT(6))   pHlp->pfnPrintf(pHlp, " ACE");
     4947            if (uEdxGst & RT_BIT(7))   pHlp->pfnPrintf(pHlp, " ACE-E");
     4948            /* possibly indicating MM/HE and MM/HE-E on older chips... */
     4949            if (uEdxGst & RT_BIT(8))   pHlp->pfnPrintf(pHlp, " ACE2");
     4950            if (uEdxGst & RT_BIT(9))   pHlp->pfnPrintf(pHlp, " ACE2-E");
     4951            if (uEdxGst & RT_BIT(10))  pHlp->pfnPrintf(pHlp, " PHE");
     4952            if (uEdxGst & RT_BIT(11))  pHlp->pfnPrintf(pHlp, " PHE-E");
     4953            if (uEdxGst & RT_BIT(12))  pHlp->pfnPrintf(pHlp, " PMM");
     4954            if (uEdxGst & RT_BIT(13))  pHlp->pfnPrintf(pHlp, " PMM-E");
     4955            for (unsigned iBit = 14; iBit < 32; iBit++)
     4956                if (uEdxGst & RT_BIT(iBit))
     4957                    pHlp->pfnPrintf(pHlp, " %d", iBit);
     4958            pHlp->pfnPrintf(pHlp, "\n");
     4959        }
     4960        else
     4961        {
     4962            pHlp->pfnPrintf(pHlp, "Mnemonic - Description                 = guest (host)\n");
     4963            pHlp->pfnPrintf(pHlp, "AIS - Alternate Instruction Set        = %d (%d)\n",  !!(uEdxGst & RT_BIT( 0)),  !!(uEdxHst & RT_BIT( 0)));
     4964            pHlp->pfnPrintf(pHlp, "AIS-E - AIS enabled                    = %d (%d)\n",  !!(uEdxGst & RT_BIT( 1)),  !!(uEdxHst & RT_BIT( 1)));
     4965            pHlp->pfnPrintf(pHlp, "RNG - Random Number Generator          = %d (%d)\n",  !!(uEdxGst & RT_BIT( 2)),  !!(uEdxHst & RT_BIT( 2)));
     4966            pHlp->pfnPrintf(pHlp, "RNG-E - RNG enabled                    = %d (%d)\n",  !!(uEdxGst & RT_BIT( 3)),  !!(uEdxHst & RT_BIT( 3)));
     4967            pHlp->pfnPrintf(pHlp, "LH - LongHaul MSR 0000_110Ah           = %d (%d)\n",  !!(uEdxGst & RT_BIT( 4)),  !!(uEdxHst & RT_BIT( 4)));
     4968            pHlp->pfnPrintf(pHlp, "FEMMS - FEMMS                          = %d (%d)\n",  !!(uEdxGst & RT_BIT( 5)),  !!(uEdxHst & RT_BIT( 5)));
     4969            pHlp->pfnPrintf(pHlp, "ACE - Advanced Cryptography Engine     = %d (%d)\n",  !!(uEdxGst & RT_BIT( 6)),  !!(uEdxHst & RT_BIT( 6)));
     4970            pHlp->pfnPrintf(pHlp, "ACE-E - ACE enabled                    = %d (%d)\n",  !!(uEdxGst & RT_BIT( 7)),  !!(uEdxHst & RT_BIT( 7)));
     4971            /* possibly indicating MM/HE and MM/HE-E on older chips... */
     4972            pHlp->pfnPrintf(pHlp, "ACE2 - Advanced Cryptography Engine 2  = %d (%d)\n",  !!(uEdxGst & RT_BIT( 8)),  !!(uEdxHst & RT_BIT( 8)));
     4973            pHlp->pfnPrintf(pHlp, "ACE2-E - ACE enabled                   = %d (%d)\n",  !!(uEdxGst & RT_BIT( 9)),  !!(uEdxHst & RT_BIT( 9)));
     4974            pHlp->pfnPrintf(pHlp, "PHE - Padlock Hash Engine              = %d (%d)\n",  !!(uEdxGst & RT_BIT(10)),  !!(uEdxHst & RT_BIT(10)));
     4975            pHlp->pfnPrintf(pHlp, "PHE-E - PHE enabled                    = %d (%d)\n",  !!(uEdxGst & RT_BIT(11)),  !!(uEdxHst & RT_BIT(11)));
     4976            pHlp->pfnPrintf(pHlp, "PMM - Montgomery Multiplier            = %d (%d)\n",  !!(uEdxGst & RT_BIT(12)),  !!(uEdxHst & RT_BIT(12)));
     4977            pHlp->pfnPrintf(pHlp, "PMM-E - PMM enabled                    = %d (%d)\n",  !!(uEdxGst & RT_BIT(13)),  !!(uEdxHst & RT_BIT(13)));
     4978            pHlp->pfnPrintf(pHlp, "14 - Reserved                          = %d (%d)\n",  !!(uEdxGst & RT_BIT(14)),  !!(uEdxHst & RT_BIT(14)));
     4979            pHlp->pfnPrintf(pHlp, "15 - Reserved                          = %d (%d)\n",  !!(uEdxGst & RT_BIT(15)),  !!(uEdxHst & RT_BIT(15)));
     4980            pHlp->pfnPrintf(pHlp, "Parallax                               = %d (%d)\n",  !!(uEdxGst & RT_BIT(16)),  !!(uEdxHst & RT_BIT(16)));
     4981            pHlp->pfnPrintf(pHlp, "Parallax enabled                       = %d (%d)\n",  !!(uEdxGst & RT_BIT(17)),  !!(uEdxHst & RT_BIT(17)));
     4982            pHlp->pfnPrintf(pHlp, "Overstress                             = %d (%d)\n",  !!(uEdxGst & RT_BIT(18)),  !!(uEdxHst & RT_BIT(18)));
     4983            pHlp->pfnPrintf(pHlp, "Overstress enabled                     = %d (%d)\n",  !!(uEdxGst & RT_BIT(19)),  !!(uEdxHst & RT_BIT(19)));
     4984            pHlp->pfnPrintf(pHlp, "TM3 - Temperature Monitoring 3         = %d (%d)\n",  !!(uEdxGst & RT_BIT(20)),  !!(uEdxHst & RT_BIT(20)));
     4985            pHlp->pfnPrintf(pHlp, "TM3-E - TM3 enabled                    = %d (%d)\n",  !!(uEdxGst & RT_BIT(21)),  !!(uEdxHst & RT_BIT(21)));
     4986            pHlp->pfnPrintf(pHlp, "RNG2 - Random Number Generator 2       = %d (%d)\n",  !!(uEdxGst & RT_BIT(22)),  !!(uEdxHst & RT_BIT(22)));
     4987            pHlp->pfnPrintf(pHlp, "RNG2-E - RNG2 enabled                  = %d (%d)\n",  !!(uEdxGst & RT_BIT(23)),  !!(uEdxHst & RT_BIT(23)));
     4988            pHlp->pfnPrintf(pHlp, "24 - Reserved                          = %d (%d)\n",  !!(uEdxGst & RT_BIT(24)),  !!(uEdxHst & RT_BIT(24)));
     4989            pHlp->pfnPrintf(pHlp, "PHE2 - Padlock Hash Engine 2           = %d (%d)\n",  !!(uEdxGst & RT_BIT(25)),  !!(uEdxHst & RT_BIT(25)));
     4990            pHlp->pfnPrintf(pHlp, "PHE2-E - PHE2 enabled                  = %d (%d)\n",  !!(uEdxGst & RT_BIT(26)),  !!(uEdxHst & RT_BIT(26)));
     4991            for (unsigned iBit = 27; iBit < 32; iBit++)
     4992                if ((uEdxGst | uEdxHst) & RT_BIT(iBit))
     4993                    pHlp->pfnPrintf(pHlp, "Bit %d                                 = %d (%d)\n", iBit, !!(uEdxGst & RT_BIT(iBit)), !!(uEdxHst & RT_BIT(iBit)));
     4994            pHlp->pfnPrintf(pHlp, "\n");
     4995        }
     4996    }
     4997}
     4998
     4999
     5000
     5001
     5002
     5003/*
     5004 *
     5005 *
     5006 * PATM interfaces.
     5007 * PATM interfaces.
     5008 * PATM interfaces.
     5009 *
     5010 *
     5011 */
    33405012
    33415013
     
    33545026VMMR3_INT_DECL(RCPTRTYPE(PCCPUMCPUID)) CPUMR3GetGuestCpuIdPatmDefRCPtr(PVM pVM)
    33555027{
    3356     return (RCPTRTYPE(PCCPUMCPUID))VM_RC_ADDR(pVM, &pVM->cpum.s.GuestCpuIdPatmDef);
     5028    return (RCPTRTYPE(PCCPUMCPUID))VM_RC_ADDR(pVM, &pVM->cpum.s.GuestInfo.DefCpuId);
    33575029}
    33585030
     
    33945066 * @remark  Intended for PATM only.
    33955067 */
    3396 VMMR3_INT_DECL(CPUMUKNOWNCPUID) CPUMR3GetGuestCpuIdPatmUnknownLeafMethod(PVM pVM)
     5068VMMR3_INT_DECL(CPUMUNKNOWNCPUID) CPUMR3GetGuestCpuIdPatmUnknownLeafMethod(PVM pVM)
    33975069{
    33985070    return pVM->cpum.s.GuestInfo.enmUnknownCpuIdMethod;
     
    34025074
    34035075/**
    3404  * Gets a number of standard CPUID leafs (PATM only).
    3405  *
    3406  * @returns Number of leafs.
     5076 * Gets a number of standard CPUID leaves (PATM only).
     5077 *
     5078 * @returns Number of leaves.
    34075079 * @param   pVM         Pointer to the VM.
    34085080 * @remark  Intended for PATM - legacy, don't use in new code.
     
    34155087
    34165088/**
    3417  * Gets a number of extended CPUID leafs (PATM only).
    3418  *
    3419  * @returns Number of leafs.
     5089 * Gets a number of extended CPUID leaves (PATM only).
     5090 *
     5091 * @returns Number of leaves.
    34205092 * @param   pVM         Pointer to the VM.
    34215093 * @remark  Intended for PATM - legacy, don't use in new code.
     
    34285100
    34295101/**
    3430  * Gets a number of centaur CPUID leafs.
    3431  *
    3432  * @returns Number of leafs.
     5102 * Gets a number of centaur CPUID leaves.
     5103 *
     5104 * @returns Number of leaves.
    34335105 * @param   pVM         Pointer to the VM.
    34345106 * @remark  Intended for PATM - legacy, don't use in new code.
  • trunk/src/VBox/VMM/VMMR3/CPUMR3Db.cpp

    r54674 r54737  
    6262    uint32_t        cCpuIdLeaves;
    6363    /** The method used to deal with unknown CPUID leaves. */
    64     CPUMUKNOWNCPUID enmUnknownCpuId;
     64    CPUMUNKNOWNCPUID enmUnknownCpuId;
    6565    /** The default unknown CPUID value. */
    6666    CPUMCPUID       DefUnknownCpuId;
  • trunk/src/VBox/VMM/VMMR3/EM.cpp

    r51987 r54737  
    14071407        uint32_t u32Dummy, u32Features;
    14081408
    1409         CPUMGetGuestCpuId(pVCpu, 1, &u32Dummy, &u32Dummy, &u32Dummy, &u32Features);
     1409        CPUMGetGuestCpuId(pVCpu, 1, 0, &u32Dummy, &u32Dummy, &u32Dummy, &u32Features);
    14101410        if (!(u32Features & X86_CPUID_FEATURE_EDX_PAE))
    14111411            return EMSTATE_REM;
  • trunk/src/VBox/VMM/VMMR3/EMRaw.cpp

    r47823 r54737  
    635635        {
    636636            uint32_t u32Dummy, u32Features, u32ExtFeatures;
    637             CPUMGetGuestCpuId(pVCpu, 1, &u32Dummy, &u32Dummy, &u32ExtFeatures, &u32Features);
     637            CPUMGetGuestCpuId(pVCpu, 1, 0, &u32Dummy, &u32Dummy, &u32ExtFeatures, &u32Features);
    638638            if (u32ExtFeatures & X86_CPUID_FEATURE_ECX_MONITOR)
    639639            {
  • trunk/src/VBox/VMM/VMMR3/GIMMinimal.cpp

    r54701 r54737  
    8181
    8282        /*
     83         * Insert missing zero leaves (you never know what missing leaves are
     84         * going to return when read).
     85         */
     86        for (uint32_t uLeaf = UINT32_C(0x40000001); uLeaf < UINT32_C(0x40000010); uLeaf++)
     87        {
     88            rc = CPUMR3CpuIdGetLeaf(pVM, &HyperLeaf, uLeaf, 0 /* uSubLeaf */);
     89            if (RT_FAILURE(rc))
     90            {
     91                RT_ZERO(HyperLeaf);
     92                HyperLeaf.uLeaf = uLeaf;
     93                rc = CPUMR3CpuIdInsert(pVM, &HyperLeaf);
     94                AssertLogRelRCReturn(rc, rc);
     95            }
     96        }
     97
     98        /*
    8399         * Add the timing information hypervisor leaf.
    84100         * MacOS X uses this to determine the TSC, bus frequency. See @bugref{7270}.
  • trunk/src/VBox/VMM/VMMR3/IEMR3.cpp

    r48266 r54737  
    7272        {
    7373            uint32_t uIgnored;
    74             CPUMGetGuestCpuId(pVCpu, 1, &uIgnored, &uIgnored,
     74            CPUMGetGuestCpuId(pVCpu, 1, 0, &uIgnored, &uIgnored,
    7575                              &pVCpu->iem.s.fCpuIdStdFeaturesEcx, &pVCpu->iem.s.fCpuIdStdFeaturesEdx);
    7676            pVCpu->iem.s.enmCpuVendor             = CPUMGetGuestCpuVendor(pVM);
  • trunk/src/VBox/VMM/VMMR3/MMHyper.cpp

    r51271 r54737  
    14431443 * @returns VBox status code.
    14441444 * @param   pVM             Pointer to the VM.
    1445  * @param   pvOld           The existing block of memory in the
    1446  *                          hyper heap to re-allocate (can be
    1447  *                          NULL).
     1445 * @param   pvOld           The existing block of memory in the hyper heap to
     1446 *                          re-allocate (can be NULL).
    14481447 * @param   cbOld           Size of the existing block.
    1449  * @param   uAlignmentNew   Required memory alignment in bytes.
    1450  *                          Values are 0,8,16,32 and PAGE_SIZE.
    1451  *                          0 -> default alignment, i.e. 8 bytes.
     1448 * @param   uAlignmentNew   Required memory alignment in bytes. Values are
     1449 *                          0,8,16,32 and PAGE_SIZE. 0 -> default alignment,
     1450 *                          i.e. 8 bytes.
    14521451 * @param   enmTagNew       The statistics tag.
    14531452 * @param   cbNew           The required size of the new block.
    1454  * @param   ppv             Where to store the address to the
    1455  *                          re-allocated block.
    1456  *
    1457  * @remarks This does not work like normal realloc()
    1458  *          on failure, the memory pointed to by @a pvOld is
    1459  *          lost if there isn't sufficient space on the hyper
    1460  *          heap for the re-allocation to succeed.
     1453 * @param   ppv             Where to store the address to the re-allocated
     1454 *                          block.
     1455 *
     1456 * @remarks This does not work like normal realloc() on failure, the memory
     1457 *          pointed to by @a pvOld is lost if there isn't sufficient space on
     1458 *          the hyper heap for the re-allocation to succeed.
    14611459*/
    14621460VMMR3DECL(int) MMR3HyperRealloc(PVM pVM, void *pvOld, size_t cbOld, unsigned uAlignmentNew, MMTAG enmTagNew, size_t cbNew,
  • trunk/src/VBox/VMM/VMMR3/PATMA.asm

    r54714 r54737  
    17841784   
    17851785    ;
    1786     ; Out of range sub-leafs aren't quite as easy and pretty as we emulate them
     1786    ; Out of range sub-leaves aren't quite as easy and pretty as we emulate them
    17871787    ; here, but we do an adequate job.
    17881788    ;   
    17891789cpuid_subleaf_not_found:
     1790    xor     ecx, ecx
     1791    test    dword [ss:ebx + CPUMCPUIDLEAF.fFlags], CPUMCPUIDLEAF_F_INTEL_TOPOLOGY_SUBLEAVES
     1792    jz      cpuid_load_zeros_except_ecx
    17901793    mov     ecx, [esp + 4]
    1791     test    dword [ss:ebx + CPUMCPUIDLEAF.fFlags], CPUMCPUIDLEAF_F_SUBLEAVES_ECX_UNCHANGED
    1792     jnz     cpuid_load_zeros_except_ecx
    1793 cpuid_load_zeros:
    1794     xor     ecx, ecx
     1794    and     ecx, 0ffh
    17951795cpuid_load_zeros_except_ecx:
    17961796    xor     edx, edx
     
    18051805    mov     edx, PATM_CPUID_UNKNOWN_METHOD
    18061806PATCH_FIXUP PATM_CPUID_UNKNOWN_METHOD
    1807     cmp     edx, CPUMUKNOWNCPUID_PASSTHRU
     1807    cmp     edx, CPUMUNKNOWNCPUID_PASSTHRU
    18081808    je      cpuid_unknown_passthru
    18091809    ; Load the default cpuid leaf.
  • trunk/src/VBox/VMM/VMMR3/PATMSSM.cpp

    r54714 r54737  
    12541254         * 2. That the forced actions were in the first 32 bytes of the VM
    12551255         *    structure.
    1256          * 3. That the CPUM leafs are less than 8KB into the structure.
     1256         * 3. That the CPUM leaves are less than 8KB into the structure.
    12571257         */
    12581258        else if (   uVersion <= PATM_SAVED_STATE_VERSION_FIXUP_HACK
  • trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp

    r53797 r54737  
    34543454    AssertPtr(pEax); AssertPtr(pEbx); AssertPtr(pEcx); AssertPtr(pEdx);
    34553455
    3456     CPUMGetGuestCpuId(VMMGetCpu(pDevIns->Internal.s.pVMR3), iLeaf, pEax, pEbx, pEcx, pEdx);
     3456    CPUMGetGuestCpuId(VMMGetCpu(pDevIns->Internal.s.pVMR3), iLeaf, 0 /*iSubLeaf*/, pEax, pEbx, pEcx, pEdx);
    34573457
    34583458    LogFlow(("pdmR3DevHlp_GetCpuId: caller='%s'/%d: returns void - *pEax=%#x *pEbx=%#x *pEcx=%#x *pEdx=%#x\n",
  • trunk/src/VBox/VMM/VMMR3/PGM.cpp

    r49893 r54737  
    22142214     */
    22152215    uint32_t u32Dummy, u32Features;
    2216     CPUMGetGuestCpuId(VMMGetCpu(pVM), 1, &u32Dummy, &u32Dummy, &u32Dummy, &u32Features);
     2216    CPUMGetGuestCpuId(VMMGetCpu(pVM), 1, 0, &u32Dummy, &u32Dummy, &u32Dummy, &u32Features);
    22172217    if (u32Features & X86_CPUID_FEATURE_EDX_PSE36)
    22182218        pVM->pgm.s.GCPhys4MBPSEMask = RT_BIT_64(RT_MAX(36, cMaxPhysAddrWidth)) - 1;
     
    35783578            uint32_t u32Dummy, u32Features;
    35793579
    3580             CPUMGetGuestCpuId(pVCpu, 1, &u32Dummy, &u32Dummy, &u32Dummy, &u32Features);
     3580            CPUMGetGuestCpuId(pVCpu, 1, 0, &u32Dummy, &u32Dummy, &u32Dummy, &u32Features);
    35813581            if (!(u32Features & X86_CPUID_FEATURE_EDX_PAE))
    35823582                return VMSetRuntimeError(pVM, VMSETRTERR_FLAGS_FATAL, "PAEmode",
  • trunk/src/VBox/VMM/VMMR3/VMM.cpp

    r53466 r54737  
    711711
    712712            /*
    713              * Last chance for GIM to update its CPUID leafs if it requires knowledge/information
    714              * from HM initialization.
     713             * Last chance for GIM to update its CPUID leaves if it requires
     714             * knowledge/information from HM initialization.
    715715             */
    716716            rc = GIMR3InitCompleted(pVM);
  • trunk/src/VBox/VMM/VMMR3/cpus/AMD_Athlon_64_3200.h

    r53624 r54737  
    66
    77/*
    8  * Copyright (C) 2013 Oracle Corporation
     8 * Copyright (C) 2013-2015 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2828{
    2929    { 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x68747541, 0x444d4163, 0x69746e65, 0 },
    30     { 0x00000001, 0x00000000, 0x00000000, 0x00000f48, 0x00000800, 0x00000000, 0x078bfbff, 0 },
     30    { 0x00000001, 0x00000000, 0x00000000, 0x00000f48, 0x00000800, 0x00000000, 0x078bfbff, 0 | CPUMCPUIDLEAF_F_CONTAINS_APIC_ID },
    3131    { 0x80000000, 0x00000000, 0x00000000, 0x80000018, 0x68747541, 0x444d4163, 0x69746e65, 0 },
    3232    { 0x80000001, 0x00000000, 0x00000000, 0x00000f48, 0x0000010a, 0x00000000, 0xe1d3fbff, 0 },
     
    210210    /*.paCpuIdLeaves    = */ NULL_ALONE(g_aCpuIdLeaves_AMD_Athlon_64_3200),
    211211    /*.cCpuIdLeaves     = */ ZERO_ALONE(RT_ELEMENTS(g_aCpuIdLeaves_AMD_Athlon_64_3200)),
    212     /*.enmUnknownCpuId  = */ CPUMUKNOWNCPUID_DEFAULTS,
     212    /*.enmUnknownCpuId  = */ CPUMUNKNOWNCPUID_DEFAULTS,
    213213    /*.DefUnknownCpuId  = */ { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    214214    /*.fMsrMask         = */ UINT32_MAX,
  • trunk/src/VBox/VMM/VMMR3/cpus/AMD_Athlon_64_X2_Dual_Core_4200.h

    r51234 r54737  
    1111
    1212/*
    13  * Copyright (C) 2013 Oracle Corporation
     13 * Copyright (C) 2013-2015 Oracle Corporation
    1414 *
    1515 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    3333{
    3434    { 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x68747541, 0x444d4163, 0x69746e65, 0 },
    35     { 0x00000001, 0x00000000, 0x00000000, 0x00040fb2, 0x01020800, 0x00002001, 0x178bfbff, 0 },
     35    { 0x00000001, 0x00000000, 0x00000000, 0x00040fb2, 0x01020800, 0x00002001, 0x178bfbff, 0 | CPUMCPUIDLEAF_F_CONTAINS_APIC_ID },
    3636    { 0x80000000, 0x00000000, 0x00000000, 0x80000018, 0x68747541, 0x444d4163, 0x69746e65, 0 },
    3737    { 0x80000001, 0x00000000, 0x00000000, 0x00040fb2, 0x000008d1, 0x0000001f, 0xebd3fbff, 0 },
     
    218218    /*.paCpuIdLeaves    = */ NULL_ALONE(g_aCpuIdLeaves_AMD_Athlon_64_X2_Dual_Core_4200),
    219219    /*.cCpuIdLeaves     = */ ZERO_ALONE(RT_ELEMENTS(g_aCpuIdLeaves_AMD_Athlon_64_X2_Dual_Core_4200)),
    220     /*.enmUnknownCpuId  = */ CPUMUKNOWNCPUID_DEFAULTS,
     220    /*.enmUnknownCpuId  = */ CPUMUNKNOWNCPUID_DEFAULTS,
    221221    /*.DefUnknownCpuId  = */ { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    222222    /*.fMsrMask         = */ UINT32_MAX,
  • trunk/src/VBox/VMM/VMMR3/cpus/AMD_FX_8150_Eight_Core.h

    r53624 r54737  
    66
    77/*
    8  * Copyright (C) 2013 Oracle Corporation
     8 * Copyright (C) 2013-2015 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2828{
    2929    { 0x00000000, 0x00000000, 0x00000000, 0x0000000d, 0x68747541, 0x444d4163, 0x69746e65, 0 },
    30     { 0x00000001, 0x00000000, 0x00000000, 0x00600f12, 0x02080800, 0x1e98220b, 0x178bfbff, 0 },
     30    { 0x00000001, 0x00000000, 0x00000000, 0x00600f12, 0x02080800, 0x1e98220b, 0x178bfbff, 0 | CPUMCPUIDLEAF_F_CONTAINS_APIC_ID },
    3131    { 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0 },
    3232    { 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0 },
     
    7676    { 0x8000001d, 0x00000003, UINT32_MAX, 0x0001c163, 0x0fc0003f, 0x000007ff, 0x00000001, 0 },
    7777    { 0x8000001d, 0x00000004, UINT32_MAX, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0 },
    78     { 0x8000001e, 0x00000000, 0x00000000, 0x00000012, 0x00000101, 0x00000000, 0x00000000, 0 },
     78    { 0x8000001e, 0x00000000, 0x00000000, 0x00000012, 0x00000101, 0x00000000, 0x00000000, 0 | CPUMCPUIDLEAF_F_CONTAINS_APIC_ID },
    7979};
    8080#endif /* !CPUM_DB_STANDALONE */
     
    369369    /*.paCpuIdLeaves    = */ NULL_ALONE(g_aCpuIdLeaves_AMD_FX_8150_Eight_Core),
    370370    /*.cCpuIdLeaves     = */ ZERO_ALONE(RT_ELEMENTS(g_aCpuIdLeaves_AMD_FX_8150_Eight_Core)),
    371     /*.enmUnknownCpuId  = */ CPUMUKNOWNCPUID_DEFAULTS,
     371    /*.enmUnknownCpuId  = */ CPUMUNKNOWNCPUID_DEFAULTS,
    372372    /*.DefUnknownCpuId  = */ { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    373373    /*.fMsrMask         = */ UINT32_MAX,
  • trunk/src/VBox/VMM/VMMR3/cpus/AMD_Phenom_II_X6_1100T.h

    r53624 r54737  
    66
    77/*
    8  * Copyright (C) 2013 Oracle Corporation
     8 * Copyright (C) 2013-2015 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2828{
    2929    { 0x00000000, 0x00000000, 0x00000000, 0x00000006, 0x68747541, 0x444d4163, 0x69746e65, 0 },
    30     { 0x00000001, 0x00000000, 0x00000000, 0x00100fa0, 0x01060800, 0x00802009, 0x178bfbff, 0 },
     30    { 0x00000001, 0x00000000, 0x00000000, 0x00100fa0, 0x01060800, 0x00802009, 0x178bfbff, 0 | CPUMCPUIDLEAF_F_CONTAINS_APIC_ID },
    3131    { 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0 },
    3232    { 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0 },
     
    258258    /*.paCpuIdLeaves    = */ NULL_ALONE(g_aCpuIdLeaves_AMD_Phenom_II_X6_1100T),
    259259    /*.cCpuIdLeaves     = */ ZERO_ALONE(RT_ELEMENTS(g_aCpuIdLeaves_AMD_Phenom_II_X6_1100T)),
    260     /*.enmUnknownCpuId  = */ CPUMUKNOWNCPUID_DEFAULTS,
     260    /*.enmUnknownCpuId  = */ CPUMUNKNOWNCPUID_DEFAULTS,
    261261    /*.DefUnknownCpuId  = */ { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    262262    /*.fMsrMask         = */ UINT32_MAX,
  • trunk/src/VBox/VMM/VMMR3/cpus/Intel_Core_i5_3570.h

    r53624 r54737  
    66
    77/*
    8  * Copyright (C) 2013 Oracle Corporation
     8 * Copyright (C) 2013-2015 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2828{
    2929    { 0x00000000, 0x00000000, 0x00000000, 0x0000000d, 0x756e6547, 0x6c65746e, 0x49656e69, 0 },
    30     { 0x00000001, 0x00000000, 0x00000000, 0x000306a9, 0x04100800, 0x7fbae3ff, 0xbfebfbff, 0 },
     30    { 0x00000001, 0x00000000, 0x00000000, 0x000306a9, 0x04100800, 0x7fbae3ff, 0xbfebfbff, 0 | CPUMCPUIDLEAF_F_CONTAINS_APIC_ID },
    3131    { 0x00000002, 0x00000000, 0x00000000, 0x76035a01, 0x00f0b0ff, 0x00000000, 0x00ca0000, 0 },
    3232    { 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0 },
     
    3838    { 0x00000009, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0 },
    3939    { 0x0000000a, 0x00000000, 0x00000000, 0x07300803, 0x00000000, 0x00000000, 0x00000603, 0 },
    40     { 0x0000000b, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000100, 0x00000004, 0 },
     40    { 0x0000000b, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000100, 0x00000004, 0 | CPUMCPUIDLEAF_F_CONTAINS_APIC_ID },
    4141    { 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0 },
    4242    { 0x0000000d, 0x00000000, 0x00000000, 0x00000007, 0x00000340, 0x00000340, 0x00000000, 0 },
     
    325325    /*.paCpuIdLeaves    = */ NULL_ALONE(g_aCpuIdLeaves_Intel_Core_i5_3570),
    326326    /*.cCpuIdLeaves     = */ ZERO_ALONE(RT_ELEMENTS(g_aCpuIdLeaves_Intel_Core_i5_3570)),
    327     /*.enmUnknownCpuId  = */ CPUMUKNOWNCPUID_LAST_STD_LEAF_WITH_ECX,
     327    /*.enmUnknownCpuId  = */ CPUMUNKNOWNCPUID_LAST_STD_LEAF_WITH_ECX,
    328328    /*.DefUnknownCpuId  = */ { 0x00000007, 0x00000340, 0x00000340, 0x00000000 },
    329329    /*.fMsrMask         = */ UINT32_MAX,
  • trunk/src/VBox/VMM/VMMR3/cpus/Intel_Core_i7_2635QM.h

    r53624 r54737  
    66
    77/*
    8  * Copyright (C) 2013 Oracle Corporation
     8 * Copyright (C) 2013-2015 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2828{
    2929    { 0x00000000, 0x00000000, 0x00000000, 0x0000000d, 0x756e6547, 0x6c65746e, 0x49656e69, 0 },
    30     { 0x00000001, 0x00000000, 0x00000000, 0x000206a7, 0x04100800, 0x1fbae3bf, 0xbfebfbff, 0 },
     30    { 0x00000001, 0x00000000, 0x00000000, 0x000206a7, 0x04100800, 0x1fbae3bf, 0xbfebfbff, 0 | CPUMCPUIDLEAF_F_CONTAINS_APIC_ID },
    3131    { 0x00000002, 0x00000000, 0x00000000, 0x76035a01, 0x00f0b2ff, 0x00000000, 0x00ca0000, 0 },
    3232    { 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0 },
     
    4242    { 0x00000009, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0 },
    4343    { 0x0000000a, 0x00000000, 0x00000000, 0x07300403, 0x00000000, 0x00000000, 0x00000603, 0 },
     44    /** @todo the b entry here is WRONG!   */
     45    { 0x0000000b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0 | CPUMCPUIDLEAF_F_INTEL_TOPOLOGY_SUBLEAVES | CPUMCPUIDLEAF_F_CONTAINS_APIC_ID },
    4446    { 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0 },
    4547    { 0x0000000d, 0x00000000, UINT32_MAX, 0x00000007, 0x00000340, 0x00000340, 0x00000000, 0 },
     
    316318    /*.paCpuIdLeaves    = */ NULL_ALONE(g_aCpuIdLeaves_Intel_Core_i7_2635QM),
    317319    /*.cCpuIdLeaves     = */ ZERO_ALONE(RT_ELEMENTS(g_aCpuIdLeaves_Intel_Core_i7_2635QM)),
    318     /*.enmUnknownCpuId  = */ CPUMUKNOWNCPUID_LAST_STD_LEAF_WITH_ECX,
     320    /*.enmUnknownCpuId  = */ CPUMUNKNOWNCPUID_LAST_STD_LEAF_WITH_ECX,
    319321    /*.DefUnknownCpuId  = */ { 0x00000007, 0x00000340, 0x00000340, 0x00000000 },
    320322    /*.fMsrMask         = */ UINT32_MAX,
  • trunk/src/VBox/VMM/VMMR3/cpus/Intel_Core_i7_3820QM.h

    r53624 r54737  
    66
    77/*
    8  * Copyright (C) 2013 Oracle Corporation
     8 * Copyright (C) 2013-2015 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2828{
    2929    { 0x00000000, 0x00000000, 0x00000000, 0x0000000d, 0x756e6547, 0x6c65746e, 0x49656e69, 0 },
    30     { 0x00000001, 0x00000000, 0x00000000, 0x000306a9, 0x02100800, 0x7fbae3ff, 0xbfebfbff, 0 },
     30    { 0x00000001, 0x00000000, 0x00000000, 0x000306a9, 0x02100800, 0x7fbae3ff, 0xbfebfbff, 0 | CPUMCPUIDLEAF_F_CONTAINS_APIC_ID },
    3131    { 0x00000002, 0x00000000, 0x00000000, 0x76035a01, 0x00f0b2ff, 0x00000000, 0x00ca0000, 0 },
    3232    { 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0 },
     
    3838    { 0x00000009, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0 },
    3939    { 0x0000000a, 0x00000000, 0x00000000, 0x07300403, 0x00000000, 0x00000000, 0x00000603, 0 },
    40     { 0x0000000b, 0x00000000, 0x00000000, 0x00000001, 0x00000002, 0x00000100, 0x00000002, 0 },
     40    { 0x0000000b, 0x00000000, 0x00000000, 0x00000001, 0x00000002, 0x00000100, 0x00000002, 0 | CPUMCPUIDLEAF_F_INTEL_TOPOLOGY_SUBLEAVES | CPUMCPUIDLEAF_F_CONTAINS_APIC_ID },
    4141    { 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0 },
    4242    { 0x0000000d, 0x00000000, 0x00000000, 0x00000007, 0x00000340, 0x00000340, 0x00000000, 0 },
     
    367367    /*.paCpuIdLeaves    = */ NULL_ALONE(g_aCpuIdLeaves_Intel_Core_i7_3820QM),
    368368    /*.cCpuIdLeaves     = */ ZERO_ALONE(RT_ELEMENTS(g_aCpuIdLeaves_Intel_Core_i7_3820QM)),
    369     /*.enmUnknownCpuId  = */ CPUMUKNOWNCPUID_LAST_STD_LEAF_WITH_ECX,
     369    /*.enmUnknownCpuId  = */ CPUMUNKNOWNCPUID_LAST_STD_LEAF_WITH_ECX,
    370370    /*.DefUnknownCpuId  = */ { 0x00000007, 0x00000340, 0x00000340, 0x00000000 },
    371371    /*.fMsrMask         = */ UINT32_MAX,
  • trunk/src/VBox/VMM/VMMR3/cpus/Intel_Core_i7_3960X.h

    r53624 r54737  
    66
    77/*
    8  * Copyright (C) 2013 Oracle Corporation
     8 * Copyright (C) 2013-2015 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2828{
    2929    { 0x00000000, 0x00000000, 0x00000000, 0x0000000d, 0x756e6547, 0x6c65746e, 0x49656e69, 0 },
    30     { 0x00000001, 0x00000000, 0x00000000, 0x000206d6, 0x02200800, 0x1fbee3bf, 0xbfebfbff, 0 },
     30    { 0x00000001, 0x00000000, 0x00000000, 0x000206d6, 0x02200800, 0x1fbee3bf, 0xbfebfbff, 0 | CPUMCPUIDLEAF_F_CONTAINS_APIC_ID },
    3131    { 0x00000002, 0x00000000, 0x00000000, 0x76035a01, 0x00f0b2ff, 0x00000000, 0x00ca0000, 0 },
    3232    { 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0 },
     
    4242    { 0x00000009, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0 },
    4343    { 0x0000000a, 0x00000000, 0x00000000, 0x07300403, 0x00000000, 0x00000000, 0x00000603, 0 },
    44     { 0x0000000b, 0x00000000, UINT32_MAX, 0x00000001, 0x00000002, 0x00000100, 0x00000002, 0 },
    45     { 0x0000000b, 0x00000001, UINT32_MAX, 0x00000005, 0x0000000c, 0x00000201, 0x00000002, 0 },
    46     { 0x0000000b, 0x00000002, UINT32_MAX, 0x00000000, 0x00000000, 0x00000002, 0x00000002, 0 | CPUMCPUIDLEAF_F_SUBLEAVES_ECX_UNCHANGED },
     44    { 0x0000000b, 0x00000000, UINT32_MAX, 0x00000001, 0x00000002, 0x00000100, 0x00000002, 0 | CPUMCPUIDLEAF_F_INTEL_TOPOLOGY_SUBLEAVES | CPUMCPUIDLEAF_F_CONTAINS_APIC_ID },
     45    { 0x0000000b, 0x00000001, UINT32_MAX, 0x00000005, 0x0000000c, 0x00000201, 0x00000002, 0 | CPUMCPUIDLEAF_F_INTEL_TOPOLOGY_SUBLEAVES | CPUMCPUIDLEAF_F_CONTAINS_APIC_ID },
     46    { 0x0000000b, 0x00000002, UINT32_MAX, 0x00000000, 0x00000000, 0x00000002, 0x00000002, 0 | CPUMCPUIDLEAF_F_INTEL_TOPOLOGY_SUBLEAVES | CPUMCPUIDLEAF_F_CONTAINS_APIC_ID },
    4747    { 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0 },
    4848    { 0x0000000d, 0x00000000, UINT32_MAX, 0x00000007, 0x00000340, 0x00000340, 0x00000000, 0 },
     
    355355    /*.paCpuIdLeaves    = */ NULL_ALONE(g_aCpuIdLeaves_Intel_Core_i7_3960X),
    356356    /*.cCpuIdLeaves     = */ ZERO_ALONE(RT_ELEMENTS(g_aCpuIdLeaves_Intel_Core_i7_3960X)),
    357     /*.enmUnknownCpuId  = */ CPUMUKNOWNCPUID_LAST_STD_LEAF_WITH_ECX,
     357    /*.enmUnknownCpuId  = */ CPUMUNKNOWNCPUID_LAST_STD_LEAF_WITH_ECX,
    358358    /*.DefUnknownCpuId  = */ { 0x00000007, 0x00000340, 0x00000340, 0x00000000 },
    359359    /*.fMsrMask         = */ UINT32_MAX,
  • trunk/src/VBox/VMM/VMMR3/cpus/Intel_Pentium_4_3_00GHz.h

    r53624 r54737  
    66
    77/*
    8  * Copyright (C) 2013 Oracle Corporation
     8 * Copyright (C) 2013-2015 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2828{
    2929    { 0x00000000, 0x00000000, 0x00000000, 0x00000005, 0x756e6547, 0x6c65746e, 0x49656e69, 0 },
    30     { 0x00000001, 0x00000000, 0x00000000, 0x00000f43, 0x00020800, 0x0000649d, 0xbfebfbff, 0 },
     30    { 0x00000001, 0x00000000, 0x00000000, 0x00000f43, 0x00020800, 0x0000649d, 0xbfebfbff, 0 | CPUMCPUIDLEAF_F_CONTAINS_APIC_ID },
    3131    { 0x00000002, 0x00000000, 0x00000000, 0x605b5001, 0x00000000, 0x00000000, 0x007d7040, 0 },
    3232    { 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0 },
     
    263263    /*.paCpuIdLeaves    = */ NULL_ALONE(g_aCpuIdLeaves_Intel_Pentium_4_3_00GHz),
    264264    /*.cCpuIdLeaves     = */ ZERO_ALONE(RT_ELEMENTS(g_aCpuIdLeaves_Intel_Pentium_4_3_00GHz)),
    265     /*.enmUnknownCpuId  = */ CPUMUKNOWNCPUID_LAST_STD_LEAF,
     265    /*.enmUnknownCpuId  = */ CPUMUNKNOWNCPUID_LAST_STD_LEAF,
    266266    /*.DefUnknownCpuId  = */ { 0x00000040, 0x00000040, 0x00000000, 0x00000000 },
    267267    /*.fMsrMask         = */ UINT32_MAX,
  • trunk/src/VBox/VMM/VMMR3/cpus/Intel_Pentium_M_processor_2_00GHz.h

    r53624 r54737  
    66
    77/*
    8  * Copyright (C) 2013 Oracle Corporation
     8 * Copyright (C) 2013-2015 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2828{
    2929    { 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x756e6547, 0x6c65746e, 0x49656e69, 0 },
    30     { 0x00000001, 0x00000000, 0x00000000, 0x000006d6, 0x00000816, 0x00000180, 0xafe9f9bf, 0 },
     30    { 0x00000001, 0x00000000, 0x00000000, 0x000006d6, 0x00000816, 0x00000180, 0xafe9f9bf, 0 | CPUMCPUIDLEAF_F_CONTAINS_APIC_ID },
    3131    { 0x00000002, 0x00000000, 0x00000000, 0x02b3b001, 0x000000f0, 0x00000000, 0x2c04307d, 0 },
    3232    { 0x80000000, 0x00000000, 0x00000000, 0x80000004, 0x00000000, 0x00000000, 0x00000000, 0 },
     
    202202    /*.paCpuIdLeaves    = */ NULL_ALONE(g_aCpuIdLeaves_Intel_Pentium_M_processor_2_00GHz),
    203203    /*.cCpuIdLeaves     = */ ZERO_ALONE(RT_ELEMENTS(g_aCpuIdLeaves_Intel_Pentium_M_processor_2_00GHz)),
    204     /*.enmUnknownCpuId  = */ CPUMUKNOWNCPUID_LAST_STD_LEAF,
     204    /*.enmUnknownCpuId  = */ CPUMUNKNOWNCPUID_LAST_STD_LEAF,
    205205    /*.DefUnknownCpuId  = */ { 0x02b3b001, 0x000000f0, 0x00000000, 0x2c04307d },
    206206    /*.fMsrMask         = */ UINT32_C(0x3fff),
  • trunk/src/VBox/VMM/VMMR3/cpus/Intel_Xeon_X5482_3_20GHz.h

    r53624 r54737  
    66
    77/*
    8  * Copyright (C) 2013 Oracle Corporation
     8 * Copyright (C) 2013-2015 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2828{
    2929    { 0x00000000, 0x00000000, 0x00000000, 0x0000000a, 0x756e6547, 0x6c65746e, 0x49656e69, 0 },
    30     { 0x00000001, 0x00000000, 0x00000000, 0x00010676, 0x04040800, 0x000ce3bd, 0xbfebfbff, 0 },
     30    { 0x00000001, 0x00000000, 0x00000000, 0x00010676, 0x04040800, 0x000ce3bd, 0xbfebfbff, 0 | CPUMCPUIDLEAF_F_CONTAINS_APIC_ID },
    3131    { 0x00000002, 0x00000000, 0x00000000, 0x05b0b101, 0x005657f0, 0x00000000, 0x2cb4304e, 0 },
    3232    { 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0 },
     
    231231    /*.paCpuIdLeaves    = */ NULL_ALONE(g_aCpuIdLeaves_Intel_Xeon_X5482_3_20GHz),
    232232    /*.cCpuIdLeaves     = */ ZERO_ALONE(RT_ELEMENTS(g_aCpuIdLeaves_Intel_Xeon_X5482_3_20GHz)),
    233     /*.enmUnknownCpuId  = */ CPUMUKNOWNCPUID_LAST_STD_LEAF,
     233    /*.enmUnknownCpuId  = */ CPUMUNKNOWNCPUID_LAST_STD_LEAF,
    234234    /*.DefUnknownCpuId  = */ { 0x07280202, 0x00000000, 0x00000000, 0x00000503 },
    235235    /*.fMsrMask         = */ UINT32_MAX,
  • trunk/src/VBox/VMM/VMMR3/cpus/Quad_Core_AMD_Opteron_2384.h

    r53624 r54737  
    66
    77/*
    8  * Copyright (C) 2013 Oracle Corporation
     8 * Copyright (C) 2013-2015 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2828{
    2929    { 0x00000000, 0x00000000, 0x00000000, 0x00000005, 0x68747541, 0x444d4163, 0x69746e65, 0 },
    30     { 0x00000001, 0x00000000, 0x00000000, 0x00100f42, 0x06040800, 0x00802009, 0x178bfbff, 0 },
     30    { 0x00000001, 0x00000000, 0x00000000, 0x00100f42, 0x06040800, 0x00802009, 0x178bfbff, 0 | CPUMCPUIDLEAF_F_CONTAINS_APIC_ID },
    3131    { 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0 },
    3232    { 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0 },
     
    256256    /*.paCpuIdLeaves    = */ NULL_ALONE(g_aCpuIdLeaves_Quad_Core_AMD_Opteron_2384),
    257257    /*.cCpuIdLeaves     = */ ZERO_ALONE(RT_ELEMENTS(g_aCpuIdLeaves_Quad_Core_AMD_Opteron_2384)),
    258     /*.enmUnknownCpuId  = */ CPUMUKNOWNCPUID_DEFAULTS,
     258    /*.enmUnknownCpuId  = */ CPUMUNKNOWNCPUID_DEFAULTS,
    259259    /*.DefUnknownCpuId  = */ { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    260260    /*.fMsrMask         = */ UINT32_MAX,
  • trunk/src/VBox/VMM/VMMR3/cpus/VIA_QuadCore_L4700_1_2_GHz.h

    r53624 r54737  
    66
    77/*
    8  * Copyright (C) 2013 Oracle Corporation
     8 * Copyright (C) 2013-2015 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2828{
    2929    { 0x00000000, 0x00000000, 0x00000000, 0x0000000a, 0x746e6543, 0x736c7561, 0x48727561, 0 },
    30     { 0x00000001, 0x00000000, 0x00000000, 0x000006fd, 0x06080800, 0x008863a9, 0xbfc9fbff, 0 },
     30    { 0x00000001, 0x00000000, 0x00000000, 0x000006fd, 0x06080800, 0x008863a9, 0xbfc9fbff, 0 | CPUMCPUIDLEAF_F_CONTAINS_APIC_ID },
    3131    { 0x00000002, 0x00000000, 0x00000000, 0x02b3b001, 0x00000000, 0x00000000, 0x2c04307d, 0 },
    3232    { 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0 },
     
    390390    /*.paCpuIdLeaves    = */ NULL_ALONE(g_aCpuIdLeaves_VIA_QuadCore_L4700_1_2_GHz),
    391391    /*.cCpuIdLeaves     = */ ZERO_ALONE(RT_ELEMENTS(g_aCpuIdLeaves_VIA_QuadCore_L4700_1_2_GHz)),
    392     /*.enmUnknownCpuId  = */ CPUMUKNOWNCPUID_DEFAULTS,
     392    /*.enmUnknownCpuId  = */ CPUMUNKNOWNCPUID_DEFAULTS,
    393393    /*.DefUnknownCpuId  = */ { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    394394    /*.fMsrMask         = */ UINT32_MAX,
  • trunk/src/VBox/VMM/include/CPUMInternal.h

    r54674 r54737  
    3030/* Some fudging. */
    3131typedef uint32_t CPUMMICROARCH;
    32 typedef uint32_t CPUMUKNOWNCPUID;
     32typedef uint32_t CPUMUNKNOWNCPUID;
    3333typedef struct CPUMCPUIDLEAF *PCPUMCPUIDLEAF;
    3434typedef struct CPUMMSRRANGE  *PCPUMMSRRANGE;
     
    123123 * @{ */
    124124/** The current saved state version. */
    125 #define CPUM_SAVED_STATE_VERSION                14
    126 /** The current saved state version before using SSMR3PutStruct. */
     125#define CPUM_SAVED_STATE_VERSION                15
     126/** The saved state version before the CPUIDs changes. */
     127#define CPUM_SAVED_STATE_VERSION_PUT_STRUCT     14
     128/** The saved state version before using SSMR3PutStruct. */
    127129#define CPUM_SAVED_STATE_VERSION_MEM            13
    128130/** The saved state version before introducing the MSR size field. */
     
    244246    uint32_t                    uPadding;
    245247    /** How to handle unknown CPUID leaves. */
    246     CPUMUKNOWNCPUID             enmUnknownCpuIdMethod;
    247     /** For use with CPUMUKNOWNCPUID_DEFAULTS. */
     248    CPUMUNKNOWNCPUID            enmUnknownCpuIdMethod;
     249    /** For use with CPUMUNKNOWNCPUID_DEFAULTS (DB & VM),
     250     * CPUMUNKNOWNCPUID_LAST_STD_LEAF (VM) and CPUMUNKNOWNCPUID_LAST_STD_LEAF_WITH_ECX (VM). */
    248251    CPUMCPUID                   DefCpuId;
    249252
     
    492495    /** The centaur set of CpuId leaves. */
    493496    CPUMCPUID               aGuestCpuIdPatmCentaur[4];
    494     /** The default set of CpuId leaves. */
    495     CPUMCPUID               GuestCpuIdPatmDef;
    496497
    497498#if HC_ARCH_BITS == 32
     
    601602RT_C_DECLS_BEGIN
    602603
    603 PCPUMCPUIDLEAF      cpumCpuIdGetLeaf(PVM pVM, uint32_t uLeaf, uint32_t uSubLeaf);
     604PCPUMCPUIDLEAF      cpumCpuIdGetLeaf(PVM pVM, uint32_t uLeaf);
     605PCPUMCPUIDLEAF      cpumCpuIdGetLeafEx(PVM pVM, uint32_t uLeaf, uint32_t uSubLeaf, bool *pfExactSubLeafHit);
    604606
    605607#ifdef IN_RING3
    606608int                 cpumR3DbgInit(PVM pVM);
    607 PCPUMCPUIDLEAF      cpumR3CpuIdGetLeaf(PCPUMCPUIDLEAF paLeaves, uint32_t cLeaves, uint32_t uLeaf, uint32_t uSubLeaf);
    608 bool                cpumR3CpuIdGetLeafLegacy(PCPUMCPUIDLEAF paLeaves, uint32_t cLeaves, uint32_t uLeaf, uint32_t uSubLeaf,
    609                                              PCPUMCPUID pLeagcy);
    610 int                 cpumR3CpuIdInsert(PVM pVM, PCPUMCPUIDLEAF *ppaLeaves, uint32_t *pcLeaves, PCPUMCPUIDLEAF pNewLeaf);
    611 void                cpumR3CpuIdRemoveRange(PCPUMCPUIDLEAF paLeaves, uint32_t *pcLeaves, uint32_t uFirst, uint32_t uLast);
    612609int                 cpumR3CpuIdExplodeFeatures(PCCPUMCPUIDLEAF paLeaves, uint32_t cLeaves, PCPUMFEATURES pFeatures);
    613 int                 cpumR3CpuIdInit(PVM pVM);
     610int                 cpumR3InitCpuIdAndMsrs(PVM pVM);
    614611void                cpumR3SaveCpuId(PVM pVM, PSSMHANDLE pSSM);
    615612int                 cpumR3LoadCpuId(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion);
     613DECLCALLBACK(void)  cpumR3CpuIdInfo(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs);
    616614
    617615int                 cpumR3DbGetCpuInfo(const char *pszName, PCPUMINFO pInfo);
  • trunk/src/VBox/VMM/include/CPUMInternal.mac

    r54674 r54737  
    8080%endif
    8181
    82     ; CPUID leafs
     82    ; Patch manager saved state compatability CPUID leaf arrays
    8383    .aGuestCpuIdPatmStd         resb    16*6
    8484    .aGuestCpuIdPatmExt         resb    16*10
    8585    .aGuestCpuIdPatmCentaur     resb    16*4
    86     .GuestCpuIdPatmDef          resb    16
    8786
    8887%if HC_ARCH_BITS == 32
  • trunk/src/VBox/VMM/testcase/tstVMStruct.h

    r54674 r54737  
    4040    GEN_CHECK_OFF(CPUM, aGuestCpuIdPatmExt);
    4141    GEN_CHECK_OFF(CPUM, aGuestCpuIdPatmCentaur);
    42     GEN_CHECK_OFF(CPUM, GuestCpuIdPatmDef);
    4342
    4443    GEN_CHECK_SIZE(CPUMCPU); // has .mac
  • trunk/src/VBox/VMM/tools/VBoxCpuReport.cpp

    r54714 r54737  
    55
    66/*
    7  * Copyright (C) 2013 Oracle Corporation
     7 * Copyright (C) 2013-2015 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    43894389            vbCpuRepPrintf("0");
    43904390            uint32_t fFlags = paLeaves[i].fFlags;
    4391             if (paLeaves[i].fFlags & CPUMCPUIDLEAF_F_SUBLEAVES_ECX_UNCHANGED)
     4391            if (paLeaves[i].fFlags & CPUMCPUIDLEAF_F_INTEL_TOPOLOGY_SUBLEAVES)
    43924392            {
    4393                 vbCpuRepPrintf(" | CPUMCPUIDLEAF_F_SUBLEAVES_ECX_UNCHANGED");
    4394                 fFlags &= ~CPUMCPUIDLEAF_F_SUBLEAVES_ECX_UNCHANGED;
     4393                vbCpuRepPrintf(" | CPUMCPUIDLEAF_F_INTEL_TOPOLOGY_SUBLEAVES");
     4394                fFlags &= ~CPUMCPUIDLEAF_F_INTEL_TOPOLOGY_SUBLEAVES;
     4395            }
     4396            if (paLeaves[i].fFlags & CPUMCPUIDLEAF_F_CONTAINS_APIC_ID)
     4397            {
     4398                vbCpuRepPrintf(" | CPUMCPUIDLEAF_F_CONTAINS_APIC_ID");
     4399                fFlags &= ~CPUMCPUIDLEAF_F_CONTAINS_APIC_ID;
    43954400            }
    43964401            if (fFlags)
     
    45894594                       "\n"
    45904595                       "/*\n"
    4591                        " * Copyright (C) 2013 Oracle Corporation\n"
     4596                       " * Copyright (C) 2013-2015 Oracle Corporation\n"
    45924597                       " *\n"
    45934598                       " * This file is part of VirtualBox Open Source Edition (OSE), as\n"
     
    46154620        return rc;
    46164621
    4617     CPUMUKNOWNCPUID enmUnknownMethod;
     4622    CPUMUNKNOWNCPUID enmUnknownMethod;
    46184623    CPUMCPUID       DefUnknown;
    46194624    rc = CPUMR3CpuIdDetectUnknownLeafMethod(&enmUnknownMethod, &DefUnknown);
     
    46504655                   "    /*.paCpuIdLeaves    = */ NULL_ALONE(g_aCpuIdLeaves_%s),\n"
    46514656                   "    /*.cCpuIdLeaves     = */ ZERO_ALONE(RT_ELEMENTS(g_aCpuIdLeaves_%s)),\n"
    4652                    "    /*.enmUnknownCpuId  = */ CPUMUKNOWNCPUID_%s,\n"
     4657                   "    /*.enmUnknownCpuId  = */ CPUMUNKNOWNCPUID_%s,\n"
    46534658                   "    /*.DefUnknownCpuId  = */ { %#010x, %#010x, %#010x, %#010x },\n"
    46544659                   "    /*.fMsrMask         = */ %s,\n"
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