]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg/VirtioNetDxe: map caller-supplied Tx packet to device-address
authorBrijesh Singh <brijesh.singh@amd.com>
Thu, 14 Sep 2017 21:22:46 +0000 (16:22 -0500)
committerLaszlo Ersek <lersek@redhat.com>
Thu, 14 Sep 2017 21:54:18 +0000 (23:54 +0200)
When device is behind the IOMMU, driver is require to pass the device
address of caller-supplied transmit buffer for the bus master operations.

The patch uses VirtioNetMapTxBuf() to map caller-supplied Tx packet to a
device-address and enqueue the device address in VRING for transfer and
perform the reverse mapping when transfer is completed so that we can
return the caller-supplied buffer.

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/VirtioNetDxe/SnpGetStatus.c
OvmfPkg/VirtioNetDxe/SnpTransmit.c

index 694940ea1d976827bd890a734cb5e154b02a2470..9b1c352227b3953834f0edc5a53da45e96de6595 100644 (file)
@@ -61,11 +61,12 @@ VirtioNetGetStatus (
   OUT VOID                       **TxBuf OPTIONAL\r
   )\r
 {\r
-  VNET_DEV   *Dev;\r
-  EFI_TPL    OldTpl;\r
-  EFI_STATUS Status;\r
-  UINT16     RxCurUsed;\r
-  UINT16     TxCurUsed;\r
+  VNET_DEV             *Dev;\r
+  EFI_TPL              OldTpl;\r
+  EFI_STATUS           Status;\r
+  UINT16               RxCurUsed;\r
+  UINT16               TxCurUsed;\r
+  EFI_PHYSICAL_ADDRESS DeviceAddress;\r
 \r
   if (This == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -141,14 +142,34 @@ VirtioNetGetStatus (
       ASSERT (DescIdx < (UINT32) (2 * Dev->TxMaxPending - 1));\r
 \r
       //\r
-      // report buffer address to caller that has been enqueued by caller\r
+      // get the device address that has been enqueued for the caller's\r
+      // transmit buffer\r
       //\r
-      *TxBuf = (VOID *)(UINTN) Dev->TxRing.Desc[DescIdx + 1].Addr;\r
+      DeviceAddress = Dev->TxRing.Desc[DescIdx + 1].Addr;\r
 \r
       //\r
       // now this descriptor can be used again to enqueue a transmit buffer\r
       //\r
       Dev->TxFreeStack[--Dev->TxCurPending] = (UINT16) DescIdx;\r
+\r
+      //\r
+      // Unmap the device address and perform the reverse mapping to find the\r
+      // caller buffer address.\r
+      //\r
+      Status = VirtioNetUnmapTxBuf (\r
+                 Dev,\r
+                 TxBuf,\r
+                 DeviceAddress\r
+                 );\r
+      if (EFI_ERROR (Status)) {\r
+        //\r
+        // VirtioNetUnmapTxBuf should never fail, if we have reached here\r
+        // that means our internal state has been corrupted\r
+        //\r
+        ASSERT (FALSE);\r
+        Status = EFI_DEVICE_ERROR;\r
+        goto Exit;\r
+      }\r
     }\r
   }\r
 \r
index 7ca40d5d06504b75e870aeab68c33cf3d9f047fc..b39226e138b9f97a40d50af942c8dec2b5449d62 100644 (file)
@@ -73,11 +73,12 @@ VirtioNetTransmit (
   IN UINT16                      *Protocol OPTIONAL\r
   )\r
 {\r
-  VNET_DEV   *Dev;\r
-  EFI_TPL    OldTpl;\r
-  EFI_STATUS Status;\r
-  UINT16     DescIdx;\r
-  UINT16     AvailIdx;\r
+  VNET_DEV              *Dev;\r
+  EFI_TPL               OldTpl;\r
+  EFI_STATUS            Status;\r
+  UINT16                DescIdx;\r
+  UINT16                AvailIdx;\r
+  EFI_PHYSICAL_ADDRESS  DeviceAddress;\r
 \r
   if (This == NULL || BufferSize == 0 || Buffer == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -143,11 +144,25 @@ VirtioNetTransmit (
     ASSERT ((UINTN) (Ptr - (UINT8 *) Buffer) == Dev->Snm.MediaHeaderSize);\r
   }\r
 \r
+  //\r
+  // Map the transmit buffer system physical address to device address.\r
+  //\r
+  Status = VirtioNetMapTxBuf (\r
+             Dev,\r
+             Buffer,\r
+             BufferSize,\r
+             &DeviceAddress\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto Exit;\r
+  }\r
+\r
   //\r
   // virtio-0.9.5, 2.4.1 Supplying Buffers to The Device\r
   //\r
   DescIdx = Dev->TxFreeStack[Dev->TxCurPending++];\r
-  Dev->TxRing.Desc[DescIdx + 1].Addr  = (UINTN) Buffer;\r
+  Dev->TxRing.Desc[DescIdx + 1].Addr  = DeviceAddress;\r
   Dev->TxRing.Desc[DescIdx + 1].Len   = (UINT32) BufferSize;\r
 \r
   //\r