Changeset 76200 in vbox for trunk/src/VBox/VMM/VMMR3
- Timestamp:
- Dec 13, 2018 9:23:47 AM (6 years ago)
- svn:sync-xref-src-repo-rev:
- 127460
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/CPUM.cpp
r76197 r76200 1236 1236 1237 1237 /** 1238 * Initializes the guest VMX MSRs from guest-CPU features. 1239 * 1240 * @param pVM The cross context VM structure. 1241 */ 1242 static void cpumR3InitGuestVmxMsrs(PVM pVM) 1243 { 1244 PVMCPU pVCpu0 = &pVM->aCpus[0]; 1245 PCCPUMFEATURES pFeatures = &pVM->cpum.s.GuestFeatures; 1246 PVMXMSRS pVmxMsrs = &pVCpu0->cpum.s.Guest.hwvirt.vmx.Msrs; 1247 1248 Assert(pFeatures->fVmx); 1249 RT_ZERO(*pVmxMsrs); 1250 1251 /* Feature control. */ 1252 pVmxMsrs->u64FeatCtrl = MSR_IA32_FEATURE_CONTROL_LOCK | MSR_IA32_FEATURE_CONTROL_VMXON; 1253 1254 /* Basic information. */ 1255 { 1256 uint64_t const u64Basic = RT_BF_MAKE(VMX_BF_BASIC_VMCS_ID, VMX_V_VMCS_REVISION_ID ) 1257 | RT_BF_MAKE(VMX_BF_BASIC_VMCS_SIZE, VMX_V_VMCS_SIZE ) 1258 | RT_BF_MAKE(VMX_BF_BASIC_PHYSADDR_WIDTH, !pFeatures->fLongMode ) 1259 | RT_BF_MAKE(VMX_BF_BASIC_DUAL_MON, 0 ) 1260 | RT_BF_MAKE(VMX_BF_BASIC_VMCS_MEM_TYPE, VMX_BASIC_MEM_TYPE_WB ) 1261 | RT_BF_MAKE(VMX_BF_BASIC_VMCS_INS_OUTS, pFeatures->fVmxInsOutInfo) 1262 | RT_BF_MAKE(VMX_BF_BASIC_TRUE_CTLS, 0 ); 1263 pVmxMsrs->u64Basic = u64Basic; 1264 } 1265 1266 /* Pin-based VM-execution controls. */ 1267 { 1268 uint32_t const fFeatures = (pFeatures->fVmxExtIntExit << VMX_BF_PIN_CTLS_EXT_INT_EXIT_SHIFT ) 1269 | (pFeatures->fVmxNmiExit << VMX_BF_PIN_CTLS_NMI_EXIT_SHIFT ) 1270 | (pFeatures->fVmxVirtNmi << VMX_BF_PIN_CTLS_VIRT_NMI_SHIFT ) 1271 | (pFeatures->fVmxPreemptTimer << VMX_BF_PIN_CTLS_PREEMPT_TIMER_SHIFT) 1272 | (pFeatures->fVmxPostedInt << VMX_BF_PIN_CTLS_POSTED_INT_SHIFT ); 1273 uint32_t const fAllowed0 = VMX_PIN_CTLS_DEFAULT1; 1274 uint32_t const fAllowed1 = fFeatures | VMX_PIN_CTLS_DEFAULT1; 1275 AssertMsg((fAllowed0 & fAllowed1) == fAllowed0, ("fAllowed0=%#RX32 fAllowed1=%#RX32 fFeatures=%#RX32\n", 1276 fAllowed0, fAllowed1, fFeatures)); 1277 pVmxMsrs->PinCtls.u = RT_MAKE_U64(fAllowed0, fAllowed1); 1278 } 1279 1280 /* Processor-based VM-execution controls. */ 1281 { 1282 uint32_t const fFeatures = (pFeatures->fVmxIntWindowExit << VMX_BF_PROC_CTLS_INT_WINDOW_EXIT_SHIFT ) 1283 | (pFeatures->fVmxTscOffsetting << VMX_BF_PROC_CTLS_USE_TSC_OFFSETTING_SHIFT) 1284 | (pFeatures->fVmxHltExit << VMX_BF_PROC_CTLS_HLT_EXIT_SHIFT ) 1285 | (pFeatures->fVmxInvlpgExit << VMX_BF_PROC_CTLS_INVLPG_EXIT_SHIFT ) 1286 | (pFeatures->fVmxMwaitExit << VMX_BF_PROC_CTLS_MWAIT_EXIT_SHIFT ) 1287 | (pFeatures->fVmxRdpmcExit << VMX_BF_PROC_CTLS_RDPMC_EXIT_SHIFT ) 1288 | (pFeatures->fVmxRdtscExit << VMX_BF_PROC_CTLS_RDTSC_EXIT_SHIFT ) 1289 | (pFeatures->fVmxCr3LoadExit << VMX_BF_PROC_CTLS_CR3_LOAD_EXIT_SHIFT ) 1290 | (pFeatures->fVmxCr3StoreExit << VMX_BF_PROC_CTLS_CR3_STORE_EXIT_SHIFT ) 1291 | (pFeatures->fVmxCr8LoadExit << VMX_BF_PROC_CTLS_CR8_LOAD_EXIT_SHIFT ) 1292 | (pFeatures->fVmxCr8StoreExit << VMX_BF_PROC_CTLS_CR8_STORE_EXIT_SHIFT ) 1293 | (pFeatures->fVmxUseTprShadow << VMX_BF_PROC_CTLS_USE_TPR_SHADOW_SHIFT ) 1294 | (pFeatures->fVmxNmiWindowExit << VMX_BF_PROC_CTLS_NMI_WINDOW_EXIT_SHIFT ) 1295 | (pFeatures->fVmxMovDRxExit << VMX_BF_PROC_CTLS_MOV_DR_EXIT_SHIFT ) 1296 | (pFeatures->fVmxUncondIoExit << VMX_BF_PROC_CTLS_UNCOND_IO_EXIT_SHIFT ) 1297 | (pFeatures->fVmxUseIoBitmaps << VMX_BF_PROC_CTLS_USE_IO_BITMAPS_SHIFT ) 1298 | (pFeatures->fVmxMonitorTrapFlag << VMX_BF_PROC_CTLS_MONITOR_TRAP_FLAG_SHIFT ) 1299 | (pFeatures->fVmxUseMsrBitmaps << VMX_BF_PROC_CTLS_USE_MSR_BITMAPS_SHIFT ) 1300 | (pFeatures->fVmxMonitorExit << VMX_BF_PROC_CTLS_MONITOR_EXIT_SHIFT ) 1301 | (pFeatures->fVmxPauseExit << VMX_BF_PROC_CTLS_PAUSE_EXIT_SHIFT ) 1302 | (pFeatures->fVmxSecondaryExecCtls << VMX_BF_PROC_CTLS_USE_SECONDARY_CTLS_SHIFT); 1303 uint32_t const fAllowed0 = VMX_PROC_CTLS_DEFAULT1; 1304 uint32_t const fAllowed1 = fFeatures | VMX_PROC_CTLS_DEFAULT1; 1305 AssertMsg((fAllowed0 & fAllowed1) == fAllowed0, ("fAllowed0=%#RX32 fAllowed1=%#RX32 fFeatures=%#RX32\n", fAllowed0, 1306 fAllowed1, fFeatures)); 1307 pVmxMsrs->ProcCtls.u = RT_MAKE_U64(fAllowed0, fAllowed1); 1308 } 1309 1310 /* Secondary processor-based VM-execution controls. */ 1311 if (pFeatures->fVmxSecondaryExecCtls) 1312 { 1313 uint32_t const fFeatures = (pFeatures->fVmxVirtApicAccess << VMX_BF_PROC_CTLS2_VIRT_APIC_ACCESS_SHIFT ) 1314 | (pFeatures->fVmxEpt << VMX_BF_PROC_CTLS2_EPT_SHIFT ) 1315 | (pFeatures->fVmxDescTableExit << VMX_BF_PROC_CTLS2_DESC_TABLE_EXIT_SHIFT ) 1316 | (pFeatures->fVmxRdtscp << VMX_BF_PROC_CTLS2_RDTSCP_SHIFT ) 1317 | (pFeatures->fVmxVirtX2ApicMode << VMX_BF_PROC_CTLS2_VIRT_X2APIC_MODE_SHIFT ) 1318 | (pFeatures->fVmxVpid << VMX_BF_PROC_CTLS2_VPID_SHIFT ) 1319 | (pFeatures->fVmxWbinvdExit << VMX_BF_PROC_CTLS2_WBINVD_EXIT_SHIFT ) 1320 | (pFeatures->fVmxUnrestrictedGuest << VMX_BF_PROC_CTLS2_UNRESTRICTED_GUEST_SHIFT) 1321 | (pFeatures->fVmxApicRegVirt << VMX_BF_PROC_CTLS2_APIC_REG_VIRT_SHIFT ) 1322 | (pFeatures->fVmxVirtIntDelivery << VMX_BF_PROC_CTLS2_VIRT_INT_DELIVERY_SHIFT ) 1323 | (pFeatures->fVmxPauseLoopExit << VMX_BF_PROC_CTLS2_PAUSE_LOOP_EXIT_SHIFT ) 1324 | (pFeatures->fVmxRdrandExit << VMX_BF_PROC_CTLS2_RDRAND_EXIT_SHIFT ) 1325 | (pFeatures->fVmxInvpcid << VMX_BF_PROC_CTLS2_INVPCID_SHIFT ) 1326 | (pFeatures->fVmxVmFunc << VMX_BF_PROC_CTLS2_VMFUNC_SHIFT ) 1327 | (pFeatures->fVmxVmcsShadowing << VMX_BF_PROC_CTLS2_VMCS_SHADOWING_SHIFT ) 1328 | (pFeatures->fVmxRdseedExit << VMX_BF_PROC_CTLS2_RDSEED_EXIT_SHIFT ) 1329 | (pFeatures->fVmxPml << VMX_BF_PROC_CTLS2_PML_SHIFT ) 1330 | (pFeatures->fVmxEptXcptVe << VMX_BF_PROC_CTLS2_EPT_VE_SHIFT ) 1331 | (pFeatures->fVmxXsavesXrstors << VMX_BF_PROC_CTLS2_XSAVES_XRSTORS_SHIFT ) 1332 | (pFeatures->fVmxUseTscScaling << VMX_BF_PROC_CTLS2_TSC_SCALING_SHIFT ); 1333 uint32_t const fAllowed0 = 0; 1334 uint32_t const fAllowed1 = fFeatures; 1335 pVmxMsrs->ProcCtls2.u = RT_MAKE_U64(fAllowed0, fAllowed1); 1336 } 1337 1338 /* VM-exit controls. */ 1339 { 1340 uint32_t const fFeatures = (pFeatures->fVmxExitSaveDebugCtls << VMX_BF_EXIT_CTLS_SAVE_DEBUG_SHIFT ) 1341 | (pFeatures->fVmxHostAddrSpaceSize << VMX_BF_EXIT_CTLS_HOST_ADDR_SPACE_SIZE_SHIFT) 1342 | (pFeatures->fVmxExitAckExtInt << VMX_BF_EXIT_CTLS_ACK_EXT_INT_SHIFT ) 1343 | (pFeatures->fVmxExitSavePatMsr << VMX_BF_EXIT_CTLS_SAVE_PAT_MSR_SHIFT ) 1344 | (pFeatures->fVmxExitLoadPatMsr << VMX_BF_EXIT_CTLS_LOAD_PAT_MSR_SHIFT ) 1345 | (pFeatures->fVmxExitSaveEferMsr << VMX_BF_EXIT_CTLS_SAVE_EFER_MSR_SHIFT ) 1346 | (pFeatures->fVmxExitLoadEferMsr << VMX_BF_EXIT_CTLS_LOAD_EFER_MSR_SHIFT ) 1347 | (pFeatures->fVmxSavePreemptTimer << VMX_BF_EXIT_CTLS_SAVE_PREEMPT_TIMER_SHIFT ); 1348 /* Set the default1 class bits. See Intel spec. A.4 "VM-exit Controls". */ 1349 uint32_t const fAllowed0 = VMX_EXIT_CTLS_DEFAULT1; 1350 uint32_t const fAllowed1 = fFeatures | VMX_EXIT_CTLS_DEFAULT1; 1351 AssertMsg((fAllowed0 & fAllowed1) == fAllowed0, ("fAllowed0=%#RX32 fAllowed1=%#RX32 fFeatures=%#RX32\n", fAllowed0, 1352 fAllowed1, fFeatures)); 1353 pVmxMsrs->ExitCtls.u = RT_MAKE_U64(fAllowed0, fAllowed1); 1354 } 1355 1356 /* VM-entry controls. */ 1357 { 1358 uint32_t const fFeatures = (pFeatures->fVmxEntryLoadDebugCtls << VMX_BF_ENTRY_CTLS_LOAD_DEBUG_SHIFT ) 1359 | (pFeatures->fVmxIa32eModeGuest << VMX_BF_ENTRY_CTLS_IA32E_MODE_GUEST_SHIFT) 1360 | (pFeatures->fVmxEntryLoadEferMsr << VMX_BF_ENTRY_CTLS_LOAD_EFER_MSR_SHIFT ) 1361 | (pFeatures->fVmxEntryLoadPatMsr << VMX_BF_ENTRY_CTLS_LOAD_PAT_MSR_SHIFT ); 1362 uint32_t const fAllowed0 = VMX_ENTRY_CTLS_DEFAULT1; 1363 uint32_t const fAllowed1 = fFeatures | VMX_ENTRY_CTLS_DEFAULT1; 1364 AssertMsg((fAllowed0 & fAllowed1) == fAllowed0, ("fAllowed0=%#RX32 fAllowed0=%#RX32 fFeatures=%#RX32\n", fAllowed0, 1365 fAllowed1, fFeatures)); 1366 pVmxMsrs->EntryCtls.u = RT_MAKE_U64(fAllowed0, fAllowed1); 1367 } 1368 1369 /* Miscellaneous data. */ 1370 { 1371 uint64_t uHostMsr = 0; 1372 HMVmxGetHostMsr(pVM, MSR_IA32_VMX_MISC, &uHostMsr); 1373 uint8_t const cMaxMsrs = RT_MIN(RT_BF_GET(uHostMsr, VMX_BF_MISC_MAX_MSRS), VMX_V_AUTOMSR_COUNT_MAX); 1374 uint8_t const fActivityState = RT_BF_GET(uHostMsr, VMX_BF_MISC_ACTIVITY_STATES) & VMX_V_GUEST_ACTIVITY_STATE_MASK; 1375 pVmxMsrs->u64Misc = RT_BF_MAKE(VMX_BF_MISC_PREEMPT_TIMER_TSC, VMX_V_PREEMPT_TIMER_SHIFT ) 1376 | RT_BF_MAKE(VMX_BF_MISC_EXIT_SAVE_EFER_LMA, pFeatures->fVmxExitSaveEferLma ) 1377 | RT_BF_MAKE(VMX_BF_MISC_ACTIVITY_STATES, fActivityState ) 1378 | RT_BF_MAKE(VMX_BF_MISC_INTEL_PT, pFeatures->fVmxIntelPt ) 1379 | RT_BF_MAKE(VMX_BF_MISC_SMM_READ_SMBASE_MSR, 0 ) 1380 | RT_BF_MAKE(VMX_BF_MISC_CR3_TARGET, VMX_V_CR3_TARGET_COUNT ) 1381 | RT_BF_MAKE(VMX_BF_MISC_MAX_MSRS, cMaxMsrs ) 1382 | RT_BF_MAKE(VMX_BF_MISC_VMXOFF_BLOCK_SMI, 0 ) 1383 | RT_BF_MAKE(VMX_BF_MISC_VMWRITE_ALL, pFeatures->fVmxVmwriteAll ) 1384 | RT_BF_MAKE(VMX_BF_MISC_ENTRY_INJECT_SOFT_INT, pFeatures->fVmxEntryInjectSoftInt) 1385 | RT_BF_MAKE(VMX_BF_MISC_MSEG_ID, VMX_V_MSEG_REV_ID ); 1386 } 1387 1388 /* CR0 Fixed-0. */ 1389 pVmxMsrs->u64Cr0Fixed0 = pFeatures->fVmxUnrestrictedGuest ? VMX_V_CR0_FIXED0_UX: VMX_V_CR0_FIXED0; 1390 1391 /* CR0 Fixed-1. */ 1392 { 1393 uint64_t uHostMsr = 0; 1394 HMVmxGetHostMsr(pVM, MSR_IA32_VMX_CR0_FIXED1, &uHostMsr); 1395 pVmxMsrs->u64Cr0Fixed1 = uHostMsr | VMX_V_CR0_FIXED0; /* Make sure the CR0 MB1 bits are not clear. */ 1396 } 1397 1398 /* CR4 Fixed-0. */ 1399 pVmxMsrs->u64Cr4Fixed0 = VMX_V_CR4_FIXED0; 1400 1401 /* CR4 Fixed-1. */ 1402 { 1403 uint64_t uHostMsr = 0; 1404 HMVmxGetHostMsr(pVM, MSR_IA32_VMX_CR4_FIXED1, &uHostMsr); 1405 pVmxMsrs->u64Cr4Fixed1 = uHostMsr | VMX_V_CR4_FIXED0; /* Make sure the CR4 MB1 bits are not clear. */ 1406 } 1407 1408 /* VMCS Enumeration. */ 1409 pVmxMsrs->u64VmcsEnum = VMX_V_VMCS_MAX_INDEX << VMX_BF_VMCS_ENUM_HIGHEST_IDX_SHIFT; 1410 1411 /* VM Functions. */ 1412 if (pFeatures->fVmxVmFunc) 1413 pVmxMsrs->u64VmFunc = RT_BF_MAKE(VMX_BF_VMFUNC_EPTP_SWITCHING, 1); 1414 1415 /* 1416 * We don't support the following MSRs yet: 1417 * - True Pin-based VM-execution controls. 1418 * - True Processor-based VM-execution controls. 1419 * - True VM-entry VM-execution controls. 1420 * - True VM-exit VM-execution controls. 1421 * - EPT/VPID capabilities. 1422 */ 1423 1424 /* 1425 * Copy the MSRs values initialized in VCPU 0 to all other VCPUs. 1426 */ 1427 for (VMCPUID idCpu = 1; idCpu < pVM->cCpus; idCpu++) 1428 { 1429 PVMCPU pVCpu = &pVM->aCpus[idCpu]; 1430 Assert(pVCpu); 1431 memcpy(&pVCpu->cpum.s.Guest.hwvirt.vmx.Msrs, pVmxMsrs, sizeof(*pVmxMsrs)); 1432 } 1433 } 1434 1435 1436 /** 1238 1437 * Explode VMX features from the provided MSRs. 1239 1438 * … … 1245 1444 Assert(pVmxMsrs); 1246 1445 Assert(pFeatures); 1446 Assert(pFeatures->fVmx); 1247 1447 1248 1448 /* Basic information. */ … … 1313 1513 } 1314 1514 1315 /* VM-entry controls. */1316 {1317 uint32_t const fEntryCtls = pVmxMsrs->EntryCtls.n.allowed1;1318 pFeatures->fVmxEntryLoadDebugCtls = RT_BOOL(fEntryCtls & VMX_ENTRY_CTLS_LOAD_DEBUG);1319 pFeatures->fVmxIa32eModeGuest = RT_BOOL(fEntryCtls & VMX_ENTRY_CTLS_IA32E_MODE_GUEST);1320 pFeatures->fVmxEntryLoadEferMsr = RT_BOOL(fEntryCtls & VMX_ENTRY_CTLS_LOAD_EFER_MSR);1321 pFeatures->fVmxEntryLoadPatMsr = RT_BOOL(fEntryCtls & VMX_ENTRY_CTLS_LOAD_PAT_MSR);1322 }1323 1324 1515 /* VM-exit controls. */ 1325 1516 { … … 1333 1524 pFeatures->fVmxExitLoadEferMsr = RT_BOOL(fExitCtls & VMX_EXIT_CTLS_LOAD_EFER_MSR); 1334 1525 pFeatures->fVmxSavePreemptTimer = RT_BOOL(fExitCtls & VMX_EXIT_CTLS_SAVE_PREEMPT_TIMER); 1526 } 1527 1528 /* VM-entry controls. */ 1529 { 1530 uint32_t const fEntryCtls = pVmxMsrs->EntryCtls.n.allowed1; 1531 pFeatures->fVmxEntryLoadDebugCtls = RT_BOOL(fEntryCtls & VMX_ENTRY_CTLS_LOAD_DEBUG); 1532 pFeatures->fVmxIa32eModeGuest = RT_BOOL(fEntryCtls & VMX_ENTRY_CTLS_IA32E_MODE_GUEST); 1533 pFeatures->fVmxEntryLoadEferMsr = RT_BOOL(fEntryCtls & VMX_ENTRY_CTLS_LOAD_EFER_MSR); 1534 pFeatures->fVmxEntryLoadPatMsr = RT_BOOL(fEntryCtls & VMX_ENTRY_CTLS_LOAD_PAT_MSR); 1335 1535 } 1336 1536 … … 1536 1736 Assert(!pGuestFeat->fVmxUseTscScaling); 1537 1737 } 1738 1739 /* 1740 * Finally initialize the VMX guest MSRs after merging the guest features. 1741 */ 1742 cpumR3InitGuestVmxMsrs(pVM); 1538 1743 } 1539 1744
Note:
See TracChangeset
for help on using the changeset viewer.