Skip to content

Commit 28d796f

Browse files
author
Martin Drab
committed
[viostor]: Use the Status table to hold the command header as well
When a pending request gets completed by the driver before it is handled by the host, it may happen that the host have not read the command header yet. This means a read from a physical memory no longer owned by the driver. Moving the physical memory holding the command header to the Status table as well enforces that the physical memory is always owned by the driver when the host code is reading from it. Signed-Off-By: Martin Drab <martin.drab@virtuozzo.com>
1 parent a8d0d42 commit 28d796f

File tree

5 files changed

+43
-40
lines changed

5 files changed

+43
-40
lines changed

viostor/virtio_status_table.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
* SUCH DAMAGE.
3131
*/
3232
#include <ntddk.h>
33+
#include "virtio_stor.h"
3334
#include "virtio_stor_trace.h"
3435
#include "virtio_status_table.h"
3536
#if defined(EVENT_TRACING)
@@ -65,12 +66,12 @@ void StatusTableInit(PSTATUS_TABLE Table)
6566
return;
6667
}
6768

68-
unsigned char *StatusTableInsert(PSTATUS_TABLE Table, ULONG64 Id)
69+
PSTATUS_TABLE_ENTRY StatusTableInsert(PSTATUS_TABLE Table, ULONG64 Id)
6970
{
7071
size_t index = 0;
7172
size_t attempt = 0;
7273
size_t nextIndex = 0;
73-
unsigned char *ret = NULL;
74+
PSTATUS_TABLE_ENTRY ret = NULL;
7475
PSTATUS_TABLE_ENTRY entry = NULL;
7576

7677
while (InterlockedCompareExchange(&Table->Lock, 1, 0))
@@ -88,7 +89,7 @@ unsigned char *StatusTableInsert(PSTATUS_TABLE Table, ULONG64 Id)
8889
entry->Present = 1;
8990
entry->Deleted = 0;
9091
entry->Id = Id;
91-
ret = &entry->Status;
92+
ret = entry;
9293
break;
9394
}
9495

viostor/virtio_status_table.h

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,25 +31,10 @@
3131
#define __VIRTIO_STATUS_TABLE_H__
3232

3333
#include <ntddk.h>
34-
35-
typedef struct _STATUS_TABLE_ENTRY
36-
{
37-
unsigned char Status;
38-
ULONG64 Id;
39-
int Present : 1;
40-
int Deleted : 1;
41-
} STATUS_TABLE_ENTRY, *PSTATUS_TABLE_ENTRY;
42-
43-
#define VIRTIO_STATUS_TABLE_SIZE 769
44-
45-
typedef struct _STATUS_TABLE
46-
{
47-
STATUS_TABLE_ENTRY Entries[VIRTIO_STATUS_TABLE_SIZE];
48-
volatile LONG Lock;
49-
} STATUS_TABLE, *PSTATUS_TABLE;
34+
#include "virtio_stor.h"
5035

5136
void StatusTableInit(PSTATUS_TABLE Table);
52-
unsigned char *StatusTableInsert(PSTATUS_TABLE Table, ULONG64 Id);
37+
PSTATUS_TABLE_ENTRY StatusTableInsert(PSTATUS_TABLE Table, ULONG64 Id);
5338
void StatusTableDelete(PSTATUS_TABLE Table, ULONG64 Id, unsigned char *Status);
5439

5540
#endif

viostor/virtio_stor.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
* SUCH DAMAGE.
3131
*/
3232
#include "virtio_stor.h"
33+
#include "virtio_status_table.h"
3334
#if defined(EVENT_TRACING)
3435
#include "virtio_stor.tmh"
3536
#endif

viostor/virtio_stor.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141
#include "virtio_ring.h"
4242
#include "virtio_stor_utils.h"
4343
#include "virtio_stor_hw_helper.h"
44-
#include "virtio_status_table.h"
4544

4645
typedef struct VirtIOBufferDescriptor VIO_SG, *PVIO_SG;
4746

@@ -207,6 +206,23 @@ typedef struct _REQUEST_LIST
207206
ULONG srb_cnt;
208207
} REQUEST_LIST, *PREQUEST_LIST;
209208

