Changeset 55466 in vbox for trunk/src/VBox/VMM/VMMR3
- Timestamp:
- Apr 28, 2015 12:10:51 AM (10 years ago)
- Location:
- trunk/src/VBox/VMM/VMMR3
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/CPUM.cpp
r55456 r55466 111 111 * Global Variables * 112 112 *******************************************************************************/ 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 155 113 /** Saved state field descriptors for CPUMCTX. */ 156 114 static const SSMFIELD g_aCpumCtxFields[] = … … 247 205 SSMFIELD_ENTRY( CPUMCTX, tr.u32Limit), 248 206 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), 249 210 SSMFIELD_ENTRY_TERM() 250 211 }; 212 213 /** Saved state field descriptors for CPUMCTX. */ 214 static 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. */ 257 static const SSMFIELD g_aCpumXSaveHdrFields[] = 258 { 259 SSMFIELD_ENTRY( X86XSAVEHDR, bmXState), 260 SSMFIELD_ENTRY_TERM() 261 }; 262 263 /** Saved state field descriptors for X86XSAVEYMMHI. */ 264 static 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. */ 286 static 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. */ 296 static 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. */ 304 static 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. */ 318 static 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. */ 340 static 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 251 362 252 363 /** Saved state field descriptors for CPUMCTX in V4.1 before the hidden selector … … 428 539 SSMFIELD_ENTRY( X86FXSTATE, aXMM[15]), 429 540 SSMFIELD_ENTRY_IGNORE( X86FXSTATE, au32RsrvdRest), 541 SSMFIELD_ENTRY_IGNORE( X86FXSTATE, au32RsrvdForSoftware), 430 542 SSMFIELD_ENTRY_TERM() 431 543 }; … … 1026 1138 * Save. 1027 1139 */ 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 1037 1140 SSMR3PutU32(pSSM, pVM->cCpus); 1038 1141 SSMR3PutU32(pSSM, sizeof(pVM->aCpus[0].cpum.s.GuestMsrs.msr)); … … 1041 1144 PVMCPU pVCpu = &pVM->aCpus[iCpu]; 1042 1145 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 1047 1179 SSMR3PutU32(pSSM, pVCpu->cpum.s.fUseFlags); 1048 1180 SSMR3PutU32(pSSM, pVCpu->cpum.s.fChanged); … … 1072 1204 static DECLCALLBACK(int) cpumR3LoadExec(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass) 1073 1205 { 1206 int rc; /* Only for AssertRCReturn use. */ 1207 1074 1208 /* 1075 1209 * Validate version. 1076 1210 */ 1077 if ( uVersion != CPUM_SAVED_STATE_VERSION 1211 if ( uVersion != CPUM_SAVED_STATE_VERSION_XSAVE 1212 && uVersion != CPUM_SAVED_STATE_VERSION_GOOD_CPUID_COUNT 1078 1213 && uVersion != CPUM_SAVED_STATE_VERSION_BAD_CPUID_COUNT 1079 1214 && uVersion != CPUM_SAVED_STATE_VERSION_PUT_STRUCT … … 1101 1236 SSMR3HandleSetGCPtrSize(pSSM, HC_ARCH_BITS == 32 ? sizeof(RTGCPTR32) : sizeof(RTGCPTR)); 1102 1237 1238 /* 1239 * Figure x86 and ctx field definitions to use for older states. 1240 */ 1103 1241 uint32_t const fLoad = uVersion > CPUM_SAVED_STATE_VERSION_MEM ? 0 : SSMSTRUCT_FLAGS_MEM_BAND_AID_RELAXED; 1104 1242 PCSSMFIELD paCpumCtx1Fields = g_aCpumX87Fields; … … 1116 1254 1117 1255 /* 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. 1119 1258 */ 1120 for (VMCPUID iCpu = 0; iCpu < pVM->cCpus; iCpu++)1259 if (uVersion < CPUM_SAVED_STATE_VERSION_XSAVE) 1121 1260 { 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 } 1132 1273 } 1133 1274 … … 1135 1276 { 1136 1277 uint32_t cCpus; 1137 intrc = SSMR3GetU32(pSSM, &cCpus); AssertRCReturn(rc, rc);1278 rc = SSMR3GetU32(pSSM, &cCpus); AssertRCReturn(rc, rc); 1138 1279 AssertLogRelMsgReturn(cCpus == pVM->cCpus, ("Mismatching CPU counts: saved: %u; configured: %u \n", cCpus, pVM->cCpus), 1139 1280 VERR_SSM_UNEXPECTED_DATA); … … 1147 1288 if (uVersion > CPUM_SAVED_STATE_VERSION_NO_MSR_SIZE) 1148 1289 { 1149 intrc = SSMR3GetU32(pSSM, &cbMsrs); AssertRCReturn(rc, rc);1290 rc = SSMR3GetU32(pSSM, &cbMsrs); AssertRCReturn(rc, rc); 1150 1291 AssertLogRelMsgReturn(RT_ALIGN(cbMsrs, sizeof(uint64_t)) == cbMsrs, ("Size of MSRs is misaligned: %#x\n", cbMsrs), 1151 1292 VERR_SSM_UNEXPECTED_DATA); … … 1154 1295 } 1155 1296 1297 /* 1298 * Do the per-CPU restoring. 1299 */ 1156 1300 for (VMCPUID iCpu = 0; iCpu < pVM->cCpus; iCpu++) 1157 1301 { 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 */ 1163 1413 SSMR3GetU32(pSSM, &pVCpu->cpum.s.fUseFlags); 1164 1414 SSMR3GetU32(pSSM, &pVCpu->cpum.s.fChanged); 1415 1165 1416 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); 1167 1418 else if (uVersion >= CPUM_SAVED_STATE_VERSION_VER3_0) 1168 1419 { 1169 1420 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)); 1171 1422 } 1423 AssertRCReturn(rc, rc); 1172 1424 1173 1425 /* REM and other may have cleared must-be-one fields in DR6 and 1174 1426 DR7, fix these. */ 1175 p VCpu->cpum.s.Guest.dr[6] &= ~(X86_DR6_RAZ_MASK | X86_DR6_MBZ_MASK);1176 p VCpu->cpum.s.Guest.dr[6] |= X86_DR6_RA1_MASK;1177 p VCpu->cpum.s.Guest.dr[7] &= ~(X86_DR7_RAZ_MASK | X86_DR7_MBZ_MASK);1178 p VCpu->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; 1179 1431 } 1180 1432 … … 1246 1498 * Guest CPUIDs. 1247 1499 */ 1248 if (uVersion > CPUM_SAVED_STATE_VERSION_VER3_0)1500 if (uVersion >= CPUM_SAVED_STATE_VERSION_VER3_2) 1249 1501 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); 1362 1503 } 1363 1504 … … 1610 1751 pszPrefix, pCtx->SysEnter.cs, pCtx->SysEnter.eip, pCtx->SysEnter.esp); 1611 1752 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", 1645 1754 pszPrefix, pCtx->aXcr[0], pszPrefix, pCtx->aXcr[1], 1646 1755 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)) 1650 1757 { 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 1654 1854 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 ", 1656 1859 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],1661 1860 pFpuCtx->aXMM[i].au32[3], 1662 1861 pFpuCtx->aXMM[i].au32[2], 1663 1862 pFpuCtx->aXMM[i].au32[1], 1664 1863 pFpuCtx->aXMM[i].au32[0]); 1665 else 1864 1865 if (pCtx->fXStateMask & XSAVE_C_OPMASK) 1666 1866 { 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]); 1712 1875 } 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]) ); 1713 1897 } 1714 else1715 for (unsigned i = 0; i < RT_ELEMENTS(pFpuCtx->aXMM); i++)1716 pHlp->pfnPrintf(pHlp,1717 i & 11718 ? "%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]) );1760 1898 1761 1899 pHlp->pfnPrintf(pHlp, -
trunk/src/VBox/VMM/VMMR3/CPUMR3CpuId.cpp
r55316 r55466 4898 4898 4899 4899 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 */ 4908 int 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 4900 5023 4901 5024 /*
Note:
See TracChangeset
for help on using the changeset viewer.