]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg/VirtioBlkDxe: map VRING using VirtioRingMap()
authorBrijesh Singh <brijesh.singh@amd.com>
Sun, 27 Aug 2017 22:53:17 +0000 (18:53 -0400)
committerLaszlo Ersek <lersek@redhat.com>
Mon, 28 Aug 2017 09:00:14 +0000 (11:00 +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>
OvmfPkg/VirtioBlkDxe/VirtioBlk.c
OvmfPkg/VirtioBlkDxe/VirtioBlk.h

index bff15fe3add1692f828122e284abe38f0dc1eef7..663ba281ab73c7983cac3523ca72925c39790eee 100644 (file)
@@ -580,7 +580,8 @@ VirtioBlkDriverBindingSupported (
                            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
@@ -601,6 +602,7 @@ VirtioBlkInit (
   UINT8      AlignmentOffset;\r
   UINT32     OptIoSize;\r
   UINT16     QueueSize;\r
+  UINT64     RingBaseShift;\r
 \r
   PhysicalBlockExp = 0;\r
   AlignmentOffset = 0;\r
@@ -728,26 +730,43 @@ VirtioBlkInit (
     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
@@ -758,7 +777,7 @@ VirtioBlkInit (
     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
@@ -768,7 +787,7 @@ VirtioBlkInit (
   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
@@ -811,6 +830,9 @@ VirtioBlkInit (
   }\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
@@ -849,6 +871,7 @@ VirtioBlkUninit (
   //\r
   Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);\r
 \r
+  Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->RingMap);\r
   VirtioRingUninit (Dev->VirtIo, &Dev->Ring);\r
 \r
   SetMem (&Dev->BlockIo,      sizeof Dev->BlockIo,      0x00);\r
@@ -885,6 +908,12 @@ VirtioBlkExitBoot (
   //\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
index 6c402ca88ea4727b41f6d64c55673c221f11377b..9ec0b956b81884ec6a05aea57d19bbd1550fe555 100644 (file)
@@ -41,6 +41,7 @@ typedef struct {
   VRING                  Ring;                 // VirtioRingInit      2\r
   EFI_BLOCK_IO_PROTOCOL  BlockIo;              // VirtioBlkInit       1\r
   EFI_BLOCK_IO_MEDIA     BlockIoMedia;         // VirtioBlkInit       1\r
+  VOID                   *RingMap;             // VirtioRingMap       2\r
 } VBLK_DEV;\r
 \r
 #define VIRTIO_BLK_FROM_BLOCK_IO(BlockIoPointer) \\r