summaryrefslogtreecommitdiff
blob: eeeb4742e9acc6ff1d410f02069bfef99e224b54 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
Index: vbox/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp
===================================================================
--- vbox/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp	(revision 64807)
+++ vbox/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp	(revision 64808)
@@ -286,6 +286,12 @@
     PDMCRITSECT           ReplyPostQueueCritSect;
     /** Critical section protecting the reply free queue. */
     PDMCRITSECT           ReplyFreeQueueCritSect;
+    /** Critical section protecting the request queue against
+     * concurrent access from the guest. */
+    PDMCRITSECT           RequestQueueCritSect;
+    /** Critical section protecting the reply free queue against
+     * concurrent write access from the guest. */
+    PDMCRITSECT           ReplyFreeQueueWriteCritSect;
 
     /** Pointer to the start of the reply free queue - R3. */
     R3PTRTYPE(volatile uint32_t *) pReplyFreeQueueBaseR3;
@@ -1275,14 +1281,22 @@
     {
         case LSILOGIC_REG_REPLY_QUEUE:
         {
+            int rc = PDMCritSectEnter(&pThis->ReplyFreeQueueWriteCritSect, VINF_IOM_R3_MMIO_WRITE);
+            if (rc != VINF_SUCCESS)
+                return rc;
             /* Add the entry to the reply free queue. */
             ASMAtomicWriteU32(&pThis->CTX_SUFF(pReplyFreeQueueBase)[pThis->uReplyFreeQueueNextEntryFreeWrite], u32);
             pThis->uReplyFreeQueueNextEntryFreeWrite++;
             pThis->uReplyFreeQueueNextEntryFreeWrite %= pThis->cReplyQueueEntries;
+            PDMCritSectLeave(&pThis->ReplyFreeQueueWriteCritSect);
             break;
         }
         case LSILOGIC_REG_REQUEST_QUEUE:
         {
+            int rc = PDMCritSectEnter(&pThis->RequestQueueCritSect, VINF_IOM_R3_MMIO_WRITE);
+            if (rc != VINF_SUCCESS)
+                return rc;
+
             uint32_t uNextWrite = ASMAtomicReadU32(&pThis->uRequestQueueNextEntryFreeWrite);
 
             ASMAtomicWriteU32(&pThis->CTX_SUFF(pRequestQueueBase)[uNextWrite], u32);
@@ -1296,6 +1310,7 @@
             uNextWrite++;
             uNextWrite %= pThis->cRequestQueueEntries;
             ASMAtomicWriteU32(&pThis->uRequestQueueNextEntryFreeWrite, uNextWrite);
+            PDMCritSectLeave(&pThis->RequestQueueCritSect);
 
             /* Send notification to R3 if there is not one sent already. Do this
              * only if the worker thread is not sleeping or might go sleeping. */
@@ -1309,7 +1324,7 @@
                     PDMQueueInsert(pThis->CTX_SUFF(pNotificationQueue), pNotificationItem);
 #else
                     LogFlowFunc(("Signal event semaphore\n"));
-                    int rc = SUPSemEventSignal(pThis->pSupDrvSession, pThis->hEvtProcess);
+                    rc = SUPSemEventSignal(pThis->pSupDrvSession, pThis->hEvtProcess);
                     AssertRC(rc);
 #endif
                 }
@@ -5304,6 +5319,8 @@
 
     PDMR3CritSectDelete(&pThis->ReplyFreeQueueCritSect);
     PDMR3CritSectDelete(&pThis->ReplyPostQueueCritSect);
+    PDMR3CritSectDelete(&pThis->RequestQueueCritSect);
+    PDMR3CritSectDelete(&pThis->ReplyFreeQueueWriteCritSect);
 
     RTMemFree(pThis->paDeviceStates);
     pThis->paDeviceStates = NULL;
@@ -5470,6 +5487,14 @@
     if (RT_FAILURE(rc))
         return PDMDEV_SET_ERROR(pDevIns, rc, N_("LsiLogic: cannot create critical section for reply post queue"));
 
+    rc = PDMDevHlpCritSectInit(pDevIns, &pThis->RequestQueueCritSect, RT_SRC_POS, "%sRQ", szDevTag);
+    if (RT_FAILURE(rc))
+        return PDMDEV_SET_ERROR(pDevIns, rc, N_("LsiLogic: cannot create critical section for request queue"));
+
+    rc = PDMDevHlpCritSectInit(pDevIns, &pThis->ReplyFreeQueueWriteCritSect, RT_SRC_POS, "%sRFQW", szDevTag);
+    if (RT_FAILURE(rc))
+        return PDMDEV_SET_ERROR(pDevIns, rc, N_("LsiLogic: cannot create critical section for reply free queue write access"));
+
     /*
      * Register the PCI device, it's I/O regions.
      */
Index: vbox/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp
===================================================================
--- vbox/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp	(revision 64807)
+++ vbox/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp	(revision 64808)
@@ -1744,6 +1744,8 @@
     GEN_CHECK_OFF(LSILOGICSCSI, cRequestQueueEntries);
     GEN_CHECK_OFF(LSILOGICSCSI, ReplyPostQueueCritSect);
     GEN_CHECK_OFF(LSILOGICSCSI, ReplyFreeQueueCritSect);
+    GEN_CHECK_OFF(LSILOGICSCSI, RequestQueueCritSect);
+    GEN_CHECK_OFF(LSILOGICSCSI, ReplyFreeQueueWriteCritSect);
     GEN_CHECK_OFF(LSILOGICSCSI, pReplyFreeQueueBaseR3);
     GEN_CHECK_OFF(LSILOGICSCSI, pReplyPostQueueBaseR3);
     GEN_CHECK_OFF(LSILOGICSCSI, pRequestQueueBaseR3);