VirtualBox

Changeset 55466 in vbox for trunk/src/VBox/VMM/VMMR3


Ignore:
Timestamp:
Apr 28, 2015 12:10:51 AM (10 years ago)
Author:
vboxsync
Message:

CPUM: Need to save and restore the extended state stuff. duh.

Location:
trunk/src/VBox/VMM/VMMR3
Files:
2 edited

Legend:

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

    r55456 r55466  
    111111*   Global Variables                                                           *
    112112*******************************************************************************/
    113 /** Saved state field descriptors for CPUMCTX. */
    114 static const SSMFIELD g_aCpumX87Fields[] =
    115 {
    116     SSMFIELD_ENTRY(         X86FXSTATE, FCW),
    117     SSMFIELD_ENTRY(         X86FXSTATE, FSW),
    118     SSMFIELD_ENTRY(         X86FXSTATE, FTW),
    119     SSMFIELD_ENTRY(         X86FXSTATE, FOP),
    120     SSMFIELD_ENTRY(         X86FXSTATE, FPUIP),
    121     SSMFIELD_ENTRY(         X86FXSTATE, CS),
    122     SSMFIELD_ENTRY(         X86FXSTATE, Rsrvd1),
    123     SSMFIELD_ENTRY(         X86FXSTATE, FPUDP),
    124     SSMFIELD_ENTRY(         X86FXSTATE, DS),
    125     SSMFIELD_ENTRY(         X86FXSTATE, Rsrvd2),
    126     SSMFIELD_ENTRY(         X86FXSTATE, MXCSR),
    127     SSMFIELD_ENTRY(         X86FXSTATE, MXCSR_MASK),
    128     SSMFIELD_ENTRY(         X86FXSTATE, aRegs[0]),
    129     SSMFIELD_ENTRY(         X86FXSTATE, aRegs[1]),
    130     SSMFIELD_ENTRY(         X86FXSTATE, aRegs[2]),
    131     SSMFIELD_ENTRY(         X86FXSTATE, aRegs[3]),
    132     SSMFIELD_ENTRY(         X86FXSTATE, aRegs[4]),
    133     SSMFIELD_ENTRY(         X86FXSTATE, aRegs[5]),
    134     SSMFIELD_ENTRY(         X86FXSTATE, aRegs[6]),
    135     SSMFIELD_ENTRY(         X86FXSTATE, aRegs[7]),
    136     SSMFIELD_ENTRY(         X86FXSTATE, aXMM[0]),
    137     SSMFIELD_ENTRY(         X86FXSTATE, aXMM[1]),
    138     SSMFIELD_ENTRY(         X86FXSTATE, aXMM[2]),
    139     SSMFIELD_ENTRY(         X86FXSTATE, aXMM[3]),
    140     SSMFIELD_ENTRY(         X86FXSTATE, aXMM[4]),
    141     SSMFIELD_ENTRY(         X86FXSTATE, aXMM[5]),
    142     SSMFIELD_ENTRY(         X86FXSTATE, aXMM[6]),
    143     SSMFIELD_ENTRY(         X86FXSTATE, aXMM[7]),
    144     SSMFIELD_ENTRY(         X86FXSTATE, aXMM[8]),
    145     SSMFIELD_ENTRY(         X86FXSTATE, aXMM[9]),
    146     SSMFIELD_ENTRY(         X86FXSTATE, aXMM[10]),
    147     SSMFIELD_ENTRY(         X86FXSTATE, aXMM[11]),
    148     SSMFIELD_ENTRY(         X86FXSTATE, aXMM[12]),
    149     SSMFIELD_ENTRY(         X86FXSTATE, aXMM[13]),
    150     SSMFIELD_ENTRY(         X86FXSTATE, aXMM[14]),
    151     SSMFIELD_ENTRY(         X86FXSTATE, aXMM[15]),
    152     SSMFIELD_ENTRY_TERM()
    153 };
    154 
    155113/** Saved state field descriptors for CPUMCTX. */
    156114static const SSMFIELD g_aCpumCtxFields[] =
     
    247205    SSMFIELD_ENTRY(         CPUMCTX, tr.u32Limit),
    248206    SSMFIELD_ENTRY(         CPUMCTX, tr.Attr),
     207    SSMFIELD_ENTRY_VER(     CPUMCTX, aXcr[0],                           CPUM_SAVED_STATE_VERSION_XSAVE),
     208    SSMFIELD_ENTRY_VER(     CPUMCTX, aXcr[1],                           CPUM_SAVED_STATE_VERSION_XSAVE),
     209    SSMFIELD_ENTRY_VER(     CPUMCTX, fXStateMask,                       CPUM_SAVED_STATE_VERSION_XSAVE),
    249210    SSMFIELD_ENTRY_TERM()
    250211};
     212
     213/** Saved state field descriptors for CPUMCTX. */
     214static const SSMFIELD g_aCpumX87Fields[] =
     215{
     216    SSMFIELD_ENTRY(         X86FXSTATE, FCW),
     217    SSMFIELD_ENTRY(         X86FXSTATE, FSW),
     218    SSMFIELD_ENTRY(         X86FXSTATE, FTW),
     219    SSMFIELD_ENTRY(         X86FXSTATE, FOP),
     220    SSMFIELD_ENTRY(         X86FXSTATE, FPUIP),
     221    SSMFIELD_ENTRY(         X86FXSTATE, CS),
     222    SSMFIELD_ENTRY(         X86FXSTATE, Rsrvd1),
     223    SSMFIELD_ENTRY(         X86FXSTATE, FPUDP),
     224    SSMFIELD_ENTRY(         X86FXSTATE, DS),
     225    SSMFIELD_ENTRY(         X86FXSTATE, Rsrvd2),
     226    SSMFIELD_ENTRY(         X86FXSTATE, MXCSR),
     227    SSMFIELD_ENTRY(         X86FXSTATE, MXCSR_MASK),
     228    SSMFIELD_ENTRY(         X86FXSTATE, aRegs[0]),
     229    SSMFIELD_ENTRY(         X86FXSTATE, aRegs[1]),
     230    SSMFIELD_ENTRY(         X86FXSTATE, aRegs[2]),
     231    SSMFIELD_ENTRY(         X86FXSTATE, aRegs[3]),
     232    SSMFIELD_ENTRY(         X86FXSTATE, aRegs[4]),
     233    SSMFIELD_ENTRY(         X86FXSTATE, aRegs[5]),
     234    SSMFIELD_ENTRY(         X86FXSTATE, aRegs[6]),
     235    SSMFIELD_ENTRY(         X86FXSTATE, aRegs[7]),
     236    SSMFIELD_ENTRY(         X86FXSTATE, aXMM[0]),
     237    SSMFIELD_ENTRY(         X86FXSTATE, aXMM[1]),
     238    SSMFIELD_ENTRY(         X86FXSTATE, aXMM[2]),
     239    SSMFIELD_ENTRY(         X86FXSTATE, aXMM[3]),
     240    SSMFIELD_ENTRY(         X86FXSTATE, aXMM[4]),
     241    SSMFIELD_ENTRY(         X86FXSTATE, aXMM[5]),
     242    SSMFIELD_ENTRY(         X86FXSTATE, aXMM[6]),
     243    SSMFIELD_ENTRY(         X86FXSTATE, aXMM[7]),
     244    SSMFIELD_ENTRY(         X86FXSTATE, aXMM[8]),
     245    SSMFIELD_ENTRY(         X86FXSTATE, aXMM[9]),
     246    SSMFIELD_ENTRY(         X86FXSTATE, aXMM[10]),
     247    SSMFIELD_ENTRY(         X86FXSTATE, aXMM[11]),
     248    SSMFIELD_ENTRY(         X86FXSTATE, aXMM[12]),
     249    SSMFIELD_ENTRY(         X86FXSTATE, aXMM[13]),
     250    SSMFIELD_ENTRY(         X86FXSTATE, aXMM[14]),
     251    SSMFIELD_ENTRY(         X86FXSTATE, aXMM[15]),
     252    SSMFIELD_ENTRY_VER(     X86FXSTATE, au32RsrvdForSoftware[0],        CPUM_SAVED_STATE_VERSION_XSAVE), /* 32-bit/64-bit hack */
     253    SSMFIELD_ENTRY_TERM()
     254};
     255
     256/** Saved state field descriptors for X86XSAVEHDR. */
     257static const SSMFIELD g_aCpumXSaveHdrFields[] =
     258{
     259    SSMFIELD_ENTRY(         X86XSAVEHDR,  bmXState),
     260    SSMFIELD_ENTRY_TERM()
     261};
     262
     263/** Saved state field descriptors for X86XSAVEYMMHI. */
     264static const SSMFIELD g_aCpumYmmHiFields[] =
     265{
     266    SSMFIELD_ENTRY(         X86XSAVEYMMHI, aYmmHi[0]),
     267    SSMFIELD_ENTRY(         X86XSAVEYMMHI, aYmmHi[1]),
     268    SSMFIELD_ENTRY(         X86XSAVEYMMHI, aYmmHi[2]),
     269    SSMFIELD_ENTRY(         X86XSAVEYMMHI, aYmmHi[3]),
     270    SSMFIELD_ENTRY(         X86XSAVEYMMHI, aYmmHi[4]),
     271    SSMFIELD_ENTRY(         X86XSAVEYMMHI, aYmmHi[5]),
     272    SSMFIELD_ENTRY(         X86XSAVEYMMHI, aYmmHi[6]),
     273    SSMFIELD_ENTRY(         X86XSAVEYMMHI, aYmmHi[7]),
     274    SSMFIELD_ENTRY(         X86XSAVEYMMHI, aYmmHi[8]),
     275    SSMFIELD_ENTRY(         X86XSAVEYMMHI, aYmmHi[9]),
     276    SSMFIELD_ENTRY(         X86XSAVEYMMHI, aYmmHi[10]),
     277    SSMFIELD_ENTRY(         X86XSAVEYMMHI, aYmmHi[11]),
     278    SSMFIELD_ENTRY(         X86XSAVEYMMHI, aYmmHi[12]),
     279    SSMFIELD_ENTRY(         X86XSAVEYMMHI, aYmmHi[13]),
     280    SSMFIELD_ENTRY(         X86XSAVEYMMHI, aYmmHi[14]),
     281    SSMFIELD_ENTRY(         X86XSAVEYMMHI, aYmmHi[15]),
     282    SSMFIELD_ENTRY_TERM()
     283};
     284
     285/** Saved state field descriptors for X86XSAVEBNDREGS. */
     286static const SSMFIELD g_aCpumBndRegsFields[] =
     287{
     288    SSMFIELD_ENTRY(         X86XSAVEBNDREGS, aRegs[0]),
     289    SSMFIELD_ENTRY(         X86XSAVEBNDREGS, aRegs[1]),
     290    SSMFIELD_ENTRY(         X86XSAVEBNDREGS, aRegs[2]),
     291    SSMFIELD_ENTRY(         X86XSAVEBNDREGS, aRegs[3]),
     292    SSMFIELD_ENTRY_TERM()
     293};
     294
     295/** Saved state field descriptors for X86XSAVEBNDCFG. */
     296static const SSMFIELD g_aCpumBndCfgFields[] =
     297{
     298    SSMFIELD_ENTRY(         X86XSAVEBNDCFG, fConfig),
     299    SSMFIELD_ENTRY(         X86XSAVEBNDCFG, fStatus),
     300    SSMFIELD_ENTRY_TERM()
     301};
     302
     303/** Saved state field descriptors for X86XSAVEOPMASK. */
     304static const SSMFIELD g_aCpumOpmaskFields[] =
     305{
     306    SSMFIELD_ENTRY(         X86XSAVEOPMASK, aKRegs[0]),
     307    SSMFIELD_ENTRY(         X86XSAVEOPMASK, aKRegs[1]),
     308    SSMFIELD_ENTRY(         X86XSAVEOPMASK, aKRegs[2]),
     309    SSMFIELD_ENTRY(         X86XSAVEOPMASK, aKRegs[3]),
     310    SSMFIELD_ENTRY(         X86XSAVEOPMASK, aKRegs[4]),
     311    SSMFIELD_ENTRY(         X86XSAVEOPMASK, aKRegs[5]),
     312    SSMFIELD_ENTRY(         X86XSAVEOPMASK, aKRegs[6]),
     313    SSMFIELD_ENTRY(         X86XSAVEOPMASK, aKRegs[7]),
     314    SSMFIELD_ENTRY_TERM()
     315};
     316
     317/** Saved state field descriptors for X86XSAVEZMMHI256. */
     318static const SSMFIELD g_aCpumZmmHi256Fields[] =
     319{
     320    SSMFIELD_ENTRY(         X86XSAVEZMMHI256, aHi256Regs[0]),
     321    SSMFIELD_ENTRY(         X86XSAVEZMMHI256, aHi256Regs[1]),
     322    SSMFIELD_ENTRY(         X86XSAVEZMMHI256, aHi256Regs[2]),
     323    SSMFIELD_ENTRY(         X86XSAVEZMMHI256, aHi256Regs[3]),
     324    SSMFIELD_ENTRY(         X86XSAVEZMMHI256, aHi256Regs[4]),
     325    SSMFIELD_ENTRY(         X86XSAVEZMMHI256, aHi256Regs[5]),
     326    SSMFIELD_ENTRY(         X86XSAVEZMMHI256, aHi256Regs[6]),
     327    SSMFIELD_ENTRY(         X86XSAVEZMMHI256, aHi256Regs[7]),
     328    SSMFIELD_ENTRY(         X86XSAVEZMMHI256, aHi256Regs[8]),
     329    SSMFIELD_ENTRY(         X86XSAVEZMMHI256, aHi256Regs[9]),
     330    SSMFIELD_ENTRY(         X86XSAVEZMMHI256, aHi256Regs[10]),
     331    SSMFIELD_ENTRY(         X86XSAVEZMMHI256, aHi256Regs[11]),
     332    SSMFIELD_ENTRY(         X86XSAVEZMMHI256, aHi256Regs[12]),
     333    SSMFIELD_ENTRY(         X86XSAVEZMMHI256, aHi256Regs[13]),
     334    SSMFIELD_ENTRY(         X86XSAVEZMMHI256, aHi256Regs[14]),
     335    SSMFIELD_ENTRY(         X86XSAVEZMMHI256, aHi256Regs[15]),
     336    SSMFIELD_ENTRY_TERM()
     337};
     338
     339/** Saved state field descriptors for X86XSAVEZMM16HI. */
     340static const SSMFIELD g_aCpumZmm16HiFields[] =
     341{
     342    SSMFIELD_ENTRY(         X86XSAVEZMM16HI, aRegs[0]),
     343    SSMFIELD_ENTRY(         X86XSAVEZMM16HI, aRegs[1]),
     344    SSMFIELD_ENTRY(         X86XSAVEZMM16HI, aRegs[2]),
     345    SSMFIELD_ENTRY(         X86XSAVEZMM16HI, aRegs[3]),
     346    SSMFIELD_ENTRY(         X86XSAVEZMM16HI, aRegs[4]),
     347    SSMFIELD_ENTRY(         X86XSAVEZMM16HI, aRegs[5]),
     348    SSMFIELD_ENTRY(         X86XSAVEZMM16HI, aRegs[6]),
     349    SSMFIELD_ENTRY(         X86XSAVEZMM16HI, aRegs[7]),
     350    SSMFIELD_ENTRY(         X86XSAVEZMM16HI, aRegs[8]),
     351    SSMFIELD_ENTRY(         X86XSAVEZMM16HI, aRegs[9]),
     352    SSMFIELD_ENTRY(         X86XSAVEZMM16HI, aRegs[10]),
     353    SSMFIELD_ENTRY(         X86XSAVEZMM16HI, aRegs[11]),
     354    SSMFIELD_ENTRY(         X86XSAVEZMM16HI, aRegs[12]),
     355    SSMFIELD_ENTRY(         X86XSAVEZMM16HI, aRegs[13]),
     356    SSMFIELD_ENTRY(         X86XSAVEZMM16HI, aRegs[14]),
     357    SSMFIELD_ENTRY(         X86XSAVEZMM16HI, aRegs[15]),
     358    SSMFIELD_ENTRY_TERM()
     359};
     360
     361
    251362
    252363/** Saved state field descriptors for CPUMCTX in V4.1 before the hidden selector
     
    428539    SSMFIELD_ENTRY(         X86FXSTATE, aXMM[15]),
    429540    SSMFIELD_ENTRY_IGNORE(  X86FXSTATE, au32RsrvdRest),
     541    SSMFIELD_ENTRY_IGNORE(  X86FXSTATE, au32RsrvdForSoftware),
    430542    SSMFIELD_ENTRY_TERM()
    431543};
     
    10261138     * Save.
    10271139     */
    1028     for (VMCPUID i = 0; i < pVM->cCpus; i++)
    1029     {
    1030         PVMCPU pVCpu = &pVM->aCpus[i];
    1031         SSMR3PutStructEx(pSSM, &pVCpu->cpum.s.Hyper.pXStateR3->x87, sizeof(*pVCpu->cpum.s.Hyper.pXStateR3),
    1032                          SSMSTRUCT_FLAGS_NO_TAIL_MARKER, g_aCpumX87Fields, NULL);
    1033         SSMR3PutStructEx(pSSM, &pVCpu->cpum.s.Hyper, sizeof(pVCpu->cpum.s.Hyper),
    1034                          SSMSTRUCT_FLAGS_NO_LEAD_MARKER, g_aCpumCtxFields, NULL);
    1035     }
    1036 
    10371140    SSMR3PutU32(pSSM, pVM->cCpus);
    10381141    SSMR3PutU32(pSSM, sizeof(pVM->aCpus[0].cpum.s.GuestMsrs.msr));
     
    10411144        PVMCPU pVCpu = &pVM->aCpus[iCpu];
    10421145
    1043         SSMR3PutStructEx(pSSM, &pVCpu->cpum.s.Guest.pXStateR3->x87, sizeof(*pVCpu->cpum.s.Guest.pXStateR3),
    1044                          SSMSTRUCT_FLAGS_NO_TAIL_MARKER, g_aCpumX87Fields, NULL);
    1045         SSMR3PutStructEx(pSSM, &pVCpu->cpum.s.Guest, sizeof(pVCpu->cpum.s.Guest),
    1046                          SSMSTRUCT_FLAGS_NO_LEAD_MARKER, g_aCpumCtxFields, NULL);
     1146        SSMR3PutStructEx(pSSM, &pVCpu->cpum.s.Hyper,     sizeof(pVCpu->cpum.s.Hyper),     0, g_aCpumCtxFields, NULL);
     1147
     1148        PCPUMCTX pGstCtx = &pVCpu->cpum.s.Guest;
     1149        SSMR3PutStructEx(pSSM, pGstCtx,                  sizeof(*pGstCtx),                0, g_aCpumCtxFields, NULL);
     1150        SSMR3PutStructEx(pSSM, &pGstCtx->pXStateR3->x87, sizeof(pGstCtx->pXStateR3->x87), 0, g_aCpumX87Fields, NULL);
     1151        if (pGstCtx->fXStateMask != 0)
     1152            SSMR3PutStructEx(pSSM, &pGstCtx->pXStateR3->Hdr, sizeof(pGstCtx->pXStateR3->Hdr), 0, g_aCpumXSaveHdrFields, NULL);
     1153        if (pGstCtx->fXStateMask & XSAVE_C_YMM)
     1154        {
     1155            PCX86XSAVEYMMHI pYmmHiCtx = CPUMCTX_XSAVE_C_PTR(pGstCtx, XSAVE_C_YMM_BIT, PCX86XSAVEYMMHI);
     1156            SSMR3PutStructEx(pSSM, pYmmHiCtx, sizeof(*pYmmHiCtx), SSMSTRUCT_FLAGS_FULL_STRUCT, g_aCpumYmmHiFields, NULL);
     1157        }
     1158        if (pGstCtx->fXStateMask & XSAVE_C_BNDREGS)
     1159        {
     1160            PCX86XSAVEBNDREGS pBndRegs = CPUMCTX_XSAVE_C_PTR(pGstCtx, XSAVE_C_BNDREGS_BIT, PCX86XSAVEBNDREGS);
     1161            SSMR3PutStructEx(pSSM, pBndRegs, sizeof(*pBndRegs), SSMSTRUCT_FLAGS_FULL_STRUCT, g_aCpumBndRegsFields, NULL);
     1162        }
     1163        if (pGstCtx->fXStateMask & XSAVE_C_BNDCSR)
     1164        {
     1165            PCX86XSAVEBNDCFG pBndCfg = CPUMCTX_XSAVE_C_PTR(pGstCtx, XSAVE_C_BNDCSR_BIT, PCX86XSAVEBNDCFG);
     1166            SSMR3PutStructEx(pSSM, pBndCfg, sizeof(*pBndCfg), SSMSTRUCT_FLAGS_FULL_STRUCT, g_aCpumBndCfgFields, NULL);
     1167        }
     1168        if (pGstCtx->fXStateMask & XSAVE_C_ZMM_HI256)
     1169        {
     1170            PCX86XSAVEZMMHI256 pZmmHi256 = CPUMCTX_XSAVE_C_PTR(pGstCtx, XSAVE_C_ZMM_HI256_BIT, PCX86XSAVEZMMHI256);
     1171            SSMR3PutStructEx(pSSM, pZmmHi256, sizeof(*pZmmHi256), SSMSTRUCT_FLAGS_FULL_STRUCT, g_aCpumZmmHi256Fields, NULL);
     1172        }
     1173        if (pGstCtx->fXStateMask & XSAVE_C_ZMM_16HI)
     1174        {
     1175            PCX86XSAVEZMM16HI pZmm16Hi = CPUMCTX_XSAVE_C_PTR(pGstCtx, XSAVE_C_ZMM_16HI_BIT, PCX86XSAVEZMM16HI);
     1176            SSMR3PutStructEx(pSSM, pZmm16Hi, sizeof(*pZmm16Hi), SSMSTRUCT_FLAGS_FULL_STRUCT, g_aCpumZmm16HiFields, NULL);
     1177        }
     1178
    10471179        SSMR3PutU32(pSSM, pVCpu->cpum.s.fUseFlags);
    10481180        SSMR3PutU32(pSSM, pVCpu->cpum.s.fChanged);
     
    10721204static DECLCALLBACK(int) cpumR3LoadExec(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
    10731205{
     1206    int rc; /* Only for AssertRCReturn use. */
     1207
    10741208    /*
    10751209     * Validate version.
    10761210     */
    1077     if (    uVersion != CPUM_SAVED_STATE_VERSION
     1211    if (    uVersion != CPUM_SAVED_STATE_VERSION_XSAVE
     1212        &&  uVersion != CPUM_SAVED_STATE_VERSION_GOOD_CPUID_COUNT
    10781213        &&  uVersion != CPUM_SAVED_STATE_VERSION_BAD_CPUID_COUNT
    10791214        &&  uVersion != CPUM_SAVED_STATE_VERSION_PUT_STRUCT
     
    11011236            SSMR3HandleSetGCPtrSize(pSSM, HC_ARCH_BITS == 32 ? sizeof(RTGCPTR32) : sizeof(RTGCPTR));
    11021237
     1238        /*
     1239         * Figure x86 and ctx field definitions to use for older states.
     1240         */
    11031241        uint32_t const  fLoad = uVersion > CPUM_SAVED_STATE_VERSION_MEM ? 0 : SSMSTRUCT_FLAGS_MEM_BAND_AID_RELAXED;
    11041242        PCSSMFIELD      paCpumCtx1Fields = g_aCpumX87Fields;
     
    11161254
    11171255        /*
    1118          * Restore.
     1256         * The hyper state used to preceed the CPU count.  Starting with
     1257         * XSAVE it was moved down till after we've got the count.
    11191258         */
    1120         for (VMCPUID iCpu = 0; iCpu < pVM->cCpus; iCpu++)
     1259        if (uVersion < CPUM_SAVED_STATE_VERSION_XSAVE)
    11211260        {
    1122             PVMCPU   pVCpu = &pVM->aCpus[iCpu];
    1123             uint64_t uCR3  = pVCpu->cpum.s.Hyper.cr3;
    1124             uint64_t uRSP  = pVCpu->cpum.s.Hyper.rsp; /* see VMMR3Relocate(). */
    1125             /** @todo drop the FPU bits here! */
    1126             SSMR3GetStructEx(pSSM, &pVCpu->cpum.s.Hyper.pXStateR3->x87, sizeof(pVCpu->cpum.s.Hyper.pXStateR3->x87),
    1127                              fLoad | SSMSTRUCT_FLAGS_NO_TAIL_MARKER, paCpumCtx1Fields, NULL);
    1128             SSMR3GetStructEx(pSSM, &pVCpu->cpum.s.Hyper, sizeof(pVCpu->cpum.s.Hyper),
    1129                              fLoad | SSMSTRUCT_FLAGS_NO_LEAD_MARKER, paCpumCtx2Fields, NULL);
    1130             pVCpu->cpum.s.Hyper.cr3 = uCR3;
    1131             pVCpu->cpum.s.Hyper.rsp = uRSP;
     1261            for (VMCPUID iCpu = 0; iCpu < pVM->cCpus; iCpu++)
     1262            {
     1263                PVMCPU      pVCpu = &pVM->aCpus[iCpu];
     1264                X86FXSTATE  Ign;
     1265                SSMR3GetStructEx(pSSM, &Ign, sizeof(Ign), fLoad | SSMSTRUCT_FLAGS_NO_TAIL_MARKER, paCpumCtx1Fields, NULL);
     1266                uint64_t    uCR3  = pVCpu->cpum.s.Hyper.cr3;
     1267                uint64_t    uRSP  = pVCpu->cpum.s.Hyper.rsp; /* see VMMR3Relocate(). */
     1268                SSMR3GetStructEx(pSSM, &pVCpu->cpum.s.Hyper, sizeof(pVCpu->cpum.s.Hyper),
     1269                                 fLoad | SSMSTRUCT_FLAGS_NO_LEAD_MARKER, paCpumCtx2Fields, NULL);
     1270                pVCpu->cpum.s.Hyper.cr3 = uCR3;
     1271                pVCpu->cpum.s.Hyper.rsp = uRSP;
     1272            }
    11321273        }
    11331274
     
    11351276        {
    11361277            uint32_t cCpus;
    1137             int rc = SSMR3GetU32(pSSM, &cCpus); AssertRCReturn(rc, rc);
     1278            rc = SSMR3GetU32(pSSM, &cCpus); AssertRCReturn(rc, rc);
    11381279            AssertLogRelMsgReturn(cCpus == pVM->cCpus, ("Mismatching CPU counts: saved: %u; configured: %u \n", cCpus, pVM->cCpus),
    11391280                                  VERR_SSM_UNEXPECTED_DATA);
     
    11471288        if (uVersion > CPUM_SAVED_STATE_VERSION_NO_MSR_SIZE)
    11481289        {
    1149             int rc = SSMR3GetU32(pSSM, &cbMsrs); AssertRCReturn(rc, rc);
     1290            rc = SSMR3GetU32(pSSM, &cbMsrs); AssertRCReturn(rc, rc);
    11501291            AssertLogRelMsgReturn(RT_ALIGN(cbMsrs, sizeof(uint64_t)) == cbMsrs, ("Size of MSRs is misaligned: %#x\n", cbMsrs),
    11511292                                  VERR_SSM_UNEXPECTED_DATA);
     
    11541295        }
    11551296
     1297        /*
     1298         * Do the per-CPU restoring.
     1299         */
    11561300        for (VMCPUID iCpu = 0; iCpu < pVM->cCpus; iCpu++)
    11571301        {
    1158             PVMCPU  pVCpu = &pVM->aCpus[iCpu];
    1159             SSMR3GetStructEx(pSSM, &pVCpu->cpum.s.Guest.pXStateR3->x87, sizeof(pVCpu->cpum.s.Guest.pXStateR3->x87),
    1160                              fLoad | SSMSTRUCT_FLAGS_NO_TAIL_MARKER, paCpumCtx1Fields, NULL);
    1161             SSMR3GetStructEx(pSSM, &pVCpu->cpum.s.Guest, sizeof(pVCpu->cpum.s.Guest),
    1162                              fLoad | SSMSTRUCT_FLAGS_NO_LEAD_MARKER, paCpumCtx2Fields, NULL);
     1302            PVMCPU   pVCpu = &pVM->aCpus[iCpu];
     1303            PCPUMCTX pGstCtx = &pVCpu->cpum.s.Guest;
     1304
     1305            if (uVersion >= CPUM_SAVED_STATE_VERSION_XSAVE)
     1306            {
     1307                /*
     1308                 * The XSAVE saved state layout moved the hyper state down here.
     1309                 */
     1310                uint64_t    uCR3  = pVCpu->cpum.s.Hyper.cr3;
     1311                uint64_t    uRSP  = pVCpu->cpum.s.Hyper.rsp; /* see VMMR3Relocate(). */
     1312                rc = SSMR3GetStructEx(pSSM, &pVCpu->cpum.s.Hyper,     sizeof(pVCpu->cpum.s.Hyper),     0, g_aCpumCtxFields, NULL);
     1313                pVCpu->cpum.s.Hyper.cr3 = uCR3;
     1314                pVCpu->cpum.s.Hyper.rsp = uRSP;
     1315                AssertRCReturn(rc, rc);
     1316
     1317                /*
     1318                 * Start by restoring the CPUMCTX structure and the X86FXSAVE bits of the extended state.
     1319                 */
     1320                rc = SSMR3GetStructEx(pSSM, pGstCtx,                  sizeof(*pGstCtx),                0, g_aCpumCtxFields, NULL);
     1321                rc = SSMR3GetStructEx(pSSM, &pGstCtx->pXStateR3->x87, sizeof(pGstCtx->pXStateR3->x87), 0, g_aCpumX87Fields, NULL);
     1322                AssertRCReturn(rc, rc);
     1323
     1324                /* Check that the xsave/xrstor mask is valid (invalid results in #GP). */
     1325                if (pGstCtx->fXStateMask != 0)
     1326                {
     1327                    AssertLogRelMsgReturn(!(pGstCtx->fXStateMask & ~pVM->cpum.s.fXStateGuestMask),
     1328                                          ("fXStateMask=%#RX64 fXStateGuestMask=%#RX64\n",
     1329                                           pGstCtx->fXStateMask, pVM->cpum.s.fXStateGuestMask),
     1330                                          VERR_CPUM_INCOMPATIBLE_XSAVE_COMP_MASK);
     1331                    AssertLogRelMsgReturn(pGstCtx->fXStateMask & XSAVE_C_X87,
     1332                                          ("fXStateMask=%#RX64\n", pGstCtx->fXStateMask), VERR_CPUM_INVALID_XSAVE_COMP_MASK);
     1333                    AssertLogRelMsgReturn((pGstCtx->fXStateMask & (XSAVE_C_SSE | XSAVE_C_YMM)) != XSAVE_C_YMM,
     1334                                          ("fXStateMask=%#RX64\n", pGstCtx->fXStateMask), VERR_CPUM_INVALID_XSAVE_COMP_MASK);
     1335                    AssertLogRelMsgReturn(   (pGstCtx->fXStateMask & (XSAVE_C_OPMASK | XSAVE_C_ZMM_HI256 | XSAVE_C_ZMM_16HI)) == 0
     1336                                          ||    (pGstCtx->fXStateMask & (XSAVE_C_SSE | XSAVE_C_YMM | XSAVE_C_OPMASK | XSAVE_C_ZMM_HI256 | XSAVE_C_ZMM_16HI))
     1337                                             ==                         (XSAVE_C_SSE | XSAVE_C_YMM | XSAVE_C_OPMASK | XSAVE_C_ZMM_HI256 | XSAVE_C_ZMM_16HI),
     1338                                          ("fXStateMask=%#RX64\n", pGstCtx->fXStateMask), VERR_CPUM_INVALID_XSAVE_COMP_MASK);
     1339                }
     1340
     1341                /* Check that the XCR0 mask is valid (invalid results in #GP). */
     1342                AssertLogRelMsgReturn(pGstCtx->aXcr[0] & XSAVE_C_X87, ("xcr0=%#RX64\n", pGstCtx->aXcr[0]), VERR_CPUM_INVALID_XCR0);
     1343                if (pGstCtx->aXcr[0] != XSAVE_C_X87)
     1344                {
     1345                    AssertLogRelMsgReturn(!(pGstCtx->aXcr[0] & ~(pGstCtx->fXStateMask | XSAVE_C_X87)),
     1346                                          ("xcr0=%#RX64 fXStateMask=%#RX64\n", pGstCtx->aXcr[0], pGstCtx->fXStateMask),
     1347                                          VERR_CPUM_INVALID_XCR0);
     1348                    AssertLogRelMsgReturn(pGstCtx->aXcr[0] & XSAVE_C_X87,
     1349                                          ("xcr0=%#RX64\n", pGstCtx->aXcr[0]), VERR_CPUM_INVALID_XSAVE_COMP_MASK);
     1350                    AssertLogRelMsgReturn((pGstCtx->aXcr[0] & (XSAVE_C_SSE | XSAVE_C_YMM)) != XSAVE_C_YMM,
     1351                                          ("xcr0=%#RX64\n", pGstCtx->aXcr[0]), VERR_CPUM_INVALID_XSAVE_COMP_MASK);
     1352                    AssertLogRelMsgReturn(   (pGstCtx->aXcr[0] & (XSAVE_C_OPMASK | XSAVE_C_ZMM_HI256 | XSAVE_C_ZMM_16HI)) == 0
     1353                                          ||    (pGstCtx->aXcr[0] & (XSAVE_C_SSE | XSAVE_C_YMM | XSAVE_C_OPMASK | XSAVE_C_ZMM_HI256 | XSAVE_C_ZMM_16HI))
     1354                                             ==                     (XSAVE_C_SSE | XSAVE_C_YMM | XSAVE_C_OPMASK | XSAVE_C_ZMM_HI256 | XSAVE_C_ZMM_16HI),
     1355                                          ("xcr0=%#RX64\n", pGstCtx->aXcr[0]), VERR_CPUM_INVALID_XSAVE_COMP_MASK);
     1356                }
     1357
     1358                /* Check that the XCR1 is zero, as we don't implement it yet. */
     1359                AssertLogRelMsgReturn(!pGstCtx->aXcr[1], ("xcr1=%#RX64\n", pGstCtx->aXcr[1]), VERR_SSM_DATA_UNIT_FORMAT_CHANGED);
     1360
     1361                /*
     1362                 * Restore the individual extended state components we support.
     1363                 */
     1364                if (pGstCtx->fXStateMask != 0)
     1365                {
     1366                    rc = SSMR3GetStructEx(pSSM, &pGstCtx->pXStateR3->Hdr, sizeof(pGstCtx->pXStateR3->Hdr),
     1367                                          0, g_aCpumXSaveHdrFields, NULL);
     1368                    AssertRCReturn(rc, rc);
     1369                    AssertLogRelMsgReturn(!(pGstCtx->pXStateR3->Hdr.bmXState & ~pGstCtx->fXStateMask),
     1370                                          ("bmXState=%#RX64 fXStateMask=%#RX64\n",
     1371                                           pGstCtx->pXStateR3->Hdr.bmXState, pGstCtx->fXStateMask),
     1372                                          VERR_CPUM_INVALID_XSAVE_HDR);
     1373                }
     1374                if (pGstCtx->fXStateMask & XSAVE_C_YMM)
     1375                {
     1376                    PX86XSAVEYMMHI pYmmHiCtx = CPUMCTX_XSAVE_C_PTR(pGstCtx, XSAVE_C_YMM_BIT, PX86XSAVEYMMHI);
     1377                    SSMR3GetStructEx(pSSM, pYmmHiCtx, sizeof(*pYmmHiCtx), SSMSTRUCT_FLAGS_FULL_STRUCT, g_aCpumYmmHiFields, NULL);
     1378                }
     1379                if (pGstCtx->fXStateMask & XSAVE_C_BNDREGS)
     1380                {
     1381                    PX86XSAVEBNDREGS pBndRegs = CPUMCTX_XSAVE_C_PTR(pGstCtx, XSAVE_C_BNDREGS_BIT, PX86XSAVEBNDREGS);
     1382                    SSMR3GetStructEx(pSSM, pBndRegs, sizeof(*pBndRegs), SSMSTRUCT_FLAGS_FULL_STRUCT, g_aCpumBndRegsFields, NULL);
     1383                }
     1384                if (pGstCtx->fXStateMask & XSAVE_C_BNDCSR)
     1385                {
     1386                    PX86XSAVEBNDCFG pBndCfg = CPUMCTX_XSAVE_C_PTR(pGstCtx, XSAVE_C_BNDCSR_BIT, PX86XSAVEBNDCFG);
     1387                    SSMR3GetStructEx(pSSM, pBndCfg, sizeof(*pBndCfg), SSMSTRUCT_FLAGS_FULL_STRUCT, g_aCpumBndCfgFields, NULL);
     1388                }
     1389                if (pGstCtx->fXStateMask & XSAVE_C_ZMM_HI256)
     1390                {
     1391                    PX86XSAVEZMMHI256 pZmmHi256 = CPUMCTX_XSAVE_C_PTR(pGstCtx, XSAVE_C_ZMM_HI256_BIT, PX86XSAVEZMMHI256);
     1392                    SSMR3GetStructEx(pSSM, pZmmHi256, sizeof(*pZmmHi256), SSMSTRUCT_FLAGS_FULL_STRUCT, g_aCpumZmmHi256Fields, NULL);
     1393                }
     1394                if (pGstCtx->fXStateMask & XSAVE_C_ZMM_16HI)
     1395                {
     1396                    PX86XSAVEZMM16HI pZmm16Hi = CPUMCTX_XSAVE_C_PTR(pGstCtx, XSAVE_C_ZMM_16HI_BIT, PX86XSAVEZMM16HI);
     1397                    SSMR3GetStructEx(pSSM, pZmm16Hi, sizeof(*pZmm16Hi), SSMSTRUCT_FLAGS_FULL_STRUCT, g_aCpumZmm16HiFields, NULL);
     1398                }
     1399            }
     1400            else
     1401            {
     1402                /*
     1403                 * Pre XSAVE saved state.
     1404                 */
     1405                SSMR3GetStructEx(pSSM, &pGstCtx->pXStateR3->x87, sizeof(pGstCtx->pXStateR3->x87),
     1406                                 fLoad | SSMSTRUCT_FLAGS_NO_TAIL_MARKER, paCpumCtx1Fields, NULL);
     1407                SSMR3GetStructEx(pSSM, pGstCtx, sizeof(*pGstCtx), fLoad | SSMSTRUCT_FLAGS_NO_LEAD_MARKER, paCpumCtx2Fields, NULL);
     1408            }
     1409
     1410            /*
     1411             * Restore a couple of flags and the MSRs.
     1412             */
    11631413            SSMR3GetU32(pSSM, &pVCpu->cpum.s.fUseFlags);
    11641414            SSMR3GetU32(pSSM, &pVCpu->cpum.s.fChanged);
     1415
    11651416            if (uVersion > CPUM_SAVED_STATE_VERSION_NO_MSR_SIZE)
    1166                 SSMR3GetMem(pSSM, &pVCpu->cpum.s.GuestMsrs.au64[0], cbMsrs);
     1417                rc = SSMR3GetMem(pSSM, &pVCpu->cpum.s.GuestMsrs.au64[0], cbMsrs);
    11671418            else if (uVersion >= CPUM_SAVED_STATE_VERSION_VER3_0)
    11681419            {
    11691420                SSMR3GetMem(pSSM, &pVCpu->cpum.s.GuestMsrs.au64[0], 2 * sizeof(uint64_t)); /* Restore two MSRs. */
    1170                 SSMR3Skip(pSSM, 62 * sizeof(uint64_t));
     1421                rc = SSMR3Skip(pSSM, 62 * sizeof(uint64_t));
    11711422            }
     1423            AssertRCReturn(rc, rc);
    11721424
    11731425            /* REM and other may have cleared must-be-one fields in DR6 and
    11741426               DR7, fix these. */
    1175             pVCpu->cpum.s.Guest.dr[6] &= ~(X86_DR6_RAZ_MASK | X86_DR6_MBZ_MASK);
    1176             pVCpu->cpum.s.Guest.dr[6] |= X86_DR6_RA1_MASK;
    1177             pVCpu->cpum.s.Guest.dr[7] &= ~(X86_DR7_RAZ_MASK | X86_DR7_MBZ_MASK);
    1178             pVCpu->cpum.s.Guest.dr[7] |= X86_DR7_RA1_MASK;
     1427            pGstCtx->dr[6] &= ~(X86_DR6_RAZ_MASK | X86_DR6_MBZ_MASK);
     1428            pGstCtx->dr[6] |= X86_DR6_RA1_MASK;
     1429            pGstCtx->dr[7] &= ~(X86_DR7_RAZ_MASK | X86_DR7_MBZ_MASK);
     1430            pGstCtx->dr[7] |= X86_DR7_RA1_MASK;
    11791431        }
    11801432
     
    12461498     * Guest CPUIDs.
    12471499     */
    1248     if (uVersion > CPUM_SAVED_STATE_VERSION_VER3_0)
     1500    if (uVersion >= CPUM_SAVED_STATE_VERSION_VER3_2)
    12491501        return cpumR3LoadCpuId(pVM, pSSM, uVersion);
    1250 
    1251     /** @todo Merge the code below into cpumR3LoadCpuId when we've found out what is
    1252      *        actually required. */
    1253 
    1254     /*
    1255      * Restore the CPUID leaves.
    1256      *
    1257      * Note that we support restoring less than the current amount of standard
    1258      * leaves because we've been allowed more is newer version of VBox.
    1259      */
    1260     uint32_t cElements;
    1261     int rc = SSMR3GetU32(pSSM, &cElements); AssertRCReturn(rc, rc);
    1262     if (cElements > RT_ELEMENTS(pVM->cpum.s.aGuestCpuIdPatmStd))
    1263         return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
    1264     SSMR3GetMem(pSSM, &pVM->cpum.s.aGuestCpuIdPatmStd[0], cElements*sizeof(pVM->cpum.s.aGuestCpuIdPatmStd[0]));
    1265 
    1266     rc = SSMR3GetU32(pSSM, &cElements); AssertRCReturn(rc, rc);
    1267     if (cElements != RT_ELEMENTS(pVM->cpum.s.aGuestCpuIdPatmExt))
    1268         return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
    1269     SSMR3GetMem(pSSM, &pVM->cpum.s.aGuestCpuIdPatmExt[0], sizeof(pVM->cpum.s.aGuestCpuIdPatmExt));
    1270 
    1271     rc = SSMR3GetU32(pSSM, &cElements); AssertRCReturn(rc, rc);
    1272     if (cElements != RT_ELEMENTS(pVM->cpum.s.aGuestCpuIdPatmCentaur))
    1273         return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
    1274     SSMR3GetMem(pSSM, &pVM->cpum.s.aGuestCpuIdPatmCentaur[0], sizeof(pVM->cpum.s.aGuestCpuIdPatmCentaur));
    1275 
    1276     SSMR3GetMem(pSSM, &pVM->cpum.s.GuestInfo.DefCpuId, sizeof(pVM->cpum.s.GuestInfo.DefCpuId));
    1277 
    1278     /*
    1279      * Check that the basic cpuid id information is unchanged.
    1280      */
    1281     /** @todo we should check the 64 bits capabilities too! */
    1282     uint32_t au32CpuId[8] = {0,0,0,0, 0,0,0,0};
    1283     ASMCpuIdExSlow(0, 0, 0, 0, &au32CpuId[0], &au32CpuId[1], &au32CpuId[2], &au32CpuId[3]);
    1284     ASMCpuIdExSlow(1, 0, 0, 0, &au32CpuId[4], &au32CpuId[5], &au32CpuId[6], &au32CpuId[7]);
    1285     uint32_t au32CpuIdSaved[8];
    1286     rc = SSMR3GetMem(pSSM, &au32CpuIdSaved[0], sizeof(au32CpuIdSaved));
    1287     if (RT_SUCCESS(rc))
    1288     {
    1289         /* Ignore CPU stepping. */
    1290         au32CpuId[4]      &=  0xfffffff0;
    1291         au32CpuIdSaved[4] &=  0xfffffff0;
    1292 
    1293         /* Ignore APIC ID (AMD specs). */
    1294         au32CpuId[5]      &= ~0xff000000;
    1295         au32CpuIdSaved[5] &= ~0xff000000;
    1296 
    1297         /* Ignore the number of Logical CPUs (AMD specs). */
    1298         au32CpuId[5]      &= ~0x00ff0000;
    1299         au32CpuIdSaved[5] &= ~0x00ff0000;
    1300 
    1301         /* Ignore some advanced capability bits, that we don't expose to the guest. */
    1302         au32CpuId[6]      &= ~(   X86_CPUID_FEATURE_ECX_DTES64
    1303                                |  X86_CPUID_FEATURE_ECX_VMX
    1304                                |  X86_CPUID_FEATURE_ECX_SMX
    1305                                |  X86_CPUID_FEATURE_ECX_EST
    1306                                |  X86_CPUID_FEATURE_ECX_TM2
    1307                                |  X86_CPUID_FEATURE_ECX_CNTXID
    1308                                |  X86_CPUID_FEATURE_ECX_TPRUPDATE
    1309                                |  X86_CPUID_FEATURE_ECX_PDCM
    1310                                |  X86_CPUID_FEATURE_ECX_DCA
    1311                                |  X86_CPUID_FEATURE_ECX_X2APIC
    1312                               );
    1313         au32CpuIdSaved[6] &= ~(   X86_CPUID_FEATURE_ECX_DTES64
    1314                                |  X86_CPUID_FEATURE_ECX_VMX
    1315                                |  X86_CPUID_FEATURE_ECX_SMX
    1316                                |  X86_CPUID_FEATURE_ECX_EST
    1317                                |  X86_CPUID_FEATURE_ECX_TM2
    1318                                |  X86_CPUID_FEATURE_ECX_CNTXID
    1319                                |  X86_CPUID_FEATURE_ECX_TPRUPDATE
    1320                                |  X86_CPUID_FEATURE_ECX_PDCM
    1321                                |  X86_CPUID_FEATURE_ECX_DCA
    1322                                |  X86_CPUID_FEATURE_ECX_X2APIC
    1323                               );
    1324 
    1325         /* Make sure we don't forget to update the masks when enabling
    1326          * features in the future.
    1327          */
    1328         AssertRelease(!(pVM->cpum.s.aGuestCpuIdPatmStd[1].uEcx &
    1329                               (   X86_CPUID_FEATURE_ECX_DTES64
    1330                                |  X86_CPUID_FEATURE_ECX_VMX
    1331                                |  X86_CPUID_FEATURE_ECX_SMX
    1332                                |  X86_CPUID_FEATURE_ECX_EST
    1333                                |  X86_CPUID_FEATURE_ECX_TM2
    1334                                |  X86_CPUID_FEATURE_ECX_CNTXID
    1335                                |  X86_CPUID_FEATURE_ECX_TPRUPDATE
    1336                                |  X86_CPUID_FEATURE_ECX_PDCM
    1337                                |  X86_CPUID_FEATURE_ECX_DCA
    1338                                |  X86_CPUID_FEATURE_ECX_X2APIC
    1339                               )));
    1340         /* do the compare */
    1341         if (memcmp(au32CpuIdSaved, au32CpuId, sizeof(au32CpuIdSaved)))
    1342         {
    1343             if (SSMR3HandleGetAfter(pSSM) == SSMAFTER_DEBUG_IT)
    1344                 LogRel(("cpumR3LoadExec: CpuId mismatch! (ignored due to SSMAFTER_DEBUG_IT)\n"
    1345                         "Saved=%.*Rhxs\n"
    1346                         "Real =%.*Rhxs\n",
    1347                         sizeof(au32CpuIdSaved), au32CpuIdSaved,
    1348                         sizeof(au32CpuId), au32CpuId));
    1349             else
    1350             {
    1351                 LogRel(("cpumR3LoadExec: CpuId mismatch!\n"
    1352                         "Saved=%.*Rhxs\n"
    1353                         "Real =%.*Rhxs\n",
    1354                         sizeof(au32CpuIdSaved), au32CpuIdSaved,
    1355                         sizeof(au32CpuId), au32CpuId));
    1356                 rc = VERR_SSM_LOAD_CPUID_MISMATCH;
    1357             }
    1358         }
    1359     }
    1360 
    1361     return rc;
     1502    return cpumR3LoadCpuIdPre32(pVM, pSSM, uVersion);
    13621503}
    13631504
     
    16101751                    pszPrefix, pCtx->SysEnter.cs, pCtx->SysEnter.eip, pCtx->SysEnter.esp);
    16111752
    1612             PX86FXSTATE pFpuCtx = &pCtx->CTX_SUFF(pXState)->x87;
    1613             pHlp->pfnPrintf(pHlp,
    1614                 "%sFCW=%04x %sFSW=%04x %sFTW=%04x %sFOP=%04x %sMXCSR=%08x %sMXCSR_MASK=%08x\n"
    1615                 "%sFPUIP=%08x %sCS=%04x %sRsrvd1=%04x  %sFPUDP=%08x %sDS=%04x %sRsvrd2=%04x\n"
    1616                 ,
    1617                 pszPrefix, pFpuCtx->FCW,   pszPrefix, pFpuCtx->FSW, pszPrefix, pFpuCtx->FTW, pszPrefix, pFpuCtx->FOP,
    1618                 pszPrefix, pFpuCtx->MXCSR, pszPrefix, pFpuCtx->MXCSR_MASK,
    1619                 pszPrefix, pFpuCtx->FPUIP, pszPrefix, pFpuCtx->CS,  pszPrefix, pFpuCtx->Rsrvd1,
    1620                 pszPrefix, pFpuCtx->FPUDP, pszPrefix, pFpuCtx->DS,  pszPrefix, pFpuCtx->Rsrvd2
    1621                 );
    1622             unsigned iShift = (pFpuCtx->FSW >> 11) & 7;
    1623             for (unsigned iST = 0; iST < RT_ELEMENTS(pFpuCtx->aRegs); iST++)
    1624             {
    1625                 unsigned iFPR        = (iST + iShift) % RT_ELEMENTS(pFpuCtx->aRegs);
    1626                 unsigned uTag        = pFpuCtx->FTW & (1 << iFPR) ? 1 : 0;
    1627                 char     chSign      = pFpuCtx->aRegs[0].au16[4] & 0x8000 ? '-' : '+';
    1628                 unsigned iInteger    = (unsigned)(pFpuCtx->aRegs[0].au64[0] >> 63);
    1629                 uint64_t u64Fraction = pFpuCtx->aRegs[0].au64[0] & UINT64_C(0x7fffffffffffffff);
    1630                 unsigned uExponent   = pFpuCtx->aRegs[0].au16[4] & 0x7fff;
    1631                 /** @todo This isn't entirenly correct and needs more work! */
    1632                 pHlp->pfnPrintf(pHlp,
    1633                                 "%sST(%u)=%sFPR%u={%04RX16'%08RX32'%08RX32} t%d %c%u.%022llu ^ %u (*)",
    1634                                 pszPrefix, iST, pszPrefix, iFPR,
    1635                                 pFpuCtx->aRegs[0].au16[4], pFpuCtx->aRegs[0].au32[1], pFpuCtx->aRegs[0].au32[0],
    1636                                 uTag, chSign, iInteger, u64Fraction, uExponent);
    1637                 if (pFpuCtx->aRegs[0].au16[5] || pFpuCtx->aRegs[0].au16[6] || pFpuCtx->aRegs[0].au16[7])
    1638                     pHlp->pfnPrintf(pHlp, " res={%04RX16,%04RX16,%04RX16}\n",
    1639                                     pFpuCtx->aRegs[0].au16[5], pFpuCtx->aRegs[0].au16[6], pFpuCtx->aRegs[0].au16[7]);
    1640                 else
    1641                     pHlp->pfnPrintf(pHlp, "\n");
    1642             }
    1643 
    1644             pHlp->pfnPrintf(pHlp, "%sXCR0=%016RX64 %sXCR1=%016RX64 %sXSS=%016RX64 (fXStateMask=%016RX64)\n",
     1753            pHlp->pfnPrintf(pHlp, "%sxcr=%016RX64 %sxcr1=%016RX64 %sxss=%016RX64 (fXStateMask=%016RX64)\n",
    16451754                            pszPrefix, pCtx->aXcr[0], pszPrefix, pCtx->aXcr[1],
    16461755                            pszPrefix, UINT64_C(0) /** @todo XSS */, pCtx->fXStateMask);
    1647 
    1648             /* XMM/YMM/ZMM registers. */
    1649             if (pCtx->fXStateMask & XSAVE_C_YMM)
     1756            if (pCtx->CTX_SUFF(pXState))
    16501757            {
    1651                 PCX86XSAVEYMMHI pYmmHiCtx;
    1652                 pYmmHiCtx = (PCX86XSAVEYMMHI)((uint8_t *)pCtx->CTX_SUFF(pXState) + pCtx->aoffXState[XSAVE_C_YMM_BIT]);
    1653                 if (!(pCtx->fXStateMask & XSAVE_C_ZMM_HI256))
     1758                PX86FXSTATE pFpuCtx = &pCtx->CTX_SUFF(pXState)->x87;
     1759                pHlp->pfnPrintf(pHlp,
     1760                    "%sFCW=%04x %sFSW=%04x %sFTW=%04x %sFOP=%04x %sMXCSR=%08x %sMXCSR_MASK=%08x\n"
     1761                    "%sFPUIP=%08x %sCS=%04x %sRsrvd1=%04x  %sFPUDP=%08x %sDS=%04x %sRsvrd2=%04x\n"
     1762                    ,
     1763                    pszPrefix, pFpuCtx->FCW,   pszPrefix, pFpuCtx->FSW, pszPrefix, pFpuCtx->FTW, pszPrefix, pFpuCtx->FOP,
     1764                    pszPrefix, pFpuCtx->MXCSR, pszPrefix, pFpuCtx->MXCSR_MASK,
     1765                    pszPrefix, pFpuCtx->FPUIP, pszPrefix, pFpuCtx->CS,  pszPrefix, pFpuCtx->Rsrvd1,
     1766                    pszPrefix, pFpuCtx->FPUDP, pszPrefix, pFpuCtx->DS,  pszPrefix, pFpuCtx->Rsrvd2
     1767                    );
     1768                unsigned iShift = (pFpuCtx->FSW >> 11) & 7;
     1769                for (unsigned iST = 0; iST < RT_ELEMENTS(pFpuCtx->aRegs); iST++)
     1770                {
     1771                    unsigned iFPR        = (iST + iShift) % RT_ELEMENTS(pFpuCtx->aRegs);
     1772                    unsigned uTag        = pFpuCtx->FTW & (1 << iFPR) ? 1 : 0;
     1773                    char     chSign      = pFpuCtx->aRegs[0].au16[4] & 0x8000 ? '-' : '+';
     1774                    unsigned iInteger    = (unsigned)(pFpuCtx->aRegs[0].au64[0] >> 63);
     1775                    uint64_t u64Fraction = pFpuCtx->aRegs[0].au64[0] & UINT64_C(0x7fffffffffffffff);
     1776                    unsigned uExponent   = pFpuCtx->aRegs[0].au16[4] & 0x7fff;
     1777                    /** @todo This isn't entirenly correct and needs more work! */
     1778                    pHlp->pfnPrintf(pHlp,
     1779                                    "%sST(%u)=%sFPR%u={%04RX16'%08RX32'%08RX32} t%d %c%u.%022llu ^ %u (*)",
     1780                                    pszPrefix, iST, pszPrefix, iFPR,
     1781                                    pFpuCtx->aRegs[0].au16[4], pFpuCtx->aRegs[0].au32[1], pFpuCtx->aRegs[0].au32[0],
     1782                                    uTag, chSign, iInteger, u64Fraction, uExponent);
     1783                    if (pFpuCtx->aRegs[0].au16[5] || pFpuCtx->aRegs[0].au16[6] || pFpuCtx->aRegs[0].au16[7])
     1784                        pHlp->pfnPrintf(pHlp, " res={%04RX16,%04RX16,%04RX16}\n",
     1785                                        pFpuCtx->aRegs[0].au16[5], pFpuCtx->aRegs[0].au16[6], pFpuCtx->aRegs[0].au16[7]);
     1786                    else
     1787                        pHlp->pfnPrintf(pHlp, "\n");
     1788                }
     1789
     1790                /* XMM/YMM/ZMM registers. */
     1791                if (pCtx->fXStateMask & XSAVE_C_YMM)
     1792                {
     1793                    PCX86XSAVEYMMHI pYmmHiCtx = CPUMCTX_XSAVE_C_PTR(pCtx, XSAVE_C_YMM_BIT, PCX86XSAVEYMMHI);
     1794                    if (!(pCtx->fXStateMask & XSAVE_C_ZMM_HI256))
     1795                        for (unsigned i = 0; i < RT_ELEMENTS(pFpuCtx->aXMM); i++)
     1796                            pHlp->pfnPrintf(pHlp, "%sYMM%u%s=%08RX32'%08RX32'%08RX32'%08RX32'%08RX32'%08RX32'%08RX32'%08RX32\n",
     1797                                            pszPrefix, i, i < 10 ? " " : "",
     1798                                            pYmmHiCtx->aYmmHi[i].au32[3],
     1799                                            pYmmHiCtx->aYmmHi[i].au32[2],
     1800                                            pYmmHiCtx->aYmmHi[i].au32[1],
     1801                                            pYmmHiCtx->aYmmHi[i].au32[0],
     1802                                            pFpuCtx->aXMM[i].au32[3],
     1803                                            pFpuCtx->aXMM[i].au32[2],
     1804                                            pFpuCtx->aXMM[i].au32[1],
     1805                                            pFpuCtx->aXMM[i].au32[0]);
     1806                    else
     1807                    {
     1808                        PCX86XSAVEZMMHI256 pZmmHi256 = CPUMCTX_XSAVE_C_PTR(pCtx, XSAVE_C_ZMM_HI256_BIT, PCX86XSAVEZMMHI256);
     1809                        for (unsigned i = 0; i < RT_ELEMENTS(pFpuCtx->aXMM); i++)
     1810                            pHlp->pfnPrintf(pHlp,
     1811                                            "%sZMM%u%s=%08RX32'%08RX32'%08RX32'%08RX32'%08RX32'%08RX32'%08RX32'%08RX32''%08RX32'%08RX32'%08RX32'%08RX32'%08RX32'%08RX32'%08RX32'%08RX32\n",
     1812                                            pszPrefix, i, i < 10 ? " " : "",
     1813                                            pZmmHi256->aHi256Regs[i].au32[7],
     1814                                            pZmmHi256->aHi256Regs[i].au32[6],
     1815                                            pZmmHi256->aHi256Regs[i].au32[5],
     1816                                            pZmmHi256->aHi256Regs[i].au32[4],
     1817                                            pZmmHi256->aHi256Regs[i].au32[3],
     1818                                            pZmmHi256->aHi256Regs[i].au32[2],
     1819                                            pZmmHi256->aHi256Regs[i].au32[1],
     1820                                            pZmmHi256->aHi256Regs[i].au32[0],
     1821                                            pYmmHiCtx->aYmmHi[i].au32[3],
     1822                                            pYmmHiCtx->aYmmHi[i].au32[2],
     1823                                            pYmmHiCtx->aYmmHi[i].au32[1],
     1824                                            pYmmHiCtx->aYmmHi[i].au32[0],
     1825                                            pFpuCtx->aXMM[i].au32[3],
     1826                                            pFpuCtx->aXMM[i].au32[2],
     1827                                            pFpuCtx->aXMM[i].au32[1],
     1828                                            pFpuCtx->aXMM[i].au32[0]);
     1829
     1830                        PCX86XSAVEZMM16HI pZmm16Hi = CPUMCTX_XSAVE_C_PTR(pCtx, XSAVE_C_ZMM_16HI_BIT, PCX86XSAVEZMM16HI);
     1831                        for (unsigned i = 0; i < RT_ELEMENTS(pZmm16Hi->aRegs); i++)
     1832                            pHlp->pfnPrintf(pHlp,
     1833                                            "%sZMM%u=%08RX32'%08RX32'%08RX32'%08RX32'%08RX32'%08RX32'%08RX32'%08RX32''%08RX32'%08RX32'%08RX32'%08RX32'%08RX32'%08RX32'%08RX32'%08RX32\n",
     1834                                            pszPrefix, i + 16,
     1835                                            pZmm16Hi->aRegs[i].au32[15],
     1836                                            pZmm16Hi->aRegs[i].au32[14],
     1837                                            pZmm16Hi->aRegs[i].au32[13],
     1838                                            pZmm16Hi->aRegs[i].au32[12],
     1839                                            pZmm16Hi->aRegs[i].au32[11],
     1840                                            pZmm16Hi->aRegs[i].au32[10],
     1841                                            pZmm16Hi->aRegs[i].au32[9],
     1842                                            pZmm16Hi->aRegs[i].au32[8],
     1843                                            pZmm16Hi->aRegs[i].au32[7],
     1844                                            pZmm16Hi->aRegs[i].au32[6],
     1845                                            pZmm16Hi->aRegs[i].au32[5],
     1846                                            pZmm16Hi->aRegs[i].au32[4],
     1847                                            pZmm16Hi->aRegs[i].au32[3],
     1848                                            pZmm16Hi->aRegs[i].au32[2],
     1849                                            pZmm16Hi->aRegs[i].au32[1],
     1850                                            pZmm16Hi->aRegs[i].au32[0]);
     1851                    }
     1852                }
     1853                else
    16541854                    for (unsigned i = 0; i < RT_ELEMENTS(pFpuCtx->aXMM); i++)
    1655                         pHlp->pfnPrintf(pHlp, "%sYMM%u%s=%08RX32'%08RX32'%08RX32'%08RX32'%08RX32'%08RX32'%08RX32'%08RX32\n",
     1855                        pHlp->pfnPrintf(pHlp,
     1856                                        i & 1
     1857                                        ? "%sXMM%u%s=%08RX32'%08RX32'%08RX32'%08RX32\n"
     1858                                        : "%sXMM%u%s=%08RX32'%08RX32'%08RX32'%08RX32  ",
    16561859                                        pszPrefix, i, i < 10 ? " " : "",
    1657                                         pYmmHiCtx->aYmmHi[i].au32[3],
    1658                                         pYmmHiCtx->aYmmHi[i].au32[2],
    1659                                         pYmmHiCtx->aYmmHi[i].au32[1],
    1660                                         pYmmHiCtx->aYmmHi[i].au32[0],
    16611860                                        pFpuCtx->aXMM[i].au32[3],
    16621861                                        pFpuCtx->aXMM[i].au32[2],
    16631862                                        pFpuCtx->aXMM[i].au32[1],
    16641863                                        pFpuCtx->aXMM[i].au32[0]);
    1665                 else
     1864
     1865                if (pCtx->fXStateMask & XSAVE_C_OPMASK)
    16661866                {
    1667                     PCX86XSAVEZMMHI256 pZmmHi256;
    1668                     pZmmHi256 = (PCX86XSAVEZMMHI256)((uint8_t *)pCtx->CTX_SUFF(pXState) + pCtx->aoffXState[XSAVE_C_ZMM_HI256_BIT]);
    1669                     for (unsigned i = 0; i < RT_ELEMENTS(pFpuCtx->aXMM); i++)
    1670                         pHlp->pfnPrintf(pHlp,
    1671                                         "%sZMM%u%s=%08RX32'%08RX32'%08RX32'%08RX32'%08RX32'%08RX32'%08RX32'%08RX32''%08RX32'%08RX32'%08RX32'%08RX32'%08RX32'%08RX32'%08RX32'%08RX32\n",
    1672                                         pszPrefix, i, i < 10 ? " " : "",
    1673                                         pZmmHi256->aHi256Regs[i].au32[7],
    1674                                         pZmmHi256->aHi256Regs[i].au32[6],
    1675                                         pZmmHi256->aHi256Regs[i].au32[5],
    1676                                         pZmmHi256->aHi256Regs[i].au32[4],
    1677                                         pZmmHi256->aHi256Regs[i].au32[3],
    1678                                         pZmmHi256->aHi256Regs[i].au32[2],
    1679                                         pZmmHi256->aHi256Regs[i].au32[1],
    1680                                         pZmmHi256->aHi256Regs[i].au32[0],
    1681                                         pYmmHiCtx->aYmmHi[i].au32[3],
    1682                                         pYmmHiCtx->aYmmHi[i].au32[2],
    1683                                         pYmmHiCtx->aYmmHi[i].au32[1],
    1684                                         pYmmHiCtx->aYmmHi[i].au32[0],
    1685                                         pFpuCtx->aXMM[i].au32[3],
    1686                                         pFpuCtx->aXMM[i].au32[2],
    1687                                         pFpuCtx->aXMM[i].au32[1],
    1688                                         pFpuCtx->aXMM[i].au32[0]);
    1689 
    1690                     PCX86XSAVEZMM16HI pZmm16Hi;
    1691                     pZmm16Hi = (PCX86XSAVEZMM16HI)((uint8_t *)pCtx->CTX_SUFF(pXState) + pCtx->aoffXState[XSAVE_C_ZMM_16HI_BIT]);
    1692                     for (unsigned i = 0; i < RT_ELEMENTS(pZmm16Hi->aRegs); i++)
    1693                         pHlp->pfnPrintf(pHlp,
    1694                                         "%sZMM%u=%08RX32'%08RX32'%08RX32'%08RX32'%08RX32'%08RX32'%08RX32'%08RX32''%08RX32'%08RX32'%08RX32'%08RX32'%08RX32'%08RX32'%08RX32'%08RX32\n",
    1695                                         pszPrefix, i + 16,
    1696                                         pZmm16Hi->aRegs[i].au32[15],
    1697                                         pZmm16Hi->aRegs[i].au32[14],
    1698                                         pZmm16Hi->aRegs[i].au32[13],
    1699                                         pZmm16Hi->aRegs[i].au32[12],
    1700                                         pZmm16Hi->aRegs[i].au32[11],
    1701                                         pZmm16Hi->aRegs[i].au32[10],
    1702                                         pZmm16Hi->aRegs[i].au32[9],
    1703                                         pZmm16Hi->aRegs[i].au32[8],
    1704                                         pZmm16Hi->aRegs[i].au32[7],
    1705                                         pZmm16Hi->aRegs[i].au32[6],
    1706                                         pZmm16Hi->aRegs[i].au32[5],
    1707                                         pZmm16Hi->aRegs[i].au32[4],
    1708                                         pZmm16Hi->aRegs[i].au32[3],
    1709                                         pZmm16Hi->aRegs[i].au32[2],
    1710                                         pZmm16Hi->aRegs[i].au32[1],
    1711                                         pZmm16Hi->aRegs[i].au32[0]);
     1867                    PCX86XSAVEOPMASK pOpMask;
     1868                    pOpMask = (PCX86XSAVEOPMASK)((uint8_t *)pCtx->CTX_SUFF(pXState) + pCtx->aoffXState[XSAVE_C_OPMASK_BIT]);
     1869                    for (unsigned i = 0; i < RT_ELEMENTS(pOpMask->aKRegs); i += 4)
     1870                        pHlp->pfnPrintf(pHlp, "%sK%u=%016RX64  %sK%u=%016RX64  %sK%u=%016RX64  %sK%u=%016RX64\n",
     1871                                        pszPrefix, i + 0, pOpMask->aKRegs[i + 0],
     1872                                        pszPrefix, i + 1, pOpMask->aKRegs[i + 1],
     1873                                        pszPrefix, i + 2, pOpMask->aKRegs[i + 2],
     1874                                        pszPrefix, i + 3, pOpMask->aKRegs[i + 3]);
    17121875                }
     1876
     1877                if (pCtx->fXStateMask & XSAVE_C_BNDREGS)
     1878                {
     1879                    PCX86XSAVEBNDREGS pBndRegs = CPUMCTX_XSAVE_C_PTR(pCtx, XSAVE_C_BNDREGS_BIT, PCX86XSAVEBNDREGS);
     1880                    for (unsigned i = 0; i < RT_ELEMENTS(pBndRegs->aRegs); i += 2)
     1881                        pHlp->pfnPrintf(pHlp, "%sBNDREG%u=%016RX64/%016RX64  %sBNDREG%u=%016RX64/%016RX64\n",
     1882                                        pszPrefix, i, pBndRegs->aRegs[i].uLowerBound, pBndRegs->aRegs[i].uUpperBound,
     1883                                        pszPrefix, i + 1, pBndRegs->aRegs[i + 1].uLowerBound, pBndRegs->aRegs[i + 1].uUpperBound);
     1884                }
     1885
     1886                if (pCtx->fXStateMask & XSAVE_C_BNDCSR)
     1887                {
     1888                    PCX86XSAVEBNDCFG pBndCfg = CPUMCTX_XSAVE_C_PTR(pCtx, XSAVE_C_BNDCSR_BIT, PCX86XSAVEBNDCFG);
     1889                    pHlp->pfnPrintf(pHlp, "%sBNDCFG.CONFIG=%016RX64 %sBNDCFG.STATUS=%016RX64\n",
     1890                                    pszPrefix, pBndCfg->fConfig, pszPrefix, pBndCfg->fStatus);
     1891                }
     1892
     1893                for (unsigned i = 0; i < RT_ELEMENTS(pFpuCtx->au32RsrvdRest); i++)
     1894                    if (pFpuCtx->au32RsrvdRest[i])
     1895                        pHlp->pfnPrintf(pHlp, "%sRsrvdRest[i]=%RX32 (offset=%#x)\n",
     1896                                        pszPrefix, i, pFpuCtx->au32RsrvdRest[i], RT_OFFSETOF(X86FXSTATE, au32RsrvdRest[i]) );
    17131897            }
    1714             else
    1715                 for (unsigned i = 0; i < RT_ELEMENTS(pFpuCtx->aXMM); i++)
    1716                     pHlp->pfnPrintf(pHlp,
    1717                                     i & 1
    1718                                     ? "%sXMM%u%s=%08RX32'%08RX32'%08RX32'%08RX32\n"
    1719                                     : "%sXMM%u%s=%08RX32'%08RX32'%08RX32'%08RX32  ",
    1720                                     pszPrefix, i, i < 10 ? " " : "",
    1721                                     pFpuCtx->aXMM[i].au32[3],
    1722                                     pFpuCtx->aXMM[i].au32[2],
    1723                                     pFpuCtx->aXMM[i].au32[1],
    1724                                     pFpuCtx->aXMM[i].au32[0]);
    1725 
    1726             if (pCtx->fXStateMask & XSAVE_C_OPMASK)
    1727             {
    1728                 PCX86XSAVEOPMASK pOpMask;
    1729                 pOpMask = (PCX86XSAVEOPMASK)((uint8_t *)pCtx->CTX_SUFF(pXState) + pCtx->aoffXState[XSAVE_C_OPMASK_BIT]);
    1730                 for (unsigned i = 0; i < RT_ELEMENTS(pOpMask->aKRegs); i += 4)
    1731                     pHlp->pfnPrintf(pHlp, "%sK%u=%016RX64  %sK%u=%016RX64  %sK%u=%016RX64  %sK%u=%016RX64\n",
    1732                                     pszPrefix, i + 0, pOpMask->aKRegs[i + 0],
    1733                                     pszPrefix, i + 1, pOpMask->aKRegs[i + 1],
    1734                                     pszPrefix, i + 2, pOpMask->aKRegs[i + 2],
    1735                                     pszPrefix, i + 3, pOpMask->aKRegs[i + 3]);
    1736             }
    1737 
    1738             if (pCtx->fXStateMask & XSAVE_C_BNDREGS)
    1739             {
    1740                 PCX86XSAVEBNDREGS pBndRegs;
    1741                 pBndRegs = (PCX86XSAVEBNDREGS)((uint8_t *)pCtx->CTX_SUFF(pXState) + pCtx->aoffXState[XSAVE_C_BNDREGS_BIT]);
    1742                 for (unsigned i = 0; i < RT_ELEMENTS(pBndRegs->aRegs); i += 2)
    1743                     pHlp->pfnPrintf(pHlp, "%sBNDREG%u=%016RX64/%016RX64  %sBNDREG%u=%016RX64/%016RX64\n",
    1744                                     pszPrefix, i, pBndRegs->aRegs[i].uLowerBound, pBndRegs->aRegs[i].uUpperBound,
    1745                                     pszPrefix, i + 1, pBndRegs->aRegs[i + 1].uLowerBound, pBndRegs->aRegs[i + 1].uUpperBound);
    1746             }
    1747 
    1748             if (pCtx->fXStateMask & XSAVE_C_BNDCSR)
    1749             {
    1750                 PCX86XSAVEBNDCFG pBndCfg;
    1751                 pBndCfg = (PCX86XSAVEBNDCFG)((uint8_t *)pCtx->CTX_SUFF(pXState) + pCtx->aoffXState[XSAVE_C_BNDCSR_BIT]);
    1752                 pHlp->pfnPrintf(pHlp, "%sBNDCFG.CONFIG=%016RX64 %sBNDCFG.STATUS=%016RX64\n",
    1753                                 pszPrefix, pBndCfg->fConfig, pszPrefix, pBndCfg->fStatus);
    1754             }
    1755 
    1756             for (unsigned i = 0; i < RT_ELEMENTS(pFpuCtx->au32RsrvdRest); i++)
    1757                 if (pFpuCtx->au32RsrvdRest[i])
    1758                     pHlp->pfnPrintf(pHlp, "%sRsrvdRest[i]=%RX32 (offset=%#x)\n",
    1759                                     pszPrefix, i, pFpuCtx->au32RsrvdRest[i], RT_OFFSETOF(X86FXSTATE, au32RsrvdRest[i]) );
    17601898
    17611899            pHlp->pfnPrintf(pHlp,
  • trunk/src/VBox/VMM/VMMR3/CPUMR3CpuId.cpp

    r55316 r55466  
    48984898
    48994899
     4900/**
     4901 * Loads the CPU ID leaves saved by pass 0 in an pre 3.2 saved state.
     4902 *
     4903 * @returns VBox status code.
     4904 * @param   pVM                 Pointer to the VM.
     4905 * @param   pSSM                The saved state handle.
     4906 * @param   uVersion            The format version.
     4907 */
     4908int cpumR3LoadCpuIdPre32(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion)
     4909{
     4910    AssertMsgReturn(uVersion < CPUM_SAVED_STATE_VERSION_VER3_2, ("%u\n", uVersion), VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION);
     4911
     4912    /*
     4913     * Restore the CPUID leaves.
     4914     *
     4915     * Note that we support restoring less than the current amount of standard
     4916     * leaves because we've been allowed more is newer version of VBox.
     4917     */
     4918    uint32_t cElements;
     4919    int rc = SSMR3GetU32(pSSM, &cElements); AssertRCReturn(rc, rc);
     4920    if (cElements > RT_ELEMENTS(pVM->cpum.s.aGuestCpuIdPatmStd))
     4921        return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
     4922    SSMR3GetMem(pSSM, &pVM->cpum.s.aGuestCpuIdPatmStd[0], cElements*sizeof(pVM->cpum.s.aGuestCpuIdPatmStd[0]));
     4923
     4924    rc = SSMR3GetU32(pSSM, &cElements); AssertRCReturn(rc, rc);
     4925    if (cElements != RT_ELEMENTS(pVM->cpum.s.aGuestCpuIdPatmExt))
     4926        return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
     4927    SSMR3GetMem(pSSM, &pVM->cpum.s.aGuestCpuIdPatmExt[0], sizeof(pVM->cpum.s.aGuestCpuIdPatmExt));
     4928
     4929    rc = SSMR3GetU32(pSSM, &cElements); AssertRCReturn(rc, rc);
     4930    if (cElements != RT_ELEMENTS(pVM->cpum.s.aGuestCpuIdPatmCentaur))
     4931        return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
     4932    SSMR3GetMem(pSSM, &pVM->cpum.s.aGuestCpuIdPatmCentaur[0], sizeof(pVM->cpum.s.aGuestCpuIdPatmCentaur));
     4933
     4934    SSMR3GetMem(pSSM, &pVM->cpum.s.GuestInfo.DefCpuId, sizeof(pVM->cpum.s.GuestInfo.DefCpuId));
     4935
     4936    /*
     4937     * Check that the basic cpuid id information is unchanged.
     4938     */
     4939    /** @todo we should check the 64 bits capabilities too! */
     4940    uint32_t au32CpuId[8] = {0,0,0,0, 0,0,0,0};
     4941    ASMCpuIdExSlow(0, 0, 0, 0, &au32CpuId[0], &au32CpuId[1], &au32CpuId[2], &au32CpuId[3]);
     4942    ASMCpuIdExSlow(1, 0, 0, 0, &au32CpuId[4], &au32CpuId[5], &au32CpuId[6], &au32CpuId[7]);
     4943    uint32_t au32CpuIdSaved[8];
     4944    rc = SSMR3GetMem(pSSM, &au32CpuIdSaved[0], sizeof(au32CpuIdSaved));
     4945    if (RT_SUCCESS(rc))
     4946    {
     4947        /* Ignore CPU stepping. */
     4948        au32CpuId[4]      &=  0xfffffff0;
     4949        au32CpuIdSaved[4] &=  0xfffffff0;
     4950
     4951        /* Ignore APIC ID (AMD specs). */
     4952        au32CpuId[5]      &= ~0xff000000;
     4953        au32CpuIdSaved[5] &= ~0xff000000;
     4954
     4955        /* Ignore the number of Logical CPUs (AMD specs). */
     4956        au32CpuId[5]      &= ~0x00ff0000;
     4957        au32CpuIdSaved[5] &= ~0x00ff0000;
     4958
     4959        /* Ignore some advanced capability bits, that we don't expose to the guest. */
     4960        au32CpuId[6]      &= ~(   X86_CPUID_FEATURE_ECX_DTES64
     4961                               |  X86_CPUID_FEATURE_ECX_VMX
     4962                               |  X86_CPUID_FEATURE_ECX_SMX
     4963                               |  X86_CPUID_FEATURE_ECX_EST
     4964                               |  X86_CPUID_FEATURE_ECX_TM2
     4965                               |  X86_CPUID_FEATURE_ECX_CNTXID
     4966                               |  X86_CPUID_FEATURE_ECX_TPRUPDATE
     4967                               |  X86_CPUID_FEATURE_ECX_PDCM
     4968                               |  X86_CPUID_FEATURE_ECX_DCA
     4969                               |  X86_CPUID_FEATURE_ECX_X2APIC
     4970                              );
     4971        au32CpuIdSaved[6] &= ~(   X86_CPUID_FEATURE_ECX_DTES64
     4972                               |  X86_CPUID_FEATURE_ECX_VMX
     4973                               |  X86_CPUID_FEATURE_ECX_SMX
     4974                               |  X86_CPUID_FEATURE_ECX_EST
     4975                               |  X86_CPUID_FEATURE_ECX_TM2
     4976                               |  X86_CPUID_FEATURE_ECX_CNTXID
     4977                               |  X86_CPUID_FEATURE_ECX_TPRUPDATE
     4978                               |  X86_CPUID_FEATURE_ECX_PDCM
     4979                               |  X86_CPUID_FEATURE_ECX_DCA
     4980                               |  X86_CPUID_FEATURE_ECX_X2APIC
     4981                              );
     4982
     4983        /* Make sure we don't forget to update the masks when enabling
     4984         * features in the future.
     4985         */
     4986        AssertRelease(!(pVM->cpum.s.aGuestCpuIdPatmStd[1].uEcx &
     4987                              (   X86_CPUID_FEATURE_ECX_DTES64
     4988                               |  X86_CPUID_FEATURE_ECX_VMX
     4989                               |  X86_CPUID_FEATURE_ECX_SMX
     4990                               |  X86_CPUID_FEATURE_ECX_EST
     4991                               |  X86_CPUID_FEATURE_ECX_TM2
     4992                               |  X86_CPUID_FEATURE_ECX_CNTXID
     4993                               |  X86_CPUID_FEATURE_ECX_TPRUPDATE
     4994                               |  X86_CPUID_FEATURE_ECX_PDCM
     4995                               |  X86_CPUID_FEATURE_ECX_DCA
     4996                               |  X86_CPUID_FEATURE_ECX_X2APIC
     4997                              )));
     4998        /* do the compare */
     4999        if (memcmp(au32CpuIdSaved, au32CpuId, sizeof(au32CpuIdSaved)))
     5000        {
     5001            if (SSMR3HandleGetAfter(pSSM) == SSMAFTER_DEBUG_IT)
     5002                LogRel(("cpumR3LoadExec: CpuId mismatch! (ignored due to SSMAFTER_DEBUG_IT)\n"
     5003                        "Saved=%.*Rhxs\n"
     5004                        "Real =%.*Rhxs\n",
     5005                        sizeof(au32CpuIdSaved), au32CpuIdSaved,
     5006                        sizeof(au32CpuId), au32CpuId));
     5007            else
     5008            {
     5009                LogRel(("cpumR3LoadExec: CpuId mismatch!\n"
     5010                        "Saved=%.*Rhxs\n"
     5011                        "Real =%.*Rhxs\n",
     5012                        sizeof(au32CpuIdSaved), au32CpuIdSaved,
     5013                        sizeof(au32CpuId), au32CpuId));
     5014                rc = VERR_SSM_LOAD_CPUID_MISMATCH;
     5015            }
     5016        }
     5017    }
     5018
     5019    return rc;
     5020}
     5021
     5022
    49005023
    49015024/*
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