Index: /trunk/include/VBox/sup.h
===================================================================
--- /trunk/include/VBox/sup.h	(revision 44172)
+++ /trunk/include/VBox/sup.h	(revision 44173)
@@ -746,5 +746,6 @@
 /**
  * Initializes the support library.
- * Each successful call to SUPR3Init() must be countered by a
+ *
+ * Each successful call to SUPR3Init() or SUPR3InitEx must be countered by a
  * call to SUPR3Term(false).
  *
@@ -753,4 +754,17 @@
  */
 SUPR3DECL(int) SUPR3Init(PSUPDRVSESSION *ppSession);
+
+
+/**
+ * Initializes the support library, extended version.
+ *
+ * Each successful call to SUPR3Init() or SUPR3InitEx must be countered by a
+ * call to SUPR3Term(false).
+ *
+ * @returns VBox status code.
+ * @param   fUnrestricted   The desired access.
+ * @param   ppSession       Where to store the session handle. Defaults to NULL.
+ */
+SUPR3DECL(int) SUPR3InitEx(bool fUnrestricted, PSUPDRVSESSION *ppSession);
 
 /**
Index: /trunk/src/VBox/HostDrivers/Support/SUPDrv.c
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/SUPDrv.c	(revision 44172)
+++ /trunk/src/VBox/HostDrivers/Support/SUPDrv.c	(revision 44173)
@@ -657,9 +657,12 @@
  *
  * @returns IPRT status code.
- * @param   pDevExt     Device extension.
- * @param   fUser       Flag indicating whether this is a user or kernel session.
- * @param   ppSession   Where to store the pointer to the session data.
- */
-int VBOXCALL supdrvCreateSession(PSUPDRVDEVEXT pDevExt, bool fUser, PSUPDRVSESSION *ppSession)
+ * @param   pDevExt         Device extension.
+ * @param   fUser           Flag indicating whether this is a user or kernel
+ *                          session.
+ * @param   fUnrestricted   Unrestricted access (system) or restricted access
+ *                          (user)?
+ * @param   ppSession       Where to store the pointer to the session data.
+ */
+int VBOXCALL supdrvCreateSession(PSUPDRVDEVEXT pDevExt, bool fUser, bool fUnrestricted, PSUPDRVSESSION *ppSession)
 {
     /*
@@ -682,4 +685,5 @@
                 pSession->pDevExt           = pDevExt;
                 pSession->u32Cookie         = BIRD_INV;
+                pSession->fUnrestricted     = fUnrestricted;
                 /*pSession->pLdrUsage         = NULL;
                 pSession->pVM               = NULL;
@@ -1081,5 +1085,5 @@
  * @param   pReqHdr     The request header.
  */
-static int supdrvIOCtlInner(uintptr_t uIOCtl, PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, PSUPREQHDR pReqHdr)
+static int supdrvIOCtlInnerUnrestricted(uintptr_t uIOCtl, PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, PSUPREQHDR pReqHdr)
 {
     /*
@@ -1758,5 +1762,4 @@
             PSUPVTCAPS pReq = (PSUPVTCAPS)pReqHdr;
             REQ_CHECK_SIZES(SUP_IOCTL_VT_CAPS);
-            REQ_CHECK_EXPR(SUP_IOCTL_VT_CAPS, pReq->Hdr.cbIn <= SUP_IOCTL_VT_CAPS_SIZE_IN);
 
             /* execute */
@@ -1846,5 +1849,5 @@
 
 /**
- * I/O Control worker.
+ * I/O Control inner worker for the restricted operations.
  *
  * @returns IPRT status code.
@@ -1856,4 +1859,89 @@
  * @param   pReqHdr     The request header.
  */
+static int supdrvIOCtlInnerRestricted(uintptr_t uIOCtl, PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, PSUPREQHDR pReqHdr)
+{
+    /*
+     * The switch.
+     */
+    switch (SUP_CTL_CODE_NO_SIZE(uIOCtl))
+    {
+        case SUP_CTL_CODE_NO_SIZE(SUP_IOCTL_COOKIE):
+        {
+            PSUPCOOKIE pReq = (PSUPCOOKIE)pReqHdr;
+            REQ_CHECK_SIZES(SUP_IOCTL_COOKIE);
+            if (strncmp(pReq->u.In.szMagic, SUPCOOKIE_MAGIC, sizeof(pReq->u.In.szMagic)))
+            {
+                OSDBGPRINT(("SUP_IOCTL_COOKIE: invalid magic %.16s\n", pReq->u.In.szMagic));
+                pReq->Hdr.rc = VERR_INVALID_MAGIC;
+                return 0;
+            }
+
+            /*
+             * Match the version.
+             * The current logic is very simple, match the major interface version.
+             */
+            if (    pReq->u.In.u32MinVersion > SUPDRV_IOC_VERSION
+                ||  (pReq->u.In.u32MinVersion & 0xffff0000) != (SUPDRV_IOC_VERSION & 0xffff0000))
+            {
+                OSDBGPRINT(("SUP_IOCTL_COOKIE: Version mismatch. Requested: %#x  Min: %#x  Current: %#x\n",
+                            pReq->u.In.u32ReqVersion, pReq->u.In.u32MinVersion, SUPDRV_IOC_VERSION));
+                pReq->u.Out.u32Cookie         = 0xffffffff;
+                pReq->u.Out.u32SessionCookie  = 0xffffffff;
+                pReq->u.Out.u32SessionVersion = 0xffffffff;
+                pReq->u.Out.u32DriverVersion  = SUPDRV_IOC_VERSION;
+                pReq->u.Out.pSession          = NULL;
+                pReq->u.Out.cFunctions        = 0;
+                pReq->Hdr.rc = VERR_VERSION_MISMATCH;
+                return 0;
+            }
+
+            /*
+             * Fill in return data and be gone.
+             * N.B. The first one to change SUPDRV_IOC_VERSION shall makes sure that
+             *      u32SessionVersion <= u32ReqVersion!
+             */
+            /** @todo Somehow validate the client and negotiate a secure cookie... */
+            pReq->u.Out.u32Cookie         = pDevExt->u32Cookie;
+            pReq->u.Out.u32SessionCookie  = pSession->u32Cookie;
+            pReq->u.Out.u32SessionVersion = SUPDRV_IOC_VERSION;
+            pReq->u.Out.u32DriverVersion  = SUPDRV_IOC_VERSION;
+            pReq->u.Out.pSession          = pSession;
+            pReq->u.Out.cFunctions        = 0;
+            pReq->Hdr.rc = VINF_SUCCESS;
+            return 0;
+        }
+
+        case SUP_CTL_CODE_NO_SIZE(SUP_IOCTL_VT_CAPS):
+        {
+            /* validate */
+            PSUPVTCAPS pReq = (PSUPVTCAPS)pReqHdr;
+            REQ_CHECK_SIZES(SUP_IOCTL_VT_CAPS);
+
+            /* execute */
+            pReq->Hdr.rc = SUPR0QueryVTCaps(pSession, &pReq->u.Out.Caps);
+            if (RT_FAILURE(pReq->Hdr.rc))
+                pReq->Hdr.cbOut = sizeof(pReq->Hdr);
+            return 0;
+        }
+
+        default:
+            Log(("Unknown IOCTL %#lx\n", (long)uIOCtl));
+            break;
+    }
+    return VERR_GENERAL_FAILURE;
+}
+
+
+/**
+ * I/O Control worker.
+ *
+ * @returns IPRT status code.
+ * @retval  VERR_INVALID_PARAMETER if the request is invalid.
+ *
+ * @param   uIOCtl      Function number.
+ * @param   pDevExt     Device extention.
+ * @param   pSession    Session data.
+ * @param   pReqHdr     The request header.
+ */
 int VBOXCALL supdrvIOCtl(uintptr_t uIOCtl, PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, PSUPREQHDR pReqHdr)
 {
@@ -1898,7 +1986,10 @@
 
     /*
-     * Hand it to an inner function to avoid lots of unnecessary return tracepoints
-     */
-    rc = supdrvIOCtlInner(uIOCtl, pDevExt, pSession, pReqHdr);
+     * Hand it to an inner function to avoid lots of unnecessary return tracepoints.
+     */
+    if (pSession->fUnrestricted)
+        rc = supdrvIOCtlInnerUnrestricted(uIOCtl, pDevExt, pSession, pReqHdr);
+    else
+        rc = supdrvIOCtlInnerRestricted(uIOCtl, pDevExt, pSession, pReqHdr);
 
     VBOXDRV_IOCTL_RETURN(pSession, uIOCtl, pReqHdr, pReqHdr->rc, rc);
@@ -2002,5 +2093,5 @@
             pReq->u.Out.uDriverRevision = VBOX_SVN_REV;
 
-            pReq->Hdr.rc = supdrvCreateSession(pDevExt, false /* fUser */, &pSession);
+            pReq->Hdr.rc = supdrvCreateSession(pDevExt, false /* fUser */, true /*fUnrestricted*/, &pSession);
             if (RT_FAILURE(pReq->Hdr.rc))
             {
@@ -3224,5 +3315,18 @@
 
 
-/** @todo document me */
+/**
+ * Quries the AMD-V and VT-x capabilities of the calling CPU.
+ *
+ * @returns VBox status code.
+ * @retval  VERR_VMX_NO_VMX
+ * @retval  VERR_VMX_MSR_LOCKED_OR_DISABLED
+ * @retval  VERR_SVM_NO_SVM
+ * @retval  VERR_SVM_DISABLED
+ * @retval  VERR_UNSUPPORTED_CPU if not identifiable as an AMD, Intel or VIA
+ *          (centaur) CPU.
+ *
+ * @param   pSession        The session handle.
+ * @param   pfCaps          Where to store the capabilities.
+ */
 SUPR0DECL(int) SUPR0QueryVTCaps(PSUPDRVSESSION pSession, uint32_t *pfCaps)
 {
@@ -3237,33 +3341,29 @@
     if (ASMHasCpuId())
     {
-        uint32_t u32FeaturesECX;
-        uint32_t u32Dummy;
-        uint32_t u32FeaturesEDX;
-        uint32_t u32VendorEBX, u32VendorECX, u32VendorEDX, u32AMDFeatureEDX, u32AMDFeatureECX;
-        uint64_t val;
-
-        ASMCpuId(0, &u32Dummy, &u32VendorEBX, &u32VendorECX, &u32VendorEDX);
-        ASMCpuId(1, &u32Dummy, &u32Dummy, &u32FeaturesECX, &u32FeaturesEDX);
-        /* Query AMD features. */
-        ASMCpuId(0x80000001, &u32Dummy, &u32Dummy, &u32AMDFeatureECX, &u32AMDFeatureEDX);
-
-        if (    u32VendorEBX == X86_CPUID_VENDOR_INTEL_EBX
-            &&  u32VendorECX == X86_CPUID_VENDOR_INTEL_ECX
-            &&  u32VendorEDX == X86_CPUID_VENDOR_INTEL_EDX
+        uint32_t fFeaturesECX, fFeaturesEDX, uDummy;
+        uint32_t uMaxId, uVendorEBX, uVendorECX, uVendorEDX;
+        uint64_t u64Value;
+
+        ASMCpuId(0, &uMaxId, &uVendorEBX, &uVendorECX, &uVendorEDX);
+        ASMCpuId(1, &uDummy, &uDummy, &fFeaturesECX, &fFeaturesEDX);
+
+        if (   ASMIsValidStdRange(uMaxId)
+            && (   ASMIsIntelCpuEx(    uVendorEBX, uVendorECX, uVendorEDX)
+                || ASMIsViaCentaurCpuEx(uVendorEBX, uVendorECX, uVendorEDX) )
            )
         {
-            if (    (u32FeaturesECX & X86_CPUID_FEATURE_ECX_VMX)
-                 && (u32FeaturesEDX & X86_CPUID_FEATURE_EDX_MSR)
-                 && (u32FeaturesEDX & X86_CPUID_FEATURE_EDX_FXSR)
+            if (    (fFeaturesECX & X86_CPUID_FEATURE_ECX_VMX)
+                 && (fFeaturesEDX & X86_CPUID_FEATURE_EDX_MSR)
+                 && (fFeaturesEDX & X86_CPUID_FEATURE_EDX_FXSR)
                )
             {
-                val = ASMRdMsr(MSR_IA32_FEATURE_CONTROL);
                 /*
                  * Both the LOCK and VMXON bit must be set; otherwise VMXON will generate a #GP.
                  * Once the lock bit is set, this MSR can no longer be modified.
                  */
-                if (       (val & (MSR_IA32_FEATURE_CONTROL_VMXON|MSR_IA32_FEATURE_CONTROL_LOCK))
-                        ==        (MSR_IA32_FEATURE_CONTROL_VMXON|MSR_IA32_FEATURE_CONTROL_LOCK) /* enabled and locked */
-                    ||  !(val & MSR_IA32_FEATURE_CONTROL_LOCK) /* not enabled, but not locked either */
+                u64Value = ASMRdMsr(MSR_IA32_FEATURE_CONTROL);
+                if (      (u64Value & (MSR_IA32_FEATURE_CONTROL_VMXON | MSR_IA32_FEATURE_CONTROL_LOCK))
+                       ==             (MSR_IA32_FEATURE_CONTROL_VMXON | MSR_IA32_FEATURE_CONTROL_LOCK) /* enabled and locked */
+                    || !(u64Value & MSR_IA32_FEATURE_CONTROL_LOCK) /* not enabled, but not locked either */
                    )
                 {
@@ -3286,24 +3386,27 @@
         }
 
-        if (    u32VendorEBX == X86_CPUID_VENDOR_AMD_EBX
-            &&  u32VendorECX == X86_CPUID_VENDOR_AMD_ECX
-            &&  u32VendorEDX == X86_CPUID_VENDOR_AMD_EDX
-           )
-        {
-            if (   (u32AMDFeatureECX & X86_CPUID_AMD_FEATURE_ECX_SVM)
-                && (u32FeaturesEDX & X86_CPUID_FEATURE_EDX_MSR)
-                && (u32FeaturesEDX & X86_CPUID_FEATURE_EDX_FXSR)
+        if (   ASMIsAmdCpuEx(uVendorEBX, uVendorECX, uVendorEDX)
+            && ASMIsValidStdRange(uMaxId))
+        {
+            uint32_t fExtFeaturesEcx, uExtMaxId;
+            ASMCpuId(0x80000000, &uExtMaxId, &uDummy, &uDummy, &uDummy);
+            ASMCpuId(0x80000001, &uDummy, &uDummy, &fExtFeaturesEcx, &uDummy);
+            if (   ASMIsValidExtRange(uExtMaxId)
+                && uExtMaxId >= 0x8000000a
+                && (fExtFeaturesEcx & X86_CPUID_AMD_FEATURE_ECX_SVM)
+                && (fFeaturesEDX    & X86_CPUID_FEATURE_EDX_MSR)
+                && (fFeaturesEDX    & X86_CPUID_FEATURE_EDX_FXSR)
                )
             {
                 /* Check if SVM is disabled */
-                val = ASMRdMsr(MSR_K8_VM_CR);
-                if (!(val & MSR_K8_VM_CR_SVM_DISABLE))
+                u64Value = ASMRdMsr(MSR_K8_VM_CR);
+                if (!(u64Value & MSR_K8_VM_CR_SVM_DISABLE))
                 {
                     *pfCaps |= SUPVTCAPS_AMD_V;
 
-                    /* Query AMD features. */
-                    ASMCpuId(0x8000000A, &u32Dummy, &u32Dummy, &u32Dummy, &u32FeaturesEDX);
-
-                    if (u32FeaturesEDX & AMD_CPUID_SVM_FEATURE_EDX_NESTED_PAGING)
+                    /* Query AMD-V features. */
+                    uint32_t fSvmFeatures;
+                    ASMCpuId(0x8000000a, &uDummy, &uDummy, &uDummy, &fSvmFeatures);
+                    if (fSvmFeatures & AMD_CPUID_SVM_FEATURE_EDX_NESTED_PAGING)
                         *pfCaps |= SUPVTCAPS_NESTED_PAGING;
 
@@ -5477,8 +5580,6 @@
         /* Check for "AuthenticAMD" */
         ASMCpuId(0, &uEAX, &uEBX, &uECX, &uEDX);
-        if (    uEAX >= 1
-            &&  uEBX == X86_CPUID_VENDOR_AMD_EBX
-            &&  uECX == X86_CPUID_VENDOR_AMD_ECX
-            &&  uEDX == X86_CPUID_VENDOR_AMD_EDX)
+        if (   uEAX >= 1
+            && ASMIsAmdCpuEx(uEBX, uECX, uEDX))
         {
             /* Check for APM support and that TscInvariant is cleared. */
Index: /trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h	(revision 44172)
+++ /trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h	(revision 44173)
@@ -407,4 +407,6 @@
     /** Session Cookie. */
     uint32_t                        u32Cookie;
+    /** Set if is an unrestricted session, clear if restricted. */
+    bool                            fUnrestricted;
 
     /** The VM associated with the session. */
@@ -675,5 +677,5 @@
 int  VBOXCALL   supdrvInitDevExt(PSUPDRVDEVEXT pDevExt, size_t cbSession);
 void VBOXCALL   supdrvDeleteDevExt(PSUPDRVDEVEXT pDevExt);
-int  VBOXCALL   supdrvCreateSession(PSUPDRVDEVEXT pDevExt, bool fUser, PSUPDRVSESSION *ppSession);
+int  VBOXCALL   supdrvCreateSession(PSUPDRVDEVEXT pDevExt, bool fUser, bool fUnrestricted,  PSUPDRVSESSION *ppSession);
 void VBOXCALL   supdrvCloseSession(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession);
 void VBOXCALL   supdrvCleanupSession(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession);
Index: /trunk/src/VBox/HostDrivers/Support/SUPLib.cpp
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/SUPLib.cpp	(revision 44172)
+++ /trunk/src/VBox/HostDrivers/Support/SUPLib.cpp	(revision 44173)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -98,9 +98,10 @@
 SUPLIBDATA                      g_supLibData =
 {
-    SUP_HDEVICE_NIL
+    /*.hDevice              = */    SUP_HDEVICE_NIL,
+    /*.fUnrestricted        = */    true
 #if   defined(RT_OS_DARWIN)
-    , NULL
+    ,/* .uConnection        = */    NULL
 #elif defined(RT_OS_LINUX)
-    , false
+    ,/* .fSysMadviseWorks   = */    false
 #endif
 };
@@ -210,5 +211,5 @@
 
 
-SUPR3DECL(int) SUPR3Init(PSUPDRVSESSION *ppSession)
+SUPR3DECL(int) SUPR3InitEx(bool fUnrestricted, PSUPDRVSESSION *ppSession)
 {
     /*
@@ -229,5 +230,14 @@
         *ppSession = g_pSession;
     if (g_cInits++ > 0)
+    {
+        if (fUnrestricted && !g_supLibData.fUnrestricted)
+        {
+            g_cInits--;
+            if (ppSession)
+                *ppSession = NULL;
+            return VERR_VM_DRIVER_NOT_ACCESSIBLE; /** @todo different status code? */
+        }
         return VINF_SUCCESS;
+    }
 
     /*
@@ -252,5 +262,5 @@
      * Open the support driver.
      */
-    int rc = suplibOsInit(&g_supLibData, g_fPreInited);
+    int rc = suplibOsInit(&g_supLibData, g_fPreInited, fUnrestricted);
     if (RT_SUCCESS(rc))
     {
@@ -282,62 +292,73 @@
                  * Query the functions.
                  */
-                PSUPQUERYFUNCS pFuncsReq = (PSUPQUERYFUNCS)RTMemAllocZ(SUP_IOCTL_QUERY_FUNCS_SIZE(CookieReq.u.Out.cFunctions));
-                if (pFuncsReq)
+                PSUPQUERYFUNCS pFuncsReq = NULL;
+                if (g_supLibData.fUnrestricted)
                 {
-                    pFuncsReq->Hdr.u32Cookie            = CookieReq.u.Out.u32Cookie;
-                    pFuncsReq->Hdr.u32SessionCookie     = CookieReq.u.Out.u32SessionCookie;
-                    pFuncsReq->Hdr.cbIn                 = SUP_IOCTL_QUERY_FUNCS_SIZE_IN;
-                    pFuncsReq->Hdr.cbOut                = SUP_IOCTL_QUERY_FUNCS_SIZE_OUT(CookieReq.u.Out.cFunctions);
-                    pFuncsReq->Hdr.fFlags               = SUPREQHDR_FLAGS_DEFAULT;
-                    pFuncsReq->Hdr.rc                   = VERR_INTERNAL_ERROR;
-                    rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_QUERY_FUNCS(CookieReq.u.Out.cFunctions), pFuncsReq, SUP_IOCTL_QUERY_FUNCS_SIZE(CookieReq.u.Out.cFunctions));
-                    if (RT_SUCCESS(rc))
-                        rc = pFuncsReq->Hdr.rc;
-                    if (RT_SUCCESS(rc))
+                    pFuncsReq = (PSUPQUERYFUNCS)RTMemAllocZ(SUP_IOCTL_QUERY_FUNCS_SIZE(CookieReq.u.Out.cFunctions));
+                    if (pFuncsReq)
                     {
-                        /*
-                         * Map the GIP into userspace.
-                         */
-                        Assert(!g_pSUPGlobalInfoPage);
-                        SUPGIPMAP GipMapReq;
-                        GipMapReq.Hdr.u32Cookie         = CookieReq.u.Out.u32Cookie;
-                        GipMapReq.Hdr.u32SessionCookie  = CookieReq.u.Out.u32SessionCookie;
-                        GipMapReq.Hdr.cbIn              = SUP_IOCTL_GIP_MAP_SIZE_IN;
-                        GipMapReq.Hdr.cbOut             = SUP_IOCTL_GIP_MAP_SIZE_OUT;
-                        GipMapReq.Hdr.fFlags            = SUPREQHDR_FLAGS_DEFAULT;
-                        GipMapReq.Hdr.rc                = VERR_INTERNAL_ERROR;
-                        GipMapReq.u.Out.HCPhysGip       = NIL_RTHCPHYS;
-                        GipMapReq.u.Out.pGipR0          = NIL_RTR0PTR;
-                        GipMapReq.u.Out.pGipR3          = NULL;
-                        rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_GIP_MAP, &GipMapReq, SUP_IOCTL_GIP_MAP_SIZE);
+                        pFuncsReq->Hdr.u32Cookie            = CookieReq.u.Out.u32Cookie;
+                        pFuncsReq->Hdr.u32SessionCookie     = CookieReq.u.Out.u32SessionCookie;
+                        pFuncsReq->Hdr.cbIn                 = SUP_IOCTL_QUERY_FUNCS_SIZE_IN;
+                        pFuncsReq->Hdr.cbOut                = SUP_IOCTL_QUERY_FUNCS_SIZE_OUT(CookieReq.u.Out.cFunctions);
+                        pFuncsReq->Hdr.fFlags               = SUPREQHDR_FLAGS_DEFAULT;
+                        pFuncsReq->Hdr.rc                   = VERR_INTERNAL_ERROR;
+                        rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_QUERY_FUNCS(CookieReq.u.Out.cFunctions), pFuncsReq,
+                                           SUP_IOCTL_QUERY_FUNCS_SIZE(CookieReq.u.Out.cFunctions));
                         if (RT_SUCCESS(rc))
-                            rc = GipMapReq.Hdr.rc;
+                            rc = pFuncsReq->Hdr.rc;
                         if (RT_SUCCESS(rc))
                         {
-                            AssertRelease(GipMapReq.u.Out.pGipR3->u32Magic == SUPGLOBALINFOPAGE_MAGIC);
-                            AssertRelease(GipMapReq.u.Out.pGipR3->u32Version >= SUPGLOBALINFOPAGE_VERSION);
-
                             /*
-                             * Set the globals and return success.
+                             * Map the GIP into userspace.
                              */
-                            ASMAtomicXchgSize(&g_HCPhysSUPGlobalInfoPage, GipMapReq.u.Out.HCPhysGip);
-                            ASMAtomicCmpXchgPtr((void * volatile *)&g_pSUPGlobalInfoPage, GipMapReq.u.Out.pGipR3, NULL);
-                            ASMAtomicCmpXchgPtr((void * volatile *)&g_pSUPGlobalInfoPageR0, (void *)GipMapReq.u.Out.pGipR0, NULL);
-
-                            g_u32Cookie         = CookieReq.u.Out.u32Cookie;
-                            g_u32SessionCookie  = CookieReq.u.Out.u32SessionCookie;
-                            g_pSession          = CookieReq.u.Out.pSession;
-                            g_pFunctions        = pFuncsReq;
-                            if (ppSession)
-                                *ppSession = CookieReq.u.Out.pSession;
-                            return VINF_SUCCESS;
+                            Assert(!g_pSUPGlobalInfoPage);
+                            SUPGIPMAP GipMapReq;
+                            GipMapReq.Hdr.u32Cookie         = CookieReq.u.Out.u32Cookie;
+                            GipMapReq.Hdr.u32SessionCookie  = CookieReq.u.Out.u32SessionCookie;
+                            GipMapReq.Hdr.cbIn              = SUP_IOCTL_GIP_MAP_SIZE_IN;
+                            GipMapReq.Hdr.cbOut             = SUP_IOCTL_GIP_MAP_SIZE_OUT;
+                            GipMapReq.Hdr.fFlags            = SUPREQHDR_FLAGS_DEFAULT;
+                            GipMapReq.Hdr.rc                = VERR_INTERNAL_ERROR;
+                            GipMapReq.u.Out.HCPhysGip       = NIL_RTHCPHYS;
+                            GipMapReq.u.Out.pGipR0          = NIL_RTR0PTR;
+                            GipMapReq.u.Out.pGipR3          = NULL;
+                            rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_GIP_MAP, &GipMapReq, SUP_IOCTL_GIP_MAP_SIZE);
+                            if (RT_SUCCESS(rc))
+                                rc = GipMapReq.Hdr.rc;
+                            if (RT_SUCCESS(rc))
+                            {
+                                /*
+                                 * Set the GIP globals.
+                                 */
+                                AssertRelease(GipMapReq.u.Out.pGipR3->u32Magic == SUPGLOBALINFOPAGE_MAGIC);
+                                AssertRelease(GipMapReq.u.Out.pGipR3->u32Version >= SUPGLOBALINFOPAGE_VERSION);
+
+                                ASMAtomicXchgSize(&g_HCPhysSUPGlobalInfoPage, GipMapReq.u.Out.HCPhysGip);
+                                ASMAtomicCmpXchgPtr((void * volatile *)&g_pSUPGlobalInfoPage, GipMapReq.u.Out.pGipR3, NULL);
+                                ASMAtomicCmpXchgPtr((void * volatile *)&g_pSUPGlobalInfoPageR0, (void *)GipMapReq.u.Out.pGipR0, NULL);
+                            }
                         }
                     }
-
-                    /* bailout */
-                    RTMemFree(pFuncsReq);
+                    else
+                        rc = VERR_NO_MEMORY;
                 }
-                else
-                    rc = VERR_NO_MEMORY;
+
+                if (RT_SUCCESS(rc))
+                {
+                    /*
+                     * Set the globals and return success.
+                     */
+                    g_u32Cookie         = CookieReq.u.Out.u32Cookie;
+                    g_u32SessionCookie  = CookieReq.u.Out.u32SessionCookie;
+                    g_pSession          = CookieReq.u.Out.pSession;
+                    g_pFunctions        = pFuncsReq;
+                    if (ppSession)
+                        *ppSession = CookieReq.u.Out.pSession;
+                    return VINF_SUCCESS;
+                }
+
+                /* bailout */
+                RTMemFree(pFuncsReq);
             }
             else
@@ -371,4 +392,10 @@
 
     return rc;
+}
+
+
+SUPR3DECL(int) SUPR3Init(PSUPDRVSESSION *ppSession)
+{
+    return SUPR3InitEx(true, ppSession);
 }
 
Index: /trunk/src/VBox/HostDrivers/Support/SUPLibInternal.h
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/SUPLibInternal.h	(revision 44172)
+++ /trunk/src/VBox/HostDrivers/Support/SUPLibInternal.h	(revision 44173)
@@ -190,4 +190,7 @@
     int                 hDevice;
 #endif
+    /** Indicates whether we have unrestricted (true) or restricted access to the
+     * support device. */
+    bool                fUnrestricted;
 #if   defined(RT_OS_DARWIN)
     /** The connection to the VBoxSupDrv service. */
@@ -264,5 +267,5 @@
 int     suplibOsInstall(void);
 int     suplibOsUninstall(void);
-int     suplibOsInit(PSUPLIBDATA pThis, bool fPreInited);
+int     suplibOsInit(PSUPLIBDATA pThis, bool fPreInited, bool fUnrestricted);
 int     suplibOsTerm(PSUPLIBDATA pThis);
 int     suplibOsIOCtl(PSUPLIBDATA pThis, uintptr_t uFunction, void *pvReq, size_t cbReq);
Index: /trunk/src/VBox/HostDrivers/Support/SUPR3HardenedMain.cpp
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/SUPR3HardenedMain.cpp	(revision 44172)
+++ /trunk/src/VBox/HostDrivers/Support/SUPR3HardenedMain.cpp	(revision 44173)
@@ -578,5 +578,5 @@
 static void supR3HardenedMainOpenDevice(void)
 {
-    int rc = suplibOsInit(&g_SupPreInitData.Data, false);
+    int rc = suplibOsInit(&g_SupPreInitData.Data, false /*fPreInit*/, true /*fUnrestricted*/);
     if (RT_SUCCESS(rc))
         return;
Index: /trunk/src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp	(revision 44172)
+++ /trunk/src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp	(revision 44173)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -80,6 +80,8 @@
 *******************************************************************************/
 
-/** The module name. */
-#define DEVICE_NAME    "vboxdrv"
+/** The system device node name. */
+#define DEVICE_NAME_SYS     "vboxdrv"
+/** The user device node name. */
+#define DEVICE_NAME_USR     "vboxdrvu"
 
 
@@ -203,6 +205,8 @@
 /** Major device number. */
 static int              g_iMajorDeviceNo = -1;
-/** Registered devfs device handle. */
-static void            *g_hDevFsDevice = NULL;
+/** Registered devfs device handle for the system device. */
+static void            *g_hDevFsDeviceSys = NULL;
+/** Registered devfs device handle for the user device. */
+static void            *g_hDevFsDeviceUsr = NULL;
 
 /** Spinlock protecting g_apSessionHashTab. */
@@ -261,26 +265,36 @@
                 {
 #ifdef VBOX_WITH_HARDENING
-                    g_hDevFsDevice = devfs_make_node(makedev(g_iMajorDeviceNo, 0), DEVFS_CHAR,
-                                                     UID_ROOT, GID_WHEEL, 0600, DEVICE_NAME);
+                    g_hDevFsDeviceSys = devfs_make_node(makedev(g_iMajorDeviceNo, 0), DEVFS_CHAR,
+                                                        UID_ROOT, GID_WHEEL, 0600, DEVICE_NAME_SYS);
 #else
-                    g_hDevFsDevice = devfs_make_node(makedev(g_iMajorDeviceNo, 0), DEVFS_CHAR,
-                                                     UID_ROOT, GID_WHEEL, 0666, DEVICE_NAME);
+                    g_hDevFsDeviceSys = devfs_make_node(makedev(g_iMajorDeviceNo, 0), DEVFS_CHAR,
+                                                        UID_ROOT, GID_WHEEL, 0666, DEVICE_NAME_SYS);
 #endif
-                    if (g_hDevFsDevice)
+                    if (g_hDevFsDeviceSys)
                     {
-                        LogRel(("VBoxDrv: version " VBOX_VERSION_STRING " r%d; IOCtl version %#x; IDC version %#x; dev major=%d\n",
-                                VBOX_SVN_REV, SUPDRV_IOC_VERSION, SUPDRV_IDC_VERSION, g_iMajorDeviceNo));
-
-                        /* Register a sleep/wakeup notification callback */
-                        g_pSleepNotifier = registerPrioritySleepWakeInterest(&VBoxDrvDarwinSleepHandler, &g_DevExt, NULL);
-                        if (g_pSleepNotifier == NULL)
-                            LogRel(("VBoxDrv: register for sleep/wakeup events failed\n"));
-
-                        /* Find kernel symbols that are kind of optional. */
-                        vboxdrvDarwinResolveSymbols();
-                        return KMOD_RETURN_SUCCESS;
+                        g_hDevFsDeviceUsr = devfs_make_node(makedev(g_iMajorDeviceNo, 1), DEVFS_CHAR,
+                                                            UID_ROOT, GID_WHEEL, 0666, DEVICE_NAME_USR);
+                        if (g_hDevFsDeviceUsr)
+                        {
+                            LogRel(("VBoxDrv: version " VBOX_VERSION_STRING " r%d; IOCtl version %#x; IDC version %#x; dev major=%d\n",
+                                    VBOX_SVN_REV, SUPDRV_IOC_VERSION, SUPDRV_IDC_VERSION, g_iMajorDeviceNo));
+
+                            /* Register a sleep/wakeup notification callback */
+                            g_pSleepNotifier = registerPrioritySleepWakeInterest(&VBoxDrvDarwinSleepHandler, &g_DevExt, NULL);
+                            if (g_pSleepNotifier == NULL)
+                                LogRel(("VBoxDrv: register for sleep/wakeup events failed\n"));
+
+                            /* Find kernel symbols that are kind of optional. */
+                            vboxdrvDarwinResolveSymbols();
+                            return KMOD_RETURN_SUCCESS;
+                        }
+
+                        LogRel(("VBoxDrv: devfs_make_node(makedev(%d,1),,,,%s) failed\n", g_iMajorDeviceNo, DEVICE_NAME_USR));
+                        devfs_remove(g_hDevFsDeviceSys);
+                        g_hDevFsDeviceSys = NULL;
                     }
-
-                    LogRel(("VBoxDrv: devfs_make_node(makedev(%d,0),,,,%s) failed\n", g_iMajorDeviceNo, DEVICE_NAME));
+                    else
+                        LogRel(("VBoxDrv: devfs_make_node(makedev(%d,0),,,,%s) failed\n", g_iMajorDeviceNo, DEVICE_NAME_SYS));
+
                     cdevsw_remove(g_iMajorDeviceNo, &g_DevCW);
                     g_iMajorDeviceNo = -1;
@@ -360,6 +374,9 @@
     }
 
-    devfs_remove(g_hDevFsDevice);
-    g_hDevFsDevice = NULL;
+    devfs_remove(g_hDevFsDeviceUsr);
+    g_hDevFsDeviceUsr = NULL;
+
+    devfs_remove(g_hDevFsDeviceSys);
+    g_hDevFsDeviceSys = NULL;
 
     rc = cdevsw_remove(g_iMajorDeviceNo, &g_DevCW);
@@ -386,6 +403,8 @@
  * Device open. Called on open /dev/vboxdrv
  *
- * @param   pInode      Pointer to inode info structure.
- * @param   pFilp       Associated file pointer.
+ * @param   Dev         The device number.
+ * @param   fFlags      ???.
+ * @param   fDevType    ???.
+ * @param   pProcess    The process issuing this request.
  */
 static int VBoxDrvDarwinOpen(dev_t Dev, int fFlags, int fDevType, struct proc *pProcess)
@@ -399,8 +418,15 @@
 
     /*
+     * Only two minor devices numbers are allowed.
+     */
+    if (minor(Dev) != 0 && minor(Dev) != 1)
+        return EACCES;
+
+    /*
      * Find the session created by org_virtualbox_SupDrvClient, fail
      * if no such session, and mark it as opened. We set the uid & gid
      * here too, since that is more straight forward at this point.
      */
+    const bool      fUnrestricted = minor(Dev) == 0;
     int             rc = VINF_SUCCESS;
     PSUPDRVSESSION  pSession = NULL;
@@ -420,9 +446,6 @@
 
         pSession = g_apSessionHashTab[iHash];
-        if (pSession && pSession->Process != Process)
-        {
-            do pSession = pSession->pNextHash;
-            while (pSession && pSession->Process != Process);
-        }
+        while (pSession && pSession->Process != Process)
+            pSession = pSession->pNextHash;
         if (pSession)
         {
@@ -430,4 +453,5 @@
             {
                 pSession->fOpened = true;
+                pSession->fUnrestricted = fUnrestricted;
                 pSession->Uid = Uid;
                 pSession->Gid = Gid;
@@ -488,4 +512,5 @@
 static int VBoxDrvDarwinIOCtl(dev_t Dev, u_long iCmd, caddr_t pData, int fFlags, struct proc *pProcess)
 {
+    const bool          fUnrestricted = minor(Dev) == 0;
     const RTPROCESS     Process = proc_pid(pProcess);
     const unsigned      iHash = SESSION_HASH(Process);
@@ -497,9 +522,6 @@
     RTSpinlockAcquire(g_Spinlock);
     pSession = g_apSessionHashTab[iHash];
-    if (pSession && pSession->Process != Process)
-    {
-        do pSession = pSession->pNextHash;
-        while (pSession && pSession->Process != Process);
-    }
+    while (pSession && pSession->Process != Process && pSession->fUnrestricted == fUnrestricted && pSession->fOpened)
+        pSession = pSession->pNextHash;
     RTSpinlockReleaseNoInts(g_Spinlock);
     if (!pSession)
@@ -514,7 +536,8 @@
      * the session and iCmd, and only returns a VBox status code.
      */
-    if (    iCmd == SUP_IOCTL_FAST_DO_RAW_RUN
-        ||  iCmd == SUP_IOCTL_FAST_DO_HM_RUN
-        ||  iCmd == SUP_IOCTL_FAST_DO_NOP)
+    if (   (    iCmd == SUP_IOCTL_FAST_DO_RAW_RUN
+            ||  iCmd == SUP_IOCTL_FAST_DO_HM_RUN
+            ||  iCmd == SUP_IOCTL_FAST_DO_NOP)
+        && fUnrestricted)
         return supdrvIOCtlFast(iCmd, *(uint32_t *)pData, &g_DevExt, pSession);
     return VBoxDrvDarwinIOCtlSlow(pSession, iCmd, pData, pProcess);
@@ -1094,13 +1117,13 @@
              * Create a new session.
              */
-            int rc = supdrvCreateSession(&g_DevExt, true /* fUser */, &m_pSession);
+            int rc = supdrvCreateSession(&g_DevExt, true /* fUser */, false /*fUnrestricted*/, &m_pSession);
             if (RT_SUCCESS(rc))
             {
                 m_pSession->fOpened = false;
-                /* The Uid and Gid fields are set on open. */
+                /* The Uid, Gid and fUnrestricted fields are set on open. */
 
                 /*
                  * Insert it into the hash table, checking that there isn't
-                 * already one for this process first.
+                 * already one for this process first. (One session per proc!)
                  */
                 unsigned iHash = SESSION_HASH(m_pSession->Process);
@@ -1147,11 +1170,12 @@
 /**
  * Common worker for clientClose and VBoxDrvDarwinClose.
- *
- * It will
  */
 /* static */ void org_virtualbox_SupDrvClient::sessionClose(RTPROCESS Process)
 {
     /*
-     * Look for the session.
+     * Find the session and remove it from the hash table.
+     *
+     * Note! Only one session per process. (Both start() and
+     * VBoxDrvDarwinOpen makes sure this is so.)
      */
     const unsigned  iHash = SESSION_HASH(Process);
Index: /trunk/src/VBox/HostDrivers/Support/darwin/SUPLib-darwin.cpp
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/darwin/SUPLib-darwin.cpp	(revision 44172)
+++ /trunk/src/VBox/HostDrivers/Support/darwin/SUPLib-darwin.cpp	(revision 44173)
@@ -62,6 +62,8 @@
 *   Defined Constants And Macros                                               *
 *******************************************************************************/
-/** BSD Device name. */
-#define DEVICE_NAME     "/dev/vboxdrv"
+/** System device name. */
+#define DEVICE_NAME_SYS "/dev/vboxdrv"
+/** User device name. */
+#define DEVICE_NAME_USR "/dev/vboxdrvu"
 /** The IOClass key of the service (see SUPDrv-darwin.cpp / Info.plist). */
 #define IOCLASS_NAME    "org_virtualbox_SupDrv"
@@ -74,5 +76,5 @@
  * @returns VBox status code.
  */
-static int suplibDarwinOpenDevice(PSUPLIBDATA pThis)
+static int suplibDarwinOpenDevice(PSUPLIBDATA pThis, bool fUnrestricted)
 {
     /*
@@ -81,5 +83,5 @@
      * started, so it has to be done after opening the service (IOC v9.1+).
      */
-    int hDevice = open(DEVICE_NAME, O_RDWR, 0);
+    int hDevice = open(fUnrestricted ? DEVICE_NAME_SYS : DEVICE_NAME_USR, O_RDWR, 0);
     if (hDevice < 0)
     {
@@ -93,5 +95,5 @@
             default:        rc = VERR_VM_DRIVER_OPEN_ERROR; break;
         }
-        LogRel(("SUP: Failed to open \"%s\", errno=%d, rc=%Rrc\n", DEVICE_NAME, errno, rc));
+        LogRel(("SUP: Failed to open \"%s\", errno=%d, rc=%Rrc\n", fUnrestricted ? DEVICE_NAME_SYS : DEVICE_NAME_USR, errno, rc));
         return rc;
     }
@@ -113,5 +115,6 @@
     }
 
-    pThis->hDevice = hDevice;
+    pThis->hDevice       = hDevice;
+    pThis->fUnrestricted = fUnrestricted;
     return VINF_SUCCESS;
 }
@@ -183,5 +186,5 @@
 
 
-int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited)
+int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited, bool fUnrestricted)
 {
     /*
@@ -198,5 +201,5 @@
     if (RT_SUCCESS(rc))
     {
-        rc = suplibDarwinOpenDevice(pThis);
+        rc = suplibDarwinOpenDevice(pThis, fUnrestricted);
         if (RT_FAILURE(rc))
         {
Index: /trunk/src/VBox/HostDrivers/Support/freebsd/SUPDrv-freebsd.c
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/freebsd/SUPDrv-freebsd.c	(revision 44172)
+++ /trunk/src/VBox/HostDrivers/Support/freebsd/SUPDrv-freebsd.c	(revision 44173)
@@ -230,5 +230,5 @@
      * Create a new session.
      */
-    rc = supdrvCreateSession(&g_VBoxDrvFreeBSDDevExt, true /* fUser */, &pSession);
+    rc = supdrvCreateSession(&g_VBoxDrvFreeBSDDevExt, true /* fUser */, true /*fUnrestricted*/, &pSession);
     if (RT_SUCCESS(rc))
     {
Index: /trunk/src/VBox/HostDrivers/Support/freebsd/SUPLib-freebsd.cpp
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/freebsd/SUPLib-freebsd.cpp	(revision 44172)
+++ /trunk/src/VBox/HostDrivers/Support/freebsd/SUPLib-freebsd.cpp	(revision 44173)
@@ -61,10 +61,12 @@
 *   Defined Constants And Macros                                               *
 *******************************************************************************/
-/** FreeBSD base device name. */
-#define DEVICE_NAME     "/dev/vboxdrv"
+/** System device name. */
+#define DEVICE_NAME_SYS "/dev/vboxdrv"
+/** User device name. */
+#define DEVICE_NAME_USR "/dev/vboxdrvu"
 
 
 
-int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited)
+int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited, bool fUnrestricted)
 {
     /*
@@ -77,5 +79,5 @@
      * Try open the BSD device.
      */
-    int hDevice = open(DEVICE_NAME, O_RDWR, 0);
+    int hDevice = open(fUnrestricted ? DEVICE_NAME_SYS : DEVICE_NAME_USR, O_RDWR, 0);
     if (hDevice < 0)
     {
@@ -89,5 +91,5 @@
             default:        rc = VERR_VM_DRIVER_OPEN_ERROR; break;
         }
-        LogRel(("Failed to open \"%s\", errno=%d, rc=%Rrc\n", DEVICE_NAME, errno, rc));
+        LogRel(("Failed to open \"%s\", errno=%d, rc=%Rrc\n", fUnrestricted ? DEVICE_NAME_SYS : DEVICE_NAME_USR, errno, rc));
         return rc;
     }
@@ -112,5 +114,6 @@
      * We're done.
      */
-    pThis->hDevice = hDevice;
+    pThis->hDevice       = hDevice;
+    pThis->fUnrestricted = fUnrestricted;
     return VINF_SUCCESS;
 }
Index: /trunk/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c	(revision 44172)
+++ /trunk/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c	(revision 44173)
@@ -436,5 +436,5 @@
      * Call common code for the rest.
      */
-    rc = supdrvCreateSession(&g_DevExt, true /* fUser */, &pSession);
+    rc = supdrvCreateSession(&g_DevExt, true /* fUser */, true /*fUnrestricted*/, &pSession);
     if (!rc)
     {
Index: /trunk/src/VBox/HostDrivers/Support/linux/SUPLib-linux.cpp
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/linux/SUPLib-linux.cpp	(revision 44172)
+++ /trunk/src/VBox/HostDrivers/Support/linux/SUPLib-linux.cpp	(revision 44173)
@@ -62,6 +62,8 @@
 *   Defined Constants And Macros                                               *
 *******************************************************************************/
-/** Unix Device name. */
-#define DEVICE_NAME     "/dev/vboxdrv"
+/** System device name. */
+#define DEVICE_NAME_SYS     "/dev/vboxdrv"
+/** User device name. */
+#define DEVICE_NAME_USR     "/dev/vboxdrvu"
 
 /* define MADV_DONTFORK if it's missing from the system headers. */
@@ -72,5 +74,5 @@
 
 
-int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited)
+int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited, bool fUnrestricted)
 {
     /*
@@ -93,5 +95,5 @@
      * Try open the device.
      */
-    int hDevice = open(DEVICE_NAME, O_RDWR, 0);
+    int hDevice = open(fUnrestricted ? DEVICE_NAME_SYS : DEVICE_NAME_USR, O_RDWR, 0);
     if (hDevice < 0)
     {
@@ -99,5 +101,5 @@
          * Try load the device.
          */
-        hDevice = open(DEVICE_NAME, O_RDWR, 0);
+        hDevice = open(fUnrestricted ? DEVICE_NAME_SYS : DEVICE_NAME_USR, O_RDWR, 0);
         if (hDevice < 0)
         {
@@ -133,5 +135,6 @@
      * We're done.
      */
-    pThis->hDevice = hDevice;
+    pThis->hDevice       = hDevice;
+    pThis->fUnrestricted = fUnrestricted;
     return VINF_SUCCESS;
 }
Index: /trunk/src/VBox/HostDrivers/Support/os2/SUPDrv-os2.cpp
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/os2/SUPDrv-os2.cpp	(revision 44172)
+++ /trunk/src/VBox/HostDrivers/Support/os2/SUPDrv-os2.cpp	(revision 44173)
@@ -151,5 +151,5 @@
      * Create a new session.
      */
-    rc = supdrvCreateSession(&g_DevExt, true /* fUser */, &pSession);
+    rc = supdrvCreateSession(&g_DevExt, true /* fUser */, true /*fUnrestricted*/, &pSession);
     if (RT_SUCCESS(rc))
     {
Index: /trunk/src/VBox/HostDrivers/Support/os2/SUPLib-os2.cpp
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/os2/SUPLib-os2.cpp	(revision 44172)
+++ /trunk/src/VBox/HostDrivers/Support/os2/SUPLib-os2.cpp	(revision 44173)
@@ -66,5 +66,5 @@
 
 
-int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited)
+int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited, bool fUnrestricted)
 {
     /*
@@ -101,4 +101,5 @@
 
     pThis->hDevice = hDevice;
+    pThis->fUnrestricted = true;
     return VINF_SUCCESS;
 }
Index: /trunk/src/VBox/HostDrivers/Support/solaris/SUPDrv-solaris.c
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/solaris/SUPDrv-solaris.c	(revision 44172)
+++ /trunk/src/VBox/HostDrivers/Support/solaris/SUPDrv-solaris.c	(revision 44173)
@@ -197,5 +197,5 @@
 int _init(void)
 {
-    LogFlowFunc((DEVICE_NAME ":_init\n"));
+    LogFlowFunc(("vboxdrv:_init\n"));
 
     /*
@@ -206,5 +206,5 @@
         pModCtl->mod_loadflags |= MOD_NOAUTOUNLOAD;
     else
-        LogRel((DEVICE_NAME ":failed to disable autounloading!\n"));
+        LogRel(("vboxdrv: failed to disable autounloading!\n"));
 
     /*
@@ -235,8 +235,8 @@
 
                     ddi_soft_state_fini(&g_pVBoxDrvSolarisState);
-                    LogRel((DEVICE_NAME ":mod_install failed! rc=%d\n", rc));
+                    LogRel(("vboxdrv: mod_install failed! rc=%d\n", rc));
                 }
                 else
-                    LogRel((DEVICE_NAME ":failed to initialize soft state.\n"));
+                    LogRel(("vboxdrv: failed to initialize soft state.\n"));
 
                 RTSpinlockDestroy(g_Spinlock);
@@ -245,5 +245,5 @@
             else
             {
-                LogRel((DEVICE_NAME ":VBoxDrvSolarisAttach: RTSpinlockCreate failed\n"));
+                LogRel(("VBoxDrvSolarisAttach: RTSpinlockCreate failed\n"));
                 rc = RTErrConvertToErrno(rc);
             }
@@ -252,5 +252,5 @@
         else
         {
-            LogRel((DEVICE_NAME ":VBoxDrvSolarisAttach: supdrvInitDevExt failed\n"));
+            LogRel(("VBoxDrvSolarisAttach: supdrvInitDevExt failed\n"));
             rc = RTErrConvertToErrno(rc);
         }
@@ -259,5 +259,5 @@
     else
     {
-        LogRel((DEVICE_NAME ":VBoxDrvSolarisAttach: failed to init R0Drv\n"));
+        LogRel(("VBoxDrvSolarisAttach: failed to init R0Drv\n"));
         rc = RTErrConvertToErrno(rc);
     }
@@ -270,5 +270,5 @@
 int _fini(void)
 {
-    LogFlowFunc((DEVICE_NAME ":_fini\n"));
+    LogFlowFunc(("vboxdrv:_fini\n"));
 
     /*
@@ -296,5 +296,5 @@
 int _info(struct modinfo *pModInfo)
 {
-    LogFlowFunc((DEVICE_NAME ":_info\n"));
+    LogFlowFunc(("vboxdrv:_info\n"));
     int e = mod_info(&g_VBoxDrvSolarisModLinkage, pModInfo);
     return e;
@@ -312,5 +312,5 @@
 static int VBoxDrvSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd)
 {
-    LogFlowFunc((DEVICE_NAME ":VBoxDrvSolarisAttach\n"));
+    LogFlowFunc(("VBoxDrvSolarisAttach\n"));
 
     switch (enmCmd)
@@ -325,5 +325,5 @@
             if (ddi_soft_state_zalloc(g_pVBoxDrvSolarisState, instance) != DDI_SUCCESS)
             {
-                LogRel((DEVICE_NAME ":VBoxDrvSolarisAttach: state alloc failed\n"));
+                LogRel(("VBoxDrvSolarisAttach: state alloc failed\n"));
                 return DDI_FAILURE;
             }
@@ -338,5 +338,5 @@
                                 "pm-hardware-state", "needs-suspend-resume", sizeof("needs-suspend-resume"));
             if (rc != DDI_PROP_SUCCESS)
-                LogRel((DEVICE_NAME ":Suspend/Resume notification registration failed.\n"));
+                LogRel(("vboxdrv: Suspend/Resume notification registration failed.\n"));
 
             /*
@@ -372,5 +372,5 @@
 #endif
             RTPowerSignalEvent(RTPOWEREVENT_RESUME);
-            LogFlow((DEVICE_NAME ": Awakened from suspend.\n"));
+            LogFlow(("vboxdrv: Awakened from suspend.\n"));
             return DDI_SUCCESS;
         }
@@ -394,5 +394,5 @@
 static int VBoxDrvSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd)
 {
-    LogFlowFunc((DEVICE_NAME ":VBoxDrvSolarisDetach\n"));
+    LogFlowFunc(("VBoxDrvSolarisDetach\n"));
     switch (enmCmd)
     {
@@ -421,5 +421,5 @@
 #endif
             RTPowerSignalEvent(RTPOWEREVENT_SUSPEND);
-            LogFlow((DEVICE_NAME ": Falling to suspend mode.\n"));
+            LogFlow(("vboxdrv: Falling to suspend mode.\n"));
             return DDI_SUCCESS;
 
@@ -440,5 +440,5 @@
     int                 rc;
     PSUPDRVSESSION      pSession;
-    LogFlowFunc((DEVICE_NAME ":VBoxDrvSolarisOpen: pDev=%p:%#x\n", pDev, *pDev));
+    LogFlowFunc(("VBoxDrvSolarisOpen: pDev=%p:%#x\n", pDev, *pDev));
 
 #ifndef USE_SESSION_HASH
@@ -462,5 +462,5 @@
     if (!pState)
     {
-        LogRel((DEVICE_NAME ":VBoxDrvSolarisOpen: too many open instances.\n"));
+        LogRel(("VBoxDrvSolarisOpen: too many open instances.\n"));
         return ENXIO;
     }
@@ -469,5 +469,5 @@
      * Create a new session.
      */
-    rc = supdrvCreateSession(&g_DevExt, true /* fUser */, &pSession);
+    rc = supdrvCreateSession(&g_DevExt, true /* fUser */, true /*fUnrestricted*/, &pSession);
     if (RT_SUCCESS(rc))
     {
@@ -477,6 +477,6 @@
         pState->pSession = pSession;
         *pDev = makedevice(getmajor(*pDev), iOpenInstance);
-        LogFlow((DEVICE_NAME ":VBoxDrvSolarisOpen: Dev=%#x pSession=%p pid=%d r0proc=%p thread=%p\n",
-                    *pDev, pSession, RTProcSelf(), RTR0ProcHandleSelf(), RTThreadNativeSelf() ));
+        LogFlow(("VBoxDrvSolarisOpen: Dev=%#x pSession=%p pid=%d r0proc=%p thread=%p\n",
+                 *pDev, pSession, RTProcSelf(), RTR0ProcHandleSelf(), RTThreadNativeSelf() ));
         return 0;
     }
@@ -491,5 +491,5 @@
      * in VBoxDrvSolarisIOCtlSlow() while calling supdrvIOCtl()
      */
-    rc = supdrvCreateSession(&g_DevExt, true /* fUser */, &pSession);
+    rc = supdrvCreateSession(&g_DevExt, true /* fUser */, true /*fUnrestricted*/, &pSession);
     if (RT_SUCCESS(rc))
     {
@@ -507,5 +507,5 @@
         g_apSessionHashTab[iHash] = pSession;
         RTSpinlockReleaseNoInts(g_Spinlock);
-        LogFlow((DEVICE_NAME ":VBoxDrvSolarisOpen success\n"));
+        LogFlow(("VBoxDrvSolarisOpen success\n"));
     }
 
@@ -520,5 +520,5 @@
     if (instance >= DEVICE_MAXINSTANCES)
     {
-        LogRel((DEVICE_NAME ":VBoxDrvSolarisOpen: All instances exhausted\n"));
+        LogRel(("VBoxDrvSolarisOpen: All instances exhausted\n"));
         return ENXIO;
     }
@@ -533,5 +533,5 @@
 static int VBoxDrvSolarisClose(dev_t Dev, int flag, int otyp, cred_t *cred)
 {
-    LogFlowFunc((DEVICE_NAME ":VBoxDrvSolarisClose: Dev=%#x\n", Dev));
+    LogFlowFunc(("VBoxDrvSolarisClose: Dev=%#x\n", Dev));
 
 #ifndef USE_SESSION_HASH
@@ -542,5 +542,5 @@
     if (!pState)
     {
-        LogRel((DEVICE_NAME ":VBoxDrvSolarisClose: no state data for %#x (%d)\n", Dev, getminor(Dev)));
+        LogRel(("VBoxDrvSolarisClose: no state data for %#x (%d)\n", Dev, getminor(Dev)));
         return EFAULT;
     }
@@ -552,8 +552,8 @@
     if (!pSession)
     {
-        LogRel((DEVICE_NAME ":VBoxDrvSolarisClose: no session in state data for %#x (%d)\n", Dev, getminor(Dev)));
+        LogRel(("VBoxDrvSolarisClose: no session in state data for %#x (%d)\n", Dev, getminor(Dev)));
         return EFAULT;
     }
-    LogFlow((DEVICE_NAME ":VBoxDrvSolarisClose: Dev=%#x pSession=%p pid=%d r0proc=%p thread=%p\n",
+    LogFlow(("VBoxDrvSolarisClose: Dev=%#x pSession=%p pid=%d r0proc=%p thread=%p\n",
             Dev, pSession, RTProcSelf(), RTR0ProcHandleSelf(), RTThreadNativeSelf() ));
 
@@ -597,6 +597,5 @@
     if (!pSession)
     {
-        LogRel((DEVICE_NAME ":VBoxDrvSolarisClose: WHAT?!? pSession == NULL! This must be a mistake... pid=%d (close)\n",
-                    (int)Process));
+        LogRel(("VBoxDrvSolarisClose: WHAT?!? pSession == NULL! This must be a mistake... pid=%d (close)\n", (int)Process));
         return EFAULT;
     }
@@ -613,5 +612,5 @@
 static int VBoxDrvSolarisRead(dev_t Dev, struct uio *pUio, cred_t *pCred)
 {
-    LogFlowFunc((DEVICE_NAME ":VBoxDrvSolarisRead"));
+    LogFlowFunc(("VBoxDrvSolarisRead"));
     return 0;
 }
@@ -620,5 +619,5 @@
 static int VBoxDrvSolarisWrite(dev_t Dev, struct uio *pUio, cred_t *pCred)
 {
-    LogFlowFunc((DEVICE_NAME ":VBoxDrvSolarisWrite"));
+    LogFlowFunc(("VBoxDrvSolarisWrite"));
     return 0;
 }
@@ -646,5 +645,5 @@
     if (!pState)
     {
-        LogRel((DEVICE_NAME ":VBoxDrvSolarisIOCtl: no state data for %#x (%d)\n", Dev, getminor(Dev)));
+        LogRel(("VBoxDrvSolarisIOCtl: no state data for %#x (%d)\n", Dev, getminor(Dev)));
         return EINVAL;
     }
@@ -653,5 +652,5 @@
     if (!pSession)
     {
-        LogRel((DEVICE_NAME ":VBoxDrvSolarisIOCtl: no session in state data for %#x (%d)\n", Dev, getminor(Dev)));
+        LogRel(("VBoxDrvSolarisIOCtl: no session in state data for %#x (%d)\n", Dev, getminor(Dev)));
         return DDI_SUCCESS;
     }
@@ -674,5 +673,5 @@
     if (!pSession)
     {
-        LogRel((DEVICE_NAME ":VBoxSupDrvIOCtl: WHAT?!? pSession == NULL! This must be a mistake... pid=%d iCmd=%#x\n",
+        LogRel(("VBoxSupDrvIOCtl: WHAT?!? pSession == NULL! This must be a mistake... pid=%d iCmd=%#x\n",
                     (int)Process, Cmd));
         return EINVAL;
@@ -732,5 +731,5 @@
     if (RT_UNLIKELY(IOCPARM_LEN(iCmd) != sizeof(StackBuf.Hdr)))
     {
-        LogRel((DEVICE_NAME ":VBoxDrvSolarisIOCtlSlow: iCmd=%#x len %d expected %d\n", iCmd, IOCPARM_LEN(iCmd), sizeof(StackBuf.Hdr)));
+        LogRel(("VBoxDrvSolarisIOCtlSlow: iCmd=%#x len %d expected %d\n", iCmd, IOCPARM_LEN(iCmd), sizeof(StackBuf.Hdr)));
         return EINVAL;
     }
@@ -738,10 +737,10 @@
     if (RT_UNLIKELY(rc))
     {
-        LogRel((DEVICE_NAME ":VBoxDrvSolarisIOCtlSlow: ddi_copyin(,%#lx,) failed; iCmd=%#x. rc=%d\n", iArg, iCmd, rc));
+        LogRel(("VBoxDrvSolarisIOCtlSlow: ddi_copyin(,%#lx,) failed; iCmd=%#x. rc=%d\n", iArg, iCmd, rc));
         return EFAULT;
     }
     if (RT_UNLIKELY((StackBuf.Hdr.fFlags & SUPREQHDR_FLAGS_MAGIC_MASK) != SUPREQHDR_FLAGS_MAGIC))
     {
-        LogRel((DEVICE_NAME ":VBoxDrvSolarisIOCtlSlow: bad header magic %#x; iCmd=%#x\n", StackBuf.Hdr.fFlags & SUPREQHDR_FLAGS_MAGIC_MASK, iCmd));
+        LogRel(("VBoxDrvSolarisIOCtlSlow: bad header magic %#x; iCmd=%#x\n", StackBuf.Hdr.fFlags & SUPREQHDR_FLAGS_MAGIC_MASK, iCmd));
         return EINVAL;
     }
@@ -751,5 +750,5 @@
                     ||  cbBuf > _1M*16))
     {
-        LogRel((DEVICE_NAME ":VBoxDrvSolarisIOCtlSlow: max(%#x,%#x); iCmd=%#x\n", StackBuf.Hdr.cbIn, StackBuf.Hdr.cbOut, iCmd));
+        LogRel(("VBoxDrvSolarisIOCtlSlow: max(%#x,%#x); iCmd=%#x\n", StackBuf.Hdr.cbIn, StackBuf.Hdr.cbOut, iCmd));
         return EINVAL;
     }
@@ -765,5 +764,5 @@
         if (RT_UNLIKELY(!pHdr))
         {
-            LogRel((DEVICE_NAME ":VBoxDrvSolarisIOCtlSlow: failed to allocate buffer of %d bytes for iCmd=%#x.\n", cbBuf, iCmd));
+            LogRel(("VBoxDrvSolarisIOCtlSlow: failed to allocate buffer of %d bytes for iCmd=%#x.\n", cbBuf, iCmd));
             return ENOMEM;
         }
@@ -772,5 +771,5 @@
     if (RT_UNLIKELY(rc))
     {
-        LogRel((DEVICE_NAME ":VBoxDrvSolarisIOCtlSlow: copy_from_user(,%#lx, %#x) failed; iCmd=%#x. rc=%d\n", iArg, cbBuf, iCmd, rc));
+        LogRel(("VBoxDrvSolarisIOCtlSlow: copy_from_user(,%#lx, %#x) failed; iCmd=%#x. rc=%d\n", iArg, cbBuf, iCmd, rc));
         if (pHdr != &StackBuf.Hdr)
             RTMemFree(pHdr);
@@ -791,5 +790,5 @@
         if (RT_UNLIKELY(cbOut > cbBuf))
         {
-            LogRel((DEVICE_NAME ":VBoxDrvSolarisIOCtlSlow: too much output! %#x > %#x; iCmd=%#x!\n", cbOut, cbBuf, iCmd));
+            LogRel(("VBoxDrvSolarisIOCtlSlow: too much output! %#x > %#x; iCmd=%#x!\n", cbOut, cbBuf, iCmd));
             cbOut = cbBuf;
         }
@@ -798,5 +797,5 @@
         {
             /* this is really bad */
-            LogRel((DEVICE_NAME ":VBoxDrvSolarisIOCtlSlow: ddi_copyout(,%p,%d) failed. rc=%d\n", (void *)iArg, cbBuf, rc));
+            LogRel(("VBoxDrvSolarisIOCtlSlow: ddi_copyout(,%p,%d) failed. rc=%d\n", (void *)iArg, cbBuf, rc));
             rc = EFAULT;
         }
Index: /trunk/src/VBox/HostDrivers/Support/solaris/SUPLib-solaris.cpp
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/solaris/SUPLib-solaris.cpp	(revision 44172)
+++ /trunk/src/VBox/HostDrivers/Support/solaris/SUPLib-solaris.cpp	(revision 44173)
@@ -65,10 +65,12 @@
 *   Defined Constants And Macros                                               *
 *******************************************************************************/
-/** Solaris device link. */
-#define DEVICE_NAME     "/dev/vboxdrv"
-
-
-
-int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited)
+/** Solaris device link - system. */
+#define DEVICE_NAME_SYS     "/dev/vboxdrv"
+/** Solaris device link - user. */
+#define DEVICE_NAME_USR     "/dev/vboxdrvu"
+
+
+
+int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited, bool fUnrestricted)
 {
     /*
@@ -102,5 +104,5 @@
      * Try to open the device.
      */
-    int hDevice = open(DEVICE_NAME, O_RDWR, 0);
+    int hDevice = open(fUnrestricted ? DEVICE_NAME_SYS : DEVICE_NAME_USR, O_RDWR, 0);
     if (hDevice < 0)
     {
@@ -134,5 +136,6 @@
     }
 
-    pThis->hDevice = hDevice;
+    pThis->hDevice       = hDevice;
+    pThis->fUnrestricted = fUnrestricted;
     return VINF_SUCCESS;
 }
Index: /trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp	(revision 44172)
+++ /trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp	(revision 44173)
@@ -265,5 +265,5 @@
         pFileObj->FsContext = NULL;
         PSUPDRVSESSION pSession;
-        int rc = supdrvCreateSession(pDevExt, true /*fUser*/, &pSession);
+        int rc = supdrvCreateSession(pDevExt, true /*fUser*/, true /*fUnrestricted*/, &pSession);
         if (!rc)
             pFileObj->FsContext = pSession;
Index: /trunk/src/VBox/HostDrivers/Support/win/SUPLib-win.cpp
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/win/SUPLib-win.cpp	(revision 44172)
+++ /trunk/src/VBox/HostDrivers/Support/win/SUPLib-win.cpp	(revision 44173)
@@ -57,6 +57,8 @@
 /** The support service name. */
 #define SERVICE_NAME    "VBoxDrv"
-/** Win32 Device name. */
-#define DEVICE_NAME     "\\\\.\\VBoxDrv"
+/** Win32 Device name - system. */
+#define DEVICE_NAME_SYS "\\\\.\\VBoxDrv"
+/** Win32 Device name - user. */
+#define DEVICE_NAME_USR "\\\\.\\VBoxDrvU"
 /** NT Device name. */
 #define DEVICE_NAME_NT   L"\\Device\\VBoxDrv"
@@ -78,5 +80,5 @@
 
 
-int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited)
+int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited, bool fUnrestricted)
 {
     /*
@@ -89,5 +91,5 @@
      * Try open the device.
      */
-    HANDLE hDevice = CreateFile(DEVICE_NAME,
+    HANDLE hDevice = CreateFile(fUnrestricted ? DEVICE_NAME_SYS : DEVICE_NAME_USR,
                                 GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
                                 NULL,
@@ -103,5 +105,5 @@
         suplibOsStartService();
 
-        hDevice = CreateFile(DEVICE_NAME,
+        hDevice = CreateFile(fUnrestricted ? DEVICE_NAME_SYS : DEVICE_NAME_USR,
                              GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
                              NULL,
@@ -139,5 +141,6 @@
      * We're done.
      */
-    pThis->hDevice = hDevice;
+    pThis->hDevice       = hDevice;
+    pThis->fUnrestricted = fUnrestricted;
     return VINF_SUCCESS;
 }
