Index: /trunk/src/VBox/HostDrivers/Support/freebsd/SUPDrv-freebsd.c
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/freebsd/SUPDrv-freebsd.c	(revision 44181)
+++ /trunk/src/VBox/HostDrivers/Support/freebsd/SUPDrv-freebsd.c	(revision 44182)
@@ -71,5 +71,6 @@
 static int VBoxDrvFreeBSDUnload(void);
 
-static d_open_t     VBoxDrvFreeBSDOpen;
+static d_open_t     VBoxDrvFreeBSDOpenUsr;
+static d_open_t     VBoxDrvFreeBSDOpenSys;
 static void         VBoxDrvFreeBSDDtr(void *pData);
 static d_ioctl_t    VBoxDrvFreeBSDIOCtl;
@@ -97,14 +98,27 @@
  * The /dev/vboxdrv character device entry points.
  */
-static struct cdevsw        g_VBoxDrvFreeBSDChrDevSW =
+static struct cdevsw        g_VBoxDrvFreeBSDChrDevSwSys =
 {
     .d_version =        D_VERSION,
-    .d_open =           VBoxDrvFreeBSDOpen,
+    .d_open =           VBoxDrvFreeBSDOpenSys,
     .d_ioctl =          VBoxDrvFreeBSDIOCtl,
     .d_name =           "vboxdrv"
 };
-
 /** The /dev/vboxdrv character device. */
-static struct cdev         *g_pVBoxDrvFreeBSDChrDev;
+static struct cdev         *g_pVBoxDrvFreeBSDChrDevSys;
+
+/**
+ * The /dev/vboxdrvu character device entry points.
+ */
+static struct cdevsw        g_VBoxDrvFreeBSDChrDevSwUsr =
+{
+    .d_version =        D_VERSION,
+    .d_open =           VBoxDrvFreeBSDOpenUsr,
+    .d_ioctl =          VBoxDrvFreeBSDIOCtl,
+    .d_name =           "vboxdrvu"
+};
+/** The /dev/vboxdrvu character device. */
+static struct cdev         *g_pVBoxDrvFreeBSDChrDevUsr;
+
 /** Reference counter. */
 static volatile uint32_t    g_cUsers;
@@ -168,11 +182,12 @@
         {
             /*
-             * Configure character device. Add symbolic link for compatibility.
+             * Configure character devices. Add symbolic links for compatibility.
              */
-            g_pVBoxDrvFreeBSDChrDev = make_dev(&g_VBoxDrvFreeBSDChrDevSW, 0, UID_ROOT, GID_WHEEL, VBOXDRV_PERM, "vboxdrv");
+            g_pVBoxDrvFreeBSDChrDevSys = make_dev(&g_VBoxDrvFreeBSDChrDevSwSys, 0, UID_ROOT, GID_WHEEL, VBOXDRV_PERM, "vboxdrv");
+            g_pVBoxDrvFreeBSDChrDevUsr = make_dev(&g_VBoxDrvFreeBSDChrDevSwUsr, 1, UID_ROOT, GID_WHEEL, 0666,         "vboxdrvu");
             return VINF_SUCCESS;
         }
-        else
-            printf("vboxdrv: supdrvInitDevExt failed, rc=%d\n", rc);
+
+        printf("vboxdrv: supdrvInitDevExt failed, rc=%d\n", rc);
         RTR0Term();
     }
@@ -192,5 +207,6 @@
      * Reserve what we did in VBoxDrvFreeBSDInit.
      */
-    destroy_dev(g_pVBoxDrvFreeBSDChrDev);
+    destroy_dev(g_pVBoxDrvFreeBSDChrDevUsr);
+    destroy_dev(g_pVBoxDrvFreeBSDChrDevSys);
 
     supdrvDeleteDevExt(&g_VBoxDrvFreeBSDDevExt);
@@ -207,11 +223,10 @@
  * @returns 0 on success, errno on failure.
  *          EBUSY if the device is used by someone else.
- * @param   pDev    The device node.
- * @param   fOpen   The open flags.
- * @param   pTd     The thread.
- * @param   pFd     The file descriptor. FreeBSD 7.0 and later.
- * @param   iFd     The file descriptor index(?). Pre FreeBSD 7.0.
- */
-static int VBoxDrvFreeBSDOpen(struct cdev *pDev, int fOpen, int iDevtype, struct thread *pTd)
+ * @param   pDev        The device node.
+ * @param   fOpen       The open flags.
+ * @param   pTd         The thread.
+ * @param   iDevType    ???
+ */
+static int vboxdrvFreeBSDOpenCommon(struct cdev *pDev, int fOpen, int iDevtype, struct thread *pTd, bool fUnrestricted)
 {
     PSUPDRVSESSION pSession;
@@ -221,5 +236,5 @@
      * Let's be a bit picky about the flags...
      */
-    if (fOpen != (FREAD|FWRITE /*=O_RDWR*/))
+    if (fOpen != (FREAD | FWRITE /*=O_RDWR*/))
     {
         Log(("VBoxDrvFreeBSDOpen: fOpen=%#x expected %#x\n", fOpen, O_RDWR));
@@ -230,5 +245,5 @@
      * Create a new session.
      */
-    rc = supdrvCreateSession(&g_VBoxDrvFreeBSDDevExt, true /* fUser */, true /*fUnrestricted*/, &pSession);
+    rc = supdrvCreateSession(&g_VBoxDrvFreeBSDDevExt, true /* fUser */, fUnrestricted, &pSession);
     if (RT_SUCCESS(rc))
     {
@@ -246,4 +261,18 @@
 
 
+/** For vboxdrv. */
+static int VBoxDrvFreeBSDOpenSys(struct cdev *pDev, int fOpen, int iDevtype, struct thread *pTd)
+{
+    return vboxdrvFreeBSDOpenCommon(pDev, fOpen, iDevtype, pTd, true);
+}
+
+
+/** For vboxdrvu. */
+static int VBoxDrvFreeBSDOpenUsr(struct cdev *pDev, int fOpen, int iDevtype, struct thread *pTd)
+{
+    return vboxdrvFreeBSDOpenCommon(pDev, fOpen, iDevtype, pTd, false);
+}
+
+
 /**
  * Close a file device previously opened by VBoxDrvFreeBSDOpen
@@ -286,7 +315,8 @@
      * Deal with the fast ioctl path first.
      */
-    if (    ulCmd == SUP_IOCTL_FAST_DO_RAW_RUN
-        ||  ulCmd == SUP_IOCTL_FAST_DO_HM_RUN
-        ||  ulCmd == SUP_IOCTL_FAST_DO_NOP)
+    if (   (   ulCmd == SUP_IOCTL_FAST_DO_RAW_RUN
+            || ulCmd == SUP_IOCTL_FAST_DO_HM_RUN
+            || ulCmd == SUP_IOCTL_FAST_DO_NOP)
+        && pSession->fUnrestricted == true)
         return supdrvIOCtlFast(ulCmd, *(uint32_t *)pvData, &g_VBoxDrvFreeBSDDevExt, pSession);
 
