OvmfPkg/Virtio: take RingBaseShift in SetQueueAddress()
authorBrijesh Singh <brijesh.singh@amd.com>
Wed, 23 Aug 2017 10:57:17 +0000 (06:57 -0400)
committerLaszlo Ersek <lersek@redhat.com>
Fri, 25 Aug 2017 08:42:19 +0000 (10:42 +0200)
For the case when an IOMMU is used for translating system physical
addresses to DMA bus master addresses, the transport-independent
virtio device drivers will be required to map their VRING areas to
bus addresses with VIRTIO_DEVICE_PROTOCOL.MapSharedBuffer() calls.

- MMIO and legacy virtio transport do not support IOMMU to translate the
  addresses hence RingBaseShift will always be set to zero.

- modern virtio transport supports IOMMU to translate the address, in
  next patch we will update the Virtio10Dxe to use RingBaseShift offset.

Suggested-by: Laszlo Ersek <lersek@redhat.com>
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>
[lersek@redhat.com: remove commit msg paragraph with VirtioLib reference]
[lersek@redhat.com: fix typo in VIRTIO_SET_QUEUE_ADDRESS comment block]
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
OvmfPkg/Include/Protocol/VirtioDevice.h
OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.h
OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c
OvmfPkg/Virtio10Dxe/Virtio10.c
OvmfPkg/VirtioBlkDxe/VirtioBlk.c
OvmfPkg/VirtioGpuDxe/Commands.c
OvmfPkg/VirtioNetDxe/SnpInitialize.c
OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.h
OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c
OvmfPkg/VirtioRngDxe/VirtioRng.c
OvmfPkg/VirtioScsiDxe/VirtioScsi.c

index 9a01932958a2901bc0e45e068dcc558ef463b3d1..afc27e54a863e2dba4038e53dc4fc2362acb564d 100644 (file)
@@ -156,7 +156,21 @@ EFI_STATUS
   @param[in] This             This instance of VIRTIO_DEVICE_PROTOCOL\r
 \r
   @param[in] Ring             The initialized VRING object to take the\r
-                              addresses from.\r
+                              addresses from. The caller is responsible for\r
+                              ensuring that on input, all Ring->NumPages pages,\r
+                              starting at Ring->Base, have been successfully\r
+                              mapped with a single call to\r
+                              This->MapSharedBuffer() for CommonBuffer bus\r
+                              master operation.\r
+\r
+  @param[in] RingBaseShift    Adding this value using UINT64 arithmetic to the\r
+                              addresses found in Ring translates them from\r
+                              system memory to bus addresses. The caller shall\r
+                              calculate RingBaseShift as\r
+                              (DeviceAddress - (UINT64)(UINTN)HostAddress),\r
+                              where DeviceAddress and HostAddress (i.e.,\r
+                              Ring->Base) were output and input parameters of\r
+                              This->MapSharedBuffer(), respectively.\r
 \r
   @retval EFI_SUCCESS         The data was written successfully.\r
   @retval EFI_UNSUPPORTED     The underlying IO device doesn't support the\r
