Coverage Report

Created: 2024-10-17 06:29

/src/hbfa-fl/HBFA/UefiHostFuzzTestCasePkg/TestStub/VirtioPciDeviceStubLib/VirtioPciDeviceStubLib.c
Line
Count
Source (jump to first uncovered line)
1
/** @file
2
3
Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
4
SPDX-License-Identifier: BSD-2-Clause-Patent
5
6
**/
7
#include <Uefi.h>
8
#include <stdio.h>
9
#include <stdlib.h>
10
#include <unistd.h>
11
#include <Library/BaseLib.h>
12
#include <Library/DebugLib.h>
13
#include <Library/BaseMemoryLib.h>
14
#include <Library/MemoryAllocationLib.h>
15
#include <Protocol/BlockIo.h>
16
#include <Protocol/VirtioDevice.h>
17
#include <Protocol/PciIo.h>
18
#include <Protocol/PciRootBridgeIo.h>
19
#include <Library/VirtioPciDeviceStubLib.h>
20
#include <IndustryStandard/Virtio095.h>
21
22
PCI_CFG_SPACE *PciCfg;
23
24
VOID
25
EFIAPI
26
0
PrintByByte(UINT8* Content, UINT32 Len) {
27
0
  UINT32 i;
28
0
  for (i = 0; i < Len; i++) {
29
0
    if (i % 16 == 0) printf ("\n");
30
0
    printf ("%02x ", Content[i]);
31
0
  }
32
0
  printf ("\n");
33
0
}
34
35
EFI_STATUS
36
EFIAPI
37
VirtioPciIoRead (
38
  IN  VIRTIO_PCI_DEVICE         *Dev,
39
  IN  UINTN                      FieldOffset,
40
  IN  UINTN                      FieldSize,
41
  IN  UINTN                      BufferSize,
42
  OUT VOID                       *Buffer
43
  );
44
45
EFI_STATUS
46
EFIAPI
47
VirtioPciIoWrite (
48
  IN  VIRTIO_PCI_DEVICE         *Dev,
49
  IN UINTN                       FieldOffset,
50
  IN UINTN                       FieldSize,
51
  IN UINT64                      Value
52
  );
53
54
/********************************************
55
 * PCI Functions for VIRTIO_DEVICE_PROTOCOL
56
 *******************************************/
57
EFI_STATUS
58
EFIAPI
59
VirtioPciDeviceRead (
60
  IN  VIRTIO_DEVICE_PROTOCOL     *This,
61
  IN  UINTN                      FieldOffset,
62
  IN  UINTN                      FieldSize,
63
  IN  UINTN                      BufferSize,
64
  OUT VOID                       *Buffer
65
  );
66
67
EFI_STATUS
68
EFIAPI
69
VirtioPciDeviceWrite (
70
  IN VIRTIO_DEVICE_PROTOCOL      *This,
71
  IN UINTN                       FieldOffset,
72
  IN UINTN                       FieldSize,
73
  IN UINT64                      Value
74
  );
75
76
EFI_STATUS
77
EFIAPI
78
VirtioPciGetDeviceFeatures (
79
  IN VIRTIO_DEVICE_PROTOCOL *This,
80
  OUT UINT64                *DeviceFeatures
81
  );
82
83
EFI_STATUS
84
EFIAPI
85
VirtioPciGetQueueSize (
86
  IN  VIRTIO_DEVICE_PROTOCOL  *This,
87
  OUT UINT16                  *QueueNumMax
88
  );
89
90
EFI_STATUS
91
EFIAPI
92
VirtioPciSetQueueAlignment (
93
  IN  VIRTIO_DEVICE_PROTOCOL         *This,
94
  IN  UINT32                         Alignment
95
  );
96
97
EFI_STATUS
98
EFIAPI
99
VirtioPciSetPageSize (
100
  IN  VIRTIO_DEVICE_PROTOCOL         *This,
101
  IN  UINT32                         PageSize
102
  );
103
104
EFI_STATUS
105
EFIAPI
106
VirtioPciGetDeviceStatus (
107
  IN  VIRTIO_DEVICE_PROTOCOL  *This,
108
  OUT UINT8                   *DeviceStatus
109
  );
110
111
EFI_STATUS
112
EFIAPI
113
VirtioPciSetGuestFeatures (
114
  IN VIRTIO_DEVICE_PROTOCOL  *This,
115
  IN UINT64                   Features
116
  );
