VirtualBox

Changeset 70913 in vbox


Ignore:
Timestamp:
Feb 8, 2018 3:11:15 PM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
120741
Message:

CPUM: Infrastructure for speculative execution control.

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/cpum.h

    r70781 r70913  
    7474    /** The MWait Extensions bits (Std) */
    7575    CPUMCPUIDFEATURE_MWAIT_EXTS,
     76    /** The speculation control feature bits. (StExt) */
     77    CPUMCPUIDFEATURE_SPEC_CTRL,
    7678    /** 32bit hackishness. */
    7779    CPUMCPUIDFEATURE_32BIT_HACK = 0x7fffffff
     
    470472    kCpumMsrRdFn_Ia32VmxTrueEntryCtls,      /**< Takes real value as reference. */
    471473    kCpumMsrRdFn_Ia32VmxVmFunc,             /**< Takes real value as reference. */
     474    kCpumMsrRdFn_Ia32SpecCtrl,
     475    kCpumMsrRdFn_Ia32ArchCapabilities,
    472476
    473477    kCpumMsrRdFn_Amd64Efer,
     
    722726    kCpumMsrWrFn_Ia32X2ApicN,
    723727    kCpumMsrWrFn_Ia32DebugInterface,
     728    kCpumMsrWrFn_Ia32SpecCtrl,
     729    kCpumMsrWrFn_Ia32PredCmd,
    724730
    725731    kCpumMsrWrFn_Amd64Efer,
     
    10721078    uint32_t        fVmx : 1;
    10731079
     1080    /** Indicates that speculative execution control CPUID bits and
     1081     *  MSRs are exposed. The details are different for Intel and
     1082     * AMD but both have similar functionality. */
     1083    uint32_t        fSpeculationControl : 1;
     1084
    10741085    /** Alignment padding / reserved for future use. */
    1075     uint32_t        fPadding : 16;
     1086    uint32_t        fPadding : 15;
    10761087
    10771088    /** SVM: Supports Nested-paging. */
  • trunk/include/VBox/vmm/cpumctx.h

    r70732 r70913  
    778778        uint64_t    MtrrFix4K_F8000;    /**< IA32_MTRR_FIX4K_F8000 */
    779779        uint64_t    PkgCStateCfgCtrl;   /**< MSR_PKG_CST_CONFIG_CONTROL */
     780        uint64_t    SpecCtrl;           /**< IA32_SPEC_CTRL */
     781        uint64_t    ArchCaps;           /**< IA32_ARCH_CAPABILITIES */
    780782    } msr;
    781783    uint64_t    au64[64];
  • trunk/include/iprt/x86.h

    r70612 r70913  
    617617#define X86_CPUID_STEXT_FEATURE_EDX_STIBP             RT_BIT_32(27)
    618618
    619 /** EDX Bit 29 - ARCHCAP - Supports the IA32_ARCH_CAP MSR. */
     619/** EDX Bit 29 - ARCHCAP - Supports the IA32_ARCH_CAPABILITIES MSR. */
    620620#define X86_CPUID_STEXT_FEATURE_EDX_ARCHCAP           RT_BIT_32(29)
    621621
     
    12051205/** Architecture capabilities (bugfixes).
    12061206 * @note May move  */
    1207 #define MSR_IA32_ARCH_CAP                   UINT32_C(0x10a)
     1207#define MSR_IA32_ARCH_CAPABILITIES          UINT32_C(0x10a)
    12081208/** CPU is no subject to spectre problems. */
    12091209#define MSR_IA32_ARCH_CAP_F_SPECTRE_FIX     RT_BIT_32(0)
  • trunk/src/VBox/VMM/VMMAll/CPUMAllMsrs.cpp

    r70071 r70913  
    14301430    return VINF_SUCCESS;
    14311431}
     1432
     1433
     1434/** @callback_method_impl{FNCPUMRDMSR} */
     1435static DECLCALLBACK(VBOXSTRICTRC) cpumMsrRd_Ia32SpecCtrl(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t *puValue)
     1436{
     1437    RT_NOREF_PV(pVCpu); RT_NOREF_PV(idMsr); RT_NOREF_PV(pRange);
     1438    *puValue = pVCpu->cpum.s.GuestMsrs.msr.SpecCtrl;
     1439    return VINF_SUCCESS;
     1440}
     1441
     1442
     1443/** @callback_method_impl{FNCPUMWRMSR} */
     1444static DECLCALLBACK(VBOXSTRICTRC) cpumMsrWr_Ia32SpecCtrl(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t uValue, uint64_t uRawValue)
     1445{
     1446    RT_NOREF_PV(pVCpu); RT_NOREF_PV(idMsr); RT_NOREF_PV(pRange); RT_NOREF_PV(uValue); RT_NOREF_PV(uRawValue);
     1447
     1448    /* NB: The STIBP bit can be set even when IBRS is present, regardless of whether STIBP is actually implemented. */
     1449    if (uValue & ~(MSR_IA32_SPEC_CTRL_F_IBRS | MSR_IA32_SPEC_CTRL_F_STIBP))
     1450    {
     1451        Log(("CPUM: Invalid IA32_SPEC_CTRL bits (trying to write %#llx)\n", uValue));
     1452        return VERR_CPUM_RAISE_GP_0;
     1453    }
     1454
     1455    pVCpu->cpum.s.GuestMsrs.msr.SpecCtrl = uValue;
     1456    return VINF_SUCCESS;
     1457}
     1458
     1459
     1460/** @callback_method_impl{FNCPUMWRMSR} */
     1461static DECLCALLBACK(VBOXSTRICTRC) cpumMsrWr_Ia32PredCmd(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t uValue, uint64_t uRawValue)
     1462{
     1463    RT_NOREF_PV(pVCpu); RT_NOREF_PV(idMsr); RT_NOREF_PV(pRange); RT_NOREF_PV(uValue); RT_NOREF_PV(uRawValue);
     1464    return VINF_SUCCESS;
     1465}
     1466
     1467
     1468/** @callback_method_impl{FNCPUMRDMSR} */
     1469static DECLCALLBACK(VBOXSTRICTRC) cpumMsrRd_Ia32ArchCapabilities(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t *puValue)
     1470{
     1471    RT_NOREF_PV(pVCpu); RT_NOREF_PV(idMsr); RT_NOREF_PV(pRange);
     1472    *puValue = pVCpu->cpum.s.GuestMsrs.msr.ArchCaps;
     1473    return VINF_SUCCESS;
     1474}
     1475
     1476
    14321477
    14331478
     
    49995044    cpumMsrRd_Ia32VmxTrueEntryCtls,
    50005045    cpumMsrRd_Ia32VmxVmFunc,
     5046    cpumMsrRd_Ia32SpecCtrl,
     5047    cpumMsrRd_Ia32ArchCapabilities,
    50015048
    50025049    cpumMsrRd_Amd64Efer,
     
    52425289    cpumMsrWr_Ia32X2ApicN,
    52435290    cpumMsrWr_Ia32DebugInterface,
     5291    cpumMsrWr_Ia32SpecCtrl,
     5292    cpumMsrWr_Ia32PredCmd,
    52445293
    52455294    cpumMsrWr_Amd64Efer,
     
    57125761    CPUM_ASSERT_RD_MSR_FN(Ia32VmxTrueEntryCtls);
    57135762    CPUM_ASSERT_RD_MSR_FN(Ia32VmxVmFunc);
     5763    CPUM_ASSERT_RD_MSR_FN(Ia32SpecCtrl);
     5764    CPUM_ASSERT_RD_MSR_FN(Ia32ArchCapabilities);
    57145765
    57155766    CPUM_ASSERT_RD_MSR_FN(Amd64Efer);
     
    59445995    CPUM_ASSERT_WR_MSR_FN(Ia32X2ApicN);
    59455996    CPUM_ASSERT_WR_MSR_FN(Ia32DebugInterface);
     5997    CPUM_ASSERT_WR_MSR_FN(Ia32SpecCtrl);
     5998    CPUM_ASSERT_WR_MSR_FN(Ia32PredCmd);
    59465999
    59476000    CPUM_ASSERT_WR_MSR_FN(Amd64Efer);
  • trunk/src/VBox/VMM/VMMR3/CPUMR3CpuId.cpp

    r70846 r70913  
    31433143                               //| X86_CPUID_STEXT_FEATURE_ECX_PREFETCHWT1 - we do not do vector functions yet.
    31443144                               ;
    3145                 pCurLeaf->uEdx &= 0; /** @todo X86_CPUID_STEXT_FEATURE_EDX_IBRS_IBPB, X86_CPUID_STEXT_FEATURE_EDX_STIBP and X86_CPUID_STEXT_FEATURE_EDX_ARCHCAP */
     3145                pCurLeaf->uEdx &= 0
     3146                               //| X86_CPUID_STEXT_FEATURE_EDX_IBRS_IBPB         RT_BIT(26)
     3147                               //| X86_CPUID_STEXT_FEATURE_EDX_STIBP             RT_BIT(27)
     3148                               //| X86_CPUID_STEXT_FEATURE_EDX_ARCHCAP           RT_BIT(29)
     3149                               ;
    31463150
    31473151                /* Mask out INVPCID unless FSGSBASE is exposed due to a bug in Windows 10 SMP guests, see @bugref{9089#c15}. */
     
    31503154                {
    31513155                    pCurLeaf->uEbx &= ~X86_CPUID_STEXT_FEATURE_EBX_INVPCID;
    3152                     LogRel(("CPUM: Disabled INVPCID without FSGSBASE to workaround buggy guests\n"));
     3156                    LogRel(("CPUM: Disabled INVPCID without FSGSBASE to work around buggy guests\n"));
    31533157                }
    31543158
     
    43094313            CPUMR3SetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_NX);
    43104314
     4315        /* Check if speculation control is enabled. */
     4316        rc = CFGMR3QueryBoolDef(CFGMR3GetRoot(pVM), "EnableSpecCtrl", &fEnable, false);
     4317        AssertRCReturn(rc, rc);
     4318        if (fEnable)
     4319            CPUMR3SetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_SPEC_CTRL);
     4320
    43114321        return VINF_SUCCESS;
    43124322    }
     
    45894599            break;
    45904600
     4601        /*
     4602         * Set up the speculation control CPUID bits and MSRs. This is quite complicated
     4603         * on Intel CPUs, and different on AMDs.
     4604         */
     4605        case CPUMCPUIDFEATURE_SPEC_CTRL:
     4606            if (pVM->cpum.s.GuestFeatures.enmCpuVendor == CPUMCPUVENDOR_INTEL)
     4607            {
     4608                pLeaf = cpumR3CpuIdGetExactLeaf(&pVM->cpum.s, UINT32_C(0x00000007), 0);
     4609                if (   !pLeaf
     4610                    || !(pVM->cpum.s.HostFeatures.fIbpb || pVM->cpum.s.HostFeatures.fIbrs))
     4611                {
     4612                    LogRel(("CPUM: WARNING! Can't turn on Speculation Control when the host doesn't support it!\n"));
     4613                    return;
     4614                }
     4615
     4616                /* The feature can be enabled. Let's see what we can actually do. */
     4617                pVM->cpum.s.GuestFeatures.fSpeculationControl = 1;
     4618
     4619                /* We will only expose STIBP if IBRS is present to keep things simpler (simple is not an option). */
     4620                if (pVM->cpum.s.HostFeatures.fIbrs)
     4621                {
     4622                    pLeaf->uEdx |= X86_CPUID_STEXT_FEATURE_EDX_IBRS_IBPB;
     4623                    if (pVM->cpum.s.HostFeatures.fStibp)
     4624                        pLeaf->uEdx |= X86_CPUID_STEXT_FEATURE_EDX_STIBP;
     4625
     4626                    /* Make sure we have the speculation control MSR... */
     4627                    pMsrRange = cpumLookupMsrRange(pVM, MSR_IA32_SPEC_CTRL);
     4628                    if (!pMsrRange)
     4629                    {
     4630                        static CPUMMSRRANGE const s_SpecCtrl =
     4631                        {
     4632                            /*.uFirst =*/ MSR_IA32_SPEC_CTRL, /*.uLast =*/ MSR_IA32_SPEC_CTRL,
     4633                            /*.enmRdFn =*/ kCpumMsrRdFn_Ia32SpecCtrl, /*.enmWrFn =*/ kCpumMsrWrFn_Ia32SpecCtrl,
     4634                            /*.offCpumCpu =*/ UINT16_MAX, /*.fReserved =*/ 0, /*.uValue =*/ 0, /*.fWrIgnMask =*/ 0, /*.fWrGpMask =*/ 0,
     4635                            /*.szName = */ "IA32_SPEC_CTRL"
     4636                        };
     4637                        int rc = CPUMR3MsrRangesInsert(pVM, &s_SpecCtrl);
     4638                        AssertLogRelRC(rc);
     4639                    }
     4640
     4641                    /* ... and the predictor command MSR. */
     4642                    pMsrRange = cpumLookupMsrRange(pVM, MSR_IA32_PRED_CMD);
     4643                    if (!pMsrRange)
     4644                    {
     4645                        static CPUMMSRRANGE const s_SpecCtrl =
     4646                        {
     4647                            /*.uFirst =*/ MSR_IA32_PRED_CMD, /*.uLast =*/ MSR_IA32_PRED_CMD,
     4648                            /*.enmRdFn =*/ kCpumMsrRdFn_WriteOnly, /*.enmWrFn =*/ kCpumMsrWrFn_Ia32PredCmd,
     4649                            /*.offCpumCpu =*/ UINT16_MAX, /*.fReserved =*/ 0, /*.uValue =*/ 0, /*.fWrIgnMask =*/ 0, /*.fWrGpMask =*/ 0,
     4650                            /*.szName = */ "IA32_PRED_CMD"
     4651                        };
     4652                        int rc = CPUMR3MsrRangesInsert(pVM, &s_SpecCtrl);
     4653                        AssertLogRelRC(rc);
     4654                    }
     4655
     4656                }
     4657
     4658                if (pVM->cpum.s.HostFeatures.fArchCap) {
     4659                    pLeaf->uEdx |= X86_CPUID_STEXT_FEATURE_EDX_ARCHCAP;
     4660
     4661                    /* Install the architectural capabilities MSR. */
     4662                    pMsrRange = cpumLookupMsrRange(pVM, MSR_IA32_ARCH_CAPABILITIES);
     4663                    if (!pMsrRange)
     4664                    {
     4665                        static CPUMMSRRANGE const s_ArchCaps =
     4666                        {
     4667                            /*.uFirst =*/ MSR_IA32_ARCH_CAPABILITIES, /*.uLast =*/ MSR_IA32_ARCH_CAPABILITIES,
     4668                            /*.enmRdFn =*/ kCpumMsrRdFn_Ia32ArchCapabilities, /*.enmWrFn =*/ kCpumMsrWrFn_ReadOnly,
     4669                            /*.offCpumCpu =*/ UINT16_MAX, /*.fReserved =*/ 0, /*.uValue =*/ 0, /*.fWrIgnMask =*/ 0, /*.fWrGpMask =*/ UINT64_MAX,
     4670                            /*.szName = */ "IA32_ARCH_CAPABILITIES"
     4671                        };
     4672                        int rc = CPUMR3MsrRangesInsert(pVM, &s_ArchCaps);
     4673                        AssertLogRelRC(rc);
     4674                    }
     4675                }
     4676
     4677                LogRel(("CPUM: SetGuestCpuIdFeature: Enabled Speculation Control.\n"));
     4678            }
     4679            else if (pVM->cpum.s.GuestFeatures.enmCpuVendor == CPUMCPUVENDOR_AMD)
     4680            {
     4681                /* The precise details of AMD's implementation are not yet clear. */
     4682            }
     4683            break;
     4684
    45914685        default:
    45924686            AssertMsgFailed(("enmFeature=%d\n", enmFeature));
     
    46274721        case CPUMCPUIDFEATURE_HVP:          return pVM->cpum.s.GuestFeatures.fHypervisorPresent;
    46284722        case CPUMCPUIDFEATURE_MWAIT_EXTS:   return pVM->cpum.s.GuestFeatures.fMWaitExtensions;
     4723        case CPUMCPUIDFEATURE_SPEC_CTRL:    return pVM->cpum.s.GuestFeatures.fSpeculationControl;
    46294724
    46304725        case CPUMCPUIDFEATURE_INVALID:
     
    47374832            pVM->cpum.s.GuestFeatures.fMWaitExtensions = 0;
    47384833            Log(("CPUM: ClearGuestCpuIdFeature: Disabled MWAIT Extensions!\n"));
     4834            break;
     4835
     4836        case CPUMCPUIDFEATURE_SPEC_CTRL:
     4837            pLeaf = cpumR3CpuIdGetExactLeaf(&pVM->cpum.s, UINT32_C(0x00000007), 0);
     4838            if (pLeaf)
     4839                /*pVM->cpum.s.aGuestCpuIdPatmStd[7].uEdx =*/ pLeaf->uEdx &= ~(X86_CPUID_STEXT_FEATURE_EDX_IBRS_IBPB | X86_CPUID_STEXT_FEATURE_EDX_STIBP | X86_CPUID_STEXT_FEATURE_EDX_ARCHCAP);
     4840            pVM->cpum.s.GuestFeatures.fSpeculationControl = 0;
     4841            Log(("CPUM: ClearGuestCpuIdFeature: Disabled speculation control!\n"));
    47394842            break;
    47404843
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