Changeset 44173 in vbox for trunk/src/VBox/HostDrivers/Support/SUPDrv.c
- Timestamp:
- Dec 19, 2012 6:12:31 PM (12 years ago)
- svn:sync-xref-src-repo-rev:
- 82883
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/Support/SUPDrv.c
r43394 r44173 657 657 * 658 658 * @returns IPRT status code. 659 * @param pDevExt Device extension. 660 * @param fUser Flag indicating whether this is a user or kernel session. 661 * @param ppSession Where to store the pointer to the session data. 662 */ 663 int VBOXCALL supdrvCreateSession(PSUPDRVDEVEXT pDevExt, bool fUser, PSUPDRVSESSION *ppSession) 659 * @param pDevExt Device extension. 660 * @param fUser Flag indicating whether this is a user or kernel 661 * session. 662 * @param fUnrestricted Unrestricted access (system) or restricted access 663 * (user)? 664 * @param ppSession Where to store the pointer to the session data. 665 */ 666 int VBOXCALL supdrvCreateSession(PSUPDRVDEVEXT pDevExt, bool fUser, bool fUnrestricted, PSUPDRVSESSION *ppSession) 664 667 { 665 668 /* … … 682 685 pSession->pDevExt = pDevExt; 683 686 pSession->u32Cookie = BIRD_INV; 687 pSession->fUnrestricted = fUnrestricted; 684 688 /*pSession->pLdrUsage = NULL; 685 689 pSession->pVM = NULL; … … 1081 1085 * @param pReqHdr The request header. 1082 1086 */ 1083 static int supdrvIOCtlInner (uintptr_t uIOCtl, PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, PSUPREQHDR pReqHdr)1087 static int supdrvIOCtlInnerUnrestricted(uintptr_t uIOCtl, PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, PSUPREQHDR pReqHdr) 1084 1088 { 1085 1089 /* … … 1758 1762 PSUPVTCAPS pReq = (PSUPVTCAPS)pReqHdr; 1759 1763 REQ_CHECK_SIZES(SUP_IOCTL_VT_CAPS); 1760 REQ_CHECK_EXPR(SUP_IOCTL_VT_CAPS, pReq->Hdr.cbIn <= SUP_IOCTL_VT_CAPS_SIZE_IN);1761 1764 1762 1765 /* execute */ … … 1846 1849 1847 1850 /** 1848 * I/O Control worker.1851 * I/O Control inner worker for the restricted operations. 1849 1852 * 1850 1853 * @returns IPRT status code. … … 1856 1859 * @param pReqHdr The request header. 1857 1860 */ 1861 static int supdrvIOCtlInnerRestricted(uintptr_t uIOCtl, PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, PSUPREQHDR pReqHdr) 1862 { 1863 /* 1864 * The switch. 1865 */ 1866 switch (SUP_CTL_CODE_NO_SIZE(uIOCtl)) 1867 { 1868 case SUP_CTL_CODE_NO_SIZE(SUP_IOCTL_COOKIE): 1869 { 1870 PSUPCOOKIE pReq = (PSUPCOOKIE)pReqHdr; 1871 REQ_CHECK_SIZES(SUP_IOCTL_COOKIE); 1872 if (strncmp(pReq->u.In.szMagic, SUPCOOKIE_MAGIC, sizeof(pReq->u.In.szMagic))) 1873 { 1874 OSDBGPRINT(("SUP_IOCTL_COOKIE: invalid magic %.16s\n", pReq->u.In.szMagic)); 1875 pReq->Hdr.rc = VERR_INVALID_MAGIC; 1876 return 0; 1877 } 1878 1879 /* 1880 * Match the version. 1881 * The current logic is very simple, match the major interface version. 1882 */ 1883 if ( pReq->u.In.u32MinVersion > SUPDRV_IOC_VERSION 1884 || (pReq->u.In.u32MinVersion & 0xffff0000) != (SUPDRV_IOC_VERSION & 0xffff0000)) 1885 { 1886 OSDBGPRINT(("SUP_IOCTL_COOKIE: Version mismatch. Requested: %#x Min: %#x Current: %#x\n", 1887 pReq->u.In.u32ReqVersion, pReq->u.In.u32MinVersion, SUPDRV_IOC_VERSION)); 1888 pReq->u.Out.u32Cookie = 0xffffffff; 1889 pReq->u.Out.u32SessionCookie = 0xffffffff; 1890 pReq->u.Out.u32SessionVersion = 0xffffffff; 1891 pReq->u.Out.u32DriverVersion = SUPDRV_IOC_VERSION; 1892 pReq->u.Out.pSession = NULL; 1893 pReq->u.Out.cFunctions = 0; 1894 pReq->Hdr.rc = VERR_VERSION_MISMATCH; 1895 return 0; 1896 } 1897 1898 /* 1899 * Fill in return data and be gone. 1900 * N.B. The first one to change SUPDRV_IOC_VERSION shall makes sure that 1901 * u32SessionVersion <= u32ReqVersion! 1902 */ 1903 /** @todo Somehow validate the client and negotiate a secure cookie... */ 1904 pReq->u.Out.u32Cookie = pDevExt->u32Cookie; 1905 pReq->u.Out.u32SessionCookie = pSession->u32Cookie; 1906 pReq->u.Out.u32SessionVersion = SUPDRV_IOC_VERSION; 1907 pReq->u.Out.u32DriverVersion = SUPDRV_IOC_VERSION; 1908 pReq->u.Out.pSession = pSession; 1909 pReq->u.Out.cFunctions = 0; 1910 pReq->Hdr.rc = VINF_SUCCESS; 1911 return 0; 1912 } 1913 1914 case SUP_CTL_CODE_NO_SIZE(SUP_IOCTL_VT_CAPS): 1915 { 1916 /* validate */ 1917 PSUPVTCAPS pReq = (PSUPVTCAPS)pReqHdr; 1918 REQ_CHECK_SIZES(SUP_IOCTL_VT_CAPS); 1919 1920 /* execute */ 1921 pReq->Hdr.rc = SUPR0QueryVTCaps(pSession, &pReq->u.Out.Caps); 1922 if (RT_FAILURE(pReq->Hdr.rc)) 1923 pReq->Hdr.cbOut = sizeof(pReq->Hdr); 1924 return 0; 1925 } 1926 1927 default: 1928 Log(("Unknown IOCTL %#lx\n", (long)uIOCtl)); 1929 break; 1930 } 1931 return VERR_GENERAL_FAILURE; 1932 } 1933 1934 1935 /** 1936 * I/O Control worker. 1937 * 1938 * @returns IPRT status code. 1939 * @retval VERR_INVALID_PARAMETER if the request is invalid. 1940 * 1941 * @param uIOCtl Function number. 1942 * @param pDevExt Device extention. 1943 * @param pSession Session data. 1944 * @param pReqHdr The request header. 1945 */ 1858 1946 int VBOXCALL supdrvIOCtl(uintptr_t uIOCtl, PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, PSUPREQHDR pReqHdr) 1859 1947 { … … 1898 1986 1899 1987 /* 1900 * Hand it to an inner function to avoid lots of unnecessary return tracepoints 1901 */ 1902 rc = supdrvIOCtlInner(uIOCtl, pDevExt, pSession, pReqHdr); 1988 * Hand it to an inner function to avoid lots of unnecessary return tracepoints. 1989 */ 1990 if (pSession->fUnrestricted) 1991 rc = supdrvIOCtlInnerUnrestricted(uIOCtl, pDevExt, pSession, pReqHdr); 1992 else 1993 rc = supdrvIOCtlInnerRestricted(uIOCtl, pDevExt, pSession, pReqHdr); 1903 1994 1904 1995 VBOXDRV_IOCTL_RETURN(pSession, uIOCtl, pReqHdr, pReqHdr->rc, rc); … … 2002 2093 pReq->u.Out.uDriverRevision = VBOX_SVN_REV; 2003 2094 2004 pReq->Hdr.rc = supdrvCreateSession(pDevExt, false /* fUser */, &pSession);2095 pReq->Hdr.rc = supdrvCreateSession(pDevExt, false /* fUser */, true /*fUnrestricted*/, &pSession); 2005 2096 if (RT_FAILURE(pReq->Hdr.rc)) 2006 2097 { … … 3224 3315 3225 3316 3226 /** @todo document me */ 3317 /** 3318 * Quries the AMD-V and VT-x capabilities of the calling CPU. 3319 * 3320 * @returns VBox status code. 3321 * @retval VERR_VMX_NO_VMX 3322 * @retval VERR_VMX_MSR_LOCKED_OR_DISABLED 3323 * @retval VERR_SVM_NO_SVM 3324 * @retval VERR_SVM_DISABLED 3325 * @retval VERR_UNSUPPORTED_CPU if not identifiable as an AMD, Intel or VIA 3326 * (centaur) CPU. 3327 * 3328 * @param pSession The session handle. 3329 * @param pfCaps Where to store the capabilities. 3330 */ 3227 3331 SUPR0DECL(int) SUPR0QueryVTCaps(PSUPDRVSESSION pSession, uint32_t *pfCaps) 3228 3332 { … … 3237 3341 if (ASMHasCpuId()) 3238 3342 { 3239 uint32_t u32FeaturesECX; 3240 uint32_t u32Dummy; 3241 uint32_t u32FeaturesEDX; 3242 uint32_t u32VendorEBX, u32VendorECX, u32VendorEDX, u32AMDFeatureEDX, u32AMDFeatureECX; 3243 uint64_t val; 3244 3245 ASMCpuId(0, &u32Dummy, &u32VendorEBX, &u32VendorECX, &u32VendorEDX); 3246 ASMCpuId(1, &u32Dummy, &u32Dummy, &u32FeaturesECX, &u32FeaturesEDX); 3247 /* Query AMD features. */ 3248 ASMCpuId(0x80000001, &u32Dummy, &u32Dummy, &u32AMDFeatureECX, &u32AMDFeatureEDX); 3249 3250 if ( u32VendorEBX == X86_CPUID_VENDOR_INTEL_EBX 3251 && u32VendorECX == X86_CPUID_VENDOR_INTEL_ECX 3252 && u32VendorEDX == X86_CPUID_VENDOR_INTEL_EDX 3343 uint32_t fFeaturesECX, fFeaturesEDX, uDummy; 3344 uint32_t uMaxId, uVendorEBX, uVendorECX, uVendorEDX; 3345 uint64_t u64Value; 3346 3347 ASMCpuId(0, &uMaxId, &uVendorEBX, &uVendorECX, &uVendorEDX); 3348 ASMCpuId(1, &uDummy, &uDummy, &fFeaturesECX, &fFeaturesEDX); 3349 3350 if ( ASMIsValidStdRange(uMaxId) 3351 && ( ASMIsIntelCpuEx( uVendorEBX, uVendorECX, uVendorEDX) 3352 || ASMIsViaCentaurCpuEx(uVendorEBX, uVendorECX, uVendorEDX) ) 3253 3353 ) 3254 3354 { 3255 if ( ( u32FeaturesECX & X86_CPUID_FEATURE_ECX_VMX)3256 && ( u32FeaturesEDX & X86_CPUID_FEATURE_EDX_MSR)3257 && ( u32FeaturesEDX & X86_CPUID_FEATURE_EDX_FXSR)3355 if ( (fFeaturesECX & X86_CPUID_FEATURE_ECX_VMX) 3356 && (fFeaturesEDX & X86_CPUID_FEATURE_EDX_MSR) 3357 && (fFeaturesEDX & X86_CPUID_FEATURE_EDX_FXSR) 3258 3358 ) 3259 3359 { 3260 val = ASMRdMsr(MSR_IA32_FEATURE_CONTROL);3261 3360 /* 3262 3361 * Both the LOCK and VMXON bit must be set; otherwise VMXON will generate a #GP. 3263 3362 * Once the lock bit is set, this MSR can no longer be modified. 3264 3363 */ 3265 if ( (val & (MSR_IA32_FEATURE_CONTROL_VMXON|MSR_IA32_FEATURE_CONTROL_LOCK)) 3266 == (MSR_IA32_FEATURE_CONTROL_VMXON|MSR_IA32_FEATURE_CONTROL_LOCK) /* enabled and locked */ 3267 || !(val & MSR_IA32_FEATURE_CONTROL_LOCK) /* not enabled, but not locked either */ 3364 u64Value = ASMRdMsr(MSR_IA32_FEATURE_CONTROL); 3365 if ( (u64Value & (MSR_IA32_FEATURE_CONTROL_VMXON | MSR_IA32_FEATURE_CONTROL_LOCK)) 3366 == (MSR_IA32_FEATURE_CONTROL_VMXON | MSR_IA32_FEATURE_CONTROL_LOCK) /* enabled and locked */ 3367 || !(u64Value & MSR_IA32_FEATURE_CONTROL_LOCK) /* not enabled, but not locked either */ 3268 3368 ) 3269 3369 { … … 3286 3386 } 3287 3387 3288 if ( u32VendorEBX == X86_CPUID_VENDOR_AMD_EBX 3289 && u32VendorECX == X86_CPUID_VENDOR_AMD_ECX 3290 && u32VendorEDX == X86_CPUID_VENDOR_AMD_EDX 3291 ) 3292 { 3293 if ( (u32AMDFeatureECX & X86_CPUID_AMD_FEATURE_ECX_SVM) 3294 && (u32FeaturesEDX & X86_CPUID_FEATURE_EDX_MSR) 3295 && (u32FeaturesEDX & X86_CPUID_FEATURE_EDX_FXSR) 3388 if ( ASMIsAmdCpuEx(uVendorEBX, uVendorECX, uVendorEDX) 3389 && ASMIsValidStdRange(uMaxId)) 3390 { 3391 uint32_t fExtFeaturesEcx, uExtMaxId; 3392 ASMCpuId(0x80000000, &uExtMaxId, &uDummy, &uDummy, &uDummy); 3393 ASMCpuId(0x80000001, &uDummy, &uDummy, &fExtFeaturesEcx, &uDummy); 3394 if ( ASMIsValidExtRange(uExtMaxId) 3395 && uExtMaxId >= 0x8000000a 3396 && (fExtFeaturesEcx & X86_CPUID_AMD_FEATURE_ECX_SVM) 3397 && (fFeaturesEDX & X86_CPUID_FEATURE_EDX_MSR) 3398 && (fFeaturesEDX & X86_CPUID_FEATURE_EDX_FXSR) 3296 3399 ) 3297 3400 { 3298 3401 /* Check if SVM is disabled */ 3299 val= ASMRdMsr(MSR_K8_VM_CR);3300 if (!( val& MSR_K8_VM_CR_SVM_DISABLE))3402 u64Value = ASMRdMsr(MSR_K8_VM_CR); 3403 if (!(u64Value & MSR_K8_VM_CR_SVM_DISABLE)) 3301 3404 { 3302 3405 *pfCaps |= SUPVTCAPS_AMD_V; 3303 3406 3304 /* Query AMD features. */3305 ASMCpuId(0x8000000A, &u32Dummy, &u32Dummy, &u32Dummy, &u32FeaturesEDX);3306 3307 if ( u32FeaturesEDX& AMD_CPUID_SVM_FEATURE_EDX_NESTED_PAGING)3407 /* Query AMD-V features. */ 3408 uint32_t fSvmFeatures; 3409 ASMCpuId(0x8000000a, &uDummy, &uDummy, &uDummy, &fSvmFeatures); 3410 if (fSvmFeatures & AMD_CPUID_SVM_FEATURE_EDX_NESTED_PAGING) 3308 3411 *pfCaps |= SUPVTCAPS_NESTED_PAGING; 3309 3412 … … 5477 5580 /* Check for "AuthenticAMD" */ 5478 5581 ASMCpuId(0, &uEAX, &uEBX, &uECX, &uEDX); 5479 if ( uEAX >= 1 5480 && uEBX == X86_CPUID_VENDOR_AMD_EBX 5481 && uECX == X86_CPUID_VENDOR_AMD_ECX 5482 && uEDX == X86_CPUID_VENDOR_AMD_EDX) 5582 if ( uEAX >= 1 5583 && ASMIsAmdCpuEx(uEBX, uECX, uEDX)) 5483 5584 { 5484 5585 /* Check for APM support and that TscInvariant is cleared. */
Note:
See TracChangeset
for help on using the changeset viewer.