VirtualBox

Changeset 76461 in vbox


Ignore:
Timestamp:
Dec 25, 2018 4:28:45 AM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
127762
Message:

SUPDrv: Added an ioctl for fetching hardware-virtualization MSRs.

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/sup.h

    r76389 r76461  
    2929#include <VBox/cdefs.h>
    3030#include <VBox/types.h>
     31#include <VBox/vmm/hm_vmx.h>
     32#include <VBox/vmm/hm_svm.h>
    3133#include <iprt/assert.h>
    3234#include <iprt/stdarg.h>
     
    106108#define SUPKERNELFEATURES_GDT_NEED_WRITABLE   RT_BIT(2)
    107109/** @} */
     110
     111
     112/**
     113 * Hardware-virtualization MSRs.
     114 */
     115typedef struct SUPHWVIRTMSRS
     116{
     117    union
     118    {
     119        VMXMSRS     vmx;
     120        SVMMSRS     svm;
     121    } u ;
     122} SUPHWVIRTMSRS;
     123AssertCompileSize(SUPHWVIRTMSRS, 224);
     124/** Pointer to a hardware-virtualization MSRs struct. */
     125typedef SUPHWVIRTMSRS *PSUPHWVIRTMSRS;
     126/** Pointer to a hardware-virtualization MSRs struct. */
     127typedef const SUPHWVIRTMSRS *PCSUPHWVIRTMSRS;
    108128
    109129
     
    18371857SUPR3DECL(int) SUPR3QueryMicrocodeRev(uint32_t *puMicrocodeRev);
    18381858
     1859/**
     1860 * Gets hardware-virtualization MSRs of the CPU, if available.
     1861 *
     1862 * @returns VINF_SUCCESS if available, error code indicating why if not.
     1863 * @param   pHwvirtMsrs     Where to store the hardware-virtualization MSRs.
     1864 * @param   fForceRequery   Whether to force complete re-querying of MSRs (rather
     1865 *                          than fetching cached values when available).
     1866 */
     1867SUPR3DECL(int) SUPR3GetHwvirtMsrs(PSUPHWVIRTMSRS pHwvirtMsrs, bool fForceRequery);
     1868
    18391869/** @} */
    18401870#endif /* IN_RING3 */
     
    19191949SUPR0DECL(int) SUPR0GipMap(PSUPDRVSESSION pSession, PRTR3PTR ppGipR3, PRTHCPHYS pHCPhysGip);
    19201950SUPR0DECL(int) SUPR0GetVTSupport(uint32_t *pfCaps);
     1951SUPR0DECL(int) SUPR0GetHwvirtMsrs(PSUPHWVIRTMSRS pMsrs, uint32_t fCaps, bool fForce);
    19211952SUPR0DECL(int) SUPR0GetSvmUsability(bool fInitSvm);
    19221953SUPR0DECL(int) SUPR0GetVmxUsability(bool *pfIsSmxModeAmbiguous);
  • trunk/src/VBox/HostDrivers/Support/SUPDrv.cpp

    r76227 r76461  
    201201    { "SUPR0GetCurrentGdtRw",                   (void *)(uintptr_t)SUPR0GetCurrentGdtRw },
    202202    { "SUPR0GetKernelFeatures",                 (void *)(uintptr_t)SUPR0GetKernelFeatures },
     203    { "SUPR0GetHwvirtMsrs",                     (void *)(uintptr_t)SUPR0GetHwvirtMsrs },
    203204    { "SUPR0GetPagingMode",                     (void *)(uintptr_t)SUPR0GetPagingMode },
    204205    { "SUPR0GetSvmUsability",                   (void *)(uintptr_t)SUPR0GetSvmUsability },
     
    488489#endif  /* RT_OS_DARWIN || RT_OS_SOLARIS || RT_OS_SOLARIS */
    489490
     491/** Hardware-virtualization MSRs. */
     492static SUPHWVIRTMSRS            g_HwvirtMsrs;
     493/** Whether the hardware-virtualization MSRs are cached. */
     494static bool                     g_fHwvirtMsrsCached;
     495
    490496
    491497/**
     
    24052411        }
    24062412
     2413        case SUP_CTL_CODE_NO_SIZE(SUP_IOCTL_GET_HWVIRT_MSRS):
     2414        {
     2415            /* validate */
     2416            PSUPGETHWVIRTMSRS pReq = (PSUPGETHWVIRTMSRS)pReqHdr;
     2417            REQ_CHECK_SIZES(SUP_IOCTL_GET_HWVIRT_MSRS);
     2418            REQ_CHECK_EXPR_FMT(!pReq->u.In.fReserved0 && !pReq->u.In.fReserved1 && !pReq->u.In.fReserved2,
     2419                               ("SUP_IOCTL_GET_HWVIRT_MSRS: fReserved0=%d fReserved1=%d fReserved2=%d\n", pReq->u.In.fReserved0,
     2420                                pReq->u.In.fReserved1, pReq->u.In.fReserved2));
     2421
     2422            /* execute */
     2423            pReq->Hdr.rc = SUPR0GetHwvirtMsrs(&pReq->u.Out.HwvirtMsrs, 0 /* fCaps */, pReq->u.In.fForce);
     2424            if (RT_FAILURE(pReq->Hdr.rc))
     2425                pReq->Hdr.cbOut = sizeof(pReq->Hdr);
     2426            return 0;
     2427        }
     2428
    24072429        default:
    24082430            Log(("Unknown IOCTL %#lx\n", (long)uIOCtl));
     
    45424564     */
    45434565    return supdrvQueryUcodeRev(puRevision);
     4566}
     4567
     4568
     4569/**
     4570 * Gets hardware-virtualization MSRs of the calling CPU.
     4571 *
     4572 * @returns VBox status code.
     4573 * @param   pMsrs       Where to store the hardware-virtualization MSRs.
     4574 * @param   fCaps       Hardware virtualization capabilities (SUPVTCAPS_XXX). Pass 0
     4575 *                      to explicitly check for the presence of VT-x/AMD-V before
     4576 *                      querying MSRs.
     4577 * @param   fForce      Force querying of MSRs from the hardware.
     4578 */
     4579SUPR0DECL(int) SUPR0GetHwvirtMsrs(PSUPHWVIRTMSRS pMsrs, uint32_t fCaps, bool fForce)
     4580{
     4581    int rc;
     4582    RTTHREADPREEMPTSTATE PreemptState = RTTHREADPREEMPTSTATE_INITIALIZER;
     4583
     4584    /*
     4585     * Input validation.
     4586     */
     4587    AssertPtrReturn(pMsrs, VERR_INVALID_POINTER);
     4588
     4589    /*
     4590     * Disable preemption so we make sure we don't migrate CPUs and because
     4591     * we access global data.
     4592     */
     4593    RTThreadPreemptDisable(&PreemptState);
     4594
     4595    /*
     4596     * Querying MSRs from hardware can be expensive (exponentially more so
     4597     * in a nested-virtualization scenario if they happen to cause VM-exits).
     4598     *
     4599     * So, if the caller does not force re-querying of MSRs and we have them
     4600     * already cached, simply copy the cached MSRs and we're done.
     4601     */
     4602    if (   !fForce
     4603        && g_fHwvirtMsrsCached)
     4604    {
     4605        memcpy(pMsrs, &g_HwvirtMsrs, sizeof(*pMsrs));
     4606        RTThreadPreemptRestore(&PreemptState);
     4607        return VINF_SUCCESS;
     4608    }
     4609
     4610    /*
     4611     * Query the MSRs from hardware, since it's either the first call since
     4612     * driver load or the caller has forced re-querying of the MSRs.
     4613     */
     4614    RT_ZERO(*pMsrs);
     4615
     4616    /* If the caller claims VT-x/AMD-V is supported, don't need to recheck it. */
     4617    if (!(fCaps & (SUPVTCAPS_VT_X | SUPVTCAPS_AMD_V)))
     4618        rc = SUPR0GetVTSupport(&fCaps);
     4619    else
     4620        rc = VINF_SUCCESS;
     4621    if (RT_SUCCESS(rc))
     4622    {
     4623        if (fCaps & SUPVTCAPS_VT_X)
     4624        {
     4625            g_HwvirtMsrs.u.vmx.u64FeatCtrl  = ASMRdMsr(MSR_IA32_FEATURE_CONTROL);
     4626            g_HwvirtMsrs.u.vmx.u64Basic     = ASMRdMsr(MSR_IA32_VMX_BASIC);
     4627            g_HwvirtMsrs.u.vmx.PinCtls.u    = ASMRdMsr(MSR_IA32_VMX_PINBASED_CTLS);
     4628            g_HwvirtMsrs.u.vmx.ProcCtls.u   = ASMRdMsr(MSR_IA32_VMX_PROCBASED_CTLS);
     4629            g_HwvirtMsrs.u.vmx.ExitCtls.u   = ASMRdMsr(MSR_IA32_VMX_EXIT_CTLS);
     4630            g_HwvirtMsrs.u.vmx.EntryCtls.u  = ASMRdMsr(MSR_IA32_VMX_ENTRY_CTLS);
     4631            g_HwvirtMsrs.u.vmx.u64Misc      = ASMRdMsr(MSR_IA32_VMX_MISC);
     4632            g_HwvirtMsrs.u.vmx.u64Cr0Fixed0 = ASMRdMsr(MSR_IA32_VMX_CR0_FIXED0);
     4633            g_HwvirtMsrs.u.vmx.u64Cr0Fixed1 = ASMRdMsr(MSR_IA32_VMX_CR0_FIXED1);
     4634            g_HwvirtMsrs.u.vmx.u64Cr4Fixed0 = ASMRdMsr(MSR_IA32_VMX_CR4_FIXED0);
     4635            g_HwvirtMsrs.u.vmx.u64Cr4Fixed1 = ASMRdMsr(MSR_IA32_VMX_CR4_FIXED1);
     4636            g_HwvirtMsrs.u.vmx.u64VmcsEnum  = ASMRdMsr(MSR_IA32_VMX_VMCS_ENUM);
     4637
     4638            if (RT_BF_GET(g_HwvirtMsrs.u.vmx.u64Basic, VMX_BF_BASIC_TRUE_CTLS))
     4639            {
     4640                g_HwvirtMsrs.u.vmx.TruePinCtls.u   = ASMRdMsr(MSR_IA32_VMX_TRUE_PINBASED_CTLS);
     4641                g_HwvirtMsrs.u.vmx.TrueProcCtls.u  = ASMRdMsr(MSR_IA32_VMX_TRUE_PROCBASED_CTLS);
     4642                g_HwvirtMsrs.u.vmx.TrueEntryCtls.u = ASMRdMsr(MSR_IA32_VMX_TRUE_ENTRY_CTLS);
     4643                g_HwvirtMsrs.u.vmx.TrueExitCtls.u  = ASMRdMsr(MSR_IA32_VMX_TRUE_EXIT_CTLS);
     4644            }
     4645
     4646            uint32_t const fProcCtlsAllowed1 = g_HwvirtMsrs.u.vmx.ProcCtls.n.allowed1;
     4647            if (fProcCtlsAllowed1 & VMX_PROC_CTLS_USE_SECONDARY_CTLS)
     4648            {
     4649                g_HwvirtMsrs.u.vmx.ProcCtls2.u = ASMRdMsr(MSR_IA32_VMX_PROCBASED_CTLS2);
     4650
     4651                uint32_t const fProcCtls2Allowed1 = g_HwvirtMsrs.u.vmx.ProcCtls2.n.allowed1;
     4652                if (fProcCtls2Allowed1 & (VMX_PROC_CTLS2_EPT | VMX_PROC_CTLS2_VPID))
     4653                    g_HwvirtMsrs.u.vmx.u64EptVpidCaps = ASMRdMsr(MSR_IA32_VMX_EPT_VPID_CAP);
     4654
     4655                if (fProcCtls2Allowed1 & VMX_PROC_CTLS2_VMFUNC)
     4656                    g_HwvirtMsrs.u.vmx.u64VmFunc = ASMRdMsr(MSR_IA32_VMX_VMFUNC);
     4657            }
     4658            g_fHwvirtMsrsCached = true;
     4659        }
     4660        else if (fCaps & SUPVTCAPS_AMD_V)
     4661        {
     4662            g_HwvirtMsrs.u.svm.u64MsrHwcr = ASMRdMsr(MSR_K8_HWCR);
     4663            g_fHwvirtMsrsCached = true;
     4664        }
     4665        else
     4666        {
     4667            RTThreadPreemptRestore(&PreemptState);
     4668            AssertMsgFailedReturn(("SUPR0GetVTSupport returns success but neither VT-x nor AMD-V reported!\n"),
     4669                                  VERR_INTERNAL_ERROR_2);
     4670        }
     4671
     4672        /*
     4673         * We have successfully populated the cache, copy the MSRs to the caller.
     4674         */
     4675        memcpy(pMsrs, &g_HwvirtMsrs, sizeof(*pMsrs));
     4676    }
     4677
     4678    RTThreadPreemptRestore(&PreemptState);
     4679
     4680    return rc;
    45444681}
    45454682
  • trunk/src/VBox/HostDrivers/Support/SUPDrvIOC.h

    r76281 r76461  
    224224 * @remarks 0x002a0000 is used by 5.1. The next version number must be 0x002b0000.
    225225 */
    226 #define SUPDRV_IOC_VERSION                              0x00290007
     226#define SUPDRV_IOC_VERSION                              0x00290008
    227227
    228228/** SUP_IOCTL_COOKIE. */
     
    16321632
    16331633
     1634/** @name SUP_IOCTL_HWVIRT_MSRS
     1635 * Get hardware-virtualization MSRs.
     1636 *
     1637 * This queries a lot more information than merely VT-x/AMD-V basic capabilities
     1638 * provided by SUP_IOCTL_VT_CAPS.
     1639 */
     1640#define SUP_IOCTL_GET_HWVIRT_MSRS                       SUP_CTL_CODE_SIZE(41, SUP_IOCTL_GET_HWVIRT_MSRS_SIZE)
     1641#define SUP_IOCTL_GET_HWVIRT_MSRS_SIZE                  sizeof(SUPGETHWVIRTMSRS)
     1642#define SUP_IOCTL_GET_HWVIRT_MSRS_SIZE_IN               (sizeof(SUPREQHDR) + RT_SIZEOFMEMB(SUPGETHWVIRTMSRS, u.In))
     1643#define SUP_IOCTL_GET_HWVIRT_MSRS_SIZE_OUT              sizeof(SUPGETHWVIRTMSRS)
     1644
     1645typedef struct SUPGETHWVIRTMSRS
     1646{
     1647    /** The header. */
     1648    SUPREQHDR               Hdr;
     1649    union
     1650    {
     1651        struct
     1652        {
     1653            /** Whether to force re-querying of MSRs. */
     1654            bool                fForce;
     1655            /** Reserved. Must be false. */
     1656            bool                fReserved0;
     1657            /** Reserved. Must be false. */
     1658            bool                fReserved1;
     1659            /** Reserved. Must be false. */
     1660            bool                fReserved2;
     1661        } In;
     1662
     1663        struct
     1664        {
     1665            /** Hardware-virtualization MSRs. */
     1666            SUPHWVIRTMSRS      HwvirtMsrs;
     1667        } Out;
     1668    } u;
     1669} SUPGETHWVIRTMSRS, *PSUPGETHWVIRTMSRS;
     1670/** @} */
     1671
     1672
    16341673#pragma pack()                          /* paranoia */
    16351674
  • trunk/src/VBox/HostDrivers/Support/SUPLib.cpp

    r76257 r76461  
    277277        CookieReq.u.In.u32ReqVersion = SUPDRV_IOC_VERSION;
    278278        const uint32_t uMinVersion = (SUPDRV_IOC_VERSION & 0xffff0000) == 0x00290000
    279                                    ? 0x00290007
     279                                   ? 0x00290008
    280280                                   : SUPDRV_IOC_VERSION & 0xffff0000;
    281281        CookieReq.u.In.u32MinVersion = uMinVersion;
     
    23342334}
    23352335
     2336
     2337SUPR3DECL(int) SUPR3GetHwvirtMsrs(PSUPHWVIRTMSRS pHwvirtMsrs, bool fForceRequery)
     2338{
     2339    AssertReturn(pHwvirtMsrs, VERR_INVALID_PARAMETER);
     2340
     2341    SUPGETHWVIRTMSRS Req;
     2342    Req.Hdr.u32Cookie        = g_u32Cookie;
     2343    Req.Hdr.u32SessionCookie = g_u32SessionCookie;
     2344    Req.Hdr.cbIn             = SUP_IOCTL_GET_HWVIRT_MSRS_SIZE_IN;
     2345    Req.Hdr.cbOut            = SUP_IOCTL_GET_HWVIRT_MSRS_SIZE_OUT;
     2346    Req.Hdr.fFlags           = SUPREQHDR_FLAGS_DEFAULT;
     2347    Req.Hdr.rc               = VERR_INTERNAL_ERROR;
     2348
     2349    Req.u.In.fForce          = fForceRequery;
     2350    Req.u.In.fReserved0      = false;
     2351    Req.u.In.fReserved1      = false;
     2352    Req.u.In.fReserved2      = false;
     2353
     2354    int rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_GET_HWVIRT_MSRS, &Req, SUP_IOCTL_GET_HWVIRT_MSRS_SIZE);
     2355    if (RT_SUCCESS(rc))
     2356    {
     2357        rc = Req.Hdr.rc;
     2358        *pHwvirtMsrs = Req.u.Out.HwvirtMsrs;
     2359    }
     2360    else
     2361        RT_ZERO(*pHwvirtMsrs);
     2362    return rc;
     2363}
     2364
Note: See TracChangeset for help on using the changeset viewer.

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