117
118
EFI_STATUS
119
EFIAPI
120
VirtioPciSetQueueAddress (
121
  IN VIRTIO_DEVICE_PROTOCOL  *This,
122
  IN VRING                   *Ring,
123
  IN UINT64                  RingBaseShift
124
  );
125
126
EFI_STATUS
127
EFIAPI
128
VirtioPciSetQueueSel (
129
  IN  VIRTIO_DEVICE_PROTOCOL         *This,
130
  IN  UINT16                         Sel
131
  );
132
133
EFI_STATUS
134
EFIAPI
135
VirtioPciSetQueueNotify (
136
  IN  VIRTIO_DEVICE_PROTOCOL         *This,
137
  IN  UINT16                         Index
138
  );
139
140
EFI_STATUS
141
EFIAPI
142
VirtioPciSetQueueSize (
143
  IN  VIRTIO_DEVICE_PROTOCOL         *This,
144
  IN  UINT16                         Size
145
  );
146
147
EFI_STATUS
148
EFIAPI
149
VirtioPciSetDeviceStatus (
150
  IN  VIRTIO_DEVICE_PROTOCOL         *This,
151
  IN  UINT8                          DeviceStatus
152
  );
153
154
EFI_STATUS
155
EFIAPI
156
VirtioPciAllocateSharedPages (
157
  IN  VIRTIO_DEVICE_PROTOCOL        *This,
158
  IN  UINTN                         NumPages,
159
  OUT VOID                          **HostAddress
160
  );
161
162
VOID
163
EFIAPI
164
VirtioPciFreeSharedPages (
165
  IN  VIRTIO_DEVICE_PROTOCOL        *This,
166
  IN  UINTN                         NumPages,
167
  IN  VOID                          *HostAddress
168
  );
169
170
EFI_STATUS
171
EFIAPI
172
VirtioPciMapSharedBuffer (
173
  IN      VIRTIO_DEVICE_PROTOCOL        *This,
174
  IN      VIRTIO_MAP_OPERATION          Operation,
175
  IN      VOID                          *HostAddress,
176
  IN OUT  UINTN                         *NumberOfBytes,
177
  OUT     EFI_PHYSICAL_ADDRESS          *DeviceAddress,
178
  OUT     VOID                          **Mapping
179
  );
180
181
EFI_STATUS
182
EFIAPI
183
VirtioPciUnmapSharedBuffer (
184
  IN  VIRTIO_DEVICE_PROTOCOL        *This,
185
  IN  VOID                          *Mapping
186
  );
