Changeset 70944 in vbox
- Timestamp:
- Feb 9, 2018 10:09:03 PM (7 years ago)
- svn:sync-xref-src-repo-rev:
- 120787
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp
r70942 r70944 30 30 #endif 31 31 #include <sysinfoapi.h> 32 #include <debugapi.h> 33 #include <errhandlingapi.h> 32 34 #include <fileapi.h> 33 #include <errhandlingapi.h>34 35 #include <winerror.h> /* no api header for this. */ 35 36 … … 120 121 # define WHvSetVirtualProcessorRegisters g_pfnWHvSetVirtualProcessorRegisters 121 122 #endif 123 124 125 126 /** 127 * Worker for nemR3NativeInit that gets the hypervisor capabilities. 128 * 129 * @returns VBox status code. 130 * @param pVM The cross context VM structure. 131 * @param pErrInfo Where to always return error info. 132 */ 133 static int nemR3NativeInitCheckCapabilities(PVM pVM, PRTERRINFO pErrInfo) 134 { 135 #define NEM_LOG_REL_CAP_EX(a_szField, a_szFmt, a_Value) LogRel(("NEM: %-38s= " a_szFmt "\n", a_szField, a_Value)) 136 #define NEM_LOG_REL_CAP_SUB_EX(a_szField, a_szFmt, a_Value) LogRel(("NEM: %36s: " a_szFmt "\n", a_szField, a_Value)) 137 #define NEM_LOG_REL_CAP_SUB(a_szField, a_Value) NEM_LOG_REL_CAP_SUB_EX(a_szField, "%d", a_Value) 138 139 /* 140 * Is the hypervisor present with the desired capability? 141 * 142 * In build 17083 this translates into: 143 * - CPUID[0x00000001].HVP is set 144 * - CPUID[0x40000000] == "Microsoft Hv" 145 * - CPUID[0x40000001].eax == "Hv#1" 146 * - CPUID[0x40000003].ebx[12] is set. 147 * - VidGetExoPartitionProperty(INVALID_HANDLE_VALUE, 0x60000, &Ignored) returns 148 * a non-zero value. 149 */ 150 /** 151 * @todo Someone (MS) please explain weird API design: 152 * 1. Caps.CapabilityCode duplication, 153 * 2. No output size. 154 */ 155 WHV_CAPABILITY Caps; 156 RT_ZERO(Caps); 157 SetLastError(0); 158 HRESULT hrc = WHvGetCapability(WHvCapabilityCodeHypervisorPresent, &Caps, sizeof(Caps)); 159 DWORD rcWin = GetLastError(); 160 if (FAILED(hrc)) 161 return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "WHvGetCapability/WHvCapabilityCodeHypervisorPresent failed: %Rhrc", hrc); 162 if (!Caps.HypervisorPresent) 163 { 164 if (!RTPathExists(RTPATH_NT_PASSTHRU_PREFIX "Device\\VidExo")) 165 return RTErrInfoSetF(pErrInfo, VERR_NEM_NOT_AVAILABLE, 166 "WHvCapabilityCodeHypervisorPresent is FALSE! Make sure you have enabled the 'Windows Hypervisor Platform' feature."); 167 return RTErrInfoSetF(pErrInfo, VERR_NEM_NOT_AVAILABLE, "WHvCapabilityCodeHypervisorPresent is FALSE! (%u)", rcWin); 168 } 169 LogRel(("NEM: WHvCapabilityCodeHypervisorPresent is TRUE, so this might work...\n")); 170 171 172 /* 173 * Check what extended VM exits are supported. 174 */ 175 RT_ZERO(Caps); 176 hrc = WHvGetCapability(WHvCapabilityCodeExtendedVmExits, &Caps, sizeof(Caps)); 177 if (FAILED(hrc)) 178 return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "WHvGetCapability/WHvCapabilityCodeExtendedVmExits failed: %Rhrc", hrc); 179 NEM_LOG_REL_CAP_EX("WHvCapabilityCodeExtendedVmExits", "%'#018RX64", Caps.ExtendedVmExits.AsUINT64); 180 pVM->nem.s.fExtendedMsrExit = RT_BOOL(Caps.ExtendedVmExits.X64MsrExit); 181 pVM->nem.s.fExtendedCpuIdExit = RT_BOOL(Caps.ExtendedVmExits.X64CpuidExit); 182 pVM->nem.s.fExtendedXcptExit = RT_BOOL(Caps.ExtendedVmExits.ExceptionExit); 183 NEM_LOG_REL_CAP_SUB("fExtendedMsrExit", pVM->nem.s.fExtendedMsrExit); 184 NEM_LOG_REL_CAP_SUB("fExtendedCpuIdExit", pVM->nem.s.fExtendedCpuIdExit); 185 NEM_LOG_REL_CAP_SUB("fExtendedXcptExit", pVM->nem.s.fExtendedXcptExit); 186 if (Caps.ExtendedVmExits.AsUINT64 & ~(uint64_t)7) 187 LogRel(("NEM: Warning! Unknown VM exit definitions: %#RX64\n", Caps.ExtendedVmExits.AsUINT64)); 188 /** @todo RECHECK: WHV_EXTENDED_VM_EXITS typedef. */ 189 190 /* 191 * Check features in case they end up defining any. 192 */ 193 RT_ZERO(Caps); 194 hrc = WHvGetCapability(WHvCapabilityCodeFeatures, &Caps, sizeof(Caps)); 195 if (FAILED(hrc)) 196 return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "WHvGetCapability/WHvCapabilityCodeFeatures failed: %Rhrc", hrc); 197 if (Caps.Features.AsUINT64 & ~(uint64_t)0) 198 LogRel(("NEM: Warning! Unknown feature definitions: %#RX64\n", Caps.Features.AsUINT64)); 199 /** @todo RECHECK: WHV_CAPABILITY_FEATURES typedef. */ 200 201 /* 202 * Check that the CPU vendor is supported. 203 */ 204 RT_ZERO(Caps); 205 hrc = WHvGetCapability(WHvCapabilityCodeProcessorVendor, &Caps, sizeof(Caps)); 206 if (FAILED(hrc)) 207 return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "WHvGetCapability/WHvCapabilityCodeProcessorVendor failed: %Rhrc", hrc); 208 switch (Caps.ProcessorVendor) 209 { 210 /** @todo RECHECK: WHV_PROCESSOR_VENDOR typedef. */ 211 case WHvProcessorVendorIntel: 212 NEM_LOG_REL_CAP_EX("WHvCapabilityCodeProcessorVendor", "%d - Intel", Caps.ProcessorVendor); 213 pVM->nem.s.enmCpuVendor = CPUMCPUVENDOR_INTEL; 214 break; 215 case WHvProcessorVendorAmd: 216 NEM_LOG_REL_CAP_EX("WHvCapabilityCodeProcessorVendor", "%d - AMD", Caps.ProcessorVendor); 217 pVM->nem.s.enmCpuVendor = CPUMCPUVENDOR_AMD; 218 break; 219 default: 220 NEM_LOG_REL_CAP_EX("WHvCapabilityCodeProcessorVendor", "%d", Caps.ProcessorVendor); 221 return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "Unknown processor vendor: %d", Caps.ProcessorVendor); 222 } 223 224 /* 225 * CPU features, guessing these are virtual CPU features? 226 */ 227 RT_ZERO(Caps); 228 hrc = WHvGetCapability(WHvCapabilityCodeProcessorFeatures, &Caps, sizeof(Caps)); 229 if (FAILED(hrc)) 230 return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "WHvGetCapability/WHvCapabilityCodeProcessorFeatures failed: %Rhrc", hrc); 231 NEM_LOG_REL_CAP_EX("WHvCapabilityCodeProcessorFeatures", "%'#018RX64", Caps.ProcessorFeatures.AsUINT64); 232 #define NEM_LOG_REL_CPU_FEATURE(a_Field) NEM_LOG_REL_CAP_SUB(#a_Field, Caps.ProcessorFeatures.a_Field) 233 NEM_LOG_REL_CPU_FEATURE(Sse3Support); 234 NEM_LOG_REL_CPU_FEATURE(LahfSahfSupport); 235 NEM_LOG_REL_CPU_FEATURE(Ssse3Support); 236 NEM_LOG_REL_CPU_FEATURE(Sse4_1Support); 237 NEM_LOG_REL_CPU_FEATURE(Sse4_2Support); 238 NEM_LOG_REL_CPU_FEATURE(Sse4aSupport); 239 NEM_LOG_REL_CPU_FEATURE(XopSupport); 240 NEM_LOG_REL_CPU_FEATURE(PopCntSupport); 241 NEM_LOG_REL_CPU_FEATURE(Cmpxchg16bSupport); 242 NEM_LOG_REL_CPU_FEATURE(Altmovcr8Support); 243 NEM_LOG_REL_CPU_FEATURE(LzcntSupport); 244 NEM_LOG_REL_CPU_FEATURE(MisAlignSseSupport); 245 NEM_LOG_REL_CPU_FEATURE(MmxExtSupport); 246 NEM_LOG_REL_CPU_FEATURE(Amd3DNowSupport); 247 NEM_LOG_REL_CPU_FEATURE(ExtendedAmd3DNowSupport); 248 NEM_LOG_REL_CPU_FEATURE(Page1GbSupport); 249 NEM_LOG_REL_CPU_FEATURE(AesSupport); 250 NEM_LOG_REL_CPU_FEATURE(PclmulqdqSupport); 251 NEM_LOG_REL_CPU_FEATURE(PcidSupport); 252 NEM_LOG_REL_CPU_FEATURE(Fma4Support); 253 NEM_LOG_REL_CPU_FEATURE(F16CSupport); 254 NEM_LOG_REL_CPU_FEATURE(RdRandSupport); 255 NEM_LOG_REL_CPU_FEATURE(RdWrFsGsSupport); 256 NEM_LOG_REL_CPU_FEATURE(SmepSupport); 257 NEM_LOG_REL_CPU_FEATURE(EnhancedFastStringSupport); 258 NEM_LOG_REL_CPU_FEATURE(Bmi1Support); 259 NEM_LOG_REL_CPU_FEATURE(Bmi2Support); 260 /* two reserved bits here, see below */ 261 NEM_LOG_REL_CPU_FEATURE(MovbeSupport); 262 NEM_LOG_REL_CPU_FEATURE(Npiep1Support); 263 NEM_LOG_REL_CPU_FEATURE(DepX87FPUSaveSupport); 264 NEM_LOG_REL_CPU_FEATURE(RdSeedSupport); 265 NEM_LOG_REL_CPU_FEATURE(AdxSupport); 266 NEM_LOG_REL_CPU_FEATURE(IntelPrefetchSupport); 267 NEM_LOG_REL_CPU_FEATURE(SmapSupport); 268 NEM_LOG_REL_CPU_FEATURE(HleSupport); 269 NEM_LOG_REL_CPU_FEATURE(RtmSupport); 270 NEM_LOG_REL_CPU_FEATURE(RdtscpSupport); 271 NEM_LOG_REL_CPU_FEATURE(ClflushoptSupport); 272 NEM_LOG_REL_CPU_FEATURE(ClwbSupport); 273 NEM_LOG_REL_CPU_FEATURE(ShaSupport); 274 NEM_LOG_REL_CPU_FEATURE(X87PointersSavedSupport); 275 #undef NEM_LOG_REL_CPU_FEATURE 276 if (Caps.ProcessorFeatures.AsUINT64 & (~(RT_BIT_64(43) - 1) | RT_BIT_64(27) | RT_BIT_64(28))) 277 LogRel(("NEM: Warning! Unknown CPU features: %#RX64\n", Caps.ProcessorFeatures.AsUINT64)); 278 pVM->nem.s.uCpuFeatures.u64 = Caps.ProcessorFeatures.AsUINT64; 279 /** @todo RECHECK: WHV_PROCESSOR_FEATURES typedef. */ 280 281 /* 282 * The cache line flush size. 283 */ 284 RT_ZERO(Caps); 285 hrc = WHvGetCapability(WHvCapabilityCodeProcessorClFlushSize, &Caps, sizeof(Caps)); 286 if (FAILED(hrc)) 287 return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "WHvGetCapability/WHvCapabilityCodeProcessorClFlushSize failed: %Rhrc", hrc); 288 NEM_LOG_REL_CAP_EX("WHvCapabilityCodeProcessorClFlushSize", "2^%u", Caps.ProcessorClFlushSize); 289 290 /* 291 * See if they've added more properties that we're not aware of. 292 */ 293 /** @todo RECHECK: WHV_CAPABILITY_CODE typedef. */ 294 if (!IsDebuggerPresent()) /* Too noisy when in debugger, so skip. */ 295 { 296 static const struct 297 { 298 uint32_t iMin, iMax; } s_aUnknowns[] = 299 { 300 { 0x0003, 0x000f }, 301 { 0x1003, 0x100f }, 302 { 0x2000, 0x200f }, 303 { 0x3000, 0x300f }, 304 { 0x4000, 0x400f }, 305 }; 306 for (uint32_t j = 0; j < RT_ELEMENTS(s_aUnknowns); j++) 307 for (uint32_t i = s_aUnknowns[j].iMin; i <= s_aUnknowns[j].iMax; i++) 308 { 309 RT_ZERO(Caps); 310 hrc = WHvGetCapability((WHV_CAPABILITY_CODE)i, &Caps, sizeof(Caps)); 311 if (SUCCEEDED(hrc)) 312 LogRel(("NEM: Warning! Unknown capability %#x returning: %.*Rhxs\n", i, sizeof(Caps), &Caps)); 313 } 314 } 315 316 #undef NEM_LOG_REL_CAP_EX 317 #undef NEM_LOG_REL_CAP_SUB_EX 318 #undef NEM_LOG_REL_CAP_SUB 319 return VINF_SUCCESS; 320 } 122 321 123 322 … … 224 423 225 424 /* 226 * Check if the hypervisor API is present.425 * Check the capabilties of the hypervisor, starting with whether it's present. 227 426 */ 228 /** @todo Someone (MS) please explain weird API design: 229 * 1. Caps.CapabilityCode duplication, 230 * 2. No output size. 231 */ 232 WHV_CAPABILITY Caps; 233 RT_ZERO(Caps); 234 SetLastError(0); 235 HRESULT hrc = WHvGetCapability(WHvCapabilityCodeHypervisorPresent, &Caps, sizeof(Caps)); 236 DWORD rcWin = GetLastError(); 237 if (FAILED(hrc)) 238 rc = RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, 239 "WHvGetCapability/WHvCapabilityCodeHypervisorPresent failed: %Rhrc", hrc); 240 else if (!Caps.HypervisorPresent) 427 rc = nemR3NativeInitCheckCapabilities(pVM, pErrInfo); 428 if (RT_SUCCESS(rc)) 241 429 { 242 if (!RTPathExists(RTPATH_NT_PASSTHRU_PREFIX "Device\\VidExo"))243 rc = RTErrInfoSetF(pErrInfo, VERR_NEM_NOT_AVAILABLE,244 "WHvCapabilityCodeHypervisorPresent is FALSE! Make sure you have enabled the 'Windows Hypervisor Platform' feature.");245 else246 rc = RTErrInfoSetF(pErrInfo, VERR_NEM_NOT_AVAILABLE,247 "WHvCapabilityCodeHypervisorPresent is FALSE! (%u)", rcWin);248 }249 else250 {251 /*252 * .253 */254 LogRel(("NEM: WHvCapabilityCodeHypervisorPresent is TRUE, so this might work...\n"));255 256 430 rc = RTErrInfoAddF(pErrInfo, VERR_NOT_IMPLEMENTED, "lazy bugger isn't done yet"); 257 431 } -
trunk/src/VBox/VMM/include/NEMInternal.h
r70918 r70944 22 22 #include <VBox/types.h> 23 23 #include <VBox/vmm/nem.h> 24 #include <VBox/vmm/cpum.h> /* For CPUMCPUVENDOR. */ 24 25 #include <VBox/vmm/stam.h> 25 26 #include <VBox/vmm/vmapi.h> … … 44 45 /** Set if enabled. */ 45 46 bool fEnabled; 47 #ifdef RT_OS_WINDOWS 48 /** WHvRunVpExitReasonX64Cpuid is supported. */ 49 bool fExtendedMsrExit; 50 /** WHvRunVpExitReasonX64MsrAccess is supported. */ 51 bool fExtendedCpuIdExit; 52 /** WHvRunVpExitReasonException is supported. */ 53 bool fExtendedXcptExit; 54 /** The reported CPU vendor. */ 55 CPUMCPUVENDOR enmCpuVendor; 56 /** Explicit padding. */ 57 uint32_t u32Padding1; 58 /** The result of WHvCapabilityCodeProcessorFeatures. */ 59 union 60 { 61 /** 64-bit view. */ 62 uint64_t u64; 63 # ifdef _WINHVAPIDEFS_H_ 64 /** Interpreed features. */ 65 WHV_PROCESSOR_FEATURES u; 66 # endif 67 } uCpuFeatures; 68 #endif 46 69 47 70 } NEM;
Note:
See TracChangeset
for help on using the changeset viewer.