VirtualBox

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


Ignore:
Timestamp:
Aug 22, 2023 9:30:06 AM (17 months ago)
Author:
vboxsync
Message:

VMM: bugref:10498 bugref:10318: Implemented basic MTRR reporting and storage, primarily to make progress with nested Hyper-V.

Location:
trunk/src/VBox/VMM/VMMR3
Files:
2 edited

Legend:

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

    r100532 r100935  
    32123212 *
    32133213 * @param   pVM         The cross context VM structure.
    3214  * @param   pCtx        The context to format.
     3214 * @param   pVCpu       The cross context virtual CPU structure.
    32153215 * @param   pHlp        Output functions.
    32163216 * @param   enmType     The dump type.
    32173217 * @param   pszPrefix   Register name prefix.
    32183218 */
    3219 static void cpumR3InfoOne(PVM pVM, PCPUMCTX pCtx, PCDBGFINFOHLP pHlp, CPUMDUMPTYPE enmType, const char *pszPrefix)
    3220 {
    3221     NOREF(pVM);
     3219static void cpumR3InfoOne(PVM pVM, PVMCPU pVCpu, PCDBGFINFOHLP pHlp, CPUMDUMPTYPE enmType, const char *pszPrefix)
     3220{
     3221    PCPUMCTX pCtx = &pVCpu->cpum.s.Guest;
    32223222
    32233223    /*
     
    35283528                for (unsigned i = 0; i < RT_ELEMENTS(pCtx->aPaePdpes); i++)
    35293529                    pHlp->pfnPrintf(pHlp, "%sPAE PDPTE %u  =%016RX64\n", pszPrefix, i, pCtx->aPaePdpes[i]);
     3530
     3531            /*
     3532             * MTRRs.
     3533             */
     3534            if (pVM->cpum.s.GuestFeatures.fMtrr)
     3535            {
     3536                pHlp->pfnPrintf(pHlp,
     3537                    "%sMTRR_CAP          =%016RX64\n"
     3538                    "%sMTRR_DEF_TYPE     =%016RX64\n"
     3539                    "%sMtrrFix64K_00000  =%016RX64\n"
     3540                    "%sMtrrFix16K_80000  =%016RX64\n"
     3541                    "%sMtrrFix16K_A0000  =%016RX64\n"
     3542                    "%sMtrrFix4K_C0000   =%016RX64\n"
     3543                    "%sMtrrFix4K_C8000   =%016RX64\n"
     3544                    "%sMtrrFix4K_D0000   =%016RX64\n"
     3545                    "%sMtrrFix4K_D8000   =%016RX64\n"
     3546                    "%sMtrrFix4K_E0000   =%016RX64\n"
     3547                    "%sMtrrFix4K_E8000   =%016RX64\n"
     3548                    "%sMtrrFix4K_F0000   =%016RX64\n"
     3549                    "%sMtrrFix4K_F8000   =%016RX64\n",
     3550                    pszPrefix, pVCpu->cpum.s.GuestMsrs.msr.MtrrCap,
     3551                    pszPrefix, pVCpu->cpum.s.GuestMsrs.msr.MtrrDefType,
     3552                    pszPrefix, pVCpu->cpum.s.GuestMsrs.msr.MtrrFix64K_00000,
     3553                    pszPrefix, pVCpu->cpum.s.GuestMsrs.msr.MtrrFix16K_80000,
     3554                    pszPrefix, pVCpu->cpum.s.GuestMsrs.msr.MtrrFix16K_A0000,
     3555                    pszPrefix, pVCpu->cpum.s.GuestMsrs.msr.MtrrFix4K_C0000,
     3556                    pszPrefix, pVCpu->cpum.s.GuestMsrs.msr.MtrrFix4K_C8000,
     3557                    pszPrefix, pVCpu->cpum.s.GuestMsrs.msr.MtrrFix4K_D0000,
     3558                    pszPrefix, pVCpu->cpum.s.GuestMsrs.msr.MtrrFix4K_D8000,
     3559                    pszPrefix, pVCpu->cpum.s.GuestMsrs.msr.MtrrFix4K_E0000,
     3560                    pszPrefix, pVCpu->cpum.s.GuestMsrs.msr.MtrrFix4K_E8000,
     3561                    pszPrefix, pVCpu->cpum.s.GuestMsrs.msr.MtrrFix4K_F0000,
     3562                    pszPrefix, pVCpu->cpum.s.GuestMsrs.msr.MtrrFix4K_F8000);
     3563
     3564                for (uint8_t iRange = 0; iRange < RT_ELEMENTS(pVCpu->cpum.s.GuestMsrs.msr.aMtrrVarMsrs); iRange++)
     3565                {
     3566                    PCX86MTRRVAR pMtrrVar = &pVCpu->cpum.s.GuestMsrs.msr.aMtrrVarMsrs[iRange];
     3567                    bool const   fIsValid = RT_BOOL(pMtrrVar->MtrrPhysMask & MSR_IA32_MTRR_PHYSMASK_VALID);
     3568                    if (fIsValid)
     3569                    {
     3570                        uint64_t const fInvPhysMask = ~(RT_BIT_64(pVM->cpum.s.GuestFeatures.cMaxPhysAddrWidth) - 1U);
     3571                        RTGCPHYS const GCPhysMask   = pMtrrVar->MtrrPhysMask & X86_PAGE_BASE_MASK;
     3572                        RTGCPHYS const GCPhysFirst  = pMtrrVar->MtrrPhysBase & X86_PAGE_BASE_MASK;
     3573                        RTGCPHYS const GCPhysLast   = (GCPhysFirst | ~GCPhysMask) & ~fInvPhysMask;
     3574                        Assert((GCPhysLast & GCPhysMask)       == (GCPhysFirst & GCPhysMask));
     3575                        Assert(((GCPhysLast + 1) & GCPhysMask) != (GCPhysFirst & GCPhysMask));
     3576                        pHlp->pfnPrintf(pHlp,
     3577                                        "%sMTRR_PHYSBASE[%2u] =%016RX64 First=%016RX64\n"
     3578                                        "%sMTRR_PHYSMASK[%2u] =%016RX64 Last =%016RX64\n",
     3579                                        pszPrefix, iRange, pMtrrVar->MtrrPhysBase, GCPhysFirst,
     3580                                        pszPrefix, iRange, pMtrrVar->MtrrPhysMask, GCPhysLast);
     3581                    }
     3582                    else
     3583                        pHlp->pfnPrintf(pHlp,
     3584                                        "%sMTRR_PHYSBASE[%2u] =%016RX64\n"
     3585                                        "%sMTRR_PHYSMASK[%2u] =%016RX64\n",
     3586                                        pszPrefix, iRange, pMtrrVar->MtrrPhysBase,
     3587                                        pszPrefix, iRange, pMtrrVar->MtrrPhysMask);
     3588                }
     3589            }
    35303590            break;
    35313591    }
     
    36103670    pHlp->pfnPrintf(pHlp, "Guest CPUM (VCPU %d) state: %s\n", pVCpu->idCpu, pszComment);
    36113671
    3612     PCPUMCTX pCtx = &pVCpu->cpum.s.Guest;
    3613     cpumR3InfoOne(pVM, pCtx, pHlp, enmType, "");
     3672    cpumR3InfoOne(pVM, pVCpu, pHlp, enmType, "");
    36143673}
    36153674
     
    45394598                }
    45404599            }
     4600
     4601            /*
     4602             * Initialize MTRRs.
     4603             */
     4604            if (pVM->cpum.s.fMtrrRead)
     4605            {
     4606                uint64_t cbRam;
     4607                CFGMR3QueryU64Def(CFGMR3GetRoot(pVM), "RamSize", &cbRam, 0);
     4608                AssertReturn(cbRam > _1M, VERR_CPUM_IPE_1);
     4609                RTGCPHYS const GCPhysFirst   = _1M;
     4610                RTGCPHYS const GCPhysLast    = cbRam - 1;
     4611                RTGCPHYS const GCPhysLength  = GCPhysLast - GCPhysFirst;
     4612                uint64_t const fInvPhysMask  = ~(RT_BIT_64(pVM->cpum.s.GuestFeatures.cMaxPhysAddrWidth) - 1U);
     4613                RTGCPHYS const GCPhysMask    = (~(GCPhysLength - 1) & ~fInvPhysMask) & X86_PAGE_BASE_MASK;
     4614                uint64_t const uMtrrPhysMask = GCPhysMask | MSR_IA32_MTRR_PHYSMASK_VALID;
     4615#ifdef VBOX_STRICT
     4616                /* Paranoia. */
     4617                Assert(GCPhysLast == ((GCPhysFirst | ~GCPhysMask) & ~fInvPhysMask));
     4618                Assert((GCPhysLast & GCPhysMask) == (GCPhysFirst & GCPhysMask));
     4619                Assert(((GCPhysLast + 1) & GCPhysMask) != (GCPhysFirst & GCPhysMask));
     4620#endif
     4621                for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
     4622                {
     4623                    PCPUMCTXMSRS pCtxMsrs = &pVM->apCpusR3[idCpu]->cpum.s.GuestMsrs;
     4624                    pCtxMsrs->msr.MtrrFix64K_00000 = 0x0606060606060606;
     4625                    pCtxMsrs->msr.MtrrFix16K_80000 = 0x0606060606060606;
     4626                    pCtxMsrs->msr.MtrrFix16K_A0000 = 0;
     4627                    pCtxMsrs->msr.MtrrFix4K_C0000  = 0x0505050505050505;
     4628                    pCtxMsrs->msr.MtrrFix4K_C8000  = 0x0505050505050505;
     4629                    pCtxMsrs->msr.MtrrFix4K_D0000  = 0x0505050505050505;
     4630                    pCtxMsrs->msr.MtrrFix4K_D8000  = 0x0505050505050505;
     4631                    pCtxMsrs->msr.MtrrFix4K_E0000  = 0x0505050505050505;
     4632                    pCtxMsrs->msr.MtrrFix4K_E8000  = 0x0505050505050505;
     4633                    pCtxMsrs->msr.MtrrFix4K_F0000  = 0x0505050505050505;
     4634                    pCtxMsrs->msr.MtrrFix4K_F8000  = 0x0505050505050505;
     4635                    pCtxMsrs->msr.aMtrrVarMsrs[0].MtrrPhysBase = GCPhysFirst | X86_MTRR_MT_WB;
     4636                    pCtxMsrs->msr.aMtrrVarMsrs[0].MtrrPhysMask = uMtrrPhysMask;
     4637                }
     4638                LogRel(("CPUM: Initialized MTRRs (MtrrPhysMask=%RGp GCPhysLast=%RGp)\n", uMtrrPhysMask, GCPhysLast));
     4639            }
    45414640            break;
    45424641        }
  • trunk/src/VBox/VMM/VMMR3/CPUMR3CpuId.cpp

    r100854 r100935  
    32313231
    32323232        /*
     3233         * MTRR support.
     3234         * Currently we are exposing MTRRs with reasonable default values just to get Nested Hyper-V
     3235         * going, it isn't feature complete, see @bugref{10318} and bugref{10498}.
     3236         */
     3237        if (pVM->cpum.s.GuestFeatures.fMtrr)
     3238        {
     3239            /* Check if MTRR read+write support is enabled. */
     3240            bool fEnableMtrrWrite;
     3241            rc = CFGMR3QueryBoolDef(pCpumCfg, "MTRRWrite", &fEnableMtrrWrite, false);
     3242            AssertRCReturn(rc, rc);
     3243            if (fEnableMtrrWrite)
     3244            {
     3245                pVM->cpum.s.fMtrrRead  = true;
     3246                pVM->cpum.s.fMtrrWrite = true;
     3247                LogRel(("CPUM: Enabled MTRR read-write support\n"));
     3248            }
     3249            else
     3250            {
     3251                /* Check if MTRR read-only reporting is enabled. */
     3252                rc = CFGMR3QueryBoolDef(pCpumCfg, "MTRR", &pVM->cpum.s.fMtrrRead, false);
     3253                AssertRCReturn(rc, rc);
     3254                LogRel(("CPUM: Enabled MTRR read-only support\n"));
     3255            }
     3256
     3257            /* Setup MTRR capability based on what the host supports. */
     3258            Assert(!pVM->cpum.s.fMtrrWrite || pVM->cpum.s.fMtrrRead);
     3259            if (pVM->cpum.s.fMtrrRead)
     3260            {
     3261                Assert(pVM->cpum.s.HostFeatures.fMtrr);
     3262
     3263                /* Lookup the number of variable-range MTRRs supported on the host. */
     3264                PCCPUMMSRRANGE pMtrrCapRange = cpumLookupMsrRange(pVM, MSR_IA32_MTRR_CAP);
     3265                AssertLogRelReturn(pMtrrCapRange, VERR_CPUM_IPE_2);
     3266                uint8_t const cHostVarRangeRegs = pMtrrCapRange->uValue & MSR_IA32_MTRR_CAP_VCNT_MASK;
     3267
     3268                /* Construct guest MTRR support capabilities. */
     3269                uint8_t const  cGuestVarRangeRegs = RT_MIN(cHostVarRangeRegs, CPUMCTX_MAX_MTRRVAR_COUNT);
     3270                uint64_t const uGstMtrrCap        = cGuestVarRangeRegs
     3271                                                  | MSR_IA32_MTRR_CAP_FIX;
     3272                for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
     3273                {
     3274                    PVMCPU pVCpu = pVM->apCpusR3[idCpu];
     3275                    pVCpu->cpum.s.GuestMsrs.msr.MtrrCap     = uGstMtrrCap;
     3276                    pVCpu->cpum.s.GuestMsrs.msr.MtrrDefType = MSR_IA32_MTRR_DEF_TYPE_FIXED_EN
     3277                                                            | MSR_IA32_MTRR_DEF_TYPE_MTRR_EN
     3278                                                            | X86_MTRR_MT_UC;
     3279                }
     3280                LogRel(("CPUM: Enabled fixed-range MTRRs and %u variable-range MTRRs\n", cGuestVarRangeRegs));
     3281            }
     3282        }
     3283
     3284        /*
    32333285         * Finally, initialize guest VMX MSRs.
    32343286         *
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