Index: /trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp
===================================================================
--- /trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp	(revision 30974)
+++ /trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp	(revision 30975)
@@ -957,7 +957,17 @@
         case LSILOGIC_REG_REQUEST_QUEUE:
         {
-            ASMAtomicWriteU32(&pThis->CTX_SUFF(pRequestQueueBase)[pThis->uRequestQueueNextEntryFreeWrite], u32);
-            pThis->uRequestQueueNextEntryFreeWrite++;
-            pThis->uRequestQueueNextEntryFreeWrite %= pThis->cRequestQueueEntries;
+            uint32_t uNextWrite = ASMAtomicReadU32(&pThis->uRequestQueueNextEntryFreeWrite);
+
+            ASMAtomicWriteU32(&pThis->CTX_SUFF(pRequestQueueBase)[uNextWrite], u32);
+
+            /*
+             * Don't update the value in place. It can happen that we get preempted
+             * after the increment but before the modulo.
+             * Another EMT will read the wrong value when processing the queues
+             * and hang in an endless loop creating thousands of requests.
+             */
+            uNextWrite++;
+            uNextWrite %= pThis->cRequestQueueEntries;
+            ASMAtomicWriteU32(&pThis->uRequestQueueNextEntryFreeWrite, uNextWrite);
 
             /* Send notification to R3 if there is not one send already. */
@@ -3422,9 +3432,9 @@
     LogFlowFunc(("pDevIns=%#p pItem=%#p\n", pDevIns, pItem));
 
+    /* Reset notification event. */
+    ASMAtomicXchgBool(&pLsiLogic->fNotificationSend, false);
+
     /* Only process request which arrived before we received the notification. */
     uint32_t uRequestQueueNextEntryWrite = ASMAtomicReadU32(&pLsiLogic->uRequestQueueNextEntryFreeWrite);
-
-    /* Reset notification event. */
-    ASMAtomicXchgBool(&pLsiLogic->fNotificationSend, false);
 
     /* Go through the messages now and process them. */
