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);
|