Changeset 76223 in vbox
- Timestamp:
- Dec 14, 2018 5:15:56 AM (6 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/sup.h
r74767 r76223 1919 1919 SUPR0DECL(int) SUPR0PageFree(PSUPDRVSESSION pSession, RTR3PTR pvR3); 1920 1920 SUPR0DECL(int) SUPR0GipMap(PSUPDRVSESSION pSession, PRTR3PTR ppGipR3, PRTHCPHYS pHCPhysGip); 1921 SUPR0DECL(int) SUPR0GetVTSupport(uint32_t *pfCaps); 1921 1922 SUPR0DECL(int) SUPR0GetSvmUsability(bool fInitSvm); 1922 1923 SUPR0DECL(int) SUPR0GetVmxUsability(bool *pfIsSmxModeAmbiguous); -
trunk/src/VBox/HostDrivers/Support/SUPDrv.cpp
r75288 r76223 4101 4101 4102 4102 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 */ 4110 SUPR0DECL(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 4103 4167 4104 4168 /** … … 4301 4365 */ 4302 4366 AssertPtrReturn(pfCaps, VERR_INVALID_POINTER); 4303 4304 4367 *pfCaps = 0; 4368 4305 4369 /* We may modify MSRs and re-read them, disable preemption so we make sure we don't migrate CPUs. */ 4306 4370 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) 4327 4387 { 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; 4341 4393 } 4342 4394 } 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. */ 4378 4413 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. */ 4379 4416 if (fIsSmxModeAmbiguous) 4380 4417 SUPR0Printf(("WARNING! CR4 hints SMX mode but your CPU is too secretive. Proceeding anyway... We wish you good luck!\n")); 4418 4381 4419 return rc; 4382 4420 } 4421 4383 4422 4384 4423 /**
Note:
See TracChangeset
for help on using the changeset viewer.