VirtualBox

Changeset 94940 in vbox


Ignore:
Timestamp:
May 9, 2022 9:16:15 AM (3 years ago)
Author:
vboxsync
Message:

VMM/CPUM: Apply cpumR0CheckCpuid to the ring-0 g_CpumHostFeatures and add MSR_IA32_ARCH_CAPABILITIES bits (also ring-0 only). bugref:10093

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR0/CPUMR0.cpp

    r94934 r94940  
    7171
    7272/**
     73 * Check the CPUID features of this particular CPU and disable relevant features
     74 * for the guest which do not exist on this CPU.
     75 *
     76 * We have seen systems where the X86_CPUID_FEATURE_ECX_MONITOR feature flag is
     77 * only set on some host CPUs, see @bugref{5436}.
     78 *
     79 * @note This function might be called simultaneously on more than one CPU!
     80 *
     81 * @param   idCpu       The identifier for the CPU the function is called on.
     82 * @param   pvUser1     Leaf array.
     83 * @param   pvUser2     Number of leaves.
     84 */
     85static DECLCALLBACK(void) cpumR0CheckCpuid(RTCPUID idCpu, void *pvUser1, void *pvUser2)
     86{
     87    PCPUMCPUIDLEAF const paLeaves = (PCPUMCPUIDLEAF)pvUser1;
     88    uint32_t const       cLeaves  = (uint32_t)(uintptr_t)pvUser2;
     89    RT_NOREF(idCpu);
     90
     91    for (uint32_t i = 0; i < RT_ELEMENTS(g_aCpuidUnifyBits); i++)
     92    {
     93        PCPUMCPUIDLEAF pLeaf = cpumCpuIdGetLeafInt(paLeaves, cLeaves, g_aCpuidUnifyBits[i].uLeaf, 0);
     94        if (pLeaf)
     95        {
     96            uint32_t uEax, uEbx, uEcx, uEdx;
     97            ASMCpuIdExSlow(g_aCpuidUnifyBits[i].uLeaf, 0, 0, 0, &uEax, &uEbx, &uEcx, &uEdx);
     98
     99            ASMAtomicAndU32(&pLeaf->uEcx, uEcx | ~g_aCpuidUnifyBits[i].uEcx);
     100            ASMAtomicAndU32(&pLeaf->uEdx, uEdx | ~g_aCpuidUnifyBits[i].uEdx);
     101        }
     102    }
     103}
     104
     105
     106/**
    73107 * Does the Ring-0 CPU initialization once during module load.
    74108 * XXX Host-CPU hot-plugging?
     
    104138    rc = CPUMCpuIdCollectLeavesX86(&paLeaves, &cLeaves);
    105139    AssertLogRelRCReturn(rc, rc);
    106     /** @todo check out the CPUID info with the other CPUs in the system. */
     140
     141    /*
     142     * Unify/cross check some CPUID feature bits on all available CPU cores
     143     * and threads.  We've seen CPUs where the monitor support differed.
     144     */
     145    RTMpOnAll(cpumR0CheckCpuid, paLeaves, (void *)(uintptr_t)cLeaves);
    107146
    108147    /*
     
    112151    RTMemFree(paLeaves);
    113152    AssertLogRelRCReturn(rc, rc);
     153
     154    /*
     155     * Get MSR_IA32_ARCH_CAPABILITIES and expand it into the host feature structure.
     156     */
     157    if (ASMHasCpuId())
     158    {
     159        /** @todo Should add this MSR to CPUMMSRS and expose it via SUPDrv... */
     160        g_CpumHostFeatures.s.fArchRdclNo             = 0;
     161        g_CpumHostFeatures.s.fArchIbrsAll            = 0;
     162        g_CpumHostFeatures.s.fArchRsbOverride        = 0;
     163        g_CpumHostFeatures.s.fArchVmmNeedNotFlushL1d = 0;
     164        g_CpumHostFeatures.s.fArchMdsNo              = 0;
     165        uint32_t const cStdRange = ASMCpuId_EAX(0);
     166        if (   RTX86IsValidStdRange(cStdRange)
     167            && cStdRange >= 7)
     168        {
     169            uint32_t const fStdFeaturesEdx = ASMCpuId_EDX(1);
     170            uint32_t fStdExtFeaturesEdx;
     171            ASMCpuIdExSlow(7, 0, 0, 0, NULL, NULL, NULL, &fStdExtFeaturesEdx);
     172            if (   (fStdExtFeaturesEdx & X86_CPUID_STEXT_FEATURE_EDX_ARCHCAP)
     173                && (fStdFeaturesEdx    & X86_CPUID_FEATURE_EDX_MSR))
     174            {
     175                uint64_t fArchVal = ASMRdMsr(MSR_IA32_ARCH_CAPABILITIES);
     176                g_CpumHostFeatures.s.fArchRdclNo             = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_RDCL_NO);
     177                g_CpumHostFeatures.s.fArchIbrsAll            = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_IBRS_ALL);
     178                g_CpumHostFeatures.s.fArchRsbOverride        = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_RSBO);
     179                g_CpumHostFeatures.s.fArchVmmNeedNotFlushL1d = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_VMM_NEED_NOT_FLUSH_L1D);
     180                g_CpumHostFeatures.s.fArchMdsNo              = RT_BOOL(fArchVal & MSR_IA32_ARCH_CAP_F_MDS_NO);
     181            }
     182            else
     183                g_CpumHostFeatures.s.fArchCap = 0;
     184        }
     185    }
    114186
    115187    return VINF_SUCCESS;
     
    138210 * @param   pvUser2     Ignored.
    139211 */
    140 static DECLCALLBACK(void) cpumR0CheckCpuid(RTCPUID idCpu, void *pvUser1, void *pvUser2)
     212static DECLCALLBACK(void) cpumR0CheckCpuidLegacy(RTCPUID idCpu, void *pvUser1, void *pvUser2)
    141213{
    142214    PVMCC     pVM   = (PVMCC)pvUser1;
     
    314386         * up to date when we get here.
    315387         */
    316         RTMpOnAll(cpumR0CheckCpuid, pVM, NULL);
     388        RTMpOnAll(cpumR0CheckCpuidLegacy, pVM, NULL);
    317389
    318390        for (uint32_t i = 0; i < RT_ELEMENTS(g_aCpuidUnifyBits); i++)
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