Example #1
0
static HWVIRTTYPE isHwVirtSupported(void)
{
#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
    uint32_t uEax, uEbx, uEcx, uEdx;

    /* VT-x */
    ASMCpuId(0x00000000, &uEax, &uEbx, &uEcx, &uEdx);
    if (ASMIsValidStdRange(uEax))
    {
        ASMCpuId(0x00000001, &uEax, &uEbx, &uEcx, &uEdx);
        if (uEcx & X86_CPUID_FEATURE_ECX_VMX)
            return HWVIRTTYPE_VTX;
    }

    /* AMD-V */
    ASMCpuId(0x80000000, &uEax, &uEbx, &uEcx, &uEdx);
    if (ASMIsValidExtRange(uEax))
    {
        ASMCpuId(0x80000001, &uEax, &uEbx, &uEcx, &uEdx);
        if (uEcx & X86_CPUID_AMD_FEATURE_ECX_SVM)
            return HWVIRTTYPE_AMDV;
    }
#endif

    return HWVIRTTYPE_NONE;
}
Example #2
0
/** Print the 'true' if nested paging is supported, 'false' if not and
 * 'dunno' if we cannot tell. */
static RTEXITCODE handlerCpuNestedPaging(int argc, char **argv)
{
    NOREF(argc); NOREF(argv);
    HWVIRTTYPE  enmHwVirt  = isHwVirtSupported();
    int         fSupported = -1;

#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
    if (enmHwVirt == HWVIRTTYPE_AMDV)
    {
        uint32_t uEax, uEbx, uEcx, uEdx;
        ASMCpuId(0x80000000, &uEax, &uEbx, &uEcx, &uEdx);
        if (ASMIsValidExtRange(uEax) && uEax >= 0x8000000a)
        {
            ASMCpuId(0x8000000a, &uEax, &uEbx, &uEcx, &uEdx);
            if (uEdx & RT_BIT(0) /* AMD_CPUID_SVM_FEATURE_EDX_NESTED_PAGING */)
                fSupported = 1;
            else
                fSupported = 0;
        }
    }
#endif

    int cch = RTPrintf(fSupported == 1 ? "true\n" : fSupported == 0 ? "false\n" : "dunno\n");
    return cch > 0 ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
}
Example #3
0
/** Print the 'true' if long mode guests are supported, 'false' if not and
 * 'dunno' if we cannot tell. */
static RTEXITCODE handlerCpuLongMode(int argc, char **argv)
{
    NOREF(argc); NOREF(argv);
    HWVIRTTYPE  enmHwVirt  = isHwVirtSupported();
    int         fSupported = 0;

    if (enmHwVirt != HWVIRTTYPE_NONE)
    {
#if defined(RT_ARCH_AMD64)
        fSupported = 1; /* We're running long mode, so it must be supported. */

#elif defined(RT_ARCH_X86)
# ifdef RT_OS_DARWIN
        /* On darwin, we just ask the kernel via sysctl. Rules are a bit different here. */
        int     f64bitCapable = 0;
        size_t  cbParameter   = sizeof(f64bitCapable);
        int rc = sysctlbyname("hw.cpu64bit_capable", &f64bitCapable, &cbParameter, NULL, NULL);
        if (rc != -1)
            fSupported = f64bitCapable != 0;
        else
# endif
        {
            /* PAE and HwVirt are required */
            uint32_t uEax, uEbx, uEcx, uEdx;
            ASMCpuId(0x00000000, &uEax, &uEbx, &uEcx, &uEdx);
            if (ASMIsValidStdRange(uEax))
            {
                ASMCpuId(0x00000001, &uEax, &uEbx, &uEcx, &uEdx);
                if (uEdx & X86_CPUID_FEATURE_EDX_PAE)
                {
                    /* AMD will usually advertise long mode in 32-bit mode. Intel OTOH,
                       won't necessarily do so. */
                    ASMCpuId(0x80000000, &uEax, &uEbx, &uEcx, &uEdx);
                    if (ASMIsValidExtRange(uEax))
                    {
                        ASMCpuId(0x80000001, &uEax, &uEbx, &uEcx, &uEdx);
                        if (uEdx & X86_CPUID_EXT_FEATURE_EDX_LONG_MODE)
                            fSupported = 1;
                        else if (enmHwVirt != HWVIRTTYPE_AMDV)
                            fSupported = -1;
                    }
                }
            }
        }
#endif
    }

    int cch = RTPrintf(fSupported == 1 ? "true\n" : fSupported == 0 ? "false\n" : "dunno\n");
    return cch > 0 ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
}
Example #4
0
/** Print the 'true' if nested paging is supported, 'false' if not and
 * 'dunno' if we cannot tell. */
static RTEXITCODE handlerCpuNestedPaging(int argc, char **argv)
{
    NOREF(argc); NOREF(argv);
    HWVIRTTYPE  enmHwVirt  = isHwVirtSupported();
    int         fSupported = -1;

#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
    if (enmHwVirt == HWVIRTTYPE_AMDV)
    {
        uint32_t uEax, uEbx, uEcx, uEdx;
        ASMCpuId(0x80000000, &uEax, &uEbx, &uEcx, &uEdx);
        if (ASMIsValidExtRange(uEax) && uEax >= 0x8000000a)
        {
            ASMCpuId(0x8000000a, &uEax, &uEbx, &uEcx, &uEdx);
            if (uEdx & RT_BIT(0) /* AMD_CPUID_SVM_FEATURE_EDX_NESTED_PAGING */)
                fSupported = 1;
            else
                fSupported = 0;
        }
    }
# if defined(RT_OS_LINUX)
    else if (enmHwVirt == HWVIRTTYPE_VTX)
    {
        /*
         * For Intel there is no generic way to query EPT support but on
         * Linux we can resort to checking for the EPT flag in /proc/cpuinfo
         */
        RTFILE hFileCpu;
        int rc = RTFileOpen(&hFileCpu, "/proc/cpuinfo", RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE);
        if (RT_SUCCESS(rc))
        {
            /*
             * Read enough to fit the first CPU entry in, we only check the first
             * CPU as all the others should have the same features.
             */
            char szBuf[_4K];
            size_t cbRead = 0;

            RT_ZERO(szBuf); /* Ensure proper termination. */
            rc = RTFileRead(hFileCpu, &szBuf[0], sizeof(szBuf) - 1, &cbRead);
            if (RT_SUCCESS(rc))
            {
                /* Look for the start of the flags section. */
                char *pszStrFlags = RTStrStr(&szBuf[0], "flags");
                if (pszStrFlags)
                {
                    /* Look for the end as indicated by new line. */
                    char *pszEnd = pszStrFlags;
                    while (   *pszEnd != '\0'
                           && *pszEnd != '\n')
                        pszEnd++;
                    *pszEnd = '\0'; /* Cut off everything after the flags section. */

                    /*
                     * Search for the ept flag indicating support and the absence meaning
                     * not supported.
                     */
                    if (RTStrStr(pszStrFlags, "ept"))
                        fSupported = 1;
                    else
                        fSupported = 0;
                }
            }
            RTFileClose(hFileCpu);
        }
    }
# endif
#endif

    int cch = RTPrintf(fSupported == 1 ? "true\n" : fSupported == 0 ? "false\n" : "dunno\n");
    return cch > 0 ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
}