Index: trunk/src/VBox/Devices/Storage/DevVirtioSCSI.cpp
===================================================================
--- trunk/src/VBox/Devices/Storage/DevVirtioSCSI.cpp	(revision 98562)
+++ trunk/src/VBox/Devices/Storage/DevVirtioSCSI.cpp	(revision 98661)
@@ -368,5 +368,6 @@
 {
     R3PTRTYPE(PPDMTHREAD)           pThread;                    /**< pointer to worker thread's handle                 */
-    uint16_t                        auRedoDescs[VIRTQ_SIZE];/**< List of previously suspended reqs to re-submit    */
+    RTCRITSECT                      CritSectVirtq;              /**< Protecting the virtq against concurrent thread access. */
+    uint16_t                        auRedoDescs[VIRTQ_SIZE];    /**< List of previously suspended reqs to re-submit    */
     uint16_t                        cRedoDescs;                 /**< Number of redo desc chain head desc idxes in list */
 } VIRTIOSCSIWORKERR3;
@@ -715,4 +716,29 @@
 
 #endif /* LOG_ENABLED */
+
+
+/**
+ * Wrapper around virtioCoreR3VirtqUsedBufPut() and virtioCoreVirtqUsedRingSync() doing some device locking.
+ *
+ * @returns nothing.
+ * @param   pDevIns         The PDM device instance.
+ * @param   pVirtio         Pointer to the shared virtio core structure.
+ * @param   uVirtqNbr       The virtq number.
+ * @param   pSgVirtReturn   The S/G buffer to return data from.
+ * @param   pVirtqBuf       The virtq buffer.
+ *
+ * @note This is a temporary fix, see @bugref{9440#c164} on why it is necessary. Should be moved to VirtioCore or
+ *       VirtioCore should be changed to not require locking.
+ */
+DECLINLINE(void) virtioScsiR3VirtqUsedBufPutAndSync(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t uVirtqNbr, PRTSGBUF pSgVirtReturn,
+                                                    PVIRTQBUF pVirtqBuf)
+{
+    PVIRTIOSCSICC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIOSCSICC);
+
+    RTCritSectEnter(&pThisCC->aWorkers[uVirtqNbr].CritSectVirtq);
+    virtioCoreR3VirtqUsedBufPut(pThisCC->pDevIns, pVirtio, uVirtqNbr, pSgVirtReturn, pVirtqBuf, true /* fFence */);
+    virtioCoreVirtqUsedRingSync(pThisCC->pDevIns, pVirtio, uVirtqNbr);
+    RTCritSectLeave(&pThisCC->aWorkers[uVirtqNbr].CritSectVirtq);
+}
 
 
@@ -793,9 +819,5 @@
     RTSgBufInit(&ReqSgBuf, aReqSegs, RT_ELEMENTS(aReqSegs));
 
-    rc = virtioCoreR3VirtqUsedBufPut(pDevIns, &pThis->Virtio, EVENTQ_IDX, &ReqSgBuf, pVirtqBuf, true /*fFence*/);
-    if (rc == VINF_SUCCESS)
-        virtioCoreVirtqUsedRingSync(pDevIns, &pThis->Virtio, EVENTQ_IDX, false);
-    else
-        LogRel(("Error writing control message to guest\n"));
+    virtioScsiR3VirtqUsedBufPutAndSync(pDevIns, &pThis->Virtio, EVENTQ_IDX, &ReqSgBuf, pVirtqBuf);
     virtioCoreR3VirtqBufRelease(&pThis->Virtio, pVirtqBuf);
 
@@ -889,7 +911,5 @@
         pRespHdr->uResponse = VIRTIOSCSI_S_RESET;
 
-    virtioCoreR3VirtqUsedBufPut(pDevIns, &pThis->Virtio, uVirtqNbr, &ReqSgBuf, pVirtqBuf, true /* fFence */);
-    virtioCoreVirtqUsedRingSync(pDevIns, &pThis->Virtio, uVirtqNbr);
-
+    virtioScsiR3VirtqUsedBufPutAndSync(pDevIns, &pThis->Virtio, uVirtqNbr, &ReqSgBuf, pVirtqBuf);
     Log2(("---------------------------------------------------------------------------------\n"));
 
@@ -1074,7 +1094,5 @@
                         VERR_BUFFER_OVERFLOW);
 
-        virtioCoreR3VirtqUsedBufPut(pDevIns, &pThis->Virtio, pReq->uVirtqNbr, &ReqSgBuf, pReq->pVirtqBuf, true /* fFence TBD */);
-        virtioCoreVirtqUsedRingSync(pDevIns, &pThis->Virtio, pReq->uVirtqNbr);
-
+        virtioScsiR3VirtqUsedBufPutAndSync(pDevIns, &pThis->Virtio, pReq->uVirtqNbr, &ReqSgBuf, pReq->pVirtqBuf);
         Log2(("-----------------------------------------------------------------------------------------\n"));
     }
@@ -1560,7 +1578,5 @@
     RTSgBufInit(&ReqSgBuf, aReqSegs, cSegs);
 
-    virtioCoreR3VirtqUsedBufPut(pDevIns, &pThis->Virtio, uVirtqNbr, &ReqSgBuf, pVirtqBuf, true /*fFence*/);
-    virtioCoreVirtqUsedRingSync(pDevIns, &pThis->Virtio, uVirtqNbr);
-
+    virtioScsiR3VirtqUsedBufPutAndSync(pDevIns, &pThis->Virtio, uVirtqNbr, &ReqSgBuf, pVirtqBuf);
     return VINF_SUCCESS;
 }
@@ -2460,4 +2476,7 @@
            pThisCC->aWorkers[uVirtqNbr].pThread = NULL;
         }
+
+        if (RTCritSectIsInitialized(&pThisCC->aWorkers[uVirtqNbr].CritSectVirtq))
+            RTCritSectDelete(&pThisCC->aWorkers[uVirtqNbr].CritSectVirtq);
     }
 
@@ -2574,4 +2593,8 @@
         }
         pThis->afVirtqAttached[uVirtqNbr] = true;
+        rc = RTCritSectInit(&pThisCC->aWorkers[uVirtqNbr].CritSectVirtq);
+        if (RT_FAILURE(rc))
+            return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,
+                                       N_("DevVirtioSCSI: Failed to create worker critical section"));
     }
 
