VirtualBox

Ignore:
Timestamp:
Dec 19, 2012 6:12:31 PM (12 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
82883
Message:

SUPDrv,SUPLib: Introducing /dev/vboxdrvu on darwin (other platforms soon to follow).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/Support/SUPDrv.c

    r43394 r44173  
    657657 *
    658658 * @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 */
     666int VBOXCALL supdrvCreateSession(PSUPDRVDEVEXT pDevExt, bool fUser, bool fUnrestricted, PSUPDRVSESSION *ppSession)
    664667{
    665668    /*
     
    682685                pSession->pDevExt           = pDevExt;
    683686                pSession->u32Cookie         = BIRD_INV;
     687                pSession->fUnrestricted     = fUnrestricted;
    684688                /*pSession->pLdrUsage         = NULL;
    685689                pSession->pVM               = NULL;
     
    10811085 * @param   pReqHdr     The request header.
    10821086 */
    1083 static int supdrvIOCtlInner(uintptr_t uIOCtl, PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, PSUPREQHDR pReqHdr)
     1087static int supdrvIOCtlInnerUnrestricted(uintptr_t uIOCtl, PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, PSUPREQHDR pReqHdr)
    10841088{
    10851089    /*
     
    17581762            PSUPVTCAPS pReq = (PSUPVTCAPS)pReqHdr;
    17591763            REQ_CHECK_SIZES(SUP_IOCTL_VT_CAPS);
    1760             REQ_CHECK_EXPR(SUP_IOCTL_VT_CAPS, pReq->Hdr.cbIn <= SUP_IOCTL_VT_CAPS_SIZE_IN);
    17611764
    17621765            /* execute */
     
    18461849
    18471850/**
    1848  * I/O Control worker.
     1851 * I/O Control inner worker for the restricted operations.
    18491852 *
    18501853 * @returns IPRT status code.
     
    18561859 * @param   pReqHdr     The request header.
    18571860 */
     1861static 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 */
    18581946int VBOXCALL supdrvIOCtl(uintptr_t uIOCtl, PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, PSUPREQHDR pReqHdr)
    18591947{
     
    18981986
    18991987    /*
    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);
    19031994
    19041995    VBOXDRV_IOCTL_RETURN(pSession, uIOCtl, pReqHdr, pReqHdr->rc, rc);
     
    20022093            pReq->u.Out.uDriverRevision = VBOX_SVN_REV;
    20032094
    2004             pReq->Hdr.rc = supdrvCreateSession(pDevExt, false /* fUser */, &pSession);
     2095            pReq->Hdr.rc = supdrvCreateSession(pDevExt, false /* fUser */, true /*fUnrestricted*/, &pSession);
    20052096            if (RT_FAILURE(pReq->Hdr.rc))
    20062097            {
     
    32243315
    32253316
    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 */
    32273331SUPR0DECL(int) SUPR0QueryVTCaps(PSUPDRVSESSION pSession, uint32_t *pfCaps)
    32283332{
     
    32373341    if (ASMHasCpuId())
    32383342    {
    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) )
    32533353           )
    32543354        {
    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)
    32583358               )
    32593359            {
    3260                 val = ASMRdMsr(MSR_IA32_FEATURE_CONTROL);
    32613360                /*
    32623361                 * Both the LOCK and VMXON bit must be set; otherwise VMXON will generate a #GP.
    32633362                 * Once the lock bit is set, this MSR can no longer be modified.
    32643363                 */
    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 */
    32683368                   )
    32693369                {
     
    32863386        }
    32873387
    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)
    32963399               )
    32973400            {
    32983401                /* 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))
    33013404                {
    33023405                    *pfCaps |= SUPVTCAPS_AMD_V;
    33033406
    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)
    33083411                        *pfCaps |= SUPVTCAPS_NESTED_PAGING;
    33093412
     
    54775580        /* Check for "AuthenticAMD" */
    54785581        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))
    54835584        {
    54845585            /* Check for APM support and that TscInvariant is cleared. */
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette