]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/VirtioScsiDxe/VirtioScsi.c
OvmfPkg/VirtioScsiDxe: map VRING using VirtioRingMap()
[mirror_edk2.git] / OvmfPkg / VirtioScsiDxe / VirtioScsi.c
index a983b3df7b9caf2d1490af8ec6b0dee7cfc45129..5e72b1a24b591958a2bf5ea12ba48d04e0f5a91c 100644 (file)
@@ -707,7 +707,7 @@ VirtioScsiInit (
 {\r
   UINT8      NextDevStat;\r
   EFI_STATUS Status;\r
-\r
+  UINT64     RingBaseShift;\r
   UINT64     Features;\r
   UINT16     MaxChannel; // for validation only\r
   UINT32     NumQueues;  // for validation only\r
@@ -838,26 +838,43 @@ VirtioScsiInit (
     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, 0);\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
@@ -867,7 +884,7 @@ VirtioScsiInit (
     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
@@ -877,11 +894,11 @@ VirtioScsiInit (
   //\r
   Status = VIRTIO_CFG_WRITE (Dev, CdbSize, VIRTIO_SCSI_CDB_SIZE);\r
   if (EFI_ERROR (Status)) {\r
-    goto ReleaseQueue;\r
+    goto UnmapQueue;\r
   }\r
   Status = VIRTIO_CFG_WRITE (Dev, SenseSize, VIRTIO_SCSI_SENSE_SIZE);\r
   if (EFI_ERROR (Status)) {\r
-    goto ReleaseQueue;\r
+    goto UnmapQueue;\r
   }\r
 \r
   //\r
@@ -890,7 +907,7 @@ VirtioScsiInit (
   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
@@ -926,6 +943,9 @@ VirtioScsiInit (
 \r
   return EFI_SUCCESS;\r
 \r
+UnmapQueue:\r
+  Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->RingMap);\r
+\r
 ReleaseQueue:\r
   VirtioRingUninit (Dev->VirtIo, &Dev->Ring);\r
 \r
@@ -965,6 +985,7 @@ VirtioScsiUninit (
   Dev->MaxLun         = 0;\r
   Dev->MaxSectors     = 0;\r
 \r
+  Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->RingMap);\r
   VirtioRingUninit (Dev->VirtIo, &Dev->Ring);\r
 \r
   SetMem (&Dev->PassThru,     sizeof Dev->PassThru,     0x00);\r
@@ -995,6 +1016,12 @@ VirtioScsiExitBoot (
   //\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 reset.\r
+  //\r
+  Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->RingMap);\r
 }\r
 \r
 \r