VirtualBox

Ignore:
Timestamp:
Oct 12, 2009 3:01:05 PM (15 years ago)
Author:
vboxsync
Message:

Added SUP_IOCTL_VT_CAPS to get VT-x/AMD-V caps that can only be checked in kernel mode.

Location:
trunk/src/VBox/HostDrivers/Support
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/Support/SUPDrv.c

    r23610 r23699  
    5050#include <VBox/log.h>
    5151#include <VBox/err.h>
     52#include <VBox/hwacc_svm.h>
     53#include <VBox/hwacc_vmx.h>
    5254#if defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD)
    5355# include <iprt/crc32.h>
     
    17361738        }
    17371739
     1740        case SUP_CTL_CODE_NO_SIZE(SUP_IOCTL_VT_CAPS):
     1741        {
     1742            /* validate */
     1743            PSUPVTCAPS pReq = (PSUPVTCAPS)pReqHdr;
     1744            REQ_CHECK_SIZES(SUP_IOCTL_VT_CAPS);
     1745            REQ_CHECK_EXPR(SUP_IOCTL_VT_CAPS, pReq->Hdr.cbIn <= SUP_IOCTL_VT_CAPS_SIZE_IN);
     1746
     1747            /* execute */
     1748            pReq->Hdr.rc = SUPR0QueryVTCaps(pSession, &pReq->u.Out.Caps);
     1749            if (RT_FAILURE(pReq->Hdr.rc))
     1750                pReq->Hdr.cbOut = sizeof(pReq->Hdr);
     1751            return 0;
     1752        }
     1753
    17381754        default:
    17391755            Log(("Unknown IOCTL %#lx\n", (long)uIOCtl));
     
    36603676    SUPR0ObjRelease(pObj, pSession);
    36613677    return rc;
     3678}
     3679
     3680
     3681SUPR0DECL(int) SUPR0QueryVTCaps(PSUPDRVSESSION pSession, uint32_t *pCaps)
     3682{
     3683    /*
     3684     * Input validation.
     3685     */
     3686    AssertReturn(SUP_IS_SESSION_VALID(pSession), VERR_INVALID_PARAMETER);
     3687    AssertReturn(pCaps, VERR_INVALID_POINTER);
     3688
     3689    *pCaps = 0;
     3690
     3691    if (ASMHasCpuId())
     3692    {
     3693        uint32_t u32FeaturesECX;
     3694        uint32_t u32Dummy;
     3695        uint32_t u32FeaturesEDX;
     3696        uint32_t u32VendorEBX, u32VendorECX, u32VendorEDX, u32AMDFeatureEDX, u32AMDFeatureECX;
     3697        uint64_t val;
     3698
     3699        ASMCpuId(0, &u32Dummy, &u32VendorEBX, &u32VendorECX, &u32VendorEDX);
     3700        ASMCpuId(1, &u32Dummy, &u32Dummy, &u32FeaturesECX, &u32FeaturesEDX);
     3701        /* Query AMD features. */
     3702        ASMCpuId(0x80000001, &u32Dummy, &u32Dummy, &u32AMDFeatureECX, &u32AMDFeatureEDX);
     3703
     3704        if (    u32VendorEBX == X86_CPUID_VENDOR_INTEL_EBX
     3705            &&  u32VendorECX == X86_CPUID_VENDOR_INTEL_ECX
     3706            &&  u32VendorEDX == X86_CPUID_VENDOR_INTEL_EDX
     3707           )
     3708        {
     3709            if (    (u32FeaturesECX & X86_CPUID_FEATURE_ECX_VMX)
     3710                 && (u32FeaturesEDX & X86_CPUID_FEATURE_EDX_MSR)
     3711                 && (u32FeaturesEDX & X86_CPUID_FEATURE_EDX_FXSR)
     3712               )
     3713            {
     3714                val = ASMRdMsr(MSR_IA32_FEATURE_CONTROL);
     3715                /*
     3716                 * Both the LOCK and VMXON bit must be set; otherwise VMXON will generate a #GP.
     3717                 * Once the lock bit is set, this MSR can no longer be modified.
     3718                 */
     3719                if (   (val & (MSR_IA32_FEATURE_CONTROL_VMXON|MSR_IA32_FEATURE_CONTROL_LOCK))
     3720                           == (MSR_IA32_FEATURE_CONTROL_VMXON|MSR_IA32_FEATURE_CONTROL_LOCK) /* enabled and locked */
     3721                    ||  !(val & MSR_IA32_FEATURE_CONTROL_LOCK) /* not enabled, but not locked either */)
     3722                {
     3723                    VMX_CAPABILITY vtCaps;
     3724
     3725                    *pCaps |= SUPVTCAPS_VT_X;
     3726
     3727                    vtCaps.u = ASMRdMsr(MSR_IA32_VMX_PROCBASED_CTLS);
     3728                    if (vtCaps.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_USE_SECONDARY_EXEC_CTRL)
     3729                    {
     3730                        vtCaps.u = ASMRdMsr(MSR_IA32_VMX_PROCBASED_CTLS2);
     3731                        if (vtCaps.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC2_EPT)
     3732                            *pCaps |= SUPVTCAPS_NESTED_PAGING;
     3733                    }
     3734                    return VINF_SUCCESS;
     3735                }
     3736                else
     3737                    return VERR_VMX_MSR_LOCKED_OR_DISABLED;
     3738            }
     3739            else
     3740                return VERR_VMX_NO_VMX;
     3741        }
     3742        else
     3743        if (    u32VendorEBX == X86_CPUID_VENDOR_AMD_EBX
     3744            &&  u32VendorECX == X86_CPUID_VENDOR_AMD_ECX
     3745            &&  u32VendorEDX == X86_CPUID_VENDOR_AMD_EDX
     3746           )
     3747        {
     3748            if (   (u32AMDFeatureECX & X86_CPUID_AMD_FEATURE_ECX_SVM)
     3749                && (u32FeaturesEDX & X86_CPUID_FEATURE_EDX_MSR)
     3750                && (u32FeaturesEDX & X86_CPUID_FEATURE_EDX_FXSR)
     3751               )
     3752            {
     3753                /* Check if SVM is disabled */
     3754                val = ASMRdMsr(MSR_K8_VM_CR);
     3755                if (!(val & MSR_K8_VM_CR_SVM_DISABLE))
     3756                {
     3757                    *pCaps |= SUPVTCAPS_AMD_V;
     3758
     3759                    /* Query AMD features. */
     3760                    ASMCpuId(0x8000000A, &u32Dummy, &u32Dummy, &u32Dummy, &u32FeaturesEDX);
     3761
     3762                    if (u32FeaturesEDX & AMD_CPUID_SVM_FEATURE_EDX_NESTED_PAGING)
     3763                        *pCaps |= SUPVTCAPS_NESTED_PAGING;
     3764
     3765                    return VINF_SUCCESS;
     3766                }
     3767                else
     3768                    return VERR_SVM_DISABLED;
     3769            }
     3770            else
     3771                return VERR_SVM_NO_SVM;
     3772        }
     3773    }
     3774    return VERR_UNSUPPORTED_CPU;
    36623775}
    36633776
  • trunk/src/VBox/HostDrivers/Support/SUPDrvIOC.h

    r23610 r23699  
    197197 *          - Nothing.
    198198 */
    199 #define SUPDRV_IOC_VERSION                              0x00100000
     199#define SUPDRV_IOC_VERSION                              0x00100001
    200200
    201201/** SUP_IOCTL_COOKIE. */
     
    10801080/** @} */
    10811081
     1082/** @name SUP_IOCTL_VT_CAPS Input.
     1083 * @{
     1084 */
     1085/** Free contious memory. */
     1086#define SUP_IOCTL_VT_CAPS                               SUP_CTL_CODE_SIZE(26, SUP_IOCTL_VT_CAPS_SIZE)
     1087#define SUP_IOCTL_VT_CAPS_SIZE                          sizeof(SUPVTCAPS)
     1088#define SUP_IOCTL_VT_CAPS_SIZE_IN                       sizeof(SUPREQHDR)
     1089#define SUP_IOCTL_VT_CAPS_SIZE_OUT                      sizeof(SUPVTCAPS)
     1090typedef struct SUPVTCAPS
     1091{
     1092    /** The header. */
     1093    SUPREQHDR               Hdr;
     1094    union
     1095    {
     1096        struct
     1097        {
     1098            /** The VT capability dword. */
     1099            uint32_t        Caps;
     1100        } Out;
     1101    } u;
     1102} SUPVTCAPS, *PSUPVTCAPS;
     1103/** @} */
    10821104
    10831105#pragma pack()                          /* paranoia */
  • trunk/src/VBox/HostDrivers/Support/SUPLib.cpp

    r23610 r23699  
    272272        strcpy(CookieReq.u.In.szMagic, SUPCOOKIE_MAGIC);
    273273        CookieReq.u.In.u32ReqVersion = SUPDRV_IOC_VERSION;
    274         const uint32_t uMinVersion = (SUPDRV_IOC_VERSION & 0xffff0000) == 0x00100000
    275                                    ?  0x00100000
     274        const uint32_t uMinVersion = (SUPDRV_IOC_VERSION & 0xffff0000) == 0x00100001
     275                                   ?  0x00100001
    276276                                   :  SUPDRV_IOC_VERSION & 0xffff0000;
    277277        CookieReq.u.In.u32MinVersion = uMinVersion;
     
    20652065#endif
    20662066}
     2067
     2068SUPR3DECL(int) SUPR3QueryVTCaps(uint32_t *pCaps)
     2069{
     2070    AssertPtrReturn(pCaps, VERR_INVALID_POINTER);
     2071
     2072    *pCaps = 0;
     2073
     2074    /* fake */
     2075    if (RT_UNLIKELY(g_u32FakeMode))
     2076        return VINF_SUCCESS;
     2077
     2078    /*
     2079     * Issue IOCtl to the SUPDRV kernel module.
     2080     */
     2081    SUPVTCAPS Req;
     2082    Req.Hdr.u32Cookie = g_u32Cookie;
     2083    Req.Hdr.u32SessionCookie = g_u32SessionCookie;
     2084    Req.Hdr.cbIn = SUP_IOCTL_VT_CAPS_SIZE_IN;
     2085    Req.Hdr.cbOut = SUP_IOCTL_VT_CAPS_SIZE_OUT;
     2086    Req.Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT;
     2087    Req.Hdr.rc = VERR_INTERNAL_ERROR;
     2088    Req.u.Out.Caps = 0;
     2089    int rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_VT_CAPS, &Req, SUP_IOCTL_VT_CAPS_SIZE);
     2090    if (RT_SUCCESS(rc))
     2091    {
     2092        rc = Req.Hdr.rc;
     2093        if (RT_SUCCESS(rc)
     2094            *pCaps = Req.u.Out.Caps;
     2095    }
     2096    return rc;
     2097}
     2098
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