Changeset 76464 in vbox for trunk/src/VBox/VMM/VMMR3
- Timestamp:
- Dec 25, 2018 4:36:48 AM (6 years ago)
- Location:
- trunk/src/VBox/VMM/VMMR3
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/CPUM.cpp
r76310 r76464 788 788 for (VMCPUID i = 0; i < pVM->cCpus; i++) 789 789 pVM->aCpus[i].cpum.s.fUseFlags |= CPUM_USE_FFXSR_LEAKY; 790 Log(("CPUM R3Init: host CPU has leaky fxsave/fxrstor behaviour\n"));790 Log(("CPUM: Host CPU has leaky fxsave/fxrstor behaviour\n")); 791 791 } 792 792 } … … 902 902 903 903 /** 904 * Initializes (or re-initializes)per-VCPU SVM hardware virtualization state.904 * Resets per-VCPU SVM hardware virtualization state. 905 905 * 906 906 * @param pVCpu The cross context virtual CPU structure. 907 907 */ 908 DECLINLINE(void) cpumR3 InitSvmHwVirtState(PVMCPU pVCpu)908 DECLINLINE(void) cpumR3ResetSvmHwVirtState(PVMCPU pVCpu) 909 909 { 910 910 PCPUMCTX pCtx = &pVCpu->cpum.s.Guest; … … 1114 1114 1115 1115 /** 1116 * Initializes (or re-initializes)per-VCPU VMX hardware virtualization state.1116 * Resets per-VCPU VMX hardware virtualization state. 1117 1117 * 1118 1118 * @param pVCpu The cross context virtual CPU structure. 1119 1119 */ 1120 DECLINLINE(void) cpumR3 InitVmxHwVirtState(PVMCPU pVCpu)1120 DECLINLINE(void) cpumR3ResetVmxHwVirtState(PVMCPU pVCpu) 1121 1121 { 1122 1122 PCPUMCTX pCtx = &pVCpu->cpum.s.Guest; … … 1157 1157 pHlp->pfnPrintf(pHlp, " Mnemonic - Description = guest (host)\n"); 1158 1158 VMXFEATDUMP("VMX - Virtual-Machine Extensions ", fVmx); 1159 if (!pGuestFeatures->fVmx)1160 return;1161 1159 /* Basic. */ 1162 1160 VMXFEATDUMP("InsOutInfo - INS/OUTS instruction info. ", fVmxInsOutInfo); … … 1250 1248 || pVM->bMainExecutionEngine == VM_EXEC_ENGINE_NATIVE_API) 1251 1249 return true; 1250 #else 1251 NOREF(pVM); 1252 1252 #endif 1253 1253 return false; … … 1256 1256 1257 1257 /** 1258 * Initializes the guest VMX MSRs from guest-CPU features. 1259 * 1260 * @param pVM The cross context VM structure. 1261 */ 1262 static void cpumR3InitGuestVmxMsrs(PVM pVM) 1263 { 1264 PVMCPU pVCpu0 = &pVM->aCpus[0]; 1265 PCCPUMFEATURES pFeatures = &pVM->cpum.s.GuestFeatures; 1266 PVMXMSRS pVmxMsrs = &pVCpu0->cpum.s.Guest.hwvirt.vmx.Msrs; 1267 1268 Assert(pFeatures->fVmx); 1269 RT_ZERO(*pVmxMsrs); 1270 1271 /* Feature control. */ 1272 pVmxMsrs->u64FeatCtrl = MSR_IA32_FEATURE_CONTROL_LOCK | MSR_IA32_FEATURE_CONTROL_VMXON; 1273 1274 /* Basic information. */ 1275 { 1276 uint64_t const u64Basic = RT_BF_MAKE(VMX_BF_BASIC_VMCS_ID, VMX_V_VMCS_REVISION_ID ) 1277 | RT_BF_MAKE(VMX_BF_BASIC_VMCS_SIZE, VMX_V_VMCS_SIZE ) 1278 | RT_BF_MAKE(VMX_BF_BASIC_PHYSADDR_WIDTH, !pFeatures->fLongMode ) 1279 | RT_BF_MAKE(VMX_BF_BASIC_DUAL_MON, 0 ) 1280 | RT_BF_MAKE(VMX_BF_BASIC_VMCS_MEM_TYPE, VMX_BASIC_MEM_TYPE_WB ) 1281 | RT_BF_MAKE(VMX_BF_BASIC_VMCS_INS_OUTS, pFeatures->fVmxInsOutInfo) 1282 | RT_BF_MAKE(VMX_BF_BASIC_TRUE_CTLS, 0 ); 1283 pVmxMsrs->u64Basic = u64Basic; 1284 } 1285 1286 /* Pin-based VM-execution controls. */ 1287 { 1288 uint32_t const fFeatures = (pFeatures->fVmxExtIntExit << VMX_BF_PIN_CTLS_EXT_INT_EXIT_SHIFT ) 1289 | (pFeatures->fVmxNmiExit << VMX_BF_PIN_CTLS_NMI_EXIT_SHIFT ) 1290 | (pFeatures->fVmxVirtNmi << VMX_BF_PIN_CTLS_VIRT_NMI_SHIFT ) 1291 | (pFeatures->fVmxPreemptTimer << VMX_BF_PIN_CTLS_PREEMPT_TIMER_SHIFT) 1292 | (pFeatures->fVmxPostedInt << VMX_BF_PIN_CTLS_POSTED_INT_SHIFT ); 1293 uint32_t const fAllowed0 = VMX_PIN_CTLS_DEFAULT1; 1294 uint32_t const fAllowed1 = fFeatures | VMX_PIN_CTLS_DEFAULT1; 1295 AssertMsg((fAllowed0 & fAllowed1) == fAllowed0, ("fAllowed0=%#RX32 fAllowed1=%#RX32 fFeatures=%#RX32\n", 1296 fAllowed0, fAllowed1, fFeatures)); 1297 pVmxMsrs->PinCtls.u = RT_MAKE_U64(fAllowed0, fAllowed1); 1298 } 1299 1300 /* Processor-based VM-execution controls. */ 1301 { 1302 uint32_t const fFeatures = (pFeatures->fVmxIntWindowExit << VMX_BF_PROC_CTLS_INT_WINDOW_EXIT_SHIFT ) 1303 | (pFeatures->fVmxTscOffsetting << VMX_BF_PROC_CTLS_USE_TSC_OFFSETTING_SHIFT) 1304 | (pFeatures->fVmxHltExit << VMX_BF_PROC_CTLS_HLT_EXIT_SHIFT ) 1305 | (pFeatures->fVmxInvlpgExit << VMX_BF_PROC_CTLS_INVLPG_EXIT_SHIFT ) 1306 | (pFeatures->fVmxMwaitExit << VMX_BF_PROC_CTLS_MWAIT_EXIT_SHIFT ) 1307 | (pFeatures->fVmxRdpmcExit << VMX_BF_PROC_CTLS_RDPMC_EXIT_SHIFT ) 1308 | (pFeatures->fVmxRdtscExit << VMX_BF_PROC_CTLS_RDTSC_EXIT_SHIFT ) 1309 | (pFeatures->fVmxCr3LoadExit << VMX_BF_PROC_CTLS_CR3_LOAD_EXIT_SHIFT ) 1310 | (pFeatures->fVmxCr3StoreExit << VMX_BF_PROC_CTLS_CR3_STORE_EXIT_SHIFT ) 1311 | (pFeatures->fVmxCr8LoadExit << VMX_BF_PROC_CTLS_CR8_LOAD_EXIT_SHIFT ) 1312 | (pFeatures->fVmxCr8StoreExit << VMX_BF_PROC_CTLS_CR8_STORE_EXIT_SHIFT ) 1313 | (pFeatures->fVmxUseTprShadow << VMX_BF_PROC_CTLS_USE_TPR_SHADOW_SHIFT ) 1314 | (pFeatures->fVmxNmiWindowExit << VMX_BF_PROC_CTLS_NMI_WINDOW_EXIT_SHIFT ) 1315 | (pFeatures->fVmxMovDRxExit << VMX_BF_PROC_CTLS_MOV_DR_EXIT_SHIFT ) 1316 | (pFeatures->fVmxUncondIoExit << VMX_BF_PROC_CTLS_UNCOND_IO_EXIT_SHIFT ) 1317 | (pFeatures->fVmxUseIoBitmaps << VMX_BF_PROC_CTLS_USE_IO_BITMAPS_SHIFT ) 1318 | (pFeatures->fVmxMonitorTrapFlag << VMX_BF_PROC_CTLS_MONITOR_TRAP_FLAG_SHIFT ) 1319 | (pFeatures->fVmxUseMsrBitmaps << VMX_BF_PROC_CTLS_USE_MSR_BITMAPS_SHIFT ) 1320 | (pFeatures->fVmxMonitorExit << VMX_BF_PROC_CTLS_MONITOR_EXIT_SHIFT ) 1321 | (pFeatures->fVmxPauseExit << VMX_BF_PROC_CTLS_PAUSE_EXIT_SHIFT ) 1322 | (pFeatures->fVmxSecondaryExecCtls << VMX_BF_PROC_CTLS_USE_SECONDARY_CTLS_SHIFT); 1323 uint32_t const fAllowed0 = VMX_PROC_CTLS_DEFAULT1; 1324 uint32_t const fAllowed1 = fFeatures | VMX_PROC_CTLS_DEFAULT1; 1325 AssertMsg((fAllowed0 & fAllowed1) == fAllowed0, ("fAllowed0=%#RX32 fAllowed1=%#RX32 fFeatures=%#RX32\n", fAllowed0, 1326 fAllowed1, fFeatures)); 1327 pVmxMsrs->ProcCtls.u = RT_MAKE_U64(fAllowed0, fAllowed1); 1328 } 1329 1330 /* Secondary processor-based VM-execution controls. */ 1331 if (pFeatures->fVmxSecondaryExecCtls) 1332 { 1333 uint32_t const fFeatures = (pFeatures->fVmxVirtApicAccess << VMX_BF_PROC_CTLS2_VIRT_APIC_ACCESS_SHIFT ) 1334 | (pFeatures->fVmxEpt << VMX_BF_PROC_CTLS2_EPT_SHIFT ) 1335 | (pFeatures->fVmxDescTableExit << VMX_BF_PROC_CTLS2_DESC_TABLE_EXIT_SHIFT ) 1336 | (pFeatures->fVmxRdtscp << VMX_BF_PROC_CTLS2_RDTSCP_SHIFT ) 1337 | (pFeatures->fVmxVirtX2ApicMode << VMX_BF_PROC_CTLS2_VIRT_X2APIC_MODE_SHIFT ) 1338 | (pFeatures->fVmxVpid << VMX_BF_PROC_CTLS2_VPID_SHIFT ) 1339 | (pFeatures->fVmxWbinvdExit << VMX_BF_PROC_CTLS2_WBINVD_EXIT_SHIFT ) 1340 | (pFeatures->fVmxUnrestrictedGuest << VMX_BF_PROC_CTLS2_UNRESTRICTED_GUEST_SHIFT) 1341 | (pFeatures->fVmxApicRegVirt << VMX_BF_PROC_CTLS2_APIC_REG_VIRT_SHIFT ) 1342 | (pFeatures->fVmxVirtIntDelivery << VMX_BF_PROC_CTLS2_VIRT_INT_DELIVERY_SHIFT ) 1343 | (pFeatures->fVmxPauseLoopExit << VMX_BF_PROC_CTLS2_PAUSE_LOOP_EXIT_SHIFT ) 1344 | (pFeatures->fVmxRdrandExit << VMX_BF_PROC_CTLS2_RDRAND_EXIT_SHIFT ) 1345 | (pFeatures->fVmxInvpcid << VMX_BF_PROC_CTLS2_INVPCID_SHIFT ) 1346 | (pFeatures->fVmxVmFunc << VMX_BF_PROC_CTLS2_VMFUNC_SHIFT ) 1347 | (pFeatures->fVmxVmcsShadowing << VMX_BF_PROC_CTLS2_VMCS_SHADOWING_SHIFT ) 1348 | (pFeatures->fVmxRdseedExit << VMX_BF_PROC_CTLS2_RDSEED_EXIT_SHIFT ) 1349 | (pFeatures->fVmxPml << VMX_BF_PROC_CTLS2_PML_SHIFT ) 1350 | (pFeatures->fVmxEptXcptVe << VMX_BF_PROC_CTLS2_EPT_VE_SHIFT ) 1351 | (pFeatures->fVmxXsavesXrstors << VMX_BF_PROC_CTLS2_XSAVES_XRSTORS_SHIFT ) 1352 | (pFeatures->fVmxUseTscScaling << VMX_BF_PROC_CTLS2_TSC_SCALING_SHIFT ); 1353 uint32_t const fAllowed0 = 0; 1354 uint32_t const fAllowed1 = fFeatures; 1355 pVmxMsrs->ProcCtls2.u = RT_MAKE_U64(fAllowed0, fAllowed1); 1356 } 1357 1358 /* VM-exit controls. */ 1359 { 1360 uint32_t const fFeatures = (pFeatures->fVmxExitSaveDebugCtls << VMX_BF_EXIT_CTLS_SAVE_DEBUG_SHIFT ) 1361 | (pFeatures->fVmxHostAddrSpaceSize << VMX_BF_EXIT_CTLS_HOST_ADDR_SPACE_SIZE_SHIFT) 1362 | (pFeatures->fVmxExitAckExtInt << VMX_BF_EXIT_CTLS_ACK_EXT_INT_SHIFT ) 1363 | (pFeatures->fVmxExitSavePatMsr << VMX_BF_EXIT_CTLS_SAVE_PAT_MSR_SHIFT ) 1364 | (pFeatures->fVmxExitLoadPatMsr << VMX_BF_EXIT_CTLS_LOAD_PAT_MSR_SHIFT ) 1365 | (pFeatures->fVmxExitSaveEferMsr << VMX_BF_EXIT_CTLS_SAVE_EFER_MSR_SHIFT ) 1366 | (pFeatures->fVmxExitLoadEferMsr << VMX_BF_EXIT_CTLS_LOAD_EFER_MSR_SHIFT ) 1367 | (pFeatures->fVmxSavePreemptTimer << VMX_BF_EXIT_CTLS_SAVE_PREEMPT_TIMER_SHIFT ); 1368 /* Set the default1 class bits. See Intel spec. A.4 "VM-exit Controls". */ 1369 uint32_t const fAllowed0 = VMX_EXIT_CTLS_DEFAULT1; 1370 uint32_t const fAllowed1 = fFeatures | VMX_EXIT_CTLS_DEFAULT1; 1371 AssertMsg((fAllowed0 & fAllowed1) == fAllowed0, ("fAllowed0=%#RX32 fAllowed1=%#RX32 fFeatures=%#RX32\n", fAllowed0, 1372 fAllowed1, fFeatures)); 1373 pVmxMsrs->ExitCtls.u = RT_MAKE_U64(fAllowed0, fAllowed1); 1374 } 1375 1376 /* VM-entry controls. */ 1377 { 1378 uint32_t const fFeatures = (pFeatures->fVmxEntryLoadDebugCtls << VMX_BF_ENTRY_CTLS_LOAD_DEBUG_SHIFT ) 1379 | (pFeatures->fVmxIa32eModeGuest << VMX_BF_ENTRY_CTLS_IA32E_MODE_GUEST_SHIFT) 1380 | (pFeatures->fVmxEntryLoadEferMsr << VMX_BF_ENTRY_CTLS_LOAD_EFER_MSR_SHIFT ) 1381 | (pFeatures->fVmxEntryLoadPatMsr << VMX_BF_ENTRY_CTLS_LOAD_PAT_MSR_SHIFT ); 1382 uint32_t const fAllowed0 = VMX_ENTRY_CTLS_DEFAULT1; 1383 uint32_t const fAllowed1 = fFeatures | VMX_ENTRY_CTLS_DEFAULT1; 1384 AssertMsg((fAllowed0 & fAllowed1) == fAllowed0, ("fAllowed0=%#RX32 fAllowed0=%#RX32 fFeatures=%#RX32\n", fAllowed0, 1385 fAllowed1, fFeatures)); 1386 pVmxMsrs->EntryCtls.u = RT_MAKE_U64(fAllowed0, fAllowed1); 1387 } 1388 1389 /* Miscellaneous data. */ 1390 { 1391 uint64_t uHostMsr = 0; 1392 if (cpumR3IsHwAssistVmxNstGstExecAllowed(pVM)) 1393 HMVmxGetHostMsr(pVM, MSR_IA32_VMX_MISC, &uHostMsr); 1394 uint8_t const cMaxMsrs = RT_MIN(RT_BF_GET(uHostMsr, VMX_BF_MISC_MAX_MSRS), VMX_V_AUTOMSR_COUNT_MAX); 1395 uint8_t const fActivityState = RT_BF_GET(uHostMsr, VMX_BF_MISC_ACTIVITY_STATES) & VMX_V_GUEST_ACTIVITY_STATE_MASK; 1396 pVmxMsrs->u64Misc = RT_BF_MAKE(VMX_BF_MISC_PREEMPT_TIMER_TSC, VMX_V_PREEMPT_TIMER_SHIFT ) 1397 | RT_BF_MAKE(VMX_BF_MISC_EXIT_SAVE_EFER_LMA, pFeatures->fVmxExitSaveEferLma ) 1398 | RT_BF_MAKE(VMX_BF_MISC_ACTIVITY_STATES, fActivityState ) 1399 | RT_BF_MAKE(VMX_BF_MISC_INTEL_PT, pFeatures->fVmxIntelPt ) 1400 | RT_BF_MAKE(VMX_BF_MISC_SMM_READ_SMBASE_MSR, 0 ) 1401 | RT_BF_MAKE(VMX_BF_MISC_CR3_TARGET, VMX_V_CR3_TARGET_COUNT ) 1402 | RT_BF_MAKE(VMX_BF_MISC_MAX_MSRS, cMaxMsrs ) 1403 | RT_BF_MAKE(VMX_BF_MISC_VMXOFF_BLOCK_SMI, 0 ) 1404 | RT_BF_MAKE(VMX_BF_MISC_VMWRITE_ALL, pFeatures->fVmxVmwriteAll ) 1405 | RT_BF_MAKE(VMX_BF_MISC_ENTRY_INJECT_SOFT_INT, pFeatures->fVmxEntryInjectSoftInt) 1406 | RT_BF_MAKE(VMX_BF_MISC_MSEG_ID, VMX_V_MSEG_REV_ID ); 1407 } 1408 1409 /* CR0 Fixed-0. */ 1410 pVmxMsrs->u64Cr0Fixed0 = pFeatures->fVmxUnrestrictedGuest ? VMX_V_CR0_FIXED0_UX: VMX_V_CR0_FIXED0; 1411 1412 /* CR0 Fixed-1. */ 1413 { 1414 uint64_t uHostMsr = 0; 1415 if (cpumR3IsHwAssistVmxNstGstExecAllowed(pVM)) 1416 HMVmxGetHostMsr(pVM, MSR_IA32_VMX_CR0_FIXED1, &uHostMsr); 1417 pVmxMsrs->u64Cr0Fixed1 = uHostMsr | VMX_V_CR0_FIXED0; /* Make sure the CR0 MB1 bits are not clear. */ 1418 } 1419 1420 /* CR4 Fixed-0. */ 1421 pVmxMsrs->u64Cr4Fixed0 = VMX_V_CR4_FIXED0; 1422 1423 /* CR4 Fixed-1. */ 1424 { 1425 uint64_t uHostMsr = 0; 1426 if (cpumR3IsHwAssistVmxNstGstExecAllowed(pVM)) 1427 HMVmxGetHostMsr(pVM, MSR_IA32_VMX_CR4_FIXED1, &uHostMsr); 1428 pVmxMsrs->u64Cr4Fixed1 = uHostMsr | VMX_V_CR4_FIXED0; /* Make sure the CR4 MB1 bits are not clear. */ 1429 } 1430 1431 /* VMCS Enumeration. */ 1432 pVmxMsrs->u64VmcsEnum = VMX_V_VMCS_MAX_INDEX << VMX_BF_VMCS_ENUM_HIGHEST_IDX_SHIFT; 1433 1434 /* VM Functions. */ 1435 if (pFeatures->fVmxVmFunc) 1436 pVmxMsrs->u64VmFunc = RT_BF_MAKE(VMX_BF_VMFUNC_EPTP_SWITCHING, 1); 1258 * Initializes the VMX guest MSRs from guest CPU features based on the host MSRs. 1259 * 1260 * @param pVM The cross context VM structure. 1261 * @param pHostVmxMsrs The host VMX MSRs. Pass NULL when fully emulating VMX 1262 * and no hardware-assisted nested-guest execution is 1263 * possible for this VM. 1264 * @param pGuestFeatures The guest features to use (only VMX features are 1265 * accessed). 1266 * @param pGuestVmxMsrs Where to store the initialized guest VMX MSRs. 1267 * 1268 * @remarks This function ASSUMES the VMX guest-features are already exploded! 1269 */ 1270 static void cpumR3InitVmxGuestMsrs(PVM pVM, PCVMXMSRS pHostVmxMsrs, PCCPUMFEATURES pGuestFeatures, PVMXMSRS pGuestVmxMsrs) 1271 { 1272 Assert(!cpumR3IsHwAssistVmxNstGstExecAllowed(pVM) || pHostVmxMsrs); 1273 Assert(pGuestFeatures->fVmx); 1437 1274 1438 1275 /* … … 1445 1282 */ 1446 1283 1447 /* 1448 * Copy the MSRs values initialized in VCPU 0 to all other VCPUs. 1449 */ 1450 for (VMCPUID idCpu = 1; idCpu < pVM->cCpus; idCpu++) 1451 { 1452 PVMCPU pVCpu = &pVM->aCpus[idCpu]; 1453 Assert(pVCpu); 1454 memcpy(&pVCpu->cpum.s.Guest.hwvirt.vmx.Msrs, pVmxMsrs, sizeof(*pVmxMsrs)); 1455 } 1456 } 1457 1458 1459 /** 1460 * Explode VMX features from the provided MSRs. 1461 * 1462 * @param pVmxMsrs Pointer to the VMX MSRs. 1463 * @param pFeatures Pointer to the features struct. to populate. 1464 */ 1465 static void cpumR3ExplodeVmxFeatures(PCVMXMSRS pVmxMsrs, PCPUMFEATURES pFeatures) 1466 { 1467 Assert(pVmxMsrs); 1468 Assert(pFeatures); 1469 Assert(pFeatures->fVmx); 1284 /* Feature control. */ 1285 pGuestVmxMsrs->u64FeatCtrl = MSR_IA32_FEATURE_CONTROL_LOCK | MSR_IA32_FEATURE_CONTROL_VMXON; 1470 1286 1471 1287 /* Basic information. */ 1472 1288 { 1473 uint64_t const u64Basic = pVmxMsrs->u64Basic; 1474 pFeatures->fVmxInsOutInfo = RT_BF_GET(u64Basic, VMX_BF_BASIC_VMCS_INS_OUTS); 1289 uint64_t const u64Basic = RT_BF_MAKE(VMX_BF_BASIC_VMCS_ID, VMX_V_VMCS_REVISION_ID ) 1290 | RT_BF_MAKE(VMX_BF_BASIC_VMCS_SIZE, VMX_V_VMCS_SIZE ) 1291 | RT_BF_MAKE(VMX_BF_BASIC_PHYSADDR_WIDTH, !pGuestFeatures->fLongMode ) 1292 | RT_BF_MAKE(VMX_BF_BASIC_DUAL_MON, 0 ) 1293 | RT_BF_MAKE(VMX_BF_BASIC_VMCS_MEM_TYPE, VMX_BASIC_MEM_TYPE_WB ) 1294 | RT_BF_MAKE(VMX_BF_BASIC_VMCS_INS_OUTS, pGuestFeatures->fVmxInsOutInfo) 1295 | RT_BF_MAKE(VMX_BF_BASIC_TRUE_CTLS, 0 ); 1296 pGuestVmxMsrs->u64Basic = u64Basic; 1475 1297 } 1476 1298 1477 1299 /* Pin-based VM-execution controls. */ 1478 1300 { 1479 uint32_t const fPinCtls = pVmxMsrs->PinCtls.n.allowed1; 1480 pFeatures->fVmxExtIntExit = RT_BOOL(fPinCtls & VMX_PIN_CTLS_EXT_INT_EXIT); 1481 pFeatures->fVmxNmiExit = RT_BOOL(fPinCtls & VMX_PIN_CTLS_NMI_EXIT); 1482 pFeatures->fVmxVirtNmi = RT_BOOL(fPinCtls & VMX_PIN_CTLS_VIRT_NMI); 1483 pFeatures->fVmxPreemptTimer = RT_BOOL(fPinCtls & VMX_PIN_CTLS_PREEMPT_TIMER); 1484 pFeatures->fVmxPostedInt = RT_BOOL(fPinCtls & VMX_PIN_CTLS_POSTED_INT); 1301 uint32_t const fFeatures = (pGuestFeatures->fVmxExtIntExit << VMX_BF_PIN_CTLS_EXT_INT_EXIT_SHIFT ) 1302 | (pGuestFeatures->fVmxNmiExit << VMX_BF_PIN_CTLS_NMI_EXIT_SHIFT ) 1303 | (pGuestFeatures->fVmxVirtNmi << VMX_BF_PIN_CTLS_VIRT_NMI_SHIFT ) 1304 | (pGuestFeatures->fVmxPreemptTimer << VMX_BF_PIN_CTLS_PREEMPT_TIMER_SHIFT) 1305 | (pGuestFeatures->fVmxPostedInt << VMX_BF_PIN_CTLS_POSTED_INT_SHIFT ); 1306 uint32_t const fAllowed0 = VMX_PIN_CTLS_DEFAULT1; 1307 uint32_t const fAllowed1 = fFeatures | VMX_PIN_CTLS_DEFAULT1; 1308 AssertMsg((fAllowed0 & fAllowed1) == fAllowed0, ("fAllowed0=%#RX32 fAllowed1=%#RX32 fFeatures=%#RX32\n", 1309 fAllowed0, fAllowed1, fFeatures)); 1310 pGuestVmxMsrs->PinCtls.u = RT_MAKE_U64(fAllowed0, fAllowed1); 1485 1311 } 1486 1312 1487 1313 /* Processor-based VM-execution controls. */ 1488 1314 { 1489 uint32_t const fProcCtls = pVmxMsrs->ProcCtls.n.allowed1; 1490 pFeatures->fVmxIntWindowExit = RT_BOOL(fProcCtls & VMX_PROC_CTLS_INT_WINDOW_EXIT); 1491 pFeatures->fVmxTscOffsetting = RT_BOOL(fProcCtls & VMX_PROC_CTLS_USE_TSC_OFFSETTING); 1492 pFeatures->fVmxHltExit = RT_BOOL(fProcCtls & VMX_PROC_CTLS_HLT_EXIT); 1493 pFeatures->fVmxInvlpgExit = RT_BOOL(fProcCtls & VMX_PROC_CTLS_INVLPG_EXIT); 1494 pFeatures->fVmxMwaitExit = RT_BOOL(fProcCtls & VMX_PROC_CTLS_MWAIT_EXIT); 1495 pFeatures->fVmxRdpmcExit = RT_BOOL(fProcCtls & VMX_PROC_CTLS_RDPMC_EXIT); 1496 pFeatures->fVmxRdtscExit = RT_BOOL(fProcCtls & VMX_PROC_CTLS_RDTSC_EXIT); 1497 pFeatures->fVmxCr3LoadExit = RT_BOOL(fProcCtls & VMX_PROC_CTLS_CR3_LOAD_EXIT); 1498 pFeatures->fVmxCr3StoreExit = RT_BOOL(fProcCtls & VMX_PROC_CTLS_CR3_STORE_EXIT); 1499 pFeatures->fVmxCr8LoadExit = RT_BOOL(fProcCtls & VMX_PROC_CTLS_CR8_LOAD_EXIT); 1500 pFeatures->fVmxCr8StoreExit = RT_BOOL(fProcCtls & VMX_PROC_CTLS_CR8_STORE_EXIT); 1501 pFeatures->fVmxUseTprShadow = RT_BOOL(fProcCtls & VMX_PROC_CTLS_USE_TPR_SHADOW); 1502 pFeatures->fVmxNmiWindowExit = RT_BOOL(fProcCtls & VMX_PROC_CTLS_NMI_WINDOW_EXIT); 1503 pFeatures->fVmxMovDRxExit = RT_BOOL(fProcCtls & VMX_PROC_CTLS_MOV_DR_EXIT); 1504 pFeatures->fVmxUncondIoExit = RT_BOOL(fProcCtls & VMX_PROC_CTLS_UNCOND_IO_EXIT); 1505 pFeatures->fVmxUseIoBitmaps = RT_BOOL(fProcCtls & VMX_PROC_CTLS_USE_IO_BITMAPS); 1506 pFeatures->fVmxMonitorTrapFlag = RT_BOOL(fProcCtls & VMX_PROC_CTLS_MONITOR_TRAP_FLAG); 1507 pFeatures->fVmxUseMsrBitmaps = RT_BOOL(fProcCtls & VMX_PROC_CTLS_USE_MSR_BITMAPS); 1508 pFeatures->fVmxMonitorExit = RT_BOOL(fProcCtls & VMX_PROC_CTLS_MONITOR_EXIT); 1509 pFeatures->fVmxPauseExit = RT_BOOL(fProcCtls & VMX_PROC_CTLS_PAUSE_EXIT); 1510 pFeatures->fVmxSecondaryExecCtls = RT_BOOL(fProcCtls & VMX_PROC_CTLS_USE_SECONDARY_CTLS); 1315 uint32_t const fFeatures = (pGuestFeatures->fVmxIntWindowExit << VMX_BF_PROC_CTLS_INT_WINDOW_EXIT_SHIFT ) 1316 | (pGuestFeatures->fVmxTscOffsetting << VMX_BF_PROC_CTLS_USE_TSC_OFFSETTING_SHIFT) 1317 | (pGuestFeatures->fVmxHltExit << VMX_BF_PROC_CTLS_HLT_EXIT_SHIFT ) 1318 | (pGuestFeatures->fVmxInvlpgExit << VMX_BF_PROC_CTLS_INVLPG_EXIT_SHIFT ) 1319 | (pGuestFeatures->fVmxMwaitExit << VMX_BF_PROC_CTLS_MWAIT_EXIT_SHIFT ) 1320 | (pGuestFeatures->fVmxRdpmcExit << VMX_BF_PROC_CTLS_RDPMC_EXIT_SHIFT ) 1321 | (pGuestFeatures->fVmxRdtscExit << VMX_BF_PROC_CTLS_RDTSC_EXIT_SHIFT ) 1322 | (pGuestFeatures->fVmxCr3LoadExit << VMX_BF_PROC_CTLS_CR3_LOAD_EXIT_SHIFT ) 1323 | (pGuestFeatures->fVmxCr3StoreExit << VMX_BF_PROC_CTLS_CR3_STORE_EXIT_SHIFT ) 1324 | (pGuestFeatures->fVmxCr8LoadExit << VMX_BF_PROC_CTLS_CR8_LOAD_EXIT_SHIFT ) 1325 | (pGuestFeatures->fVmxCr8StoreExit << VMX_BF_PROC_CTLS_CR8_STORE_EXIT_SHIFT ) 1326 | (pGuestFeatures->fVmxUseTprShadow << VMX_BF_PROC_CTLS_USE_TPR_SHADOW_SHIFT ) 1327 | (pGuestFeatures->fVmxNmiWindowExit << VMX_BF_PROC_CTLS_NMI_WINDOW_EXIT_SHIFT ) 1328 | (pGuestFeatures->fVmxMovDRxExit << VMX_BF_PROC_CTLS_MOV_DR_EXIT_SHIFT ) 1329 | (pGuestFeatures->fVmxUncondIoExit << VMX_BF_PROC_CTLS_UNCOND_IO_EXIT_SHIFT ) 1330 | (pGuestFeatures->fVmxUseIoBitmaps << VMX_BF_PROC_CTLS_USE_IO_BITMAPS_SHIFT ) 1331 | (pGuestFeatures->fVmxMonitorTrapFlag << VMX_BF_PROC_CTLS_MONITOR_TRAP_FLAG_SHIFT ) 1332 | (pGuestFeatures->fVmxUseMsrBitmaps << VMX_BF_PROC_CTLS_USE_MSR_BITMAPS_SHIFT ) 1333 | (pGuestFeatures->fVmxMonitorExit << VMX_BF_PROC_CTLS_MONITOR_EXIT_SHIFT ) 1334 | (pGuestFeatures->fVmxPauseExit << VMX_BF_PROC_CTLS_PAUSE_EXIT_SHIFT ) 1335 | (pGuestFeatures->fVmxSecondaryExecCtls << VMX_BF_PROC_CTLS_USE_SECONDARY_CTLS_SHIFT); 1336 uint32_t const fAllowed0 = VMX_PROC_CTLS_DEFAULT1; 1337 uint32_t const fAllowed1 = fFeatures | VMX_PROC_CTLS_DEFAULT1; 1338 AssertMsg((fAllowed0 & fAllowed1) == fAllowed0, ("fAllowed0=%#RX32 fAllowed1=%#RX32 fFeatures=%#RX32\n", fAllowed0, 1339 fAllowed1, fFeatures)); 1340 pGuestVmxMsrs->ProcCtls.u = RT_MAKE_U64(fAllowed0, fAllowed1); 1511 1341 } 1512 1342 1513 1343 /* Secondary processor-based VM-execution controls. */ 1514 { 1515 uint32_t const fProcCtls2 = pFeatures->fVmxSecondaryExecCtls ? pVmxMsrs->ProcCtls2.n.allowed1 : 0; 1516 pFeatures->fVmxVirtApicAccess = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_VIRT_APIC_ACCESS); 1517 pFeatures->fVmxEpt = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_EPT); 1518 pFeatures->fVmxDescTableExit = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_DESC_TABLE_EXIT); 1519 pFeatures->fVmxRdtscp = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_RDTSCP); 1520 pFeatures->fVmxVirtX2ApicMode = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_VIRT_X2APIC_MODE); 1521 pFeatures->fVmxVpid = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_VPID); 1522 pFeatures->fVmxWbinvdExit = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_WBINVD_EXIT); 1523 pFeatures->fVmxUnrestrictedGuest = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_UNRESTRICTED_GUEST); 1524 pFeatures->fVmxApicRegVirt = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_APIC_REG_VIRT); 1525 pFeatures->fVmxVirtIntDelivery = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_VIRT_INT_DELIVERY); 1526 pFeatures->fVmxPauseLoopExit = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_PAUSE_LOOP_EXIT); 1527 pFeatures->fVmxRdrandExit = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_RDRAND_EXIT); 1528 pFeatures->fVmxInvpcid = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_INVPCID); 1529 pFeatures->fVmxVmFunc = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_VMFUNC); 1530 pFeatures->fVmxVmcsShadowing = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_VMCS_SHADOWING); 1531 pFeatures->fVmxRdseedExit = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_RDSEED_EXIT); 1532 pFeatures->fVmxPml = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_PML); 1533 pFeatures->fVmxEptXcptVe = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_EPT_VE); 1534 pFeatures->fVmxXsavesXrstors = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_XSAVES_XRSTORS); 1535 pFeatures->fVmxUseTscScaling = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_TSC_SCALING); 1344 if (pGuestFeatures->fVmxSecondaryExecCtls) 1345 { 1346 uint32_t const fFeatures = (pGuestFeatures->fVmxVirtApicAccess << VMX_BF_PROC_CTLS2_VIRT_APIC_ACCESS_SHIFT ) 1347 | (pGuestFeatures->fVmxEpt << VMX_BF_PROC_CTLS2_EPT_SHIFT ) 1348 | (pGuestFeatures->fVmxDescTableExit << VMX_BF_PROC_CTLS2_DESC_TABLE_EXIT_SHIFT ) 1349 | (pGuestFeatures->fVmxRdtscp << VMX_BF_PROC_CTLS2_RDTSCP_SHIFT ) 1350 | (pGuestFeatures->fVmxVirtX2ApicMode << VMX_BF_PROC_CTLS2_VIRT_X2APIC_MODE_SHIFT ) 1351 | (pGuestFeatures->fVmxVpid << VMX_BF_PROC_CTLS2_VPID_SHIFT ) 1352 | (pGuestFeatures->fVmxWbinvdExit << VMX_BF_PROC_CTLS2_WBINVD_EXIT_SHIFT ) 1353 | (pGuestFeatures->fVmxUnrestrictedGuest << VMX_BF_PROC_CTLS2_UNRESTRICTED_GUEST_SHIFT) 1354 | (pGuestFeatures->fVmxApicRegVirt << VMX_BF_PROC_CTLS2_APIC_REG_VIRT_SHIFT ) 1355 | (pGuestFeatures->fVmxVirtIntDelivery << VMX_BF_PROC_CTLS2_VIRT_INT_DELIVERY_SHIFT ) 1356 | (pGuestFeatures->fVmxPauseLoopExit << VMX_BF_PROC_CTLS2_PAUSE_LOOP_EXIT_SHIFT ) 1357 | (pGuestFeatures->fVmxRdrandExit << VMX_BF_PROC_CTLS2_RDRAND_EXIT_SHIFT ) 1358 | (pGuestFeatures->fVmxInvpcid << VMX_BF_PROC_CTLS2_INVPCID_SHIFT ) 1359 | (pGuestFeatures->fVmxVmFunc << VMX_BF_PROC_CTLS2_VMFUNC_SHIFT ) 1360 | (pGuestFeatures->fVmxVmcsShadowing << VMX_BF_PROC_CTLS2_VMCS_SHADOWING_SHIFT ) 1361 | (pGuestFeatures->fVmxRdseedExit << VMX_BF_PROC_CTLS2_RDSEED_EXIT_SHIFT ) 1362 | (pGuestFeatures->fVmxPml << VMX_BF_PROC_CTLS2_PML_SHIFT ) 1363 | (pGuestFeatures->fVmxEptXcptVe << VMX_BF_PROC_CTLS2_EPT_VE_SHIFT ) 1364 | (pGuestFeatures->fVmxXsavesXrstors << VMX_BF_PROC_CTLS2_XSAVES_XRSTORS_SHIFT ) 1365 | (pGuestFeatures->fVmxUseTscScaling << VMX_BF_PROC_CTLS2_TSC_SCALING_SHIFT ); 1366 uint32_t const fAllowed0 = 0; 1367 uint32_t const fAllowed1 = fFeatures; 1368 pGuestVmxMsrs->ProcCtls2.u = RT_MAKE_U64(fAllowed0, fAllowed1); 1536 1369 } 1537 1370 1538 1371 /* VM-exit controls. */ 1539 1372 { 1540 uint32_t const fExitCtls = pVmxMsrs->ExitCtls.n.allowed1; 1541 pFeatures->fVmxExitSaveDebugCtls = RT_BOOL(fExitCtls & VMX_EXIT_CTLS_SAVE_DEBUG); 1542 pFeatures->fVmxHostAddrSpaceSize = RT_BOOL(fExitCtls & VMX_EXIT_CTLS_HOST_ADDR_SPACE_SIZE); 1543 pFeatures->fVmxExitAckExtInt = RT_BOOL(fExitCtls & VMX_EXIT_CTLS_ACK_EXT_INT); 1544 pFeatures->fVmxExitSavePatMsr = RT_BOOL(fExitCtls & VMX_EXIT_CTLS_SAVE_PAT_MSR); 1545 pFeatures->fVmxExitLoadPatMsr = RT_BOOL(fExitCtls & VMX_EXIT_CTLS_LOAD_PAT_MSR); 1546 pFeatures->fVmxExitSaveEferMsr = RT_BOOL(fExitCtls & VMX_EXIT_CTLS_SAVE_EFER_MSR); 1547 pFeatures->fVmxExitLoadEferMsr = RT_BOOL(fExitCtls & VMX_EXIT_CTLS_LOAD_EFER_MSR); 1548 pFeatures->fVmxSavePreemptTimer = RT_BOOL(fExitCtls & VMX_EXIT_CTLS_SAVE_PREEMPT_TIMER); 1373 uint32_t const fFeatures = (pGuestFeatures->fVmxExitSaveDebugCtls << VMX_BF_EXIT_CTLS_SAVE_DEBUG_SHIFT ) 1374 | (pGuestFeatures->fVmxHostAddrSpaceSize << VMX_BF_EXIT_CTLS_HOST_ADDR_SPACE_SIZE_SHIFT) 1375 | (pGuestFeatures->fVmxExitAckExtInt << VMX_BF_EXIT_CTLS_ACK_EXT_INT_SHIFT ) 1376 | (pGuestFeatures->fVmxExitSavePatMsr << VMX_BF_EXIT_CTLS_SAVE_PAT_MSR_SHIFT ) 1377 | (pGuestFeatures->fVmxExitLoadPatMsr << VMX_BF_EXIT_CTLS_LOAD_PAT_MSR_SHIFT ) 1378 | (pGuestFeatures->fVmxExitSaveEferMsr << VMX_BF_EXIT_CTLS_SAVE_EFER_MSR_SHIFT ) 1379 | (pGuestFeatures->fVmxExitLoadEferMsr << VMX_BF_EXIT_CTLS_LOAD_EFER_MSR_SHIFT ) 1380 | (pGuestFeatures->fVmxSavePreemptTimer << VMX_BF_EXIT_CTLS_SAVE_PREEMPT_TIMER_SHIFT ); 1381 /* Set the default1 class bits. See Intel spec. A.4 "VM-exit Controls". */ 1382 uint32_t const fAllowed0 = VMX_EXIT_CTLS_DEFAULT1; 1383 uint32_t const fAllowed1 = fFeatures | VMX_EXIT_CTLS_DEFAULT1; 1384 AssertMsg((fAllowed0 & fAllowed1) == fAllowed0, ("fAllowed0=%#RX32 fAllowed1=%#RX32 fFeatures=%#RX32\n", fAllowed0, 1385 fAllowed1, fFeatures)); 1386 pGuestVmxMsrs->ExitCtls.u = RT_MAKE_U64(fAllowed0, fAllowed1); 1549 1387 } 1550 1388 1551 1389 /* VM-entry controls. */ 1552 1390 { 1553 uint32_t const fEntryCtls = pVmxMsrs->EntryCtls.n.allowed1; 1554 pFeatures->fVmxEntryLoadDebugCtls = RT_BOOL(fEntryCtls & VMX_ENTRY_CTLS_LOAD_DEBUG); 1555 pFeatures->fVmxIa32eModeGuest = RT_BOOL(fEntryCtls & VMX_ENTRY_CTLS_IA32E_MODE_GUEST); 1556 pFeatures->fVmxEntryLoadEferMsr = RT_BOOL(fEntryCtls & VMX_ENTRY_CTLS_LOAD_EFER_MSR); 1557 pFeatures->fVmxEntryLoadPatMsr = RT_BOOL(fEntryCtls & VMX_ENTRY_CTLS_LOAD_PAT_MSR); 1391 uint32_t const fFeatures = (pGuestFeatures->fVmxEntryLoadDebugCtls << VMX_BF_ENTRY_CTLS_LOAD_DEBUG_SHIFT ) 1392 | (pGuestFeatures->fVmxIa32eModeGuest << VMX_BF_ENTRY_CTLS_IA32E_MODE_GUEST_SHIFT) 1393 | (pGuestFeatures->fVmxEntryLoadEferMsr << VMX_BF_ENTRY_CTLS_LOAD_EFER_MSR_SHIFT ) 1394 | (pGuestFeatures->fVmxEntryLoadPatMsr << VMX_BF_ENTRY_CTLS_LOAD_PAT_MSR_SHIFT ); 1395 uint32_t const fAllowed0 = VMX_ENTRY_CTLS_DEFAULT1; 1396 uint32_t const fAllowed1 = fFeatures | VMX_ENTRY_CTLS_DEFAULT1; 1397 AssertMsg((fAllowed0 & fAllowed1) == fAllowed0, ("fAllowed0=%#RX32 fAllowed0=%#RX32 fFeatures=%#RX32\n", fAllowed0, 1398 fAllowed1, fFeatures)); 1399 pGuestVmxMsrs->EntryCtls.u = RT_MAKE_U64(fAllowed0, fAllowed1); 1558 1400 } 1559 1401 1560 1402 /* Miscellaneous data. */ 1561 1403 { 1562 uint32_t const fMiscData = pVmxMsrs->u64Misc; 1563 pFeatures->fVmxExitSaveEferLma = RT_BOOL(fMiscData & VMX_MISC_EXIT_SAVE_EFER_LMA); 1564 pFeatures->fVmxIntelPt = RT_BOOL(fMiscData & VMX_MISC_INTEL_PT); 1565 pFeatures->fVmxVmwriteAll = RT_BOOL(fMiscData & VMX_MISC_VMWRITE_ALL); 1566 pFeatures->fVmxEntryInjectSoftInt = RT_BOOL(fMiscData & VMX_MISC_ENTRY_INJECT_SOFT_INT); 1567 } 1404 uint64_t const uHostMsr = cpumR3IsHwAssistVmxNstGstExecAllowed(pVM) ? pHostVmxMsrs->u64Misc : 0; 1405 1406 uint8_t const cMaxMsrs = RT_MIN(RT_BF_GET(uHostMsr, VMX_BF_MISC_MAX_MSRS), VMX_V_AUTOMSR_COUNT_MAX); 1407 uint8_t const fActivityState = RT_BF_GET(uHostMsr, VMX_BF_MISC_ACTIVITY_STATES) & VMX_V_GUEST_ACTIVITY_STATE_MASK; 1408 pGuestVmxMsrs->u64Misc = RT_BF_MAKE(VMX_BF_MISC_PREEMPT_TIMER_TSC, VMX_V_PREEMPT_TIMER_SHIFT ) 1409 | RT_BF_MAKE(VMX_BF_MISC_EXIT_SAVE_EFER_LMA, pGuestFeatures->fVmxExitSaveEferLma ) 1410 | RT_BF_MAKE(VMX_BF_MISC_ACTIVITY_STATES, fActivityState ) 1411 | RT_BF_MAKE(VMX_BF_MISC_INTEL_PT, pGuestFeatures->fVmxIntelPt ) 1412 | RT_BF_MAKE(VMX_BF_MISC_SMM_READ_SMBASE_MSR, 0 ) 1413 | RT_BF_MAKE(VMX_BF_MISC_CR3_TARGET, VMX_V_CR3_TARGET_COUNT ) 1414 | RT_BF_MAKE(VMX_BF_MISC_MAX_MSRS, cMaxMsrs ) 1415 | RT_BF_MAKE(VMX_BF_MISC_VMXOFF_BLOCK_SMI, 0 ) 1416 | RT_BF_MAKE(VMX_BF_MISC_VMWRITE_ALL, pGuestFeatures->fVmxVmwriteAll ) 1417 | RT_BF_MAKE(VMX_BF_MISC_ENTRY_INJECT_SOFT_INT, pGuestFeatures->fVmxEntryInjectSoftInt) 1418 | RT_BF_MAKE(VMX_BF_MISC_MSEG_ID, VMX_V_MSEG_REV_ID ); 1419 } 1420 1421 /* CR0 Fixed-0. */ 1422 pGuestVmxMsrs->u64Cr0Fixed0 = pGuestFeatures->fVmxUnrestrictedGuest ? VMX_V_CR0_FIXED0_UX: VMX_V_CR0_FIXED0; 1423 1424 /* CR0 Fixed-1. */ 1425 { 1426 uint64_t const uHostMsr = cpumR3IsHwAssistVmxNstGstExecAllowed(pVM) ? pHostVmxMsrs->u64Cr0Fixed1 : 0; 1427 pGuestVmxMsrs->u64Cr0Fixed1 = uHostMsr | VMX_V_CR0_FIXED0; /* Make sure the CR0 MB1 bits are not clear. */ 1428 } 1429 1430 /* CR4 Fixed-0. */ 1431 pGuestVmxMsrs->u64Cr4Fixed0 = VMX_V_CR4_FIXED0; 1432 1433 /* CR4 Fixed-1. */ 1434 { 1435 uint64_t const uHostMsr = cpumR3IsHwAssistVmxNstGstExecAllowed(pVM) ? pHostVmxMsrs->u64Cr4Fixed1 : 0; 1436 pGuestVmxMsrs->u64Cr4Fixed1 = uHostMsr | VMX_V_CR4_FIXED0; /* Make sure the CR4 MB1 bits are not clear. */ 1437 } 1438 1439 /* VMCS Enumeration. */ 1440 pGuestVmxMsrs->u64VmcsEnum = VMX_V_VMCS_MAX_INDEX << VMX_BF_VMCS_ENUM_HIGHEST_IDX_SHIFT; 1441 1442 /* VM Functions. */ 1443 if (pGuestFeatures->fVmxVmFunc) 1444 pGuestVmxMsrs->u64VmFunc = RT_BF_MAKE(VMX_BF_VMFUNC_EPTP_SWITCHING, 1); 1568 1445 } 1569 1446 … … 1659 1536 #endif 1660 1537 1661 /** 1662 * Initializes VMX host and guest features. 1663 * 1664 * @param pVM The cross context VM structure. 1665 * 1666 * @remarks This must be called only after HM has fully initialized since it calls 1667 * into HM to retrieve VMX and related MSRs. 1668 */ 1669 static void cpumR3InitVmxCpuFeatures(PVM pVM) 1670 { 1671 /* 1672 * Init. host features. 1673 */ 1674 PCPUMFEATURES pHostFeat = &pVM->cpum.s.HostFeatures; 1675 VMXMSRS VmxMsrs; 1676 if (cpumR3IsHwAssistVmxNstGstExecAllowed(pVM)) 1677 { 1678 /** @todo NSTVMX: When NEM support for nested-VMX is there, we'll need to fetch 1679 * the MSRs from NEM or do the support driver IOCTL route, see patch in 1680 * @bugref{9180}. */ 1681 if (HMIsEnabled(pVM)) 1682 { 1683 int rc = HMVmxGetHostMsrs(pVM, &VmxMsrs); 1684 if (RT_SUCCESS(rc)) 1685 cpumR3ExplodeVmxFeatures(&VmxMsrs, pHostFeat); 1686 } 1687 else 1688 AssertMsgFailed(("NEM support for nested-VMX is not implemented yet\n")); 1689 } 1538 1539 /** 1540 * Initializes VMX guest features and MSRs. 1541 * 1542 * @param pVM The cross context VM structure. 1543 * @param pHostVmxMsrs The host VMX MSRs. Pass NULL when fully emulating VMX 1544 * and no hardware-assisted nested-guest execution is 1545 * possible for this VM. 1546 * @param pGuestVmxMsrs Where to store the initialized guest VMX MSRs. 1547 */ 1548 void cpumR3InitVmxGuestFeaturesAndMsrs(PVM pVM, PCVMXMSRS pHostVmxMsrs, PVMXMSRS pGuestVmxMsrs) 1549 { 1550 Assert(pVM); 1551 Assert(pGuestVmxMsrs); 1690 1552 1691 1553 /* 1692 1554 * Initialize the set of VMX features we emulate. 1693 * Note! Some bits might be reported as 1 always if they fall under the default1 class bits 1694 * (e.g. fVmxEntryLoadDebugCtls), see @bugref{9180#c5}. 1555 * 1556 * Note! Some bits might be reported as 1 always if they fall under the 1557 * default1 class bits (e.g. fVmxEntryLoadDebugCtls), see @bugref{9180#c5}. 1695 1558 */ 1696 1559 CPUMFEATURES EmuFeat; … … 1767 1630 * by the hardware, hence we merge our emulated features with the host features below. 1768 1631 */ 1769 PCCPUMFEATURES pBaseFeat = cpumR3IsHwAssistVmxNstGstExecAllowed(pVM) ? pHostFeat: &EmuFeat;1770 PCPUMFEATURES pGuestFeat 1771 pGuestFeat->fVmx = (pBaseFeat->fVmx & EmuFeat.fVmx);1632 PCCPUMFEATURES pBaseFeat = cpumR3IsHwAssistVmxNstGstExecAllowed(pVM) ? &pVM->cpum.s.HostFeatures : &EmuFeat; 1633 PCPUMFEATURES pGuestFeat = &pVM->cpum.s.GuestFeatures; 1634 Assert(pBaseFeat->fVmx); 1772 1635 pGuestFeat->fVmxInsOutInfo = (pBaseFeat->fVmxInsOutInfo & EmuFeat.fVmxInsOutInfo ); 1773 1636 pGuestFeat->fVmxExtIntExit = (pBaseFeat->fVmxExtIntExit & EmuFeat.fVmxExtIntExit ); … … 1860 1723 1861 1724 /* 1862 * Finally initialize the VMX guest MSRs after merging the guest features.1725 * Finally initialize the VMX guest MSRs. 1863 1726 */ 1864 cpumR3InitGuestVmxMsrs(pVM); 1727 cpumR3InitVmxGuestMsrs(pVM, pHostVmxMsrs, pGuestFeat, pGuestVmxMsrs); 1728 } 1729 1730 1731 static int cpumR3GetHostHwvirtMsrs(PCPUMMSRS pMsrs) 1732 { 1733 Assert(pMsrs); 1734 1735 uint32_t fCaps = 0; 1736 int rc = SUPR3QueryVTCaps(&fCaps); 1737 if (RT_SUCCESS(rc)) 1738 { 1739 if (fCaps & (SUPVTCAPS_VT_X | SUPVTCAPS_AMD_V)) 1740 { 1741 SUPHWVIRTMSRS HwvirtMsrs; 1742 int rc = SUPR3GetHwvirtMsrs(&HwvirtMsrs, false /* fForceRequery */); 1743 if (RT_SUCCESS(rc)) 1744 { 1745 if (fCaps & SUPVTCAPS_VT_X) 1746 pMsrs->hwvirt.vmx = HwvirtMsrs.u.vmx; 1747 else 1748 pMsrs->hwvirt.svm = HwvirtMsrs.u.svm; 1749 return VINF_SUCCESS; 1750 } 1751 1752 LogRel(("CPUM: Query hardware-virtualization MSRs failed. rc=%Rrc\n", rc)); 1753 return rc; 1754 } 1755 else 1756 { 1757 LogRel(("CPUM: Querying hardware-virtualization capability succeeded but did not find VT-x or AMD-V\n")); 1758 return VERR_INTERNAL_ERROR_5; 1759 } 1760 } 1761 else 1762 LogRel(("CPUM: No hardware-virtualization capability detected\n")); 1763 1764 return VINF_SUCCESS; 1865 1765 } 1866 1766 … … 1916 1816 if (!ASMHasCpuId()) 1917 1817 { 1918 Log (("The CPU doesn't support CPUID!\n"));1818 LogRel(("The CPU doesn't support CPUID!\n")); 1919 1819 return VERR_UNSUPPORTED_CPU; 1920 1820 } 1921 1821 1922 1822 pVM->cpum.s.fHostMxCsrMask = CPUMR3DeterminHostMxCsrMask(); 1823 1824 CPUMMSRS HostMsrs; 1825 RT_ZERO(HostMsrs); 1826 int rc = cpumR3GetHostHwvirtMsrs(&HostMsrs); 1827 AssertLogRelRCReturn(rc, rc); 1923 1828 1924 1829 PCPUMCPUIDLEAF paLeaves; 1925 1830 uint32_t cLeaves; 1926 intrc = CPUMR3CpuIdCollectLeaves(&paLeaves, &cLeaves);1831 rc = CPUMR3CpuIdCollectLeaves(&paLeaves, &cLeaves); 1927 1832 AssertLogRelRCReturn(rc, rc); 1928 1833 1929 rc = cpumR3CpuIdExplodeFeatures(paLeaves, cLeaves, & pVM->cpum.s.HostFeatures);1834 rc = cpumR3CpuIdExplodeFeatures(paLeaves, cLeaves, &HostMsrs, &pVM->cpum.s.HostFeatures); 1930 1835 RTMemFree(paLeaves); 1931 1836 AssertLogRelRCReturn(rc, rc); … … 2042 1947 * Initialize the Guest CPUID and MSR states. 2043 1948 */ 2044 rc = cpumR3InitCpuIdAndMsrs(pVM );1949 rc = cpumR3InitCpuIdAndMsrs(pVM, &HostMsrs); 2045 1950 if (RT_FAILURE(rc)) 2046 1951 return rc; 2047 1952 2048 1953 /* 2049 * Allocate memory required by the guest hardware virtualization state. 1954 * Allocate memory required by the guest hardware-virtualization structures. 1955 * This must be done after initializing CPUID/MSR features as we access the 1956 * the VMX/SVM guest features below. 2050 1957 */ 2051 1958 if (pVM->cpum.s.GuestFeatures.fVmx) … … 2057 1964 if (RT_FAILURE(rc)) 2058 1965 return rc; 2059 2060 /*2061 * Initialize guest hardware virtualization state.2062 */2063 CPUMHWVIRT const enmHwvirt = pVM->aCpus[0].cpum.s.Guest.hwvirt.enmHwvirt;2064 if (enmHwvirt == CPUMHWVIRT_VMX)2065 {2066 for (VMCPUID i = 0; i < pVM->cCpus; i++)2067 cpumR3InitVmxHwVirtState(&pVM->aCpus[i]);2068 2069 /* Initialize VMX features. */2070 cpumR3InitVmxCpuFeatures(pVM);2071 DBGFR3Info(pVM->pUVM, "cpumvmxfeat", "default", DBGFR3InfoLogRelHlp());2072 }2073 else if (enmHwvirt == CPUMHWVIRT_SVM)2074 {2075 for (VMCPUID i = 0; i < pVM->cCpus; i++)2076 cpumR3InitSvmHwVirtState(&pVM->aCpus[i]);2077 }2078 1966 2079 1967 /* … … 2314 2202 Assert(!pVM->cpum.s.GuestFeatures.fVmx || !pVM->cpum.s.GuestFeatures.fSvm); /* Paranoia. */ 2315 2203 if (pVM->cpum.s.GuestFeatures.fVmx) 2316 cpumR3 InitVmxHwVirtState(pVCpu);2204 cpumR3ResetVmxHwVirtState(pVCpu); 2317 2205 else if (pVM->cpum.s.GuestFeatures.fSvm) 2318 cpumR3 InitSvmHwVirtState(pVCpu);2206 cpumR3ResetSvmHwVirtState(pVCpu); 2319 2207 } 2320 2208 … … 2670 2558 } 2671 2559 } 2560 /** @todo NSTVMX: Load VMX state. */ 2672 2561 } 2673 2562 else … … 2773 2662 */ 2774 2663 if (uVersion >= CPUM_SAVED_STATE_VERSION_VER3_2) 2775 return cpumR3LoadCpuId(pVM, pSSM, uVersion); 2664 { 2665 CPUMMSRS GuestMsrs; 2666 RT_ZERO(GuestMsrs); 2667 if (pVM->cpum.s.GuestFeatures.fVmx) 2668 GuestMsrs.hwvirt.vmx = pVM->aCpus[0].cpum.s.Guest.hwvirt.vmx.Msrs; 2669 return cpumR3LoadCpuId(pVM, pSSM, uVersion, &GuestMsrs); 2670 } 2776 2671 return cpumR3LoadCpuIdPre32(pVM, pSSM, uVersion); 2777 2672 } … … 4032 3927 RTLogRelSetBuffering(fOldBuffered); 4033 3928 LogRel(("******************** End of CPUID dump **********************\n")); 4034 } 4035 3929 3930 /* 3931 * Log VT-x extended features. 3932 * 3933 * SVM features are currently all covered under CPUID so there is nothing 3934 * to do here for SVM. 3935 */ 3936 if (pVM->cpum.s.HostFeatures.fVmx) 3937 { 3938 LogRel(("*********************** VT-x features ***********************\n")); 3939 DBGFR3Info(pVM->pUVM, "cpumvmxfeat", "default", DBGFR3InfoLogRelHlp()); 3940 LogRel(("\n")); 3941 LogRel(("******************* End of VT-x features ********************\n")); 3942 } 3943 } 3944 -
trunk/src/VBox/VMM/VMMR3/CPUMR3CpuId.cpp
r74163 r76464 1679 1679 1680 1680 1681 int cpumR3CpuIdExplodeFeatures(PCCPUMCPUIDLEAF paLeaves, uint32_t cLeaves, PCPUMFEATURES pFeatures) 1682 { 1681 static void cpumR3ExplodeVmxFeatures(PCVMXMSRS pVmxMsrs, PCPUMFEATURES pFeatures) 1682 { 1683 Assert(pVmxMsrs); 1684 Assert(pFeatures); 1685 Assert(pFeatures->fVmx); 1686 1687 /* Basic information. */ 1688 { 1689 uint64_t const u64Basic = pVmxMsrs->u64Basic; 1690 pFeatures->fVmxInsOutInfo = RT_BF_GET(u64Basic, VMX_BF_BASIC_VMCS_INS_OUTS); 1691 } 1692 1693 /* Pin-based VM-execution controls. */ 1694 { 1695 uint32_t const fPinCtls = pVmxMsrs->PinCtls.n.allowed1; 1696 pFeatures->fVmxExtIntExit = RT_BOOL(fPinCtls & VMX_PIN_CTLS_EXT_INT_EXIT); 1697 pFeatures->fVmxNmiExit = RT_BOOL(fPinCtls & VMX_PIN_CTLS_NMI_EXIT); 1698 pFeatures->fVmxVirtNmi = RT_BOOL(fPinCtls & VMX_PIN_CTLS_VIRT_NMI); 1699 pFeatures->fVmxPreemptTimer = RT_BOOL(fPinCtls & VMX_PIN_CTLS_PREEMPT_TIMER); 1700 pFeatures->fVmxPostedInt = RT_BOOL(fPinCtls & VMX_PIN_CTLS_POSTED_INT); 1701 } 1702 1703 /* Processor-based VM-execution controls. */ 1704 { 1705 uint32_t const fProcCtls = pVmxMsrs->ProcCtls.n.allowed1; 1706 pFeatures->fVmxIntWindowExit = RT_BOOL(fProcCtls & VMX_PROC_CTLS_INT_WINDOW_EXIT); 1707 pFeatures->fVmxTscOffsetting = RT_BOOL(fProcCtls & VMX_PROC_CTLS_USE_TSC_OFFSETTING); 1708 pFeatures->fVmxHltExit = RT_BOOL(fProcCtls & VMX_PROC_CTLS_HLT_EXIT); 1709 pFeatures->fVmxInvlpgExit = RT_BOOL(fProcCtls & VMX_PROC_CTLS_INVLPG_EXIT); 1710 pFeatures->fVmxMwaitExit = RT_BOOL(fProcCtls & VMX_PROC_CTLS_MWAIT_EXIT); 1711 pFeatures->fVmxRdpmcExit = RT_BOOL(fProcCtls & VMX_PROC_CTLS_RDPMC_EXIT); 1712 pFeatures->fVmxRdtscExit = RT_BOOL(fProcCtls & VMX_PROC_CTLS_RDTSC_EXIT); 1713 pFeatures->fVmxCr3LoadExit = RT_BOOL(fProcCtls & VMX_PROC_CTLS_CR3_LOAD_EXIT); 1714 pFeatures->fVmxCr3StoreExit = RT_BOOL(fProcCtls & VMX_PROC_CTLS_CR3_STORE_EXIT); 1715 pFeatures->fVmxCr8LoadExit = RT_BOOL(fProcCtls & VMX_PROC_CTLS_CR8_LOAD_EXIT); 1716 pFeatures->fVmxCr8StoreExit = RT_BOOL(fProcCtls & VMX_PROC_CTLS_CR8_STORE_EXIT); 1717 pFeatures->fVmxUseTprShadow = RT_BOOL(fProcCtls & VMX_PROC_CTLS_USE_TPR_SHADOW); 1718 pFeatures->fVmxNmiWindowExit = RT_BOOL(fProcCtls & VMX_PROC_CTLS_NMI_WINDOW_EXIT); 1719 pFeatures->fVmxMovDRxExit = RT_BOOL(fProcCtls & VMX_PROC_CTLS_MOV_DR_EXIT); 1720 pFeatures->fVmxUncondIoExit = RT_BOOL(fProcCtls & VMX_PROC_CTLS_UNCOND_IO_EXIT); 1721 pFeatures->fVmxUseIoBitmaps = RT_BOOL(fProcCtls & VMX_PROC_CTLS_USE_IO_BITMAPS); 1722 pFeatures->fVmxMonitorTrapFlag = RT_BOOL(fProcCtls & VMX_PROC_CTLS_MONITOR_TRAP_FLAG); 1723 pFeatures->fVmxUseMsrBitmaps = RT_BOOL(fProcCtls & VMX_PROC_CTLS_USE_MSR_BITMAPS); 1724 pFeatures->fVmxMonitorExit = RT_BOOL(fProcCtls & VMX_PROC_CTLS_MONITOR_EXIT); 1725 pFeatures->fVmxPauseExit = RT_BOOL(fProcCtls & VMX_PROC_CTLS_PAUSE_EXIT); 1726 pFeatures->fVmxSecondaryExecCtls = RT_BOOL(fProcCtls & VMX_PROC_CTLS_USE_SECONDARY_CTLS); 1727 } 1728 1729 /* Secondary processor-based VM-execution controls. */ 1730 { 1731 uint32_t const fProcCtls2 = pFeatures->fVmxSecondaryExecCtls ? pVmxMsrs->ProcCtls2.n.allowed1 : 0; 1732 pFeatures->fVmxVirtApicAccess = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_VIRT_APIC_ACCESS); 1733 pFeatures->fVmxEpt = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_EPT); 1734 pFeatures->fVmxDescTableExit = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_DESC_TABLE_EXIT); 1735 pFeatures->fVmxRdtscp = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_RDTSCP); 1736 pFeatures->fVmxVirtX2ApicMode = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_VIRT_X2APIC_MODE); 1737 pFeatures->fVmxVpid = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_VPID); 1738 pFeatures->fVmxWbinvdExit = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_WBINVD_EXIT); 1739 pFeatures->fVmxUnrestrictedGuest = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_UNRESTRICTED_GUEST); 1740 pFeatures->fVmxApicRegVirt = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_APIC_REG_VIRT); 1741 pFeatures->fVmxVirtIntDelivery = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_VIRT_INT_DELIVERY); 1742 pFeatures->fVmxPauseLoopExit = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_PAUSE_LOOP_EXIT); 1743 pFeatures->fVmxRdrandExit = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_RDRAND_EXIT); 1744 pFeatures->fVmxInvpcid = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_INVPCID); 1745 pFeatures->fVmxVmFunc = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_VMFUNC); 1746 pFeatures->fVmxVmcsShadowing = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_VMCS_SHADOWING); 1747 pFeatures->fVmxRdseedExit = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_RDSEED_EXIT); 1748 pFeatures->fVmxPml = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_PML); 1749 pFeatures->fVmxEptXcptVe = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_EPT_VE); 1750 pFeatures->fVmxXsavesXrstors = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_XSAVES_XRSTORS); 1751 pFeatures->fVmxUseTscScaling = RT_BOOL(fProcCtls2 & VMX_PROC_CTLS2_TSC_SCALING); 1752 } 1753 1754 /* VM-exit controls. */ 1755 { 1756 uint32_t const fExitCtls = pVmxMsrs->ExitCtls.n.allowed1; 1757 pFeatures->fVmxExitSaveDebugCtls = RT_BOOL(fExitCtls & VMX_EXIT_CTLS_SAVE_DEBUG); 1758 pFeatures->fVmxHostAddrSpaceSize = RT_BOOL(fExitCtls & VMX_EXIT_CTLS_HOST_ADDR_SPACE_SIZE); 1759 pFeatures->fVmxExitAckExtInt = RT_BOOL(fExitCtls & VMX_EXIT_CTLS_ACK_EXT_INT); 1760 pFeatures->fVmxExitSavePatMsr = RT_BOOL(fExitCtls & VMX_EXIT_CTLS_SAVE_PAT_MSR); 1761 pFeatures->fVmxExitLoadPatMsr = RT_BOOL(fExitCtls & VMX_EXIT_CTLS_LOAD_PAT_MSR); 1762 pFeatures->fVmxExitSaveEferMsr = RT_BOOL(fExitCtls & VMX_EXIT_CTLS_SAVE_EFER_MSR); 1763 pFeatures->fVmxExitLoadEferMsr = RT_BOOL(fExitCtls & VMX_EXIT_CTLS_LOAD_EFER_MSR); 1764 pFeatures->fVmxSavePreemptTimer = RT_BOOL(fExitCtls & VMX_EXIT_CTLS_SAVE_PREEMPT_TIMER); 1765 } 1766 1767 /* VM-entry controls. */ 1768 { 1769 uint32_t const fEntryCtls = pVmxMsrs->EntryCtls.n.allowed1; 1770 pFeatures->fVmxEntryLoadDebugCtls = RT_BOOL(fEntryCtls & VMX_ENTRY_CTLS_LOAD_DEBUG); 1771 pFeatures->fVmxIa32eModeGuest = RT_BOOL(fEntryCtls & VMX_ENTRY_CTLS_IA32E_MODE_GUEST); 1772 pFeatures->fVmxEntryLoadEferMsr = RT_BOOL(fEntryCtls & VMX_ENTRY_CTLS_LOAD_EFER_MSR); 1773 pFeatures->fVmxEntryLoadPatMsr = RT_BOOL(fEntryCtls & VMX_ENTRY_CTLS_LOAD_PAT_MSR); 1774 } 1775 1776 /* Miscellaneous data. */ 1777 { 1778 uint32_t const fMiscData = pVmxMsrs->u64Misc; 1779 pFeatures->fVmxExitSaveEferLma = RT_BOOL(fMiscData & VMX_MISC_EXIT_SAVE_EFER_LMA); 1780 pFeatures->fVmxIntelPt = RT_BOOL(fMiscData & VMX_MISC_INTEL_PT); 1781 pFeatures->fVmxVmwriteAll = RT_BOOL(fMiscData & VMX_MISC_VMWRITE_ALL); 1782 pFeatures->fVmxEntryInjectSoftInt = RT_BOOL(fMiscData & VMX_MISC_ENTRY_INJECT_SOFT_INT); 1783 } 1784 } 1785 1786 1787 int cpumR3CpuIdExplodeFeatures(PCCPUMCPUIDLEAF paLeaves, uint32_t cLeaves, PCCPUMMSRS pMsrs, PCPUMFEATURES pFeatures) 1788 { 1789 Assert(pMsrs); 1683 1790 RT_ZERO(*pFeatures); 1684 1791 if (cLeaves >= 2) … … 1747 1854 pFeatures->fPcid = RT_BOOL(pStd1Leaf->uEcx & X86_CPUID_FEATURE_ECX_PCID); 1748 1855 pFeatures->fVmx = RT_BOOL(pStd1Leaf->uEcx & X86_CPUID_FEATURE_ECX_VMX); 1749 /* VMX sub-features will be initialized in cpumR3InitVmxCpuFeatures(). */ 1856 if (pFeatures->fVmx) 1857 cpumR3ExplodeVmxFeatures(&pMsrs->hwvirt.vmx, pFeatures); 1750 1858 1751 1859 /* Structured extended features. */ … … 2186 2294 * @param paLeaves The leaves. These will be copied (but not freed). 2187 2295 * @param cLeaves The number of leaves. 2296 * @param pMsrs The MSRs. 2188 2297 */ 2189 static int cpumR3CpuIdInstallAndExplodeLeaves(PVM pVM, PCPUM pCpum, PCPUMCPUIDLEAF paLeaves, uint32_t cLeaves )2298 static int cpumR3CpuIdInstallAndExplodeLeaves(PVM pVM, PCPUM pCpum, PCPUMCPUIDLEAF paLeaves, uint32_t cLeaves, PCCPUMMSRS pMsrs) 2190 2299 { 2191 2300 cpumR3CpuIdAssertOrder(paLeaves, cLeaves); … … 2235 2344 * Explode the guest CPU features. 2236 2345 */ 2237 rc = cpumR3CpuIdExplodeFeatures(pCpum->GuestInfo.paCpuIdLeavesR3, pCpum->GuestInfo.cCpuIdLeaves, &pCpum->GuestFeatures); 2346 rc = cpumR3CpuIdExplodeFeatures(pCpum->GuestInfo.paCpuIdLeavesR3, pCpum->GuestInfo.cCpuIdLeaves, pMsrs, 2347 &pCpum->GuestFeatures); 2238 2348 AssertLogRelRCReturn(rc, rc); 2239 2349 … … 4219 4329 * @returns VBox status code. 4220 4330 * @param pVM The cross context VM structure. 4331 * @param pHostMsrs Pointer to the host MSRs. 4221 4332 */ 4222 int cpumR3InitCpuIdAndMsrs(PVM pVM) 4223 { 4333 int cpumR3InitCpuIdAndMsrs(PVM pVM, PCCPUMMSRS pHostMsrs) 4334 { 4335 Assert(pHostMsrs); 4336 4224 4337 PCPUM pCpum = &pVM->cpum.s; 4225 4338 PCFGMNODE pCpumCfg = CFGMR3GetChild(CFGMR3GetRoot(pVM), "CPUM"); … … 4281 4394 "Please use IMachine::setCPUIDLeaf() instead."); 4282 4395 4396 CPUMMSRS GuestMsrs; 4397 RT_ZERO(GuestMsrs); 4398 4283 4399 /* 4284 4400 * Pre-explode the CPUID info. 4285 4401 */ 4286 4402 if (RT_SUCCESS(rc)) 4287 rc = cpumR3CpuIdExplodeFeatures(pCpum->GuestInfo.paCpuIdLeavesR3, pCpum->GuestInfo.cCpuIdLeaves, &pCpum->GuestFeatures); 4403 { 4404 rc = cpumR3CpuIdExplodeFeatures(pCpum->GuestInfo.paCpuIdLeavesR3, pCpum->GuestInfo.cCpuIdLeaves, &GuestMsrs, 4405 &pCpum->GuestFeatures); 4406 } 4288 4407 4289 4408 /* … … 4325 4444 void *pvFree = pCpum->GuestInfo.paCpuIdLeavesR3; 4326 4445 int rc1 = cpumR3CpuIdInstallAndExplodeLeaves(pVM, pCpum, pCpum->GuestInfo.paCpuIdLeavesR3, 4327 pCpum->GuestInfo.cCpuIdLeaves );4446 pCpum->GuestInfo.cCpuIdLeaves, &GuestMsrs); 4328 4447 RTMemFree(pvFree); 4329 4448 … … 4339 4458 pCpum->GuestInfo.paMsrRangesRC = MMHyperR3ToRC(pVM, pCpum->GuestInfo.paMsrRangesR3); 4340 4459 4460 /* 4461 * Finally, initialize guest VMX MSRs. 4462 * 4463 * This needs to be done -after- exploding guest features and sanitizing CPUID leaves 4464 * as constructing VMX capabilities MSRs rely on CPU feature bits such as long mode, 4465 * unrestricted execution and possibly more in the future. 4466 */ 4467 if (pVM->cpum.s.GuestFeatures.fVmx) 4468 { 4469 Assert(Config.fNestedHWVirt); 4470 cpumR3InitVmxGuestFeaturesAndMsrs(pVM, &pHostMsrs->hwvirt.vmx, &GuestMsrs.hwvirt.vmx); 4471 4472 /* Copy MSRs to all VCPUs */ 4473 PCVMXMSRS pVmxMsrs = &GuestMsrs.hwvirt.vmx; 4474 for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++) 4475 { 4476 PVMCPU pVCpu = &pVM->aCpus[idCpu]; 4477 memcpy(&pVCpu->cpum.s.Guest.hwvirt.vmx.Msrs, pVmxMsrs, sizeof(*pVmxMsrs)); 4478 } 4479 } 4341 4480 4342 4481 /* … … 5116 5255 * @param paLeaves Guest CPUID leaves loaded from the state. 5117 5256 * @param cLeaves The number of leaves in @a paLeaves. 5257 * @param pMsrs The guest MSRs. 5118 5258 */ 5119 int cpumR3LoadCpuIdInner(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, PCPUMCPUIDLEAF paLeaves, uint32_t cLeaves )5259 int cpumR3LoadCpuIdInner(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, PCPUMCPUIDLEAF paLeaves, uint32_t cLeaves, PCCPUMMSRS pMsrs) 5120 5260 { 5121 5261 AssertMsgReturn(uVersion >= CPUM_SAVED_STATE_VERSION_VER3_2, ("%u\n", uVersion), VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION); … … 5859 5999 pVM->cpum.s.GuestInfo.paCpuIdLeavesRC = NIL_RTRCPTR; 5860 6000 pVM->cpum.s.GuestInfo.DefCpuId = GuestDefCpuId; 5861 rc = cpumR3CpuIdInstallAndExplodeLeaves(pVM, &pVM->cpum.s, paLeaves, cLeaves );6001 rc = cpumR3CpuIdInstallAndExplodeLeaves(pVM, &pVM->cpum.s, paLeaves, cLeaves, pMsrs); 5862 6002 AssertLogRelRCReturn(rc, rc); 5863 6003 … … 5873 6013 * @param pSSM The saved state handle. 5874 6014 * @param uVersion The format version. 6015 * @param pMsrs The guest MSRs. 5875 6016 */ 5876 int cpumR3LoadCpuId(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion )6017 int cpumR3LoadCpuId(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, PCCPUMMSRS pMsrs) 5877 6018 { 5878 6019 AssertMsgReturn(uVersion >= CPUM_SAVED_STATE_VERSION_VER3_2, ("%u\n", uVersion), VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION); … … 5888 6029 if (RT_SUCCESS(rc)) 5889 6030 { 5890 rc = cpumR3LoadCpuIdInner(pVM, pSSM, uVersion, paLeaves, cLeaves );6031 rc = cpumR3LoadCpuIdInner(pVM, pSSM, uVersion, paLeaves, cLeaves, pMsrs); 5891 6032 RTMemFree(paLeaves); 5892 6033 } -
trunk/src/VBox/VMM/VMMR3/HM.cpp
r76290 r76464 703 703 if (fCaps & SUPVTCAPS_AMD_V) 704 704 { 705 rc = SUPR3CallVMMR0Ex(pVM->pVMR0, 0 /*idCpu*/, VMMR0_DO_HM_PRE_INIT, 0, NULL); 706 AssertRCReturn(rc, rc); 707 Assert(pVM->hm.s.svm.fSupported); 708 705 pVM->hm.s.svm.fSupported = true; 709 706 LogRel(("HM: HMR3Init: AMD-V%s\n", fCaps & SUPVTCAPS_NESTED_PAGING ? " w/ nested paging" : "")); 710 707 VM_SET_MAIN_EXECUTION_ENGINE(pVM, VM_EXEC_ENGINE_HW_VIRT); … … 716 713 if (RT_SUCCESS(rc)) 717 714 { 718 rc = SUPR3CallVMMR0Ex(pVM->pVMR0, 0 /*idCpu*/, VMMR0_DO_HM_PRE_INIT, 0, NULL); 719 AssertRCReturn(rc, rc); 720 Assert(pVM->hm.s.vmx.fSupported); 721 715 pVM->hm.s.vmx.fSupported = true; 722 716 LogRel(("HM: HMR3Init: VT-x%s%s%s\n", 723 717 fCaps & SUPVTCAPS_NESTED_PAGING ? " w/ nested paging" : "",
Note:
See TracChangeset
for help on using the changeset viewer.