Index: /trunk/Config.kmk
===================================================================
--- /trunk/Config.kmk	(revision 45458)
+++ /trunk/Config.kmk	(revision 45459)
@@ -94,5 +94,5 @@
  INST_SYS             = $(INST_BIN)
  INST_TESTCASE        = $(INST_BIN)testcase/
- INST_ADDITIONS       = $(INST_BIN)additions/
+ INST_ADDITIONS       = $(INST_DIST)additions/
  INST_ADDITIONS_ISO   = $(INST_BIN)
 
@@ -284,8 +284,5 @@
 # This indicates that additions (of some kind or another) is being _built_.
 # VBOX_WITHOUT_ADDITIONS overrides it.
-#if1of ($(KBUILD_TARGET), freebsd linux os2 solaris win)
-if1of ($(KBUILD_TARGET), freebsd linux solaris win)
- VBOX_WITH_ADDITIONS = 1
-endif
+VBOX_WITH_ADDITIONS = 1
 # Build the optional ring-0 part of the additions for syntax checking.
 # (Except when cross-building on linux since we're using /usr/src/...)
@@ -4823,5 +4820,5 @@
 ifeq ($(KBUILD_TARGET),linux) # As few libs as possible on linux.
  TEMPLATE_VBOXGUESTR3EXE_LIBS     = pthread rt m dl
-else if1of ($(KBUILD_TARGET), freebsd netbsd openbsd)
+else if1of ($(KBUILD_TARGET), darwin freebsd netbsd openbsd)
  TEMPLATE_VBOXGUESTR3EXE_LIBS     = $(TEMPLATE_VBOXR3EXE_LIBS) iconv
 else ifeq ($(KBUILD_TARGET), solaris)
Index: /trunk/src/VBox/Additions/common/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Additions/common/Makefile.kmk	(revision 45458)
+++ /trunk/src/VBox/Additions/common/Makefile.kmk	(revision 45459)
@@ -23,10 +23,6 @@
  include $(PATH_SUB_CURRENT)/VBoxGuestLib/Makefile.kmk
  include $(PATH_SUB_CURRENT)/VBoxControl/Makefile.kmk
- if1of ($(KBUILD_TARGET), freebsd haiku linux os2 solaris win)
-  include $(PATH_SUB_CURRENT)/VBoxGuest/Makefile.kmk
- endif
- if1of ($(KBUILD_TARGET), freebsd haiku linux os2 solaris win)
-  include $(PATH_SUB_CURRENT)/VBoxService/Makefile.kmk
- endif
+ include $(PATH_SUB_CURRENT)/VBoxGuest/Makefile.kmk
+ include $(PATH_SUB_CURRENT)/VBoxService/Makefile.kmk
  ifdef VBOX_WITH_CROGL
    include $(PATH_SUB_CURRENT)/crOpenGL/Makefile.kmk
Index: /trunk/src/VBox/Additions/common/VBoxControl/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Additions/common/VBoxControl/Makefile.kmk	(revision 45458)
+++ /trunk/src/VBox/Additions/common/VBoxControl/Makefile.kmk	(revision 45459)
@@ -43,4 +43,5 @@
 VBoxControl_SOURCES.win = \
 	VBoxControl.rc
+VBoxControl_LDFLAGS.darwin = -framework IOKit
 
 include $(FILE_KBUILD_SUB_FOOTER)
Index: /trunk/src/VBox/Additions/common/VBoxGuest/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Additions/common/VBoxGuest/Makefile.kmk	(revision 45458)
+++ /trunk/src/VBox/Additions/common/VBoxGuest/Makefile.kmk	(revision 45459)
@@ -20,5 +20,5 @@
 
 
-if1of ($(KBUILD_TARGET), freebsd haiku $(if $(defined VBOX_WITH_ADDITION_DRIVERS),linux,) os2 solaris win)
+if1of ($(KBUILD_TARGET), darwin freebsd haiku $(if $(defined VBOX_WITH_ADDITION_DRIVERS),linux,) os2 solaris win)
  #
  # VBoxGuest - The Guest Additions Driver.
@@ -30,4 +30,5 @@
  VBoxGuest_NAME.linux    = vboxguest
  VBoxGuest_NAME.solaris  = vboxguest
+ VBoxGuest_INST.darwin   = $(INST_ADDITIONS)VBoxGuest.kext/Contents/MacOS/
  ifdef VBOX_SIGN_ADDITIONS # See Additions/WINNT/Makefile.kmk?
   VBoxGuest_INSTTYPE.win = none
@@ -51,6 +52,7 @@
  VBoxGuest_DEPS.solaris += $(VBOX_SVN_REV_KMK)
  VBoxGuest_DEPS.linux   += $(VBOX_SVN_REV_HEADER)
+ VBoxGuest_DEPS.haiku   += $(VBOX_SVN_REV_HEADER)
  VBoxGuest_DEPS.freebsd += $(VBOX_SVN_REV_HEADER)
- VBoxGuest_DEPS.haiku   += $(VBOX_SVN_REV_HEADER)
+ VBoxGuest_DEPS.darwin  += $(VBOX_SVN_REV_HEADER)
  VBoxGuest_DEFS          = VBGL_VBOXGUEST VBOX_WITH_HGCM
  VBoxGuest_INCS          = .
@@ -165,4 +167,30 @@
 endif # enabled
 
+
+ifeq ($(KBUILD_TARGET), darwin)
+ # Files necessary to make a darwin kernel extension bundle.
+ INSTALLS += VBoxGuest.kext
+ VBoxGuest.kext_INST     = $(INST_ADDITIONS)/VBoxGuest.kext/Contents/
+ VBoxGuest.kext_SOURCES  = $(VBoxGuest.kext_0_OUTDIR)/Info.plist
+ VBoxGuest.kext_CLEAN    = $(VBoxGuest.kext_0_OUTDIR)/Info.plist
+
+$$(VBoxGuest.kext_0_OUTDIR)/Info.plist: \
+		$(PATH_SUB_CURRENT)/darwin/Info.plist \
+		$(VBOX_VERSION_MK) | $$(dir $$@)
+	$(call MSG_GENERATE,VBoxGuest,$@,$<)
+	$(QUIET)$(RM) -f $@
+	$(QUIET)$(SED) \
+		-e 's/@VBOX_VERSION_STRING@/$(VBOX_VERSION_STRING)/g' \
+		-e 's/@VBOX_VERSION_MAJOR@/$(VBOX_VERSION_MAJOR)/g' \
+		-e 's/@VBOX_VERSION_MINOR@/$(VBOX_VERSION_MINOR)/g' \
+		-e 's/@VBOX_VERSION_BUILD@/$(VBOX_VERSION_BUILD)/g' \
+		-e 's/@VBOX_VENDOR@/$(VBOX_VENDOR)/g' \
+		-e 's/@VBOX_PRODUCT@/$(VBOX_PRODUCT)/g' \
+		-e 's/@VBOX_C_YEAR@/$(VBOX_C_YEAR)/g' \
+		--output $@ \
+		$<
+endif # darwin
+
+
 ifeq ($(KBUILD_TARGET),linux)
  #
Index: /trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-darwin.cpp
===================================================================
--- /trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-darwin.cpp	(revision 45458)
+++ /trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-darwin.cpp	(revision 45459)
@@ -1,9 +1,9 @@
 /* $Id$ */
 /** @file
- * VirtualBox Support Driver - Darwin Specific Code.
+ * VBoxGuest - Darwin Specifics.
  */
 
 /*
- * Copyright (C) 2006-2012 Oracle Corporation
+ * Copyright (C) 2006-2013 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -28,5 +28,5 @@
 *   Header Files                                                               *
 *******************************************************************************/
-#define LOG_GROUP LOG_GROUP_SUP_DRV
+#define LOG_GROUP LOG_GROUP_VBGD
 /*
  * Deal with conflicts first.
@@ -40,8 +40,6 @@
 #include <IOKit/IOLib.h> /* Assert as function */
 
-#include "../SUPDrvInternal.h"
 #include <VBox/version.h>
 #include <iprt/asm.h>
-#include <iprt/asm-amd64-x86.h>
 #include <iprt/initterm.h>
 #include <iprt/assert.h>
@@ -51,5 +49,4 @@
 #include <iprt/alloc.h>
 #include <iprt/power.h>
-#include <iprt/dbg.h>
 #include <VBox/err.h>
 #include <VBox/log.h>
@@ -66,12 +63,8 @@
 #include <IOKit/IOUserClient.h>
 #include <IOKit/pwr_mgt/RootDomain.h>
-#include <IOKit/IODeviceTreeSupport.h>
-
-#ifdef VBOX_WITH_HOST_VMX
-# include <libkern/version.h>
-RT_C_DECLS_BEGIN
-# include <i386/vmx.h>
-RT_C_DECLS_END
-#endif
+#include <IOkit/pci/IOPCIDevice.h>
+#include <IOkit/IOBufferMemoryDescriptor.h>
+#include <IOkit/IOFilterInterruptEventSource.h>
+#include "VBoxGuestInternal.h"
 
 
@@ -81,7 +74,7 @@
 
 /** The system device node name. */
-#define DEVICE_NAME_SYS     "vboxdrv"
+#define DEVICE_NAME_SYS     "vboxguest"
 /** The user device node name. */
-#define DEVICE_NAME_USR     "vboxdrvu"
+#define DEVICE_NAME_USR     "vboxguestu"
 
 
@@ -91,18 +84,17 @@
 *******************************************************************************/
 RT_C_DECLS_BEGIN
-static kern_return_t    VBoxDrvDarwinStart(struct kmod_info *pKModInfo, void *pvData);
-static kern_return_t    VBoxDrvDarwinStop(struct kmod_info *pKModInfo, void *pvData);
-
-static int              VBoxDrvDarwinOpen(dev_t Dev, int fFlags, int fDevType, struct proc *pProcess);
-static int              VBoxDrvDarwinClose(dev_t Dev, int fFlags, int fDevType, struct proc *pProcess);
-static int              VBoxDrvDarwinIOCtl(dev_t Dev, u_long iCmd, caddr_t pData, int fFlags, struct proc *pProcess);
-static int              VBoxDrvDarwinIOCtlSlow(PSUPDRVSESSION pSession, u_long iCmd, caddr_t pData, struct proc *pProcess);
-
-static int              VBoxDrvDarwinErr2DarwinErr(int rc);
-
-static IOReturn         VBoxDrvDarwinSleepHandler(void *pvTarget, void *pvRefCon, UInt32 uMessageType, IOService *pProvider, void *pvMessageArgument, vm_size_t argSize);
+static kern_return_t    VbgdDarwinStart(struct kmod_info *pKModInfo, void *pvData);
+static kern_return_t    VbgdDarwinStop(struct kmod_info *pKModInfo, void *pvData);
+static int              VbgdDarwinCharDevRemove(void);
+
+static int              VbgdDarwinOpen(dev_t Dev, int fFlags, int fDevType, struct proc *pProcess);
+static int              VbgdDarwinClose(dev_t Dev, int fFlags, int fDevType, struct proc *pProcess);
+static int              VbgdDarwinIOCtlSlow(PVBOXGUESTSESSION pSession, u_long iCmd, caddr_t pData, struct proc *pProcess);
+static int              VbgdDarwinIOCtl(dev_t Dev, u_long iCmd, caddr_t pData, int fFlags, struct proc *pProcess);
+
+static int              VbgdDarwinErr2DarwinErr(int rc);
+
+static IOReturn         VbgdDarwinSleepHandler(void *pvTarget, void *pvRefCon, UInt32 uMessageType, IOService *pProvider, void *pvMessageArgument, vm_size_t argSize);
 RT_C_DECLS_END
