Changeset 102605 in vbox for trunk/src/VBox/VMM/VMMR3
- Timestamp:
- Dec 15, 2023 7:43:02 AM (13 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/CPUMR3CpuId.cpp
r102604 r102605 3062 3062 3063 3063 /* 3064 * CPUID determines the actual maximum physical address width reported and supported. 3065 * If the CPU DB profile reported fewer address bits, we must correct it here by 3066 * updating the MSR write #GP masks of all the variable-range MTRR MSRs. Otherwise, 3064 * CPUID determines the actual maximum physical address width reported and supported. 3065 * If the CPU DB profile reported fewer address bits, we must correct it here by 3066 * updating the MSR write #GP masks of all the variable-range MTRR MSRs. Otherwise, 3067 3067 * they cause problems when guests write to these MTRR MSRs, see @bugref{10498#c32}. 3068 3068 */ 3069 for (uint8_t iVarMtrr = 0; iVarMtrr < cVarMtrrs; iVarMtrr++) 3070 { 3071 PCPUMMSRRANGE pBaseRange = cpumLookupMsrRange(pVM, MSR_IA32_MTRR_PHYSBASE0 + (iVarMtrr * 2)); 3072 AssertLogRelMsgReturn(pBaseRange, ("Failed to lookup the IA32_MTRR_PHYSBASE[%u] MSR range\n", iVarMtrr), 3073 VERR_NOT_FOUND); 3074 3075 PCPUMMSRRANGE pMaskRange = cpumLookupMsrRange(pVM, MSR_IA32_MTRR_PHYSMASK0 + (iVarMtrr * 2)); 3076 AssertLogRelMsgReturn(pBaseRange, ("Failed to lookup the IA32_MTRR_PHYSMASK[%u] MSR range\n", iVarMtrr), 3077 VERR_NOT_FOUND); 3078 3079 uint64_t const fBaseWrGpMask = pBaseRange->fWrGpMask; 3080 uint64_t const fMaskWrGpMask = pMaskRange->fWrGpMask; 3081 3082 uint8_t const cGuestMaxPhysAddrWidth = pVM->cpum.s.GuestFeatures.cMaxPhysAddrWidth; 3083 uint8_t const cProfilePhysBaseMaxPhysAddrWidth = ASMBitLastSetU64(~fBaseWrGpMask); 3084 uint8_t const cProfilePhysMaskMaxPhysAddrWidth = ASMBitLastSetU64(~fMaskWrGpMask); 3085 3086 AssertLogRelMsgReturn(cProfilePhysBaseMaxPhysAddrWidth == cProfilePhysMaskMaxPhysAddrWidth, 3087 ("IA32_MTRR_PHYSBASE and IA32_MTRR_PHYSMASK report different physical address widths (%u and %u)\n", 3088 cProfilePhysBaseMaxPhysAddrWidth, cProfilePhysMaskMaxPhysAddrWidth), 3089 VERR_CPUM_IPE_2); 3090 AssertLogRelMsgReturn(cProfilePhysBaseMaxPhysAddrWidth > 12 && cProfilePhysBaseMaxPhysAddrWidth <= 64, 3091 ("IA32_MTRR_PHYSBASE and IA32_MTRR_PHYSMASK reports an invalid physical address width of %u bits\n", 3092 cProfilePhysBaseMaxPhysAddrWidth), VERR_CPUM_IPE_2); 3093 3094 if (cProfilePhysBaseMaxPhysAddrWidth < cGuestMaxPhysAddrWidth) 3095 { 3096 uint64_t fNewBaseWrGpMask = fBaseWrGpMask; 3097 uint64_t fNewMaskWrGpMask = fMaskWrGpMask; 3098 int8_t cBits = cGuestMaxPhysAddrWidth - cProfilePhysBaseMaxPhysAddrWidth; 3099 while (cBits) 3100 { 3101 uint64_t const fWrGpAndMask = ~(uint64_t)RT_BIT_64(cProfilePhysBaseMaxPhysAddrWidth + cBits - 1); 3102 fNewBaseWrGpMask &= fWrGpAndMask; 3103 fNewMaskWrGpMask &= fWrGpAndMask; 3104 --cBits; 3105 } 3106 3107 pBaseRange->fWrGpMask = fBaseWrGpMask; 3108 pMaskRange->fWrGpMask = fMaskWrGpMask; 3109 3110 LogRel(("CPUM: Updated IA32_MTRR_PHYSBASE[%u] MSR write #GP mask (old=%#016RX64 new=%#016RX64)\n", 3111 iVarMtrr, fBaseWrGpMask, fNewBaseWrGpMask)); 3112 LogRel(("CPUM: Updated IA32_MTRR_PHYSMASK[%u] MSR write #GP mask (old=%#016RX64 new=%#016RX64)\n", 3113 iVarMtrr, fMaskWrGpMask, fNewMaskWrGpMask)); 3114 } 3069 PCPUMMSRRANGE pBaseRange0 = cpumLookupMsrRange(pVM, MSR_IA32_MTRR_PHYSBASE0); 3070 AssertLogRelMsgReturn(pBaseRange0, ("Failed to lookup the IA32_MTRR_PHYSBASE[0] MSR range\n"), VERR_NOT_FOUND); 3071 3072 PCPUMMSRRANGE pMaskRange0 = cpumLookupMsrRange(pVM, MSR_IA32_MTRR_PHYSMASK0); 3073 AssertLogRelMsgReturn(pMaskRange0, ("Failed to lookup the IA32_MTRR_PHYSMASK[0] MSR range\n"), VERR_NOT_FOUND); 3074 3075 uint64_t const fPhysBaseWrGpMask = pBaseRange0->fWrGpMask; 3076 uint64_t const fPhysMaskWrGpMask = pMaskRange0->fWrGpMask; 3077 3078 uint8_t const cGuestMaxPhysAddrWidth = pVM->cpum.s.GuestFeatures.cMaxPhysAddrWidth; 3079 uint8_t const cProfilePhysBaseMaxPhysAddrWidth = ASMBitLastSetU64(~fPhysBaseWrGpMask); 3080 uint8_t const cProfilePhysMaskMaxPhysAddrWidth = ASMBitLastSetU64(~fPhysMaskWrGpMask); 3081 3082 AssertLogRelMsgReturn(cProfilePhysBaseMaxPhysAddrWidth == cProfilePhysMaskMaxPhysAddrWidth, 3083 ("IA32_MTRR_PHYSBASE and IA32_MTRR_PHYSMASK report different physical address widths (%u and %u)\n", 3084 cProfilePhysBaseMaxPhysAddrWidth, cProfilePhysMaskMaxPhysAddrWidth), 3085 VERR_CPUM_IPE_2); 3086 AssertLogRelMsgReturn(cProfilePhysBaseMaxPhysAddrWidth > 12 && cProfilePhysBaseMaxPhysAddrWidth <= 64, 3087 ("IA32_MTRR_PHYSBASE and IA32_MTRR_PHYSMASK reports an invalid physical address width of %u bits\n", 3088 cProfilePhysBaseMaxPhysAddrWidth), VERR_CPUM_IPE_2); 3089 3090 if (cProfilePhysBaseMaxPhysAddrWidth < cGuestMaxPhysAddrWidth) 3091 { 3092 uint64_t fNewPhysBaseWrGpMask = fPhysBaseWrGpMask; 3093 uint64_t fNewPhysMaskWrGpMask = fPhysMaskWrGpMask; 3094 int8_t cBits = cGuestMaxPhysAddrWidth - cProfilePhysBaseMaxPhysAddrWidth; 3095 while (cBits) 3096 { 3097 uint64_t const fWrGpAndMask = ~(uint64_t)RT_BIT_64(cProfilePhysBaseMaxPhysAddrWidth + cBits - 1); 3098 fNewPhysBaseWrGpMask &= fWrGpAndMask; 3099 fNewPhysMaskWrGpMask &= fWrGpAndMask; 3100 --cBits; 3101 } 3102 3103 for (uint8_t iVarMtrr = 1; iVarMtrr < cVarMtrrs; iVarMtrr++) 3104 { 3105 PCPUMMSRRANGE pBaseRange = cpumLookupMsrRange(pVM, MSR_IA32_MTRR_PHYSBASE0 + (iVarMtrr * 2)); 3106 AssertLogRelMsgReturn(pBaseRange, ("Failed to lookup the IA32_MTRR_PHYSBASE[%u] MSR range\n", iVarMtrr), 3107 VERR_NOT_FOUND); 3108 3109 PCPUMMSRRANGE pMaskRange = cpumLookupMsrRange(pVM, MSR_IA32_MTRR_PHYSMASK0 + (iVarMtrr * 2)); 3110 AssertLogRelMsgReturn(pBaseRange, ("Failed to lookup the IA32_MTRR_PHYSMASK[%u] MSR range\n", iVarMtrr), 3111 VERR_NOT_FOUND); 3112 3113 AssertLogRelMsgReturn(pBaseRange->fWrGpMask == fPhysBaseWrGpMask, 3114 ("IA32_MTRR_PHYSBASE[%u] write GP mask (%#016RX64) differs from IA32_MTRR_PHYSBASE[0] write GP mask (%#016RX64)\n", 3115 iVarMtrr, pBaseRange->fWrGpMask, fPhysBaseWrGpMask), 3116 VERR_CPUM_IPE_1); 3117 AssertLogRelMsgReturn(pMaskRange->fWrGpMask == fPhysMaskWrGpMask, 3118 ("IA32_MTRR_PHYSMASK[%u] write GP mask (%#016RX64) differs from IA32_MTRR_PHYSMASK[0] write GP mask (%#016RX64)\n", 3119 iVarMtrr, pMaskRange->fWrGpMask, fPhysMaskWrGpMask), 3120 VERR_CPUM_IPE_1); 3121 3122 pBaseRange->fWrGpMask = fNewPhysBaseWrGpMask; 3123 pMaskRange->fWrGpMask = fNewPhysMaskWrGpMask; 3124 } 3125 3126 pBaseRange0->fWrGpMask = fNewPhysBaseWrGpMask; 3127 pMaskRange0->fWrGpMask = fNewPhysMaskWrGpMask; 3128 3129 LogRel(("CPUM: Updated IA32_MTRR_PHYSBASE[0..%u] MSR write #GP mask (old=%#016RX64 new=%#016RX64)\n", 3130 cVarMtrrs - 1, fPhysBaseWrGpMask, fNewPhysBaseWrGpMask)); 3131 LogRel(("CPUM: Updated IA32_MTRR_PHYSMASK[0..%u] MSR write #GP mask (old=%#016RX64 new=%#016RX64)\n", 3132 cVarMtrrs - 1, fPhysMaskWrGpMask, fNewPhysMaskWrGpMask)); 3115 3133 } 3116 3134
Note:
See TracChangeset
for help on using the changeset viewer.