Index: /trunk/src/VBox/Devices/Network/DevE1000.cpp
===================================================================
--- /trunk/src/VBox/Devices/Network/DevE1000.cpp	(revision 81416)
+++ /trunk/src/VBox/Devices/Network/DevE1000.cpp	(revision 81417)
@@ -1048,6 +1048,4 @@
     /** Transmit task. */
     PDMTASKHANDLE           hTxTask;
-    /** Rx wakeup signaller. */
-    PDMTASKHANDLE           hCanRxTask;
 
     /** Critical section - what is it protecting? */
@@ -1110,5 +1108,5 @@
     bool volatile fMaybeOutOfSpace;
     /** EMT: Gets signalled when more RX descriptors become available. */
-    RTSEMEVENT  hEventMoreRxDescAvail;
+    SUPSEMEVENT hEventMoreRxDescAvail;
 #ifdef E1K_WITH_RXD_CACHE
     /** RX: Fetched RX descriptors. */
@@ -1209,5 +1207,6 @@
     STAMPROFILE                         StatTransmitSendR3;
     STAMPROFILE                         StatRxOverflow;
-    STAMCOUNTER                         StatRxOverflowWakeup;
+    STAMCOUNTER                         StatRxOverflowWakeupRZ;
+    STAMCOUNTER                         StatRxOverflowWakeupR3;
     STAMCOUNTER                         StatTxDescCtxNormal;
     STAMCOUNTER                         StatTxDescCtxTSE;
@@ -1671,20 +1670,21 @@
 #endif /* E1K_WITH_TX_CS */
 
+
+/**
+ * Wakeup the RX thread.
+ */
+static void e1kWakeupReceive(PPDMDEVINS pDevIns, PE1KSTATE pThis)
+{
+    if (   pThis->fMaybeOutOfSpace
+        && pThis->hEventMoreRxDescAvail != NIL_SUPSEMEVENT)
+    {
+        STAM_COUNTER_INC(&pThis->CTX_SUFF_Z(StatRxOverflowWakeup));
+        E1kLog(("%s Waking up Out-of-RX-space semaphore\n",  pThis->szPrf));
+        int rc = PDMDevHlpSUPSemEventSignal(pDevIns, pThis->hEventMoreRxDescAvail);
+        AssertRC(rc);
+    }
+}
+
 #ifdef IN_RING3
-
-/**
- * Wakeup the RX thread.
- */
-static void e1kWakeupReceive(PPDMDEVINS pDevIns)
-{
-    PE1KSTATE pThis = PDMINS_2_DATA(pDevIns, PE1KSTATE);
-    if (    pThis->fMaybeOutOfSpace
-        &&  pThis->hEventMoreRxDescAvail != NIL_RTSEMEVENT)
-    {
-        STAM_COUNTER_INC(&pThis->StatRxOverflowWakeup);
-        E1kLog(("%s Waking up Out-of-RX-space semaphore\n",  pThis->szPrf));
-        RTSemEventSignal(pThis->hEventMoreRxDescAvail);
-    }
-}
 
 /**
@@ -3339,15 +3339,6 @@
         if (RT_SUCCESS(rc))
         {
-/** @todo bird: Use SUPSem* for this so we can signal it in ring-0 as well
- *        without requiring any context switches.  We should also check the
- *        wait condition before bothering to queue the item as we're currently
- *        queuing thousands of items per second here in a normal transmit
- *        scenario.  Expect performance changes when fixing this! */
-#ifdef IN_RING3
             /* Signal that we have more receive descriptors available. */
-            e1kWakeupReceive(pDevIns);
-#else
-            PDMDevHlpTaskTrigger(pDevIns, pThis->hCanRxTask);
-#endif
+            e1kWakeupReceive(pDevIns, pThis);
         }
     }
@@ -5619,5 +5610,5 @@
 {
     RT_NOREF(pvUser);
-    e1kWakeupReceive(pDevIns);
+    e1kWakeupReceive(pDevIns, PDMINS_2_DATA(pDevIns, PE1KSTATE));
 }
 
@@ -6498,5 +6489,5 @@
         E1kLogRel(("E1000: e1kR3NetworkDown_WaitReceiveAvail: waiting cMillies=%u...\n", cMillies));
         E1kLog(("%s: e1kR3NetworkDown_WaitReceiveAvail: waiting cMillies=%u...\n", pThis->szPrf, cMillies));
-        RTSemEventWait(pThis->hEventMoreRxDescAvail, cMillies);
+        PDMDevHlpSUPSemEventWaitNoResume(pDevIns, pThis->hEventMoreRxDescAvail, cMillies);
     }
     STAM_PROFILE_STOP(&pThis->StatRxOverflow, a);
