VirtualBox

Changeset 102605 in vbox for trunk/src/VBox/VMM/VMMR3


Ignore:
Timestamp:
Dec 15, 2023 7:43:02 AM (13 months ago)
Author:
vboxsync
Message:

VMM/CPUM: bugref:10498 Slight optimization to the fix in r160758.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/CPUMR3CpuId.cpp

    r102604 r102605  
    30623062
    30633063    /*
    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,
    30673067     * they cause problems when guests write to these MTRR MSRs, see @bugref{10498#c32}.
    30683068     */
    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));
    31153133    }
    31163134
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette