public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: Brijesh Singh <brijesh.singh@amd.com>
To: edk2-devel@lists.01.org
Cc: Brijesh Singh <brijesh.singh@amd.com>,
	Ard Biesheuvel <ard.biesheuvel@linaro.org>,
	Jordan Justen <jordan.l.justen@intel.com>,
	Tom Lendacky <thomas.lendacky@amd.com>,
	Laszlo Ersek <lersek@redhat.com>
Subject: [PATCH v2 21/23] OvmfPkg/VirtioNetDxe: dynamically alloc transmit header
Date: Mon, 14 Aug 2017 07:36:43 -0400	[thread overview]
Message-ID: <1502710605-8058-22-git-send-email-brijesh.singh@amd.com> (raw)
In-Reply-To: <1502710605-8058-1-git-send-email-brijesh.singh@amd.com>

A network packets are transmitted by placing then into a transmit queue,
each packet is preceded by a VIRTIO_1_0_NET_REQ header. VirtioNetInitTx(),
builds the header once and fills the vring descriptors with the system
physical address of header.

The patch uses VirtIo->AllocateSharedPages() to allocate the header buffer
and map it with BusMasterCommonBuffer so that it can be equally accessed by
both processor and device.

We could map it with  BusMasterRead but since the header pointer is
used after it was added into vring hence I choose to dynamically allocate
it and map it with BusMasterCommonBuffer to avoid the code complexity.

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>
---
 OvmfPkg/VirtioNetDxe/VirtioNet.h        |  3 +-
 OvmfPkg/VirtioNetDxe/Events.c           |  6 ++
 OvmfPkg/VirtioNetDxe/SnpInitialize.c    | 60 +++++++++++++++++---
 OvmfPkg/VirtioNetDxe/SnpSharedHelpers.c |  6 ++
 4 files changed, 66 insertions(+), 9 deletions(-)

diff --git a/OvmfPkg/VirtioNetDxe/VirtioNet.h b/OvmfPkg/VirtioNetDxe/VirtioNet.h
index a4661bd5d2fe..873069e9de82 100644
--- a/OvmfPkg/VirtioNetDxe/VirtioNet.h
+++ b/OvmfPkg/VirtioNetDxe/VirtioNet.h
@@ -94,7 +94,8 @@ typedef struct {
   UINT16                      TxMaxPending;      // VirtioNetInitTx
   UINT16                      TxCurPending;      // VirtioNetInitTx
   UINT16                      *TxFreeStack;      // VirtioNetInitTx
-  VIRTIO_1_0_NET_REQ          TxSharedReq;       // VirtioNetInitTx
+  VIRTIO_1_0_NET_REQ          *TxSharedReq;      // VirtioNetInitTx
+  VOID                        *TxSharedReqMap;   // VirtioNetInitTx
   UINT16                      TxLastUsed;        // VirtioNetInitTx
 } VNET_DEV;
 
diff --git a/OvmfPkg/VirtioNetDxe/Events.c b/OvmfPkg/VirtioNetDxe/Events.c
index 2f61da6aece4..21468f44a3f0 100644
--- a/OvmfPkg/VirtioNetDxe/Events.c
+++ b/OvmfPkg/VirtioNetDxe/Events.c
@@ -101,4 +101,10 @@ VirtioNetExitBoot (
   // device is reset.
   //
   Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->RxBufMap);
+
+  //
+  // Unmap shared Tx request mapping so that hypervisor can not get readable
+  // data after device is reset.
+  //
+  Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->TxSharedReqMap);
 }
diff --git a/OvmfPkg/VirtioNetDxe/SnpInitialize.c b/OvmfPkg/VirtioNetDxe/SnpInitialize.c
index db2314446bbb..9bac19f8e3d1 100644
--- a/OvmfPkg/VirtioNetDxe/SnpInitialize.c
+++ b/OvmfPkg/VirtioNetDxe/SnpInitialize.c
@@ -18,6 +18,7 @@
 **/
 
 #include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
 #include <Library/MemoryAllocationLib.h>
 #include <Library/UefiBootServicesTableLib.h>
 