@@ -166,7 +180,8 @@ typedef
 EFI_STATUS\r
 (EFIAPI *VIRTIO_SET_QUEUE_ADDRESS) (\r
   IN VIRTIO_DEVICE_PROTOCOL  *This,\r
-  IN VRING                   *Ring\r
+  IN VRING                   *Ring,\r
+  IN UINT64                  RingBaseShift\r
   );\r
 \r
 /**\r
index e5881d537f09349bf8f0518ee761d88c5151f26a..e6279159f8ba989bc2a43a3a98751662f06a6b9c 100644 (file)
@@ -115,7 +115,8 @@ VirtioMmioSetQueueSel (
 EFI_STATUS\r
 VirtioMmioSetQueueAddress (\r
   IN VIRTIO_DEVICE_PROTOCOL  *This,\r
-  IN VRING                   *Ring\r
+  IN VRING                   *Ring,\r
+  IN UINT64                  RingBaseShift\r
   );\r
 \r
 EFI_STATUS\r
index 644ec65e1788b1e319d1f6c7bcf4ee33295cda17..67458e56231bcdbe1c1bc62cca717b4384a9df5e 100644 (file)
@@ -181,11 +181,14 @@ VirtioMmioSetQueueSel (
 EFI_STATUS\r
 VirtioMmioSetQueueAddress (\r
   IN VIRTIO_DEVICE_PROTOCOL  *This,\r
-  IN VRING                   *Ring\r
+  IN VRING                   *Ring,\r
+  IN UINT64                  RingBaseShift\r
   )\r
 {\r
   VIRTIO_MMIO_DEVICE *Device;\r
 \r
+  ASSERT (RingBaseShift == 0);\r
+\r
   Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);\r
 \r
   VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_PFN,\r
index 89ccac8c1c044f0c52ecbc186279c13305bc3415..ef9a00710668daf041b011224a1a9cbc1ba69e7c 100644 (file)
@@ -489,7 +489,8 @@ EFI_STATUS
 EFIAPI\r
 Virtio10SetQueueAddress (\r
   IN VIRTIO_DEVICE_PROTOCOL  *This,\r
-  IN VRING                   *Ring\r
+  IN VRING                   *Ring,\r
+  IN UINT64                  RingBaseShift\r
   )\r
 {\r
   VIRTIO_1_0_DEV *Dev;\r
@@ -497,6 +498,8 @@ Virtio10SetQueueAddress (
   UINT64         Address;\r
   UINT16         Enable;\r
 \r
+  ASSERT (RingBaseShift == 0);\r
+\r
   Dev = VIRTIO_1_0_FROM_VIRTIO_DEVICE (This);\r
 \r
   Address = (UINTN)Ring->Desc;\r
index 61b9cab4ff02f41363340d5666e7cb3606008bba..bff15fe3add1692f828122e284abe38f0dc1eef7 100644 (file)
@@ -745,7 +745,7 @@ VirtioBlkInit (
   //\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 (Dev->VirtIo, &Dev->Ring, 0);\r
   if (EFI_ERROR (Status)) {\r
     goto ReleaseQueue;\r
   }\r
index c2e4d72feb679cd64b3d607268d2e548c714ef19..5cb0031612077ea0bc096765d9f2f48773d8f826 100644 (file)
@@ -132,7 +132,11 @@ VirtioGpuInit (
   if (EFI_ERROR (Status)) {\r
     goto Failed;\r
   }\r
-  Status = VgpuDev->VirtIo->SetQueueAddress (VgpuDev->VirtIo, &VgpuDev->Ring);\r
+  Status = VgpuDev->VirtIo->SetQueueAddress (\r
+                              VgpuDev->VirtIo,\r
+                              &VgpuDev->Ring,\r
+                              0\r
+                              );\r
   if (EFI_ERROR (Status)) {\r
     goto ReleaseQueue;\r
   }\r
index 6d9b81a9f9399e08c73b13f7d204c2d77d2ab472..0ecfe044a97735754eddd1e1a6025e6d24270f5f 100644 (file)
@@ -96,7 +96,7 @@ VirtioNetInitRing (
   //\r
   // step 4c -- report GPFN (guest-physical frame number) of queue\r
   //\r
-  Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, Ring);\r
+  Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, Ring, 0);\r
   if (EFI_ERROR (Status)) {\r
     goto ReleaseQueue;\r
   }\r
index 41df5a98e560af12356bab0a9c1f914dba8f1a71..1f0dc45d501e33b7f901e3e0b17e1094542b3cc0 100644 (file)
@@ -126,7 +126,8 @@ EFI_STATUS
 EFIAPI\r
 VirtioPciSetQueueAddress (\r
   IN VIRTIO_DEVICE_PROTOCOL  *This,\r
-  IN VRING                   *Ring\r
+  IN VRING                   *Ring,\r
+  IN UINT64                  RingBaseShift\r
   );\r
 \r
 EFI_STATUS\r
index bd912cca9b29d47855817a49c080dd4472b7bd4c..b52060d13d97024b4fa4cc19ca0997bb5161fef8 100644 (file)
@@ -183,11 +183,14 @@ EFI_STATUS
 EFIAPI\r
 VirtioPciSetQueueAddress (\r
   IN VIRTIO_DEVICE_PROTOCOL  *This,\r
-  IN VRING                   *Ring\r
+  IN VRING                   *Ring,\r
+  IN UINT64                  RingBaseShift\r
   )\r
 {\r
   VIRTIO_PCI_DEVICE *Dev;\r
 \r
+  ASSERT (RingBaseShift == 0);\r
+\r
   Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);\r
 \r
   return VirtioPciIoWrite (Dev, VIRTIO_PCI_OFFSET_QUEUE_ADDRESS, sizeof (UINT32),\r
index e20602ac722525d9d7c5a1e1f872b67730e6b910..0abca488e6cdd6614d4443c90c5c80d570bbe554 100644 (file)
@@ -298,7 +298,7 @@ VirtioRngInit (
   //\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 (Dev->VirtIo, &Dev->Ring, 0);\r
   if (EFI_ERROR (Status)) {\r
     goto ReleaseQueue;\r
   }\r
index c2f6f412ff408f2f602948a59ffbda930bc41f14..a983b3df7b9caf2d1490af8ec6b0dee7cfc45129 100644 (file)
@@ -855,7 +855,7 @@ VirtioScsiInit (
   //\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 (Dev->VirtIo, &Dev->Ring, 0);\r
   if (EFI_ERROR (Status)) {\r
     goto ReleaseQueue;\r
   }\r