VirtualBox

Changeset 107703 in vbox for trunk/src


Ignore:
Timestamp:
Jan 11, 2025 10:55:53 PM (9 days ago)
Author:
vboxsync
Message:

VMM/CPUM: Try consolidate the MSR_IA32_ARCH_CAPABILITIES handling in CPUM and do better sanitizing of what's exposed to the guest. jiraref:VBP-947

Location:
trunk/src/VBox/VMM
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/CPUMAllCpuId.cpp

    r107650 r107703  
    16441644}
    16451645
     1646
     1647/**
     1648 * Helper for extracting feature bits from IA32_ARCH_CAPABILITIES.
     1649 */
     1650static void cpumCpuIdExplodeArchCapabilities(CPUMFEATURESX86 *pFeatures, bool fHasArchCap, uint64_t fArchVal)
     1651{
     1652    Assert(fHasArchCap || fArchVal == 0);
     1653    pFeatures->fArchCap                = fHasArchCap;
     1654    pFeatures->fArchRdclNo             = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_RDCL_NO);
     1655    pFeatures->fArchIbrsAll            = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_IBRS_ALL);
     1656    pFeatures->fArchRsbOverride        = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_RSBO);
     1657    pFeatures->fArchVmmNeedNotFlushL1d = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_VMM_NEED_NOT_FLUSH_L1D);
     1658#if 0
     1659    pFeatures->fArchSsbNo              = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_SSB_NO);
     1660#endif
     1661    pFeatures->fArchMdsNo              = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_MDS_NO);
     1662#if 0
     1663    pFeatures->fArchIfPschangeMscNo    = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_IF_PSCHANGE_MC_NO);
     1664    pFeatures->fArchTsxCtrl            = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_TSX_CTRL);
     1665    pFeatures->fArchTaaNo              = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_TAA_NO);
     1666    pFeatures->fArchMiscPackageCtrls   = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_MISC_PACKAGE_CTRLS);
     1667    pFeatures->fArchEnergyFilteringCtl = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_ENERGY_FILTERING_CTL);
     1668    pFeatures->fArchDoitm              = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_DOITM);
     1669    pFeatures->fArchSbdrSsdpNo         = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_SBDR_SSDP_NO);
     1670    pFeatures->fArchFbsdpNo            = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_FBSDP_NO);
     1671    pFeatures->fArchPsdpNo             = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_PSDP_NO);
     1672    pFeatures->fArchFbClear            = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_FB_CLEAR);
     1673    pFeatures->fArchFbClearCtrl        = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_FB_CLEAR_CTRL);
     1674    pFeatures->fArchRrsba              = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_RRSBA);
     1675    pFeatures->fArchBhiNo              = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_BHI_NO);
     1676    pFeatures->fArchXapicDisableStatus = RT_BOOL(fArchVal & XAPIC_DISABLE_STATUS);
     1677    pFeatures->fArchOverclockingStatus = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_OVERCLOCKING_STATUS);
     1678    pFeatures->fArchPbrsbNo            = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_PBRSB_NO);
     1679    pFeatures->fArchGdsCtrl            = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_GDS_CTRL);
     1680    pFeatures->fArchGdsNo              = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_GDS_NO);
     1681    pFeatures->fArchRfdsNo             = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_RFDS_NO);
     1682    pFeatures->fArchRfdsClear          = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_RFDS_CLEAR);
     1683    pFeatures->fArchIgnUmonitorSupport = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_IGN_UMONITOR_SUPPORT);
     1684    pFeatures->fArchMonUmonMitigSupport= RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_MON_UMON_MITIG_SUPPORT);
     1685#endif
     1686}
     1687
     1688
     1689# if defined(VBOX_VMM_TARGET_X86) || defined(VBOX_VMM_TARGET_AGNOSTIC)
     1690/**
     1691 * Sets the guest IA32_ARCH_CAPABILITIES value and associated feature bits.
     1692 */
     1693void cpumCpuIdSetGuestArchCapabilities(PVMCC pVM, bool fHasArchCap, uint64_t fArchVal, bool fHasIbrs)
     1694{
     1695    if (!fHasArchCap)
     1696        fArchVal = 0;
     1697    else if (!fHasIbrs)
     1698        fArchVal &= ~MSR_IA32_ARCH_CAP_F_IBRS_ALL;
     1699    fArchVal &= ~(  RT_BIT_64(9)
     1700                  | MSR_IA32_ARCH_CAP_F_MISC_PACKAGE_CTRLS
     1701                  | MSR_IA32_ARCH_CAP_F_ENERGY_FILTERING_CTL
     1702                  | MSR_IA32_ARCH_CAP_F_DOITM
     1703                  | RT_BIT_64(16)
     1704                  | RT_BIT_64(22)
     1705                  | MSR_IA32_ARCH_CAP_F_FB_CLEAR_CTRL
     1706                    /** @todo mask off MSR_IA32_ARCH_CAP_F_RRSBA ? */
     1707                  | MSR_IA32_ARCH_CAP_F_XAPIC_DISABLE_STATUS
     1708                  | MSR_IA32_ARCH_CAP_F_OVERCLOCKING_STATUS /** @todo expose IA32_OVERCLOCKING_STATUS */
     1709                  | MSR_IA32_ARCH_CAP_F_GDS_CTRL
     1710                  | MSR_IA32_ARCH_CAP_F_IGN_UMONITOR_SUPPORT
     1711                  | MSR_IA32_ARCH_CAP_F_MON_UMON_MITIG_SUPPORT
     1712                  | ~(RT_BIT_64(31) - 1U)
     1713                  );
     1714    VMCC_FOR_EACH_VMCPU_STMT(pVM, pVCpu->cpum.s.GuestMsrs.msr.ArchCaps = fArchVal);
     1715
     1716    cpumCpuIdExplodeArchCapabilities(&pVM->cpum.s.GuestFeatures, fHasArchCap, fArchVal);
     1717    LogRel(("CPUM: Guest IA32_ARCH_CAPABILITIES = %#RX64\n", fArchVal));
     1718}
     1719# endif
     1720
     1721
     1722# if defined(RT_ARCH_X86) || defined(RT_ARCH_AMD64)
     1723/**
     1724 * Sets host & guest feature bits & MSRs related to IA32_ARCH_CAPABILITIES.
     1725 *
     1726 * ASSUMES this is called after the basic guest features has been exploded.
     1727 */
     1728VMM_INT_DECL(void) CPUMCpuIdApplyX86HostArchCapabilities(PVMCC pVM, bool fHasArchCap, uint64_t fHostArchVal)
     1729{
     1730    cpumCpuIdExplodeArchCapabilities(const_cast<CPUMFEATURESX86 *>(&pVM->cpum.s.HostFeatures.s), fHasArchCap, fHostArchVal);
     1731    LogRel(("CPUM: Host IA32_ARCH_CAPABILITIES  = %#RX64\n", fHostArchVal));
     1732
     1733# if defined(VBOX_VMM_TARGET_X86) || defined(VBOX_VMM_TARGET_AGNOSTIC)
     1734#  ifdef VBOX_VMM_TARGET_AGNOSTIC
     1735    /** @todo arm on x86: check VM target. */
     1736#  endif
     1737    cpumCpuIdSetGuestArchCapabilities(pVM, fHasArchCap && pVM->cpum.s.GuestFeatures.fArchCap,
     1738                                      fHostArchVal, pVM->cpum.s.GuestFeatures.fIbrs);
     1739#  endif
     1740}
     1741# endif /* defined(RT_ARCH_X86) || defined(RT_ARCH_AMD64) */
     1742
    16461743#endif /* defined(RT_ARCH_X86) || defined(RT_ARCH_AMD64) || defined(VBOX_VMM_TARGET_X86) */
    16471744
  • trunk/src/VBox/VMM/VMMR0/CPUMR0.cpp

    r107650 r107703  
    361361         * Copy MSR_IA32_ARCH_CAPABILITIES bits over into the host and guest feature
    362362         * structure and as well as the guest MSR.
    363          * Note! we assume this happens after the CPUMR3Init is done, so CPUID bits are settled.
     363         * Note! We assume this happens after the CPUMR3Init is done, so CPUID bits are settled.
    364364         */
    365         pVM->cpum.s.HostFeatures.s.fArchRdclNo             = 0;
    366         pVM->cpum.s.HostFeatures.s.fArchIbrsAll            = 0;
    367         pVM->cpum.s.HostFeatures.s.fArchRsbOverride        = 0;
    368         pVM->cpum.s.HostFeatures.s.fArchVmmNeedNotFlushL1d = 0;
    369         pVM->cpum.s.HostFeatures.s.fArchMdsNo              = 0;
    370         uint32_t const cStdRange = ASMCpuId_EAX(0);
     365        uint64_t       fHostArchVal = 0;
     366        bool           fHasArchCap  = false;
     367        uint32_t const cStdRange    = ASMCpuId_EAX(0);
    371368        if (   RTX86IsValidStdRange(cStdRange)
    372369            && cStdRange >= 7)
     
    377374                && (fFeatures & X86_CPUID_FEATURE_EDX_MSR))
    378375            {
    379                 /* Host: */
    380                 uint64_t const fHostArchVal = ASMRdMsr(MSR_IA32_ARCH_CAPABILITIES);
    381                 uint64_t fArchVal = fHostArchVal;
    382                 pVM->cpum.s.HostFeatures.s.fArchRdclNo             = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_RDCL_NO);
    383                 pVM->cpum.s.HostFeatures.s.fArchIbrsAll            = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_IBRS_ALL);
    384                 pVM->cpum.s.HostFeatures.s.fArchRsbOverride        = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_RSBO);
    385                 pVM->cpum.s.HostFeatures.s.fArchVmmNeedNotFlushL1d = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_VMM_NEED_NOT_FLUSH_L1D);
    386                 pVM->cpum.s.HostFeatures.s.fArchMdsNo              = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_MDS_NO);
    387 
    388                 /* guest: */
    389                 if (!pVM->cpum.s.GuestFeatures.fArchCap)
    390                     fArchVal = 0;
    391                 else if (!pVM->cpum.s.GuestFeatures.fIbrs)
    392                     fArchVal &= ~MSR_IA32_ARCH_CAP_F_IBRS_ALL;
    393                 VMCC_FOR_EACH_VMCPU_STMT(pVM, pVCpu->cpum.s.GuestMsrs.msr.ArchCaps = fArchVal);
    394                 pVM->cpum.s.GuestFeatures.fArchRdclNo             = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_RDCL_NO);
    395                 pVM->cpum.s.GuestFeatures.fArchIbrsAll            = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_IBRS_ALL);
    396                 pVM->cpum.s.GuestFeatures.fArchRsbOverride        = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_RSBO);
    397                 pVM->cpum.s.GuestFeatures.fArchVmmNeedNotFlushL1d = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_VMM_NEED_NOT_FLUSH_L1D);
    398                 pVM->cpum.s.GuestFeatures.fArchMdsNo              = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_MDS_NO);
    399                 LogRel(("CPUM: IA32_ARCH_CAPABILITIES (Host=%#RX64 Guest=%#RX64)\n", fHostArchVal, fArchVal));
     376                fHostArchVal = ASMRdMsr(MSR_IA32_ARCH_CAPABILITIES);
     377                fHasArchCap  = true;
    400378            }
    401             else
    402             {
    403                 pVM->cpum.s.HostFeatures.s.fArchCap = 0;
    404                 LogRel(("CPUM: IA32_ARCH_CAPABILITIES unsupported\n"));
    405             }
    406         }
     379        }
     380        CPUMCpuIdApplyX86HostArchCapabilities(pVM, fHasArchCap, fHostArchVal);
    407381
    408382        /*
  • trunk/src/VBox/VMM/VMMR3/NEMR3Native-darwin.cpp

    r107115 r107703  
    22032203    /*
    22042204     * Get MSR_IA32_ARCH_CAPABILITIES and expand it into the host feature structure.
     2205     *
    22052206     * This is only available with 11.0+ (BigSur) as the required API is only available there,
    22062207     * we could in theory initialize this when creating the EMTs using hv_vcpu_read_msr() but
    22072208     * the required vCPU handle is created after CPUM was initialized which is too late.
    22082209     * Given that the majority of users is on 11.0 and later we don't care for now.
     2210     *
     2211     * (Yes, this is done after CPUM init.)
    22092212     */
     2213    uint64_t fHostArchVal = 0;
     2214    bool     fHasArchCap  = false;
    22102215    if (   hrc == HV_SUCCESS
    22112216        && hv_vmx_get_msr_info)
    22122217    {
    2213         g_CpumHostFeatures.s.fArchRdclNo             = 0;
    2214         g_CpumHostFeatures.s.fArchIbrsAll            = 0;
    2215         g_CpumHostFeatures.s.fArchRsbOverride        = 0;
    2216         g_CpumHostFeatures.s.fArchVmmNeedNotFlushL1d = 0;
    2217         g_CpumHostFeatures.s.fArchMdsNo              = 0;
    22182218        uint32_t const cStdRange = ASMCpuId_EAX(0);
    22192219        if (   RTX86IsValidStdRange(cStdRange)
     
    22262226                && (fStdFeaturesEdx    & X86_CPUID_FEATURE_EDX_MSR))
    22272227            {
    2228                 uint64_t fArchVal;
    2229                 hrc = hv_vmx_get_msr_info(HV_VMX_INFO_MSR_IA32_ARCH_CAPABILITIES, &fArchVal);
    2230                 if (hrc == HV_SUCCESS)
    2231                 {
    2232                     g_CpumHostFeatures.s.fArchRdclNo             = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_RDCL_NO);
    2233                     g_CpumHostFeatures.s.fArchIbrsAll            = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_IBRS_ALL);
    2234                     g_CpumHostFeatures.s.fArchRsbOverride        = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_RSBO);
    2235                     g_CpumHostFeatures.s.fArchVmmNeedNotFlushL1d = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_VMM_NEED_NOT_FLUSH_L1D);
    2236                     g_CpumHostFeatures.s.fArchMdsNo              = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_MDS_NO);
    2237                 }
     2228                fHasArchCap = true;
     2229                hrc = hv_vmx_get_msr_info(HV_VMX_INFO_MSR_IA32_ARCH_CAPABILITIES, &fHostArchVal);
     2230                if (hrc != HV_SUCCESS)
     2231                    fHostArchVal = 0;
    22382232            }
    2239             else
    2240                 g_CpumHostFeatures.s.fArchCap = 0;
    2241         }
    2242     }
     2233        }
     2234    }
     2235    CPUMCpuIdApplyX86HostArchCapabilities(pVM, fHasArchCap, fHostArchVal);
    22432236
    22442237    return nemR3DarwinHvSts2Rc(hrc);
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