@@ -149,8 +150,11 @@ VirtioNetInitTx (
   IN OUT VNET_DEV *Dev
   )
 {
-  UINTN TxSharedReqSize;
-  UINTN PktIdx;
+  UINTN                 TxSharedReqSize;
+  UINTN                 PktIdx;
+  EFI_STATUS            Status;
+  EFI_PHYSICAL_ADDRESS  DeviceAddress;
+  UINT64                BufBaseShift;
 
   Dev->TxMaxPending = (UINT16) MIN (Dev->TxRing.QueueSize / 2,
                                  VNET_MAX_PENDING);
@@ -162,24 +166,57 @@ VirtioNetInitTx (
   }
 
   //
+  // Allocate TxSharedReq header and map with BusMasterCommonBuffer so that it
+  // can be accessed equally by both processor and device.
+  //
+  Status = Dev->VirtIo->AllocateSharedPages (
+                          Dev->VirtIo,
+                          EFI_SIZE_TO_PAGES (sizeof *(Dev->TxSharedReq)),
+                          (VOID *) &Dev->TxSharedReq
+                          );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = VirtioMapAllBytesInSharedBuffer (
+             Dev->VirtIo,
+             VirtioOperationBusMasterCommonBuffer,
+             (VOID *) Dev->TxSharedReq,
+             sizeof *(Dev->TxSharedReq),
+             &DeviceAddress,
+             &Dev->TxSharedReqMap
+             );
+  if (EFI_ERROR (Status)) {
+    goto FreeBuffer;
+  }
+
+  BufBaseShift = (UINT64) (UINTN)Dev->TxSharedReq - (UINT64) DeviceAddress;
+
+  ZeroMem ((VOID *) Dev->TxSharedReq, sizeof *(Dev->TxSharedReq));
+
+  //
   // In VirtIo 1.0, the NumBuffers field is mandatory. In 0.9.5, it depends on
   // VIRTIO_NET_F_MRG_RXBUF, which we never negotiate.
   //
   TxSharedReqSize = (Dev->VirtIo->Revision < VIRTIO_SPEC_REVISION (1, 0, 0)) ?
-                    sizeof Dev->TxSharedReq.V0_9_5 :
-                    sizeof Dev->TxSharedReq;
+                    sizeof ((Dev->TxSharedReq)->V0_9_5) :
+                    sizeof *(Dev->TxSharedReq);
 
   for (PktIdx = 0; PktIdx < Dev->TxMaxPending; ++PktIdx) {
     UINT16 DescIdx;
+    UINT64 Address;
 
     DescIdx = (UINT16) (2 * PktIdx);
     Dev->TxFreeStack[PktIdx] = DescIdx;
 
+    Address = (UINTN) Dev->TxSharedReq;
+    Address += BufBaseShift;
+
     //
     // For each possibly pending packet, lay out the descriptor for the common
     // (unmodified by the host) virtio-net request header.
     //
-    Dev->TxRing.Desc[DescIdx].Addr  = (UINTN) &Dev->TxSharedReq;
+    Dev->TxRing.Desc[DescIdx].Addr  = (UINTN) Address;
     Dev->TxRing.Desc[DescIdx].Len   = (UINT32) TxSharedReqSize;
     Dev->TxRing.Desc[DescIdx].Flags = VRING_DESC_F_NEXT;
     Dev->TxRing.Desc[DescIdx].Next  = (UINT16) (DescIdx + 1);
@@ -194,13 +231,13 @@ VirtioNetInitTx (
   //
   // virtio-0.9.5, Appendix C, Packet Transmission
   //
-  Dev->TxSharedReq.V0_9_5.Flags   = 0;
-  Dev->TxSharedReq.V0_9_5.GsoType = VIRTIO_NET_HDR_GSO_NONE;
+  Dev->TxSharedReq->V0_9_5.Flags   = 0;
+  Dev->TxSharedReq->V0_9_5.GsoType = VIRTIO_NET_HDR_GSO_NONE;
 
   //
   // For VirtIo 1.0 only -- the field exists, but it is unused
   //
-  Dev->TxSharedReq.NumBuffers = 0;
+  Dev->TxSharedReq->NumBuffers = 0;
 
   //
   // virtio-0.9.5, 2.4.2 Receiving Used Buffers From the Device
@@ -215,6 +252,13 @@ VirtioNetInitTx (
   *Dev->TxRing.Avail.Flags = (UINT16) VRING_AVAIL_F_NO_INTERRUPT;
 
   return EFI_SUCCESS;
+FreeBuffer:
+  Dev->VirtIo->FreeSharedPages (
+                 Dev->VirtIo,
+                 EFI_SIZE_TO_PAGES (sizeof *(Dev->TxSharedReq)),
+                 (VOID *) Dev->TxSharedReq
+                 );
+  return Status;
 }
 
 
diff --git a/OvmfPkg/VirtioNetDxe/SnpSharedHelpers.c b/OvmfPkg/VirtioNetDxe/SnpSharedHelpers.c
index ec8e63ebdc32..6e7166144f2d 100644
--- a/OvmfPkg/VirtioNetDxe/SnpSharedHelpers.c
+++ b/OvmfPkg/VirtioNetDxe/SnpSharedHelpers.c
@@ -53,5 +53,11 @@ VirtioNetShutdownTx (
   IN OUT VNET_DEV *Dev
   )
 {
+  Dev->VirtIo->FreeSharedPages (
+                 Dev->VirtIo,
+                 EFI_SIZE_TO_PAGES (sizeof *(Dev->TxSharedReq)),
+                 (VOID *) Dev->TxSharedReq
+                 );
+
   FreePool (Dev->TxFreeStack);
 }
-- 
2.7.4



  parent reply	other threads:[~2017-08-14 11:35 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-08-14 11:36 [PATCH v2 00/21] OvmfPkg/Virtio: introduce IOMMU-like member functions Brijesh Singh
2017-08-14 11:36 ` [PATCH v2 01/23] OvmfPkg/VirtioPciDeviceDxe: supply missing BUS_MASTER attribute Brijesh Singh
2017-08-16  0:34   ` Laszlo Ersek
2017-08-14 11:36 ` [PATCH v2 02/23] OvmfPkg/Virtio10Dxe: " Brijesh Singh
2017-08-16  0:36   ` Laszlo Ersek
2017-08-14 11:36 ` [PATCH v2 03/23] OvmfPkg/VirtioPciDeviceDxe: add missing IN and OUT decoration Brijesh Singh
2017-08-16  0:36   ` Laszlo Ersek
2017-08-14 11:36 ` [PATCH v2 04/23] OvmfPkg/VirtioMmioDeviceLib: " Brijesh Singh
2017-08-16  0:37   ` Laszlo Ersek
2017-08-14 11:36 ` [PATCH v2 05/23] OvmfPkg/Virtio: fix comment style Brijesh Singh
2017-08-16  0:41   ` Laszlo Ersek
2017-08-14 11:36 ` [PATCH v2 06/23] OvmfPkg/Virtio: introduce IOMMU-like member functions to VIRTIO_DEVICE_PROTOCOL Brijesh Singh
2017-08-16 14:37   ` Laszlo Ersek
2017-08-16 15:58     ` Brijesh Singh
2017-08-14 11:36 ` [PATCH v2 07/23] OvmfPkg/Virtio10Dxe: implement IOMMU-like member functions Brijesh Singh
2017-08-16 14:59   ` Laszlo Ersek
2017-08-14 11:36 ` [PATCH v2 08/23] OvmfPkg/VirtioPciDeviceDxe: " Brijesh Singh
2017-08-16 15:32   ` Laszlo Ersek
2017-08-16 15:53     ` Brijesh Singh
2017-08-14 11:36 ` [PATCH v2 09/23] OvmfPkg/VirtioMmioDeviceLib: " Brijesh Singh
2017-08-16 15:58   ` Laszlo Ersek
2017-08-14 11:36 ` [PATCH v2 10/23] OvmfPkg/VirtioLib: add VirtioMapAllBytesInSharedBuffer() helper function Brijesh Singh
2017-08-16 16:47   ` Laszlo Ersek
2017-08-14 11:36 ` [PATCH v2 11/23] OvmfPkg/VirtioLib: take VirtIo instance in VirtioRingInit/VirtioRingUninit Brijesh Singh
2017-08-16 16:53   ` Laszlo Ersek
2017-08-14 11:36 ` [PATCH v2 12/23] OvmfPkg/VirtioLib: add functions to map/unmap VRING Brijesh Singh
2017-08-16 20:56   ` Laszlo Ersek
2017-08-14 11:36 ` [PATCH v2 13/23] OvmfPkg/Virtio: take RingBaseShift in VirtioSetQueueAddress() Brijesh Singh
2017-08-16 21:43   ` Laszlo Ersek
2017-08-16 21:51     ` Laszlo Ersek
2017-08-14 11:36 ` [PATCH v2 14/23] OvmfPkg/Virtio10Dxe: add the RingBaseShift offset Brijesh Singh
2017-08-16 21:57   ` Laszlo Ersek
2017-08-14 11:36 ` [PATCH v2 15/23] OvmfPkg/VirtioLib: alloc vring buffer with AllocateSharedPages() Brijesh Singh
2017-08-16 22:18   ` Laszlo Ersek
2017-08-14 11:36 ` [PATCH v2 16/23] OvmfPkg/VirtioRngDxe: map host address to device address Brijesh Singh
2017-08-21 14:05   ` Laszlo Ersek
2017-08-22 15:44     ` Brijesh Singh
2017-08-22 16:28       ` Laszlo Ersek
2017-08-14 11:36 ` [PATCH v2 17/23] OvmfPkg/VirtioBlkDxe: " Brijesh Singh
2017-08-21 15:24   ` Laszlo Ersek
2017-08-22  1:42     ` Brijesh Singh
     [not found]       ` <1387174d-0040-0072-5e36-c133fd7ec934@redhat.com>
2017-08-22 14:29         ` Brijesh Singh
2017-08-22 15:53           ` Laszlo Ersek
2017-08-14 11:36 ` [PATCH v2 18/23] OvmfPkg/VirtioScsiDxe: Use DeviceAddresses in vring descriptors Brijesh Singh
2017-08-21 19:08   ` Laszlo Ersek
2017-08-14 11:36 ` [PATCH v2 19/23] OvmfPkg/VirtioNetDxe: alloc Tx and Rx rings using AllocateSharedPage() Brijesh Singh
2017-08-14 11:36 ` [PATCH v2 20/23] OvmfPkg/VirtioNetDxe: alloc RxBuf using AllocateSharedPages() Brijesh Singh
2017-08-14 11:36 ` Brijesh Singh [this message]
2017-08-14 11:36 ` [PATCH v2 22/23] OvmfPkg/VirtioNetDxe: map transmit buffer host address to device address Brijesh Singh
2017-08-14 11:36 ` [PATCH v2 23/23] OvmfPkg/Virtio: define VIRITO_F_IOMMU_PLATFORM feature bit Brijesh Singh
2017-08-21 15:40   ` Laszlo Ersek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1502710605-8058-22-git-send-email-brijesh.singh@amd.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox