VirtualBox

Changeset 76223 in vbox


Ignore:
Timestamp:
Dec 14, 2018 5:15:56 AM (6 years ago)
Author:
vboxsync
Message:

SUPDrv: Have a separate function to check for VT-x/AMD-V support, for upcoming changes to HMR0 which will re-use this. No need to duplicate this code in multiple places.

Location:
trunk
Files:
2 edited

Legend:

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

    r74767 r76223  
    19191919SUPR0DECL(int) SUPR0PageFree(PSUPDRVSESSION pSession, RTR3PTR pvR3);
    19201920SUPR0DECL(int) SUPR0GipMap(PSUPDRVSESSION pSession, PRTR3PTR ppGipR3, PRTHCPHYS pHCPhysGip);
     1921SUPR0DECL(int) SUPR0GetVTSupport(uint32_t *pfCaps);
    19211922SUPR0DECL(int) SUPR0GetSvmUsability(bool fInitSvm);
    19221923SUPR0DECL(int) SUPR0GetVmxUsability(bool *pfIsSmxModeAmbiguous);
  • trunk/src/VBox/HostDrivers/Support/SUPDrv.cpp

    r75288 r76223  
    41014101
    41024102
     4103/**
     4104 * Gets AMD-V and VT-x support for the calling CPU.
     4105 *
     4106 * @returns VBox status code.
     4107 * @param   pfCaps          Where to store whether VT-x (SUPVTCAPS_VT_X) or AMD-V
     4108 *                          (SUPVTCAPS_AMD_V) is supported.
     4109 */
     4110SUPR0DECL(int) SUPR0GetVTSupport(uint32_t *pfCaps)
     4111{
     4112    Assert(!RTThreadPreemptIsEnabled(NIL_RTTHREAD));
     4113    Assert(pfCaps);
     4114    *pfCaps = 0;
     4115
     4116    /* Check if the CPU even supports CPUID (extremely ancient CPUs). */
     4117    if (ASMHasCpuId())
     4118    {
     4119        /* Check the range of standard CPUID leafs. */
     4120        uint32_t uMaxLeaf, uVendorEbx, uVendorEcx, uVendorEdx;
     4121        ASMCpuId(0, &uMaxLeaf, &uVendorEbx, &uVendorEcx, &uVendorEdx);
     4122        if (ASMIsValidStdRange(uMaxLeaf))
     4123        {
     4124            /* Query the standard CPUID leaf. */
     4125            uint32_t fFeatEcx, fFeatEdx, uDummy;
     4126            ASMCpuId(1, &uDummy, &uDummy, &fFeatEcx, &fFeatEdx);
     4127
     4128            /* Check if the vendor is Intel (or compatible). */
     4129            if (   ASMIsIntelCpuEx(uVendorEbx, uVendorEcx, uVendorEdx)
     4130                || ASMIsViaCentaurCpuEx(uVendorEbx, uVendorEcx, uVendorEdx))
     4131            {
     4132                /* Check VT-x support. In addition, VirtualBox requires MSR and FXSAVE/FXRSTOR to function. */
     4133                if (   (fFeatEcx & X86_CPUID_FEATURE_ECX_VMX)
     4134                    && (fFeatEdx & X86_CPUID_FEATURE_EDX_MSR)
     4135                    && (fFeatEdx & X86_CPUID_FEATURE_EDX_FXSR))
     4136                {
     4137                    *pfCaps = SUPVTCAPS_VT_X;
     4138                    return VINF_SUCCESS;
     4139                }
     4140                return VERR_VMX_NO_VMX;
     4141            }
     4142
     4143            /* Check if the vendor is AMD (or compatible). */
     4144            if (ASMIsAmdCpuEx(uVendorEbx, uVendorEcx, uVendorEdx))
     4145            {
     4146                uint32_t fExtFeatEcx, uExtMaxId;
     4147                ASMCpuId(0x80000000, &uExtMaxId, &uDummy, &uDummy, &uDummy);
     4148                ASMCpuId(0x80000001, &uDummy, &uDummy, &fExtFeatEcx, &uDummy);
     4149
     4150                /* Check AMD-V support. In addition, VirtualBox requires MSR and FXSAVE/FXRSTOR to function. */
     4151                if (   ASMIsValidExtRange(uExtMaxId)
     4152                    && uExtMaxId >= 0x8000000a
     4153                    && (fExtFeatEcx & X86_CPUID_AMD_FEATURE_ECX_SVM)
     4154                    && (fFeatEdx    & X86_CPUID_FEATURE_EDX_MSR)
     4155                    && (fFeatEdx    & X86_CPUID_FEATURE_EDX_FXSR))
     4156                {
     4157                    *pfCaps = SUPVTCAPS_AMD_V;
     4158                    return VINF_SUCCESS;
     4159                }
     4160                return VERR_SVM_NO_SVM;
     4161            }
     4162        }
     4163    }
     4164    return VERR_UNSUPPORTED_CPU;
     4165}
     4166
    41034167
    41044168/**
     
    43014365     */
    43024366    AssertPtrReturn(pfCaps, VERR_INVALID_POINTER);
    4303 
    43044367    *pfCaps = 0;
     4368
    43054369    /* We may modify MSRs and re-read them, disable preemption so we make sure we don't migrate CPUs. */
    43064370    RTThreadPreemptDisable(&PreemptState);
    4307     if (ASMHasCpuId())
    4308     {
    4309         uint32_t fFeaturesECX, fFeaturesEDX, uDummy;
    4310         uint32_t uMaxId, uVendorEBX, uVendorECX, uVendorEDX;
    4311 
    4312         ASMCpuId(0, &uMaxId, &uVendorEBX, &uVendorECX, &uVendorEDX);
    4313         ASMCpuId(1, &uDummy, &uDummy, &fFeaturesECX, &fFeaturesEDX);
    4314 
    4315         if (   ASMIsValidStdRange(uMaxId)
    4316             && (   ASMIsIntelCpuEx(     uVendorEBX, uVendorECX, uVendorEDX)
    4317                 || ASMIsViaCentaurCpuEx(uVendorEBX, uVendorECX, uVendorEDX) )
    4318            )
    4319         {
    4320             if (    (fFeaturesECX & X86_CPUID_FEATURE_ECX_VMX)
    4321                  && (fFeaturesEDX & X86_CPUID_FEATURE_EDX_MSR)
    4322                  && (fFeaturesEDX & X86_CPUID_FEATURE_EDX_FXSR)
    4323                )
    4324             {
    4325                 rc = SUPR0GetVmxUsability(&fIsSmxModeAmbiguous);
    4326                 if (rc == VINF_SUCCESS)
     4371
     4372    /* Check if VT-x/AMD-V is supported. */
     4373    rc = SUPR0GetVTSupport(pfCaps);
     4374    if (RT_SUCCESS(rc))
     4375    {
     4376        /* Check if VT-x is supported. */
     4377        if (*pfCaps & SUPVTCAPS_VT_X)
     4378        {
     4379            /* Check if VT-x is usable. */
     4380            rc = SUPR0GetVmxUsability(&fIsSmxModeAmbiguous);
     4381            if (RT_SUCCESS(rc))
     4382            {
     4383                /* Query some basic VT-x capabilities (mainly required by our GUI). */
     4384                VMXCTLSMSR vtCaps;
     4385                vtCaps.u = ASMRdMsr(MSR_IA32_VMX_PROCBASED_CTLS);
     4386                if (vtCaps.n.allowed1 & VMX_PROC_CTLS_USE_SECONDARY_CTLS)
    43274387                {
    4328                     VMXCTLSMSR vtCaps;
    4329 
    4330                     *pfCaps |= SUPVTCAPS_VT_X;
    4331 
    4332                     vtCaps.u = ASMRdMsr(MSR_IA32_VMX_PROCBASED_CTLS);
    4333                     if (vtCaps.n.allowed1 & VMX_PROC_CTLS_USE_SECONDARY_CTLS)
    4334                     {
    4335                         vtCaps.u = ASMRdMsr(MSR_IA32_VMX_PROCBASED_CTLS2);
    4336                         if (vtCaps.n.allowed1 & VMX_PROC_CTLS2_EPT)
    4337                             *pfCaps |= SUPVTCAPS_NESTED_PAGING;
    4338                         if (vtCaps.n.allowed1 & VMX_PROC_CTLS2_UNRESTRICTED_GUEST)
    4339                             *pfCaps |= SUPVTCAPS_VTX_UNRESTRICTED_GUEST;
    4340                     }
     4388                    vtCaps.u = ASMRdMsr(MSR_IA32_VMX_PROCBASED_CTLS2);
     4389                    if (vtCaps.n.allowed1 & VMX_PROC_CTLS2_EPT)
     4390                        *pfCaps |= SUPVTCAPS_NESTED_PAGING;
     4391                    if (vtCaps.n.allowed1 & VMX_PROC_CTLS2_UNRESTRICTED_GUEST)
     4392                        *pfCaps |= SUPVTCAPS_VTX_UNRESTRICTED_GUEST;
    43414393                }
    43424394            }
    4343             else
    4344                 rc = VERR_VMX_NO_VMX;
    4345         }
    4346         else if (   ASMIsAmdCpuEx(uVendorEBX, uVendorECX, uVendorEDX)
    4347                  && ASMIsValidStdRange(uMaxId))
    4348         {
    4349             uint32_t fExtFeaturesEcx, uExtMaxId;
    4350             ASMCpuId(0x80000000, &uExtMaxId, &uDummy, &uDummy, &uDummy);
    4351             ASMCpuId(0x80000001, &uDummy, &uDummy, &fExtFeaturesEcx, &uDummy);
    4352 
    4353             /* Check if SVM is available. */
    4354             if (   ASMIsValidExtRange(uExtMaxId)
    4355                 && uExtMaxId >= 0x8000000a
    4356                 && (fExtFeaturesEcx & X86_CPUID_AMD_FEATURE_ECX_SVM)
    4357                 && (fFeaturesEDX    & X86_CPUID_FEATURE_EDX_MSR)
    4358                 && (fFeaturesEDX    & X86_CPUID_FEATURE_EDX_FXSR)
    4359                )
    4360             {
    4361                 rc = SUPR0GetSvmUsability(false /* fInitSvm */);
    4362                 if (RT_SUCCESS(rc))
    4363                 {
    4364                     uint32_t fSvmFeatures;
    4365                     *pfCaps |= SUPVTCAPS_AMD_V;
    4366 
    4367                     /* Query AMD-V features. */
    4368                     ASMCpuId(0x8000000a, &uDummy, &uDummy, &uDummy, &fSvmFeatures);
    4369                     if (fSvmFeatures & X86_CPUID_SVM_FEATURE_EDX_NESTED_PAGING)
    4370                         *pfCaps |= SUPVTCAPS_NESTED_PAGING;
    4371                 }
    4372             }
    4373             else
    4374                 rc = VERR_SVM_NO_SVM;
    4375         }
    4376     }
    4377 
     4395        }
     4396        /* Check if AMD-V is supported. */
     4397        else if (*pfCaps & SUPVTCAPS_AMD_V)
     4398        {
     4399            /* Check is SVM is usable. */
     4400            rc = SUPR0GetSvmUsability(false /* fInitSvm */);
     4401            if (RT_SUCCESS(rc))
     4402            {
     4403                /* Query some basic AMD-V capabilities (mainly required by our GUI). */
     4404                uint32_t uDummy, fSvmFeatures;
     4405                ASMCpuId(0x8000000a, &uDummy, &uDummy, &uDummy, &fSvmFeatures);
     4406                if (fSvmFeatures & X86_CPUID_SVM_FEATURE_EDX_NESTED_PAGING)
     4407                    *pfCaps |= SUPVTCAPS_NESTED_PAGING;
     4408            }
     4409        }
     4410    }
     4411
     4412    /* Restore preemption. */
    43784413    RTThreadPreemptRestore(&PreemptState);
     4414
     4415    /* After restoring preemption, if we may be in SMX mode, print a warning as it's difficult to debug such problems. */
    43794416    if (fIsSmxModeAmbiguous)
    43804417        SUPR0Printf(("WARNING! CR4 hints SMX mode but your CPU is too secretive. Proceeding anyway... We wish you good luck!\n"));
     4418
    43814419    return rc;
    43824420}
     4421
    43834422
    43844423/**
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