Skip to content

Commit e35ba95

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 <[email protected]>
1 parent a8d0d42 commit e35ba95

File tree

5 files changed

+40
-40
lines changed

5 files changed

+40
-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: 16 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,31 @@ 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, NULL, &opEntry->OutHdr, &dummy);
91+
srbExt->sg[0].length = sizeof(opEntry->OutHdr);
92+
if (srbExt->sg[0].physAddr.QuadPart == 0)
93+
{
94+
RhelDbgPrint(TRACE_LEVEL_WARNING, " Unable to translate address 0x%p, Srb 0x%p\n", &opEntry->OutHdr, Srb);
95+
StatusTableDelete(&adaptExt->StatusTable, srbExt->id, NULL);
96+
return FALSE;
97+
}
98+
8999
srbExt->sg[srbExt->in + srbExt->out - 1].physAddr = StorPortGetPhysicalAddress(DeviceExtension,
90100
NULL,
91-
pStatus,
101+
&opEntry->Status,
92102
&dummy);
103+
srbExt->sg[srbExt->in + srbExt->out - 1].length = sizeof(opEntry->Status);
93104
if (srbExt->sg[srbExt->in + srbExt->out - 1].physAddr.QuadPart == 0)
94105
{
95-
RhelDbgPrint(TRACE_LEVEL_WARNING, " Unable to translate address 0x%p, Srb 0x%p\n", pStatus, Srb);
106+
RhelDbgPrint(TRACE_LEVEL_WARNING, " Unable to translate address 0x%p, Srb 0x%p\n", &opEntry->Status, Srb);
96107
StatusTableDelete(&adaptExt->StatusTable, srbExt->id, NULL);
97108
return FALSE;
98109
}
@@ -146,7 +157,6 @@ RhelDoFlush(PVOID DeviceExtension, PSRB_TYPE Srb, BOOLEAN resend, BOOLEAN bIsr)
146157
{
147158
PADAPTER_EXTENSION adaptExt = (PADAPTER_EXTENSION)DeviceExtension;
148159
PSRB_EXTENSION srbExt = SRB_EXTENSION(Srb);
149-
ULONG fragLen = 0UL;
150160
PVOID va = NULL;
151161
ULONGLONG pa = 0ULL;
152162

@@ -197,11 +207,6 @@ RhelDoFlush(PVOID DeviceExtension, PSRB_TYPE Srb, BOOLEAN resend, BOOLEAN bIsr)
197207
srbExt->out = 1;
198208
srbExt->in = 1;
199209

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-
205210
return _SendSRB(DeviceExtension, Srb, QueueNumber, MessageId, resend, va, pa);
206211
}
207212

@@ -332,12 +337,8 @@ RhelDoUnMap(IN PVOID DeviceExtension, IN PSRB_TYPE Srb)
332337
srbExt->out = 2;
333338
srbExt->in = 1;
334339

335-
srbExt->sg[0].physAddr = StorPortGetPhysicalAddress(DeviceExtension, NULL, &srbExt->vbr.out_hdr, &fragLen);
336-
srbExt->sg[0].length = sizeof(srbExt->vbr.out_hdr);
337340
srbExt->sg[1].physAddr = MmGetPhysicalAddress(&adaptExt->blk_discard[0]);
338341
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);
341342

342343
if (adaptExt->num_queues > 1)
343344
{
@@ -427,12 +428,8 @@ RhelGetSerialNumber(IN PVOID DeviceExtension, IN PSRB_TYPE Srb)
427428
srbExt->out = 1;
428429
srbExt->in = 2;
429430

430-
srbExt->sg[0].physAddr = StorPortGetPhysicalAddress(DeviceExtension, NULL, &srbExt->vbr.out_hdr, &fragLen);
431-
srbExt->sg[0].length = sizeof(srbExt->vbr.out_hdr);
432431
srbExt->sg[1].physAddr = StorPortGetPhysicalAddress(DeviceExtension, NULL, &adaptExt->sn[0], &fragLen);
433432
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);
436433

437434
return _SendSRB(DeviceExtension, Srb, QueueNumber, MessageId, FALSE, va, pa);
438435
}

0 commit comments

Comments
 (0)