synchronous requests and EFI_BLOCK_IO_PROTOCOL for now.\r
\r
Copyright (C) 2012, Red Hat, Inc.\r
- Copyright (c) 2012 - 2014, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2017, AMD Inc, All rights reserved.<BR>\r
\r
This program and the accompanying materials are licensed and made available\r
under the terms and conditions of the BSD License which accompanies this\r
virtio-blk attributes the host provides.\r
\r
@return Error codes from VirtioRingInit() or\r
- VIRTIO_CFG_READ() / VIRTIO_CFG_WRITE().\r
+ VIRTIO_CFG_READ() / VIRTIO_CFG_WRITE or\r
+ VirtioRingMap().\r
\r
**/\r
\r
UINT8 AlignmentOffset;\r
UINT32 OptIoSize;\r
UINT16 QueueSize;\r
+ UINT64 RingBaseShift;\r
\r
PhysicalBlockExp = 0;\r
AlignmentOffset = 0;\r
goto Failed;\r
}\r
\r
- Status = VirtioRingInit (QueueSize, &Dev->Ring);\r
+ Status = VirtioRingInit (Dev->VirtIo, QueueSize, &Dev->Ring);\r
if (EFI_ERROR (Status)) {\r
goto Failed;\r
}\r
\r
+ //\r
+ // If anything fails from here on, we must release the ring resources\r
+ //\r
+ Status = VirtioRingMap (\r
+ Dev->VirtIo,\r
+ &Dev->Ring,\r
+ &RingBaseShift,\r
+ &Dev->RingMap\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ReleaseQueue;\r
+ }\r
+\r
//\r
// Additional steps for MMIO: align the queue appropriately, and set the\r
- // size. If anything fails from here on, we must release the ring resources.\r
+ // size. If anything fails from here on, we must unmap the ring resources.\r
//\r
Status = Dev->VirtIo->SetQueueNum (Dev->VirtIo, QueueSize);\r
if (EFI_ERROR (Status)) {\r
- goto ReleaseQueue;\r
+ goto UnmapQueue;\r
}\r
\r
Status = Dev->VirtIo->SetQueueAlign (Dev->VirtIo, EFI_PAGE_SIZE);\r
if (EFI_ERROR (Status)) {\r
- goto ReleaseQueue;\r
+ goto UnmapQueue;\r
}\r
\r
//\r
// step 4c -- Report GPFN (guest-physical frame number) of queue.\r
//\r
- Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, &Dev->Ring);\r
+ Status = Dev->VirtIo->SetQueueAddress (\r
+ Dev->VirtIo,\r
+ &Dev->Ring,\r
+ RingBaseShift\r
+ );\r
if (EFI_ERROR (Status)) {\r
- goto ReleaseQueue;\r
+ goto UnmapQueue;\r
}\r
\r
\r
Features &= ~(UINT64)VIRTIO_F_VERSION_1;\r
Status = Dev->VirtIo->SetGuestFeatures (Dev->VirtIo, Features);\r
if (EFI_ERROR (Status)) {\r
- goto ReleaseQueue;\r
+ goto UnmapQueue;\r
}\r
}\r
\r
NextDevStat |= VSTAT_DRIVER_OK;\r
Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);\r
if (EFI_ERROR (Status)) {\r
- goto ReleaseQueue;\r
+ goto UnmapQueue;\r
}\r
\r
//\r
}\r
return EFI_SUCCESS;\r
\r
+UnmapQueue:\r
+ Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->RingMap);\r
+\r
ReleaseQueue:\r
- VirtioRingUninit (&Dev->Ring);\r
+ VirtioRingUninit (Dev->VirtIo, &Dev->Ring);\r
\r
Failed:\r
//\r
//\r
Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);\r
\r
- VirtioRingUninit (&Dev->Ring);\r
+ Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->RingMap);\r
+ VirtioRingUninit (Dev->VirtIo, &Dev->Ring);\r
\r
SetMem (&Dev->BlockIo, sizeof Dev->BlockIo, 0x00);\r
SetMem (&Dev->BlockIoMedia, sizeof Dev->BlockIoMedia, 0x00);\r
//\r
Dev = Context;\r
Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);\r
+\r
+ //\r
+ // Unmap the ring buffer so that hypervisor will not be able to get\r
+ // readable data after device is reset.\r
+ //\r
+ Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->RingMap);\r
}\r
\r
/**\r
\r
After we've pronounced support for a specific device in\r
DriverBindingSupported(), we start managing said device (passed in by the\r
- Driver Exeuction Environment) with the following service.\r
+ Driver Execution Environment) with the following service.\r
\r
See DriverBindingSupported() for specification references.\r
\r
\r
@retval EFI_SUCCESS Driver instance has been created and\r
initialized for the virtio-blk device, it\r
- is now accessibla via EFI_BLOCK_IO_PROTOCOL.\r
+ is now accessible via EFI_BLOCK_IO_PROTOCOL.\r
\r
@retval EFI_OUT_OF_RESOURCES Memory allocation failed.\r
\r