]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg/VirtioScsiDxe: map VRING using VirtioRingMap()
authorBrijesh Singh <brijesh.singh@amd.com>
Thu, 31 Aug 2017 14:25:26 +0000 (10:25 -0400)
committerLaszlo Ersek <lersek@redhat.com>
Thu, 31 Aug 2017 18:57:04 +0000 (20:57 +0200)
When device is behind the IOMMU then driver need to pass the device
address when programing the bus master. The patch uses VirtioRingMap() to
map the VRING system physical address to device address.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Laszlo Ersek <lersek@redhat.com>
OvmfPkg/VirtioScsiDxe/VirtioScsi.c
OvmfPkg/VirtioScsiDxe/VirtioScsi.h

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
index 6d00567e8cb8304cfc6dc868195a791f34064b5a..05a6bf5672631a4cf858373b578a10e1d22d6943 100644 (file)
@@ -60,6 +60,7 @@ typedef struct {
   VRING                           Ring;           // VirtioRingInit      2\r
   EFI_EXT_SCSI_PASS_THRU_PROTOCOL PassThru;       // VirtioScsiInit      1\r
   EFI_EXT_SCSI_PASS_THRU_MODE     PassThruMode;   // VirtioScsiInit      1\r
+  VOID                            *RingMap;       // VirtioRingMap       2\r
 } VSCSI_DEV;\r
 \r
 #define VIRTIO_SCSI_FROM_PASS_THRU(PassThruPointer) \\r