EFI_PHYSICAL_ADDRESS HostStatusDeviceAddress;\r
EFI_PHYSICAL_ADDRESS RequestDeviceAddress;\r
EFI_STATUS Status;\r
+ EFI_STATUS UnmapStatus;\r
\r
BlockSize = Dev->BlockIoMedia.BlockSize;\r
\r
\r
UnmapDataBuffer:\r
if (BufferSize > 0) {\r
- Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, BufferMapping);\r
+ UnmapStatus = Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, BufferMapping);\r
+ if (EFI_ERROR (UnmapStatus) && !RequestIsWrite && !EFI_ERROR (Status)) {\r
+ //\r
+ // Data from the bus master may not reach the caller; fail the request.\r
+ //\r
+ Status = EFI_DEVICE_ERROR;\r
+ }\r
}\r
\r
UnmapRequestBuffer:\r
}\r
\r
Features &= VIRTIO_BLK_F_BLK_SIZE | VIRTIO_BLK_F_TOPOLOGY | VIRTIO_BLK_F_RO |\r
- VIRTIO_BLK_F_FLUSH | VIRTIO_F_VERSION_1;\r
+ VIRTIO_BLK_F_FLUSH | VIRTIO_F_VERSION_1 |\r
+ VIRTIO_F_IOMMU_PLATFORM;\r
\r
//\r
// In virtio-1.0, feature negotiation is expected to complete before queue\r
// step 5 -- Report understood features.\r
//\r
if (Dev->VirtIo->Revision < VIRTIO_SPEC_REVISION (1, 0, 0)) {\r
- Features &= ~(UINT64)VIRTIO_F_VERSION_1;\r
+ Features &= ~(UINT64)(VIRTIO_F_VERSION_1 | VIRTIO_F_IOMMU_PLATFORM);\r
Status = Dev->VirtIo->SetGuestFeatures (Dev->VirtIo, Features);\r
if (EFI_ERROR (Status)) {\r
goto UnmapQueue;\r
{\r
VBLK_DEV *Dev;\r
\r
+ DEBUG ((DEBUG_VERBOSE, "%a: Context=0x%p\n", __FUNCTION__, Context));\r
//\r
// Reset the device. This causes the hypervisor to forget about the virtio\r
// ring.\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