-
-static void             vboxdrvDarwinResolveSymbols(void);
 
 
@@ -111,21 +103,28 @@
 *******************************************************************************/
 /**
- * The service class.
- * This is just a formality really.
- */
-class org_virtualbox_SupDrv : public IOService
-{
-    OSDeclareDefaultStructors(org_virtualbox_SupDrv);
+ * The service class for handling the VMMDev PCI device.
+ *
+ * Instantiated when the module is loaded (and on PCI hotplugging?).
+ */
+class org_virtualbox_VBoxGuest : public IOService
+{
+    OSDeclareDefaultStructors(org_virtualbox_VBoxGuest);
+
+private:
+    IOPCIDevice                *m_pIOPCIDevice;
+    IOMemoryMap                *m_pMap;
+    IOFilterInterruptEventSource *m_pInterruptSrc;
+
+    bool setupVmmDevInterrupts(IOService *pProvider);
+    bool disableVmmDevInterrupts(void);
+    bool isVmmDev(IOPCIDevice *pIOPCIDevice);
 
 public:
-    virtual bool init(OSDictionary *pDictionary = 0);
-    virtual void free(void);
     virtual bool start(IOService *pProvider);
     virtual void stop(IOService *pProvider);
-    virtual IOService *probe(IOService *pProvider, SInt32 *pi32Score);
     virtual bool terminate(IOOptionBits fOptions);
 };
 
-OSDefineMetaClassAndStructors(org_virtualbox_SupDrv, IOService);
+OSDefineMetaClassAndStructors(org_virtualbox_VBoxGuest, IOService);
 
 
@@ -134,13 +133,15 @@
  * I don't think it'll work as I cannot figure out where/what creates the correct
  * port right.
- */
-class org_virtualbox_SupDrvClient : public IOUserClient
-{
-    OSDeclareDefaultStructors(org_virtualbox_SupDrvClient);
+ *
+ * Instantiated when userland does IOServiceOpen().
+ */
+class org_virtualbox_VBoxGuestClient : public IOUserClient
+{
+    OSDeclareDefaultStructors(org_virtualbox_VBoxGuestClient);
 
 private:
-    PSUPDRVSESSION          m_pSession;     /**< The session. */
-    task_t                  m_Task;         /**< The client task. */
-    org_virtualbox_SupDrv  *m_pProvider;    /**< The service provider. */
+    PVBOXGUESTSESSION           m_pSession;     /**< The session. */
+    task_t                      m_Task;         /**< The client task. */
+    org_virtualbox_VBoxGuest   *m_pProvider;    /**< The service provider. */
 
 public:
@@ -149,11 +150,7 @@
     static  void sessionClose(RTPROCESS Process);
     virtual IOReturn clientClose(void);
-    virtual IOReturn clientDied(void);
-    virtual bool terminate(IOOptionBits fOptions = 0);
-    virtual bool finalize(IOOptionBits fOptions);
-    virtual void stop(IOService *pProvider);
 };
 
-OSDefineMetaClassAndStructors(org_virtualbox_SupDrvClient, IOUserClient);
+OSDefineMetaClassAndStructors(org_virtualbox_VBoxGuestClient, IOUserClient);
 
 
@@ -169,7 +166,7 @@
 extern kern_return_t _stop(struct kmod_info *pKModInfo, void *pvData);
 
-KMOD_EXPLICIT_DECL(VBoxDrv, VBOX_VERSION_STRING, _start, _stop)
-DECLHIDDEN(kmod_start_func_t *) _realmain = VBoxDrvDarwinStart;
-DECLHIDDEN(kmod_stop_func_t *)  _antimain = VBoxDrvDarwinStop;
+KMOD_EXPLICIT_DECL(VBoxGuest, VBOX_VERSION_STRING, _start, _stop)
+DECLHIDDEN(kmod_start_func_t *) _realmain = VbgdDarwinStart;
+DECLHIDDEN(kmod_stop_func_t *)  _antimain = VbgdDarwinStop;
 DECLHIDDEN(int)                 _kext_apple_cc = __APPLE_CC__;
 RT_C_DECLS_END
@@ -179,5 +176,5 @@
  * Device extention & session data association structure.
  */
-static SUPDRVDEVEXT     g_DevExt;
+static VBOXGUESTDEVEXT  g_DevExt;
 
 /**
@@ -186,45 +183,40 @@
 static struct cdevsw    g_DevCW =
 {
-    /** @todo g++ doesn't like this syntax - it worked with gcc before renaming to .cpp. */
-    /*.d_open  = */VBoxDrvDarwinOpen,
-    /*.d_close = */VBoxDrvDarwinClose,
-    /*.d_read  = */eno_rdwrt,
-    /*.d_write = */eno_rdwrt,
-    /*.d_ioctl = */VBoxDrvDarwinIOCtl,
-    /*.d_stop  = */eno_stop,
-    /*.d_reset = */eno_reset,
-    /*.d_ttys  = */NULL,
-    /*.d_select= */eno_select,
-    /*.d_mmap  = */eno_mmap,
-    /*.d_strategy = */eno_strat,
-    /*.d_getc  = */eno_getc,
-    /*.d_putc  = */eno_putc,
-    /*.d_type  = */0
+    /*.d_open     = */ VbgdDarwinOpen,
+    /*.d_close    = */ VbgdDarwinClose,
+    /*.d_read     = */ eno_rdwrt,
+    /*.d_write    = */ eno_rdwrt,
+    /*.d_ioctl    = */ VbgdDarwinIOCtl,
+    /*.d_stop     = */ eno_stop,
+    /*.d_reset    = */ eno_reset,
+    /*.d_ttys     = */ NULL,
+    /*.d_select   = */ eno_select,
+    /*.d_mmap     = */ eno_mmap,
+    /*.d_strategy = */ eno_strat,
+    /*.d_getc     = */ eno_getc,
+    /*.d_putc     = */ eno_putc,
+    /*.d_type     = */ 0
 };
 
 /** Major device number. */
-static int              g_iMajorDeviceNo = -1;
-/** Registered devfs device handle for the system device. */
-static void            *g_hDevFsDeviceSys = NULL;
+static int                  g_iMajorDeviceNo    = -1;
+/** Registered devfs device handle. */
+static void                *g_hDevFsDeviceSys   = NULL;
 /** Registered devfs device handle for the user device. */
-static void            *g_hDevFsDeviceUsr = NULL;
+static void                *g_hDevFsDeviceUsr   = NULL; /**< @todo 4 later */
 
 /** Spinlock protecting g_apSessionHashTab. */
-static RTSPINLOCK       g_Spinlock = NIL_RTSPINLOCK;
+static RTSPINLOCK           g_Spinlock          = NIL_RTSPINLOCK;
 /** Hash table */
-static PSUPDRVSESSION   g_apSessionHashTab[19];
+static PVBOXGUESTSESSION    g_apSessionHashTab[19];
 /** Calculates the index into g_apSessionHashTab.*/
-#define SESSION_HASH(pid)     ((pid) % RT_ELEMENTS(g_apSessionHashTab))
+#define SESSION_HASH(pid)   ((pid) % RT_ELEMENTS(g_apSessionHashTab))
 /** The number of open sessions. */
-static int32_t volatile g_cSessions = 0;
+static int32_t volatile     g_cSessions         = 0;
+/** The number of IOService class instances. */
+static bool volatile        g_fInstantiated     = 0;
 /** The notifier handle for the sleep callback handler. */
-static IONotifier      *g_pSleepNotifier = NULL;
-
-/** Pointer to vmx_suspend(). */
-static PFNRT            g_pfnVmxSuspend = NULL;
-/** Pointer to vmx_resume(). */
-static PFNRT            g_pfnVmxResume = NULL;
-/** Pointer to vmx_use_count. */
-static int volatile    *g_pVmxUseCount = NULL;
+static IONotifier          *g_pSleepNotifier    = NULL;
+
 
 
@@ -232,9 +224,8 @@
  * Start the kernel module.
  */
-static kern_return_t    VBoxDrvDarwinStart(struct kmod_info *pKModInfo, void *pvData)
-{
-    int rc;
+static kern_return_t    VbgdDarwinStart(struct kmod_info *pKModInfo, void *pvData)
+{
 #ifdef DEBUG
-    printf("VBoxDrvDarwinStart\n");
+    printf("VbgdDarwinStart\n");
 #endif
 
@@ -242,130 +233,73 @@
      * Initialize IPRT.
      */
-    rc = RTR0Init(0);
-    if (RT_SUCCESS(rc))
-    {
-        /*
-         * Initialize the device extension.
-         */
-        rc = supdrvInitDevExt(&g_DevExt, sizeof(SUPDRVSESSION));
-        if (RT_SUCCESS(rc))
-        {
-            /*
-             * Initialize the session hash table.
-             */
-            memset(g_apSessionHashTab, 0, sizeof(g_apSessionHashTab)); /* paranoia */
-            rc = RTSpinlockCreate(&g_Spinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "VBoxDrvDarwin");
-            if (RT_SUCCESS(rc))
-            {
-                /*
-                 * Registering ourselves as a character device.
-                 */
-                g_iMajorDeviceNo = cdevsw_add(-1, &g_DevCW);
-                if (g_iMajorDeviceNo >= 0)
-                {
-#ifdef VBOX_WITH_HARDENING
-                    g_hDevFsDeviceSys = devfs_make_node(makedev(g_iMajorDeviceNo, 0), DEVFS_CHAR,
-                                                        UID_ROOT, GID_WHEEL, 0600, DEVICE_NAME_SYS);
-#else
-                    g_hDevFsDeviceSys = devfs_make_node(makedev(g_iMajorDeviceNo, 0), DEVFS_CHAR,
-                                                        UID_ROOT, GID_WHEEL, 0666, DEVICE_NAME_SYS);
+    int rc = RTR0Init(0);
+    if (RT_FAILURE(rc))
+    {
+        printf("VBoxGuest: RTR0Init failed with rc=%d\n", rc);
+        return KMOD_RETURN_FAILURE;
+    }
+
+    return KMOD_RETURN_SUCCESS;
+}
+
+
+/* Register VBoxGuest char device */
+static int VbgdDarwinCharDevInit(void)
+{
+    int rc = RTSpinlockCreate(&g_Spinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "VBoxGuestDarwin");
+    if (RT_FAILURE(rc))
+    {
+        return KMOD_RETURN_FAILURE;
+    }
+
+    /*
+     * Registering ourselves as a character device.
+     */
+    g_iMajorDeviceNo = cdevsw_add(-1, &g_DevCW);
+    if (g_iMajorDeviceNo < 0)
+    {
+        VbgdDarwinCharDevRemove();
+        return KMOD_RETURN_FAILURE;
+    }
+
+    g_hDevFsDeviceSys = devfs_make_node(makedev(g_iMajorDeviceNo, 0), DEVFS_CHAR,
+                                        UID_ROOT, GID_WHEEL, 0666, DEVICE_NAME_SYS);
+    if (!g_hDevFsDeviceSys)
+    {
+        VbgdDarwinCharDevRemove();
+        return KMOD_RETURN_FAILURE;
+    }
+
+    /* Register a sleep/wakeup notification callback */
+    g_pSleepNotifier = registerPrioritySleepWakeInterest(&VbgdDarwinSleepHandler, &g_DevExt, NULL);
+    if (g_pSleepNotifier == NULL)
+    {
+        VbgdDarwinCharDevRemove();
+        return KMOD_RETURN_FAILURE;
+    }
+
+    return KMOD_RETURN_SUCCESS;
+}
+
+
+/**
+ * Stop the kernel module.
+ */
+static kern_return_t VbgdDarwinStop(struct kmod_info *pKModInfo, void *pvData)
+{
+    RTR0TermForced();
+#ifdef DEBUG
+    printf("VbgdDarwinStop - done\n");
 #endif
-                    if (g_hDevFsDeviceSys)
-                    {
-                        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;
-                    }
-                    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;
-                }
-                else
-                    LogRel(("VBoxDrv: cdevsw_add failed (%d)\n", g_iMajorDeviceNo));
-                RTSpinlockDestroy(g_Spinlock);
-                g_Spinlock = NIL_RTSPINLOCK;
-            }
-            else
-                LogRel(("VBoxDrv: RTSpinlockCreate failed (rc=%d)\n", rc));
-            supdrvDeleteDevExt(&g_DevExt);
-        }
-        else
-            printf("VBoxDrv: failed to initialize device extension (rc=%d)\n", rc);
-        RTR0TermForced();
-    }
-    else
-        printf("VBoxDrv: failed to initialize IPRT (rc=%d)\n", rc);
-
-    memset(&g_DevExt, 0, sizeof(g_DevExt));
-    return KMOD_RETURN_FAILURE;
-}
-
-
-/**
- * Resolves kernel symbols we want (but may do without).
- */
-static void vboxdrvDarwinResolveSymbols(void)
-{
-    RTDBGKRNLINFO hKrnlInfo;
-    int rc = RTR0DbgKrnlInfoOpen(&hKrnlInfo, 0);
-    if (RT_SUCCESS(rc))
-    {
-        /* The VMX stuff. */
-        int rc1 = RTR0DbgKrnlInfoQuerySymbol(hKrnlInfo, NULL, "vmx_resume", (void **)&g_pfnVmxResume);
-        int rc2 = RTR0DbgKrnlInfoQuerySymbol(hKrnlInfo, NULL, "vmx_suspend", (void **)&g_pfnVmxSuspend);
-        int rc3 = RTR0DbgKrnlInfoQuerySymbol(hKrnlInfo, NULL, "vmx_use_count", (void **)&g_pVmxUseCount);
-        if (RT_SUCCESS(rc1) && RT_SUCCESS(rc2) && RT_SUCCESS(rc3))
-        {
-            LogRel(("VBoxDrv: vmx_resume=%p vmx_suspend=%p vmx_use_count=%p (%d) cr4=%#x\n",
-                    g_pfnVmxResume, g_pfnVmxSuspend, g_pVmxUseCount, *g_pVmxUseCount, ASMGetCR4() ));
-        }
-        else
-        {
-            LogRel(("VBoxDrv: failed to resolve vmx stuff: vmx_resume=%Rrc vmx_suspend=%Rrc vmx_use_count=%Rrc", rc1, rc2, rc3));
-            g_pfnVmxResume  = NULL;
-            g_pfnVmxSuspend = NULL;
-            g_pVmxUseCount  = NULL;
-        }
-
-        RTR0DbgKrnlInfoRelease(hKrnlInfo);
-    }
-    else
-        LogRel(("VBoxDrv: Failed to open kernel symbols, rc=%Rrc\n", rc));
-}
-
-
-/**
- * Stop the kernel module.
- */
-static kern_return_t    VBoxDrvDarwinStop(struct kmod_info *pKModInfo, void *pvData)
-{
-    int rc;
-    LogFlow(("VBoxDrvDarwinStop\n"));
-
-    /** @todo I've got a nagging feeling that we'll have to keep track of users and refuse
-     * unloading if we're busy. Investigate and implement this! */
-
-    /*
-     * Undo the work done during start (in reverse order).
-     */
+    return KMOD_RETURN_SUCCESS;
+}
+
+
+/* Unregister VBoxGuest char device */
+static int
+VbgdDarwinCharDevRemove(void)
+{
+    int rc = KMOD_RETURN_SUCCESS;
+
     if (g_pSleepNotifier)
     {
@@ -374,32 +308,35 @@
     }
 
-    devfs_remove(g_hDevFsDeviceUsr);
-    g_hDevFsDeviceUsr = NULL;
-
-    devfs_remove(g_hDevFsDeviceSys);
-    g_hDevFsDeviceSys = NULL;
-
-    rc = cdevsw_remove(g_iMajorDeviceNo, &g_DevCW);
-    Assert(rc == g_iMajorDeviceNo);
-    g_iMajorDeviceNo = -1;
-
-    supdrvDeleteDevExt(&g_DevExt);
-
-    rc = RTSpinlockDestroy(g_Spinlock);
-    AssertRC(rc);
-    g_Spinlock = NIL_RTSPINLOCK;
-
-    RTR0TermForced();
-
-    memset(&g_DevExt, 0, sizeof(g_DevExt));
-#ifdef DEBUG
-    printf("VBoxDrvDarwinStop - done\n");
-#endif
-    return KMOD_RETURN_SUCCESS;
-}
-
-
-/**
- * Device open. Called on open /dev/vboxdrv
+    if (g_hDevFsDeviceSys)
+    {
+        devfs_remove(g_hDevFsDeviceSys);
+        g_hDevFsDeviceSys = NULL;
+    }
+
+    if (g_hDevFsDeviceUsr)
+    {
+        devfs_remove(g_hDevFsDeviceUsr);
+        g_hDevFsDeviceUsr = NULL;
+    }
+
+    if (g_iMajorDeviceNo != -1)
+    {
+        int rc2 = cdevsw_remove(g_iMajorDeviceNo, &g_DevCW);
+        Assert(rc2 == g_iMajorDeviceNo);
+        g_iMajorDeviceNo = -1;
+    }
+
+    if (g_Spinlock != NIL_RTSPINLOCK)
+    {
+        int rc2 = RTSpinlockDestroy(g_Spinlock); AssertRC(rc2);
+        g_Spinlock = NIL_RTSPINLOCK;
+    }
+
+    return rc;
+}
+
+
+/**
+ * Device open. Called on open /dev/vboxguest and (later) /dev/vboxguestu.
  *
  * @param   Dev         The device number.
@@ -408,13 +345,6 @@
  * @param   pProcess    The process issuing this request.
  */
-static int VBoxDrvDarwinOpen(dev_t Dev, int fFlags, int fDevType, struct proc *pProcess)
-{
-#ifdef DEBUG_DARWIN_GIP
-    char szName[128];
-    szName[0] = '\0';
-    proc_name(proc_pid(pProcess), szName, sizeof(szName));
-    Log(("VBoxDrvDarwinOpen: pid=%d '%s'\n", proc_pid(pProcess), szName));
-#endif
-
+static int VbgdDarwinOpen(dev_t Dev, int fFlags, int fDevType, struct proc *pProcess)
+{
     /*
      * Only two minor devices numbers are allowed.
@@ -424,21 +354,14 @@
 
     /*
-     * Find the session created by org_virtualbox_SupDrvClient, fail
+     * Find the session created by org_virtualbox_VBoxGuestClient, 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;
-    kauth_cred_t    pCred = kauth_cred_proc_ref(pProcess);
+    //const bool          fUnrestricted = minor(Dev) == 0;
+    int                 rc = VINF_SUCCESS;
+    PVBOXGUESTSESSION   pSession = NULL;
+    kauth_cred_t        pCred = kauth_cred_proc_ref(pProcess);
     if (pCred)
     {
-#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
-        RTUID           Uid = kauth_cred_getruid(pCred);
-        RTGID           Gid = kauth_cred_getrgid(pCred);
-#else
-        RTUID           Uid = pCred->cr_ruid;
-        RTGID           Gid = pCred->cr_rgid;
-#endif
         RTPROCESS       Process = RTProcSelf();
         unsigned        iHash = SESSION_HASH(Process);
@@ -453,7 +376,5 @@
             {
                 pSession->fOpened = true;
-                pSession->fUnrestricted = fUnrestricted;
-                pSession->Uid = Uid;
-                pSession->Gid = Gid;
+                /*pSession->fUnrestricted = fUnrestricted; - later */
             }
             else
@@ -475,10 +396,6 @@
         rc = VERR_INVALID_PARAMETER;
 
-#ifdef DEBUG_DARWIN_GIP
-    OSDBGPRINT(("VBoxDrvDarwinOpen: pid=%d '%s' pSession=%p rc=%d\n", proc_pid(pProcess), szName, pSession, rc));
-#else
-    Log(("VBoxDrvDarwinOpen: g_DevExt=%p pSession=%p rc=%d pid=%d\n", &g_DevExt, pSession, rc, proc_pid(pProcess)));
-#endif
-    return VBoxDrvDarwinErr2DarwinErr(rc);
+    Log(("VbgdDarwinOpen: g_DevExt=%p pSession=%p rc=%d pid=%d\n", &g_DevExt, pSession, rc, proc_pid(pProcess)));
+    return VbgdDarwinErr2DarwinErr(rc);
 }
 
@@ -487,13 +404,13 @@
  * Close device.
  */
-static int VBoxDrvDarwinClose(dev_t Dev, int fFlags, int fDevType, struct proc *pProcess)
-{
-    Log(("VBoxDrvDarwinClose: pid=%d\n", (int)RTProcSelf()));
+static int VbgdDarwinClose(dev_t Dev, int fFlags, int fDevType, struct proc *pProcess)
+{
+    Log(("VbgdDarwinClose: pid=%d\n", (int)RTProcSelf()));
     Assert(proc_pid(pProcess) == (int)RTProcSelf());
 
     /*
-     * Hand the session closing to org_virtualbox_SupDrvClient.
-     */
-    org_virtualbox_SupDrvClient::sessionClose(RTProcSelf());
+     * Hand the session closing to org_virtualbox_VBoxGuestClient.
+     */
+    org_virtualbox_VBoxGuestClient::sessionClose(RTProcSelf());
     return 0;
 }
@@ -506,14 +423,14 @@
  * @param   Dev         The device number (major+minor).
  * @param   iCmd        The IOCtl command.
- * @param   pData       Pointer to the data (if any it's a SUPDRVIOCTLDATA (kernel copy)).
+ * @param   pData       Pointer to the data (if any it's a VBOXGUESTIOCTLDATA (kernel copy)).
  * @param   fFlags      Flag saying we're a character device (like we didn't know already).
  * @param   pProcess    The process issuing this request.
  */
-static int VBoxDrvDarwinIOCtl(dev_t Dev, u_long iCmd, caddr_t pData, int fFlags, struct proc *pProcess)
-{
-    const bool          fUnrestricted = minor(Dev) == 0;
+static int VbgdDarwinIOCtl(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);
-    PSUPDRVSESSION      pSession;
+    PVBOXGUESTSESSION   pSession;
 
     /*
@@ -522,29 +439,24 @@
     RTSpinlockAcquire(g_Spinlock);
     pSession = g_apSessionHashTab[iHash];
-    while (pSession && pSession->Process != Process && pSession->fUnrestricted == fUnrestricted && pSession->fOpened)
+    while (pSession && pSession->Process != Process /*later: && pSession->fUnrestricted == fUnrestricted*/ && pSession->fOpened)
         pSession = pSession->pNextHash;
     RTSpinlockReleaseNoInts(g_Spinlock);
     if (!pSession)
     {
-        OSDBGPRINT(("VBoxDrvDarwinIOCtl: WHAT?!? pSession == NULL! This must be a mistake... pid=%d iCmd=%#lx\n",
-                    (int)Process, iCmd));
+        Log(("VBoxDrvDarwinIOCtl: WHAT?!? pSession == NULL! This must be a mistake... pid=%d iCmd=%#lx\n",
+             (int)Process, iCmd));
         return EINVAL;
     }
 
     /*
-     * Deal with the two high-speed IOCtl that takes it's arguments from
-     * 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)
-        && fUnrestricted)
-        return supdrvIOCtlFast(iCmd, *(uint32_t *)pData, &g_DevExt, pSession);
-    return VBoxDrvDarwinIOCtlSlow(pSession, iCmd, pData, pProcess);
-}
-
-
-/**
- * Worker for VBoxDrvDarwinIOCtl that takes the slow IOCtl functions.
+     * No high speed IOCtls here yet.
+     */
+
+    return VbgdDarwinIOCtlSlow(pSession, iCmd, pData, pProcess);
+}
+
+
+/**
+ * Worker for VbgdDarwinIOCtl that takes the slow IOCtl functions.
  *
  * @returns Darwin errno.
@@ -552,10 +464,10 @@
  * @param pSession  The session.
  * @param iCmd      The IOCtl command.
- * @param pData     Pointer to the kernel copy of the SUPDRVIOCTLDATA buffer.
+ * @param pData     Pointer to the kernel copy of the data buffer.
  * @param pProcess  The calling process.
  */
-static int VBoxDrvDarwinIOCtlSlow(PSUPDRVSESSION pSession, u_long iCmd, caddr_t pData, struct proc *pProcess)
-{
-    LogFlow(("VBoxDrvDarwinIOCtlSlow: pSession=%p iCmd=%p pData=%p pProcess=%p\n", pSession, iCmd, pData, pProcess));
+static int VbgdDarwinIOCtlSlow(PVBOXGUESTSESSION pSession, u_long iCmd, caddr_t pData, struct proc *pProcess)
+{
+    LogFlow(("VbgdDarwinIOCtlSlow: pSession=%p iCmd=%p pData=%p pProcess=%p\n", pSession, iCmd, pData, pProcess));
 
 
@@ -563,5 +475,5 @@
      * Buffered or unbuffered?
      */
-    PSUPREQHDR pHdr;
+    void *pvReqData;
     user_addr_t pUser = 0;
     void *pvPageBuf = NULL;
@@ -569,22 +481,8 @@
     if ((IOC_DIRMASK & iCmd) == IOC_INOUT)
     {
-        pHdr = (PSUPREQHDR)pData;
-        if (RT_UNLIKELY(cbReq < sizeof(*pHdr)))
-        {
-            OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: cbReq=%#x < %#x; iCmd=%#lx\n", cbReq, (int)sizeof(*pHdr), iCmd));
-            return EINVAL;
-        }
-        if (RT_UNLIKELY((pHdr->fFlags & SUPREQHDR_FLAGS_MAGIC_MASK) != SUPREQHDR_FLAGS_MAGIC))
-        {
-            OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: bad magic fFlags=%#x; iCmd=%#lx\n", pHdr->fFlags, iCmd));
-            return EINVAL;
-        }
-        if (RT_UNLIKELY(    RT_MAX(pHdr->cbIn, pHdr->cbOut) != cbReq
-                        ||  pHdr->cbIn < sizeof(*pHdr)
-                        ||  pHdr->cbOut < sizeof(*pHdr)))
-        {
-            OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: max(%#x,%#x) != %#x; iCmd=%#lx\n", pHdr->cbIn, pHdr->cbOut, cbReq, iCmd));
-            return EINVAL;
-        }
+        /*
+         * Raw buffered request data, common code validates it.
+         */
+        pvReqData = pData;
     }
     else if ((IOC_DIRMASK & iCmd) == IOC_VOID && !cbReq)
@@ -593,46 +491,45 @@
          * Get the header and figure out how much we're gonna have to read.
          */
-        SUPREQHDR Hdr;
+        VBGLBIGREQ Hdr;
         pUser = (user_addr_t)*(void **)pData;
         int rc = copyin(pUser, &Hdr, sizeof(Hdr));
         if (RT_UNLIKELY(rc))
         {
-            OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: copyin(%llx,Hdr,) -> %#x; iCmd=%#lx\n", (unsigned long long)pUser, rc, iCmd));
+            Log(("VbgdDarwinIOCtlSlow: copyin(%llx,Hdr,) -> %#x; iCmd=%#lx\n", (unsigned long long)pUser, rc, iCmd));
             return rc;
         }
-        if (RT_UNLIKELY((Hdr.fFlags & SUPREQHDR_FLAGS_MAGIC_MASK) != SUPREQHDR_FLAGS_MAGIC))
-        {
-            OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: bad magic fFlags=%#x; iCmd=%#lx\n", Hdr.fFlags, iCmd));
+        if (RT_UNLIKELY(Hdr.u32Magic != VBGLBIGREQ_MAGIC))
+        {
+            Log(("VbgdDarwinIOCtlSlow: bad magic u32Magic=%#x; iCmd=%#lx\n", Hdr.u32Magic, iCmd));
             return EINVAL;
         }
-        cbReq = RT_MAX(Hdr.cbIn, Hdr.cbOut);
-        if (RT_UNLIKELY(    Hdr.cbIn < sizeof(Hdr)
-                        ||  Hdr.cbOut < sizeof(Hdr)
-                        ||  cbReq > _1M*16))
-        {
-            OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: max(%#x,%#x); iCmd=%#lx\n", Hdr.cbIn, Hdr.cbOut, iCmd));
+        cbReq = Hdr.cbData;
+        if (RT_UNLIKELY(cbReq > _1M*16))
+        {
+            Log(("VbgdDarwinIOCtlSlow: %#x; iCmd=%#lx\n", Hdr.cbData, iCmd));
             return EINVAL;
         }
+        pUser = Hdr.pvDataR3;
 
         /*
          * Allocate buffer and copy in the data.
          */
-        pHdr = (PSUPREQHDR)RTMemTmpAlloc(cbReq);
-        if (!pHdr)
-            pvPageBuf = pHdr = (PSUPREQHDR)IOMallocAligned(RT_ALIGN_Z(cbReq, PAGE_SIZE), 8);
-        if (RT_UNLIKELY(!pHdr))
-        {
-            OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: failed to allocate buffer of %d bytes; iCmd=%#lx\n", cbReq, iCmd));
+        pvReqData = RTMemTmpAlloc(cbReq);
+        if (!pvReqData)
+            pvPageBuf = pvReqData = IOMallocAligned(RT_ALIGN_Z(cbReq, PAGE_SIZE), 8);
+        if (RT_UNLIKELY(!pvReqData))
+        {
+            Log(("VbgdDarwinIOCtlSlow: failed to allocate buffer of %d bytes; iCmd=%#lx\n", cbReq, iCmd));
             return ENOMEM;
         }
-        rc = copyin(pUser, pHdr, Hdr.cbIn);
+        rc = copyin(pUser, pvReqData, Hdr.cbData);
         if (RT_UNLIKELY(rc))
         {
-            OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: copyin(%llx,%p,%#x) -> %#x; iCmd=%#lx\n",
-                        (unsigned long long)pUser, pHdr, Hdr.cbIn, rc, iCmd));
+            Log(("VbgdDarwinIOCtlSlow: copyin(%llx,%p,%#x) -> %#x; iCmd=%#lx\n",
+                 (unsigned long long)pUser, pvReqData, Hdr.cbData, rc, iCmd));
             if (pvPageBuf)
                 IOFreeAligned(pvPageBuf, RT_ALIGN_Z(cbReq, PAGE_SIZE));
             else
-                RTMemTmpFree(pHdr);
+                RTMemTmpFree(pvReqData);
             return rc;
         }
@@ -640,5 +537,5 @@
     else
     {
-        Log(("VBoxDrvDarwinIOCtlSlow: huh? cbReq=%#x iCmd=%#lx\n", cbReq, iCmd));
+        Log(("VbgdDarwinIOCtlSlow: huh? cbReq=%#x iCmd=%#lx\n", cbReq, iCmd));
         return EINVAL;
     }
@@ -647,6 +544,7 @@
      * Process the IOCtl.
      */
-    int rc = supdrvIOCtl(iCmd, &g_DevExt, pSession, pHdr);
-    if (RT_LIKELY(!rc))
+    size_t cbReqRet = 0;
+    int rc = VBoxGuestCommonIOCtl(iCmd, &g_DevExt, pSession, pvReqData, cbReq, &cbReqRet);
+    if (RT_SUCCESS(rc))
     {
         /*
@@ -655,14 +553,13 @@
         if (pUser)
         {
-            uint32_t cbOut = pHdr->cbOut;
-            if (cbOut > cbReq)
+            if (cbReqRet > cbReq)
             {
-                OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: too much output! %#x > %#x; uCmd=%#lx!\n", cbOut, cbReq, iCmd));
-                cbOut = cbReq;
+                Log(("VbgdDarwinIOCtlSlow: too much output! %#x > %#x; uCmd=%#lx!\n", cbReqRet, cbReq, iCmd));
+                cbReqRet = cbReq;
             }
-            rc = copyout(pHdr, pUser, cbOut);
+            rc = copyout(pvReqData, pUser, cbReqRet);
             if (RT_UNLIKELY(rc))
-                OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: copyout(%p,%llx,%#x) -> %d; uCmd=%#lx!\n",
-                            pHdr, (unsigned long long)pUser, cbOut, rc, iCmd));
+                Log(("VbgdDarwinIOCtlSlow: copyout(%p,%llx,%#x) -> %d; uCmd=%#lx!\n",
+                     pvReqData, (unsigned long long)pUser, cbReqRet, rc, iCmd));
 
             /* cleanup */
@@ -670,6 +567,8 @@
                 IOFreeAligned(pvPageBuf, RT_ALIGN_Z(cbReq, PAGE_SIZE));
             else
-                RTMemTmpFree(pHdr);
-        }
+                RTMemTmpFree(pvReqData);
+        }
+        else
+            rc = 0;
     }
     else
@@ -683,87 +582,36 @@
                 IOFreeAligned(pvPageBuf, RT_ALIGN_Z(cbReq, PAGE_SIZE));
             else
-                RTMemTmpFree(pHdr);
-        }
-
-        Log(("VBoxDrvDarwinIOCtlSlow: pid=%d iCmd=%lx pData=%p failed, rc=%d\n", proc_pid(pProcess), iCmd, (void *)pData, rc));
+                RTMemTmpFree(pvReqData);
+        }
+
+        Log(("VbgdDarwinIOCtlSlow: pid=%d iCmd=%lx pData=%p failed, rc=%d\n", proc_pid(pProcess), iCmd, (void *)pData, rc));
         rc = EINVAL;
     }
 
-    Log2(("VBoxDrvDarwinIOCtlSlow: returns %d\n", rc));
+    Log2(("VbgdDarwinIOCtlSlow: returns %d\n", rc));
     return rc;
 }
 
 
-/**
- * The SUPDRV IDC entry point.
- *
- * @returns VBox status code, see supdrvIDC.
- * @param   iReq        The request code.
- * @param   pReq        The request.
- */
-DECLEXPORT(int) VBOXCALL SUPDrvDarwinIDC(uint32_t uReq, PSUPDRVIDCREQHDR pReq)
-{
-    PSUPDRVSESSION  pSession;
-
-    /*
-     * Some quick validations.
-     */
-    if (RT_UNLIKELY(!VALID_PTR(pReq)))
-        return VERR_INVALID_POINTER;
-
-    pSession = pReq->pSession;
-    if (pSession)
-    {
-        if (RT_UNLIKELY(!VALID_PTR(pSession)))
-            return VERR_INVALID_PARAMETER;
-        if (RT_UNLIKELY(pSession->pDevExt != &g_DevExt))
-            return VERR_INVALID_PARAMETER;
-    }
-    else if (RT_UNLIKELY(uReq != SUPDRV_IDC_REQ_CONNECT))
-        return VERR_INVALID_PARAMETER;
-
-    /*
-     * Do the job.
-     */
-    return supdrvIDC(uReq, &g_DevExt, pSession, pReq);
-}
-
-
-/**
- * Initializes any OS specific object creator fields.
- */
-void VBOXCALL   supdrvOSObjInitCreator(PSUPDRVOBJ pObj, PSUPDRVSESSION pSession)
-{
-    NOREF(pObj);
-    NOREF(pSession);
-}
-
-
-/**
- * Checks if the session can access the object.
- *
- * @returns true if a decision has been made.
- * @returns false if the default access policy should be applied.
- *
- * @param   pObj        The object in question.
- * @param   pSession    The session wanting to access the object.
- * @param   pszObjName  The object name, can be NULL.
- * @param   prc         Where to store the result when returning true.
- */
-bool VBOXCALL   supdrvOSObjCanAccess(PSUPDRVOBJ pObj, PSUPDRVSESSION pSession, const char *pszObjName, int *prc)
-{
-    NOREF(pObj);
-    NOREF(pSession);
-    NOREF(pszObjName);
-    NOREF(prc);
-    return false;
-}
+/*
+ * The VBoxGuest IDC entry points.
+ *
+ * This code is shared with the other unixy OSes.
+ */
+#include "VBoxGuestIDC-unix.c.h"
+
+
+void VBoxGuestNativeISRMousePollEvent(PVBOXGUESTDEVEXT pDevExt)
+{
+    NOREF(pDevExt);
+}
+
 
 /**
  * Callback for blah blah blah.
  */
-IOReturn VBoxDrvDarwinSleepHandler(void * /* pvTarget */, void *pvRefCon, UInt32 uMessageType, IOService * /* pProvider */, void * /* pvMessageArgument */, vm_size_t /* argSize */)
-{
-    LogFlow(("VBoxDrv: Got sleep/wake notice. Message type was %X\n", (uint)uMessageType));
+IOReturn VbgdDarwinSleepHandler(void * /* pvTarget */, void *pvRefCon, UInt32 uMessageType, IOService * /* pProvider */, void * /* pvMessageArgument */, vm_size_t /* argSize */)
+{
+    LogFlow(("VBoxGuest: Got sleep/wake notice. Message type was %X\n", (uint)uMessageType));
 
     if (uMessageType == kIOMessageSystemWillSleep)
@@ -779,161 +627,4 @@
 
 /**
- * @copydoc SUPR0EnableVTx
- */
-int VBOXCALL supdrvOSEnableVTx(bool fEnable)
-{
-#ifdef VBOX_WITH_HOST_VMX
-    int rc;
-    if (   version_major >= 10 /* 10 = 10.6.x = Snow Leopard */
-        && g_pfnVmxSuspend
-        && g_pfnVmxResume
-        && g_pVmxUseCount)
-    {
-        if (fEnable)
-        {
-            rc = host_vmxon(false /* exclusive */);
-            if (rc == VMX_OK)
-                rc = VINF_SUCCESS;
-            else if (rc == VMX_UNSUPPORTED)
-                rc = VERR_VMX_NO_VMX;
-            else if (rc == VMX_INUSE)
-                rc = VERR_VMX_IN_VMX_ROOT_MODE;
-            else /* shouldn't happen, but just in case. */
-            {
-                LogRel(("host_vmxon returned %d\n", rc));
-                rc = VERR_UNRESOLVED_ERROR;
-            }
-            LogRel(("VBoxDrv: host_vmxon  -> vmx_use_count=%d rc=%Rrc\n", *g_pVmxUseCount, rc));
-        }
-        else
-        {
-            host_vmxoff();
-            rc = VINF_SUCCESS;
-            LogRel(("VBoxDrv: host_vmxoff -> vmx_use_count=%d\n", *g_pVmxUseCount));
-        }
-    }
-    else
-    {
-        /* In 10.5.x the host_vmxon is severely broken!  Don't use it, it will
-           frequnetly panic the host. */
-        rc = VERR_NOT_SUPPORTED;
-    }
-    return rc;
-#else
-    return VERR_NOT_SUPPORTED;
-#endif
-}
-
-
-/**
- * @copydoc SUPR0SuspendVTxOnCpu
- */
-bool VBOXCALL supdrvOSSuspendVTxOnCpu(void)
-{
-#ifdef VBOX_WITH_HOST_VMX
-    /*
-     * Consult the VMX usage counter, don't try suspend if not enabled.
-     *
-     * Note!  The host_vmxon/off code is still race prone since, but this is
-     *        currently the best we can do without always enable VMX when
-     *        loading the driver.
-     */
-    if (   g_pVmxUseCount
-        && *g_pVmxUseCount > 0)
-    {
-        g_pfnVmxSuspend();
-        return true;
-    }
-    return false;
-#else
-    return false;
-#endif
-}
-
-
-/**
- * @copydoc SUPR0ResumeVTxOnCpu
- */
-void VBOXCALL   supdrvOSResumeVTxOnCpu(bool fSuspended)
-{
-#ifdef VBOX_WITH_HOST_VMX
-    /*
-     * Don't consult the counter here, the state knows better.
-     * We're executing with interrupts disabled and anyone racing us with
-     * disabling VT-x will be waiting in the rendezvous code.
-     */
-    if (   fSuspended
-        && g_pfnVmxResume)
-        g_pfnVmxResume();
-    else
-        Assert(!fSuspended);
-#else
-    Assert(!fSuspended);
-#endif
-}
-
-
-bool VBOXCALL supdrvOSGetForcedAsyncTscMode(PSUPDRVDEVEXT pDevExt)
-{
-    NOREF(pDevExt);
-    return false;
-}
-
-
-void VBOXCALL   supdrvOSLdrNotifyOpened(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage)
-{
-#if 1
-    NOREF(pDevExt); NOREF(pImage);
-#else
-    /*
-     * Try store the image load address in NVRAM so we can retrived it on panic.
-     * Note! This only works if you're root! - Acutally, it doesn't work at all at the moment. FIXME!
-     */
-    IORegistryEntry *pEntry = IORegistryEntry::fromPath("/options", gIODTPlane);
-    if (pEntry)
-    {
-        char szVar[80];
-        RTStrPrintf(szVar, sizeof(szVar), "vboximage"/*-%s*/, pImage->szName);
-        char szValue[48];
-        RTStrPrintf(szValue, sizeof(szValue), "%#llx,%#llx", (uint64_t)(uintptr_t)pImage->pvImage,
-                    (uint64_t)(uintptr_t)pImage->pvImage + pImage->cbImageBits - 1);
-        bool fRc = pEntry->setProperty(szVar, szValue); NOREF(fRc);
-        pEntry->release();
-        SUPR0Printf("fRc=%d '%s'='%s'\n", fRc, szVar, szValue);
-    }
-    /*else
-        SUPR0Printf("failed to find /options in gIODTPlane\n");*/
-#endif
-}
-
-
-int  VBOXCALL   supdrvOSLdrOpen(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const char *pszFilename)
-{
-    NOREF(pDevExt); NOREF(pImage); NOREF(pszFilename);
-    return VERR_NOT_SUPPORTED;
-}
-
-
-int  VBOXCALL   supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, void *pv, const uint8_t *pbImageBits)
-{
-    NOREF(pDevExt); NOREF(pImage); NOREF(pv); NOREF(pbImageBits);
-    return VERR_NOT_SUPPORTED;
-}
-
-
-int  VBOXCALL   supdrvOSLdrLoad(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const uint8_t *pbImageBits, PSUPLDRLOAD pReq)
-{
-    NOREF(pDevExt); NOREF(pImage); NOREF(pbImageBits); NOREF(pReq);
-    return VERR_NOT_SUPPORTED;
-}
-
-
-void VBOXCALL   supdrvOSLdrUnload(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage)
-{
-    NOREF(pDevExt); NOREF(pImage);
-}
-
-
-/**
  * Converts an IPRT error code to a darwin error code.
  *
@@ -941,5 +632,5 @@
  * @param   rc      IPRT status code.
  */
-static int VBoxDrvDarwinErr2DarwinErr(int rc)
+static int VbgdDarwinErr2DarwinErr(int rc)
 {
     switch (rc)
@@ -961,37 +652,189 @@
 
 
-RTDECL(int) SUPR0Printf(const char *pszFormat, ...)
-{
-    va_list     va;
-    char        szMsg[512];
-
-    va_start(va, pszFormat);
-    RTStrPrintfV(szMsg, sizeof(szMsg) - 1, pszFormat, va);
-    va_end(va);
-    szMsg[sizeof(szMsg) - 1] = '\0';
-
-    printf("%s", szMsg);
-    return 0;
-}
-
-
 /*
  *
- * org_virtualbox_SupDrv
- *
- */
-
-
-/**
- * Initialize the object.
- */
-bool org_virtualbox_SupDrv::init(OSDictionary *pDictionary)
-{
-    LogFlow(("org_virtualbox_SupDrv::init([%p], %p)\n", this, pDictionary));
-    if (IOService::init(pDictionary))
-    {
-        /* init members. */
+ * org_virtualbox_VBoxGuest
+ *
+ */
+
+static void
+interruptHandler(OSObject *pOwner, IOInterruptEventSource *pSrc, int cInts)
+{
+    if (!pSrc)
+        return;
+
+    bool fTaken = VBoxGuestCommonISR(&g_DevExt);
+    if (!fTaken)
+        printf("VBoxGuestCommonISR error\n");
+}
+
+static bool
+checkForInterrupt(OSObject *pOwner, IOFilterInterruptEventSource *pSrc)
+{
+    if (!pSrc)
+        return false;
+
+    return true;
+}
+
+bool
+org_virtualbox_VBoxGuest::setupVmmDevInterrupts(IOService *pProvider)
+{
+    IOWorkLoop *pWorkLoop = (IOWorkLoop *)getWorkLoop();
+
+    if (!pWorkLoop)
+        return false;
+
+    m_pInterruptSrc = IOFilterInterruptEventSource::filterInterruptEventSource(this,
+                                                                               &interruptHandler,
+                                                                               &checkForInterrupt,
+                                                                               pProvider);
+
+    if (kIOReturnSuccess != pWorkLoop->addEventSource(m_pInterruptSrc))
+    {
+        m_pInterruptSrc->disable();
+        m_pInterruptSrc->release();
+        m_pInterruptSrc = 0;
+        return false;
+    }
+
+    m_pInterruptSrc->enable();
+
+    return true;
+}
+
+bool
+org_virtualbox_VBoxGuest::disableVmmDevInterrupts(void)
+{
+    IOWorkLoop *pWorkLoop = (IOWorkLoop *)getWorkLoop();
+
+    if (!pWorkLoop)
+        return false;
+
+    if (!m_pInterruptSrc)
+        return false;
+
+    m_pInterruptSrc->disable();
+    pWorkLoop->removeEventSource(m_pInterruptSrc);
+    m_pInterruptSrc->release();
+    m_pInterruptSrc = 0;
+
+    return true;
+}
+
+bool org_virtualbox_VBoxGuest::isVmmDev(IOPCIDevice *pIOPCIDevice)
+{
+    UInt16 uVendorId, uDeviceId;
+
+    if (!pIOPCIDevice)
+        return false;
+
+    uVendorId = m_pIOPCIDevice->configRead16(kIOPCIConfigVendorID);
+    uDeviceId = m_pIOPCIDevice->configRead16(kIOPCIConfigDeviceID);
+
+    if (uVendorId == VMMDEV_VENDORID && uDeviceId == VMMDEV_DEVICEID)
         return true;
-    }
+
+    return true;
+}
+
+
+/**
+ * Start this service.
+ */
+bool org_virtualbox_VBoxGuest::start(IOService *pProvider)
+{
+    if (!IOService::start(pProvider))
+        return false;
+
+    /* Low level initialization should be performed only once */
+    if (!ASMAtomicCmpXchgBool(&g_fInstantiated, true, false))
+    {
+        IOService::stop(pProvider);
+        return false;
+    }
+
+    m_pIOPCIDevice = OSDynamicCast(IOPCIDevice, pProvider);
+    if (m_pIOPCIDevice)
+    {
+        if (isVmmDev(m_pIOPCIDevice))
+        {
+            /* Enable memory response from VMM device */
+            m_pIOPCIDevice->setMemoryEnable(true);
+            m_pIOPCIDevice->setIOEnable(true);
+
+            IOMemoryDescriptor *pMem = m_pIOPCIDevice->getDeviceMemoryWithIndex(0);
+            if (pMem)
+            {
+                IOPhysicalAddress IOPortBasePhys = pMem->getPhysicalAddress();
+                /* Check that returned value is from I/O port range (at least it is 16-bit lenght) */
+                if((IOPortBasePhys >> 16) == 0)
+                {
+
+                    RTIOPORT IOPortBase = (RTIOPORT)IOPortBasePhys;
+                    void    *pvMMIOBase = NULL;
+                    uint32_t cbMMIO     = 0;
+                    m_pMap = m_pIOPCIDevice->mapDeviceMemoryWithIndex(1);
+                    if (m_pMap)
+                    {
+                        pvMMIOBase = (void *)m_pMap->getVirtualAddress();
+                        cbMMIO     = m_pMap->getLength();
+                    }
+
+                    int rc = VBoxGuestInitDevExt(&g_DevExt,
+                                                 IOPortBase,
+                                                 pvMMIOBase,
+                                                 cbMMIO,
+#if ARCH_BITS == 64
+                                                 VBOXOSTYPE_MacOS_x64,
+#else
+                                                 VBOXOSTYPE_MacOS,
+#endif
+                                                 0);
+                    if (RT_SUCCESS(rc))
+                    {
+                        rc = VbgdDarwinCharDevInit();
+                        if (rc == KMOD_RETURN_SUCCESS)
+                        {
+                            if (setupVmmDevInterrupts(pProvider))
+                            {
+                                /* register the service. */
+                                registerService();
+                                printf("VBoxGuest: Successfully started I/O kit class instance.\n");
+                                return true;
+                            }
+
+                            printf("VBoxGuest: Failed to set up interrupts\n");
+                            VbgdDarwinCharDevRemove();
+                        }
+                        else
+                            printf("VBoxGuest: Failed to initialize character device (rc=%d).\n", rc);
+
+                        VBoxGuestDeleteDevExt(&g_DevExt);
+                    }
+                    else
+                        printf("VBoxGuest: Failed to initialize common code (rc=%d).\n", rc);
+
+                    if (m_pMap)
+                    {
+                        m_pMap->release();
+                        m_pMap = NULL;
+                    }
+                }
+            }
+            else
+                printf("VBoxGuest: The device missing is the I/O port range (#0).\n");
+        }
+        else
+            printf("VBoxGuest: Not the VMMDev (%#x:%#x).\n",
+                   m_pIOPCIDevice->configRead16(kIOPCIConfigVendorID), m_pIOPCIDevice->configRead16(kIOPCIConfigDeviceID));
+    }
+    else
+        printf("VBoxGuest: Provider is not an instance of IOPCIDevice.\n");
+
+    ASMAtomicXchgBool(&g_fInstantiated, false);
+
+    IOService::stop(pProvider);
+
     return false;
 }
@@ -999,48 +842,30 @@
 
 /**
- * Free the object.
- */
-void org_virtualbox_SupDrv::free(void)
-{
-    LogFlow(("IOService::free([%p])\n", this));
-    IOService::free();
-}
-
-
-/**
- * Check if it's ok to start this service.
- * It's always ok by us, so it's up to IOService to decide really.
- */
-IOService *org_virtualbox_SupDrv::probe(IOService *pProvider, SInt32 *pi32Score)
-{
-    LogFlow(("org_virtualbox_SupDrv::probe([%p])\n", this));
-    return IOService::probe(pProvider, pi32Score);
-}
-
-
-/**
- * Start this service.
- */
-bool org_virtualbox_SupDrv::start(IOService *pProvider)
-{
-    LogFlow(("org_virtualbox_SupDrv::start([%p])\n", this));
-
-    if (IOService::start(pProvider))
-    {
-        /* register the service. */
-        registerService();
-        return true;
-    }
-    return false;
-}
-
-
-/**
  * Stop this service.
  */
-void org_virtualbox_SupDrv::stop(IOService *pProvider)
-{
-    LogFlow(("org_virtualbox_SupDrv::stop([%p], %p)\n", this, pProvider));
+void org_virtualbox_VBoxGuest::stop(IOService *pProvider)
+{
+    LogFlow(("org_virtualbox_VBoxGuest::stop([%p], %p)\n", this, pProvider));
+
+    AssertReturnVoid(ASMAtomicReadBool(&g_fInstantiated));
+
+    /* Low level termination should be performed only once */
+    if (!disableVmmDevInterrupts())
+        printf("vboxguest: unable to unregister interrupt handler\n");
+
+    VbgdDarwinCharDevRemove();
+    VBoxGuestDeleteDevExt(&g_DevExt);
+
+    if (m_pMap)
+    {
+        m_pMap->release();
+        m_pMap = NULL;
+    }
+
     IOService::stop(pProvider);
+
+    ASMAtomicWriteBool(&g_fInstantiated, false);
+
+    printf("vboxguest module unloaded\n");
 }
 
@@ -1052,8 +877,8 @@
  * @param   fOptions        Flags.
  */
-bool org_virtualbox_SupDrv::terminate(IOOptionBits fOptions)
+bool org_virtualbox_VBoxGuest::terminate(IOOptionBits fOptions)
 {
     bool fRc;
-    LogFlow(("org_virtualbox_SupDrv::terminate: reference_count=%d g_cSessions=%d (fOptions=%#x)\n",
+    LogFlow(("org_virtualbox_VBoxGuest::terminate: reference_count=%d g_cSessions=%d (fOptions=%#x)\n",
              KMOD_INFO_NAME.reference_count, ASMAtomicUoReadS32(&g_cSessions), fOptions));
     if (    KMOD_INFO_NAME.reference_count != 0
@@ -1069,5 +894,5 @@
 /*
  *
- * org_virtualbox_SupDrvClient
+ * org_virtualbox_VBoxGuestClient
  *
  */
@@ -1077,7 +902,7 @@
  * Initializer called when the client opens the service.
  */
-bool org_virtualbox_SupDrvClient::initWithTask(task_t OwningTask, void *pvSecurityId, UInt32 u32Type)
-{
-    LogFlow(("org_virtualbox_SupDrvClient::initWithTask([%p], %#x, %p, %#x) (cur pid=%d proc=%p)\n",
+bool org_virtualbox_VBoxGuestClient::initWithTask(task_t OwningTask, void *pvSecurityId, UInt32 u32Type)
+{
+    LogFlow(("org_virtualbox_VBoxGuestClient::initWithTask([%p], %#x, %p, %#x) (cur pid=%d proc=%p)\n",
              this, OwningTask, pvSecurityId, u32Type, RTProcSelf(), RTR0ProcHandleSelf()));
     AssertMsg((RTR0PROCESS)OwningTask == RTR0ProcHandleSelf(), ("%p %p\n", OwningTask, RTR0ProcHandleSelf()));
@@ -1099,7 +924,7 @@
  * Start the client service.
  */
-bool org_virtualbox_SupDrvClient::start(IOService *pProvider)
-{
-    LogFlow(("org_virtualbox_SupDrvClient::start([%p], %p) (cur pid=%d proc=%p)\n",
+bool org_virtualbox_VBoxGuestClient::start(IOService *pProvider)
+{
+    LogFlow(("org_virtualbox_VBoxGuestClient::start([%p], %p) (cur pid=%d proc=%p)\n",
              this, pProvider, RTProcSelf(), RTR0ProcHandleSelf() ));
     AssertMsgReturn((RTR0PROCESS)m_Task == RTR0ProcHandleSelf(),
@@ -1109,5 +934,5 @@
     if (IOUserClient::start(pProvider))
     {
-        m_pProvider = OSDynamicCast(org_virtualbox_SupDrv, pProvider);
+        m_pProvider = OSDynamicCast(org_virtualbox_VBoxGuest, pProvider);
         if (m_pProvider)
         {
@@ -1117,9 +942,9 @@
              * Create a new session.
              */
-            int rc = supdrvCreateSession(&g_DevExt, true /* fUser */, false /*fUnrestricted*/, &m_pSession);
+            int rc = VBoxGuestCreateUserSession(&g_DevExt, &m_pSession);
             if (RT_SUCCESS(rc))
             {
                 m_pSession->fOpened = false;
-                /* The Uid, Gid and fUnrestricted fields are set on open. */
+                /* The fUnrestricted field is set on open. */
 
                 /*
@@ -1130,5 +955,5 @@
                 RTSpinlockAcquire(g_Spinlock);
 
-                PSUPDRVSESSION pCur = g_apSessionHashTab[iHash];
+                PVBOXGUESTSESSION pCur = g_apSessionHashTab[iHash];
                 if (pCur && pCur->Process != m_pSession->Process)
                 {
@@ -1140,5 +965,5 @@
                     m_pSession->pNextHash = g_apSessionHashTab[iHash];
                     g_apSessionHashTab[iHash] = m_pSession;
-                    m_pSession->pvSupDrvClient = this;
+                    m_pSession->pvVBoxGuestClient = this;
                     ASMAtomicIncS32(&g_cSessions);
                     rc = VINF_SUCCESS;
@@ -1147,20 +972,20 @@
                     rc = VERR_ALREADY_LOADED;
 
-                RTSpinlockReleaseNoInts(g_Spinlock);
+                RTSpinlockRelease(g_Spinlock);
                 if (RT_SUCCESS(rc))
                 {
-                    Log(("org_virtualbox_SupDrvClient::start: created session %p for pid %d\n", m_pSession, (int)RTProcSelf()));
+                    Log(("org_virtualbox_VBoxGuestClient::start: created session %p for pid %d\n", m_pSession, (int)RTProcSelf()));
                     return true;
                 }
 
-                LogFlow(("org_virtualbox_SupDrvClient::start: already got a session for this process (%p)\n", pCur));
-                supdrvCloseSession(&g_DevExt, m_pSession);
+                LogFlow(("org_virtualbox_VBoxGuestClient::start: already got a session for this process (%p)\n", pCur));
+                VBoxGuestCloseSession(&g_DevExt, m_pSession);
             }
 
             m_pSession = NULL;
-            LogFlow(("org_virtualbox_SupDrvClient::start: rc=%Rrc from supdrvCreateSession\n", rc));
+            LogFlow(("org_virtualbox_VBoxGuestClient::start: rc=%Rrc from supdrvCreateSession\n", rc));
         }
         else
-            LogFlow(("org_virtualbox_SupDrvClient::start: %p isn't org_virtualbox_SupDrv\n", pProvider));
+            LogFlow(("org_virtualbox_VBoxGuestClient::start: %p isn't org_virtualbox_VBoxGuest\n", pProvider));
     }
     return false;
@@ -1171,5 +996,5 @@
  * Common worker for clientClose and VBoxDrvDarwinClose.
  */
-/* static */ void org_virtualbox_SupDrvClient::sessionClose(RTPROCESS Process)
+/* static */ void org_virtualbox_VBoxGuestClient::sessionClose(RTPROCESS Process)
 {
     /*
@@ -1177,9 +1002,9 @@
      *
      * Note! Only one session per process. (Both start() and
-     * VBoxDrvDarwinOpen makes sure this is so.)
+     * VbgdDarwinOpen makes sure this is so.)
      */
     const unsigned  iHash = SESSION_HASH(Process);
     RTSpinlockAcquire(g_Spinlock);
-    PSUPDRVSESSION  pSession = g_apSessionHashTab[iHash];
+    PVBOXGUESTSESSION  pSession = g_apSessionHashTab[iHash];
     if (pSession)
     {
@@ -1192,5 +1017,5 @@
         else
         {
-            PSUPDRVSESSION pPrev = pSession;
+            PVBOXGUESTSESSION pPrev = pSession;
             pSession = pSession->pNextHash;
             while (pSession)
@@ -1210,8 +1035,8 @@
         }
     }
-    RTSpinlockReleaseNoInts(g_Spinlock);
+    RTSpinlockRelease(g_Spinlock);
     if (!pSession)
     {
-        Log(("SupDrvClient::sessionClose: pSession == NULL, pid=%d; freed already?\n", (int)Process));
+        Log(("VBoxGuestClient::sessionClose: pSession == NULL, pid=%d; freed already?\n", (int)Process));
         return;
     }
@@ -1220,6 +1045,6 @@
      * Remove it from the client object.
      */
-    org_virtualbox_SupDrvClient *pThis = (org_virtualbox_SupDrvClient *)pSession->pvSupDrvClient;
-    pSession->pvSupDrvClient = NULL;
+    org_virtualbox_VBoxGuestClient *pThis = (org_virtualbox_VBoxGuestClient *)pSession->pvVBoxGuestClient;
+    pSession->pvVBoxGuestClient = NULL;
     if (pThis)
     {
@@ -1231,5 +1056,5 @@
      * Close the session.
      */
-    supdrvCloseSession(&g_DevExt, pSession);
+    VBoxGuestCloseSession(&g_DevExt, pSession);
 }
 
@@ -1238,7 +1063,7 @@
  * Client exits normally.
  */
-IOReturn org_virtualbox_SupDrvClient::clientClose(void)
-{
-    LogFlow(("org_virtualbox_SupDrvClient::clientClose([%p]) (cur pid=%d proc=%p)\n", this, RTProcSelf(), RTR0ProcHandleSelf()));
+IOReturn org_virtualbox_VBoxGuestClient::clientClose(void)
+{
+    LogFlow(("org_virtualbox_VBoxGuestClient::clientClose([%p]) (cur pid=%d proc=%p)\n", this, RTProcSelf(), RTR0ProcHandleSelf()));
     AssertMsg((RTR0PROCESS)m_Task == RTR0ProcHandleSelf(), ("%p %p\n", m_Task, RTR0ProcHandleSelf()));
 
@@ -1261,45 +1086,2 @@
 }
 
-
-/**
- * The client exits abnormally / forgets to do cleanups. (logging)
- */
-IOReturn org_virtualbox_SupDrvClient::clientDied(void)
-{
-    LogFlow(("org_virtualbox_SupDrvClient::clientDied([%p]) m_Task=%p R0Process=%p Process=%d\n",
-             this, m_Task, RTR0ProcHandleSelf(), RTProcSelf()));
-
-    /* IOUserClient::clientDied() calls clientClose, so we'll just do the work there. */
-    return IOUserClient::clientDied();
-}
-
-
-/**
- * Terminate the service (initiate the destruction). (logging)
- */
-bool org_virtualbox_SupDrvClient::terminate(IOOptionBits fOptions)
-{
-    LogFlow(("org_virtualbox_SupDrvClient::terminate([%p], %#x)\n", this, fOptions));
-    return IOUserClient::terminate(fOptions);
-}
-
-
-/**
- * The final stage of the client service destruction. (logging)
- */
-bool org_virtualbox_SupDrvClient::finalize(IOOptionBits fOptions)
-{
-    LogFlow(("org_virtualbox_SupDrvClient::finalize([%p], %#x)\n", this, fOptions));
-    return IOUserClient::finalize(fOptions);
-}
-
-
-/**
- * Stop the client service. (logging)
- */
-void org_virtualbox_SupDrvClient::stop(IOService *pProvider)
-{
-    LogFlow(("org_virtualbox_SupDrvClient::stop([%p])\n", this));
-    IOUserClient::stop(pProvider);
-}
-
Index: /trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp
===================================================================
--- /trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp	(revision 45458)
+++ /trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp	(revision 45459)
@@ -55,5 +55,5 @@
 # endif
 #endif
-#if defined(RT_OS_SOLARIS)
+#if defined(RT_OS_SOLARIS) || defined(RT_OS_DARWIN)
 # include <iprt/rand.h>
 #endif
@@ -77,5 +77,5 @@
 static const size_t cbChangeMemBalloonReq = RT_OFFSETOF(VMMDevChangeMemBalloon, aPhysPage[VMMDEV_MEMORY_BALLOON_CHUNK_PAGES]);
 
-#if defined(RT_OS_SOLARIS)
+#if defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS)
 /**
  * Drag in the rest of IRPT since we share it with the
@@ -97,5 +97,5 @@
     NULL
 };
-#endif  /* RT_OS_SOLARIS */
+#endif  /* RT_OS_DARWIN || RT_OS_SOLARIS  */
 
 
Index: /trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h
===================================================================
--- /trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h	(revision 45458)
+++ /trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h	(revision 45459)
@@ -195,5 +195,5 @@
 typedef struct VBOXGUESTSESSION
 {
-#if defined(RT_OS_OS2) || defined(RT_OS_FREEBSD) || defined(RT_OS_SOLARIS)
+#if defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD) || defined(RT_OS_OS2) || defined(RT_OS_SOLARIS)
     /** Pointer to the next session with the same hash. */
     PVBOXGUESTSESSION           pNextHash;
@@ -224,5 +224,10 @@
      * be enabled for the host. */
     uint32_t volatile           fMouseStatus;
-
+#ifdef RT_OS_DARWIN
+    /** Pointer to the associated org_virtualbox_VBoxGuestClient object. */
+    void                       *pvVBoxGuestClient;
+    /** Whether this session has been opened or not. */
+    bool                        fOpened;
+#endif
 } VBOXGUESTSESSION;
 
Index: /trunk/src/VBox/Additions/common/VBoxGuest/darwin/Info.plist
===================================================================
--- /trunk/src/VBox/Additions/common/VBoxGuest/darwin/Info.plist	(revision 45458)
+++ /trunk/src/VBox/Additions/common/VBoxGuest/darwin/Info.plist	(revision 45459)
@@ -1,13 +1,14 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 <plist version="1.0">
 <dict>
     <key>CFBundleDevelopmentRegion</key>        <string>English</string>
-    <key>CFBundleExecutable</key>               <string>VBoxDrv</string>
-    <key>CFBundleIdentifier</key>               <string>org.virtualbox.kext.VBoxDrv</string>
+    <key>CFBundleExecutable</key>               <string>VBoxGuest</string>
+    <key>CFBundleIdentifier</key>               <string>org.virtualbox.kext.VBoxGuest</string>
     <key>CFBundleInfoDictionaryVersion</key>    <string>6.0</string>
-    <key>CFBundleName</key>                     <string>VBoxDrv</string>
+    <key>CFBundleName</key>                     <string>VBoxGuest</string>
     <key>CFBundlePackageType</key>              <string>KEXT</string>
     <key>CFBundleSignature</key>                <string>????</string>
+    <key>NSHumanReadableCopyright</key>         <string>Copyright © 2007-@VBOX_C_YEAR@ @VBOX_VENDOR@</string>
     <key>CFBundleGetInfoString</key>            <string>@VBOX_PRODUCT@ @VBOX_VERSION_STRING@, © 2007-@VBOX_C_YEAR@ @VBOX_VENDOR@</string>
     <key>CFBundleVersion</key>                  <string>@VBOX_VERSION_MAJOR@.@VBOX_VERSION_MINOR@.@VBOX_VERSION_BUILD@</string>
@@ -16,24 +17,27 @@
     <key>IOKitPersonalities</key>
     <dict>
-        <key>VBoxDrv</key>
+        <key>VBoxGuest</key>
         <dict>
-            <key>CFBundleIdentifier</key>       <string>org.virtualbox.kext.VBoxDrv</string>
-            <key>IOClass</key>                  <string>org_virtualbox_SupDrv</string>
-            <key>IOMatchCategory</key>          <string>org_virtualbox_SupDrv</string>
-            <key>IOProviderClass</key>          <string>IOResources</string>
-            <key>IOResourceMatch</key>          <string>IOKit</string>
-            <key>IOUserClientClass</key>        <string>org_virtualbox_SupDrvClient</string>
+            <key>CFBundleIdentifier</key>       <string>org.virtualbox.kext.VBoxGuest</string>
+            <key>IOClass</key>                  <string>org_virtualbox_VBoxGuest</string>
+            <key>IOMatchCategory</key>          <string>org_virtualbox_VBoxGuest</string>
+            <key>IOUserClientClass</key>        <string>org_virtualbox_VBoxGuestClient</string>
+            <key>IOKitDebug</key>               <integer>65535</integer>
+            <key>IOProviderClass</key>          <string>IOPCIDevice</string>
+            <key>IONameMatch</key>              <string>pci80ee,cafe</string>
         </dict>
     </dict>
     <key>OSBundleLibraries</key>
     <dict>
-        <key>com.apple.kpi.bsd</key>            <string>9.0.0</string>
-        <key>com.apple.kpi.mach</key>           <string>9.0.0</string>
-        <key>com.apple.kpi.libkern</key>        <string>9.0.0</string>
-        <key>com.apple.kpi.unsupported</key>    <string>9.0.0</string>
-        <key>com.apple.kpi.iokit</key>          <string>9.0.0</string>
+        <key>com.apple.iokit.IOPCIFamily</key>  <string>2.5</string> <!-- TODO: Figure the version in mac os x 10.4. -->
+        <key>com.apple.kpi.bsd</key>            <string>8.0.0</string>
+        <key>com.apple.kpi.mach</key>           <string>8.0.0</string>
+        <key>com.apple.kpi.libkern</key>        <string>8.0.0</string>
+        <key>com.apple.kpi.unsupported</key>    <string>8.0.0</string>
+        <key>com.apple.kpi.iokit</key>          <string>8.0.0</string>
     </dict>
     <key>OSBundleLibraries_x86_64</key>
     <dict>
+        <key>com.apple.iokit.IOPCIFamily</key>  <string>2.6</string>
         <key>com.apple.kpi.bsd</key>            <string>10.0.0d4</string>
         <key>com.apple.kpi.mach</key>           <string>10.0.0d3</string>
Index: /trunk/src/VBox/Additions/common/VBoxGuestLib/HGCMInternal.cpp
===================================================================
--- /trunk/src/VBox/Additions/common/VBoxGuestLib/HGCMInternal.cpp	(revision 45458)
+++ /trunk/src/VBox/Additions/common/VBoxGuestLib/HGCMInternal.cpp	(revision 45459)
@@ -50,7 +50,8 @@
 /** The max parameter buffer size for a kernel request. */
 #define VBGLR0_MAX_HGCM_KERNEL_PARM     (16*_1M)
-#ifdef RT_OS_LINUX
+#if defined(RT_OS_LINUX) || (defined(RT_OS_DARWIN) && defined(RT_ARCH_X86))
 /** Linux needs to use bounce buffers since RTR0MemObjLockUser has unwanted
- *  side effects. */
+ * side effects.
+ * Darwin 32bit also needs this because of 4GB/4GB user/kernel space. */
 # define USE_BOUNCE_BUFFERS
 #endif
Index: /trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3Lib.cpp
===================================================================
--- /trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3Lib.cpp	(revision 45458)
+++ /trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3Lib.cpp	(revision 45459)
@@ -37,5 +37,6 @@
 # include <os2.h>
 
-#elif defined(RT_OS_FREEBSD) \
+#elif defined(RT_OS_DARWIN) \
+   || defined(RT_OS_FREEBSD) \
    || defined(RT_OS_HAIKU) \
    || defined(RT_OS_LINUX) \
@@ -43,6 +44,10 @@
 # include <sys/types.h>
 # include <sys/stat.h>
-# if defined(RT_OS_LINUX) /** @todo check this on solaris+freebsd as well. */
+# if defined(RT_OS_DARWIN) || defined(RT_OS_LINUX) /** @todo check this on solaris+freebsd as well. */
 #  include <sys/ioctl.h>
+# endif
+# if defined(RT_OS_DARWIN)
+#  include <mach/mach_port.h>
+#  include <IOKit/IOKitLib.h>
 # endif
 # include <errno.h>
@@ -87,4 +92,8 @@
  */
 static uint32_t volatile g_cInits = 0;
+#ifdef RT_OS_DARWIN
+/** I/O Kit connection handle. */
+static io_connect_t g_uConnection = 0;
+#endif
 
 
@@ -191,4 +200,38 @@
     g_File = (RTFILE)hf;
 
+#elif defined(RT_OS_DARWIN)
+    /* 
+     * Darwin is kind of special we need to engage the device via I/O first 
+     * before we open it via the BSD device node. 
+     */
+    mach_port_t MasterPort;
+    kern_return_t kr = IOMasterPort(MACH_PORT_NULL, &MasterPort);
+    if (kr != kIOReturnSuccess)
+        return VERR_GENERAL_FAILURE;
+
+    CFDictionaryRef ClassToMatch = IOServiceMatching("org_virtualbox_VBoxGuest");
+    if (!ClassToMatch)
+        return VERR_GENERAL_FAILURE;
+
+    io_service_t ServiceObject = IOServiceGetMatchingService(kIOMasterPortDefault, ClassToMatch);
+    if (!ServiceObject)
+        return VERR_NOT_FOUND;
+
+    io_connect_t uConnection;
+    kr = IOServiceOpen(ServiceObject, mach_task_self(), 0, &uConnection);
+    IOObjectRelease(ServiceObject);
+    if (kr != kIOReturnSuccess)
+        return VERR_OPEN_FAILED;
+
+    RTFILE hFile;
+    int rc = RTFileOpen(&hFile, pszDeviceName, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
+    if (RT_FAILURE(rc))
+    {
+        IOServiceClose(uConnection);
+        return rc;
+    }
+    g_File = hFile;
+    g_uConnection = uConnection;
+
 #elif defined(VBOX_VBGLR3_XFREE86)
     int File = xf86open(pszDeviceName, XF86_O_RDWR);
@@ -264,5 +307,4 @@
 
 # elif defined(RT_OS_OS2)
-
     RTFILE File = g_File;
     g_File = NIL_RTFILE;
@@ -270,4 +312,14 @@
     APIRET rc = DosClose((uintptr_t)File);
     AssertMsg(!rc, ("%ld\n", rc));
+
+#elif defined(RT_OS_DARWIN)
+    io_connect_t    uConnection = g_uConnection;
+    RTFILE          hFile       = g_File;
+    g_uConnection = 0;
+    g_File        = NIL_RTFILE;
+    kern_return_t kr = IOServiceClose(uConnection);
+    AssertMsg(kr == kIOReturnSuccess, ("%#x (%d)\n", kr, kr));
+    int rc = RTFileClose(hFile);
+    AssertRC(rc);
 
 # else /* The IPRT case. */
@@ -359,5 +411,5 @@
     return VINF_SUCCESS;
 
-#elif defined(RT_OS_LINUX)
+#elif defined(RT_OS_DARWIN) || defined(RT_OS_LINUX)
 # ifdef VBOX_VBGLR3_XFREE86
     int rc = xf86ioctl((int)g_File, iFunction, pvData);
Index: /trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibDaemonize.cpp
===================================================================
--- /trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibDaemonize.cpp	(revision 45458)
+++ /trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibDaemonize.cpp	(revision 45459)
@@ -29,8 +29,5 @@
 *   Header Files                                                               *
 *******************************************************************************/
-#if defined(RT_OS_DARWIN)
-# error "PORTME"
-
-#elif defined(RT_OS_OS2)
+#if defined(RT_OS_OS2)
 # define INCL_BASE
 # define INCL_ERRORS
@@ -74,8 +71,5 @@
 VBGLR3DECL(int) VbglR3Daemonize(bool fNoChDir, bool fNoClose)
 {
-#if defined(RT_OS_DARWIN)
-# error "PORTME"
-
-#elif defined(RT_OS_OS2)
+#if defined(RT_OS_OS2)
     PPIB pPib;
     PTIB pTib;
Index: /trunk/src/VBox/Additions/common/VBoxService/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Additions/common/VBoxService/Makefile.kmk	(revision 45458)
+++ /trunk/src/VBox/Additions/common/VBoxService/Makefile.kmk	(revision 45459)
@@ -120,4 +120,6 @@
 	VBoxServiceClipboard-os2.cpp
 
+VBoxService_LDFLAGS.darwin = -framework IOKit
+
 VBoxService_LIBS        += \
 	$(VBOX_LIB_IPRT_GUEST_R3) \
Index: /trunk/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo.cpp
===================================================================
--- /trunk/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo.cpp	(revision 45458)
+++ /trunk/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo.cpp	(revision 45459)
@@ -48,5 +48,5 @@
 #  include <net/if_arp.h>
 # endif
-# ifdef RT_OS_FREEBSD
+# if defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD)
 #  include <ifaddrs.h> /* getifaddrs, freeifaddrs */
 #  include <net/if_dl.h> /* LLADDR */
@@ -450,6 +450,11 @@
            && RT_SUCCESS(rc))
     {
+#ifdef RT_OS_DARWIN /* No ut_user->ut_session on Darwin */
+        VBoxServiceVerbose(4, "Found entry \"%s\" (type: %d, PID: %RU32)\n",
+                           ut_user->ut_user, ut_user->ut_type, ut_user->ut_pid);
+#else
         VBoxServiceVerbose(4, "Found entry \"%s\" (type: %d, PID: %RU32, session: %RU32)\n",
                            ut_user->ut_user, ut_user->ut_type, ut_user->ut_pid, ut_user->ut_session);
+#endif
         if (cUsersInList > cListSize)
         {
@@ -908,5 +913,5 @@
     return VERR_NOT_IMPLEMENTED;
 
-#elif defined(RT_OS_FREEBSD)
+#elif defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD)
     struct ifaddrs *pIfHead = NULL;
 
