Changeset 76461 in vbox
- Timestamp:
- Dec 25, 2018 4:28:45 AM (6 years ago)
- svn:sync-xref-src-repo-rev:
- 127762
- Location:
- trunk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/sup.h
r76389 r76461 29 29 #include <VBox/cdefs.h> 30 30 #include <VBox/types.h> 31 #include <VBox/vmm/hm_vmx.h> 32 #include <VBox/vmm/hm_svm.h> 31 33 #include <iprt/assert.h> 32 34 #include <iprt/stdarg.h> … … 106 108 #define SUPKERNELFEATURES_GDT_NEED_WRITABLE RT_BIT(2) 107 109 /** @} */ 110 111 112 /** 113 * Hardware-virtualization MSRs. 114 */ 115 typedef struct SUPHWVIRTMSRS 116 { 117 union 118 { 119 VMXMSRS vmx; 120 SVMMSRS svm; 121 } u ; 122 } SUPHWVIRTMSRS; 123 AssertCompileSize(SUPHWVIRTMSRS, 224); 124 /** Pointer to a hardware-virtualization MSRs struct. */ 125 typedef SUPHWVIRTMSRS *PSUPHWVIRTMSRS; 126 /** Pointer to a hardware-virtualization MSRs struct. */ 127 typedef const SUPHWVIRTMSRS *PCSUPHWVIRTMSRS; 108 128 109 129 … … 1837 1857 SUPR3DECL(int) SUPR3QueryMicrocodeRev(uint32_t *puMicrocodeRev); 1838 1858 1859 /** 1860 * Gets hardware-virtualization MSRs of the CPU, if available. 1861 * 1862 * @returns VINF_SUCCESS if available, error code indicating why if not. 1863 * @param pHwvirtMsrs Where to store the hardware-virtualization MSRs. 1864 * @param fForceRequery Whether to force complete re-querying of MSRs (rather 1865 * than fetching cached values when available). 1866 */ 1867 SUPR3DECL(int) SUPR3GetHwvirtMsrs(PSUPHWVIRTMSRS pHwvirtMsrs, bool fForceRequery); 1868 1839 1869 /** @} */ 1840 1870 #endif /* IN_RING3 */ … … 1919 1949 SUPR0DECL(int) SUPR0GipMap(PSUPDRVSESSION pSession, PRTR3PTR ppGipR3, PRTHCPHYS pHCPhysGip); 1920 1950 SUPR0DECL(int) SUPR0GetVTSupport(uint32_t *pfCaps); 1951 SUPR0DECL(int) SUPR0GetHwvirtMsrs(PSUPHWVIRTMSRS pMsrs, uint32_t fCaps, bool fForce); 1921 1952 SUPR0DECL(int) SUPR0GetSvmUsability(bool fInitSvm); 1922 1953 SUPR0DECL(int) SUPR0GetVmxUsability(bool *pfIsSmxModeAmbiguous); -
trunk/src/VBox/HostDrivers/Support/SUPDrv.cpp
r76227 r76461 201 201 { "SUPR0GetCurrentGdtRw", (void *)(uintptr_t)SUPR0GetCurrentGdtRw }, 202 202 { "SUPR0GetKernelFeatures", (void *)(uintptr_t)SUPR0GetKernelFeatures }, 203 { "SUPR0GetHwvirtMsrs", (void *)(uintptr_t)SUPR0GetHwvirtMsrs }, 203 204 { "SUPR0GetPagingMode", (void *)(uintptr_t)SUPR0GetPagingMode }, 204 205 { "SUPR0GetSvmUsability", (void *)(uintptr_t)SUPR0GetSvmUsability }, … … 488 489 #endif /* RT_OS_DARWIN || RT_OS_SOLARIS || RT_OS_SOLARIS */ 489 490 491 /** Hardware-virtualization MSRs. */ 492 static SUPHWVIRTMSRS g_HwvirtMsrs; 493 /** Whether the hardware-virtualization MSRs are cached. */ 494 static bool g_fHwvirtMsrsCached; 495 490 496 491 497 /** … … 2405 2411 } 2406 2412 2413 case SUP_CTL_CODE_NO_SIZE(SUP_IOCTL_GET_HWVIRT_MSRS): 2414 { 2415 /* validate */ 2416 PSUPGETHWVIRTMSRS pReq = (PSUPGETHWVIRTMSRS)pReqHdr; 2417 REQ_CHECK_SIZES(SUP_IOCTL_GET_HWVIRT_MSRS); 2418 REQ_CHECK_EXPR_FMT(!pReq->u.In.fReserved0 && !pReq->u.In.fReserved1 && !pReq->u.In.fReserved2, 2419 ("SUP_IOCTL_GET_HWVIRT_MSRS: fReserved0=%d fReserved1=%d fReserved2=%d\n", pReq->u.In.fReserved0, 2420 pReq->u.In.fReserved1, pReq->u.In.fReserved2)); 2421 2422 /* execute */ 2423 pReq->Hdr.rc = SUPR0GetHwvirtMsrs(&pReq->u.Out.HwvirtMsrs, 0 /* fCaps */, pReq->u.In.fForce); 2424 if (RT_FAILURE(pReq->Hdr.rc)) 2425 pReq->Hdr.cbOut = sizeof(pReq->Hdr); 2426 return 0; 2427 } 2428 2407 2429 default: 2408 2430 Log(("Unknown IOCTL %#lx\n", (long)uIOCtl)); … … 4542 4564 */ 4543 4565 return supdrvQueryUcodeRev(puRevision); 4566 } 4567 4568 4569 /** 4570 * Gets hardware-virtualization MSRs of the calling CPU. 4571 * 4572 * @returns VBox status code. 4573 * @param pMsrs Where to store the hardware-virtualization MSRs. 4574 * @param fCaps Hardware virtualization capabilities (SUPVTCAPS_XXX). Pass 0 4575 * to explicitly check for the presence of VT-x/AMD-V before 4576 * querying MSRs. 4577 * @param fForce Force querying of MSRs from the hardware. 4578 */ 4579 SUPR0DECL(int) SUPR0GetHwvirtMsrs(PSUPHWVIRTMSRS pMsrs, uint32_t fCaps, bool fForce) 4580 { 4581 int rc; 4582 RTTHREADPREEMPTSTATE PreemptState = RTTHREADPREEMPTSTATE_INITIALIZER; 4583 4584 /* 4585 * Input validation. 4586 */ 4587 AssertPtrReturn(pMsrs, VERR_INVALID_POINTER); 4588 4589 /* 4590 * Disable preemption so we make sure we don't migrate CPUs and because 4591 * we access global data. 4592 */ 4593 RTThreadPreemptDisable(&PreemptState); 4594 4595 /* 4596 * Querying MSRs from hardware can be expensive (exponentially more so 4597 * in a nested-virtualization scenario if they happen to cause VM-exits). 4598 * 4599 * So, if the caller does not force re-querying of MSRs and we have them 4600 * already cached, simply copy the cached MSRs and we're done. 4601 */ 4602 if ( !fForce 4603 && g_fHwvirtMsrsCached) 4604 { 4605 memcpy(pMsrs, &g_HwvirtMsrs, sizeof(*pMsrs)); 4606 RTThreadPreemptRestore(&PreemptState); 4607 return VINF_SUCCESS; 4608 } 4609 4610 /* 4611 * Query the MSRs from hardware, since it's either the first call since 4612 * driver load or the caller has forced re-querying of the MSRs. 4613 */ 4614 RT_ZERO(*pMsrs); 4615 4616 /* If the caller claims VT-x/AMD-V is supported, don't need to recheck it. */ 4617 if (!(fCaps & (SUPVTCAPS_VT_X | SUPVTCAPS_AMD_V))) 4618 rc = SUPR0GetVTSupport(&fCaps); 4619 else 4620 rc = VINF_SUCCESS; 4621 if (RT_SUCCESS(rc)) 4622 { 4623 if (fCaps & SUPVTCAPS_VT_X) 4624 { 4625 g_HwvirtMsrs.u.vmx.u64FeatCtrl = ASMRdMsr(MSR_IA32_FEATURE_CONTROL); 4626 g_HwvirtMsrs.u.vmx.u64Basic = ASMRdMsr(MSR_IA32_VMX_BASIC); 4627 g_HwvirtMsrs.u.vmx.PinCtls.u = ASMRdMsr(MSR_IA32_VMX_PINBASED_CTLS); 4628 g_HwvirtMsrs.u.vmx.ProcCtls.u = ASMRdMsr(MSR_IA32_VMX_PROCBASED_CTLS); 4629 g_HwvirtMsrs.u.vmx.ExitCtls.u = ASMRdMsr(MSR_IA32_VMX_EXIT_CTLS); 4630 g_HwvirtMsrs.u.vmx.EntryCtls.u = ASMRdMsr(MSR_IA32_VMX_ENTRY_CTLS); 4631 g_HwvirtMsrs.u.vmx.u64Misc = ASMRdMsr(MSR_IA32_VMX_MISC); 4632 g_HwvirtMsrs.u.vmx.u64Cr0Fixed0 = ASMRdMsr(MSR_IA32_VMX_CR0_FIXED0); 4633 g_HwvirtMsrs.u.vmx.u64Cr0Fixed1 = ASMRdMsr(MSR_IA32_VMX_CR0_FIXED1); 4634 g_HwvirtMsrs.u.vmx.u64Cr4Fixed0 = ASMRdMsr(MSR_IA32_VMX_CR4_FIXED0); 4635 g_HwvirtMsrs.u.vmx.u64Cr4Fixed1 = ASMRdMsr(MSR_IA32_VMX_CR4_FIXED1); 4636 g_HwvirtMsrs.u.vmx.u64VmcsEnum = ASMRdMsr(MSR_IA32_VMX_VMCS_ENUM); 4637 4638 if (RT_BF_GET(g_HwvirtMsrs.u.vmx.u64Basic, VMX_BF_BASIC_TRUE_CTLS)) 4639 { 4640 g_HwvirtMsrs.u.vmx.TruePinCtls.u = ASMRdMsr(MSR_IA32_VMX_TRUE_PINBASED_CTLS); 4641 g_HwvirtMsrs.u.vmx.TrueProcCtls.u = ASMRdMsr(MSR_IA32_VMX_TRUE_PROCBASED_CTLS); 4642 g_HwvirtMsrs.u.vmx.TrueEntryCtls.u = ASMRdMsr(MSR_IA32_VMX_TRUE_ENTRY_CTLS); 4643 g_HwvirtMsrs.u.vmx.TrueExitCtls.u = ASMRdMsr(MSR_IA32_VMX_TRUE_EXIT_CTLS); 4644 } 4645 4646 uint32_t const fProcCtlsAllowed1 = g_HwvirtMsrs.u.vmx.ProcCtls.n.allowed1; 4647 if (fProcCtlsAllowed1 & VMX_PROC_CTLS_USE_SECONDARY_CTLS) 4648 { 4649 g_HwvirtMsrs.u.vmx.ProcCtls2.u = ASMRdMsr(MSR_IA32_VMX_PROCBASED_CTLS2); 4650 4651 uint32_t const fProcCtls2Allowed1 = g_HwvirtMsrs.u.vmx.ProcCtls2.n.allowed1; 4652 if (fProcCtls2Allowed1 & (VMX_PROC_CTLS2_EPT | VMX_PROC_CTLS2_VPID)) 4653 g_HwvirtMsrs.u.vmx.u64EptVpidCaps = ASMRdMsr(MSR_IA32_VMX_EPT_VPID_CAP); 4654 4655 if (fProcCtls2Allowed1 & VMX_PROC_CTLS2_VMFUNC) 4656 g_HwvirtMsrs.u.vmx.u64VmFunc = ASMRdMsr(MSR_IA32_VMX_VMFUNC); 4657 } 4658 g_fHwvirtMsrsCached = true; 4659 } 4660 else if (fCaps & SUPVTCAPS_AMD_V) 4661 { 4662 g_HwvirtMsrs.u.svm.u64MsrHwcr = ASMRdMsr(MSR_K8_HWCR); 4663 g_fHwvirtMsrsCached = true; 4664 } 4665 else 4666 { 4667 RTThreadPreemptRestore(&PreemptState); 4668 AssertMsgFailedReturn(("SUPR0GetVTSupport returns success but neither VT-x nor AMD-V reported!\n"), 4669 VERR_INTERNAL_ERROR_2); 4670 } 4671 4672 /* 4673 * We have successfully populated the cache, copy the MSRs to the caller. 4674 */ 4675 memcpy(pMsrs, &g_HwvirtMsrs, sizeof(*pMsrs)); 4676 } 4677 4678 RTThreadPreemptRestore(&PreemptState); 4679 4680 return rc; 4544 4681 } 4545 4682 -
trunk/src/VBox/HostDrivers/Support/SUPDrvIOC.h
r76281 r76461 224 224 * @remarks 0x002a0000 is used by 5.1. The next version number must be 0x002b0000. 225 225 */ 226 #define SUPDRV_IOC_VERSION 0x0029000 7226 #define SUPDRV_IOC_VERSION 0x00290008 227 227 228 228 /** SUP_IOCTL_COOKIE. */ … … 1632 1632 1633 1633 1634 /** @name SUP_IOCTL_HWVIRT_MSRS 1635 * Get hardware-virtualization MSRs. 1636 * 1637 * This queries a lot more information than merely VT-x/AMD-V basic capabilities 1638 * provided by SUP_IOCTL_VT_CAPS. 1639 */ 1640 #define SUP_IOCTL_GET_HWVIRT_MSRS SUP_CTL_CODE_SIZE(41, SUP_IOCTL_GET_HWVIRT_MSRS_SIZE) 1641 #define SUP_IOCTL_GET_HWVIRT_MSRS_SIZE sizeof(SUPGETHWVIRTMSRS) 1642 #define SUP_IOCTL_GET_HWVIRT_MSRS_SIZE_IN (sizeof(SUPREQHDR) + RT_SIZEOFMEMB(SUPGETHWVIRTMSRS, u.In)) 1643 #define SUP_IOCTL_GET_HWVIRT_MSRS_SIZE_OUT sizeof(SUPGETHWVIRTMSRS) 1644 1645 typedef struct SUPGETHWVIRTMSRS 1646 { 1647 /** The header. */ 1648 SUPREQHDR Hdr; 1649 union 1650 { 1651 struct 1652 { 1653 /** Whether to force re-querying of MSRs. */ 1654 bool fForce; 1655 /** Reserved. Must be false. */ 1656 bool fReserved0; 1657 /** Reserved. Must be false. */ 1658 bool fReserved1; 1659 /** Reserved. Must be false. */ 1660 bool fReserved2; 1661 } In; 1662 1663 struct 1664 { 1665 /** Hardware-virtualization MSRs. */ 1666 SUPHWVIRTMSRS HwvirtMsrs; 1667 } Out; 1668 } u; 1669 } SUPGETHWVIRTMSRS, *PSUPGETHWVIRTMSRS; 1670 /** @} */ 1671 1672 1634 1673 #pragma pack() /* paranoia */ 1635 1674 -
trunk/src/VBox/HostDrivers/Support/SUPLib.cpp
r76257 r76461 277 277 CookieReq.u.In.u32ReqVersion = SUPDRV_IOC_VERSION; 278 278 const uint32_t uMinVersion = (SUPDRV_IOC_VERSION & 0xffff0000) == 0x00290000 279 ? 0x0029000 7279 ? 0x00290008 280 280 : SUPDRV_IOC_VERSION & 0xffff0000; 281 281 CookieReq.u.In.u32MinVersion = uMinVersion; … … 2334 2334 } 2335 2335 2336 2337 SUPR3DECL(int) SUPR3GetHwvirtMsrs(PSUPHWVIRTMSRS pHwvirtMsrs, bool fForceRequery) 2338 { 2339 AssertReturn(pHwvirtMsrs, VERR_INVALID_PARAMETER); 2340 2341 SUPGETHWVIRTMSRS Req; 2342 Req.Hdr.u32Cookie = g_u32Cookie; 2343 Req.Hdr.u32SessionCookie = g_u32SessionCookie; 2344 Req.Hdr.cbIn = SUP_IOCTL_GET_HWVIRT_MSRS_SIZE_IN; 2345 Req.Hdr.cbOut = SUP_IOCTL_GET_HWVIRT_MSRS_SIZE_OUT; 2346 Req.Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT; 2347 Req.Hdr.rc = VERR_INTERNAL_ERROR; 2348 2349 Req.u.In.fForce = fForceRequery; 2350 Req.u.In.fReserved0 = false; 2351 Req.u.In.fReserved1 = false; 2352 Req.u.In.fReserved2 = false; 2353 2354 int rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_GET_HWVIRT_MSRS, &Req, SUP_IOCTL_GET_HWVIRT_MSRS_SIZE); 2355 if (RT_SUCCESS(rc)) 2356 { 2357 rc = Req.Hdr.rc; 2358 *pHwvirtMsrs = Req.u.Out.HwvirtMsrs; 2359 } 2360 else 2361 RT_ZERO(*pHwvirtMsrs); 2362 return rc; 2363 } 2364
Note:
See TracChangeset
for help on using the changeset viewer.