Index: /trunk/include/VBox/VBoxGuest.h
===================================================================
--- /trunk/include/VBox/VBoxGuest.h	(revision 41639)
+++ /trunk/include/VBox/VBoxGuest.h	(revision 41640)
@@ -362,7 +362,4 @@
 #endif /* VBOX_WITH_HGCM */
 
-#ifdef RT_OS_WINDOWS
-# ifdef IN_RING0
-
 typedef DECLCALLBACK(void) FNVBOXMOUSENOTIFYCB(void *pvContext);
 typedef FNVBOXMOUSENOTIFYCB *PFNVBOXMOUSENOTIFYCB;
@@ -373,7 +370,5 @@
 } VBoxGuestMouseSetNotifyCallback;
 
-#  define VBOXGUEST_IOCTL_INTERNAL_SET_MOUSE_NOTIFY_CALLBACK   VBOXGUEST_IOCTL_CODE_(31, sizeof(VBoxGuestMouseSetNotifyCallback))
-# endif
-#endif
+#define VBOXGUEST_IOCTL_INTERNAL_SET_MOUSE_NOTIFY_CALLBACK   VBOXGUEST_IOCTL_CODE_(31, sizeof(VBoxGuestMouseSetNotifyCallback))
 
 #ifdef RT_OS_OS2
Index: /trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp
===================================================================
--- /trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp	(revision 41639)
+++ /trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp	(revision 41640)
@@ -727,4 +727,7 @@
         pDevExt->acMouseFeatureUsage[i] = 0;
     pDevExt->fMouseStatus = 0;
+    pDevExt->MouseSetNotifyCallback.pfnNotify = NULL;
+    pDevExt->MouseSetNotifyCallback.pvNotify = NULL;
+    pDevExt->cISR = 0;
 
     /*
@@ -1225,4 +1228,36 @@
     return VINF_SUCCESS;
 }
+
+
+#ifndef RT_OS_WINDOWS
+/**
+ * Set the callback for the kernel mouse handler.
+ *
+ * returns IPRT status code.
+ * @param   pDevExt         The device extension.
+ * @param   pNotify         The new callback information.
+ * @note  This function takes the session spinlock to update the callback
+ *        information, but the interrupt handler will not do this.  To make
+ *        sure that the interrupt handler sees a consistent structure, we
+ *        set the function pointer to NULL before updating the data and only
+ *        set it to the correct value once the data is updated.  Since the
+ *        interrupt handler executes atomically this ensures that the data is
+ *        valid if the function pointer is non-NULL.
+ */
+int VBoxGuestCommonIOCtl_SetMouseNotifyCallback(PVBOXGUESTDEVEXT pDevExt, VBoxGuestMouseSetNotifyCallback *pNotify)
+{
+    Log(("VBoxGuestCommonIOCtl: SET_MOUSE_NOTIFY_CALLBACK\n"));
+    RTSpinlockAcquire(pDevExt->SessionSpinlock);
+    ASMAtomicWriteNullPtr(&pDevExt->MouseSetNotifyCallback.pfnNotify);
+    pDevExt->MouseSetNotifyCallback.pvNotify = pNotify->pvNotify;
+    ASMAtomicWritePtr(&pDevExt->MouseSetNotifyCallback.pfnNotify,
+                      pNotify->pfnNotify);
+    RTSpinlockReleaseNoInts(pDevExt->SessionSpinlock);
+    /* Make sure no one is referencing the old data - hacky but should be
+     * effective. */
+    while (pDevExt->cISR > 0);
+    return VINF_SUCCESS;
+}
+#endif
 
 
@@ -2504,4 +2539,13 @@
                 break;
 
+#ifndef RT_OS_WINDOWS  /* Windows has its own implementation of this. */
+            case VBOXGUEST_IOCTL_INTERNAL_SET_MOUSE_NOTIFY_CALLBACK:
+                CHECKRET_RING0("SET_MOUSE_NOTIFY_CALLBACK");
+                CHECKRET_SIZE("SET_MOUSE_NOTIFY_CALLBACK",
+                           sizeof(VBoxGuestMouseSetNotifyCallback));
+                rc = VBoxGuestCommonIOCtl_SetMouseNotifyCallback(pDevExt, (VBoxGuestMouseSetNotifyCallback *)pvData);
+                break;
+#endif
+
             case VBOXGUEST_IOCTL_WAITEVENT:
                 CHECKRET_MIN_SIZE("WAITEVENT", sizeof(VBoxGuestWaitEventInfo));
@@ -2607,7 +2651,9 @@
 
     /*
-     * Enter the spinlock and check if it's our IRQ or not.
+     * Enter the spinlock, increase the ISR count and check if it's our IRQ or
+     * not.
      */
     RTSpinlockAcquire(pDevExt->EventSpinlock);
+    ASMAtomicIncU32(&pDevExt->cISR);
     fOurIrq = pDevExt->pVMMDevMemory->V.V1_04.fHaveEvents;
     if (fOurIrq)
@@ -2713,6 +2759,11 @@
         ASMAtomicIncU32(&pDevExt->u32MousePosChangedSeq);
         VBoxGuestNativeISRMousePollEvent(pDevExt);
-    }
-
+#ifndef RT_OS_WINDOWS
+        if (pDevExt->MouseSetNotifyCallback.pfnNotify)
+            pDevExt->MouseSetNotifyCallback.pfnNotify(pDevExt->MouseSetNotifyCallback.pvNotify);
+#endif
+    }
+
+    ASMAtomicDecU32(&pDevExt->cISR);
     Assert(rc == 0);
     return fOurIrq;
Index: /trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h
===================================================================
--- /trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h	(revision 41639)
+++ /trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h	(revision 41640)
@@ -167,4 +167,9 @@
      * together inside the session spinlock. */
     uint32_t volatile           fMouseStatus;
+    /** Callback and user data for a kernel mouse handler. */
+    VBoxGuestMouseSetNotifyCallback volatile MouseSetNotifyCallback;
+    /** Counter of number of active ISRs.  Currently used for safely removing
+     * the mouse handler callback. */
+    uint32_t volatile           cISR;
 
     /** Windows part. */