209+
typedef struct _STATUS_TABLE_ENTRY
210+
{
211+
blk_outhdr OutHdr;
212+
unsigned char Status;
213+
ULONG64 Id;
214+
int Present : 1;
215+
int Deleted : 1;
216+
} STATUS_TABLE_ENTRY, * PSTATUS_TABLE_ENTRY;
217+
218+
#define VIRTIO_STATUS_TABLE_SIZE 769
219+
220+
typedef struct _STATUS_TABLE
221+
{
222+
STATUS_TABLE_ENTRY Entries[VIRTIO_STATUS_TABLE_SIZE];
223+
volatile LONG Lock;
224+
} STATUS_TABLE, * PSTATUS_TABLE;
225+
210226
typedef struct _ADAPTER_EXTENSION
211227
{
212228
VirtIODevice vdev;

viostor/virtio_stor_hw_helper.c

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ static BOOLEAN _SendSRB(PVOID DeviceExtension,
6868
ULONGLONG PA)
6969
{
7070
ULONG dummy = 1;
71-
unsigned char *pStatus = NULL;
71+
PSTATUS_TABLE_ENTRY opEntry = NULL;
7272
PADAPTER_EXTENSION adaptExt = NULL;
7373
PSRB_EXTENSION srbExt = NULL;
7474
PREQUEST_LIST element;
@@ -79,20 +79,34 @@ static BOOLEAN _SendSRB(PVOID DeviceExtension,
7979

8080
adaptExt = (PADAPTER_EXTENSION)DeviceExtension;
8181
srbExt = SRB_EXTENSION(Srb);
82-
pStatus = StatusTableInsert(&adaptExt->StatusTable, srbExt->id);
83-
if (pStatus == NULL)
82+
opEntry = StatusTableInsert(&adaptExt->StatusTable, srbExt->id);
83+
if (opEntry == NULL)
8484
{
8585
RhelDbgPrint(TRACE_LEVEL_WARNING, " Unable to allocate space for holding status for Srb 0x%p\n", Srb);
8686
return FALSE;
8787
}
8888

89+
opEntry->OutHdr = srbExt->vbr.out_hdr;
90+
srbExt->sg[0].physAddr = StorPortGetPhysicalAddress(DeviceExtension,
91+
NULL,
92+
&opEntry->OutHdr,
93+
&dummy);
94+
srbExt->sg[0].length = sizeof(opEntry->OutHdr);
95+
if (srbExt->sg[0].physAddr.QuadPart == 0)
96+
{
97+
RhelDbgPrint(TRACE_LEVEL_WARNING, " Unable to translate address 0x%p, Srb 0x%p\n", &opEntry->OutHdr, Srb);
98+
StatusTableDelete(&adaptExt->StatusTable, srbExt->id, NULL);
99+
return FALSE;
100+
}
101+
89102
srbExt->sg[srbExt->in + srbExt->out - 1].physAddr = StorPortGetPhysicalAddress(DeviceExtension,
90103
NULL,
91-
pStatus,
104+
&opEntry->Status,
92105
&dummy);
106+
srbExt->sg[srbExt->in + srbExt->out - 1].length = sizeof(opEntry->Status);
93107
if (srbExt->sg[srbExt->in + srbExt->out - 1].physAddr.QuadPart == 0)
94108
{
95-
RhelDbgPrint(TRACE_LEVEL_WARNING, " Unable to translate address 0x%p, Srb 0x%p\n", pStatus, Srb);
109+
RhelDbgPrint(TRACE_LEVEL_WARNING, " Unable to translate address 0x%p, Srb 0x%p\n", &opEntry->Status, Srb);
96110
StatusTableDelete(&adaptExt->StatusTable, srbExt->id, NULL);
97111
return FALSE;
98112
}
@@ -146,7 +160,6 @@ RhelDoFlush(PVOID DeviceExtension, PSRB_TYPE Srb, BOOLEAN resend, BOOLEAN bIsr)
146160
{
147161
PADAPTER_EXTENSION adaptExt = (PADAPTER_EXTENSION)DeviceExtension;
148162
PSRB_EXTENSION srbExt = SRB_EXTENSION(Srb);
149-
ULONG fragLen = 0UL;
150163
PVOID va = NULL;
151164
ULONGLONG pa = 0ULL;
152165

@@ -197,11 +210,6 @@ RhelDoFlush(PVOID DeviceExtension, PSRB_TYPE Srb, BOOLEAN resend, BOOLEAN bIsr)
197210
srbExt->out = 1;
198211
srbExt->in = 1;
199212

200-
srbExt->sg[0].physAddr = StorPortGetPhysicalAddress(DeviceExtension, NULL, &srbExt->vbr.out_hdr, &fragLen);
201-
srbExt->sg[0].length = sizeof(srbExt->vbr.out_hdr);
202-
srbExt->sg[1].physAddr = StorPortGetPhysicalAddress(DeviceExtension, NULL, &srbExt->vbr.status, &fragLen);
203-
srbExt->sg[1].length = sizeof(srbExt->vbr.status);
204-
205213
return _SendSRB(DeviceExtension, Srb, QueueNumber, MessageId, resend, va, pa);
206214
}
207215

@@ -332,12 +340,8 @@ RhelDoUnMap(IN PVOID DeviceExtension, IN PSRB_TYPE Srb)
332340
srbExt->out = 2;
333341
srbExt->in = 1;
334342

335-
srbExt->sg[0].physAddr = StorPortGetPhysicalAddress(DeviceExtension, NULL, &srbExt->vbr.out_hdr, &fragLen);
336-
srbExt->sg[0].length = sizeof(srbExt->vbr.out_hdr);
337343
srbExt->sg[1].physAddr = MmGetPhysicalAddress(&adaptExt->blk_discard[0]);
338344
srbExt->sg[1].length = sizeof(blk_discard_write_zeroes) * BlockDescrCount;
339-
srbExt->sg[2].physAddr = StorPortGetPhysicalAddress(DeviceExtension, NULL, &srbExt->vbr.status, &fragLen);
340-
srbExt->sg[2].length = sizeof(srbExt->vbr.status);
341345

342346
if (adaptExt->num_queues > 1)
343347
{
@@ -427,12 +431,8 @@ RhelGetSerialNumber(IN PVOID DeviceExtension, IN PSRB_TYPE Srb)
427431
srbExt->out = 1;
428432
srbExt->in = 2;
429433

430-
srbExt->sg[0].physAddr = StorPortGetPhysicalAddress(DeviceExtension, NULL, &srbExt->vbr.out_hdr, &fragLen);
431-
srbExt->sg[0].length = sizeof(srbExt->vbr.out_hdr);
432434
srbExt->sg[1].physAddr = StorPortGetPhysicalAddress(DeviceExtension, NULL, &adaptExt->sn[0], &fragLen);
433435
srbExt->sg[1].length = sizeof(adaptExt->sn);
434-
srbExt->sg[2].physAddr = StorPortGetPhysicalAddress(DeviceExtension, NULL, &srbExt->vbr.status, &fragLen);
435-
srbExt->sg[2].length = sizeof(srbExt->vbr.status);
436436

437437
return _SendSRB(DeviceExtension, Srb, QueueNumber, MessageId, FALSE, va, pa);
438438
}

0 commit comments

Comments
 (0)