@@ -7548,5 +7539,5 @@
 {
     /* Poke thread waiting for buffer space. */
-    e1kWakeupReceive(pDevIns);
+    e1kWakeupReceive(pDevIns, PDMINS_2_DATA(pDevIns, PE1KSTATE));
 }
 
@@ -7580,5 +7571,5 @@
 {
     /* Poke thread waiting for buffer space. */
-    e1kWakeupReceive(pDevIns);
+    e1kWakeupReceive(pDevIns, PDMINS_2_DATA(pDevIns, PE1KSTATE));
 }
 
@@ -7625,9 +7616,10 @@
     if (PDMCritSectIsInitialized(&pThis->cs))
     {
-        if (pThis->hEventMoreRxDescAvail != NIL_RTSEMEVENT)
-        {
-            RTSemEventSignal(pThis->hEventMoreRxDescAvail);
-            RTSemEventDestroy(pThis->hEventMoreRxDescAvail);
-            pThis->hEventMoreRxDescAvail = NIL_RTSEMEVENT;
+        if (pThis->hEventMoreRxDescAvail != NIL_SUPSEMEVENT)
+        {
+            PDMDevHlpSUPSemEventSignal(pDevIns, pThis->hEventMoreRxDescAvail);
+            RTThreadYield();
+            PDMDevHlpSUPSemEventClose(pDevIns, pThis->hEventMoreRxDescAvail);
+            pThis->hEventMoreRxDescAvail = NIL_SUPSEMEVENT;
         }
 #ifdef E1K_WITH_TX_CS
@@ -7730,5 +7722,5 @@
     RTStrPrintf(pThis->szPrf, sizeof(pThis->szPrf), "E1000#%d", iInstance);
     E1kLog(("%s Constructing new instance sizeof(E1KRXDESC)=%d\n", pThis->szPrf, sizeof(E1KRXDESC)));
-    pThis->hEventMoreRxDescAvail = NIL_RTSEMEVENT;
+    pThis->hEventMoreRxDescAvail = NIL_SUPSEMEVENT;
     pThis->u16TxPktLen  = 0;
     pThis->fIPcsum      = false;
@@ -7926,8 +7918,4 @@
     AssertRCReturn(rc, rc);
 
-    /* Create the RX notifier signaller. */
-    rc = PDMDevHlpTaskCreate(pDevIns, PDMTASK_F_RZ, "E1000-Rcv", e1kCanRxTaskCallback, NULL, &pThis->hCanRxTask);
-    AssertRCReturn(rc, rc);
-
 #ifdef E1K_TX_DELAY
     /* Create Transmit Delay Timer */
@@ -8014,5 +8002,5 @@
         return PDMDEV_SET_ERROR(pDevIns, rc, N_("Failed to attach the network LUN"));
 
-    rc = RTSemEventCreate(&pThis->hEventMoreRxDescAvail);
+    rc = PDMDevHlpSUPSemEventCreate(pDevIns, &pThis->hEventMoreRxDescAvail);
     AssertRCReturn(rc, rc);
 
@@ -8048,5 +8036,6 @@
     PDMDevHlpSTAMRegisterF(pDevIns, &pThis->StatReceiveStore,       STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling receive storing",          "/Devices/E1k%d/Receive/Store", iInstance);
     PDMDevHlpSTAMRegisterF(pDevIns, &pThis->StatRxOverflow,         STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_OCCURENCE, "Profiling RX overflows",        "/Devices/E1k%d/RxOverflow", iInstance);
-    PDMDevHlpSTAMRegisterF(pDevIns, &pThis->StatRxOverflowWakeup,   STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,     "Nr of RX overflow wakeups",          "/Devices/E1k%d/RxOverflowWakeup", iInstance);
+    PDMDevHlpSTAMRegisterF(pDevIns, &pThis->StatRxOverflowWakeupRZ, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,     "Nr of RX overflow wakeups in RZ",    "/Devices/E1k%d/RxOverflowWakeupRZ", iInstance);
+    PDMDevHlpSTAMRegisterF(pDevIns, &pThis->StatRxOverflowWakeupR3, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,     "Nr of RX overflow wakeups in R3",    "/Devices/E1k%d/RxOverflowWakeupR3", iInstance);
     PDMDevHlpSTAMRegisterF(pDevIns, &pThis->StatTransmitRZ,         STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling transmits in RZ",          "/Devices/E1k%d/Transmit/TotalRZ", iInstance);
     PDMDevHlpSTAMRegisterF(pDevIns, &pThis->StatTransmitR3,         STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling transmits in R3",          "/Devices/E1k%d/Transmit/TotalR3", iInstance);