187
188
EFI_STATUS
189
EFIAPI
190
PciIoRead (
191
  IN EFI_PCI_IO_PROTOCOL       *PciIo,
192
  IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
193
  IN UINT8                     BAR_IDX,
194
  IN UINT64                    Offset,
195
  IN UINTN                     Count,
196
  IN OUT VOID                  *Buffer
197
20.3k
) {
198
20.3k
  UINT16 Len = 0;
199
200
20.3k
  switch (Width)
201
20.3k
  {
202
7.37k
  case EfiPciIoWidthUint32:
203
7.37k
    Len = Count * sizeof(UINT32);
204
7.37k
    break;
205
11.1k
  case EfiPciIoWidthUint16:
206
11.1k
    Len = Count * sizeof(UINT16);
207
11.1k
    break;
208
1.84k
  case EfiPciIoWidthUint8:
209
1.84k
    Len = Count * sizeof(UINT8);
210
1.84k
    break;
211
0
  default:
212
0
    break;
213
20.3k
  }
214
20.3k
  CopyMem (Buffer, (void *) ((UINT64) (PciCfg->PciBasicCfg.Device.Bar[1]) << 32 | PciCfg->PciBasicCfg.Device.Bar[0] + Offset), Len);
215
20.3k
  return EFI_SUCCESS;
216
20.3k
}
217
218
EFI_STATUS
219
EFIAPI
220
PciIoWrite (
221
  IN EFI_PCI_IO_PROTOCOL       *PciIo,
222
  IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
223
  IN UINT8                     BAR_IDX,
224
  IN UINT64                    Offset,
225
  IN UINTN                     Count,
226
  IN OUT VOID                  *Buffer
227
830
) {
228
830
  UINT16 Len = 0;
229
230
830
  switch (Width)
231
830
  {
232
136
  case EfiPciIoWidthUint32:
233
136
    Len = Count * sizeof(UINT32);
234
136
    break;
235
74
  case EfiPciIoWidthUint16:
236
74
    Len = Count * sizeof(UINT16);
237
74
    break;
238
620
  case EfiPciIoWidthUint8:
239
620
    Len = Count * sizeof(UINT8);
240
620
    break;
241
0
  default:
242
0
    break;
243
830
  }
244
830
  CopyMem ((void *) ((UINT64) (PciCfg->PciBasicCfg.Device.Bar[1]) << 32 | PciCfg->PciBasicCfg.Device.Bar[0] + Offset), Buffer, Len);
245
830
  return EFI_SUCCESS;
246
830
}
247
248
STATIC VIRTIO_DEVICE_PROTOCOL mDeviceProtocolTemplate = {
249
  0,                                    // Revision
250
  0,                                    // SubSystemDeviceId
251
  VirtioPciGetDeviceFeatures,           // GetDeviceFeatures
252
  VirtioPciSetGuestFeatures,            // SetGuestFeatures
253
  VirtioPciSetQueueAddress,             // SetQueueAddress
254
  VirtioPciSetQueueSel,                 // SetQueueSel
255
  VirtioPciSetQueueNotify,              // SetQueueNotify
256
  VirtioPciSetQueueAlignment,           // SetQueueAlignment
257
  VirtioPciSetPageSize,                 // SetPageSize
258
  VirtioPciGetQueueSize,                // GetQueueNumMax
259
  VirtioPciSetQueueSize,                // SetQueueNum
260
  VirtioPciGetDeviceStatus,             // GetDeviceStatus
261
  VirtioPciSetDeviceStatus,             // SetDeviceStatus
262
  VirtioPciDeviceWrite,                 // WriteDevice
263
  VirtioPciDeviceRead,                  // ReadDevice
264
  VirtioPciAllocateSharedPages,         // AllocateSharedPages
265
  VirtioPciFreeSharedPages,             // FreeSharedPages
266
  VirtioPciMapSharedBuffer,             // MapSharedBuffer
267
  VirtioPciUnmapSharedBuffer,           // UnmapSharedBuffer
268
};
269
270
EFI_STATUS
271
EFIAPI
272
InitVirtioPciDev (
273
  IN      EFI_PCI_IO_PROTOCOL     *PciIo,
274
  IN      VOID                    *ConfigRegion,
275
  IN OUT  VIRTIO_PCI_DEVICE       *Device
276
0
) {
277
  // VOID                          *ConfigRegion;
278
279
  // ConfigRegion = (VOID *) AllocatePool(sizeof (PCI_CFG_SPACE) + sizeof(VIRTIO_HDR) + sizeof (VIRTIO_BLK_CONFIG));
280
0
  if (ConfigRegion == NULL) {
281
0
    return EFI_OUT_OF_RESOURCES;
282
0
  }
283
  
284
0
  Device->Signature = VIRTIO_PCI_DEVICE_SIGNATURE;
285
  //
286
  // Copy protocol template
287
  //
288
0
  CopyMem (&Device->VirtioDevice, &mDeviceProtocolTemplate, sizeof (VIRTIO_DEVICE_PROTOCOL));
289
290
0
  PciCfg = (PCI_CFG_SPACE *) ConfigRegion;
291
 
292
  //This test expects this binary file to exist in the current execution folder
293
0
  FILE *f = fopen("VirtioBlkFuzzSeed0.9.5.bin", "rb");
294
0
  if (f==NULL) {
295
0
    fputs ("File error",stderr);
296
0
    goto FreeDevice;
297
0
  }
298
299
0
  fseek(f, 0, SEEK_END);
300
301
0
  long int fsize = ftell(f);
302
0
  rewind(f);
303
0
  if (fsize<0) {
304
0
    fputs ("Error on reading file size",stderr);
305
0
    fclose(f);
306
0
    goto FreeDevice;
307
0
  }
308
309
0
  size_t bytes_read = fread((void *)ConfigRegion, 1, (size_t)fsize, f);
310
0
  fclose(f);
311
0
  if ((UINTN)bytes_read!=fsize) {
312
0
    fputs ("File error",stderr);
313
0
    goto FreeDevice;
314
0
  }
315
316
0
  PciCfg->PciBasicCfg.Device.Bar[0] = (UINT32) ((UINT64)PciCfg + sizeof(PCI_CFG_SPACE));
317
0
  PciCfg->PciBasicCfg.Device.Bar[1] = (UINT32) (((UINT64)PciCfg + sizeof(PCI_CFG_SPACE)) >> 32);
318
319
0
  Device->VirtioDevice.SubSystemDeviceId = PciCfg->PciBasicCfg.Device.SubsystemID;
320
321
0
  PciIo->Io.Read = &PciIoRead;
322
0
  PciIo->Io.Write = &PciIoWrite;
323
0
  Device->PciIo = PciIo;
324
325
  //
326
  // Note: We don't support the MSI-X capability.  If we did,
327
  //       the offset would become 24 after enabling MSI-X.
328
  //
329
0
  Device->DeviceSpecificConfigurationOffset = VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_PCI;
330
331
0
  return EFI_SUCCESS;
332
333
0
FreeDevice:
334
  // FreePool (ConfigRegion);
335
336
0
  return EFI_OUT_OF_RESOURCES;
337
0
}
338
339
EFI_STATUS
340
EFIAPI
341
ParseBufferAndInitVirtioPciDev (
342
  IN      UINT8                   *TestBuffer,
343
  IN      UINTN                   BufferSize,
344
  IN      EFI_PCI_IO_PROTOCOL     *PciIo,
345
  IN      VOID                    *ConfigRegion,
346
  IN OUT  VIRTIO_PCI_DEVICE       *Device
347
)
348
295
{
349
295
  VIRTIO_HDR                    *VirtioHdr;
350
351
352
  // ConfigRegion = (VOID *) AllocatePool(sizeof (PCI_CFG_SPACE) + sizeof(VIRTIO_HDR) + sizeof (VIRTIO_BLK_CONFIG));
353
295
  if (ConfigRegion == NULL) {
354
0
    return EFI_OUT_OF_RESOURCES;
355
0
  }
356
357
295
  if (BufferSize != sizeof (PCI_CFG_SPACE) + sizeof(VIRTIO_HDR) + sizeof (VIRTIO_BLK_CONFIG)) {
358
65
    goto FreeDevice;
359
65
  }
360
361
230
  Device->Signature = VIRTIO_PCI_DEVICE_SIGNATURE;
362
363
230
  PciCfg = (PCI_CFG_SPACE *) ConfigRegion;
364
365
  //
366
  // Copy protocol template
367
  //
368
230
  CopyMem (&Device->VirtioDevice, &mDeviceProtocolTemplate, sizeof (VIRTIO_DEVICE_PROTOCOL));
369
370
230
  CopyMem ((void *)PciCfg, (void *) TestBuffer, sizeof (PCI_CFG_SPACE) + sizeof(VIRTIO_HDR) + sizeof (VIRTIO_BLK_CONFIG));
371
372
230
  Device->VirtioDevice.Revision = VIRTIO_SPEC_REVISION (0, 9, 5);
373
230
  Device->VirtioDevice.SubSystemDeviceId = PciCfg->PciBasicCfg.Device.SubsystemID;
374
375
  //
376
  // virtio-0.9.5, 2.1 PCI Discovery
377
  //
378
230
  if (!((PciCfg->PciBasicCfg.Hdr.VendorId == VIRTIO_VENDOR_ID) &&
379
230
      (PciCfg->PciBasicCfg.Hdr.DeviceId >= 0x1000) &&
380
230
      (PciCfg->PciBasicCfg.Hdr.DeviceId <= 0x103F) &&
381
230
      (PciCfg->PciBasicCfg.Hdr.RevisionID == 0x00))) {
382
59
      goto FreeDevice;
383
59
  }
384
385
171
  PciCfg->PciBasicCfg.Device.Bar[0] = (UINT32) ((UINT64)PciCfg + sizeof(PCI_CFG_SPACE));
386
171
  PciCfg->PciBasicCfg.Device.Bar[1] = (UINT32) (((UINT64)PciCfg + sizeof(PCI_CFG_SPACE)) >> 32);
387
388
171
  Device->VirtioDevice.SubSystemDeviceId = PciCfg->PciBasicCfg.Device.SubsystemID;
389
390
171
  PciIo->Io.Read = &PciIoRead;
391
171
  PciIo->Io.Write = &PciIoWrite;
392
171
  Device->PciIo = PciIo;
393
394
  //
395
  // Note: We don't support the MSI-X capability.  If we did,
396
  //       the offset would become 24 after enabling MSI-X.
397
  //
398
171
  Device->DeviceSpecificConfigurationOffset = VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_PCI;
399
400
171
  return EFI_SUCCESS;
401
402
124
FreeDevice:
403
124
  return EFI_OUT_OF_RESOURCES;
404
230
}