VirtualBox

Changeset 24453 in vbox for trunk/src


Ignore:
Timestamp:
Nov 6, 2009 3:43:52 PM (15 years ago)
Author:
vboxsync
Message:

CPUM: CPUID validation on state load.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/CPUM.cpp

    r24416 r24453  
    461461                                       /* ECX Bit 21 - x2APIC support - not yet. */
    462462                                       // | X86_CPUID_FEATURE_ECX_X2APIC
    463                                        /* ECX Bit 23 - POPCOUNT instruction. */
    464                                        //| X86_CPUID_FEATURE_ECX_POPCOUNT
     463                                       /* ECX Bit 23 - POPCNT instruction. */
     464                                       //| X86_CPUID_FEATURE_ECX_POPCNT
    465465                                       | 0;
    466466
     
    507507                                       //| X86_CPUID_AMD_FEATURE_ECX_3DNOWPRF
    508508                                       //| X86_CPUID_AMD_FEATURE_ECX_OSVW
     509                                       //| X86_CPUID_AMD_FEATURE_ECX_IBS
     510                                       //| X86_CPUID_AMD_FEATURE_ECX_SSE5
    509511                                       //| X86_CPUID_AMD_FEATURE_ECX_SKINIT
    510512                                       //| X86_CPUID_AMD_FEATURE_ECX_WDT
     
    10111013     * handy when validating features for raw mode.
    10121014     */
    1013     CPUMCPUID   aRawStd[8];
     1015    CPUMCPUID   aRawStd[16];
    10141016    for (unsigned i = 0; i < RT_ELEMENTS(aRawStd); i++)
    10151017        ASMCpuId(i, &aRawStd[i].eax, &aRawStd[i].ebx, &aRawStd[i].ecx, &aRawStd[i].edx);
     
    10171019    SSMR3PutMem(pSSM, &aRawStd[0], sizeof(aRawStd));
    10181020
    1019     CPUMCPUID   aRawExt[16];
     1021    CPUMCPUID   aRawExt[32];
    10201022    for (unsigned i = 0; i < RT_ELEMENTS(aRawExt); i++)
    10211023        ASMCpuId(i | UINT32_C(0x80000000), &aRawExt[i].eax, &aRawExt[i].ebx, &aRawExt[i].ecx, &aRawExt[i].edx);
     
    10361038{
    10371039    AssertMsgReturn(uVersion >= CPUM_SAVED_STATE_VERSION, ("%u\n", uVersion), VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION);
     1040
     1041    /*
     1042     * Define a bunch of macros for simplifying the code.
     1043     */
     1044    /* Generic expression + failure message. */
     1045#define CPUID_CHECK_RET(expr, fmt) \
     1046    do { \
     1047        if (!(expr)) \
     1048        { \
     1049            char *pszMsg = RTStrAPrintf2 fmt; /* lack of variadict macros sucks */ \
     1050            if (fStrictCpuIdChecks) \
     1051            { \
     1052                int rc = SSMR3SetLoadError(pSSM, VERR_SSM_LOAD_CPUID_MISMATCH, RT_SRC_POS, "%s", pszMsg); \
     1053                RTStrFree(pszMsg); \
     1054                return rc; \
     1055            } \
     1056            LogRel(("CPUM: %s\n", pszMsg)); \
     1057            RTStrFree(pszMsg); \
     1058        } \
     1059    } while (0)
     1060#define CPUID_CHECK_WRN(expr, fmt) \
     1061    do { \
     1062        if (!(expr)) \
     1063            LogRel(fmt); \
     1064    } while (0)
     1065
     1066    /* For comparing two values and bitch if they differs. */
     1067#define CPUID_CHECK2_RET(what, host, saved) \
     1068    do { \
     1069        if ((host) != (saved)) \
     1070        { \
     1071            if (fStrictCpuIdChecks) \
     1072                return SSMR3SetLoadError(pSSM, VERR_SSM_LOAD_CPUID_MISMATCH, RT_SRC_POS, \
     1073                                         N_(#what " mismatch: host=%#x saved=%#x"), (host), (saved)); \
     1074            LogRel(("CPUM: " #what " differs: host=%#x saved=%#x\n", (host), (saved))); \
     1075        } \
     1076    } while (0)
     1077#define CPUID_CHECK2_WRN(what, host, saved) \
     1078    do { \
     1079        if ((host) != (saved)) \
     1080            LogRel(("CPUM: " #what " differs: host=%#x saved=%#x\n", (host), (saved))); \
     1081    } while (0)
     1082
     1083    /* For checking raw cpu features (raw mode). */
     1084#define CPUID_RAW_FEATURE_RET(set, reg, bit) \
     1085    do { \
     1086        if ((aHostRaw##set [1].reg & bit) != (aRaw##set [1].reg & bit)) \
     1087        { \
     1088            if (fStrictCpuIdChecks) \
     1089                return SSMR3SetLoadError(pSSM, VERR_SSM_LOAD_CPUID_MISMATCH, RT_SRC_POS, \
     1090                                         N_(#bit " mismatch: host=%d saved=%d"), \
     1091                                         aHostRaw##set [1].reg & (bit), aRaw##set [1].reg & (bit) ); \
     1092            LogRel(("CPUM: " #bit" differs: host=%d saved=%d\n", \
     1093                    aHostRaw##set [1].reg & (bit), aRaw##set [1].reg & (bit) )); \
     1094        } \
     1095    } while (0)
     1096#define CPUID_RAW_FEATURE_WRN(set, reg, bit) \
     1097    do { \
     1098        if ((aHostRaw##set [1].reg & bit) != (aRaw##set [1].reg & bit)) \
     1099            LogRel(("CPUM: " #bit" differs: host=%d saved=%d\n", \
     1100                    aHostRaw##set [1].reg & (bit), aRaw##set [1].reg & (bit) )); \
     1101    } while (0)
     1102#define CPUID_RAW_FEATURE_IGN(set, reg, bit) do { } while (0)
     1103
     1104    /* For checking guest features. */
     1105#define CPUID_GST_FEATURE_RET(set, reg, bit) \
     1106    do { \
     1107        if (    (aGuestCpuId##set [1].reg & bit) \
     1108            && !(aHostRaw##set [1].reg & bit) \
     1109            && !(aHostOverride##set [1].reg & bit) \
     1110            && !(aGuestOverride##set [1].reg & bit) \
     1111           ) \
     1112        { \
     1113            if (fStrictCpuIdChecks) \
     1114                return SSMR3SetLoadError(pSSM, VERR_SSM_LOAD_CPUID_MISMATCH, RT_SRC_POS, \
     1115                                         N_(#bit " is not supported by the host but has already exposed to the guest")); \
     1116            LogRel(("CPUM: " #bit " is not supported by the host but has already exposed to the guest\n")); \
     1117        } \
     1118    } while (0)
     1119#define CPUID_GST_FEATURE_WRN(set, reg, bit) \
     1120    do { \
     1121        if (    (aGuestCpuId##set [1].reg & bit) \
     1122            && !(aHostRaw##set [1].reg & bit) \
     1123            && !(aHostOverride##set [1].reg & bit) \
     1124            && !(aGuestOverride##set [1].reg & bit) \
     1125           ) \
     1126            LogRel(("CPUM: " #bit " is not supported by the host but has already exposed to the guest\n")); \
     1127    } while (0)
     1128#define CPUID_GST_FEATURE_EMU(set, reg, bit) \
     1129    do { \
     1130        if (    (aGuestCpuId##set [1].reg & bit) \
     1131            && !(aHostRaw##set [1].reg & bit) \
     1132            && !(aHostOverride##set [1].reg & bit) \
     1133            && !(aGuestOverride##set [1].reg & bit) \
     1134           ) \
     1135            LogRel(("CPUM: Warning - " #bit " is not supported by the host but already exposed to the guest. This may impact performance.\n")); \
     1136    } while (0)
     1137#define CPUID_GST_FEATURE_IGN(set, reg, bit) do { } while (0)
     1138
     1139    /* For checking guest features if AMD guest CPU. */
     1140#define CPUID_GST_AMD_FEATURE_RET(set, reg, bit) \
     1141    do { \
     1142        if (    (aGuestCpuId##set [1].reg & bit) \
     1143            &&  fGuestAmd \
     1144            && (!fGuestAmd || !(aHostRaw##set [1].reg & bit)) \
     1145            && !(aHostOverride##set [1].reg & bit) \
     1146            && !(aGuestOverride##set [1].reg & bit) \
     1147           ) \
     1148        { \
     1149            if (fStrictCpuIdChecks) \
     1150                return SSMR3SetLoadError(pSSM, VERR_SSM_LOAD_CPUID_MISMATCH, RT_SRC_POS, \
     1151                                         N_(#bit " is not supported by the host but has already exposed to the guest")); \
     1152            LogRel(("CPUM: " #bit " is not supported by the host but has already exposed to the guest\n")); \
     1153        } \
     1154    } while (0)
     1155#define CPUID_GST_AMD_FEATURE_WRN(set, reg, bit) \
     1156    do { \
     1157        if (    (aGuestCpuId##set [1].reg & bit) \
     1158            &&  fGuestAmd \
     1159            && (!fGuestAmd || !(aHostRaw##set [1].reg & bit)) \
     1160            && !(aHostOverride##set [1].reg & bit) \
     1161            && !(aGuestOverride##set [1].reg & bit) \
     1162           ) \
     1163            LogRel(("CPUM: " #bit " is not supported by the host but has already exposed to the guest\n")); \
     1164    } while (0)
     1165#define CPUID_GST_AMD_FEATURE_EMU(set, reg, bit) \
     1166    do { \
     1167        if (    (aGuestCpuId##set [1].reg & bit) \
     1168            &&  fGuestAmd \
     1169            && (!fGuestAmd || !(aHostRaw##set [1].reg & bit)) \
     1170            && !(aHostOverride##set [1].reg & bit) \
     1171            && !(aGuestOverride##set [1].reg & bit) \
     1172           ) \
     1173            LogRel(("CPUM: Warning - " #bit " is not supported by the host but already exposed to the guest. This may impact performance.\n")); \
     1174    } while (0)
     1175#define CPUID_GST_AMD_FEATURE_IGN(set, reg, bit) do { } while (0)
     1176
     1177    /* For checking AMD features which have a corresponding bit in the standard
     1178       range.  (Intel defines very few bits in the extended feature sets.) */
     1179#define CPUID_GST_FEATURE2_RET(reg, ExtBit, StdBit) \
     1180    do { \
     1181        if (    (aGuestCpuIdExt [1].reg    & (ExtBit)) \
     1182            && !(fHostAmd  \
     1183                 ? aHostRawExt[1].reg      & (ExtBit) \
     1184                 : aHostRawStd[1].reg      & (StdBit)) \
     1185            && !(aHostOverrideExt[1].reg   & (ExtBit)) \
     1186            && !(aGuestOverrideExt[1].reg  & (ExtBit)) \
     1187           ) \
     1188        { \
     1189            if (fStrictCpuIdChecks) \
     1190                return SSMR3SetLoadError(pSSM, VERR_SSM_LOAD_CPUID_MISMATCH, RT_SRC_POS, \
     1191                                         N_(#ExtBit " is not supported by the host but has already exposed to the guest")); \
     1192            LogRel(("CPUM: " #ExtBit " is not supported by the host but has already exposed to the guest\n")); \
     1193        } \
     1194    } while (0)
     1195#define CPUID_GST_FEATURE2_WRN(reg, ExtBit, StdBit) \
     1196    do { \
     1197        if (    (aGuestCpuIdExt [1].reg    & (ExtBit)) \
     1198            && !(fHostAmd  \
     1199                 ? aHostRawExt[1].reg      & (ExtBit) \
     1200                 : aHostRawStd[1].reg      & (StdBit)) \
     1201            && !(aHostOverrideExt[1].reg   & (ExtBit)) \
     1202            && !(aGuestOverrideExt[1].reg  & (ExtBit)) \
     1203           ) \
     1204            LogRel(("CPUM: " #ExtBit " is not supported by the host but has already exposed to the guest\n")); \
     1205    } while (0)
     1206#define CPUID_GST_FEATURE2_EMU(reg, ExtBit, StdBit) \
     1207    do { \
     1208        if (    (aGuestCpuIdExt [1].reg    & (ExtBit)) \
     1209            && !(fHostAmd  \
     1210                 ? aHostRawExt[1].reg      & (ExtBit) \
     1211                 : aHostRawStd[1].reg      & (StdBit)) \
     1212            && !(aHostOverrideExt[1].reg   & (ExtBit)) \
     1213            && !(aGuestOverrideExt[1].reg  & (ExtBit)) \
     1214           ) \
     1215            LogRel(("CPUM: Warning - " #ExtBit " is not supported by the host but already exposed to the guest. This may impact performance.\n")); \
     1216    } while (0)
     1217#define CPUID_GST_FEATURE2_IGN(reg, ExtBit, StdBit) do { } while (0)
    10381218
    10391219    /*
     
    10651245    AssertRCReturn(rc, rc);
    10661246
    1067     CPUMCPUID   aRawStd[8];
     1247    CPUMCPUID   aRawStd[16];
    10681248    uint32_t    cRawStd;
    10691249    rc = SSMR3GetU32(pSSM, &cRawStd); AssertRCReturn(rc, rc);
     
    10721252    SSMR3GetMem(pSSM, &aRawStd[0], cRawStd * sizeof(aRawStd[0]));
    10731253
    1074     CPUMCPUID   aRawExt[16];
     1254    CPUMCPUID   aRawExt[32];
    10751255    uint32_t    cRawExt;
    10761256    rc = SSMR3GetU32(pSSM, &cRawExt); AssertRCReturn(rc, rc);
     
    11041284     * Get the raw CPU IDs for the current host.
    11051285     */
    1106     CPUMCPUID   aHostRawStd[8];
     1286    CPUMCPUID   aHostRawStd[16];
    11071287    for (unsigned i = 0; i < RT_ELEMENTS(aHostRawStd); i++)
    11081288        ASMCpuId(i, &aHostRawStd[i].eax, &aHostRawStd[i].ebx, &aHostRawStd[i].ecx, &aHostRawStd[i].edx);
    11091289
    1110     CPUMCPUID   aHostRawExt[16];
     1290    CPUMCPUID   aHostRawExt[32];
    11111291    for (unsigned i = 0; i < RT_ELEMENTS(aHostRawExt); i++)
    11121292        ASMCpuId(i | UINT32_C(0x80000000), &aHostRawExt[i].eax, &aHostRawExt[i].ebx, &aHostRawExt[i].ecx, &aHostRawExt[i].edx);
    11131293
    11141294    /*
    1115      * Now for the fun part...
    1116      */
    1117 
     1295     * Get the host and guest overrides so we don't reject the state because
     1296     * some feature was enabled thru these interfaces.
     1297     * Note! We currently only need the feature leafs, so skip rest.
     1298     */
     1299    PCFGMNODE   pOverrideCfg = CFGMR3GetChild(CFGMR3GetRoot(pVM), "CPUM/CPUID");
     1300    CPUMCPUID   aGuestOverrideStd[2];
     1301    memcpy(&aGuestOverrideStd[0], &aHostRawStd[0], sizeof(aGuestOverrideStd));
     1302    cpumR3CpuIdInitLoadOverrideSet(UINT32_C(0x00000000), &aGuestOverrideStd[0], RT_ELEMENTS(aGuestOverrideStd), pOverrideCfg);
     1303
     1304    CPUMCPUID   aGuestOverrideExt[2];
     1305    memcpy(&aGuestOverrideExt[0], &aHostRawExt[0], sizeof(aGuestOverrideExt));
     1306    cpumR3CpuIdInitLoadOverrideSet(UINT32_C(0x80000000), &aGuestOverrideExt[0], RT_ELEMENTS(aGuestOverrideExt), pOverrideCfg);
     1307
     1308    pOverrideCfg = CFGMR3GetChild(CFGMR3GetRoot(pVM), "CPUM/HostCPUID");
     1309    CPUMCPUID   aHostOverrideStd[2];
     1310    memcpy(&aHostOverrideStd[0], &aHostRawStd[0], sizeof(aHostOverrideStd));
     1311    cpumR3CpuIdInitLoadOverrideSet(UINT32_C(0x00000000), &aHostOverrideStd[0], RT_ELEMENTS(aHostOverrideStd), pOverrideCfg);
     1312
     1313    CPUMCPUID   aHostOverrideExt[2];
     1314    memcpy(&aHostOverrideExt[0], &aHostRawExt[0], sizeof(aHostOverrideExt));
     1315    cpumR3CpuIdInitLoadOverrideSet(UINT32_C(0x80000000), &aHostOverrideExt[0], RT_ELEMENTS(aHostOverrideExt), pOverrideCfg);
     1316
     1317    /*
     1318     * This can be skipped.
     1319     */
     1320    bool fStrictCpuIdChecks;
     1321    CFGMR3QueryBoolDef(CFGMR3GetChild(CFGMR3GetRoot(pVM), "CPUM"), "StrictCpuIdChecks", &fStrictCpuIdChecks, false);
     1322
     1323
     1324
     1325    /*
     1326     * For raw-mode we'll require that the CPUs are very similar since we don't
     1327     * intercept CPUID instructions for user mode applications.
     1328     */
     1329    if (!HWACCMIsEnabled(pVM))
     1330    {
     1331        /* CPUID(0) */
     1332        CPUID_CHECK_RET(   aHostRawStd[0].ebx == aRawStd[0].ebx
     1333                        && aHostRawStd[0].ecx == aRawStd[0].ecx
     1334                        && aHostRawStd[0].edx == aRawStd[0].edx,
     1335                        (N_("CPU vendor mismatch: host='%.4s%.4s%.4s' saved='%.4s%.4s%.4s'"),
     1336                         &aHostRawStd[0].ebx, &aHostRawStd[0].edx, &aHostRawStd[0].ecx,
     1337                         &aRawStd[0].ebx, &aRawStd[0].edx, &aRawStd[0].ecx));
     1338        CPUID_CHECK2_WRN("Std CPUID max leaf",   aHostRawStd[0].eax, aRawStd[0].eax);
     1339        CPUID_CHECK2_WRN("Reserved bits 15:14", (aHostRawExt[1].eax >> 14) & 3, (aRawExt[1].eax >> 14) & 3);
     1340        CPUID_CHECK2_WRN("Reserved bits 31:28",  aHostRawExt[1].eax >> 28,       aRawExt[1].eax >> 28);
     1341
     1342        bool const fIntel = ASMIsIntelCpuEx(aRawStd[0].ebx, aRawStd[0].ecx, aRawStd[0].edx);
     1343
     1344        /* CPUID(1).eax */
     1345        CPUID_CHECK2_RET("CPU family",          ASMGetCpuFamily(aHostRawStd[1].eax),        ASMGetCpuFamily(aRawStd[1].eax));
     1346        CPUID_CHECK2_RET("CPU model",           ASMGetCpuModel(aHostRawStd[1].eax, fIntel), ASMGetCpuModel(aRawStd[1].eax, fIntel));
     1347        CPUID_CHECK2_WRN("CPU type",            (aHostRawStd[1].eax >> 12) & 3,             (aRawStd[1].eax >> 12) & 3 );
     1348
     1349        /* CPUID(1).ebx - completely ignore CPU count and APIC ID. */
     1350        CPUID_CHECK2_RET("CPU brand ID",         aHostRawStd[1].ebx & 0xff,                 aRawStd[1].ebx & 0xff);
     1351        CPUID_CHECK2_WRN("CLFLUSH chunk count", (aHostRawStd[1].ebx >> 8) & 0xff,           (aRawStd[1].ebx >> 8) & 0xff);
     1352
     1353        /* CPUID(1).ecx */
     1354        CPUID_RAW_FEATURE_RET(Std, ecx, X86_CPUID_FEATURE_ECX_SSE3);
     1355        CPUID_RAW_FEATURE_RET(Std, ecx, X86_CPUID_FEATURE_ECX_PCLMUL);
     1356        CPUID_RAW_FEATURE_IGN(Std, ecx, X86_CPUID_FEATURE_ECX_DTES64);
     1357        CPUID_RAW_FEATURE_RET(Std, ecx, X86_CPUID_FEATURE_ECX_MONITOR);
     1358        CPUID_RAW_FEATURE_RET(Std, ecx, X86_CPUID_FEATURE_ECX_CPLDS);
     1359        CPUID_RAW_FEATURE_IGN(Std, ecx, X86_CPUID_FEATURE_ECX_VMX);
     1360        CPUID_RAW_FEATURE_IGN(Std, ecx, X86_CPUID_FEATURE_ECX_SMX);
     1361        CPUID_RAW_FEATURE_IGN(Std, ecx, X86_CPUID_FEATURE_ECX_EST);
     1362        CPUID_RAW_FEATURE_IGN(Std, ecx, X86_CPUID_FEATURE_ECX_TM2);
     1363        CPUID_RAW_FEATURE_RET(Std, ecx, X86_CPUID_FEATURE_ECX_SSSE3);
     1364        CPUID_RAW_FEATURE_IGN(Std, ecx, X86_CPUID_FEATURE_ECX_CNTXID);
     1365        CPUID_RAW_FEATURE_RET(Std, ecx, RT_BIT_32(11) /*reserved*/ );
     1366        CPUID_RAW_FEATURE_RET(Std, ecx, X86_CPUID_FEATURE_ECX_FMA);
     1367        CPUID_RAW_FEATURE_RET(Std, ecx, X86_CPUID_FEATURE_ECX_CX16);
     1368        CPUID_RAW_FEATURE_IGN(Std, ecx, X86_CPUID_FEATURE_ECX_TPRUPDATE);
     1369        CPUID_RAW_FEATURE_IGN(Std, ecx, X86_CPUID_FEATURE_ECX_PDCM);
     1370        CPUID_RAW_FEATURE_RET(Std, ecx, RT_BIT_32(16) /*reserved*/);
     1371        CPUID_RAW_FEATURE_RET(Std, ecx, RT_BIT_32(17) /*reserved*/);
     1372        CPUID_RAW_FEATURE_IGN(Std, ecx, X86_CPUID_FEATURE_ECX_DCA);
     1373        CPUID_RAW_FEATURE_RET(Std, ecx, X86_CPUID_FEATURE_ECX_SSE4_1);
     1374        CPUID_RAW_FEATURE_RET(Std, ecx, X86_CPUID_FEATURE_ECX_SSE4_2);
     1375        CPUID_RAW_FEATURE_IGN(Std, ecx, X86_CPUID_FEATURE_ECX_X2APIC);
     1376        CPUID_RAW_FEATURE_RET(Std, ecx, X86_CPUID_FEATURE_ECX_MOVBE);
     1377        CPUID_RAW_FEATURE_RET(Std, ecx, X86_CPUID_FEATURE_ECX_POPCNT);
     1378        CPUID_RAW_FEATURE_RET(Std, ecx, RT_BIT_32(24) /*reserved*/);
     1379        CPUID_RAW_FEATURE_RET(Std, ecx, X86_CPUID_FEATURE_ECX_AES);
     1380        CPUID_RAW_FEATURE_RET(Std, ecx, X86_CPUID_FEATURE_ECX_XSAVE);
     1381        CPUID_RAW_FEATURE_RET(Std, ecx, X86_CPUID_FEATURE_ECX_OSXSAVE);
     1382        CPUID_RAW_FEATURE_RET(Std, ecx, X86_CPUID_FEATURE_ECX_AVX);
     1383        CPUID_RAW_FEATURE_RET(Std, ecx, RT_BIT_32(29) /*reserved*/);
     1384        CPUID_RAW_FEATURE_RET(Std, ecx, RT_BIT_32(30) /*reserved*/);
     1385        CPUID_RAW_FEATURE_RET(Std, ecx, RT_BIT_32(31) /*reserved*/);
     1386
     1387        /* CPUID(1).edx */
     1388        CPUID_RAW_FEATURE_RET(Std, edx, X86_CPUID_FEATURE_EDX_FPU);
     1389        CPUID_RAW_FEATURE_RET(Std, edx, X86_CPUID_FEATURE_EDX_VME);
     1390        CPUID_RAW_FEATURE_RET(Std, edx, X86_CPUID_FEATURE_EDX_DE);
     1391        CPUID_RAW_FEATURE_IGN(Std, edx, X86_CPUID_FEATURE_EDX_PSE);
     1392        CPUID_RAW_FEATURE_RET(Std, edx, X86_CPUID_FEATURE_EDX_TSC);
     1393        CPUID_RAW_FEATURE_RET(Std, edx, X86_CPUID_FEATURE_EDX_MSR);
     1394        CPUID_RAW_FEATURE_IGN(Std, edx, X86_CPUID_FEATURE_EDX_PAE);
     1395        CPUID_RAW_FEATURE_IGN(Std, edx, X86_CPUID_FEATURE_EDX_MCE);
     1396        CPUID_RAW_FEATURE_RET(Std, edx, X86_CPUID_FEATURE_EDX_CX8);
     1397        CPUID_RAW_FEATURE_IGN(Std, edx, X86_CPUID_FEATURE_EDX_APIC);
     1398        CPUID_RAW_FEATURE_RET(Std, edx, RT_BIT_32(10) /*reserved*/);
     1399        CPUID_RAW_FEATURE_IGN(Std, edx, X86_CPUID_FEATURE_EDX_SEP);
     1400        CPUID_RAW_FEATURE_IGN(Std, edx, X86_CPUID_FEATURE_EDX_MTRR);
     1401        CPUID_RAW_FEATURE_IGN(Std, edx, X86_CPUID_FEATURE_EDX_PGE);
     1402        CPUID_RAW_FEATURE_IGN(Std, edx, X86_CPUID_FEATURE_EDX_MCA);
     1403        CPUID_RAW_FEATURE_RET(Std, edx, X86_CPUID_FEATURE_EDX_CMOV);
     1404        CPUID_RAW_FEATURE_IGN(Std, edx, X86_CPUID_FEATURE_EDX_PAT);
     1405        CPUID_RAW_FEATURE_IGN(Std, edx, X86_CPUID_FEATURE_EDX_PSE36);
     1406        CPUID_RAW_FEATURE_IGN(Std, edx, X86_CPUID_FEATURE_EDX_PSN);
     1407        CPUID_RAW_FEATURE_RET(Std, edx, X86_CPUID_FEATURE_EDX_CLFSH);
     1408        CPUID_RAW_FEATURE_RET(Std, edx, RT_BIT_32(20) /*reserved*/);
     1409        CPUID_RAW_FEATURE_IGN(Std, edx, X86_CPUID_FEATURE_EDX_DS);
     1410        CPUID_RAW_FEATURE_IGN(Std, edx, X86_CPUID_FEATURE_EDX_ACPI);
     1411        CPUID_RAW_FEATURE_RET(Std, edx, X86_CPUID_FEATURE_EDX_MMX);
     1412        CPUID_RAW_FEATURE_RET(Std, edx, X86_CPUID_FEATURE_EDX_FXSR);
     1413        CPUID_RAW_FEATURE_RET(Std, edx, X86_CPUID_FEATURE_EDX_SSE);
     1414        CPUID_RAW_FEATURE_RET(Std, edx, X86_CPUID_FEATURE_EDX_SSE2);
     1415        CPUID_RAW_FEATURE_IGN(Std, edx, X86_CPUID_FEATURE_EDX_SS);
     1416        CPUID_RAW_FEATURE_IGN(Std, edx, X86_CPUID_FEATURE_EDX_HTT);
     1417        CPUID_RAW_FEATURE_IGN(Std, edx, X86_CPUID_FEATURE_EDX_TM);
     1418        CPUID_RAW_FEATURE_RET(Std, edx, RT_BIT_32(30) /*JMPE/IA64*/);
     1419        CPUID_RAW_FEATURE_IGN(Std, edx, X86_CPUID_FEATURE_EDX_PBE);
     1420
     1421        /* CPUID(2) - config, mostly about caches. ignore. */
     1422        /* CPUID(3) - processor serial number. ignore. */
     1423        /* CPUID(4) - config, cache and topology - takes ECX as input. ignore. */
     1424        /* CPUID(5) - mwait/monitor config. ignore. */
     1425        /* CPUID(6) - power management. ignore. */
     1426        /* CPUID(7) - ???. ignore. */
     1427        /* CPUID(8) - ???. ignore. */
     1428        /* CPUID(9) - DCA. ignore for now. */
     1429        /* CPUID(a) - PeMo info. ignore for now. */
     1430        /* CPUID(b) - topology info - takes ECX as input. ignore. */
     1431
     1432        /* CPUID(d) - XCR0 stuff - takes ECX as input. We only warn about the main level (ECX=0) for now. */
     1433        CPUID_CHECK_WRN(   aRawStd[0].eax     <  UINT32_C(0x0000000d)
     1434                        || aHostRawStd[0].eax >= UINT32_C(0x0000000d),
     1435                        ("CPUM: Standard leaf D was present on saved state host, not present on current.\n"));
     1436        if (   aRawStd[0].eax     >= UINT32_C(0x0000000d)
     1437            && aHostRawStd[0].eax >= UINT32_C(0x0000000d))
     1438        {
     1439            CPUID_CHECK2_WRN("Valid low XCR0 bits",             aHostRawStd[0xd].eax, aRawStd[0xd].eax);
     1440            CPUID_CHECK2_WRN("Valid high XCR0 bits",            aHostRawStd[0xd].edx, aRawStd[0xd].edx);
     1441            CPUID_CHECK2_WRN("Current XSAVE/XRSTOR area size",  aHostRawStd[0xd].ebx, aRawStd[0xd].ebx);
     1442            CPUID_CHECK2_WRN("Max XSAVE/XRSTOR area size",      aHostRawStd[0xd].ecx, aRawStd[0xd].ecx);
     1443        }
     1444
     1445        /* CPUID(0x80000000) - same as CPUID(0) except for eax.
     1446           Note! Intel have/is marking many of the fields here as reserved. We
     1447                 will verify them as if it's an AMD CPU. */
     1448        CPUID_CHECK_RET(   (aHostRawExt[0].eax >= UINT32_C(0x80000001) && aHostRawExt[0].eax <= UINT32_C(0x8000007f))
     1449                        || !(aRawExt[0].eax    >= UINT32_C(0x80000001) && aRawExt[0].eax     <= UINT32_C(0x8000007f)),
     1450                        (N_("Extended leafs was present on saved state host, but is missing on the current\n")));
     1451        if (aRawExt[0].eax >= UINT32_C(0x80000001) && aRawExt[0].eax     <= UINT32_C(0x8000007f))
     1452        {
     1453            CPUID_CHECK_RET(   aHostRawExt[0].ebx == aRawExt[0].ebx
     1454                            && aHostRawExt[0].ecx == aRawExt[0].ecx
     1455                            && aHostRawExt[0].edx == aRawExt[0].edx,
     1456                            (N_("CPU vendor mismatch: host='%.4s%.4s%.4s' saved='%.4s%.4s%.4s'"),
     1457                             &aHostRawExt[0].ebx, &aHostRawExt[0].edx, &aHostRawExt[0].ecx,
     1458                             &aRawExt[0].ebx,     &aRawExt[0].edx,     &aRawExt[0].ecx));
     1459            CPUID_CHECK2_WRN("Ext CPUID max leaf",   aHostRawExt[0].eax, aRawExt[0].eax);
     1460
     1461            /* CPUID(0x80000001).eax - same as CPUID(0).eax. */
     1462            CPUID_CHECK2_RET("CPU family",          ASMGetCpuFamily(aHostRawExt[1].eax),        ASMGetCpuFamily(aRawExt[1].eax));
     1463            CPUID_CHECK2_RET("CPU model",           ASMGetCpuModel(aHostRawExt[1].eax, fIntel), ASMGetCpuModel(aRawExt[1].eax, fIntel));
     1464            CPUID_CHECK2_WRN("CPU type",            (aHostRawExt[1].eax >> 12) & 3, (aRawExt[1].eax >> 12) & 3 );
     1465            CPUID_CHECK2_WRN("Reserved bits 15:14", (aHostRawExt[1].eax >> 14) & 3, (aRawExt[1].eax >> 14) & 3 );
     1466            CPUID_CHECK2_WRN("Reserved bits 31:28",  aHostRawExt[1].eax >> 28, aRawExt[1].eax >> 28);
     1467
     1468            /* CPUID(0x80000001).ebx - Brand ID (maybe), just warn if things differs. */
     1469            CPUID_CHECK2_WRN("CPU BrandID",          aHostRawExt[1].ebx & 0xffff, aRawExt[1].ebx & 0xffff);
     1470            CPUID_CHECK2_WRN("Reserved bits 16:27", (aHostRawExt[1].ebx >> 16) & 0xfff, (aRawExt[1].ebx >> 16) & 0xfff);
     1471            CPUID_CHECK2_WRN("PkgType",             (aHostRawExt[1].ebx >> 28) &   0xf, (aRawExt[1].ebx >> 28) &   0xf);
     1472
     1473            /* CPUID(0x80000001).ecx */
     1474            CPUID_RAW_FEATURE_IGN(Ext, ecx, X86_CPUID_AMD_FEATURE_ECX_LAHF_SAHF);
     1475            CPUID_RAW_FEATURE_IGN(Ext, ecx, X86_CPUID_AMD_FEATURE_ECX_CMPL);
     1476            CPUID_RAW_FEATURE_IGN(Ext, ecx, X86_CPUID_AMD_FEATURE_ECX_SVM);
     1477            CPUID_RAW_FEATURE_IGN(Ext, ecx, X86_CPUID_AMD_FEATURE_ECX_EXT_APIC);
     1478            CPUID_RAW_FEATURE_IGN(Ext, ecx, X86_CPUID_AMD_FEATURE_ECX_CR8L);
     1479            CPUID_RAW_FEATURE_WRN(Ext, ecx, X86_CPUID_AMD_FEATURE_ECX_ABM);
     1480            CPUID_RAW_FEATURE_WRN(Ext, ecx, X86_CPUID_AMD_FEATURE_ECX_SSE4A);
     1481            CPUID_RAW_FEATURE_WRN(Ext, ecx, X86_CPUID_AMD_FEATURE_ECX_MISALNSSE);
     1482            CPUID_RAW_FEATURE_WRN(Ext, ecx, X86_CPUID_AMD_FEATURE_ECX_3DNOWPRF);
     1483            CPUID_RAW_FEATURE_WRN(Ext, ecx, X86_CPUID_AMD_FEATURE_ECX_OSVW);
     1484            CPUID_RAW_FEATURE_IGN(Ext, ecx, X86_CPUID_AMD_FEATURE_ECX_IBS);
     1485            CPUID_RAW_FEATURE_WRN(Ext, ecx, X86_CPUID_AMD_FEATURE_ECX_SSE5);
     1486            CPUID_RAW_FEATURE_IGN(Ext, ecx, X86_CPUID_AMD_FEATURE_ECX_SKINIT);
     1487            CPUID_RAW_FEATURE_IGN(Ext, ecx, X86_CPUID_AMD_FEATURE_ECX_WDT);
     1488            CPUID_RAW_FEATURE_WRN(Ext, ecx, RT_BIT_32(14));
     1489            CPUID_RAW_FEATURE_WRN(Ext, ecx, RT_BIT_32(15));
     1490            CPUID_RAW_FEATURE_WRN(Ext, ecx, RT_BIT_32(16));
     1491            CPUID_RAW_FEATURE_WRN(Ext, ecx, RT_BIT_32(17));
     1492            CPUID_RAW_FEATURE_WRN(Ext, ecx, RT_BIT_32(18));
     1493            CPUID_RAW_FEATURE_WRN(Ext, ecx, RT_BIT_32(19));
     1494            CPUID_RAW_FEATURE_WRN(Ext, ecx, RT_BIT_32(20));
     1495            CPUID_RAW_FEATURE_WRN(Ext, ecx, RT_BIT_32(21));
     1496            CPUID_RAW_FEATURE_WRN(Ext, ecx, RT_BIT_32(22));
     1497            CPUID_RAW_FEATURE_WRN(Ext, ecx, RT_BIT_32(23));
     1498            CPUID_RAW_FEATURE_WRN(Ext, ecx, RT_BIT_32(24));
     1499            CPUID_RAW_FEATURE_WRN(Ext, ecx, RT_BIT_32(25));
     1500            CPUID_RAW_FEATURE_WRN(Ext, ecx, RT_BIT_32(26));
     1501            CPUID_RAW_FEATURE_WRN(Ext, ecx, RT_BIT_32(27));
     1502            CPUID_RAW_FEATURE_WRN(Ext, ecx, RT_BIT_32(28));
     1503            CPUID_RAW_FEATURE_WRN(Ext, ecx, RT_BIT_32(29));
     1504            CPUID_RAW_FEATURE_WRN(Ext, ecx, RT_BIT_32(30));
     1505            CPUID_RAW_FEATURE_WRN(Ext, ecx, RT_BIT_32(31));
     1506
     1507            /* CPUID(0x80000001).edx */
     1508            CPUID_RAW_FEATURE_RET(Ext, edx, X86_CPUID_AMD_FEATURE_EDX_FPU);
     1509            CPUID_RAW_FEATURE_RET(Ext, edx, X86_CPUID_AMD_FEATURE_EDX_VME);
     1510            CPUID_RAW_FEATURE_RET(Ext, edx, X86_CPUID_AMD_FEATURE_EDX_DE);
     1511            CPUID_RAW_FEATURE_RET(Ext, edx, X86_CPUID_AMD_FEATURE_EDX_PSE);
     1512            CPUID_RAW_FEATURE_RET(Ext, edx, X86_CPUID_AMD_FEATURE_EDX_TSC);
     1513            CPUID_RAW_FEATURE_RET(Ext, edx, X86_CPUID_AMD_FEATURE_EDX_MSR);
     1514            CPUID_RAW_FEATURE_IGN(Ext, edx, X86_CPUID_AMD_FEATURE_EDX_PAE);
     1515            CPUID_RAW_FEATURE_IGN(Ext, edx, X86_CPUID_AMD_FEATURE_EDX_MCE);
     1516            CPUID_RAW_FEATURE_RET(Ext, edx, X86_CPUID_AMD_FEATURE_EDX_CX8);
     1517            CPUID_RAW_FEATURE_IGN(Ext, edx, X86_CPUID_AMD_FEATURE_EDX_APIC);
     1518            CPUID_RAW_FEATURE_IGN(Ext, edx, RT_BIT_32(10) /*reserved*/);
     1519            CPUID_RAW_FEATURE_IGN(Ext, edx, X86_CPUID_AMD_FEATURE_EDX_SEP);
     1520            CPUID_RAW_FEATURE_IGN(Ext, edx, X86_CPUID_AMD_FEATURE_EDX_MTRR);
     1521            CPUID_RAW_FEATURE_IGN(Ext, edx, X86_CPUID_AMD_FEATURE_EDX_PGE);
     1522            CPUID_RAW_FEATURE_IGN(Ext, edx, X86_CPUID_AMD_FEATURE_EDX_MCA);
     1523            CPUID_RAW_FEATURE_RET(Ext, edx, X86_CPUID_AMD_FEATURE_EDX_CMOV);
     1524            CPUID_RAW_FEATURE_IGN(Ext, edx, X86_CPUID_AMD_FEATURE_EDX_PAT);
     1525            CPUID_RAW_FEATURE_IGN(Ext, edx, X86_CPUID_AMD_FEATURE_EDX_PSE36);
     1526            CPUID_RAW_FEATURE_IGN(Ext, edx, RT_BIT_32(18) /*reserved*/);
     1527            CPUID_RAW_FEATURE_IGN(Ext, edx, RT_BIT_32(19) /*reserved*/);
     1528            CPUID_RAW_FEATURE_IGN(Ext, edx, X86_CPUID_AMD_FEATURE_EDX_NX);
     1529            CPUID_RAW_FEATURE_IGN(Ext, edx, RT_BIT_32(21) /*reserved*/);
     1530            CPUID_RAW_FEATURE_IGN(Ext, edx, X86_CPUID_AMD_FEATURE_EDX_AXMMX);
     1531            CPUID_RAW_FEATURE_RET(Ext, edx, X86_CPUID_AMD_FEATURE_EDX_MMX);
     1532            CPUID_RAW_FEATURE_RET(Ext, edx, X86_CPUID_AMD_FEATURE_EDX_FXSR);
     1533            CPUID_RAW_FEATURE_RET(Ext, edx, X86_CPUID_AMD_FEATURE_EDX_FFXSR);
     1534            CPUID_RAW_FEATURE_IGN(Ext, edx, X86_CPUID_AMD_FEATURE_EDX_PAGE1GB);
     1535            CPUID_RAW_FEATURE_IGN(Ext, edx, X86_CPUID_AMD_FEATURE_EDX_RDTSCP);
     1536            CPUID_RAW_FEATURE_IGN(Ext, edx, RT_BIT_32(28) /*reserved*/);
     1537            CPUID_RAW_FEATURE_IGN(Ext, edx, X86_CPUID_AMD_FEATURE_EDX_LONG_MODE);
     1538            CPUID_RAW_FEATURE_RET(Ext, edx, X86_CPUID_AMD_FEATURE_EDX_3DNOW_EX);
     1539            CPUID_RAW_FEATURE_RET(Ext, edx, X86_CPUID_AMD_FEATURE_EDX_3DNOW);
     1540
     1541            /** @todo verify the rest as well. */
     1542        }
     1543    }
     1544
     1545
     1546
     1547    /*
     1548     * Verify that we can support the features already exposed to the guest on
     1549     * this host.
     1550     *
     1551     * Most of the features we're emulating requires intercepting instruction
     1552     * and doing it the slow way, so there is no need to warn when they aren't
     1553     * present in the host CPU.  Thus we use IGN instead of EMU on these.
     1554     *
     1555     * Trailing comments:
     1556     *      "EMU"  - Possible to emulate, could be lots of work and very slow.
     1557     *      "EMU?" - Can this be emulated?
     1558     */
     1559    /* CPUID(1).ecx */
     1560    CPUID_GST_FEATURE_RET(Std, ecx, X86_CPUID_FEATURE_ECX_SSE3);    // -> EMU
     1561    CPUID_GST_FEATURE_RET(Std, ecx, X86_CPUID_FEATURE_ECX_PCLMUL);  // -> EMU?
     1562    CPUID_GST_FEATURE_RET(Std, ecx, X86_CPUID_FEATURE_ECX_DTES64);  // -> EMU?
     1563    CPUID_GST_FEATURE_IGN(Std, ecx, X86_CPUID_FEATURE_ECX_MONITOR);
     1564    CPUID_GST_FEATURE_RET(Std, ecx, X86_CPUID_FEATURE_ECX_CPLDS);   // -> EMU?
     1565    CPUID_GST_FEATURE_RET(Std, ecx, X86_CPUID_FEATURE_ECX_VMX);     // -> EMU
     1566    CPUID_GST_FEATURE_RET(Std, ecx, X86_CPUID_FEATURE_ECX_SMX);     // -> EMU
     1567    CPUID_GST_FEATURE_RET(Std, ecx, X86_CPUID_FEATURE_ECX_EST);     // -> EMU
     1568    CPUID_GST_FEATURE_RET(Std, ecx, X86_CPUID_FEATURE_ECX_TM2);     // -> EMU?
     1569    CPUID_GST_FEATURE_RET(Std, ecx, X86_CPUID_FEATURE_ECX_SSSE3);   // -> EMU
     1570    CPUID_GST_FEATURE_RET(Std, ecx, X86_CPUID_FEATURE_ECX_CNTXID);  // -> EMU
     1571    CPUID_GST_FEATURE_RET(Std, ecx, RT_BIT_32(11) /*reserved*/ );
     1572    CPUID_GST_FEATURE_RET(Std, ecx, X86_CPUID_FEATURE_ECX_FMA);     // -> EMU? what's this?
     1573    CPUID_GST_FEATURE_RET(Std, ecx, X86_CPUID_FEATURE_ECX_CX16);    // -> EMU?
     1574    CPUID_GST_FEATURE_RET(Std, ecx, X86_CPUID_FEATURE_ECX_TPRUPDATE);//-> EMU
     1575    CPUID_GST_FEATURE_RET(Std, ecx, X86_CPUID_FEATURE_ECX_PDCM);    // -> EMU
     1576    CPUID_GST_FEATURE_RET(Std, ecx, RT_BIT_32(16) /*reserved*/);
     1577    CPUID_GST_FEATURE_RET(Std, ecx, RT_BIT_32(17) /*reserved*/);
     1578    CPUID_GST_FEATURE_RET(Std, ecx, X86_CPUID_FEATURE_ECX_DCA);     // -> EMU?
     1579    CPUID_GST_FEATURE_RET(Std, ecx, X86_CPUID_FEATURE_ECX_SSE4_1);  // -> EMU
     1580    CPUID_GST_FEATURE_RET(Std, ecx, X86_CPUID_FEATURE_ECX_SSE4_2);  // -> EMU
     1581    CPUID_GST_FEATURE_IGN(Std, ecx, X86_CPUID_FEATURE_ECX_X2APIC);
     1582    CPUID_GST_FEATURE_RET(Std, ecx, X86_CPUID_FEATURE_ECX_MOVBE);   // -> EMU
     1583    CPUID_GST_FEATURE_RET(Std, ecx, X86_CPUID_FEATURE_ECX_POPCNT);  // -> EMU
     1584    CPUID_GST_FEATURE_RET(Std, ecx, RT_BIT_32(24) /*reserved*/);
     1585    CPUID_GST_FEATURE_RET(Std, ecx, X86_CPUID_FEATURE_ECX_AES);     // -> EMU
     1586    CPUID_GST_FEATURE_RET(Std, ecx, X86_CPUID_FEATURE_ECX_XSAVE);   // -> EMU
     1587    CPUID_GST_FEATURE_RET(Std, ecx, X86_CPUID_FEATURE_ECX_OSXSAVE); // -> EMU
     1588    CPUID_GST_FEATURE_RET(Std, ecx, X86_CPUID_FEATURE_ECX_AVX);     // -> EMU?
     1589    CPUID_GST_FEATURE_RET(Std, ecx, RT_BIT_32(29) /*reserved*/);
     1590    CPUID_GST_FEATURE_RET(Std, ecx, RT_BIT_32(30) /*reserved*/);
     1591    CPUID_GST_FEATURE_RET(Std, ecx, RT_BIT_32(31) /*reserved*/);
     1592
     1593    /* CPUID(1).edx */
     1594    CPUID_GST_FEATURE_RET(Std, edx, X86_CPUID_FEATURE_EDX_FPU);
     1595    CPUID_GST_FEATURE_RET(Std, edx, X86_CPUID_FEATURE_EDX_VME);
     1596    CPUID_GST_FEATURE_RET(Std, edx, X86_CPUID_FEATURE_EDX_DE);      // -> EMU?
     1597    CPUID_GST_FEATURE_IGN(Std, edx, X86_CPUID_FEATURE_EDX_PSE);
     1598    CPUID_GST_FEATURE_RET(Std, edx, X86_CPUID_FEATURE_EDX_TSC);     // -> EMU
     1599    CPUID_GST_FEATURE_RET(Std, edx, X86_CPUID_FEATURE_EDX_MSR);     // -> EMU
     1600    CPUID_GST_FEATURE_RET(Std, edx, X86_CPUID_FEATURE_EDX_PAE);
     1601    CPUID_GST_FEATURE_IGN(Std, edx, X86_CPUID_FEATURE_EDX_MCE);
     1602    CPUID_GST_FEATURE_RET(Std, edx, X86_CPUID_FEATURE_EDX_CX8);     // -> EMU?
     1603    CPUID_GST_FEATURE_IGN(Std, edx, X86_CPUID_FEATURE_EDX_APIC);
     1604    CPUID_GST_FEATURE_RET(Std, edx, RT_BIT_32(10) /*reserved*/);
     1605    CPUID_GST_FEATURE_IGN(Std, edx, X86_CPUID_FEATURE_EDX_SEP);
     1606    CPUID_GST_FEATURE_IGN(Std, edx, X86_CPUID_FEATURE_EDX_MTRR);
     1607    CPUID_GST_FEATURE_IGN(Std, edx, X86_CPUID_FEATURE_EDX_PGE);
     1608    CPUID_GST_FEATURE_IGN(Std, edx, X86_CPUID_FEATURE_EDX_MCA);
     1609    CPUID_GST_FEATURE_RET(Std, edx, X86_CPUID_FEATURE_EDX_CMOV);    // -> EMU
     1610    CPUID_GST_FEATURE_IGN(Std, edx, X86_CPUID_FEATURE_EDX_PAT);
     1611    CPUID_GST_FEATURE_IGN(Std, edx, X86_CPUID_FEATURE_EDX_PSE36);
     1612    CPUID_GST_FEATURE_IGN(Std, edx, X86_CPUID_FEATURE_EDX_PSN);
     1613    CPUID_GST_FEATURE_RET(Std, edx, X86_CPUID_FEATURE_EDX_CLFSH);   // -> EMU
     1614    CPUID_GST_FEATURE_RET(Std, edx, RT_BIT_32(20) /*reserved*/);
     1615    CPUID_GST_FEATURE_RET(Std, edx, X86_CPUID_FEATURE_EDX_DS);      // -> EMU?
     1616    CPUID_GST_FEATURE_RET(Std, edx, X86_CPUID_FEATURE_EDX_ACPI);    // -> EMU?
     1617    CPUID_GST_FEATURE_RET(Std, edx, X86_CPUID_FEATURE_EDX_MMX);     // -> EMU
     1618    CPUID_GST_FEATURE_RET(Std, edx, X86_CPUID_FEATURE_EDX_FXSR);    // -> EMU
     1619    CPUID_GST_FEATURE_RET(Std, edx, X86_CPUID_FEATURE_EDX_SSE);     // -> EMU
     1620    CPUID_GST_FEATURE_RET(Std, edx, X86_CPUID_FEATURE_EDX_SSE2);    // -> EMU
     1621    CPUID_GST_FEATURE_RET(Std, edx, X86_CPUID_FEATURE_EDX_SS);      // -> EMU?
     1622    CPUID_GST_FEATURE_RET(Std, edx, X86_CPUID_FEATURE_EDX_HTT);     // -> EMU?
     1623    CPUID_GST_FEATURE_RET(Std, edx, X86_CPUID_FEATURE_EDX_TM);      // -> EMU?
     1624    CPUID_GST_FEATURE_RET(Std, edx, RT_BIT_32(30) /*JMPE/IA64*/);   // -> EMU
     1625    CPUID_GST_FEATURE_RET(Std, edx, X86_CPUID_FEATURE_EDX_PBE);     // -> EMU?
     1626
     1627    /* CPUID(0x80000000). */
     1628    if (    aGuestCpuIdExt[0].eax >= UINT32_C(0x80000001)
     1629        &&  aGuestCpuIdExt[0].eax <  UINT32_C(0x8000007f))
     1630    {
     1631        /** @todo deal with no 0x80000001 on the host. */
     1632        bool const fHostAmd  = ASMIsAmdCpuEx(aHostRawStd[0].ebx, aHostRawStd[0].ecx, aHostRawStd[0].edx);
     1633        bool const fGuestAmd = ASMIsAmdCpuEx(aGuestCpuIdExt[0].ebx, aGuestCpuIdExt[0].ecx, aGuestCpuIdExt[0].edx);
     1634
     1635        /* CPUID(0x80000001).ecx */
     1636        CPUID_GST_FEATURE_WRN(Ext, ecx, X86_CPUID_AMD_FEATURE_ECX_LAHF_SAHF);   // -> EMU
     1637        CPUID_GST_AMD_FEATURE_WRN(Ext, ecx, X86_CPUID_AMD_FEATURE_ECX_CMPL);    // -> EMU
     1638        CPUID_GST_AMD_FEATURE_RET(Ext, ecx, X86_CPUID_AMD_FEATURE_ECX_SVM);     // -> EMU
     1639        CPUID_GST_AMD_FEATURE_WRN(Ext, ecx, X86_CPUID_AMD_FEATURE_ECX_EXT_APIC);// ???
     1640        CPUID_GST_AMD_FEATURE_RET(Ext, ecx, X86_CPUID_AMD_FEATURE_ECX_CR8L);    // -> EMU
     1641        CPUID_GST_AMD_FEATURE_RET(Ext, ecx, X86_CPUID_AMD_FEATURE_ECX_ABM);     // -> EMU
     1642        CPUID_GST_AMD_FEATURE_RET(Ext, ecx, X86_CPUID_AMD_FEATURE_ECX_SSE4A);   // -> EMU
     1643        CPUID_GST_AMD_FEATURE_RET(Ext, ecx, X86_CPUID_AMD_FEATURE_ECX_MISALNSSE);//-> EMU
     1644        CPUID_GST_AMD_FEATURE_RET(Ext, ecx, X86_CPUID_AMD_FEATURE_ECX_3DNOWPRF);// -> EMU
     1645        CPUID_GST_AMD_FEATURE_RET(Ext, ecx, X86_CPUID_AMD_FEATURE_ECX_OSVW);    // -> EMU?
     1646        CPUID_GST_AMD_FEATURE_RET(Ext, ecx, X86_CPUID_AMD_FEATURE_ECX_IBS);     // -> EMU
     1647        CPUID_GST_AMD_FEATURE_RET(Ext, ecx, X86_CPUID_AMD_FEATURE_ECX_SSE5);    // -> EMU
     1648        CPUID_GST_AMD_FEATURE_RET(Ext, ecx, X86_CPUID_AMD_FEATURE_ECX_SKINIT);  // -> EMU
     1649        CPUID_GST_AMD_FEATURE_RET(Ext, ecx, X86_CPUID_AMD_FEATURE_ECX_WDT);     // -> EMU
     1650        CPUID_GST_AMD_FEATURE_WRN(Ext, ecx, RT_BIT_32(14));
     1651        CPUID_GST_AMD_FEATURE_WRN(Ext, ecx, RT_BIT_32(15));
     1652        CPUID_GST_AMD_FEATURE_WRN(Ext, ecx, RT_BIT_32(16));
     1653        CPUID_GST_AMD_FEATURE_WRN(Ext, ecx, RT_BIT_32(17));
     1654        CPUID_GST_AMD_FEATURE_WRN(Ext, ecx, RT_BIT_32(18));
     1655        CPUID_GST_AMD_FEATURE_WRN(Ext, ecx, RT_BIT_32(19));
     1656        CPUID_GST_AMD_FEATURE_WRN(Ext, ecx, RT_BIT_32(20));
     1657        CPUID_GST_AMD_FEATURE_WRN(Ext, ecx, RT_BIT_32(21));
     1658        CPUID_GST_AMD_FEATURE_WRN(Ext, ecx, RT_BIT_32(22));
     1659        CPUID_GST_AMD_FEATURE_WRN(Ext, ecx, RT_BIT_32(23));
     1660        CPUID_GST_AMD_FEATURE_WRN(Ext, ecx, RT_BIT_32(24));
     1661        CPUID_GST_AMD_FEATURE_WRN(Ext, ecx, RT_BIT_32(25));
     1662        CPUID_GST_AMD_FEATURE_WRN(Ext, ecx, RT_BIT_32(26));
     1663        CPUID_GST_AMD_FEATURE_WRN(Ext, ecx, RT_BIT_32(27));
     1664        CPUID_GST_AMD_FEATURE_WRN(Ext, ecx, RT_BIT_32(28));
     1665        CPUID_GST_AMD_FEATURE_WRN(Ext, ecx, RT_BIT_32(29));
     1666        CPUID_GST_AMD_FEATURE_WRN(Ext, ecx, RT_BIT_32(30));
     1667        CPUID_GST_AMD_FEATURE_WRN(Ext, ecx, RT_BIT_32(31));
     1668
     1669        /* CPUID(0x80000001).edx */
     1670        CPUID_GST_FEATURE2_RET(        edx, X86_CPUID_AMD_FEATURE_EDX_FPU,   X86_CPUID_FEATURE_EDX_FPU);     // -> EMU
     1671        CPUID_GST_FEATURE2_RET(        edx, X86_CPUID_AMD_FEATURE_EDX_VME,   X86_CPUID_FEATURE_EDX_VME);     // -> EMU
     1672        CPUID_GST_FEATURE2_RET(        edx, X86_CPUID_AMD_FEATURE_EDX_DE,    X86_CPUID_FEATURE_EDX_DE);      // -> EMU
     1673        CPUID_GST_FEATURE2_IGN(        edx, X86_CPUID_AMD_FEATURE_EDX_PSE,   X86_CPUID_FEATURE_EDX_PSE);
     1674        CPUID_GST_FEATURE2_RET(        edx, X86_CPUID_AMD_FEATURE_EDX_TSC,   X86_CPUID_FEATURE_EDX_TSC);     // -> EMU
     1675        CPUID_GST_FEATURE2_RET(        edx, X86_CPUID_AMD_FEATURE_EDX_MSR,   X86_CPUID_FEATURE_EDX_MSR);     // -> EMU
     1676        CPUID_GST_FEATURE2_RET(        edx, X86_CPUID_AMD_FEATURE_EDX_PAE,   X86_CPUID_FEATURE_EDX_PAE);
     1677        CPUID_GST_FEATURE2_IGN(        edx, X86_CPUID_AMD_FEATURE_EDX_MCE,   X86_CPUID_FEATURE_EDX_MCE);
     1678        CPUID_GST_FEATURE2_RET(        edx, X86_CPUID_AMD_FEATURE_EDX_CX8,   X86_CPUID_FEATURE_EDX_CX8);     // -> EMU?
     1679        CPUID_GST_FEATURE2_IGN(        edx, X86_CPUID_AMD_FEATURE_EDX_APIC,  X86_CPUID_FEATURE_EDX_APIC);
     1680        CPUID_GST_AMD_FEATURE_WRN(Ext, edx, RT_BIT_32(10) /*reserved*/);
     1681        CPUID_GST_FEATURE_IGN(    Ext, edx, X86_CPUID_AMD_FEATURE_EDX_SEP);                                  // Intel: long mode only.
     1682        CPUID_GST_FEATURE2_IGN(        edx, X86_CPUID_AMD_FEATURE_EDX_MTRR,  X86_CPUID_FEATURE_EDX_MTRR);
     1683        CPUID_GST_FEATURE2_IGN(        edx, X86_CPUID_AMD_FEATURE_EDX_PGE,   X86_CPUID_FEATURE_EDX_PGE);
     1684        CPUID_GST_FEATURE2_IGN(        edx, X86_CPUID_AMD_FEATURE_EDX_MCA,   X86_CPUID_FEATURE_EDX_MCA);
     1685        CPUID_GST_FEATURE2_RET(        edx, X86_CPUID_AMD_FEATURE_EDX_CMOV,  X86_CPUID_FEATURE_EDX_CMOV);    // -> EMU
     1686        CPUID_GST_FEATURE2_IGN(        edx, X86_CPUID_AMD_FEATURE_EDX_PAT,   X86_CPUID_FEATURE_EDX_PAT);
     1687        CPUID_GST_FEATURE2_IGN(        edx, X86_CPUID_AMD_FEATURE_EDX_PSE36, X86_CPUID_FEATURE_EDX_PSE36);
     1688        CPUID_GST_AMD_FEATURE_WRN(Ext, edx, RT_BIT_32(18) /*reserved*/);
     1689        CPUID_GST_AMD_FEATURE_WRN(Ext, edx, RT_BIT_32(19) /*reserved*/);
     1690        CPUID_GST_FEATURE_RET(    Ext, edx, X86_CPUID_AMD_FEATURE_EDX_NX);
     1691        CPUID_GST_FEATURE_WRN(    Ext, edx, RT_BIT_32(21) /*reserved*/);
     1692        CPUID_GST_FEATURE_RET(    Ext, edx, X86_CPUID_AMD_FEATURE_EDX_AXMMX);
     1693        CPUID_GST_FEATURE2_RET(        edx, X86_CPUID_AMD_FEATURE_EDX_MMX,   X86_CPUID_FEATURE_EDX_MMX);     // -> EMU
     1694        CPUID_GST_FEATURE2_RET(        edx, X86_CPUID_AMD_FEATURE_EDX_FXSR,  X86_CPUID_FEATURE_EDX_FXSR);    // -> EMU
     1695        CPUID_GST_AMD_FEATURE_RET(Ext, edx, X86_CPUID_AMD_FEATURE_EDX_FFXSR);
     1696        CPUID_GST_AMD_FEATURE_RET(Ext, edx, X86_CPUID_AMD_FEATURE_EDX_PAGE1GB);
     1697        CPUID_GST_AMD_FEATURE_RET(Ext, edx, X86_CPUID_AMD_FEATURE_EDX_RDTSCP);
     1698        CPUID_GST_FEATURE_IGN(    Ext, edx, RT_BIT_32(28) /*reserved*/);
     1699        CPUID_GST_FEATURE_RET(    Ext, edx, X86_CPUID_AMD_FEATURE_EDX_LONG_MODE);
     1700        CPUID_GST_AMD_FEATURE_RET(Ext, edx, X86_CPUID_AMD_FEATURE_EDX_3DNOW_EX);
     1701        CPUID_GST_AMD_FEATURE_RET(Ext, edx, X86_CPUID_AMD_FEATURE_EDX_3DNOW);
     1702    }
    11181703
    11191704    /*
    11201705     * We're good, commit the CPU ID leaves.
    11211706     */
    1122     memcmp(&pVM->cpum.s.aGuestCpuIdStd[0],     &aGuestCpuIdStd[0],     sizeof(aGuestCpuIdStd));
    1123     memcmp(&pVM->cpum.s.aGuestCpuIdExt[0],     &aGuestCpuIdExt[0],     sizeof(aGuestCpuIdExt));
    1124     memcmp(&pVM->cpum.s.aGuestCpuIdCentaur[0], &aGuestCpuIdCentaur[0], sizeof(aGuestCpuIdCentaur));
     1707    memcpy(&pVM->cpum.s.aGuestCpuIdStd[0],     &aGuestCpuIdStd[0],     sizeof(aGuestCpuIdStd));
     1708    memcpy(&pVM->cpum.s.aGuestCpuIdExt[0],     &aGuestCpuIdExt[0],     sizeof(aGuestCpuIdExt));
     1709    memcpy(&pVM->cpum.s.aGuestCpuIdCentaur[0], &aGuestCpuIdCentaur[0], sizeof(aGuestCpuIdCentaur));
    11251710    pVM->cpum.s.GuestCpuIdDef = GuestCpuIdDef;
     1711
     1712#undef CPUID_CHECK_RET
     1713#undef CPUID_CHECK_WRN
     1714#undef CPUID_CHECK2_RET
     1715#undef CPUID_CHECK2_WRN
     1716#undef CPUID_RAW_FEATURE_RET
     1717#undef CPUID_RAW_FEATURE_WRN
     1718#undef CPUID_RAW_FEATURE_IGN
     1719#undef CPUID_GST_FEATURE_RET
     1720#undef CPUID_GST_FEATURE_WRN
     1721#undef CPUID_GST_FEATURE_EMU
     1722#undef CPUID_GST_FEATURE_IGN
     1723#undef CPUID_GST_FEATURE2_RET
     1724#undef CPUID_GST_FEATURE2_WRN
     1725#undef CPUID_GST_FEATURE2_EMU
     1726#undef CPUID_GST_FEATURE2_IGN
     1727#undef CPUID_GST_AMD_FEATURE_RET
     1728#undef CPUID_GST_AMD_FEATURE_WRN
     1729#undef CPUID_GST_AMD_FEATURE_EMU
     1730#undef CPUID_GST_AMD_FEATURE_IGN
    11261731
    11271732    return VINF_SUCCESS;
     
    13841989#ifdef VBOX_WITH_LIVE_MIGRATION
    13851990    /*
    1386      * Guest CPU config and CPUID.
    1387      */
    1388     /** @todo config. */
    1389 
     1991     * Guest CPUIDs.
     1992     */
    13901993    if (uVersion > CPUM_SAVED_STATE_VERSION_VER3_0)
    13911994        return cpumR3LoadCpuId(pVM, pSSM, uVersion);
     
    20712674                        "Model:                           %d  \tExtended: %d \tEffective: %d\n"
    20722675                        "Stepping:                        %d\n"
     2676                        "Type:                            %d\n"
    20732677                        "APIC ID:                         %#04x\n"
    20742678                        "Logical CPUs:                    %d\n"
     
    20782682                        (uEAX >> 4) & 0xf, (uEAX >> 16) & 0x0f, ASMGetCpuModel(uEAX, fIntel),
    20792683                        ASMGetCpuStepping(uEAX),
     2684                        (uEAX >> 12) & 3,
    20802685                        (Guest.ebx >> 24) & 0xff,
    20812686                        (Guest.ebx >> 16) & 0xff,
     
    21232728            pHlp->pfnPrintf(pHlp, "Features ECX:                   ");
    21242729            if (uECX & RT_BIT(0))   pHlp->pfnPrintf(pHlp, " SSE3");
    2125             if (uECX & RT_BIT(1))   pHlp->pfnPrintf(pHlp, " 1");
    2126             if (uECX & RT_BIT(2))   pHlp->pfnPrintf(pHlp, " 2");
     2730            if (uECX & RT_BIT(1))   pHlp->pfnPrintf(pHlp, " PCLMUL");
     2731            if (uECX & RT_BIT(2))   pHlp->pfnPrintf(pHlp, " DTES64");
    21272732            if (uECX & RT_BIT(3))   pHlp->pfnPrintf(pHlp, " MONITOR");
    21282733            if (uECX & RT_BIT(4))   pHlp->pfnPrintf(pHlp, " DS-CPL");
    21292734            if (uECX & RT_BIT(5))   pHlp->pfnPrintf(pHlp, " VMX");
    2130             if (uECX & RT_BIT(6))   pHlp->pfnPrintf(pHlp, " 6");
     2735            if (uECX & RT_BIT(6))   pHlp->pfnPrintf(pHlp, " SMX");
    21312736            if (uECX & RT_BIT(7))   pHlp->pfnPrintf(pHlp, " EST");
    21322737            if (uECX & RT_BIT(8))   pHlp->pfnPrintf(pHlp, " TM2");
    2133             if (uECX & RT_BIT(9))   pHlp->pfnPrintf(pHlp, " 9");
     2738            if (uECX & RT_BIT(9))   pHlp->pfnPrintf(pHlp, " SSSE3");
    21342739            if (uECX & RT_BIT(10))  pHlp->pfnPrintf(pHlp, " CNXT-ID");
    21352740            if (uECX & RT_BIT(11))  pHlp->pfnPrintf(pHlp, " 11");
    2136             if (uECX & RT_BIT(12))  pHlp->pfnPrintf(pHlp, " 12");
     2741            if (uECX & RT_BIT(12))  pHlp->pfnPrintf(pHlp, " FMA");
    21372742            if (uECX & RT_BIT(13))  pHlp->pfnPrintf(pHlp, " CX16");
    2138             for (unsigned iBit = 14; iBit < 32; iBit++)
    2139                 if (uECX & RT_BIT(iBit))
    2140                     pHlp->pfnPrintf(pHlp, " %d", iBit);
     2743            if (uECX & RT_BIT(14))  pHlp->pfnPrintf(pHlp, " TPRUPDATE");
     2744            if (uECX & RT_BIT(15))  pHlp->pfnPrintf(pHlp, " PDCM");
     2745            if (uECX & RT_BIT(16))  pHlp->pfnPrintf(pHlp, " 16");
     2746            if (uECX & RT_BIT(17))  pHlp->pfnPrintf(pHlp, " 17");
     2747            if (uECX & RT_BIT(18))  pHlp->pfnPrintf(pHlp, " DCA");
     2748            if (uECX & RT_BIT(19))  pHlp->pfnPrintf(pHlp, " SSE4_1");
     2749            if (uECX & RT_BIT(20))  pHlp->pfnPrintf(pHlp, " SSE4_2");
     2750            if (uECX & RT_BIT(21))  pHlp->pfnPrintf(pHlp, " X2APIC");
     2751            if (uECX & RT_BIT(22))  pHlp->pfnPrintf(pHlp, " MOVBE");
     2752            if (uECX & RT_BIT(23))  pHlp->pfnPrintf(pHlp, " POPCNT");
     2753            if (uECX & RT_BIT(24))  pHlp->pfnPrintf(pHlp, " 24");
     2754            if (uECX & RT_BIT(25))  pHlp->pfnPrintf(pHlp, " AES");
     2755            if (uECX & RT_BIT(26))  pHlp->pfnPrintf(pHlp, " XSAVE");
     2756            if (uECX & RT_BIT(27))  pHlp->pfnPrintf(pHlp, " OSXSAVE");
     2757            if (uECX & RT_BIT(28))  pHlp->pfnPrintf(pHlp, " AVX");
     2758            if (uECX & RT_BIT(29))  pHlp->pfnPrintf(pHlp, " 29");
     2759            if (uECX & RT_BIT(30))  pHlp->pfnPrintf(pHlp, " 30");
     2760            if (uECX & RT_BIT(31))  pHlp->pfnPrintf(pHlp, " 31");
    21412761            pHlp->pfnPrintf(pHlp, "\n");
    21422762        }
     
    21952815            pHlp->pfnPrintf(pHlp, "Supports Supplemental SSE3 or not      = %d (%d)\n",  EcxGuest.u1SSSE3,      EcxHost.u1SSSE3);
    21962816            pHlp->pfnPrintf(pHlp, "L1 Context ID                          = %d (%d)\n",  EcxGuest.u1CNTXID,     EcxHost.u1CNTXID);
    2197             pHlp->pfnPrintf(pHlp, "Reserved                               = %#x (%#x)\n",EcxGuest.u2Reserved2,  EcxHost.u2Reserved2);
     2817            pHlp->pfnPrintf(pHlp, "FMA                                    = %d (%d)\n",  EcxGuest.u1FMA,        EcxHost.u1FMA);
     2818            pHlp->pfnPrintf(pHlp, "Reserved                               = %d (%d)\n",  EcxGuest.u1Reserved2,  EcxHost.u1Reserved2);
    21982819            pHlp->pfnPrintf(pHlp, "CMPXCHG16B                             = %d (%d)\n",  EcxGuest.u1CX16,       EcxHost.u1CX16);
    21992820            pHlp->pfnPrintf(pHlp, "xTPR Update Control                    = %d (%d)\n",  EcxGuest.u1TPRUpdate,  EcxHost.u1TPRUpdate);
     
    22062827            pHlp->pfnPrintf(pHlp, "Supports MOVBE                         = %d (%d)\n",  EcxGuest.u1MOVBE,      EcxHost.u1MOVBE);
    22072828            pHlp->pfnPrintf(pHlp, "Supports POPCNT                        = %d (%d)\n",  EcxGuest.u1POPCNT,     EcxHost.u1POPCNT);
    2208             pHlp->pfnPrintf(pHlp, "Reserved                               = %#x (%#x)\n",EcxGuest.u2Reserved4,  EcxHost.u2Reserved4);
     2829            pHlp->pfnPrintf(pHlp, "Reserved                               = %#x (%#x)\n",EcxGuest.u1Reserved4,  EcxHost.u1Reserved4);
    22092830            pHlp->pfnPrintf(pHlp, "Supports XSAVE                         = %d (%d)\n",  EcxGuest.u1XSAVE,      EcxHost.u1XSAVE);
    22102831            pHlp->pfnPrintf(pHlp, "Supports OSXSAVE                       = %d (%d)\n",  EcxGuest.u1OSXSAVE,    EcxHost.u1OSXSAVE);
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