VirtualBox

Changeset 44174 in vbox


Ignore:
Timestamp:
Dec 19, 2012 6:14:39 PM (12 years ago)
Author:
vboxsync
Message:

HostImpl.cpp / Host::GetProcessorFeature: Finally use /dev/vboxdrvu to get reliable VT-x/AMD-V info (nested paging, enabled in bios).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-server/HostImpl.cpp

    r44091 r44174  
    200200    VBoxMainDriveInfo       hostDrives;
    201201#endif
    202     /* Features that can be queried with GetProcessorFeature */
    203     BOOL                    fVTSupported,
     202    /** @name Features that can be queried with GetProcessorFeature.
     203     * @{ */
     204    bool                    fVTSupported,
    204205                            fLongModeSupported,
    205206                            fPAESupported,
    206                             fNestedPagingSupported;
     207                            fNestedPagingSupported,
     208                            fRecheckVTSupported;
     209
     210    /** @}  */
    207211
    208212    /* 3D hardware acceleration supported? */
     
    290294    m->fPAESupported = false;
    291295    m->fNestedPagingSupported = false;
     296    m->fRecheckVTSupported = false;
    292297
    293298    if (ASMHasCpuId())
    294299    {
    295         uint32_t u32FeaturesECX;
    296         uint32_t u32Dummy;
    297         uint32_t u32FeaturesEDX;
    298         uint32_t u32VendorEBX, u32VendorECX, u32VendorEDX, u32ExtFeatureEDX, u32ExtFeatureECX;
    299 
    300         ASMCpuId(0, &u32Dummy, &u32VendorEBX, &u32VendorECX, &u32VendorEDX);
    301         ASMCpuId(1, &u32Dummy, &u32Dummy, &u32FeaturesECX, &u32FeaturesEDX);
    302         /* Query Extended features. */
    303         ASMCpuId(0x80000001, &u32Dummy, &u32Dummy, &u32ExtFeatureECX, &u32ExtFeatureEDX);
    304 
    305         m->fLongModeSupported = !!(u32ExtFeatureEDX & X86_CPUID_EXT_FEATURE_EDX_LONG_MODE);
    306         m->fPAESupported      = !!(u32FeaturesEDX & X86_CPUID_FEATURE_EDX_PAE);
    307 
    308         if (    u32VendorEBX == X86_CPUID_VENDOR_INTEL_EBX
    309             &&  u32VendorECX == X86_CPUID_VENDOR_INTEL_ECX
    310             &&  u32VendorEDX == X86_CPUID_VENDOR_INTEL_EDX
    311            )
    312         {
    313             /* Intel. */
    314             if (    (u32FeaturesECX & X86_CPUID_FEATURE_ECX_VMX)
    315                  && (u32FeaturesEDX & X86_CPUID_FEATURE_EDX_MSR)
    316                  && (u32FeaturesEDX & X86_CPUID_FEATURE_EDX_FXSR)
    317                )
    318             {
    319                 int rc = SUPR3QueryVTxSupported();
    320                 if (RT_SUCCESS(rc))
     300        /* Note! This code is duplicated in SUPDrv.c and other places! */
     301        uint32_t uMaxId, uVendorEBX, uVendorECX, uVendorEDX;
     302        ASMCpuId(0, &uMaxId, &uVendorEBX, &uVendorECX, &uVendorEDX);
     303        if (ASMIsValidStdRange(uMaxId))
     304        {
     305            /* PAE? */
     306            uint32_t uDummy, fFeaturesEcx, fFeaturesEdx;
     307            ASMCpuId(1, &uDummy, &uDummy, &fFeaturesEcx, &fFeaturesEdx);
     308            m->fPAESupported = RT_BOOL(fFeaturesEdx & X86_CPUID_FEATURE_EDX_PAE);
     309
     310            /* Long Mode? */
     311            uint32_t uExtMaxId, fExtFeaturesEcx, fExtFeaturesEdx;
     312            ASMCpuId(0x80000000, &uExtMaxId, &uDummy, &uDummy, &uDummy);
     313            ASMCpuId(0x80000001, &uDummy, &uDummy, &fExtFeaturesEcx, &fExtFeaturesEdx);
     314            m->fLongModeSupported = ASMIsValidExtRange(uExtMaxId)
     315                                 && (u32ExtFeatureEDX & X86_CPUID_EXT_FEATURE_EDX_LONG_MODE);
     316
     317            /* VT-x? */
     318            if (   ASMIsIntelCpuEx(uVendorEBX, uVendorECX, uVendorEDX)
     319                || ASMIsViaCentaurCpuEx(uVendorEBX, uVendorECX, uVendorEDX))
     320            {
     321                if (    (fFeaturesEcx & X86_CPUID_FEATURE_ECX_VMX)
     322                     && (fFeaturesEdx & X86_CPUID_FEATURE_EDX_MSR)
     323                     && (fFeaturesEdx & X86_CPUID_FEATURE_EDX_FXSR)
     324                   )
     325                {
     326                    int rc = SUPR3QueryVTxSupported();
     327                    if (RT_SUCCESS(rc))
     328                        m->fVTSupported = true;
     329                }
     330            }
     331            /* AMD-V */
     332            else if (ASMIsAmdCpuEx(uVendorEBX, uVendorECX, uVendorEDX))
     333            {
     334                if (   (fExtFeaturesEcx & X86_CPUID_AMD_FEATURE_ECX_SVM)
     335                    && (fFeaturesEdx    & X86_CPUID_FEATURE_EDX_MSR)
     336                    && (fFeaturesEdx    & X86_CPUID_FEATURE_EDX_FXSR)
     337                    && ASMIsValidExtRange(uExtMaxId)
     338                   )
     339                {
    321340                    m->fVTSupported = true;
     341
     342                    /* Query AMD features. */
     343                    if (uExtMaxId >= 0x8000000a)
     344                    {
     345                        uint32_t fSVMFeaturesEdx;
     346                        ASMCpuId(0x8000000a, &uDummy, &uDummy, &uDummy, &fSVMFeaturesEdx);
     347                        if (fSVMFeaturesEdx & AMD_CPUID_SVM_FEATURE_EDX_NESTED_PAGING)
     348                            m->fNestedPagingSupported = true;
     349                    }
     350                }
     351            }
     352        }
     353    }
     354
     355    /* Check with SUPDrv if VT-x and AMD-V are really supported (may fail). */
     356    if (m->fVTSupported)
     357    {
     358        int rc = SUPR3InitEx(false /*fUnrestricted*/, NULL);
     359        if (RT_SUCCESS(rc))
     360        {
     361            uint32_t fVTCaps;
     362            rc = SUPR3QueryVTCaps(&fVTCaps);
     363            if (RT_SUCCESS(rc))
     364            {
     365                Assert(fVTCaps & (SUPVTCAPS_AMD_V | SUPVTCAPS_VT_X));
     366                if (fVTCaps & SUPVTCAPS_NESTED_PAGING)
     367                    m->fNestedPagingSupported = true;
     368                else
     369                    Assert(m->fNestedPagingSupported == false);
     370            }
     371            else
     372            {
     373                LogRel(("SUPR0QueryVTCaps -> %Rrc\n", rc));
     374                m->fVTSupported = m->fNestedPagingSupported = true;
    322375            }
    323376        }
    324377        else
    325         if (    u32VendorEBX == X86_CPUID_VENDOR_AMD_EBX
    326             &&  u32VendorECX == X86_CPUID_VENDOR_AMD_ECX
    327             &&  u32VendorEDX == X86_CPUID_VENDOR_AMD_EDX
    328            )
    329         {
    330             /* AMD. */
    331             if (   (u32ExtFeatureECX & X86_CPUID_AMD_FEATURE_ECX_SVM)
    332                 && (u32FeaturesEDX & X86_CPUID_FEATURE_EDX_MSR)
    333                 && (u32FeaturesEDX & X86_CPUID_FEATURE_EDX_FXSR)
    334                )
    335             {
    336                 uint32_t u32SVMFeatureEDX;
    337 
    338                 m->fVTSupported = true;
    339 
    340                 /* Query AMD features. */
    341                 ASMCpuId(0x8000000A, &u32Dummy, &u32Dummy, &u32Dummy, &u32SVMFeatureEDX);
    342                 if (u32SVMFeatureEDX & AMD_CPUID_SVM_FEATURE_EDX_NESTED_PAGING)
    343                     m->fNestedPagingSupported = true;
    344             }
    345         }
    346         else
    347         if (    u32VendorEBX == X86_CPUID_VENDOR_VIA_EBX
    348             &&  u32VendorECX == X86_CPUID_VENDOR_VIA_ECX
    349             &&  u32VendorEDX == X86_CPUID_VENDOR_VIA_EDX
    350            )
    351         {
    352             /* VIA. */
    353             if (    (u32FeaturesECX & X86_CPUID_FEATURE_ECX_VMX)
    354                  && (u32FeaturesEDX & X86_CPUID_FEATURE_EDX_MSR)
    355                  && (u32FeaturesEDX & X86_CPUID_FEATURE_EDX_FXSR)
    356                )
    357             {
    358                 int rc = SUPR3QueryVTxSupported();
    359                 if (RT_SUCCESS(rc))
    360                     m->fVTSupported = true;
    361             }
    362         }
    363     }
    364 
    365 #if 0 /* needs testing */
    366     if (m->fVTSupported)
    367     {
    368         uint32_t u32Caps = 0;
    369 
    370         int rc = SUPR3QueryVTCaps(&u32Caps);
    371         if (RT_SUCCESS(rc))
    372         {
    373             if (u32Caps & SUPVTCAPS_NESTED_PAGING)
    374                 m->fNestedPagingSupported = true;
    375         }
    376         /* else @todo; report BIOS trouble in some way. */
    377     }
    378 #endif
     378            m->fRecheckVTSupported = true; /* Try again later when the driver is loaded. */
     379    }
    379380
    380381    /* Test for 3D hardware acceleration support */
     
    914915STDMETHODIMP Host::GetProcessorFeature(ProcessorFeature_T aFeature, BOOL *aSupported)
    915916{
     917    /* Validate input. */
    916918    CheckComArgOutPointerValid(aSupported);
     919    switch (aFeature)
     920    {
     921        case ProcessorFeature_HWVirtEx:
     922        case ProcessorFeature_PAE:
     923        case ProcessorFeature_LongMode:
     924        case ProcessorFeature_NestedPaging:
     925            break;
     926        default:
     927            return setError(E_INVALIDARG, tr("The aFeature value %d (%#x) is out of range."), (int)aFeature, (int)aFeature);
     928    }
     929
     930    /* Do the job. */
    917931    AutoCaller autoCaller(this);
    918     if (FAILED(autoCaller.rc())) return autoCaller.rc();
    919 
    920     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    921 
    922     switch (aFeature)
    923     {
    924         case ProcessorFeature_HWVirtEx:
    925             *aSupported = m->fVTSupported;
    926             break;
    927 
    928         case ProcessorFeature_PAE:
    929             *aSupported = m->fPAESupported;
    930             break;
    931 
    932         case ProcessorFeature_LongMode:
    933             *aSupported = m->fLongModeSupported;
    934             break;
    935 
    936         case ProcessorFeature_NestedPaging:
    937             *aSupported = m->fNestedPagingSupported;
    938             break;
    939 
    940         default:
    941             ReturnComNotImplemented();
    942     }
    943     return S_OK;
     932    HRESULT hrc = autoCaller.rc();
     933    if (SUCCEEDED(hrc))
     934    {
     935        AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     936
     937        if (   m->fRecheckVTSupported
     938            && (   aFeature == ProcessorFeature_HWVirtEx
     939                || aFeature == ProcessorFeature_NestedPaging)
     940           )
     941        {
     942            alock.release();
     943
     944            /* Perhaps the driver is available now... */
     945            int rc = SUPR3InitEx(false /*fUnrestricted*/, NULL);
     946            if (RT_SUCCESS(rc))
     947            {
     948                uint32_t fVTCaps;
     949                rc = SUPR3QueryVTCaps(&fVTCaps);
     950
     951                AutoWriteLock wlock(this COMMA_LOCKVAL_SRC_POS);
     952                if (RT_SUCCESS(rc))
     953                {
     954                    Assert(fVTCaps & (SUPVTCAPS_AMD_V | SUPVTCAPS_VT_X));
     955                    if (fVTCaps & SUPVTCAPS_NESTED_PAGING)
     956                        m->fNestedPagingSupported = true;
     957                    else
     958                        Assert(m->fNestedPagingSupported == false);
     959                }
     960                else
     961                {
     962                    LogRel(("SUPR0QueryVTCaps -> %Rrc\n", rc));
     963                    m->fVTSupported = m->fNestedPagingSupported = true;
     964                }
     965            }
     966
     967            alock.acquire();
     968        }
     969
     970        switch (aFeature)
     971        {
     972            case ProcessorFeature_HWVirtEx:
     973                *aSupported = m->fVTSupported;
     974                break;
     975
     976            case ProcessorFeature_PAE:
     977                *aSupported = m->fPAESupported;
     978                break;
     979
     980            case ProcessorFeature_LongMode:
     981                *aSupported = m->fLongModeSupported;
     982                break;
     983
     984            case ProcessorFeature_NestedPaging:
     985                *aSupported = m->fNestedPagingSupported;
     986                break;
     987
     988            default:
     989                AssertFailed();
     990        }
     991    }
     992    return hrc;
    944993}
    945994
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