Changeset 107854 in vbox for trunk/src/VBox/VMM/VMMR3
- Timestamp:
- Jan 18, 2025 11:59:26 PM (4 months ago)
- svn:sync-xref-src-repo-rev:
- 167053
- Location:
- trunk/src/VBox/VMM/VMMR3
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/CPUMR3CpuId.cpp
r107749 r107854 132 132 * insert. 133 133 */ 134 static int cpumR3CpuIdInsert(PVM pVM, PCPUMCPUIDLEAF *ppaLeaves, uint32_t *pcLeaves, PC PUMCPUIDLEAF pNewLeaf)134 static int cpumR3CpuIdInsert(PVM pVM, PCPUMCPUIDLEAF *ppaLeaves, uint32_t *pcLeaves, PCCPUMCPUIDLEAF pNewLeaf) 135 135 { 136 136 /* … … 1040 1040 bool fForceVme; 1041 1041 bool fNestedHWVirt; 1042 bool fSpecCtrl; 1042 1043 1043 1044 CPUMISAEXTCFG enmCmpXchg16b; … … 2393 2394 * currently not doing the apic id assignments in a compatible manner. 2394 2395 */ 2396 bool fAmdGstSupIbpb = false; /* Used below. */ 2395 2397 uSubLeaf = 0; 2396 2398 while ((pCurLeaf = cpumR3CpuIdGetExactLeaf(pCpum, UINT32_C(0x80000008), uSubLeaf)) != NULL) … … 2401 2403 { 2402 2404 /* Expose XSaveErPtr aka RstrFpErrPtrs to guest. */ 2403 pCurLeaf->uEbx &= X86_CPUID_AMD_EFEID_EBX_XSAVE_ER_PTR; /* reserved - [12] == IBPB */ 2405 pCurLeaf->uEbx &= 0 2406 //| X86_CPUID_AMD_EFEID_EBX_CLZERO 2407 //| X86_CPUID_AMD_EFEID_EBX_IRPERF 2408 //| X86_CPUID_AMD_EFEID_EBX_XSAVE_ER_PTR 2409 //| X86_CPUID_AMD_EFEID_EBX_INVLPGB 2410 //| X86_CPUID_AMD_EFEID_EBX_RDPRU 2411 //| X86_CPUID_AMD_EFEID_EBX_BE 2412 //| X86_CPUID_AMD_EFEID_EBX_MCOMMIT 2413 | (pConfig->fSpecCtrl || PASSTHRU_FEATURE(pConfig->enmFlushCmdMsr, pHstFeat->fFlushCmd, true) 2414 ? X86_CPUID_AMD_EFEID_EBX_IBPB : 0) 2415 //| X86_CPUID_AMD_EFEID_EBX_INT_WBINVD 2416 | (pConfig->fSpecCtrl ? X86_CPUID_AMD_EFEID_EBX_IBRS : 0) 2417 | (pConfig->fSpecCtrl ? X86_CPUID_AMD_EFEID_EBX_STIBP : 0) 2418 | (pConfig->fSpecCtrl ? X86_CPUID_AMD_EFEID_EBX_IBRS_ALWAYS_ON : 0) 2419 | (pConfig->fSpecCtrl ? X86_CPUID_AMD_EFEID_EBX_STIBP_ALWAYS_ON : 0) 2420 | (pConfig->fSpecCtrl ? X86_CPUID_AMD_EFEID_EBX_IBRS_PREFERRED : 0) 2421 | (pConfig->fSpecCtrl ? X86_CPUID_AMD_EFEID_EBX_IBRS_SAME_MODE : 0) 2422 //| X86_CPUID_AMD_EFEID_EBX_NO_EFER_LMSLE 2423 //| X86_CPUID_AMD_EFEID_EBX_INVLPGB_NESTED_PAGES 2424 | (pConfig->fSpecCtrl ? X86_CPUID_AMD_EFEID_EBX_SPEC_CTRL_SSBD : 0) 2425 /// @todo | X86_CPUID_AMD_EFEID_EBX_VIRT_SPEC_CTRL_SSBD 2426 | X86_CPUID_AMD_EFEID_EBX_SSBD_NOT_REQUIRED 2427 //| X86_CPUID_AMD_EFEID_EBX_CPPC 2428 | (pConfig->fSpecCtrl ? X86_CPUID_AMD_EFEID_EBX_PSFD : 0) 2429 | X86_CPUID_AMD_EFEID_EBX_BTC_NO 2430 | (pConfig->fSpecCtrl ? X86_CPUID_AMD_EFEID_EBX_IBPB_RET : 0); 2431 2432 PORTABLE_DISABLE_FEATURE_BIT_CFG(3, pCurLeaf->uEbx, IBPB, X86_CPUID_AMD_EFEID_EBX_IBPB, pConfig->enmFlushCmdMsr); 2433 2434 /* Sharing this forced setting with intel would maybe confuse guests... */ 2435 if (pConfig->enmFlushCmdMsr == CPUMISAEXTCFG_ENABLED_ALWAYS) 2436 pCurLeaf->uEbx |= X86_CPUID_AMD_EFEID_EBX_IBPB; 2437 2438 fAmdGstSupIbpb = RT_BOOL(pCurLeaf->uEbx & X86_CPUID_AMD_EFEID_EBX_IBPB); 2404 2439 } 2405 2440 else … … 2551 2586 } 2552 2587 2553 /* Cpuid 0x8000001f...0x8ffffffd: Unknown. 2588 /* Cpuid 0x80000020: Platform Quality of Service (PQOS), may have subleaves. 2589 * For now we just zero it. */ 2590 pCurLeaf = cpumR3CpuIdGetExactLeaf(pCpum, UINT32_C(0x80000020), 0); 2591 if (pCurLeaf) 2592 { 2593 pCurLeaf = cpumR3CpuIdMakeSingleLeaf(pCpum, pCurLeaf); 2594 cpumR3CpuIdZeroLeaf(pCpum, UINT32_C(0x80000020)); 2595 } 2596 2597 /* Cpuid 0x80000021: Extended Feature 2 (Zen3+?). 2598 * 2599 */ 2600 pCurLeaf = cpumR3CpuIdGetExactLeaf(pCpum, UINT32_C(0x80000021), 0); 2601 if (pCurLeaf) 2602 { 2603 /** @todo sanitize these bits! */ 2604 pCurLeaf->uEax = 0; 2605 pCurLeaf->uEbx = 0; 2606 pCurLeaf->uEcx = 0; 2607 pCurLeaf->uEdx = 0; 2608 } 2609 /* Linux expects us as a hypervisor to insert this leaf for Zen 1 & 2 CPUs 2610 iff IBPB is available to the guest. This is also documented by AMD in 2611 "TECHNICAL UPDATE REGARDING SPECULATIVE RETURN STACK OVERFLOW" rev 2.0 2612 dated 2024-02-00. */ 2613 else if ( fAmdGstSupIbpb 2614 && ( pCpum->GuestFeatures.enmCpuVendor == CPUMCPUVENDOR_AMD 2615 || pCpum->GuestFeatures.enmCpuVendor == CPUMCPUVENDOR_HYGON) 2616 && (pExtFeatureLeaf = cpumR3CpuIdGetExactLeaf(pCpum, UINT32_C(0x80000001), 0)) != NULL 2617 && RTX86GetCpuFamily(pExtFeatureLeaf->uEax) == 0x17) 2618 { 2619 static CPUMCPUIDLEAF const s_NewLeaf = 2620 { 2621 /* .uLeaf =*/ UINT32_C(0x80000021), 2622 /* .uSubLeaf = */ 0, 2623 /* .fSubLeafMask = */ 0, 2624 /* .uEax = */ X86_CPUID_AMD_21_EAX_IBPB_BRTYPE, 2625 /* .uEbx = */ 0, 2626 /* .uEcx = */ 0, 2627 /* .uEdx = */ 0, 2628 /* .fFlags = */ 0, 2629 }; 2630 int const rc2 = cpumR3CpuIdInsert(NULL, &pCpum->GuestInfo.paCpuIdLeavesR3, &pCpum->GuestInfo.cCpuIdLeaves, &s_NewLeaf); 2631 AssertRC(rc2); 2632 pCurLeaf = cpumR3CpuIdGetExactLeaf(pCpum, UINT32_C(0x80000000), 0); 2633 if (pCurLeaf && pCurLeaf->uEax < UINT32_C(0x80000021)) 2634 pCurLeaf->uEax = UINT32_C(0x80000021); 2635 } 2636 2637 /* Cpuid 0x80000022...0x8ffffffd: Unknown. 2554 2638 * We don't know these and what they mean, so remove them. */ 2555 2639 cpumR3CpuIdRemoveRange(pCpum->GuestInfo.paCpuIdLeavesR3, &pCpum->GuestInfo.cCpuIdLeaves, 2556 UINT32_C(0x800000 1f), UINT32_C(0x8ffffffd));2640 UINT32_C(0x80000022), UINT32_C(0x8ffffffd)); 2557 2641 2558 2642 /* Cpuid 0x8ffffffe: Mystery AMD K6 leaf. … … 2818 2902 * leaf are removed. The default is set to what we're able to sanitize. 2819 2903 */ 2820 rc = CFGMR3QueryU32Def(pCpumCfg, "MaxExtLeaf", &pConfig->uMaxExtLeaf, UINT32_C(0x800000 1e));2904 rc = CFGMR3QueryU32Def(pCpumCfg, "MaxExtLeaf", &pConfig->uMaxExtLeaf, UINT32_C(0x80000021)); 2821 2905 AssertLogRelRCReturn(rc, rc); 2822 2906 … … 2828 2912 rc = CFGMR3QueryU32Def(pCpumCfg, "MaxCentaurLeaf", &pConfig->uMaxCentaurLeaf, UINT32_C(0xc0000004)); 2829 2913 AssertLogRelRCReturn(rc, rc); 2914 2915 /** @cfgm{/CPUM/SpecCtrl, bool, false} 2916 * Enables passing thru IA32_SPEC_CTRL and associated CPU bugfixes. 2917 */ 2918 rc = CFGMR3QueryBoolDef(pCpumCfg, "SpecCtrl", &pConfig->fSpecCtrl, false); 2919 AssertRCReturn(rc, rc); 2830 2920 2831 2921 #ifdef RT_ARCH_AMD64 /** @todo next VT-x/AMD-V on non-AMD64 hosts */ … … 3533 3623 */ 3534 3624 if (RT_SUCCESS(rc)) 3535 rc = cpumR3MsrReconcileWithCpuId(pVM );3625 rc = cpumR3MsrReconcileWithCpuId(pVM, false, false); 3536 3626 /* 3537 3627 * MSR fudging. … … 3599 3689 3600 3690 /* Check if speculation control is enabled. */ 3601 rc = CFGMR3QueryBoolDef(pCpumCfg, "SpecCtrl", &fEnable, false); 3602 AssertRCReturn(rc, rc); 3603 if (fEnable) 3691 if (Config.fSpecCtrl) 3604 3692 CPUMR3SetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_SPEC_CTRL); 3605 3693 else … … 3638 3726 if (pLeaf) 3639 3727 { 3640 pLeaf->uEbx |= X86_CPUID_AMD_EFEID_EBX_ NO_SSBD_REQUIRED;3728 pLeaf->uEbx |= X86_CPUID_AMD_EFEID_EBX_SSBD_NOT_REQUIRED; 3641 3729 LogRel(("CPUM: Set SSBD not required flag for AMD to work around some buggy Linux kernels!\n")); 3642 3730 } … … 3956 4044 */ 3957 4045 case CPUMCPUIDFEATURE_SPEC_CTRL: 4046 { 4047 AssertReturnVoid(!pVM->cpum.s.GuestFeatures.fSpeculationControl); /* should only be done once! */ 4048 4049 #ifdef RT_ARCH_AMD64 4050 if (!pVM->cpum.s.HostFeatures.s.fIbpb && !pVM->cpum.s.HostFeatures.s.fIbrs) 4051 { 4052 LogRel(("CPUM: WARNING! Can't turn on Speculation Control when the host doesn't support it!\n")); 4053 return; 4054 } 4055 #endif 4056 bool fForceSpecCtrl = false; 4057 bool fForceFlushCmd = false; 4058 4059 /* 4060 * Intel spread feature info around a bit... 4061 */ 3958 4062 if (pVM->cpum.s.GuestFeatures.enmCpuVendor == CPUMCPUVENDOR_INTEL) 3959 4063 { 3960 4064 pLeaf = cpumR3CpuIdGetExactLeaf(&pVM->cpum.s, UINT32_C(0x00000007), 0); 3961 #ifdef RT_ARCH_AMD64 3962 if ( !pLeaf 3963 || !(pVM->cpum.s.HostFeatures.s.fIbpb || pVM->cpum.s.HostFeatures.s.fIbrs)) 4065 if (!pLeaf) 3964 4066 { 3965 LogRel(("CPUM: WARNING! Can't turn on Speculation Control when the host doesn't support it!\n"));4067 LogRel(("CPUM: WARNING! Can't turn on Speculation Control on Intel CPUs without leaf 0x00000007!\n")); 3966 4068 return; 3967 4069 } 3968 #else 3969 if (!pLeaf) 3970 { 3971 LogRel(("CPUM: WARNING! Can't turn on Speculation Control without leaf 0x00000007!\n")); 3972 return; 3973 } 3974 #endif 3975 3976 /* The feature can be enabled. Let's see what we can actually do. */ 3977 pVM->cpum.s.GuestFeatures.fSpeculationControl = 1; 4070 4071 /* Okay, the feature can be enabled. Let's see what we can actually do. */ 3978 4072 3979 4073 #ifdef RT_ARCH_AMD64 … … 3985 4079 pLeaf->uEdx |= X86_CPUID_STEXT_FEATURE_EDX_IBRS_IBPB; 3986 4080 pVM->cpum.s.GuestFeatures.fIbrs = 1; 4081 pVM->cpum.s.GuestFeatures.fIbpb = 1; 3987 4082 #ifdef RT_ARCH_AMD64 3988 4083 if (pVM->cpum.s.HostFeatures.s.fStibp) … … 4043 4138 pVM->cpum.s.GuestFeatures.fBhiCtrl = 1; 4044 4139 } 4140 fForceSpecCtrl = true; 4045 4141 } 4046 4047 /* Make sure we have the speculation control MSR... */ 4048 pMsrRange = cpumLookupMsrRange(pVM, MSR_IA32_SPEC_CTRL); 4049 if (!pMsrRange) 4050 { 4051 static CPUMMSRRANGE const s_SpecCtrl = 4052 { 4053 /*.uFirst =*/ MSR_IA32_SPEC_CTRL, /*.uLast =*/ MSR_IA32_SPEC_CTRL, 4054 /*.enmRdFn =*/ kCpumMsrRdFn_Ia32SpecCtrl, /*.enmWrFn =*/ kCpumMsrWrFn_Ia32SpecCtrl, 4055 /*.offCpumCpu =*/ UINT16_MAX, /*.fReserved =*/ 0, /*.uValue =*/ 0, /*.fWrIgnMask =*/ 0, /*.fWrGpMask =*/ 0, 4056 /*.szName = */ "IA32_SPEC_CTRL" 4057 }; 4058 int rc = CPUMR3MsrRangesInsert(pVM, &s_SpecCtrl); 4059 AssertLogRelRC(rc); 4060 } 4061 4062 /* ... and the predictor command MSR. */ 4063 pMsrRange = cpumLookupMsrRange(pVM, MSR_IA32_PRED_CMD); 4064 if (!pMsrRange) 4065 { 4066 /** @todo incorrect fWrGpMask. */ 4067 static CPUMMSRRANGE const s_SpecCtrl = 4068 { 4069 /*.uFirst =*/ MSR_IA32_PRED_CMD, /*.uLast =*/ MSR_IA32_PRED_CMD, 4070 /*.enmRdFn =*/ kCpumMsrRdFn_WriteOnly, /*.enmWrFn =*/ kCpumMsrWrFn_Ia32PredCmd, 4071 /*.offCpumCpu =*/ UINT16_MAX, /*.fReserved =*/ 0, /*.uValue =*/ 0, /*.fWrIgnMask =*/ 0, /*.fWrGpMask =*/ 0, 4072 /*.szName = */ "IA32_PRED_CMD" 4073 }; 4074 int rc = CPUMR3MsrRangesInsert(pVM, &s_SpecCtrl); 4075 AssertLogRelRC(rc); 4076 } 4077 4142 } 4143 4144 #ifdef RT_ARCH_AMD64 4145 if (pVM->cpum.s.HostFeatures.s.fFlushCmd) 4146 #endif 4147 { 4148 pLeaf->uEdx |= X86_CPUID_STEXT_FEATURE_EDX_FLUSH_CMD; 4149 pVM->cpum.s.GuestFeatures.fFlushCmd = 1; 4150 fForceFlushCmd = true; 4078 4151 } 4079 4152 … … 4082 4155 #endif 4083 4156 { 4084 /* Install the architectural capabilities MSR. */ 4085 pMsrRange = cpumLookupMsrRange(pVM, MSR_IA32_ARCH_CAPABILITIES); 4086 if (!pMsrRange) 4087 { 4088 static CPUMMSRRANGE const s_ArchCaps = 4089 { 4090 /*.uFirst =*/ MSR_IA32_ARCH_CAPABILITIES, /*.uLast =*/ MSR_IA32_ARCH_CAPABILITIES, 4091 /*.enmRdFn =*/ kCpumMsrRdFn_Ia32ArchCapabilities, /*.enmWrFn =*/ kCpumMsrWrFn_ReadOnly, 4092 /*.offCpumCpu =*/ UINT16_MAX, /*.fReserved =*/ 0, /*.uValue =*/ 0, /*.fWrIgnMask =*/ 0, /*.fWrGpMask =*/ UINT64_MAX, 4093 /*.szName = */ "IA32_ARCH_CAPABILITIES" 4094 }; 4095 int rc = CPUMR3MsrRangesInsert(pVM, &s_ArchCaps); 4096 AssertLogRelRC(rc); 4097 } 4157 pLeaf->uEdx |= X86_CPUID_STEXT_FEATURE_EDX_ARCHCAP; 4158 pVM->cpum.s.GuestFeatures.fArchCap = 1; 4098 4159 4099 4160 /* Advertise IBRS_ALL if present at this point... */ … … 4103 4164 VMCC_FOR_EACH_VMCPU_STMT(pVM, pVCpu->cpum.s.GuestMsrs.msr.ArchCaps |= MSR_IA32_ARCH_CAP_F_IBRS_ALL); 4104 4165 } 4105 4106 LogRel(("CPUM: SetGuestCpuIdFeature: Enabled Speculation Control.\n")); 4166 cpumCpuIdExplodeFeaturesX86SetSummaryBits(&pVM->cpum.s.GuestFeatures); 4107 4167 } 4168 /* 4169 * AMD does things in a different (better) way. No MSR with info, 4170 * it's all in various CPUID leaves. 4171 */ 4108 4172 else if ( pVM->cpum.s.GuestFeatures.enmCpuVendor == CPUMCPUVENDOR_AMD 4109 4173 || pVM->cpum.s.GuestFeatures.enmCpuVendor == CPUMCPUVENDOR_HYGON) 4110 4174 { 4111 4175 /* The precise details of AMD's implementation are not yet clear. */ 4176 pLeaf = cpumR3CpuIdGetExactLeaf(&pVM->cpum.s, UINT32_C(0x80000008), 0); 4177 if (!pLeaf) 4178 { 4179 LogRel(("CPUM: WARNING! Can't turn on Speculation Control on AMD CPUs without leaf 0x80000008!\n")); 4180 return; 4181 } 4182 4183 /* We passthru all the host cpuid bits on AMD, see cpumR3CpuIdSanitize, 4184 and there is no code to clear/unset the feature. So, little to do. 4185 The only thing we could consider here, is to re-enable stuff 4186 suppressed for portability reasons. */ 4112 4187 } 4188 else 4189 break; 4190 4191 LogRel(("CPUM: SetGuestCpuIdFeature: Enabled Speculation Control.\n")); 4192 pVM->cpum.s.GuestFeatures.fSpeculationControl = 1; 4193 cpumR3MsrReconcileWithCpuId(pVM, fForceFlushCmd, fForceSpecCtrl); 4113 4194 break; 4195 } 4114 4196 4115 4197 default: … … 5614 5696 DBGFREGSUBFIELD_RO("EferLmsleUnsupported\0" "EFER.LMSLE is unsupported", 20, 1, 0), 5615 5697 DBGFREGSUBFIELD_RO("INVLPGBnestedPages\0" "INVLPGB for nested translation", 21, 1, 0), 5698 DBGFREGSUBFIELD_RO("PPIN\0" "Protected processor inventory number", 23, 1, 0), 5616 5699 DBGFREGSUBFIELD_RO("SSBD\0" "Speculative Store Bypass Disable", 24, 1, 0), 5617 5700 DBGFREGSUBFIELD_RO("SsbdVirtSpecCtrl\0" "Use VIRT_SPEC_CTL for SSBD", 25, 1, 0), … … 5708 5791 5709 5792 static void cpumR3CpuIdInfoVerboseCompareListU32(PCDBGFINFOHLP pHlp, uint32_t uVal1, uint32_t uVal2, PCDBGFREGSUBFIELD pDesc, 5710 uint32_t cchWidth)5793 const char *pszLeadIn, uint32_t cchWidth) 5711 5794 { 5795 if (pszLeadIn) 5796 pHlp->pfnPrintf(pHlp, 5797 "%s\n" 5798 " %-*s= guest (host)\n", 5799 pszLeadIn, 5800 cchWidth, "Mnemonic - Description"); 5801 5712 5802 uint32_t uCombined = uVal1 | uVal2; 5713 5803 for (uint32_t iBit = 0; iBit < 32; iBit++) … … 5787 5877 ASMCpuIdExSlow(1, 0, 0, 0, &Host.uEax, &Host.uEbx, &Host.uEcx, &Host.uEdx); 5788 5878 #endif 5789 pHlp->pfnPrintf(pHlp, "Features\n"); 5790 pHlp->pfnPrintf(pHlp, " Mnemonic - Description = guest (host)\n"); 5791 cpumR3CpuIdInfoVerboseCompareListU32(pHlp, pCurLeaf->uEdx, Host.uEdx, g_aLeaf1EdxSubFields, 56); 5792 cpumR3CpuIdInfoVerboseCompareListU32(pHlp, pCurLeaf->uEcx, Host.uEcx, g_aLeaf1EcxSubFields, 56); 5879 cpumR3CpuIdInfoVerboseCompareListU32(pHlp, pCurLeaf->uEdx, Host.uEdx, g_aLeaf1EdxSubFields, "Features", 56); 5880 cpumR3CpuIdInfoVerboseCompareListU32(pHlp, pCurLeaf->uEcx, Host.uEcx, g_aLeaf1EcxSubFields, NULL, 56); 5793 5881 } 5794 5882 else … … 5826 5914 if (fVerbose) 5827 5915 { 5828 pHlp->pfnPrintf(pHlp, " Sub-leaf 0\n"); 5829 pHlp->pfnPrintf(pHlp, " Mnemonic - Description = guest (host)\n"); 5830 cpumR3CpuIdInfoVerboseCompareListU32(pHlp, pCurLeaf->uEbx, Host.uEbx, g_aLeaf7Sub0EbxSubFields, 56); 5831 cpumR3CpuIdInfoVerboseCompareListU32(pHlp, pCurLeaf->uEcx, Host.uEcx, g_aLeaf7Sub0EcxSubFields, 56); 5916 cpumR3CpuIdInfoVerboseCompareListU32(pHlp, pCurLeaf->uEbx, Host.uEbx, g_aLeaf7Sub0EbxSubFields, "Sub-leaf 0", 56); 5917 cpumR3CpuIdInfoVerboseCompareListU32(pHlp, pCurLeaf->uEcx, Host.uEcx, g_aLeaf7Sub0EcxSubFields, NULL, 56); 5832 5918 if (pCurLeaf->uEdx || Host.uEdx) 5833 cpumR3CpuIdInfoVerboseCompareListU32(pHlp, pCurLeaf->uEdx, Host.uEdx, g_aLeaf7Sub0EdxSubFields, 56);5919 cpumR3CpuIdInfoVerboseCompareListU32(pHlp, pCurLeaf->uEdx, Host.uEdx, g_aLeaf7Sub0EdxSubFields, NULL, 56); 5834 5920 } 5835 5921 else … … 5850 5936 pHlp->pfnPrintf(pHlp, " Mnemonic - Description = guest (host)\n"); 5851 5937 if (pCurLeaf->uEbx || Host.uEbx) 5852 cpumR3CpuIdInfoVerboseCompareListU32(pHlp, pCurLeaf->uEbx, Host.uEbx, g_aLeaf7Sub2EbxSubFields, 56);5938 cpumR3CpuIdInfoVerboseCompareListU32(pHlp, pCurLeaf->uEbx, Host.uEbx, g_aLeaf7Sub2EbxSubFields, NULL, 56); 5853 5939 if (pCurLeaf->uEcx || Host.uEcx) 5854 cpumR3CpuIdInfoVerboseCompareListU32(pHlp, pCurLeaf->uEcx, Host.uEcx, g_aLeaf7Sub2EcxSubFields, 56);5855 cpumR3CpuIdInfoVerboseCompareListU32(pHlp, pCurLeaf->uEdx, Host.uEdx, g_aLeaf7Sub2EdxSubFields, 56);5940 cpumR3CpuIdInfoVerboseCompareListU32(pHlp, pCurLeaf->uEcx, Host.uEcx, g_aLeaf7Sub2EcxSubFields, NULL, 56); 5941 cpumR3CpuIdInfoVerboseCompareListU32(pHlp, pCurLeaf->uEdx, Host.uEdx, g_aLeaf7Sub2EdxSubFields, NULL, 56); 5856 5942 } 5857 5943 else … … 6240 6326 ASMCpuIdExSlow(0x80000001, 0, 0, 0, &Host.uEax, &Host.uEbx, &Host.uEcx, &Host.uEdx); 6241 6327 #endif 6242 pHlp->pfnPrintf(pHlp, "Ext Features\n"); 6243 pHlp->pfnPrintf(pHlp, " Mnemonic - Description = guest (host)\n"); 6244 cpumR3CpuIdInfoVerboseCompareListU32(pHlp, pCurLeaf->uEdx, Host.uEdx, g_aExtLeaf1EdxSubFields, 56); 6245 cpumR3CpuIdInfoVerboseCompareListU32(pHlp, pCurLeaf->uEcx, Host.uEcx, g_aExtLeaf1EcxSubFields, 56); 6328 cpumR3CpuIdInfoVerboseCompareListU32(pHlp, pCurLeaf->uEdx, Host.uEdx, g_aExtLeaf1EdxSubFields, "Ext Features", 56); 6329 cpumR3CpuIdInfoVerboseCompareListU32(pHlp, pCurLeaf->uEcx, Host.uEcx, g_aExtLeaf1EcxSubFields, NULL, 56); 6246 6330 if (Host.uEcx & X86_CPUID_AMD_FEATURE_ECX_SVM) 6247 6331 { 6248 pHlp->pfnPrintf(pHlp, "SVM Feature Identification (leaf A):\n");6249 6332 #if defined(RT_ARCH_X86) || defined(RT_ARCH_AMD64) 6250 6333 ASMCpuIdExSlow(0x8000000a, 0, 0, 0, &Host.uEax, &Host.uEbx, &Host.uEcx, &Host.uEdx); … … 6252 6335 pCurLeaf = cpumCpuIdGetLeafInt(paLeaves, cLeaves, UINT32_C(0x8000000a), 0); 6253 6336 uint32_t const uGstEdx = pCurLeaf ? pCurLeaf->uEdx : 0; 6254 cpumR3CpuIdInfoVerboseCompareListU32(pHlp, uGstEdx, Host.uEdx, g_aExtLeafAEdxSubFields, 56); 6337 cpumR3CpuIdInfoVerboseCompareListU32(pHlp, uGstEdx, Host.uEdx, g_aExtLeafAEdxSubFields, 6338 "SVM Feature Identification (leaf A)", 56); 6255 6339 } 6256 6340 } … … 6369 6453 cpumR3CpuIdInfoMnemonicListU32(pHlp, pCurLeaf->uEdx, g_aExtLeaf7EdxSubFields, "APM Features EDX:", 34); 6370 6454 else 6371 cpumR3CpuIdInfoVerboseCompareListU32(pHlp, pCurLeaf->uEdx, Host.uEdx, g_aExtLeaf7EdxSubFields, 56); 6455 cpumR3CpuIdInfoVerboseCompareListU32(pHlp, pCurLeaf->uEdx, Host.uEdx, g_aExtLeaf7EdxSubFields, 6456 "APM Features EDX", 56); 6372 6457 } 6373 6458 } … … 6384 6469 cpumR3CpuIdInfoMnemonicListU32(pHlp, pCurLeaf->uEbx, g_aExtLeaf8EbxSubFields, "Ext Features ext IDs EBX:", 34); 6385 6470 else 6386 cpumR3CpuIdInfoVerboseCompareListU32(pHlp, pCurLeaf->uEbx, Host.uEbx, g_aExtLeaf8EbxSubFields, 56); 6471 cpumR3CpuIdInfoVerboseCompareListU32(pHlp, pCurLeaf->uEbx, Host.uEbx, g_aExtLeaf8EbxSubFields, 6472 "Ext Features ext IDs EBX", 56); 6387 6473 } 6388 6474 6389 6475 if (iVerbosity) 6390 6476 { 6391 uint32_t uEAX = pCurLeaf->uEax; 6392 uint32_t uECX = pCurLeaf->uEcx; 6393 6394 /** @todo 0x80000008:EAX[23:16] is only defined for AMD. We'll get 0 on Intel. On 6395 * AMD if we get 0, the guest physical address width should be taken from 6396 * 0x80000008:EAX[7:0] instead. Guest Physical address width is relevant 6397 * for guests using nested paging. */ 6477 uint32_t const uEAX = pCurLeaf->uEax; 6398 6478 pHlp->pfnPrintf(pHlp, 6399 6479 "Physical Address Width: %d bits\n" 6400 "Virtual Address Width: %d bits\n" 6401 "Guest Physical Address Width: %d bits\n", 6480 "Virtual Address Width: %d bits\n", 6402 6481 (uEAX >> 0) & 0xff, 6403 (uEAX >> 8) & 0xff, 6404 (uEAX >> 16) & 0xff); 6405 6406 /** @todo 0x80000008:ECX is reserved on Intel (we'll get incorrect physical core 6407 * count here). */ 6408 pHlp->pfnPrintf(pHlp, 6409 "Physical Core Count: %d\n", 6410 ((uECX >> 0) & 0xff) + 1); 6482 (uEAX >> 8) & 0xff); 6483 if ( ((uEAX >> 16) & 0xff) != 0 6484 || pVM->cpum.s.GuestFeatures.enmCpuVendor == CPUMCPUVENDOR_AMD 6485 || pVM->cpum.s.GuestFeatures.enmCpuVendor == CPUMCPUVENDOR_HYGON) 6486 pHlp->pfnPrintf(pHlp, "Guest Physical Address Width: %d bits%s\n", 6487 (uEAX >> 16) & 0xff ? (uEAX >> 16) & 0xff : (uEAX >> 0) & 0xff, 6488 (uEAX >> 16) & 0xff ? "" : " (0)"); 6489 6490 uint32_t const uECX = pCurLeaf->uEcx; 6491 if ( ((uECX >> 0) & 0xff) != 0 6492 || pVM->cpum.s.GuestFeatures.enmCpuVendor == CPUMCPUVENDOR_AMD 6493 || pVM->cpum.s.GuestFeatures.enmCpuVendor == CPUMCPUVENDOR_HYGON) 6494 { 6495 uint32_t const cPhysCoreCount = ((uECX >> 0) & 0xff) + 1; 6496 uint32_t const cApicIdSize = (uECX >> 12) & 0xf ? RT_BIT_32((uECX >> 12) & 0xf) : cPhysCoreCount; 6497 pHlp->pfnPrintf(pHlp, 6498 "Physical Core Count: %d\n" 6499 "APIC ID size: %u (%#x)\n" 6500 "Performance TSC size: %u bits\n", 6501 cPhysCoreCount, 6502 cApicIdSize, cApicIdSize, 6503 (((uECX >> 16) & 0x3) << 3) + 40); 6504 } 6505 uint32_t const uEDX = pCurLeaf->uEax; 6506 if (uEDX) 6507 pHlp->pfnPrintf(pHlp, 6508 "Max page count for INVLPGB: %#x\n" 6509 "Max ECX for RDPRU: %#x\n", 6510 (uEDX & 0xffff), uEDX >> 16); 6411 6511 } 6412 6512 } -
trunk/src/VBox/VMM/VMMR3/CPUMR3Db.cpp
r107778 r107854 587 587 * @returns VBox status code. 588 588 * @param pVM The cross context VM structure. 589 */ 590 int cpumR3MsrReconcileWithCpuId(PVM pVM) 591 { 592 PCCPUMMSRRANGE papToAdd[10]; 589 * @param fForceFlushCmd Make sure MSR_IA32_FLUSH_CMD is present. 590 * @param fForceSpecCtrl Make sure MSR_IA32_SPEC_CTRL is present. 591 */ 592 DECLHIDDEN(int) cpumR3MsrReconcileWithCpuId(PVM pVM, bool fForceFlushCmd, bool fForceSpecCtrl) 593 { 594 PCCPUMMSRRANGE apToAdd[10]; 593 595 uint32_t cToAdd = 0; 594 596 … … 596 598 * The IA32_FLUSH_CMD MSR was introduced in MCUs for CVS-2018-3646 and associates. 597 599 */ 598 if (pVM->cpum.s.GuestFeatures.fFlushCmd && !cpumLookupMsrRange(pVM, MSR_IA32_FLUSH_CMD)) 600 if ( pVM->cpum.s.GuestFeatures.fFlushCmd 601 || fForceFlushCmd) 599 602 { 600 603 static CPUMMSRRANGE const s_FlushCmd = … … 611 614 /*.szName = */ "IA32_FLUSH_CMD" 612 615 }; 613 papToAdd[cToAdd++] = &s_FlushCmd; 616 apToAdd[cToAdd++] = &s_FlushCmd; 617 } 618 619 /* 620 * The IA32_PRED_CMD MSR was introduced in MCUs for CVS-2018-3646 and associates. 621 */ 622 if ( pVM->cpum.s.GuestFeatures.fIbpb 623 /** @todo || pVM->cpum.s.GuestFeatures.fSbpb*/) 624 { 625 static CPUMMSRRANGE const s_PredCmd = 626 { 627 /*.uFirst =*/ MSR_IA32_PRED_CMD, 628 /*.uLast =*/ MSR_IA32_PRED_CMD, 629 /*.enmRdFn =*/ kCpumMsrRdFn_WriteOnly, 630 /*.enmWrFn =*/ kCpumMsrWrFn_Ia32PredCmd, 631 /*.offCpumCpu =*/ UINT16_MAX, 632 /*.fReserved =*/ 0, 633 /*.uValue =*/ 0, 634 /*.fWrIgnMask =*/ 0, 635 /*.fWrGpMask =*/ ~MSR_IA32_PRED_CMD_F_IBPB, 636 /*.szName = */ "IA32_PRED_CMD" 637 }; 638 apToAdd[cToAdd++] = &s_PredCmd; 639 } 640 641 /* 642 * The IA32_SPEC_CTRL MSR was introduced in MCUs for CVS-2018-3646 and associates. 643 */ 644 if ( pVM->cpum.s.GuestFeatures.fSpecCtrlMsr 645 || fForceSpecCtrl) 646 { 647 static CPUMMSRRANGE const s_SpecCtrl = 648 { 649 /*.uFirst =*/ MSR_IA32_SPEC_CTRL, 650 /*.uLast =*/ MSR_IA32_SPEC_CTRL, 651 /*.enmRdFn =*/ kCpumMsrRdFn_Ia32SpecCtrl, 652 /*.enmWrFn =*/ kCpumMsrWrFn_Ia32SpecCtrl, 653 /*.offCpumCpu =*/ UINT16_MAX, 654 /*.fReserved =*/ 0, 655 /*.uValue =*/ 0, 656 /*.fWrIgnMask =*/ 0, 657 /*.fWrGpMask =*/ 0, 658 /*.szName = */ "IA32_SPEC_CTRL" 659 }; 660 apToAdd[cToAdd++] = &s_SpecCtrl; 614 661 } 615 662 … … 618 665 * documented in relation to such. 619 666 */ 620 if (pVM->cpum.s.GuestFeatures.fArchCap && !cpumLookupMsrRange(pVM, MSR_IA32_ARCH_CAPABILITIES))667 if (pVM->cpum.s.GuestFeatures.fArchCap) 621 668 { 622 669 static CPUMMSRRANGE const s_ArchCaps = … … 633 680 /*.szName = */ "IA32_ARCH_CAPABILITIES" 634 681 }; 635 papToAdd[cToAdd++] = &s_ArchCaps;682 apToAdd[cToAdd++] = &s_ArchCaps; 636 683 } 637 684 … … 639 686 * Do the adding. 640 687 */ 688 Assert(cToAdd <= RT_ELEMENTS(apToAdd)); 641 689 for (uint32_t i = 0; i < cToAdd; i++) 642 690 { 643 PCCPUMMSRRANGE pRange = papToAdd[i]; 644 LogRel(("CPUM: MSR/CPUID reconciliation insert: %#010x %s\n", pRange->uFirst, pRange->szName)); 645 int rc = cpumR3MsrRangesInsert(NULL /* pVM */, &pVM->cpum.s.GuestInfo.paMsrRangesR3, &pVM->cpum.s.GuestInfo.cMsrRanges, 646 pRange); 647 if (RT_FAILURE(rc)) 648 return rc; 691 PCCPUMMSRRANGE pRange = apToAdd[i]; 692 Assert(pRange->uFirst == pRange->uLast); 693 if (!cpumLookupMsrRange(pVM, pRange->uFirst)) 694 { 695 LogRel(("CPUM: MSR/CPUID reconciliation insert: %#010x %s\n", pRange->uFirst, pRange->szName)); 696 int rc = cpumR3MsrRangesInsert(NULL /* pVM */, &pVM->cpum.s.GuestInfo.paMsrRangesR3, 697 &pVM->cpum.s.GuestInfo.cMsrRanges, pRange); 698 AssertRCReturn(rc, rc); 699 } 649 700 } 650 701 return VINF_SUCCESS;
Note:
See TracChangeset
for help on using the changeset viewer.