public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH v3 00/21] OvmfPkg/Virtio: introduce IOMMU-like member functions
@ 2017-08-23 12:22 Brijesh Singh
  2017-08-23 12:22 ` [PATCH v3 01/23] OvmfPkg: introduce IOMMU-like member functions to VIRTIO_DEVICE_PROTOCOL Brijesh Singh
                   ` (23 more replies)
  0 siblings, 24 replies; 46+ messages in thread
From: Brijesh Singh @ 2017-08-23 12:22 UTC (permalink / raw)
  To: edk2-devel
  Cc: Brijesh Singh, Ard Biesheuvel, Jordan Justen, Tom Lendacky,
	Laszlo Ersek

Currently, virtio drivers provides the system physical address to the device.
However, some systems may feature an IOMMU that requires the drivers to pass
the device addresses to the device - which are then translated by the IOMMU 
into physical addresses in memory. The patch series introduces new member
functions in VIRTIO_DEVICE_PROTOCOL which can be used for mapping a system
physical address to device address.

The approach that this patch series takes is to maps the system physical
address to device address for buffers (including rings, device specifc
request and response  pointed by vring descriptor, and any further memory 
reference by those request and response).

Patch 1 - 4:
 Defines and implements new member functions to map a system physical address
 to device address. The patch implements Laszlo's suggestion [1].

[1] http://mid.mail-archive.com/841bec5f-6f6e-8b1f-25ba-0fd37a915b72@redhat.com

Patch 5 - 12:
 Add some helper functions and allocate the vring using newly added member
 functions.

Patch 13:
 Update the virtio-rng driver to use newly added member functions to map the
 addresses.
 Verified using the following qemu cli

 # $QEMU \
    -device virtio-rng-pci

 # $QEMU \
    -device virtio-rng-pci,disable-legacy=on

 # $QEMU \
    -device virtio-rng-pci,disable-legacy=on,iommu_platform=true

 And succesfully ran RngTest.efi from SecurityPkg/Application and also
 verified that /dev/hwrng get created after Linux guest boot

Patch 14:
 Update the virtio-blk driver to use newly added member functions to map the
 addresses.
 Verified using the following qemu cli

 # $QEMU \
    -drive file=${IMAGE},if=none,id=disk0 \
    -device virtio-blk-pci,drive=disk0

 # $QEMU \
    -drive file=${IMAGE},if=none,id=disk0 \
    -device virtio-blk-pci,drive=disk0,disable-legacy=on

 # $QEMU \
    -drive file=${IMAGE},if=none,id=disk0 \
    -device virtio-blk-pci,drive=disk0,disable-legacy=on,iommu_platform=true

Patch 15:
 Update the virtio-scsi driver to use newly added member functions to map the
 addresses.
 Verified using the following qemu cli

 # $QEMU \
    -drive file=${IMAGE},if=none,id=disk0 \
    -device scsi-hd,drive=disk0 \
    -device virtio-scsi-pci,id=scsi 

 # $QEMU \
    -drive file=${IMAGE},if=none,id=disk0 \
    -device scsi-hd,drive=disk0 \
    -device virtio-scsi-pci,id=scsi,disable-legacy=on 

 # $QEMU \
    -drive file=${IMAGE},if=none,id=disk0 \
    -device scsi-hd,drive=disk0 \
    -device virtio-scsi-pci,id=scsi,disable-legacy=on,iommu_platform=true

Patch 16 - 19:
 Update the virtio-net driver to use newly added member functions to map the
 addresses.
 Verified using the following qemu cli

 # $QEMU \
    -netdev type=tap,id=net0 \
    -device virtio-net-pci,netdev=net0,romfile=

 # $QEMU \
    -netdev type=tap,id=net0 \
    -device virtio-net-pci,netdev=net0,disable-legacy=on,romfile=

 # $QEMU \
    -netdev type=tap,id=net0 \
    -device virtio-net-pci,netdev=net0,disable-legacy=on,iommu_platform=true,romfile=

Patch 20 - 23:
 Add support for VIRTIO_F_IOMMU_FEATURE bit

Repo: https://github.com/codomania/edk2
Branch: virtio-support-v3

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>

TODO:
 * add VirtioGpuDxe (i will take Laszlo's offer that he can help with this driver)
 * I did minimal test on aarch64 - I was running into some Linux
   bootup issues with Fedora aarch64 iso. The issue does not appear to
   be releated to virtio changes. If anyone can help doing additional
   test with their aarch images that will be great ! thanks

Changes since v2:
 * changes to address v2 feedbacks
 * split the iommu_platform support into multiple patches

Changes since v1:
 * changes to address v1 feedbacks
 * add VIRTIO_F_IOMMU_PLATFORM feature bit

Brijesh Singh (23):
  OvmfPkg: introduce IOMMU-like member functions to
    VIRTIO_DEVICE_PROTOCOL
  OvmfPkg/Virtio10Dxe: implement IOMMU-like member functions
  OvmfPkg/VirtioPciDeviceDxe: implement IOMMU-like member functions
  OvmfPkg/VirtioMmioDeviceLib: implement IOMMU-like member functions
  OvmfPkg/VirtioLib: add VirtioMapAllBytesInSharedBuffer() helper
    function
  OvmfPkg/VirtioLib: take VirtIo instance in
    VirtioRingInit/VirtioRingUninit
  OvmfPkg/Virtio: take RingBaseShift in SetQueueAddress()
  OvmfPkg/Virtio10Dxe: add the RingBaseShift offset
  OvmfPkg/VirtioLib: add function to map VRING
  OvmfPkg/VirtioLib: alloc VRING buffer with AllocateSharedPages()
  OvmfPkg/VirtioLib: change the parameter of VirtioAppendDesc() to
    UINT64
  OvmfPkg/VirtioRngDxe: map host address to device address
  OvmfPkg/VirtioBlkDxe: map host address to device address
  OvmfPkg/VirtioScsiDxe: map host address to device address
  OvmfPkg/VirtioNetDxe: alloc Tx and Rx rings using AllocateSharedPage()
  OvmfPkg/VirtioNetDxe: alloc RxBuf using AllocateSharedPages()
  OvmfPkg/VirtioNetDxe: dynamically alloc transmit header
  OvmfPkg/VirtioNetDxe: map transmit buffer host address to device
    address
  OvmfPkg/Virtio10: define VIRITO_F_IOMMU_PLATFORM feature bit
  OvmfPkg/VirtioRngDxe: negotiate VIRITO_F_IOMMU_PLATFORM
  OvmfPkg/VirtioBlkDxe: negotiate VIRITO_F_IOMMU_PLATFORM
  OvmfPkg/VirtioScsiDxe: negotiate VIRITO_F_IOMMU_PLATFORM
  OvmfPkg/VirtioNetDxe: negotiate VIRITO_F_IOMMU_PLATFORM

 OvmfPkg/Library/VirtioLib/VirtioLib.inf                         |   1 -
 OvmfPkg/Include/IndustryStandard/Virtio10.h                     |   4 +-
 OvmfPkg/Include/Library/VirtioLib.h                             | 132 +++++++++---
 OvmfPkg/Include/Protocol/VirtioDevice.h                         | 162 +++++++++++++-
 OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.h          |  39 +++-
 OvmfPkg/VirtioBlkDxe/VirtioBlk.h                                |   1 +
 OvmfPkg/VirtioNetDxe/VirtioNet.h                                |  25 ++-
 OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.h                    |  37 +++-
 OvmfPkg/VirtioRngDxe/VirtioRng.h                                |   1 +
 OvmfPkg/VirtioScsiDxe/VirtioScsi.h                              |   1 +
 OvmfPkg/Library/VirtioLib/VirtioLib.c                           | 204 +++++++++++++++---
 OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c          |   8 +-
 OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c |  62 +++++-
 OvmfPkg/Virtio10Dxe/Virtio10.c                                  | 128 ++++++++++-
 OvmfPkg/VirtioBlkDxe/VirtioBlk.c                                | 213 ++++++++++++++++---
 OvmfPkg/VirtioGpuDxe/Commands.c                                 |  13 +-
 OvmfPkg/VirtioNetDxe/Events.c                                   |  19 ++
 OvmfPkg/VirtioNetDxe/SnpGetStatus.c                             |  29 ++-
 OvmfPkg/VirtioNetDxe/SnpInitialize.c                            | 195 ++++++++++++++---
 OvmfPkg/VirtioNetDxe/SnpSharedHelpers.c                         | 133 +++++++++++-
 OvmfPkg/VirtioNetDxe/SnpShutdown.c                              |   7 +-
 OvmfPkg/VirtioNetDxe/SnpTransmit.c                              |  30 ++-
 OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c                    |   7 +-
 OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c                 |  63 +++++-
 OvmfPkg/VirtioRngDxe/VirtioRng.c                                |  93 ++++++--
 OvmfPkg/VirtioScsiDxe/VirtioScsi.c                              | 222 +++++++++++++++++---
 26 files changed, 1635 insertions(+), 194 deletions(-)

-- 
2.7.4



^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v3 01/23] OvmfPkg: introduce IOMMU-like member functions to VIRTIO_DEVICE_PROTOCOL
  2017-08-23 12:22 [PATCH v3 00/21] OvmfPkg/Virtio: introduce IOMMU-like member functions Brijesh Singh
@ 2017-08-23 12:22 ` Brijesh Singh
  2017-08-23 19:04   ` Laszlo Ersek
  2017-08-23 12:22 ` [PATCH v3 02/23] OvmfPkg/Virtio10Dxe: implement IOMMU-like member functions Brijesh Singh
                   ` (22 subsequent siblings)
  23 siblings, 1 reply; 46+ messages in thread
From: Brijesh Singh @ 2017-08-23 12:22 UTC (permalink / raw)
  To: edk2-devel
  Cc: Brijesh Singh, Ard Biesheuvel, Jordan Justen, Tom Lendacky,
	Laszlo Ersek

The patch extends VIRTIO_DEVICE_PROTOCOL to provide the following new
member functions:

- AllocateSharedPages : allocate a memory region suitable for sharing
   between guest and hypervisor (e.g ring buffer).

- FreeSharedPages: free the memory allocated using AllocateSharedPages ().

- MapSharedBuffer: map a host address to device address suitable to share
   with device for bus master operations.

- UnmapSharedBuffer: unmap the device address obtained through the
   MapSharedBuffer().

We're free to extend the protocol structure without changing the protocol
GUID, or bumping any protocol version fields (of which we currently have
none), because VIRTIO_DEVICE_PROTOCOL is internal to edk2 by design --
see the disclaimers in "VirtioDevice.h".

The patch implements Laszlo's recommendation [1].

[1] http://mid.mail-archive.com/841bec5f-6f6e-8b1f-25ba-0fd37a915b72@redhat.com

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>
---
 OvmfPkg/Include/Protocol/VirtioDevice.h | 143 ++++++++++++++++++++
 1 file changed, 143 insertions(+)

diff --git a/OvmfPkg/Include/Protocol/VirtioDevice.h b/OvmfPkg/Include/Protocol/VirtioDevice.h
index fc166bd1a2b4..9a01932958a2 100644
--- a/OvmfPkg/Include/Protocol/VirtioDevice.h
+++ b/OvmfPkg/Include/Protocol/VirtioDevice.h
@@ -5,6 +5,7 @@
   and should not be used outside of the EDK II tree.
 
   Copyright (c) 2013, ARM Ltd. All rights reserved.<BR>
+  Copyright (c) 2017, AMD Inc, All rights reserved.<BR>
 
   This program and the accompanying materials are licensed and made available
   under the terms and conditions of the BSD License which accompanies this
@@ -33,6 +34,25 @@
 
 typedef struct _VIRTIO_DEVICE_PROTOCOL  VIRTIO_DEVICE_PROTOCOL;
 
+//
+// VIRTIO Operation for VIRTIO_MAP_SHARED
+//
+typedef enum {
+  //
+  // A read operation from system memory by a bus master
+  //
+  VirtioOperationBusMasterRead,
+  //
+  // A write operation to system memory by a bus master
+  //
+  VirtioOperationBusMasterWrite,
+  //
+  // Provides both read and write access to system memory by both the
+  // processor and a bus master
+  //
+  VirtioOperationBusMasterCommonBuffer,
+} VIRTIO_MAP_OPERATION;
+
 /**
 
   Read a word from the device-specific I/O region of the Virtio Header.
@@ -321,6 +341,121 @@ EFI_STATUS
   IN UINT8                   DeviceStatus
   );
 
+/**
+
+  Allocates pages that are suitable for an VirtioOperationBusMasterCommonBuffer
+  mapping. This means that the buffer allocated by this function supports
+  simultaneous access by both the processor and the bus master. The device
+  address that the bus master uses to access the buffer must be retrieved with
+  a call to VIRTIO_MAP_SHARED.
+
+  @param[in]      This              The protocol instance pointer.
+
+  @param[in]      Pages             The number of pages to allocate.
+
+  @param[in,out]  HostAddress       A pointer to store the system memory base
+                                    address of the allocated range.
+
+  @retval EFI_SUCCESS               The requested memory pages were allocated.
+  @retval EFI_OUT_OF_RESOURCES      The memory pages could not be allocated.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *VIRTIO_ALLOCATE_SHARED)(
+  IN     VIRTIO_DEVICE_PROTOCOL                   *This,
+  IN     UINTN                                    Pages,
+  IN OUT VOID                                     **HostAddress
+  );
+
+/**
+  Frees memory that was allocated with VIRTIO_ALLOCATE_SHARED.
+
+  @param[in]  This           The protocol instance pointer.
+
+  @param[in]  Pages          The number of pages to free.
+
+  @param[in]  HostAddress    The system memory base address of the allocated
+                             range.
+
+**/
+typedef
+VOID
+(EFIAPI *VIRTIO_FREE_SHARED)(
+  IN  VIRTIO_DEVICE_PROTOCOL                   *This,
+  IN  UINTN                                    Pages,
+  IN  VOID                                     *HostAddress
+  );
+
+/**
+  Provides the virtio device address required to access system memory from a
+  DMA bus master.
+
+  The interface follows the same usage pattern as defined in UEFI spec 2.6
+  (Section 13.2 PCI Root Bridge I/O Protocol)
+
+  @param[in]     This             The protocol instance pointer.
+
+  @param[in]     Operation        Indicates if the bus master is going to
+                                  read or write to system memory.
+
+  @param[in]     HostAddress      The system memory address to map to shared
+                                  buffer address.
+
+  @param[in,out] NumberOfBytes    On input the number of bytes to map.
+                                  On output the number of bytes that were
+                                  mapped.
+
+  @param[out]    DeviceAddress    The resulting shared map address for the
+                                  bus master to access the hosts HostAddress.
+
+  @param[out]    Mapping          A resulting token to pass to
+                                  VIRTIO_UNMAP_SHARED.
+
+  @retval EFI_SUCCESS             The range was mapped for the returned
+                                  NumberOfBytes.
+  @retval EFI_UNSUPPORTED         The HostAddress cannot be mapped as a
+                                  common buffer.
+  @retval EFI_INVALID_PARAMETER   One or more parameters are invalid.
+  @retval EFI_OUT_OF_RESOURCES    The request could not be completed due to
+                                  a lack of resources.
+  @retval EFI_DEVICE_ERROR        The system hardware could not map the
+                                  requested address.
+**/
+
+typedef
+EFI_STATUS
+(EFIAPI *VIRTIO_MAP_SHARED) (
+  IN     VIRTIO_DEVICE_PROTOCOL       *This,
+  IN     VIRTIO_MAP_OPERATION         Operation,
+  IN     VOID                         *HostAddress,
+  IN OUT UINTN                        *NumberOfBytes,
+  OUT    EFI_PHYSICAL_ADDRESS         *DeviceAddress,
+  OUT    VOID                         **Mapping
+  );
+
+/**
+  Completes the VIRTIO_MAP_SHARED operation and releases any corresponding
+  resources.
+
+  @param[in]  This               The protocol instance pointer.
+
+  @param[in]  Mapping            The mapping token returned from
+                                 VIRTIO_MAP_SHARED.
+
+  @retval EFI_SUCCESS            The range was unmapped.
+  @retval EFI_INVALID_PARAMETER  Mapping is not a value that was returned by
+                                 VIRTIO_MAP_SHARED. Passing an invalid Mapping
+                                 token can cause undefined behavior.
+  @retval EFI_DEVICE_ERROR       The data was not committed to the target
+                                 system memory.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *VIRTIO_UNMAP_SHARED)(
+  IN  VIRTIO_DEVICE_PROTOCOL    *This,
+  IN  VOID                      *Mapping
+  );
 
 ///
 ///  This protocol provides an abstraction over the VirtIo transport layer
@@ -361,6 +496,14 @@ struct _VIRTIO_DEVICE_PROTOCOL {
   //
   VIRTIO_DEVICE_WRITE         WriteDevice;
   VIRTIO_DEVICE_READ          ReadDevice;
+
+  //
+  // Functions to allocate, free, map and unmap shared buffer
+  //
+  VIRTIO_ALLOCATE_SHARED      AllocateSharedPages;
+  VIRTIO_FREE_SHARED          FreeSharedPages;
+  VIRTIO_MAP_SHARED           MapSharedBuffer;
+  VIRTIO_UNMAP_SHARED         UnmapSharedBuffer;
 };
 
 extern EFI_GUID gVirtioDeviceProtocolGuid;
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 02/23] OvmfPkg/Virtio10Dxe: implement IOMMU-like member functions
  2017-08-23 12:22 [PATCH v3 00/21] OvmfPkg/Virtio: introduce IOMMU-like member functions Brijesh Singh
  2017-08-23 12:22 ` [PATCH v3 01/23] OvmfPkg: introduce IOMMU-like member functions to VIRTIO_DEVICE_PROTOCOL Brijesh Singh
@ 2017-08-23 12:22 ` Brijesh Singh
  2017-08-23 19:13   ` Laszlo Ersek
  2017-08-23 12:22 ` [PATCH v3 03/23] OvmfPkg/VirtioPciDeviceDxe: " Brijesh Singh
                   ` (21 subsequent siblings)
  23 siblings, 1 reply; 46+ messages in thread
From: Brijesh Singh @ 2017-08-23 12:22 UTC (permalink / raw)
  To: edk2-devel
  Cc: Brijesh Singh, Ard Biesheuvel, Jordan Justen, Tom Lendacky,
	Laszlo Ersek

The patch implements the newly added IOMMU-like member functions by
respectively delegating the job to:

- VIRTIO_DEVICE_PROTOCOL.AllocateSharedPages() ->
    EFI_PCI_IO_PROTOCOL.AllocateBuffer()

- VIRTIO_DEVICE_PROTOCOL.FreeSharedPages() ->
    EFI_PCI_IO_PROTOCOL.FreeBuffer()

- VIRTIO_DEVICE_PROTOCOL.MapSharedBuffer() ->
    EFI_PCI_IO_PROTOCOL.Map()

- VIRTIO_DEVICE_PROTOCOL.UnmapSharedBuffer() ->
    EFI_PCI_IO_PROTOCOL.Unmap()

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>
---
 OvmfPkg/Virtio10Dxe/Virtio10.c | 122 +++++++++++++++++++-
 1 file changed, 120 insertions(+), 2 deletions(-)

diff --git a/OvmfPkg/Virtio10Dxe/Virtio10.c b/OvmfPkg/Virtio10Dxe/Virtio10.c
index d7ea4432bcb6..89ccac8c1c04 100644
--- a/OvmfPkg/Virtio10Dxe/Virtio10.c
+++ b/OvmfPkg/Virtio10Dxe/Virtio10.c
@@ -2,6 +2,7 @@
   A non-transitional driver for VirtIo 1.0 PCI devices.
 
   Copyright (C) 2016, Red Hat, Inc.
+  Copyright (C) 2017, AMD Inc, All rights reserved.<BR>
 
   This program and the accompanying materials are licensed and made available
   under the terms and conditions of the BSD License which accompanies this
@@ -15,6 +16,7 @@
 #include <IndustryStandard/Pci.h>
 #include <IndustryStandard/Virtio.h>
 #include <Protocol/PciIo.h>
+#include <Protocol/PciRootBridgeIo.h>
 #include <Protocol/VirtioDevice.h>
 #include <Library/BaseMemoryLib.h>
 #include <Library/DebugLib.h>
@@ -772,6 +774,117 @@ Virtio10ReadDevice (
   return Status;
 }
 
+STATIC
+EFI_STATUS
+EFIAPI
+Virtio10AllocateSharedPages (
+  IN     VIRTIO_DEVICE_PROTOCOL  *This,
+  IN     UINTN                   Pages,
+  IN OUT VOID                    **HostAddress
+  )
+{
+  VIRTIO_1_0_DEV *Dev;
+  EFI_STATUS     Status;
+
+  Dev = VIRTIO_1_0_FROM_VIRTIO_DEVICE (This);
+
+  Status = Dev->PciIo->AllocateBuffer (
+                         Dev->PciIo,
+                         AllocateAnyPages,
+                         EfiBootServicesData,
+                         Pages,
+                         HostAddress,
+                         EFI_PCI_ATTRIBUTE_MEMORY_CACHED
+                         );
+  return Status;
+}
+
+STATIC
+VOID
+EFIAPI
+Virtio10FreeSharedPages (
+  IN  VIRTIO_DEVICE_PROTOCOL  *This,
+  IN  UINTN                   Pages,
+  IN  VOID                    *HostAddress
+  )
+{
+  VIRTIO_1_0_DEV *Dev;
+
+  Dev = VIRTIO_1_0_FROM_VIRTIO_DEVICE (This);
+
+  Dev->PciIo->FreeBuffer (
+                Dev->PciIo,
+                Pages,
+                HostAddress
+                );
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+Virtio10MapSharedBuffer (
+  IN     VIRTIO_DEVICE_PROTOCOL  *This,
+  IN     VIRTIO_MAP_OPERATION    Operation,
+  IN     VOID                    *HostAddress,
+  IN OUT UINTN                   *NumberOfBytes,
+  OUT    EFI_PHYSICAL_ADDRESS    *DeviceAddress,
+  OUT    VOID                    **Mapping
+  )
+{
+  EFI_STATUS                    Status;
+  VIRTIO_1_0_DEV                *Dev;
+  EFI_PCI_IO_PROTOCOL_OPERATION PciIoOperation;
+
+  Dev = VIRTIO_1_0_FROM_VIRTIO_DEVICE (This);
+
+  //
+  // Map VIRTIO_MAP_OPERATION to EFI_PCI_IO_PROTOCOL_OPERATION
+  //
+  switch (Operation) {
+  case VirtioOperationBusMasterRead:
+    PciIoOperation = EfiPciIoOperationBusMasterRead;
+    break;
+  case VirtioOperationBusMasterWrite:
+    PciIoOperation = EfiPciIoOperationBusMasterWrite;
+    break;
+  case VirtioOperationBusMasterCommonBuffer:
+    PciIoOperation = EfiPciIoOperationBusMasterCommonBuffer;
+    break;
+  default:
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = Dev->PciIo->Map (
+                         Dev->PciIo,
+                         PciIoOperation,
+                         HostAddress,
+                         NumberOfBytes,
+                         DeviceAddress,
+                         Mapping
+                         );
+  return Status;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+Virtio10UnmapSharedBuffer (
+  IN  VIRTIO_DEVICE_PROTOCOL  *This,
+  IN  VOID                    *Mapping
+  )
+{
+  EFI_STATUS      Status;
+  VIRTIO_1_0_DEV  *Dev;
+
+  Dev = VIRTIO_1_0_FROM_VIRTIO_DEVICE (This);
+
+  Status = Dev->PciIo->Unmap (
+                         Dev->PciIo,
+                         Mapping
+                         );
+
+  return Status;
+}
 
 STATIC CONST VIRTIO_DEVICE_PROTOCOL mVirtIoTemplate = {
   VIRTIO_SPEC_REVISION (1, 0, 0),
@@ -788,7 +901,11 @@ STATIC CONST VIRTIO_DEVICE_PROTOCOL mVirtIoTemplate = {
   Virtio10GetDeviceStatus,
   Virtio10SetDeviceStatus,
   Virtio10WriteDevice,
-  Virtio10ReadDevice
+  Virtio10ReadDevice,
+  Virtio10AllocateSharedPages,
+  Virtio10FreeSharedPages,
+  Virtio10MapSharedBuffer,
+  Virtio10UnmapSharedBuffer
 };
 
 
@@ -906,7 +1023,8 @@ Virtio10BindingStart (
     goto ClosePciIo;
   }
 
-  SetAttributes = EFI_PCI_IO_ATTRIBUTE_BUS_MASTER;
+  SetAttributes = (EFI_PCI_IO_ATTRIBUTE_BUS_MASTER |
+                   EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE);
   UpdateAttributes (&Device->CommonConfig, &SetAttributes);
   UpdateAttributes (&Device->NotifyConfig, &SetAttributes);
   UpdateAttributes (&Device->SpecificConfig, &SetAttributes);
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 03/23] OvmfPkg/VirtioPciDeviceDxe: implement IOMMU-like member functions
  2017-08-23 12:22 [PATCH v3 00/21] OvmfPkg/Virtio: introduce IOMMU-like member functions Brijesh Singh
  2017-08-23 12:22 ` [PATCH v3 01/23] OvmfPkg: introduce IOMMU-like member functions to VIRTIO_DEVICE_PROTOCOL Brijesh Singh
  2017-08-23 12:22 ` [PATCH v3 02/23] OvmfPkg/Virtio10Dxe: implement IOMMU-like member functions Brijesh Singh
@ 2017-08-23 12:22 ` Brijesh Singh
  2017-08-23 19:16   ` Laszlo Ersek
  2017-08-23 12:22 ` [PATCH v3 04/23] OvmfPkg/VirtioMmioDeviceLib: " Brijesh Singh
                   ` (20 subsequent siblings)
  23 siblings, 1 reply; 46+ messages in thread
From: Brijesh Singh @ 2017-08-23 12:22 UTC (permalink / raw)
  To: edk2-devel
  Cc: Brijesh Singh, Ard Biesheuvel, Jordan Justen, Tom Lendacky,
	Laszlo Ersek

The patch implements the newly added IOMMU-like member functions by
respectively delegating the job to:

- VIRTIO_DEVICE_PROTOCOL.AllocateSharedPages () ->
    MemoryAllocationLib.AllocatePages()

- VIRTIO_DEVICE_PROTOCOL.FreeSharedPages () ->
    MemoryAllocationLib.FreePages ()

- VIRTIO_DEVICE_PROTOCOL.MapSharedBuffer () -> no-op

- VIRTIO_DEVICE_PROTOCOL.UnmapSharedBuffer () -> no-op

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>
---
 OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.h    | 34 ++++++++++++
 OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c    |  7 ++-
 OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c | 58 ++++++++++++++++++++
 3 files changed, 98 insertions(+), 1 deletion(-)

diff --git a/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.h b/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.h
index 6f51f816ef0f..41df5a98e560 100644
--- a/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.h
+++ b/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.h
@@ -3,6 +3,7 @@
   Internal definitions for the VirtIo PCI Device driver
 
   Copyright (C) 2013, ARM Ltd
+  Copyright (c) 2017, AMD Inc, All rights reserved.<BR>
 
   This program and the accompanying materials are licensed and made available
   under the terms and conditions of the BSD License which accompanies this
@@ -156,4 +157,37 @@ VirtioPciSetDeviceStatus (
   IN  UINT8                          DeviceStatus
   );
 
+EFI_STATUS
+EFIAPI
+VirtioPciAllocateSharedPages (
+  IN  VIRTIO_DEVICE_PROTOCOL        *This,
+  IN  UINTN                         NumPages,
+  OUT VOID                          **HostAddress
+  );
+
+VOID
+EFIAPI
+VirtioPciFreeSharedPages (
+  IN  VIRTIO_DEVICE_PROTOCOL        *This,
+  IN  UINTN                         NumPages,
+  IN  VOID                          *HostAddress
+  );
+
+EFI_STATUS
+EFIAPI
+VirtioPciMapSharedBuffer (
+  IN      VIRTIO_DEVICE_PROTOCOL        *This,
+  IN      VIRTIO_MAP_OPERATION          Operation,
+  IN      VOID                          *HostAddress,
+  IN OUT  UINTN                         *NumberOfBytes,
+  OUT     EFI_PHYSICAL_ADDRESS          *DeviceAddress,
+  OUT     VOID                          **Mapping
+  );
+
+EFI_STATUS
+EFIAPI
+VirtioPciUnmapSharedBuffer (
+  IN  VIRTIO_DEVICE_PROTOCOL        *This,
+  IN  VOID                          *Mapping
+  );
 #endif // _VIRTIO_PCI_DEVICE_DXE_H_
diff --git a/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c b/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c
index 8aae58e8b482..d4b4ec21c34d 100644
--- a/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c
+++ b/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c
@@ -5,6 +5,7 @@
   Copyright (C) 2012, Red Hat, Inc.
   Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>
   Copyright (C) 2013, ARM Ltd.
+  Copyright (C) 2017, AMD Inc, All rights reserved.<BR>
 
   This program and the accompanying materials are licensed and made available
   under the terms and conditions of the BSD License which accompanies this
@@ -40,7 +41,11 @@ STATIC VIRTIO_DEVICE_PROTOCOL mDeviceProtocolTemplate = {
   VirtioPciGetDeviceStatus,             // GetDeviceStatus
   VirtioPciSetDeviceStatus,             // SetDeviceStatus
   VirtioPciDeviceWrite,                 // WriteDevice
-  VirtioPciDeviceRead                   // ReadDevice
+  VirtioPciDeviceRead,                  // ReadDevice
+  VirtioPciAllocateSharedPages,         // AllocateSharedPages
+  VirtioPciFreeSharedPages,             // FreeSharedPages
+  VirtioPciMapSharedBuffer,             // MapSharedBuffer
+  VirtioPciUnmapSharedBuffer,           // UnmapSharedBuffer
 };
 
 /**
diff --git a/OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c b/OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c
index 5f86914265ea..bd912cca9b29 100644
--- a/OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c
+++ b/OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c
@@ -5,6 +5,7 @@
   Copyright (C) 2012, Red Hat, Inc.
   Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
   Copyright (C) 2013, ARM Ltd.
+  Copyright (C) 2017, AMD Inc, All rights reserved.<BR>
 
   This program and the accompanying materials are licensed and made available
   under the terms and conditions of the BSD License which accompanies this
@@ -271,3 +272,60 @@ VirtioPciSetDeviceStatus (
   return VirtioPciIoWrite (Dev, VIRTIO_PCI_OFFSET_QUEUE_DEVICE_STATUS,
       sizeof (UINT8), DeviceStatus);
 }
+
+EFI_STATUS
+EFIAPI
+VirtioPciAllocateSharedPages (
+  IN  VIRTIO_DEVICE_PROTOCOL  *This,
+  IN  UINTN                   NumPages,
+  OUT VOID                    **HostAddress
+  )
+{
+  VOID        *Buffer;
+
+  Buffer = AllocatePages (NumPages);
+  if (Buffer == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  *HostAddress = Buffer;
+  return EFI_SUCCESS;
+}
+
+VOID
+EFIAPI
+VirtioPciFreeSharedPages (
+  IN  VIRTIO_DEVICE_PROTOCOL  *This,
+  IN  UINTN                   NumPages,
+  IN  VOID                    *HostAddress
+  )
+{
+  FreePages (HostAddress, NumPages);
+}
+
+EFI_STATUS
+EFIAPI
+VirtioPciMapSharedBuffer (
+  IN      VIRTIO_DEVICE_PROTOCOL  *This,
+  IN      VIRTIO_MAP_OPERATION    Operation,
+  IN      VOID                    *HostAddress,
+  IN OUT  UINTN                   *NumberOfBytes,
+  OUT     EFI_PHYSICAL_ADDRESS    *DeviceAddress,
+  OUT     VOID                    **Mapping
+  )
+{
+  *DeviceAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress;
+  *Mapping = NULL;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+VirtioPciUnmapSharedBuffer (
+  IN VIRTIO_DEVICE_PROTOCOL    *This,
+  IN VOID                      *Mapping
+  )
+{
+  return EFI_SUCCESS;
+}
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 04/23] OvmfPkg/VirtioMmioDeviceLib: implement IOMMU-like member functions
  2017-08-23 12:22 [PATCH v3 00/21] OvmfPkg/Virtio: introduce IOMMU-like member functions Brijesh Singh
                   ` (2 preceding siblings ...)
  2017-08-23 12:22 ` [PATCH v3 03/23] OvmfPkg/VirtioPciDeviceDxe: " Brijesh Singh
@ 2017-08-23 12:22 ` Brijesh Singh
  2017-08-23 19:26   ` Laszlo Ersek
  2017-08-23 12:22 ` [PATCH v3 05/23] OvmfPkg/VirtioLib: add VirtioMapAllBytesInSharedBuffer() helper function Brijesh Singh
                   ` (19 subsequent siblings)
  23 siblings, 1 reply; 46+ messages in thread
From: Brijesh Singh @ 2017-08-23 12:22 UTC (permalink / raw)
  To: edk2-devel
  Cc: Brijesh Singh, Ard Biesheuvel, Jordan Justen, Tom Lendacky,
	Laszlo Ersek

The patch implements the newly added IOMMU-like member functions by
respectively delegating the job to:

- VIRTIO_DEVICE_PROTOCOL.AllocateSharedPages () ->
    MemoryAllocationLib.AllocatePages()

- VIRTIO_DEVICE_PROTOCOL.FreeSharedPages () ->
    MemoryAllocationLib.FreePages ()

- VIRTIO_DEVICE_PROTOCOL.MapSharedBuffer () -> no-op

- VIRTIO_DEVICE_PROTOCOL.UnmapSharedBuffer () -> no-op

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>
---
 OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.h          | 36 +++++++++++++
 OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c          |  8 ++-
 OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c | 57 ++++++++++++++++++++
 3 files changed, 99 insertions(+), 2 deletions(-)

diff --git a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.h b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.h
index bedd635e1a86..e5881d537f09 100644
--- a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.h
+++ b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.h
@@ -3,6 +3,7 @@
   Internal definitions for the VirtIo MMIO Device driver
 
   Copyright (C) 2013, ARM Ltd
+  Copyright (C) 2017, AMD Inc. All rights reserved.<BR>
 
   This program and the accompanying materials are licensed and made available
   under the terms and conditions of the BSD License which accompanies this
@@ -25,6 +26,7 @@
 #include <Library/IoLib.h>
 #include <Library/UefiLib.h>
 #include <Library/VirtioMmioDeviceLib.h>
+#include <Library/MemoryAllocationLib.h>
 
 #define VIRTIO_MMIO_DEVICE_SIGNATURE  SIGNATURE_32 ('V', 'M', 'I', 'O')
 
@@ -137,4 +139,38 @@ VirtioMmioSetGuestFeatures (
   IN UINT64                  Features
   );
 
+EFI_STATUS
+EFIAPI
+VirtioMmioAllocateSharedPages (
+  IN  VIRTIO_DEVICE_PROTOCOL        *This,
+  IN  UINTN                         NumPages,
+  OUT VOID                          **HostAddress
+  );
+
+VOID
+EFIAPI
+VirtioMmioFreeSharedPages (
+  IN  VIRTIO_DEVICE_PROTOCOL        *This,
+  IN  UINTN                         NumPages,
+  IN  VOID                          *HostAddress
+  );
+
+EFI_STATUS
+EFIAPI
+VirtioMmioMapSharedBuffer (
+  IN      VIRTIO_DEVICE_PROTOCOL        *This,
+  IN      VIRTIO_MAP_OPERATION          Operation,
+  IN      VOID                          *HostAddress,
+  IN OUT  UINTN                         *NumberOfBytes,
+  OUT     EFI_PHYSICAL_ADDRESS          *DeviceAddress,
+  OUT     VOID                          **Mapping
+  );
+
+EFI_STATUS
+EFIAPI
+VirtioMmioUnmapSharedBuffer (
+  IN  VIRTIO_DEVICE_PROTOCOL        *This,
+  IN  VOID                          *Mapping
+  );
+
 #endif // _VIRTIO_MMIO_DEVICE_INTERNAL_H_
diff --git a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c
index b1d443ea7007..fce934e1e953 100644
--- a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c
+++ b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c
@@ -3,6 +3,7 @@
   This driver produces Virtio Device Protocol instances for Virtio Mmio devices.
 
   Copyright (C) 2013, ARM Ltd.
+  Copyright (C) 2017, AMD Inc. All rights reserved.<BR>
 
   This program and the accompanying materials are licensed and made available
   under the terms and conditions of the BSD License which accompanies this
@@ -15,7 +16,6 @@
 **/
 
 #include <Library/BaseMemoryLib.h>
-#include <Library/MemoryAllocationLib.h>
 #include <Library/UefiBootServicesTableLib.h>
 
 #include "VirtioMmioDevice.h"
@@ -35,7 +35,11 @@ static VIRTIO_DEVICE_PROTOCOL mMmioDeviceProtocolTemplate = {
     VirtioMmioGetDeviceStatus,             // GetDeviceStatus
     VirtioMmioSetDeviceStatus,             // SetDeviceStatus
     VirtioMmioDeviceWrite,                 // WriteDevice
-    VirtioMmioDeviceRead                   // ReadDevice
+    VirtioMmioDeviceRead,                  // ReadDevice
+    VirtioMmioAllocateSharedPages,         // AllocateSharedPages
+    VirtioMmioFreeSharedPages,             // FreeSharedPages
+    VirtioMmioMapSharedBuffer,             // MapSharedBuffer
+    VirtioMmioUnmapSharedBuffer            // UnmapSharedBuffer
 };
 
 /**
diff --git a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c
index 9142d4a162c0..644ec65e1788 100644
--- a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c
+++ b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c
@@ -293,3 +293,60 @@ VirtioMmioDeviceRead (
 
   return EFI_SUCCESS;
 }
+
+EFI_STATUS
+EFIAPI
+VirtioMmioAllocateSharedPages (
+  IN  VIRTIO_DEVICE_PROTOCOL  *This,
+  IN  UINTN                   NumPages,
+  OUT VOID                    **HostAddress
+  )
+{
+  VOID        *Buffer;
+
+  Buffer = AllocatePages (NumPages);
+  if (Buffer == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  *HostAddress = Buffer;
+  return EFI_SUCCESS;
+}
+
+VOID
+EFIAPI
+VirtioMmioFreeSharedPages (
+  IN  VIRTIO_DEVICE_PROTOCOL  *This,
+  IN  UINTN                   NumPages,
+  IN  VOID                    *HostAddress
+  )
+{
+  FreePages (HostAddress, NumPages);
+}
+
+EFI_STATUS
+EFIAPI
+VirtioMmioMapSharedBuffer (
+  IN      VIRTIO_DEVICE_PROTOCOL  *This,
+  IN      VIRTIO_MAP_OPERATION    Operation,
+  IN      VOID                    *HostAddress,
+  IN OUT  UINTN                   *NumberOfBytes,
+  OUT     EFI_PHYSICAL_ADDRESS    *DeviceAddress,
+  OUT     VOID                    **Mapping
+  )
+{
+  *DeviceAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress;
+  *Mapping = NULL;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+VirtioMmioUnmapSharedBuffer (
+  IN VIRTIO_DEVICE_PROTOCOL    *This,
+  IN VOID                      *Mapping
+  )
+{
+  return EFI_SUCCESS;
+}
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 05/23] OvmfPkg/VirtioLib: add VirtioMapAllBytesInSharedBuffer() helper function
  2017-08-23 12:22 [PATCH v3 00/21] OvmfPkg/Virtio: introduce IOMMU-like member functions Brijesh Singh
                   ` (3 preceding siblings ...)
  2017-08-23 12:22 ` [PATCH v3 04/23] OvmfPkg/VirtioMmioDeviceLib: " Brijesh Singh
@ 2017-08-23 12:22 ` Brijesh Singh
  2017-08-23 19:45   ` Laszlo Ersek
  2017-08-23 12:22 ` [PATCH v3 06/23] OvmfPkg/VirtioLib: take VirtIo instance in VirtioRingInit/VirtioRingUninit Brijesh Singh
                   ` (18 subsequent siblings)
  23 siblings, 1 reply; 46+ messages in thread
From: Brijesh Singh @ 2017-08-23 12:22 UTC (permalink / raw)
  To: edk2-devel
  Cc: Brijesh Singh, Ard Biesheuvel, Jordan Justen, Tom Lendacky,
	Laszlo Ersek

The function can be used for mapping the system physical address to virtio
device address using VIRTIO_DEVICE_PROTOCOL.MapSharedBuffer (). The
function helps with centralizing error handling, and it allows the caller
to pass in constant or other evaluated expressions for NumberOfBytes.

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/Include/Library/VirtioLib.h   | 52 ++++++++++++
 OvmfPkg/Library/VirtioLib/VirtioLib.c | 85 ++++++++++++++++++++
 2 files changed, 137 insertions(+)

diff --git a/OvmfPkg/Include/Library/VirtioLib.h b/OvmfPkg/Include/Library/VirtioLib.h
index 5badfb32917f..9ec9b91b59bb 100644
--- a/OvmfPkg/Include/Library/VirtioLib.h
+++ b/OvmfPkg/Include/Library/VirtioLib.h
@@ -3,6 +3,7 @@
   Declarations of utility functions used by virtio device drivers.
 
   Copyright (C) 2012-2016, Red Hat, Inc.
+  Copyright (C) 2017, AMD Inc, All rights reserved.<BR>
 
   This program and the accompanying materials are licensed and made available
   under the terms and conditions of the BSD License which accompanies this
@@ -235,4 +236,55 @@ Virtio10WriteFeatures (
   IN OUT UINT8                  *DeviceStatus
   );
 
+/**
+  Provides the virtio device address required to access system memory from a
+  DMA bus master.
+
+  The interface follows the same usage pattern as defined in UEFI spec 2.6
+  (Section 13.2 PCI Root Bridge I/O Protocol)
+
+  The VirtioMapAllBytesInSharedBuffer() is similar to VIRTIO_MAP_SHARED
+  with exception that NumberOfBytes is IN-only parameter. The function
+  maps all the bytes specified in NumberOfBytes param in one consecutive
+  range.
+
+  @param[in]     This             The virtio device for which the mapping is
+                                  requested.
+
+  @param[in]     Operation        Indicates if the bus master is going to
+                                  read or write to system memory.
+
+  @param[in]     HostAddress      The system memory address to map to shared
+                                  buffer address.
+
+  @param[in]     NumberOfBytes    Number of bytes to map.
+
+  @param[out]    DeviceAddress    The resulting shared map address for the
+                                  bus master to access the hosts HostAddress.
+
+  @param[out]    Mapping          A resulting token to pass to
+                                  VIRTIO_UNMAP_SHARED.
+
+
+  @retval EFI_SUCCESS             The NumberOfBytes is succesfully mapped.
+  @retval EFI_UNSUPPORTED         The HostAddress cannot be mapped as a
+                                  common buffer.
+  @retval EFI_INVALID_PARAMETER   One or more parameters are invalid.
+  @retval EFI_OUT_OF_RESOURCES    The request could not be completed due to
+                                  a lack of resources. This includes the case
+                                  when NumberOfBytes bytes cannot be mapped
+                                  in one consecutive range.
+  @retval EFI_DEVICE_ERROR        The system hardware could not map the
+                                  requested address.
+**/
+EFI_STATUS
+EFIAPI
+VirtioMapAllBytesInSharedBuffer (
+  IN  VIRTIO_DEVICE_PROTOCOL  *VirtIo,
+  IN  VIRTIO_MAP_OPERATION    Operation,
+  IN  VOID                    *HostAddress,
+  IN  UINTN                   NumberOfBytes,
+  OUT EFI_PHYSICAL_ADDRESS    *DeviceAddress,
+  OUT VOID                    **Mapping
+  );
 #endif // _VIRTIO_LIB_H_
diff --git a/OvmfPkg/Library/VirtioLib/VirtioLib.c b/OvmfPkg/Library/VirtioLib/VirtioLib.c
index 845f206369a3..c85cd8dba569 100644
--- a/OvmfPkg/Library/VirtioLib/VirtioLib.c
+++ b/OvmfPkg/Library/VirtioLib/VirtioLib.c
@@ -4,6 +4,7 @@
 
   Copyright (C) 2012-2016, Red Hat, Inc.
   Portion of Copyright (C) 2013, ARM Ltd.
+  Copyright (C) 2017, AMD Inc, All rights reserved.<BR>
 
   This program and the accompanying materials are licensed and made available
   under the terms and conditions of the BSD License which accompanies this
@@ -414,3 +415,87 @@ Virtio10WriteFeatures (
 
   return Status;
 }
+
+/**
+  Provides the virtio device address required to access system memory from a
+  DMA bus master.
+
+  The interface follows the same usage pattern as defined in UEFI spec 2.6
+  (Section 13.2 PCI Root Bridge I/O Protocol)
+
+  The VirtioMapAllBytesInSharedBuffer() is similar to VIRTIO_MAP_SHARED
+  with exception that NumberOfBytes is IN-only parameter. The function
+  maps all the bytes specified in NumberOfBytes param in one consecutive
+  range.
+
+  @param[in]     This             The virtio device for which the mapping is
+                                  requested.
+
+  @param[in]     Operation        Indicates if the bus master is going to
+                                  read or write to system memory.
+
+  @param[in]     HostAddress      The system memory address to map to shared
+                                  buffer address.
+
+  @param[in]     NumberOfBytes    Number of bytes to map.
+
+  @param[out]    DeviceAddress    The resulting shared map address for the
+                                  bus master to access the hosts HostAddress.
+
+  @param[out]    Mapping          A resulting token to pass to
+                                  VIRTIO_UNMAP_SHARED.
+
+
+  @retval EFI_SUCCESS             The NumberOfBytes is succesfully mapped.
+  @retval EFI_UNSUPPORTED         The HostAddress cannot be mapped as a
+                                  common buffer.
+  @retval EFI_INVALID_PARAMETER   One or more parameters are invalid.
+  @retval EFI_OUT_OF_RESOURCES    The request could not be completed due to
+                                  a lack of resources. This includes the case
+                                  when NumberOfBytes bytes cannot be mapped
+                                  in one consecutive range.
+  @retval EFI_DEVICE_ERROR        The system hardware could not map the
+                                  requested address.
+**/
+EFI_STATUS
+EFIAPI
+VirtioMapAllBytesInSharedBuffer (
+  IN  VIRTIO_DEVICE_PROTOCOL  *VirtIo,
+  IN  VIRTIO_MAP_OPERATION    Operation,
+  IN  VOID                    *HostAddress,
+  IN  UINTN                   NumberOfBytes,
+  OUT EFI_PHYSICAL_ADDRESS    *DeviceAddress,
+  OUT VOID                    **Mapping
+  )
+{
+  EFI_STATUS            Status;
+  VOID                  *MapInfo;
+  UINTN                 Size;
+  EFI_PHYSICAL_ADDRESS  PhysicalAddress;
+
+  Size = NumberOfBytes;
+  Status = VirtIo->MapSharedBuffer (
+                     VirtIo,
+                     Operation,
+                     HostAddress,
+                     &Size,
+                     &PhysicalAddress,
+                     &MapInfo
+                     );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  if (Size < NumberOfBytes) {
+    goto Failed;
+  }
+
+  *Mapping = MapInfo;
+  *DeviceAddress = PhysicalAddress;
+
+  return EFI_SUCCESS;
+
+Failed:
+  VirtIo->UnmapSharedBuffer (VirtIo, MapInfo);
+  return EFI_OUT_OF_RESOURCES;
+}
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 06/23] OvmfPkg/VirtioLib: take VirtIo instance in VirtioRingInit/VirtioRingUninit
  2017-08-23 12:22 [PATCH v3 00/21] OvmfPkg/Virtio: introduce IOMMU-like member functions Brijesh Singh
                   ` (4 preceding siblings ...)
  2017-08-23 12:22 ` [PATCH v3 05/23] OvmfPkg/VirtioLib: add VirtioMapAllBytesInSharedBuffer() helper function Brijesh Singh
@ 2017-08-23 12:22 ` Brijesh Singh
  2017-08-23 12:22 ` [PATCH v3 07/23] OvmfPkg/Virtio: take RingBaseShift in SetQueueAddress() Brijesh Singh
                   ` (17 subsequent siblings)
  23 siblings, 0 replies; 46+ messages in thread
From: Brijesh Singh @ 2017-08-23 12:22 UTC (permalink / raw)
  To: edk2-devel
  Cc: Brijesh Singh, Ard Biesheuvel, Jordan Justen, Tom Lendacky,
	Laszlo Ersek

Passing the VirtIo protocol instance will allow the vring to use
VIRTIO_DEVICE_PROTOCOL.AllocateSharedPages () to allocate vring 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>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 OvmfPkg/Include/Library/VirtioLib.h   | 14 ++++++++++----
 OvmfPkg/Library/VirtioLib/VirtioLib.c | 14 ++++++++++----
 OvmfPkg/VirtioBlkDxe/VirtioBlk.c      |  7 ++++---
 OvmfPkg/VirtioGpuDxe/Commands.c       |  7 ++++---
 OvmfPkg/VirtioNetDxe/SnpInitialize.c  |  9 +++++----
 OvmfPkg/VirtioNetDxe/SnpShutdown.c    |  5 +++--
 OvmfPkg/VirtioRngDxe/VirtioRng.c      |  7 ++++---
 OvmfPkg/VirtioScsiDxe/VirtioScsi.c    |  7 ++++---
 8 files changed, 44 insertions(+), 26 deletions(-)

diff --git a/OvmfPkg/Include/Library/VirtioLib.h b/OvmfPkg/Include/Library/VirtioLib.h
index 9ec9b91b59bb..40c51a2b3305 100644
--- a/OvmfPkg/Include/Library/VirtioLib.h
+++ b/OvmfPkg/Include/Library/VirtioLib.h
@@ -35,6 +35,8 @@
   - 1.1 Virtqueues,
   - 2.3 Virtqueue Configuration.
 
+  @param[in]  VirtIo            The virtio device which will use the ring.
+
   @param[in]                    The number of descriptors to allocate for the
                                 virtio ring, as requested by the host.
 
@@ -52,8 +54,9 @@
 EFI_STATUS
 EFIAPI
 VirtioRingInit (
-  IN  UINT16 QueueSize,
-  OUT VRING  *Ring
+  IN  VIRTIO_DEVICE_PROTOCOL *VirtIo,
+  IN  UINT16                 QueueSize,
+  OUT VRING                  *Ring
   );
 
 
@@ -65,13 +68,16 @@ VirtioRingInit (
   invoking this function: the VSTAT_DRIVER_OK bit must be clear in
   VhdrDeviceStatus.
 
-  @param[out] Ring  The virtio ring to clean up.
+  @param[in]  VirtIo  The virtio device which was using the ring.
+
+  @param[out] Ring    The virtio ring to clean up.
 
 **/
 VOID
 EFIAPI
 VirtioRingUninit (
-  IN OUT VRING *Ring
+  IN     VIRTIO_DEVICE_PROTOCOL *VirtIo,
+  IN OUT VRING                  *Ring
   );
 
 
diff --git a/OvmfPkg/Library/VirtioLib/VirtioLib.c b/OvmfPkg/Library/VirtioLib/VirtioLib.c
index c85cd8dba569..8bc5b9aea4fc 100644
--- a/OvmfPkg/Library/VirtioLib/VirtioLib.c
+++ b/OvmfPkg/Library/VirtioLib/VirtioLib.c
@@ -37,6 +37,8 @@
   - 1.1 Virtqueues,
   - 2.3 Virtqueue Configuration.
 
+  @param[in]  VirtIo            The virtio device which will use the ring.
+
   @param[in]                    The number of descriptors to allocate for the
                                 virtio ring, as requested by the host.
 
@@ -54,8 +56,9 @@
 EFI_STATUS
 EFIAPI
 VirtioRingInit (
-  IN  UINT16 QueueSize,
-  OUT VRING  *Ring
+  IN  VIRTIO_DEVICE_PROTOCOL *VirtIo,
+  IN  UINT16                 QueueSize,
+  OUT VRING                  *Ring
   )
 {
   UINTN          RingSize;
@@ -128,13 +131,16 @@ VirtioRingInit (
   invoking this function: the VSTAT_DRIVER_OK bit must be clear in
   VhdrDeviceStatus.
 
-  @param[out] Ring  The virtio ring to clean up.
+  @param[in]  VirtIo  The virtio device which was using the ring.
+
+  @param[out] Ring    The virtio ring to clean up.
 
 **/
 VOID
 EFIAPI
 VirtioRingUninit (
-  IN OUT VRING *Ring
+  IN     VIRTIO_DEVICE_PROTOCOL *VirtIo,
+  IN OUT VRING                  *Ring
   )
 {
   FreePages (Ring->Base, Ring->NumPages);
diff --git a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
index 3ce72281c204..61b9cab4ff02 100644
--- a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
+++ b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
@@ -12,6 +12,7 @@
 
   Copyright (C) 2012, Red Hat, Inc.
   Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2017, AMD Inc, All rights reserved.<BR>
 
   This program and the accompanying materials are licensed and made available
   under the terms and conditions of the BSD License which accompanies this
@@ -722,7 +723,7 @@ VirtioBlkInit (
     goto Failed;
   }
 
-  Status = VirtioRingInit (QueueSize, &Dev->Ring);
+  Status = VirtioRingInit (Dev->VirtIo, QueueSize, &Dev->Ring);
   if (EFI_ERROR (Status)) {
     goto Failed;
   }
@@ -811,7 +812,7 @@ VirtioBlkInit (
   return EFI_SUCCESS;
 
 ReleaseQueue:
-  VirtioRingUninit (&Dev->Ring);
+  VirtioRingUninit (Dev->VirtIo, &Dev->Ring);
 
 Failed:
   //
@@ -848,7 +849,7 @@ VirtioBlkUninit (
   //
   Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
 
-  VirtioRingUninit (&Dev->Ring);
+  VirtioRingUninit (Dev->VirtIo, &Dev->Ring);
 
   SetMem (&Dev->BlockIo,      sizeof Dev->BlockIo,      0x00);
   SetMem (&Dev->BlockIoMedia, sizeof Dev->BlockIoMedia, 0x00);
diff --git a/OvmfPkg/VirtioGpuDxe/Commands.c b/OvmfPkg/VirtioGpuDxe/Commands.c
index 962087cfec97..c2e4d72feb67 100644
--- a/OvmfPkg/VirtioGpuDxe/Commands.c
+++ b/OvmfPkg/VirtioGpuDxe/Commands.c
@@ -3,6 +3,7 @@
   VirtIo GPU initialization, and commands (primitives) for the GPU device.
 
   Copyright (C) 2016, Red Hat, Inc.
+  Copyright (c) 2017, AMD Inc, All rights reserved.<BR>
 
   This program and the accompanying materials are licensed and made available
   under the terms and conditions of the BSD License which accompanies this
@@ -127,7 +128,7 @@ VirtioGpuInit (
   //
   // [...] population of virtqueues [...]
   //
-  Status = VirtioRingInit (QueueSize, &VgpuDev->Ring);
+  Status = VirtioRingInit (VgpuDev->VirtIo, QueueSize, &VgpuDev->Ring);
   if (EFI_ERROR (Status)) {
     goto Failed;
   }
@@ -148,7 +149,7 @@ VirtioGpuInit (
   return EFI_SUCCESS;
 
 ReleaseQueue:
-  VirtioRingUninit (&VgpuDev->Ring);
+  VirtioRingUninit (VgpuDev->VirtIo, &VgpuDev->Ring);
 
 Failed:
   //
@@ -183,7 +184,7 @@ VirtioGpuUninit (
   // configuration.
   //
   VgpuDev->VirtIo->SetDeviceStatus (VgpuDev->VirtIo, 0);
-  VirtioRingUninit (&VgpuDev->Ring);
+  VirtioRingUninit (VgpuDev->VirtIo, &VgpuDev->Ring);
 }
 
 /**
diff --git a/OvmfPkg/VirtioNetDxe/SnpInitialize.c b/OvmfPkg/VirtioNetDxe/SnpInitialize.c
index 430670a980f2..6d9b81a9f939 100644
--- a/OvmfPkg/VirtioNetDxe/SnpInitialize.c
+++ b/OvmfPkg/VirtioNetDxe/SnpInitialize.c
@@ -5,6 +5,7 @@
 
   Copyright (C) 2013, Red Hat, Inc.
   Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2017, AMD Inc, All rights reserved.<BR>
 
   This program and the accompanying materials are licensed and made available
   under the terms and conditions of the BSD License which accompanies this
@@ -73,7 +74,7 @@ VirtioNetInitRing (
   if (QueueSize < 2) {
     return EFI_UNSUPPORTED;
   }
-  Status = VirtioRingInit (QueueSize, Ring);
+  Status = VirtioRingInit (Dev->VirtIo, QueueSize, Ring);
   if (EFI_ERROR (Status)) {
     return Status;
   }
@@ -103,7 +104,7 @@ VirtioNetInitRing (
   return EFI_SUCCESS;
 
 ReleaseQueue:
-  VirtioRingUninit (Ring);
+  VirtioRingUninit (Dev->VirtIo, Ring);
 
   return Status;
 }
@@ -509,10 +510,10 @@ AbortDevice:
   Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
 
 ReleaseTxRing:
-  VirtioRingUninit (&Dev->TxRing);
+  VirtioRingUninit (Dev->VirtIo, &Dev->TxRing);
 
 ReleaseRxRing:
-  VirtioRingUninit (&Dev->RxRing);
+  VirtioRingUninit (Dev->VirtIo, &Dev->RxRing);
 
 DeviceFailed:
   //
diff --git a/OvmfPkg/VirtioNetDxe/SnpShutdown.c b/OvmfPkg/VirtioNetDxe/SnpShutdown.c
index 01409c0ce714..5e84191fbbdd 100644
--- a/OvmfPkg/VirtioNetDxe/SnpShutdown.c
+++ b/OvmfPkg/VirtioNetDxe/SnpShutdown.c
@@ -4,6 +4,7 @@
 
   Copyright (C) 2013, Red Hat, Inc.
   Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2017, AMD Inc, All rights reserved.<BR>
 
   This program and the accompanying materials are licensed and made available
   under the terms and conditions of the BSD License which accompanies this
@@ -66,8 +67,8 @@ VirtioNetShutdown (
   Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
   VirtioNetShutdownRx (Dev);
   VirtioNetShutdownTx (Dev);
-  VirtioRingUninit (&Dev->TxRing);
-  VirtioRingUninit (&Dev->RxRing);
+  VirtioRingUninit (Dev->VirtIo, &Dev->TxRing);
+  VirtioRingUninit (Dev->VirtIo, &Dev->RxRing);
 
   Dev->Snm.State = EfiSimpleNetworkStarted;
   Status = EFI_SUCCESS;
diff --git a/OvmfPkg/VirtioRngDxe/VirtioRng.c b/OvmfPkg/VirtioRngDxe/VirtioRng.c
index 1a186d04082a..e20602ac7225 100644
--- a/OvmfPkg/VirtioRngDxe/VirtioRng.c
+++ b/OvmfPkg/VirtioRngDxe/VirtioRng.c
@@ -6,6 +6,7 @@
 
   Copyright (C) 2012, Red Hat, Inc.
   Copyright (c) 2012 - 2014, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2017, AMD Inc, All rights reserved.<BR>
 
   This driver:
 
@@ -275,7 +276,7 @@ VirtioRngInit (
     goto Failed;
   }
 
-  Status = VirtioRingInit (QueueSize, &Dev->Ring);
+  Status = VirtioRingInit (Dev->VirtIo, QueueSize, &Dev->Ring);
   if (EFI_ERROR (Status)) {
     goto Failed;
   }
@@ -331,7 +332,7 @@ VirtioRngInit (
   return EFI_SUCCESS;
 
 ReleaseQueue:
-  VirtioRingUninit (&Dev->Ring);
+  VirtioRingUninit (Dev->VirtIo, &Dev->Ring);
 
 Failed:
   //
@@ -358,7 +359,7 @@ VirtioRngUninit (
   // the old comms area.
   //
   Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
-  VirtioRingUninit (&Dev->Ring);
+  VirtioRingUninit (Dev->VirtIo, &Dev->Ring);
 }
 
 //
diff --git a/OvmfPkg/VirtioScsiDxe/VirtioScsi.c b/OvmfPkg/VirtioScsiDxe/VirtioScsi.c
index c080404330e5..c2f6f412ff40 100644
--- a/OvmfPkg/VirtioScsiDxe/VirtioScsi.c
+++ b/OvmfPkg/VirtioScsiDxe/VirtioScsi.c
@@ -27,6 +27,7 @@
 
   Copyright (C) 2012, Red Hat, Inc.
   Copyright (c) 2012 - 2014, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2017, AMD Inc, All rights reserved.<BR>
 
   This program and the accompanying materials are licensed and made available
   under the terms and conditions of the BSD License which accompanies this
@@ -832,7 +833,7 @@ VirtioScsiInit (
     goto Failed;
   }
 
-  Status = VirtioRingInit (QueueSize, &Dev->Ring);
+  Status = VirtioRingInit (Dev->VirtIo, QueueSize, &Dev->Ring);
   if (EFI_ERROR (Status)) {
     goto Failed;
   }
@@ -926,7 +927,7 @@ VirtioScsiInit (
   return EFI_SUCCESS;
 
 ReleaseQueue:
-  VirtioRingUninit (&Dev->Ring);
+  VirtioRingUninit (Dev->VirtIo, &Dev->Ring);
 
 Failed:
   //
@@ -964,7 +965,7 @@ VirtioScsiUninit (
   Dev->MaxLun         = 0;
   Dev->MaxSectors     = 0;
 
-  VirtioRingUninit (&Dev->Ring);
+  VirtioRingUninit (Dev->VirtIo, &Dev->Ring);
 
   SetMem (&Dev->PassThru,     sizeof Dev->PassThru,     0x00);
   SetMem (&Dev->PassThruMode, sizeof Dev->PassThruMode, 0x00);
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 07/23] OvmfPkg/Virtio: take RingBaseShift in SetQueueAddress()
  2017-08-23 12:22 [PATCH v3 00/21] OvmfPkg/Virtio: introduce IOMMU-like member functions Brijesh Singh
                   ` (5 preceding siblings ...)
  2017-08-23 12:22 ` [PATCH v3 06/23] OvmfPkg/VirtioLib: take VirtIo instance in VirtioRingInit/VirtioRingUninit Brijesh Singh
@ 2017-08-23 12:22 ` Brijesh Singh
  2017-08-23 20:41   ` Laszlo Ersek
  2017-08-23 12:22 ` [PATCH v3 08/23] OvmfPkg/Virtio10Dxe: add the RingBaseShift offset Brijesh Singh
                   ` (16 subsequent siblings)
  23 siblings, 1 reply; 46+ messages in thread
From: Brijesh Singh @ 2017-08-23 12:22 UTC (permalink / raw)
  To: edk2-devel
  Cc: Brijesh Singh, Ard Biesheuvel, Jordan Justen, Tom Lendacky,
	Laszlo Ersek

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.

VirtioRingMap() maps the ring buffer system physical to a bus address.
When an IOMMU is used for translating the address then bus address can
start at a different offset from the system physical address.

- 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>
---
 OvmfPkg/Include/Protocol/VirtioDevice.h                         | 19 +++++++++++++++++--
 OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.h          |  3 ++-
 OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.h                    |  3 ++-
 OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c |  5 ++++-
 OvmfPkg/Virtio10Dxe/Virtio10.c                                  |  5 ++++-
 OvmfPkg/VirtioBlkDxe/VirtioBlk.c                                |  2 +-
 OvmfPkg/VirtioGpuDxe/Commands.c                                 |  6 +++++-
 OvmfPkg/VirtioNetDxe/SnpInitialize.c                            |  2 +-
 OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c                 |  5 ++++-
 OvmfPkg/VirtioRngDxe/VirtioRng.c                                |  2 +-
 OvmfPkg/VirtioScsiDxe/VirtioScsi.c                              |  2 +-
 11 files changed, 42 insertions(+), 12 deletions(-)

diff --git a/OvmfPkg/Include/Protocol/VirtioDevice.h b/OvmfPkg/Include/Protocol/VirtioDevice.h
index 9a01932958a2..2e3a6d6edf04 100644
--- a/OvmfPkg/Include/Protocol/VirtioDevice.h
+++ b/OvmfPkg/Include/Protocol/VirtioDevice.h
@@ -156,7 +156,21 @@ EFI_STATUS
   @param[in] This             This instance of VIRTIO_DEVICE_PROTOCOL
 
   @param[in] Ring             The initialized VRING object to take the
-                              addresses from.
+                              addresses from. The caller is responsible for
+                              ensuring that on input, all Ring->NumPages pages,
+                              starting at Ring->Base, have been successfully
+                              mapped with a single call to
+                              This->MapSharedBuffer() for CommonBuffer bus
+                              master operation..
+
+  @param[in] RingBaseShift    Adding this value using UINT64 arithmetic to the
+                              addresses found in Ring translates them from
+                              system memory to bus addresses. The caller shall
+                              calculate RingBaseShift as
+                              (DeviceAddress - (UINT64)(UINTN)HostAddress),
+                              where DeviceAddress and HostAddress (i.e.,
+                              Ring->Base) were output and input parameters of
+                              This->MapSharedBuffer(), respectively.
 
   @retval EFI_SUCCESS         The data was written successfully.
   @retval EFI_UNSUPPORTED     The underlying IO device doesn't support the
@@ -166,7 +180,8 @@ typedef
 EFI_STATUS
 (EFIAPI *VIRTIO_SET_QUEUE_ADDRESS) (
   IN VIRTIO_DEVICE_PROTOCOL  *This,
-  IN VRING                   *Ring
+  IN VRING                   *Ring,
+  IN UINT64                  RingBaseShift
   );
 
 /**
diff --git a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.h b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.h
index e5881d537f09..e6279159f8ba 100644
--- a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.h
+++ b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.h
@@ -115,7 +115,8 @@ VirtioMmioSetQueueSel (
 EFI_STATUS
 VirtioMmioSetQueueAddress (
   IN VIRTIO_DEVICE_PROTOCOL  *This,
-  IN VRING                   *Ring
+  IN VRING                   *Ring,
+  IN UINT64                  RingBaseShift
   );
 
 EFI_STATUS
diff --git a/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.h b/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.h
index 41df5a98e560..1f0dc45d501e 100644
--- a/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.h
+++ b/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.h
@@ -126,7 +126,8 @@ EFI_STATUS
 EFIAPI
 VirtioPciSetQueueAddress (
   IN VIRTIO_DEVICE_PROTOCOL  *This,
-  IN VRING                   *Ring
+  IN VRING                   *Ring,
+  IN UINT64                  RingBaseShift
   );
 
 EFI_STATUS
diff --git a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c
index 644ec65e1788..67458e56231b 100644
--- a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c
+++ b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c
@@ -181,11 +181,14 @@ VirtioMmioSetQueueSel (
 EFI_STATUS
 VirtioMmioSetQueueAddress (
   IN VIRTIO_DEVICE_PROTOCOL  *This,
-  IN VRING                   *Ring
+  IN VRING                   *Ring,
+  IN UINT64                  RingBaseShift
   )
 {
   VIRTIO_MMIO_DEVICE *Device;
 
+  ASSERT (RingBaseShift == 0);
+
   Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
 
   VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_PFN,
diff --git a/OvmfPkg/Virtio10Dxe/Virtio10.c b/OvmfPkg/Virtio10Dxe/Virtio10.c
index 89ccac8c1c04..ef9a00710668 100644
--- a/OvmfPkg/Virtio10Dxe/Virtio10.c
+++ b/OvmfPkg/Virtio10Dxe/Virtio10.c
@@ -489,7 +489,8 @@ EFI_STATUS
 EFIAPI
 Virtio10SetQueueAddress (
   IN VIRTIO_DEVICE_PROTOCOL  *This,
-  IN VRING                   *Ring
+  IN VRING                   *Ring,
+  IN UINT64                  RingBaseShift
   )
 {
   VIRTIO_1_0_DEV *Dev;
@@ -497,6 +498,8 @@ Virtio10SetQueueAddress (
   UINT64         Address;
   UINT16         Enable;
 
+  ASSERT (RingBaseShift == 0);
+
   Dev = VIRTIO_1_0_FROM_VIRTIO_DEVICE (This);
 
   Address = (UINTN)Ring->Desc;
diff --git a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
index 61b9cab4ff02..bff15fe3add1 100644
--- a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
+++ b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
@@ -745,7 +745,7 @@ VirtioBlkInit (
   //
   // step 4c -- Report GPFN (guest-physical frame number) of queue.
   //
-  Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, &Dev->Ring);
+  Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, &Dev->Ring, 0);
   if (EFI_ERROR (Status)) {
     goto ReleaseQueue;
   }
diff --git a/OvmfPkg/VirtioGpuDxe/Commands.c b/OvmfPkg/VirtioGpuDxe/Commands.c
index c2e4d72feb67..5cb003161207 100644
--- a/OvmfPkg/VirtioGpuDxe/Commands.c
+++ b/OvmfPkg/VirtioGpuDxe/Commands.c
@@ -132,7 +132,11 @@ VirtioGpuInit (
   if (EFI_ERROR (Status)) {
     goto Failed;
   }
-  Status = VgpuDev->VirtIo->SetQueueAddress (VgpuDev->VirtIo, &VgpuDev->Ring);
+  Status = VgpuDev->VirtIo->SetQueueAddress (
+                              VgpuDev->VirtIo,
+                              &VgpuDev->Ring,
+                              0
+                              );
   if (EFI_ERROR (Status)) {
     goto ReleaseQueue;
   }
diff --git a/OvmfPkg/VirtioNetDxe/SnpInitialize.c b/OvmfPkg/VirtioNetDxe/SnpInitialize.c
index 6d9b81a9f939..0ecfe044a977 100644
--- a/OvmfPkg/VirtioNetDxe/SnpInitialize.c
+++ b/OvmfPkg/VirtioNetDxe/SnpInitialize.c
@@ -96,7 +96,7 @@ VirtioNetInitRing (
   //
   // step 4c -- report GPFN (guest-physical frame number) of queue
   //
-  Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, Ring);
+  Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, Ring, 0);
   if (EFI_ERROR (Status)) {
     goto ReleaseQueue;
   }
diff --git a/OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c b/OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c
index bd912cca9b29..b52060d13d97 100644
--- a/OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c
+++ b/OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c
@@ -183,11 +183,14 @@ EFI_STATUS
 EFIAPI
 VirtioPciSetQueueAddress (
   IN VIRTIO_DEVICE_PROTOCOL  *This,
-  IN VRING                   *Ring
+  IN VRING                   *Ring,
+  IN UINT64                  RingBaseShift
   )
 {
   VIRTIO_PCI_DEVICE *Dev;
 
+  ASSERT (RingBaseShift == 0);
+
   Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);
 
   return VirtioPciIoWrite (Dev, VIRTIO_PCI_OFFSET_QUEUE_ADDRESS, sizeof (UINT32),
diff --git a/OvmfPkg/VirtioRngDxe/VirtioRng.c b/OvmfPkg/VirtioRngDxe/VirtioRng.c
index e20602ac7225..0abca488e6cd 100644
--- a/OvmfPkg/VirtioRngDxe/VirtioRng.c
+++ b/OvmfPkg/VirtioRngDxe/VirtioRng.c
@@ -298,7 +298,7 @@ VirtioRngInit (
   //
   // step 4c -- Report GPFN (guest-physical frame number) of queue.
   //
-  Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, &Dev->Ring);
+  Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, &Dev->Ring, 0);
   if (EFI_ERROR (Status)) {
     goto ReleaseQueue;
   }
diff --git a/OvmfPkg/VirtioScsiDxe/VirtioScsi.c b/OvmfPkg/VirtioScsiDxe/VirtioScsi.c
index c2f6f412ff40..a983b3df7b9c 100644
--- a/OvmfPkg/VirtioScsiDxe/VirtioScsi.c
+++ b/OvmfPkg/VirtioScsiDxe/VirtioScsi.c
@@ -855,7 +855,7 @@ VirtioScsiInit (
   //
   // step 4c -- Report GPFN (guest-physical frame number) of queue.
   //
-  Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, &Dev->Ring);
+  Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, &Dev->Ring, 0);
   if (EFI_ERROR (Status)) {
     goto ReleaseQueue;
   }
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 08/23] OvmfPkg/Virtio10Dxe: add the RingBaseShift offset
  2017-08-23 12:22 [PATCH v3 00/21] OvmfPkg/Virtio: introduce IOMMU-like member functions Brijesh Singh
                   ` (6 preceding siblings ...)
  2017-08-23 12:22 ` [PATCH v3 07/23] OvmfPkg/Virtio: take RingBaseShift in SetQueueAddress() Brijesh Singh
@ 2017-08-23 12:22 ` Brijesh Singh
  2017-08-23 20:51   ` Laszlo Ersek
  2017-08-23 12:22 ` [PATCH v3 09/23] OvmfPkg/VirtioLib: add function to map VRING Brijesh Singh
                   ` (15 subsequent siblings)
  23 siblings, 1 reply; 46+ messages in thread
From: Brijesh Singh @ 2017-08-23 12:22 UTC (permalink / raw)
  To: edk2-devel
  Cc: Brijesh Singh, Ard Biesheuvel, Jordan Justen, Tom Lendacky,
	Laszlo Ersek

virtio drivers use VIRTIO_DEVICE_PROTOCOL.MapSharedBuffer() to map the
ring buffer host address to a device address. If an IOMMU is present then
RingBaseShift contains the offset from the host address.

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>
---
 OvmfPkg/Virtio10Dxe/Virtio10.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/OvmfPkg/Virtio10Dxe/Virtio10.c b/OvmfPkg/Virtio10Dxe/Virtio10.c
index ef9a00710668..e9b50b6e437b 100644
--- a/OvmfPkg/Virtio10Dxe/Virtio10.c
+++ b/OvmfPkg/Virtio10Dxe/Virtio10.c
@@ -498,11 +498,10 @@ Virtio10SetQueueAddress (
   UINT64         Address;
   UINT16         Enable;
 
-  ASSERT (RingBaseShift == 0);
-
   Dev = VIRTIO_1_0_FROM_VIRTIO_DEVICE (This);
 
   Address = (UINTN)Ring->Desc;
+  Address += RingBaseShift;
   Status = Virtio10Transfer (Dev->PciIo, &Dev->CommonConfig, TRUE,
              OFFSET_OF (VIRTIO_PCI_COMMON_CFG, QueueDesc),
              sizeof Address, &Address);
@@ -511,6 +510,7 @@ Virtio10SetQueueAddress (
   }
 
   Address = (UINTN)Ring->Avail.Flags;
+  Address += RingBaseShift;
   Status = Virtio10Transfer (Dev->PciIo, &Dev->CommonConfig, TRUE,
              OFFSET_OF (VIRTIO_PCI_COMMON_CFG, QueueAvail),
              sizeof Address, &Address);
@@ -519,6 +519,7 @@ Virtio10SetQueueAddress (
   }
 
   Address = (UINTN)Ring->Used.Flags;
+  Address += RingBaseShift;
   Status = Virtio10Transfer (Dev->PciIo, &Dev->CommonConfig, TRUE,
              OFFSET_OF (VIRTIO_PCI_COMMON_CFG, QueueUsed),
              sizeof Address, &Address);
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 09/23] OvmfPkg/VirtioLib: add function to map VRING
  2017-08-23 12:22 [PATCH v3 00/21] OvmfPkg/Virtio: introduce IOMMU-like member functions Brijesh Singh
                   ` (7 preceding siblings ...)
  2017-08-23 12:22 ` [PATCH v3 08/23] OvmfPkg/Virtio10Dxe: add the RingBaseShift offset Brijesh Singh
@ 2017-08-23 12:22 ` Brijesh Singh
  2017-08-23 20:10   ` Laszlo Ersek
  2017-08-23 12:22 ` [PATCH v3 10/23] OvmfPkg/VirtioLib: alloc VRING buffer with AllocateSharedPages() Brijesh Singh
                   ` (14 subsequent siblings)
  23 siblings, 1 reply; 46+ messages in thread
From: Brijesh Singh @ 2017-08-23 12:22 UTC (permalink / raw)
  To: edk2-devel
  Cc: Brijesh Singh, Ard Biesheuvel, Jordan Justen, Tom Lendacky,
	Laszlo Ersek

Add functions to map the ring buffer with BusMasterCommonBuffer so that
ring can be accessed by both guest and hypervisor.

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/Include/Library/VirtioLib.h   | 26 +++++++++++
 OvmfPkg/Library/VirtioLib/VirtioLib.c | 45 ++++++++++++++++++++
 2 files changed, 71 insertions(+)

diff --git a/OvmfPkg/Include/Library/VirtioLib.h b/OvmfPkg/Include/Library/VirtioLib.h
index 40c51a2b3305..3d9314b3acaf 100644
--- a/OvmfPkg/Include/Library/VirtioLib.h
+++ b/OvmfPkg/Include/Library/VirtioLib.h
@@ -62,6 +62,32 @@ VirtioRingInit (
 
 /**
 
+  Map the ring buffer so that it can be accessed equally by both guest
+  and hypervisor.
+
+  @param[in]      VirtIo          The virtio device instance.
+
+  @param[in]      Ring            The virtio ring to map.
+
+  @param[out]     RingBaseShift   A resulting translation offset, to be
+                                  passed to VirtIo->SetQueueAddress().
+
+  @param[out]     Mapping         A resulting token to pass to
+                                  VirtIo->UnmapSharedBuffer().
+
+  @return         Status code from VirtIo->MapSharedBuffer()
+**/
+EFI_STATUS
+EFIAPI
+VirtioRingMap (
+  IN  VIRTIO_DEVICE_PROTOCOL *VirtIo,
+  IN  VRING                  *Ring,
+  OUT UINT64                 *RingBaseShift,
+  OUT VOID                   **Mapping
+  );
+
+/**
+
   Tear down the internal resources of a configured virtio ring.
 
   The caller is responsible to stop the host from using this ring before
diff --git a/OvmfPkg/Library/VirtioLib/VirtioLib.c b/OvmfPkg/Library/VirtioLib/VirtioLib.c
index 8bc5b9aea4fc..535635ac0ba8 100644
--- a/OvmfPkg/Library/VirtioLib/VirtioLib.c
+++ b/OvmfPkg/Library/VirtioLib/VirtioLib.c
@@ -505,3 +505,48 @@ Failed:
   VirtIo->UnmapSharedBuffer (VirtIo, MapInfo);
   return EFI_OUT_OF_RESOURCES;
 }
+
+/**
+
+  Map the ring buffer so that it can be accessed equally by both guest
+  and hypervisor.
+
+  @param[in]      VirtIo          The virtio device instance.
+
+  @param[in]      Ring            The virtio ring to map.
+
+  @param[out]     RingBaseShift   A resulting translation offset, to be
+                                  passed to VirtIo->SetQueueAddress().
+
+  @param[out]     Mapping         A resulting token to pass to
+                                  VirtIo->UnmapSharedBuffer().
+
+  @return         Status code from VirtIo->MapSharedBuffer()
+**/
+EFI_STATUS
+EFIAPI
+VirtioRingMap (
+  IN  VIRTIO_DEVICE_PROTOCOL *VirtIo,
+  IN  VRING                  *Ring,
+  OUT UINT64                 *RingBaseShift,
+  OUT VOID                   **Mapping
+  )
+{
+  EFI_STATUS            Status;
+  EFI_PHYSICAL_ADDRESS  DeviceAddress;
+
+  Status = VirtioMapAllBytesInSharedBuffer (
+             VirtIo,
+             VirtioOperationBusMasterCommonBuffer,
+             Ring->Base,
+             EFI_PAGES_TO_SIZE (Ring->NumPages),
+             &DeviceAddress,
+             Mapping
+             );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  *RingBaseShift = DeviceAddress - (UINT64)(UINTN)Ring->Base;
+  return EFI_SUCCESS;
+}
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 10/23] OvmfPkg/VirtioLib: alloc VRING buffer with AllocateSharedPages()
  2017-08-23 12:22 [PATCH v3 00/21] OvmfPkg/Virtio: introduce IOMMU-like member functions Brijesh Singh
                   ` (8 preceding siblings ...)
  2017-08-23 12:22 ` [PATCH v3 09/23] OvmfPkg/VirtioLib: add function to map VRING Brijesh Singh
@ 2017-08-23 12:22 ` Brijesh Singh
  2017-08-23 21:18   ` Laszlo Ersek
  2017-08-23 12:22 ` [PATCH v3 11/23] OvmfPkg/VirtioLib: change the parameter of VirtioAppendDesc() to UINT64 Brijesh Singh
                   ` (13 subsequent siblings)
  23 siblings, 1 reply; 46+ messages in thread
From: Brijesh Singh @ 2017-08-23 12:22 UTC (permalink / raw)
  To: edk2-devel
  Cc: Brijesh Singh, Ard Biesheuvel, Jordan Justen, Tom Lendacky,
	Laszlo Ersek

The VRING buffer is a communication area between guest and hypervisor.
Allocate it using VIRTIO_DEVICE_PROTOCOL.AllocateSharedPages() so that
it can be mapped later with VirtioRingMap() for bi-directional access.

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/Library/VirtioLib/VirtioLib.inf |  1 -
 OvmfPkg/Include/Library/VirtioLib.h     |  5 ++---
 OvmfPkg/Library/VirtioLib/VirtioLib.c   | 22 +++++++++++++-------
 3 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/OvmfPkg/Library/VirtioLib/VirtioLib.inf b/OvmfPkg/Library/VirtioLib/VirtioLib.inf
index fb5897a88ecf..e33856de38c4 100644
--- a/OvmfPkg/Library/VirtioLib/VirtioLib.inf
+++ b/OvmfPkg/Library/VirtioLib/VirtioLib.inf
@@ -32,5 +32,4 @@ [LibraryClasses]
   BaseLib
   BaseMemoryLib
   DebugLib
-  MemoryAllocationLib
   UefiBootServicesTableLib
diff --git a/OvmfPkg/Include/Library/VirtioLib.h b/OvmfPkg/Include/Library/VirtioLib.h
index 3d9314b3acaf..c3e56ea23b89 100644
--- a/OvmfPkg/Include/Library/VirtioLib.h
+++ b/OvmfPkg/Include/Library/VirtioLib.h
@@ -42,9 +42,8 @@
 
   @param[out] Ring              The virtio ring to set up.
 
-  @retval EFI_OUT_OF_RESOURCES  AllocatePages() failed to allocate contiguous
-                                pages for the requested QueueSize. Fields of
-                                Ring have indeterminate value.
+  @retval                       Status codes propagated from
+                                VirtIo->AllocateSharedPages().
 
   @retval EFI_SUCCESS           Allocation and setup successful. Ring->Base
                                 (and nothing else) is responsible for
diff --git a/OvmfPkg/Library/VirtioLib/VirtioLib.c b/OvmfPkg/Library/VirtioLib/VirtioLib.c
index 535635ac0ba8..e5366e385f5d 100644
--- a/OvmfPkg/Library/VirtioLib/VirtioLib.c
+++ b/OvmfPkg/Library/VirtioLib/VirtioLib.c
@@ -19,7 +19,6 @@
 #include <Library/BaseLib.h>
 #include <Library/BaseMemoryLib.h>
 #include <Library/DebugLib.h>
-#include <Library/MemoryAllocationLib.h>
 #include <Library/UefiBootServicesTableLib.h>
 
 #include <Library/VirtioLib.h>
@@ -44,9 +43,8 @@
 
   @param[out] Ring              The virtio ring to set up.
 
-  @retval EFI_OUT_OF_RESOURCES  AllocatePages() failed to allocate contiguous
-                                pages for the requested QueueSize. Fields of
-                                Ring have indeterminate value.
+  @retval                       Status codes propagated from
+                                VirtIo->AllocateSharedPages().
 
   @retval EFI_SUCCESS           Allocation and setup successful. Ring->Base
                                 (and nothing else) is responsible for
@@ -61,6 +59,7 @@ VirtioRingInit (
   OUT VRING                  *Ring
   )
 {
+  EFI_STATUS     Status;
   UINTN          RingSize;
   volatile UINT8 *RingPagesPtr;
 
@@ -79,10 +78,17 @@ VirtioRingInit (
                 sizeof *Ring->Used.AvailEvent,
                 EFI_PAGE_SIZE);
 
+  //
+  // Allocate a shared ring buffer
+  //
   Ring->NumPages = EFI_SIZE_TO_PAGES (RingSize);
-  Ring->Base = AllocatePages (Ring->NumPages);
-  if (Ring->Base == NULL) {
-    return EFI_OUT_OF_RESOURCES;
+  Status = VirtIo->AllocateSharedPages (
+                     VirtIo,
+                     Ring->NumPages,
+                     &Ring->Base
+                     );
+  if (EFI_ERROR (Status)) {
+    return Status;
   }
   SetMem (Ring->Base, RingSize, 0x00);
   RingPagesPtr = Ring->Base;
@@ -143,7 +149,7 @@ VirtioRingUninit (
   IN OUT VRING                  *Ring
   )
 {
-  FreePages (Ring->Base, Ring->NumPages);
+  VirtIo->FreeSharedPages (VirtIo, Ring->NumPages, Ring->Base);
   SetMem (Ring, sizeof *Ring, 0x00);
 }
 
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 11/23] OvmfPkg/VirtioLib: change the parameter of VirtioAppendDesc() to UINT64
  2017-08-23 12:22 [PATCH v3 00/21] OvmfPkg/Virtio: introduce IOMMU-like member functions Brijesh Singh
                   ` (9 preceding siblings ...)
  2017-08-23 12:22 ` [PATCH v3 10/23] OvmfPkg/VirtioLib: alloc VRING buffer with AllocateSharedPages() Brijesh Singh
@ 2017-08-23 12:22 ` Brijesh Singh
  2017-08-23 21:38   ` Laszlo Ersek
  2017-08-23 12:22 ` [PATCH v3 12/23] OvmfPkg/VirtioRngDxe: map host address to device address Brijesh Singh
                   ` (12 subsequent siblings)
  23 siblings, 1 reply; 46+ messages in thread
From: Brijesh Singh @ 2017-08-23 12:22 UTC (permalink / raw)
  To: edk2-devel
  Cc: Brijesh Singh, Ard Biesheuvel, Jordan Justen, Tom Lendacky,
	Laszlo Ersek

The patch change the "BufferPhysAddr" parameter of VirtioAppendDesc()
from type UINTN to UINT64.

UINTN is appropriate as long as we pass system memory references. After
the introduction of this feature, that's no longer the case in general.
Should we implement "real" IOMMU support at some point, UINTN could
break in 32-bit builds of OVMF.

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>
---
 OvmfPkg/Include/Library/VirtioLib.h   | 35 +++++++++---------
 OvmfPkg/Library/VirtioLib/VirtioLib.c | 38 ++++++++++----------
 2 files changed, 37 insertions(+), 36 deletions(-)

diff --git a/OvmfPkg/Include/Library/VirtioLib.h b/OvmfPkg/Include/Library/VirtioLib.h
index c3e56ea23b89..a966311ac941 100644
--- a/OvmfPkg/Include/Library/VirtioLib.h
+++ b/OvmfPkg/Include/Library/VirtioLib.h
@@ -151,33 +151,34 @@ VirtioPrepare (
   The caller is responsible for initializing *Indices with VirtioPrepare()
   first.
 
-  @param[in,out] Ring        The virtio ring to append the buffer to, as a
-                             descriptor.
+  @param[in,out] Ring               The virtio ring to append the buffer to,
+                                    as a descriptor.
 
-  @param[in] BufferPhysAddr  (Guest pseudo-physical) start address of the
-                             transmit / receive buffer.
+  @param[in] BufferDeviceAddress    (Bus master device)) start address of the
+                                    transmit / receive buffer.
 
-  @param[in] BufferSize      Number of bytes to transmit or receive.
+  @param[in] BufferSize             Number of bytes to transmit or receive.
 
-  @param[in] Flags           A bitmask of VRING_DESC_F_* flags. The caller
-                             computes this mask dependent on further buffers to
-                             append and transfer direction.
-                             VRING_DESC_F_INDIRECT is unsupported. The
-                             VRING_DESC.Next field is always set, but the host
-                             only interprets it dependent on VRING_DESC_F_NEXT.
+  @param[in] Flags                  A bitmask of VRING_DESC_F_* flags. The
+                                    caller computes this mask dependent on
+                                    further buffers to append and transfer
+                                    direction. VRING_DESC_F_INDIRECT is
+                                    unsupported. The VRING_DESC.Next field is
+                                    always set, but the host only interprets
+                                    it dependent on VRING_DESC_F_NEXT.
 
-  @param[in,out] Indices     Indices->HeadDescIdx is not accessed.
-                             On input, Indices->NextDescIdx identifies the next
-                             descriptor to carry the buffer. On output,
-                             Indices->NextDescIdx is incremented by one, modulo
-                             2^16.
+  @param[in,out] Indices            Indices->HeadDescIdx is not accessed.
+                                    On input, Indices->NextDescIdx identifies
+                                    the next descriptor to carry the buffer.
+                                    On output, Indices->NextDescIdx is
+                                    incremented by one, modulo 2^16.
 
 **/
 VOID
 EFIAPI
 VirtioAppendDesc (
   IN OUT VRING        *Ring,
-  IN     UINTN        BufferPhysAddr,
+  IN     UINT64       BufferDeviceAddress,
   IN     UINT32       BufferSize,
   IN     UINT16       Flags,
   IN OUT DESC_INDICES *Indices
diff --git a/OvmfPkg/Library/VirtioLib/VirtioLib.c b/OvmfPkg/Library/VirtioLib/VirtioLib.c
index e5366e385f5d..fcd484fffada 100644
--- a/OvmfPkg/Library/VirtioLib/VirtioLib.c
+++ b/OvmfPkg/Library/VirtioLib/VirtioLib.c
@@ -189,7 +189,6 @@ VirtioPrepare (
   Indices->NextDescIdx = Indices->HeadDescIdx;
 }
 
-
 /**
 
   Append a contiguous buffer for transmission / reception via the virtio ring.
@@ -205,33 +204,34 @@ VirtioPrepare (
   The caller is responsible for initializing *Indices with VirtioPrepare()
   first.
 
-  @param[in,out] Ring        The virtio ring to append the buffer to, as a
-                             descriptor.
+  @param[in,out] Ring               The virtio ring to append the buffer to,
+                                    as a descriptor.
 
-  @param[in] BufferPhysAddr  (Guest pseudo-physical) start address of the
-                             transmit / receive buffer.
+  @param[in] BufferDeviceAddress    (Bus master device)) start address of the
+                                    transmit / receive buffer.
 
-  @param[in] BufferSize      Number of bytes to transmit or receive.
+  @param[in] BufferSize             Number of bytes to transmit or receive.
 
-  @param[in] Flags           A bitmask of VRING_DESC_F_* flags. The caller
-                             computes this mask dependent on further buffers to
-                             append and transfer direction.
-                             VRING_DESC_F_INDIRECT is unsupported. The
-                             VRING_DESC.Next field is always set, but the host
-                             only interprets it dependent on VRING_DESC_F_NEXT.
+  @param[in] Flags                  A bitmask of VRING_DESC_F_* flags. The
+                                    caller computes this mask dependent on
+                                    further buffers to append and transfer
+                                    direction. VRING_DESC_F_INDIRECT is
+                                    unsupported. The VRING_DESC.Next field is
+                                    always set, but the host only interprets
+                                    it dependent on VRING_DESC_F_NEXT.
 
-  @param[in,out] Indices     Indices->HeadDescIdx is not accessed.
-                             On input, Indices->NextDescIdx identifies the next
-                             descriptor to carry the buffer. On output,
-                             Indices->NextDescIdx is incremented by one, modulo
-                             2^16.
+  @param[in,out] Indices            Indices->HeadDescIdx is not accessed.
+                                    On input, Indices->NextDescIdx identifies
+                                    the next descriptor to carry the buffer.
+                                    On output, Indices->NextDescIdx is
+                                    incremented by one, modulo 2^16.
 
 **/
 VOID
 EFIAPI
 VirtioAppendDesc (
   IN OUT VRING        *Ring,
-  IN     UINTN        BufferPhysAddr,
+  IN     UINT64       BufferDeviceAddress,
   IN     UINT32       BufferSize,
   IN     UINT16       Flags,
   IN OUT DESC_INDICES *Indices
@@ -240,7 +240,7 @@ VirtioAppendDesc (
   volatile VRING_DESC *Desc;
 
   Desc        = &Ring->Desc[Indices->NextDescIdx++ % Ring->QueueSize];
-  Desc->Addr  = BufferPhysAddr;
+  Desc->Addr  = BufferDeviceAddress;
   Desc->Len   = BufferSize;
   Desc->Flags = Flags;
   Desc->Next  = Indices->NextDescIdx % Ring->QueueSize;
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 12/23] OvmfPkg/VirtioRngDxe: map host address to device address
  2017-08-23 12:22 [PATCH v3 00/21] OvmfPkg/Virtio: introduce IOMMU-like member functions Brijesh Singh
                   ` (10 preceding siblings ...)
  2017-08-23 12:22 ` [PATCH v3 11/23] OvmfPkg/VirtioLib: change the parameter of VirtioAppendDesc() to UINT64 Brijesh Singh
@ 2017-08-23 12:22 ` Brijesh Singh
  2017-08-23 22:54   ` Laszlo Ersek
  2017-08-23 12:22 ` [PATCH v3 13/23] OvmfPkg/VirtioBlkDxe: " Brijesh Singh
                   ` (11 subsequent siblings)
  23 siblings, 1 reply; 46+ messages in thread
From: Brijesh Singh @ 2017-08-23 12:22 UTC (permalink / raw)
  To: edk2-devel
  Cc: Brijesh Singh, Ard Biesheuvel, Jordan Justen, Tom Lendacky,
	Laszlo Ersek

patch maps the host address to a device address for buffers (including
rings, device specifc request and response pointed by vring descriptor,
and any further memory reference by those request and response).

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/VirtioRngDxe/VirtioRng.h |  1 +
 OvmfPkg/VirtioRngDxe/VirtioRng.c | 82 +++++++++++++++++---
 2 files changed, 74 insertions(+), 9 deletions(-)

diff --git a/OvmfPkg/VirtioRngDxe/VirtioRng.h b/OvmfPkg/VirtioRngDxe/VirtioRng.h
index 998f9fae48c2..389c8ddc8d31 100644
--- a/OvmfPkg/VirtioRngDxe/VirtioRng.h
+++ b/OvmfPkg/VirtioRngDxe/VirtioRng.h
@@ -38,6 +38,7 @@ typedef struct {
   EFI_EVENT                 ExitBoot;       // DriverBindingStart   0
   VRING                     Ring;           // VirtioRingInit       2
   EFI_RNG_PROTOCOL          Rng;            // VirtioRngInit        1
+  VOID                      *RingMap;       // VirtioRingMap        2
 } VIRTIO_RNG_DEV;
 
 #define VIRTIO_ENTROPY_SOURCE_FROM_RNG(RngPointer) \
diff --git a/OvmfPkg/VirtioRngDxe/VirtioRng.c b/OvmfPkg/VirtioRngDxe/VirtioRng.c
index 0abca488e6cd..59f32d343179 100644
--- a/OvmfPkg/VirtioRngDxe/VirtioRng.c
+++ b/OvmfPkg/VirtioRngDxe/VirtioRng.c
@@ -140,6 +140,8 @@ VirtioRngGetRNG (
   UINT32                    Len;
   UINT32                    BufferSize;
   EFI_STATUS                Status;
+  EFI_PHYSICAL_ADDRESS      DeviceAddress;
+  VOID                      *Mapping;
 
   if (This == NULL || RNGValueLength == 0 || RNGValue == NULL) {
     return EFI_INVALID_PARAMETER;
@@ -159,6 +161,20 @@ VirtioRngGetRNG (
   }
 
   Dev = VIRTIO_ENTROPY_SOURCE_FROM_RNG (This);
+  //
+  // Map Buffer's system phyiscal address to device address
+  //
+  Status = VirtioMapAllBytesInSharedBuffer (
+             Dev->VirtIo,
+             VirtioOperationBusMasterWrite,
+             (VOID *)Buffer,
+             RNGValueLength,
+             &DeviceAddress,
+             &Mapping
+             );
+  if (EFI_ERROR (Status)) {
+    goto FreeBuffer;
+  }
 
   //
   // The Virtio RNG device may return less data than we asked it to, and can
@@ -170,7 +186,7 @@ VirtioRngGetRNG (
 
     VirtioPrepare (&Dev->Ring, &Indices);
     VirtioAppendDesc (&Dev->Ring,
-      (UINTN)Buffer + Index,
+      DeviceAddress + Index,
       BufferSize,
       VRING_DESC_F_WRITE,
       &Indices);
@@ -178,17 +194,35 @@ VirtioRngGetRNG (
     if (VirtioFlush (Dev->VirtIo, 0, &Dev->Ring, &Indices, &Len) !=
         EFI_SUCCESS) {
       Status = EFI_DEVICE_ERROR;
-      goto FreeBuffer;
+      goto UnmapBuffer;
     }
     ASSERT (Len > 0);
     ASSERT (Len <= BufferSize);
   }
 
+  //
+  // Unmap the device buffer before accessing it.
+  //
+  Status = Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Mapping);
+  if (EFI_ERROR (Status)) {
+    Status = EFI_DEVICE_ERROR;
+    goto FreeBuffer;
+  }
+
   for (Index = 0; Index < RNGValueLength; Index++) {
     RNGValue[Index] = Buffer[Index];
   }
   Status = EFI_SUCCESS;
 
+UnmapBuffer:
+  //
+  // If we are reached here due to the error then unmap the buffer otherwise
+  // the buffer is already unmapped after VirtioFlush().
+  //
+  if (EFI_ERROR (Status)) {
+    Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Mapping);
+  }
+
 FreeBuffer:
   FreePool ((VOID *)Buffer);
   return Status;
@@ -205,6 +239,7 @@ VirtioRngInit (
   EFI_STATUS Status;
   UINT16     QueueSize;
   UINT64     Features;
+  UINT64     RingBaseShift;
 
   //
   // Execute virtio-0.9.5, 2.2.1 Device Initialization Sequence.
@@ -282,25 +317,42 @@ VirtioRngInit (
   }
 
   //
+  // If anything fails from here on, we must release the ring resources.
+  //
+  Status = VirtioRingMap (
+             Dev->VirtIo,
+             &Dev->Ring,
+             &RingBaseShift,
+             &Dev->RingMap
+             );
+  if (EFI_ERROR (Status)) {
+    goto ReleaseQueue;
+  }
+
+  //
   // Additional steps for MMIO: align the queue appropriately, and set the
-  // size. If anything fails from here on, we must release the ring resources.
+  // size. If anything fails from here on, we must unmap the ring resources.
   //
   Status = Dev->VirtIo->SetQueueNum (Dev->VirtIo, QueueSize);
   if (EFI_ERROR (Status)) {
-    goto ReleaseQueue;
+    goto UnmapQueue;
   }
 
   Status = Dev->VirtIo->SetQueueAlign (Dev->VirtIo, EFI_PAGE_SIZE);
   if (EFI_ERROR (Status)) {
-    goto ReleaseQueue;
+    goto UnmapQueue;
   }
 
   //
   // step 4c -- Report GPFN (guest-physical frame number) of queue.
   //
-  Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, &Dev->Ring, 0);
+  Status = Dev->VirtIo->SetQueueAddress (
+                          Dev->VirtIo,
+                          &Dev->Ring,
+                          RingBaseShift
+                          );
   if (EFI_ERROR (Status)) {
-    goto ReleaseQueue;
+    goto UnmapQueue;
   }
 
   //
@@ -310,7 +362,7 @@ VirtioRngInit (
     Features &= ~(UINT64)VIRTIO_F_VERSION_1;
     Status = Dev->VirtIo->SetGuestFeatures (Dev->VirtIo, Features);
     if (EFI_ERROR (Status)) {
-      goto ReleaseQueue;
+      goto UnmapQueue;
     }
   }
 
@@ -320,7 +372,7 @@ VirtioRngInit (
   NextDevStat |= VSTAT_DRIVER_OK;
   Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
   if (EFI_ERROR (Status)) {
-    goto ReleaseQueue;
+    goto UnmapQueue;
   }
 
   //
@@ -331,6 +383,9 @@ VirtioRngInit (
 
   return EFI_SUCCESS;
 
+UnmapQueue:
+  Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->RingMap);
+
 ReleaseQueue:
   VirtioRingUninit (Dev->VirtIo, &Dev->Ring);
 
@@ -359,6 +414,9 @@ VirtioRngUninit (
   // the old comms area.
   //
   Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
+
+  Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->RingMap);
+
   VirtioRingUninit (Dev->VirtIo, &Dev->Ring);
 }
 
@@ -385,6 +443,12 @@ VirtioRngExitBoot (
   //
   Dev = Context;
   Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
+
+  //
+  // Unmap the ring buffer so that hypervisor will not be able to get readable
+  // data after device reset.
+  //
+  Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->RingMap);
 }
 
 
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 13/23] OvmfPkg/VirtioBlkDxe: map host address to device address
  2017-08-23 12:22 [PATCH v3 00/21] OvmfPkg/Virtio: introduce IOMMU-like member functions Brijesh Singh
                   ` (11 preceding siblings ...)
  2017-08-23 12:22 ` [PATCH v3 12/23] OvmfPkg/VirtioRngDxe: map host address to device address Brijesh Singh
@ 2017-08-23 12:22 ` Brijesh Singh
  2017-08-23 12:22 ` [PATCH v3 14/23] OvmfPkg/VirtioScsiDxe: " Brijesh Singh
                   ` (10 subsequent siblings)
  23 siblings, 0 replies; 46+ messages in thread
From: Brijesh Singh @ 2017-08-23 12:22 UTC (permalink / raw)
  To: edk2-devel
  Cc: Brijesh Singh, Ard Biesheuvel, Jordan Justen, Tom Lendacky,
	Laszlo Ersek

The SynchronousRequest() function, programs the vring descriptor with the
buffers pointed-by virtio-blk requests, status and memory that is
referenced inside the request header.

The patch uses VIRTIO_DEVICE_PROTOCOL.MapSharedBuffer() function to map
host address to device address and programs the vring descriptor with
device addresses.

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/VirtioBlkDxe/VirtioBlk.h |   1 +
 OvmfPkg/VirtioBlkDxe/VirtioBlk.c | 201 +++++++++++++++++---
 2 files changed, 180 insertions(+), 22 deletions(-)

diff --git a/OvmfPkg/VirtioBlkDxe/VirtioBlk.h b/OvmfPkg/VirtioBlkDxe/VirtioBlk.h
index 6c402ca88ea4..9ec0b956b818 100644
--- a/OvmfPkg/VirtioBlkDxe/VirtioBlk.h
+++ b/OvmfPkg/VirtioBlkDxe/VirtioBlk.h
@@ -41,6 +41,7 @@ typedef struct {
   VRING                  Ring;                 // VirtioRingInit      2
   EFI_BLOCK_IO_PROTOCOL  BlockIo;              // VirtioBlkInit       1
   EFI_BLOCK_IO_MEDIA     BlockIoMedia;         // VirtioBlkInit       1
+  VOID                   *RingMap;             // VirtioRingMap       2
 } VBLK_DEV;
 
 #define VIRTIO_BLK_FROM_BLOCK_IO(BlockIoPointer) \
diff --git a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
index bff15fe3add1..e23762743f75 100644
--- a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
+++ b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
@@ -232,7 +232,8 @@ VerifyReadWriteRequest (
 
   @retval EFI_DEVICE_ERROR     Failed to notify host side via VirtIo write, or
                                unable to parse host response, or host response
-                               is not VIRTIO_BLK_S_OK.
+                               is not VIRTIO_BLK_S_OK or failed to map Buffer
+                               for a bus master operation.
 
 **/
 
@@ -249,8 +250,16 @@ SynchronousRequest (
 {
   UINT32                  BlockSize;
   volatile VIRTIO_BLK_REQ Request;
-  volatile UINT8          HostStatus;
+  volatile UINT8          *HostStatus;
+  VOID                    *HostStatusBuffer;
   DESC_INDICES            Indices;
+  VOID                    *RequestMapping;
+  VOID                    *StatusMapping;
+  VOID                    *BufferMapping;
+  EFI_PHYSICAL_ADDRESS    BufferDeviceAddress;
+  EFI_PHYSICAL_ADDRESS    HostStatusDeviceAddress;
+  EFI_PHYSICAL_ADDRESS    RequestDeviceAddress;
+  EFI_STATUS              Status, Ret;
 
   BlockSize = Dev->BlockIoMedia.BlockSize;
 
@@ -278,9 +287,88 @@ SynchronousRequest (
   VirtioPrepare (&Dev->Ring, &Indices);
 
   //
+  // Host status is bi-directional (we preset with a value and expect the device
+  // to update it). Allocate a host status buffer which can be mapped to
+  // access equally by both processor and the device.
+  //
+  Status = Dev->VirtIo->AllocateSharedPages (
+                          Dev->VirtIo,
+                          EFI_SIZE_TO_PAGES (sizeof *HostStatus),
+                          &HostStatusBuffer
+                          );
+  if (EFI_ERROR (Status)) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  // Map virtio-blk request header
+  //
+  Status = VirtioMapAllBytesInSharedBuffer (
+             Dev->VirtIo,
+             VirtioOperationBusMasterRead,
+             (VOID *) &Request,
+             sizeof Request,
+             &RequestDeviceAddress,
+             &RequestMapping
+             );
+  if (EFI_ERROR (Status)) {
+    Status = EFI_DEVICE_ERROR;
+    goto FreeHostStatusBuffer;
+  }
+
+  //
+  // Map data buffer
+  //
+  if (BufferSize > 0) {
+    if (RequestIsWrite) {
+      Status = VirtioMapAllBytesInSharedBuffer (
+                 Dev->VirtIo,
+                 VirtioOperationBusMasterRead,
+                 (VOID *) Buffer,
+                 BufferSize,
+                 &BufferDeviceAddress,
+                 &BufferMapping
+                 );
+    } else {
+      Status = VirtioMapAllBytesInSharedBuffer (
+                 Dev->VirtIo,
+                 VirtioOperationBusMasterWrite,
+                 (VOID *) Buffer,
+                 BufferSize,
+                 &BufferDeviceAddress,
+                 &BufferMapping
+                 );
+    }
+
+    if (EFI_ERROR (Status)) {
+      Status = EFI_DEVICE_ERROR;
+      goto UnmapRequestBuffer;
+    }
+  }
+
+  //
+  // Map the Status Buffer with VirtioOperationBusMasterCommonBuffer so that
+  // both processor and device can access it.
+  //
+  Status = VirtioMapAllBytesInSharedBuffer (
+             Dev->VirtIo,
+             VirtioOperationBusMasterCommonBuffer,
+             HostStatusBuffer,
+             sizeof *HostStatus,
+             &HostStatusDeviceAddress,
+             &StatusMapping
+             );
+  if (EFI_ERROR (Status)) {
+    Status = EFI_DEVICE_ERROR;
+    goto UnmapDataBuffer;
+  }
+
+  HostStatus = HostStatusBuffer;
+
+  //
   // preset a host status for ourselves that we do not accept as success
   //
-  HostStatus = VIRTIO_BLK_S_IOERR;
+  *HostStatus = VIRTIO_BLK_S_IOERR;
 
   //
   // ensured by VirtioBlkInit() -- this predicate, in combination with the
@@ -291,8 +379,13 @@ SynchronousRequest (
   //
   // virtio-blk header in first desc
   //
-  VirtioAppendDesc (&Dev->Ring, (UINTN) &Request, sizeof Request,
-    VRING_DESC_F_NEXT, &Indices);
+  VirtioAppendDesc (
+    &Dev->Ring,
+    RequestDeviceAddress,
+    sizeof Request,
+    VRING_DESC_F_NEXT,
+    &Indices
+    );
 
   //
   // data buffer for read/write in second desc
@@ -311,27 +404,62 @@ SynchronousRequest (
     //
     // VRING_DESC_F_WRITE is interpreted from the host's point of view.
     //
-    VirtioAppendDesc (&Dev->Ring, (UINTN) Buffer, (UINT32) BufferSize,
+    VirtioAppendDesc (
+      &Dev->Ring,
+      BufferDeviceAddress,
+      (UINT32) BufferSize,
       VRING_DESC_F_NEXT | (RequestIsWrite ? 0 : VRING_DESC_F_WRITE),
-      &Indices);
+      &Indices
+      );
   }
 
   //
   // host status in last (second or third) desc
   //
-  VirtioAppendDesc (&Dev->Ring, (UINTN) &HostStatus, sizeof HostStatus,
-    VRING_DESC_F_WRITE, &Indices);
+  VirtioAppendDesc (
+    &Dev->Ring,
+    HostStatusDeviceAddress,
+    sizeof *HostStatus,
+    VRING_DESC_F_WRITE,
+    &Indices
+    );
 
   //
   // virtio-blk's only virtqueue is #0, called "requestq" (see Appendix D).
   //
-  if (VirtioFlush (Dev->VirtIo, 0, &Dev->Ring, &Indices,
-        NULL) == EFI_SUCCESS &&
-      HostStatus == VIRTIO_BLK_S_OK) {
-    return EFI_SUCCESS;
+  Status = VirtioFlush (Dev->VirtIo, 0, &Dev->Ring, &Indices, NULL);
+
+  //
+  // Unmap the HostStatus buffer before accessing it
+  //
+  Ret = Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, StatusMapping);
+  if (EFI_ERROR (Ret)) {
+    Status = EFI_DEVICE_ERROR;
+  }
+
+  if (!EFI_ERROR (Status) &&
+      *HostStatus == VIRTIO_BLK_S_OK) {
+    Status = EFI_SUCCESS;
+  } else {
+    Status = EFI_DEVICE_ERROR;
   }
 
-  return EFI_DEVICE_ERROR;
+UnmapDataBuffer:
+  if (BufferSize > 0) {
+    Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, BufferMapping);
+  }
+
+UnmapRequestBuffer:
+  Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, RequestMapping);
+
+FreeHostStatusBuffer:
+  Dev->VirtIo->FreeSharedPages (
+                 Dev->VirtIo,
+                 EFI_SIZE_TO_PAGES (sizeof *HostStatus),
+                 HostStatusBuffer
+                 );
+
+  return Status;
 }
 
 
@@ -580,7 +708,8 @@ VirtioBlkDriverBindingSupported (
                            virtio-blk attributes the host provides.
 
   @return                  Error codes from VirtioRingInit() or
-                           VIRTIO_CFG_READ() / VIRTIO_CFG_WRITE().
+                           VIRTIO_CFG_READ() / VIRTIO_CFG_WRITE or
+                           VirtioRingMap().
 
 **/
 
@@ -601,6 +730,7 @@ VirtioBlkInit (
   UINT8      AlignmentOffset;
   UINT32     OptIoSize;
   UINT16     QueueSize;
+  UINT64     RingBaseShift;
 
   PhysicalBlockExp = 0;
   AlignmentOffset = 0;
@@ -729,25 +859,42 @@ VirtioBlkInit (
   }
 
   //
+  // If anything fails from here on, we must release the ring resources
+  //
+  Status = VirtioRingMap (
+             Dev->VirtIo,
+             &Dev->Ring,
+             &RingBaseShift,
+             &Dev->RingMap
+             );
+  if (EFI_ERROR (Status)) {
+    goto ReleaseQueue;
+  }
+
+  //
   // Additional steps for MMIO: align the queue appropriately, and set the
-  // size. If anything fails from here on, we must release the ring resources.
+  // size. If anything fails from here on, we must unmap the ring resources.
   //
   Status = Dev->VirtIo->SetQueueNum (Dev->VirtIo, QueueSize);
   if (EFI_ERROR (Status)) {
-    goto ReleaseQueue;
+    goto UnmapQueue;
   }
 
   Status = Dev->VirtIo->SetQueueAlign (Dev->VirtIo, EFI_PAGE_SIZE);
   if (EFI_ERROR (Status)) {
-    goto ReleaseQueue;
+    goto UnmapQueue;
   }
 
   //
   // step 4c -- Report GPFN (guest-physical frame number) of queue.
   //
-  Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, &Dev->Ring, 0);
+  Status = Dev->VirtIo->SetQueueAddress (
+                          Dev->VirtIo,
+                          &Dev->Ring,
+                          RingBaseShift
+                          );
   if (EFI_ERROR (Status)) {
-    goto ReleaseQueue;
+    goto UnmapQueue;
   }
 
 
@@ -758,7 +905,7 @@ VirtioBlkInit (
     Features &= ~(UINT64)VIRTIO_F_VERSION_1;
     Status = Dev->VirtIo->SetGuestFeatures (Dev->VirtIo, Features);
     if (EFI_ERROR (Status)) {
-      goto ReleaseQueue;
+      goto UnmapQueue;
     }
   }
 
@@ -768,7 +915,7 @@ VirtioBlkInit (
   NextDevStat |= VSTAT_DRIVER_OK;
   Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
   if (EFI_ERROR (Status)) {
-    goto ReleaseQueue;
+    goto UnmapQueue;
   }
 
   //
@@ -811,6 +958,9 @@ VirtioBlkInit (
   }
   return EFI_SUCCESS;
 
+UnmapQueue:
+  Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->RingMap);
+
 ReleaseQueue:
   VirtioRingUninit (Dev->VirtIo, &Dev->Ring);
 
@@ -849,6 +999,7 @@ VirtioBlkUninit (
   //
   Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
 
+  Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->RingMap);
   VirtioRingUninit (Dev->VirtIo, &Dev->Ring);
 
   SetMem (&Dev->BlockIo,      sizeof Dev->BlockIo,      0x00);
@@ -885,6 +1036,12 @@ VirtioBlkExitBoot (
   //
   Dev = Context;
   Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
+
+  //
+  // Unmap the ring buffer so that hypervisor will not be able to get
+  // readable data after device is reset.
+  //
+  Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->RingMap);
 }
 
 /**
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 14/23] OvmfPkg/VirtioScsiDxe: map host address to device address
  2017-08-23 12:22 [PATCH v3 00/21] OvmfPkg/Virtio: introduce IOMMU-like member functions Brijesh Singh
                   ` (12 preceding siblings ...)
  2017-08-23 12:22 ` [PATCH v3 13/23] OvmfPkg/VirtioBlkDxe: " Brijesh Singh
@ 2017-08-23 12:22 ` Brijesh Singh
  2017-08-23 12:22 ` [PATCH v3 15/23] OvmfPkg/VirtioNetDxe: alloc Tx and Rx rings using AllocateSharedPage() Brijesh Singh
                   ` (9 subsequent siblings)
  23 siblings, 0 replies; 46+ messages in thread
From: Brijesh Singh @ 2017-08-23 12:22 UTC (permalink / raw)
  To: edk2-devel
  Cc: Brijesh Singh, Ard Biesheuvel, Jordan Justen, Tom Lendacky,
	Laszlo Ersek

The VirtioScsiPassThru() function, programs the vring descriptor using
the host addresses pointed-by virtio-scsi request, response and memory
that is referenced inside the request and response header.

The patch uses newly introduced VIRTIO_DEVICE_PROTOCOL.MapSharedBuffer()
function to map system memory to device address and programs the vring
descriptors with device addresses.

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/VirtioScsiDxe/VirtioScsi.h |   1 +
 OvmfPkg/VirtioScsiDxe/VirtioScsi.c | 210 +++++++++++++++++---
 2 files changed, 186 insertions(+), 25 deletions(-)

diff --git a/OvmfPkg/VirtioScsiDxe/VirtioScsi.h b/OvmfPkg/VirtioScsiDxe/VirtioScsi.h
index 6d00567e8cb8..05a6bf567263 100644
--- a/OvmfPkg/VirtioScsiDxe/VirtioScsi.h
+++ b/OvmfPkg/VirtioScsiDxe/VirtioScsi.h
@@ -60,6 +60,7 @@ typedef struct {
   VRING                           Ring;           // VirtioRingInit      2
   EFI_EXT_SCSI_PASS_THRU_PROTOCOL PassThru;       // VirtioScsiInit      1
   EFI_EXT_SCSI_PASS_THRU_MODE     PassThruMode;   // VirtioScsiInit      1
+  VOID                            *RingMap;       // VirtioRingMap       2
 } VSCSI_DEV;
 
 #define VIRTIO_SCSI_FROM_PASS_THRU(PassThruPointer) \
diff --git a/OvmfPkg/VirtioScsiDxe/VirtioScsi.c b/OvmfPkg/VirtioScsiDxe/VirtioScsi.c
index a983b3df7b9c..ed7fd1dd58a8 100644
--- a/OvmfPkg/VirtioScsiDxe/VirtioScsi.c
+++ b/OvmfPkg/VirtioScsiDxe/VirtioScsi.c
@@ -409,11 +409,19 @@ VirtioScsiPassThru (
   UINT16                    TargetValue;
   EFI_STATUS                Status;
   volatile VIRTIO_SCSI_REQ  Request;
-  volatile VIRTIO_SCSI_RESP Response;
+  volatile VIRTIO_SCSI_RESP *Response;
+  VOID                      *ResponseBuffer;
   DESC_INDICES              Indices;
+  VOID                      *RequestMapping;
+  VOID                      *ResponseMapping;
+  VOID                      *InDataMapping;
+  VOID                      *OutDataMapping;
+  EFI_PHYSICAL_ADDRESS      RequestDeviceAddress;
+  EFI_PHYSICAL_ADDRESS      ResponseDeviceAddress;
+  EFI_PHYSICAL_ADDRESS      InDataDeviceAddress;
+  EFI_PHYSICAL_ADDRESS      OutDataDeviceAddress;
 
   ZeroMem ((VOID*) &Request, sizeof (Request));
-  ZeroMem ((VOID*) &Response, sizeof (Response));
 
   Dev = VIRTIO_SCSI_FROM_PASS_THRU (This);
   CopyMem (&TargetValue, Target, sizeof TargetValue);
@@ -423,12 +431,93 @@ VirtioScsiPassThru (
     return Status;
   }
 
+  //
+  // Response header is bi-direction (we preset with host status and expect the
+  // device to update it). Allocate a response buffer which can be mapped to
+  // access equally by both processor and device.
+  //
+  Status = Dev->VirtIo->AllocateSharedPages (
+                          Dev->VirtIo,
+                          EFI_SIZE_TO_PAGES (sizeof *Response),
+                          &ResponseBuffer
+                          );
+  if (EFI_ERROR (Status)) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  Status = VirtioMapAllBytesInSharedBuffer (
+             Dev->VirtIo,
+             VirtioOperationBusMasterCommonBuffer,
+             ResponseBuffer,
+             sizeof (*Response),
+             &ResponseDeviceAddress,
+             &ResponseMapping
+             );
+  if (EFI_ERROR (Status)) {
+    Status = EFI_DEVICE_ERROR;
+    goto FreeResponseBuffer;
+  }
+
+  Response = ResponseBuffer;
+
+  //
+  // Map the scsi-blk Request header buffer host address to device address
+  //
+  Status = VirtioMapAllBytesInSharedBuffer (
+             Dev->VirtIo,
+             VirtioOperationBusMasterRead,
+             (VOID *) &Request,
+             sizeof Request,
+             &RequestDeviceAddress,
+             &RequestMapping);
+  if (EFI_ERROR (Status)) {
+    Status = EFI_DEVICE_ERROR;
+    goto UnmapResponseBuffer;
+  }
+
+  //
+  // Map the input buffer host address to a device address
+  //
+  if (Packet->InTransferLength > 0) {
+    Status = VirtioMapAllBytesInSharedBuffer (
+               Dev->VirtIo,
+               VirtioOperationBusMasterWrite,
+               Packet->InDataBuffer,
+               Packet->InTransferLength,
+               &InDataDeviceAddress,
+               &InDataMapping
+               );
+    if (EFI_ERROR (Status)) {
+      Status = EFI_DEVICE_ERROR;
+      goto UnmapRequestBuffer;
+    }
+  }
+
+  //
+  // Map the output buffer host address to a device address
+  //
+  if (Packet->OutTransferLength > 0) {
+    Status = VirtioMapAllBytesInSharedBuffer (
+               Dev->VirtIo,
+               VirtioOperationBusMasterRead,
+               Packet->OutDataBuffer,
+               Packet->OutTransferLength,
+               &OutDataDeviceAddress,
+               &OutDataMapping
+               );
+    if (EFI_ERROR (Status)) {
+      Status = EFI_DEVICE_ERROR;
+      goto UnmapInDataBuffer;
+    }
+  }
+
+
   VirtioPrepare (&Dev->Ring, &Indices);
 
   //
   // preset a host status for ourselves that we do not accept as success
   //
-  Response.Response = VIRTIO_SCSI_S_FAILURE;
+  Response->Response = VIRTIO_SCSI_S_FAILURE;
 
   //
   // ensured by VirtioScsiInit() -- this predicate, in combination with the
@@ -439,31 +528,49 @@ VirtioScsiPassThru (
   //
   // enqueue Request
   //
-  VirtioAppendDesc (&Dev->Ring, (UINTN) &Request, sizeof Request,
-    VRING_DESC_F_NEXT, &Indices);
+  VirtioAppendDesc (
+    &Dev->Ring,
+    RequestDeviceAddress,
+    sizeof Request,
+    VRING_DESC_F_NEXT,
+    &Indices
+    );
 
   //
   // enqueue "dataout" if any
   //
   if (Packet->OutTransferLength > 0) {
-    VirtioAppendDesc (&Dev->Ring, (UINTN) Packet->OutDataBuffer,
-      Packet->OutTransferLength, VRING_DESC_F_NEXT, &Indices);
+    VirtioAppendDesc (
+      &Dev->Ring,
+      OutDataDeviceAddress,
+      Packet->OutTransferLength,
+      VRING_DESC_F_NEXT,
+      &Indices
+      );
   }
 
   //
   // enqueue Response, to be written by the host
   //
-  VirtioAppendDesc (&Dev->Ring, (UINTN) &Response, sizeof Response,
-    VRING_DESC_F_WRITE | (Packet->InTransferLength > 0 ?
-                          VRING_DESC_F_NEXT : 0),
-    &Indices);
+  VirtioAppendDesc (
+    &Dev->Ring,
+    ResponseDeviceAddress,
+    sizeof *Response,
+    VRING_DESC_F_WRITE | (Packet->InTransferLength > 0 ? VRING_DESC_F_NEXT : 0),
+    &Indices
+    );
 
   //
   // enqueue "datain" if any, to be written by the host
   //
   if (Packet->InTransferLength > 0) {
-    VirtioAppendDesc (&Dev->Ring, (UINTN) Packet->InDataBuffer,
-      Packet->InTransferLength, VRING_DESC_F_WRITE, &Indices);
+    VirtioAppendDesc (
+      &Dev->Ring,
+      InDataDeviceAddress,
+      Packet->InTransferLength,
+      VRING_DESC_F_WRITE,
+      &Indices
+      );
   }
 
   // If kicking the host fails, we must fake a host adapter error.
@@ -477,10 +584,36 @@ VirtioScsiPassThru (
     Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OTHER;
     Packet->TargetStatus      = EFI_EXT_SCSI_STATUS_TARGET_GOOD;
     Packet->SenseDataLength   = 0;
-    return EFI_DEVICE_ERROR;
+    Status = EFI_DEVICE_ERROR;
+    goto UnmapOutDataBuffer;
   }
 
-  return ParseResponse (Packet, &Response);
+  Status = ParseResponse (Packet, Response);
+
+UnmapOutDataBuffer:
+  if (Packet->OutTransferLength > 0) {
+    Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, OutDataMapping);
+  }
+
+UnmapInDataBuffer:
+  if (Packet->InTransferLength > 0) {
+    Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, InDataMapping);
+  }
+
+UnmapRequestBuffer:
+  Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, RequestMapping);
+
+UnmapResponseBuffer:
+  Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, ResponseMapping);
+
+FreeResponseBuffer:
+  Dev->VirtIo->FreeSharedPages (
+                 Dev->VirtIo,
+                 EFI_SIZE_TO_PAGES (sizeof *Response),
+                 ResponseBuffer
+                 );
+
+  return Status;
 }
 
 
@@ -707,7 +840,7 @@ VirtioScsiInit (
 {
   UINT8      NextDevStat;
   EFI_STATUS Status;
-
+  UINT64     RingBaseShift;
   UINT64     Features;
   UINT16     MaxChannel; // for validation only
   UINT32     NumQueues;  // for validation only
@@ -839,25 +972,42 @@ VirtioScsiInit (
   }
 
   //
+  // If anything fails from here on, we must release the ring resources
+  //
+  Status = VirtioRingMap (
+             Dev->VirtIo,
+             &Dev->Ring,
+             &RingBaseShift,
+             &Dev->RingMap
+             );
+  if (EFI_ERROR (Status)) {
+    goto ReleaseQueue;
+  }
+
+  //
   // Additional steps for MMIO: align the queue appropriately, and set the
-  // size. If anything fails from here on, we must release the ring resources.
+  // size. If anything fails from here on, we must unmap the ring resources.
   //
   Status = Dev->VirtIo->SetQueueNum (Dev->VirtIo, QueueSize);
   if (EFI_ERROR (Status)) {
-    goto ReleaseQueue;
+    goto UnmapQueue;
   }
 
   Status = Dev->VirtIo->SetQueueAlign (Dev->VirtIo, EFI_PAGE_SIZE);
   if (EFI_ERROR (Status)) {
-    goto ReleaseQueue;
+    goto UnmapQueue;
   }
 
   //
   // step 4c -- Report GPFN (guest-physical frame number) of queue.
   //
-  Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, &Dev->Ring, 0);
+  Status = Dev->VirtIo->SetQueueAddress (
+                          Dev->VirtIo,
+                          &Dev->Ring,
+                          RingBaseShift
+                          );
   if (EFI_ERROR (Status)) {
-    goto ReleaseQueue;
+    goto UnmapQueue;
   }
 
   //
@@ -867,7 +1017,7 @@ VirtioScsiInit (
     Features &= ~(UINT64)VIRTIO_F_VERSION_1;
     Status = Dev->VirtIo->SetGuestFeatures (Dev->VirtIo, Features);
     if (EFI_ERROR (Status)) {
-      goto ReleaseQueue;
+      goto UnmapQueue;
     }
   }
 
@@ -877,11 +1027,11 @@ VirtioScsiInit (
   //
   Status = VIRTIO_CFG_WRITE (Dev, CdbSize, VIRTIO_SCSI_CDB_SIZE);
   if (EFI_ERROR (Status)) {
-    goto ReleaseQueue;
+    goto UnmapQueue;
   }
   Status = VIRTIO_CFG_WRITE (Dev, SenseSize, VIRTIO_SCSI_SENSE_SIZE);
   if (EFI_ERROR (Status)) {
-    goto ReleaseQueue;
+    goto UnmapQueue;
   }
 
   //
@@ -890,7 +1040,7 @@ VirtioScsiInit (
   NextDevStat |= VSTAT_DRIVER_OK;
   Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
   if (EFI_ERROR (Status)) {
-    goto ReleaseQueue;
+    goto UnmapQueue;
   }
 
   //
@@ -926,6 +1076,9 @@ VirtioScsiInit (
 
   return EFI_SUCCESS;
 
+UnmapQueue:
+  Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->RingMap);
+
 ReleaseQueue:
   VirtioRingUninit (Dev->VirtIo, &Dev->Ring);
 
@@ -965,6 +1118,7 @@ VirtioScsiUninit (
   Dev->MaxLun         = 0;
   Dev->MaxSectors     = 0;
 
+  Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->RingMap);
   VirtioRingUninit (Dev->VirtIo, &Dev->Ring);
 
   SetMem (&Dev->PassThru,     sizeof Dev->PassThru,     0x00);
@@ -995,6 +1149,12 @@ VirtioScsiExitBoot (
   //
   Dev = Context;
   Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
+
+  //
+  // Unmap the ring buffer so that hypervisor will not be able to get
+  // readable data after device reset.
+  //
+  Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->RingMap);
 }
 
 
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 15/23] OvmfPkg/VirtioNetDxe: alloc Tx and Rx rings using AllocateSharedPage()
  2017-08-23 12:22 [PATCH v3 00/21] OvmfPkg/Virtio: introduce IOMMU-like member functions Brijesh Singh
                   ` (13 preceding siblings ...)
  2017-08-23 12:22 ` [PATCH v3 14/23] OvmfPkg/VirtioScsiDxe: " Brijesh Singh
@ 2017-08-23 12:22 ` Brijesh Singh
  2017-08-23 12:22 ` [PATCH v3 16/23] OvmfPkg/VirtioNetDxe: alloc RxBuf using AllocateSharedPages() Brijesh Singh
                   ` (8 subsequent siblings)
  23 siblings, 0 replies; 46+ messages in thread
From: Brijesh Singh @ 2017-08-23 12:22 UTC (permalink / raw)
  To: edk2-devel
  Cc: Brijesh Singh, Ard Biesheuvel, Jordan Justen, Tom Lendacky,
	Laszlo Ersek

The Tx and Rx rings are accessed by both guest and hypervisor, allocate
the rings using newly added VirtIo->AllocateSharedPages() and map it with
BusMasterCommonBuffer so that it can be accessed by both guest and
hypervisor.

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     |  2 +
 OvmfPkg/VirtioNetDxe/Events.c        |  7 ++++
 OvmfPkg/VirtioNetDxe/SnpInitialize.c | 40 ++++++++++++++++----
 OvmfPkg/VirtioNetDxe/SnpShutdown.c   |  2 +
 4 files changed, 43 insertions(+), 8 deletions(-)

diff --git a/OvmfPkg/VirtioNetDxe/VirtioNet.h b/OvmfPkg/VirtioNetDxe/VirtioNet.h
index 710859bc6115..d80d441b50a4 100644
--- a/OvmfPkg/VirtioNetDxe/VirtioNet.h
+++ b/OvmfPkg/VirtioNetDxe/VirtioNet.h
@@ -82,10 +82,12 @@ typedef struct {
   EFI_HANDLE                  MacHandle;         // VirtioNetDriverBindingStart
 
   VRING                       RxRing;            // VirtioNetInitRing
+  VOID                        *RxRingMap;        // VirtioRingMap
   UINT8                       *RxBuf;            // VirtioNetInitRx
   UINT16                      RxLastUsed;        // VirtioNetInitRx
 
   VRING                       TxRing;            // VirtioNetInitRing
+  VOID                        *TxRingMap;        // VirtioRingMap
   UINT16                      TxMaxPending;      // VirtioNetInitTx
   UINT16                      TxCurPending;      // VirtioNetInitTx
   UINT16                      *TxFreeStack;      // VirtioNetInitTx
diff --git a/OvmfPkg/VirtioNetDxe/Events.c b/OvmfPkg/VirtioNetDxe/Events.c
index 5be1af6ffbee..6950c4d56df1 100644
--- a/OvmfPkg/VirtioNetDxe/Events.c
+++ b/OvmfPkg/VirtioNetDxe/Events.c
@@ -88,4 +88,11 @@ VirtioNetExitBoot (
   if (Dev->Snm.State == EfiSimpleNetworkInitialized) {
     Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
   }
+
+  //
+  // Unmap Tx and Rx rings so that hypervisor will not be able get readable data
+  // after device is reset.
+  //
+  Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->TxRingMap);
+  Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->RxRingMap);
 }
diff --git a/OvmfPkg/VirtioNetDxe/SnpInitialize.c b/OvmfPkg/VirtioNetDxe/SnpInitialize.c
index 0ecfe044a977..803a38bd4239 100644
--- a/OvmfPkg/VirtioNetDxe/SnpInitialize.c
+++ b/OvmfPkg/VirtioNetDxe/SnpInitialize.c
@@ -35,11 +35,13 @@
                            the network device.
   @param[out]    Ring      The virtio-ring inside the VNET_DEV structure,
                            corresponding to Selector.
+  @param[out]    Mapping   A token return from the VirtioRingMap().
 
   @retval EFI_UNSUPPORTED  The queue size reported by the virtio-net device is
                            too small.
   @return                  Status codes from VIRTIO_CFG_WRITE(),
-                           VIRTIO_CFG_READ() and VirtioRingInit().
+                           VIRTIO_CFG_READ(), VirtioRingInit() and
+                           VirtioRingMap().
   @retval EFI_SUCCESS      Ring initialized.
 */
 
@@ -49,11 +51,13 @@ EFIAPI
 VirtioNetInitRing (
   IN OUT VNET_DEV *Dev,
   IN     UINT16   Selector,
-  OUT    VRING    *Ring
+  OUT    VRING    *Ring,
+  OUT    VOID     **Mapping
   )
 {
   EFI_STATUS Status;
   UINT16     QueueSize;
+  UINT64     RingBaseShift;
 
   //
   // step 4b -- allocate selected queue
@@ -79,30 +83,38 @@ VirtioNetInitRing (
     return Status;
   }
 
+  Status = VirtioRingMap (Dev->VirtIo, Ring, &RingBaseShift, Mapping);
+  if (EFI_ERROR (Status)) {
+    goto ReleaseQueue;
+  }
+
   //
   // Additional steps for MMIO: align the queue appropriately, and set the
   // size. If anything fails from here on, we must release the ring resources.
   //
   Status = Dev->VirtIo->SetQueueNum (Dev->VirtIo, QueueSize);
   if (EFI_ERROR (Status)) {
-    goto ReleaseQueue;
+    goto UnmapQueue;
   }
 
   Status = Dev->VirtIo->SetQueueAlign (Dev->VirtIo, EFI_PAGE_SIZE);
   if (EFI_ERROR (Status)) {
-    goto ReleaseQueue;
+    goto UnmapQueue;
   }
 
   //
   // step 4c -- report GPFN (guest-physical frame number) of queue
   //
-  Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, Ring, 0);
+  Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, Ring, RingBaseShift);
   if (EFI_ERROR (Status)) {
-    goto ReleaseQueue;
+    goto UnmapQueue;
   }
 
   return EFI_SUCCESS;
 
+UnmapQueue:
+  Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Mapping);
+
 ReleaseQueue:
   VirtioRingUninit (Dev->VirtIo, Ring);
 
@@ -456,12 +468,22 @@ VirtioNetInitialize (
   //
   // step 4b, 4c -- allocate and report virtqueues
   //
-  Status = VirtioNetInitRing (Dev, VIRTIO_NET_Q_RX, &Dev->RxRing);
+  Status = VirtioNetInitRing (
+             Dev,
+             VIRTIO_NET_Q_RX,
+             &Dev->RxRing,
+             &Dev->RxRingMap
+             );
   if (EFI_ERROR (Status)) {
     goto DeviceFailed;
   }
 
-  Status = VirtioNetInitRing (Dev, VIRTIO_NET_Q_TX, &Dev->TxRing);
+  Status = VirtioNetInitRing (
+             Dev,
+             VIRTIO_NET_Q_TX,
+             &Dev->TxRing,
+             &Dev->TxRingMap
+             );
   if (EFI_ERROR (Status)) {
     goto ReleaseRxRing;
   }
@@ -510,9 +532,11 @@ AbortDevice:
   Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
 
 ReleaseTxRing:
+  Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->TxRingMap);
   VirtioRingUninit (Dev->VirtIo, &Dev->TxRing);
 
 ReleaseRxRing:
+  Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->RxRingMap);
   VirtioRingUninit (Dev->VirtIo, &Dev->RxRing);
 
 DeviceFailed:
diff --git a/OvmfPkg/VirtioNetDxe/SnpShutdown.c b/OvmfPkg/VirtioNetDxe/SnpShutdown.c
index 5e84191fbbdd..36f3253e77ad 100644
--- a/OvmfPkg/VirtioNetDxe/SnpShutdown.c
+++ b/OvmfPkg/VirtioNetDxe/SnpShutdown.c
@@ -67,7 +67,9 @@ VirtioNetShutdown (
   Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
   VirtioNetShutdownRx (Dev);
   VirtioNetShutdownTx (Dev);
+  Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->TxRingMap);
   VirtioRingUninit (Dev->VirtIo, &Dev->TxRing);
+  Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->RxRingMap);
   VirtioRingUninit (Dev->VirtIo, &Dev->RxRing);
 
   Dev->Snm.State = EfiSimpleNetworkStarted;
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 16/23] OvmfPkg/VirtioNetDxe: alloc RxBuf using AllocateSharedPages()
  2017-08-23 12:22 [PATCH v3 00/21] OvmfPkg/Virtio: introduce IOMMU-like member functions Brijesh Singh
                   ` (14 preceding siblings ...)
  2017-08-23 12:22 ` [PATCH v3 15/23] OvmfPkg/VirtioNetDxe: alloc Tx and Rx rings using AllocateSharedPage() Brijesh Singh
@ 2017-08-23 12:22 ` Brijesh Singh
  2017-08-23 12:22 ` [PATCH v3 17/23] OvmfPkg/VirtioNetDxe: dynamically alloc transmit header Brijesh Singh
                   ` (7 subsequent siblings)
  23 siblings, 0 replies; 46+ messages in thread
From: Brijesh Singh @ 2017-08-23 12:22 UTC (permalink / raw)
  To: edk2-devel
  Cc: Brijesh Singh, Ard Biesheuvel, Jordan Justen, Tom Lendacky,
	Laszlo Ersek

RxBuf is shared between guest and hypervisor, use
VIRTIO_DEVICE_PROTOCOL.AllocateSharedPages() to allocate this memory
region and map it with BusMasterCommonBuffer operation so that it can be
accessed by both guest and hypervisor.

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    | 76 ++++++++++++++++----
 OvmfPkg/VirtioNetDxe/SnpSharedHelpers.c |  7 +-
 4 files changed, 78 insertions(+), 14 deletions(-)

diff --git a/OvmfPkg/VirtioNetDxe/VirtioNet.h b/OvmfPkg/VirtioNetDxe/VirtioNet.h
index d80d441b50a4..7df51bd044f5 100644
--- a/OvmfPkg/VirtioNetDxe/VirtioNet.h
+++ b/OvmfPkg/VirtioNetDxe/VirtioNet.h
@@ -4,6 +4,7 @@
   Protocol instances for virtio-net devices.
 
   Copyright (C) 2013, Red Hat, Inc.
+  Copyright (c) 2017, AMD Inc, All rights reserved.<BR>
 
   This program and the accompanying materials are licensed and made available
   under the terms and conditions of the BSD License which accompanies this
@@ -85,6 +86,8 @@ typedef struct {
   VOID                        *RxRingMap;        // VirtioRingMap
   UINT8                       *RxBuf;            // VirtioNetInitRx
   UINT16                      RxLastUsed;        // VirtioNetInitRx
+  UINTN                       RxBufNoPages;      // VirtioNetInitRx
+  VOID                        *RxBufMap;         // VirtioMapSharedBuffer
 
   VRING                       TxRing;            // VirtioNetInitRing
   VOID                        *TxRingMap;        // VirtioRingMap
diff --git a/OvmfPkg/VirtioNetDxe/Events.c b/OvmfPkg/VirtioNetDxe/Events.c
index 6950c4d56df1..0586a82cdf09 100644
--- a/OvmfPkg/VirtioNetDxe/Events.c
+++ b/OvmfPkg/VirtioNetDxe/Events.c
@@ -95,4 +95,10 @@ VirtioNetExitBoot (
   //
   Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->TxRingMap);
   Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->RxRingMap);
+
+  //
+  // Unmap Rx buffer so that hypervisor will not be able get readable data after
+  // device is reset.
+  //
+  Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->RxBufMap);
 }
diff --git a/OvmfPkg/VirtioNetDxe/SnpInitialize.c b/OvmfPkg/VirtioNetDxe/SnpInitialize.c
index 803a38bd4239..bdc3fd7ac6a2 100644
--- a/OvmfPkg/VirtioNetDxe/SnpInitialize.c
+++ b/OvmfPkg/VirtioNetDxe/SnpInitialize.c
@@ -249,13 +249,17 @@ VirtioNetInitRx (
   IN OUT VNET_DEV *Dev
   )
 {
-  EFI_STATUS Status;
-  UINTN      VirtioNetReqSize;
-  UINTN      RxBufSize;
-  UINT16     RxAlwaysPending;
-  UINTN      PktIdx;
-  UINT16     DescIdx;
-  UINT8      *RxPtr;
+  EFI_STATUS            Status;
+  UINTN                 VirtioNetReqSize;
+  UINTN                 RxBufSize;
+  UINT16                RxAlwaysPending;
+  UINTN                 PktIdx;
+  UINT16                DescIdx;
+  UINT8                 *RxPtr;
+  UINTN                 NumBytes;
+  EFI_PHYSICAL_ADDRESS  RxBufDeviceAddress;
+  UINT64                BufBaseShift;
+  VOID                  *RxBuffer;
 
   //
   // In VirtIo 1.0, the NumBuffers field is mandatory. In 0.9.5, it depends on
@@ -280,11 +284,41 @@ VirtioNetInitRx (
   //
   RxAlwaysPending = (UINT16) MIN (Dev->RxRing.QueueSize / 2, VNET_MAX_PENDING);
 
-  Dev->RxBuf = AllocatePool (RxAlwaysPending * RxBufSize);
-  if (Dev->RxBuf == NULL) {
-    return EFI_OUT_OF_RESOURCES;
+  //
+  // The RxBuf is shared between guest and hypervisor, use SharedPages() to
+  // allocate this memory region and map it with BusMasterCommonBuffer
+  // operation so that it can be accessed equally by both guest and
+  // hypervisor.
+  //
+  NumBytes = RxAlwaysPending * RxBufSize;
+  Dev->RxBufNoPages = EFI_SIZE_TO_PAGES (NumBytes);
+  Status = Dev->VirtIo->AllocateSharedPages (
+                          Dev->VirtIo,
+                          Dev->RxBufNoPages,
+                          &RxBuffer
+                          );
+  if (EFI_ERROR (Status)) {
+    Status = EFI_OUT_OF_RESOURCES;
+    return Status;
   }
 
+  Status = VirtioMapAllBytesInSharedBuffer (
+             Dev->VirtIo,
+             VirtioOperationBusMasterCommonBuffer,
+             RxBuffer,
+             NumBytes,
+             &RxBufDeviceAddress,
+             &Dev->RxBufMap
+             );
+  if (EFI_ERROR (Status)) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto FreeSharedBuffer;
+  }
+
+  Dev->RxBuf = RxBuffer;
+
+  BufBaseShift = (UINT64) (UINTN)Dev->RxBuf - (UINT64) RxBufDeviceAddress;
+
   //
   // virtio-0.9.5, 2.4.2 Receiving Used Buffers From the Device
   //
@@ -306,6 +340,11 @@ VirtioNetInitRx (
   DescIdx = 0;
   RxPtr = Dev->RxBuf;
   for (PktIdx = 0; PktIdx < RxAlwaysPending; ++PktIdx) {
+    UINT64    Address;
+
+    Address = (UINTN) RxPtr;
+    Address += BufBaseShift;
+
     //
     // virtio-0.9.5, 2.4.1.2 Updating the Available Ring
     // invisible to the host until we update the Index Field
@@ -315,13 +354,13 @@ VirtioNetInitRx (
     //
     // virtio-0.9.5, 2.4.1.1 Placing Buffers into the Descriptor Table
     //
-    Dev->RxRing.Desc[DescIdx].Addr  = (UINTN) RxPtr;
+    Dev->RxRing.Desc[DescIdx].Addr  = Address;
     Dev->RxRing.Desc[DescIdx].Len   = (UINT32) VirtioNetReqSize;
     Dev->RxRing.Desc[DescIdx].Flags = VRING_DESC_F_WRITE | VRING_DESC_F_NEXT;
     Dev->RxRing.Desc[DescIdx].Next  = (UINT16) (DescIdx + 1);
     RxPtr += Dev->RxRing.Desc[DescIdx++].Len;
 
-    Dev->RxRing.Desc[DescIdx].Addr  = (UINTN) RxPtr;
+    Dev->RxRing.Desc[DescIdx].Addr  = Address;
     Dev->RxRing.Desc[DescIdx].Len   = (UINT32) (RxBufSize - VirtioNetReqSize);
     Dev->RxRing.Desc[DescIdx].Flags = VRING_DESC_F_WRITE;
     RxPtr += Dev->RxRing.Desc[DescIdx++].Len;
@@ -345,10 +384,21 @@ VirtioNetInitRx (
   Status = Dev->VirtIo->SetQueueNotify (Dev->VirtIo, VIRTIO_NET_Q_RX);
   if (EFI_ERROR (Status)) {
     Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
-    FreePool (Dev->RxBuf);
+    goto UnmapSharedBuffer;
   }
 
   return Status;
+
+UnmapSharedBuffer:
+  Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->RxBufMap);
+
+FreeSharedBuffer:
+  Dev->VirtIo->FreeSharedPages (
+                 Dev->VirtIo,
+                 Dev->RxBufNoPages,
+                 (VOID *) Dev->RxBuf
+                 );
+  return Status;
 }
 
 
diff --git a/OvmfPkg/VirtioNetDxe/SnpSharedHelpers.c b/OvmfPkg/VirtioNetDxe/SnpSharedHelpers.c
index 9fedb72fdbd4..4c9d9ece0790 100644
--- a/OvmfPkg/VirtioNetDxe/SnpSharedHelpers.c
+++ b/OvmfPkg/VirtioNetDxe/SnpSharedHelpers.c
@@ -39,7 +39,12 @@ VirtioNetShutdownRx (
   IN OUT VNET_DEV *Dev
   )
 {
-  FreePool (Dev->RxBuf);
+  Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->RxBufMap);
+  Dev->VirtIo->FreeSharedPages (
+                 Dev->VirtIo,
+                 Dev->RxBufNoPages,
+                 (VOID *) Dev->RxBuf
+                 );
 }
 
 
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 17/23] OvmfPkg/VirtioNetDxe: dynamically alloc transmit header
  2017-08-23 12:22 [PATCH v3 00/21] OvmfPkg/Virtio: introduce IOMMU-like member functions Brijesh Singh
                   ` (15 preceding siblings ...)
  2017-08-23 12:22 ` [PATCH v3 16/23] OvmfPkg/VirtioNetDxe: alloc RxBuf using AllocateSharedPages() Brijesh Singh
@ 2017-08-23 12:22 ` Brijesh Singh
  2017-08-23 12:22 ` [PATCH v3 18/23] OvmfPkg/VirtioNetDxe: map transmit buffer host address to device address Brijesh Singh
                   ` (6 subsequent siblings)
  23 siblings, 0 replies; 46+ messages in thread
From: Brijesh Singh @ 2017-08-23 12:22 UTC (permalink / raw)
  To: edk2-devel
  Cc: Brijesh Singh, Ard Biesheuvel, Jordan Justen, Tom Lendacky,
	Laszlo Ersek

A network packets are transmitted by placing them 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 the VIRTIO_1_0_NET_REQ 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    | 65 +++++++++++++++++---
 OvmfPkg/VirtioNetDxe/SnpSharedHelpers.c |  7 +++
 4 files changed, 72 insertions(+), 9 deletions(-)

diff --git a/OvmfPkg/VirtioNetDxe/VirtioNet.h b/OvmfPkg/VirtioNetDxe/VirtioNet.h
index 7df51bd044f5..3efe95a735d8 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;   // VirtioMapSharedBuffer
   UINT16                      TxLastUsed;        // VirtioNetInitTx
 } VNET_DEV;
 
diff --git a/OvmfPkg/VirtioNetDxe/Events.c b/OvmfPkg/VirtioNetDxe/Events.c
index 0586a82cdf09..9366aa00a1b3 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 will not be able to 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 bdc3fd7ac6a2..3d4eb70aa630 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>
 
@@ -151,8 +152,12 @@ VirtioNetInitTx (
   IN OUT VNET_DEV *Dev
   )
 {
-  UINTN TxSharedReqSize;
-  UINTN PktIdx;
+  UINTN                 TxSharedReqSize;
+  UINTN                 PktIdx;
+  EFI_STATUS            Status;
+  EFI_PHYSICAL_ADDRESS  DeviceAddress;
+  UINT64                BufBaseShift;
+  VOID                  *TxSharedReqBuffer;
 
   Dev->TxMaxPending = (UINT16) MIN (Dev->TxRing.QueueSize / 2,
                                  VNET_MAX_PENDING);
@@ -164,24 +169,60 @@ 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)),
+                          &TxSharedReqBuffer
+                          );
+  if (EFI_ERROR (Status)) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Status = VirtioMapAllBytesInSharedBuffer (
+             Dev->VirtIo,
+             VirtioOperationBusMasterCommonBuffer,
+             TxSharedReqBuffer,
+             sizeof *(Dev->TxSharedReq),
+             &DeviceAddress,
+             &Dev->TxSharedReqMap
+             );
+  if (EFI_ERROR (Status)) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto FreeBuffer;
+  }
+
+  Dev->TxSharedReq = TxSharedReqBuffer;
+
+  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  = 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);
@@ -196,13 +237,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
@@ -217,6 +258,14 @@ 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 4c9d9ece0790..aeb9e6605f0d 100644
--- a/OvmfPkg/VirtioNetDxe/SnpSharedHelpers.c
+++ b/OvmfPkg/VirtioNetDxe/SnpSharedHelpers.c
@@ -54,5 +54,12 @@ VirtioNetShutdownTx (
   IN OUT VNET_DEV *Dev
   )
 {
+  Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->TxSharedReqMap);
+  Dev->VirtIo->FreeSharedPages (
+                 Dev->VirtIo,
+                 EFI_SIZE_TO_PAGES (sizeof *(Dev->TxSharedReq)),
+                 (VOID *) Dev->TxSharedReq
+                 );
+
   FreePool (Dev->TxFreeStack);
 }
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 18/23] OvmfPkg/VirtioNetDxe: map transmit buffer host address to device address
  2017-08-23 12:22 [PATCH v3 00/21] OvmfPkg/Virtio: introduce IOMMU-like member functions Brijesh Singh
                   ` (16 preceding siblings ...)
  2017-08-23 12:22 ` [PATCH v3 17/23] OvmfPkg/VirtioNetDxe: dynamically alloc transmit header Brijesh Singh
@ 2017-08-23 12:22 ` Brijesh Singh
  2017-08-23 12:22 ` [PATCH v3 19/23] OvmfPkg/Virtio10: define VIRITO_F_IOMMU_PLATFORM feature bit Brijesh Singh
                   ` (5 subsequent siblings)
  23 siblings, 0 replies; 46+ messages in thread
From: Brijesh Singh @ 2017-08-23 12:22 UTC (permalink / raw)
  To: edk2-devel
  Cc: Brijesh Singh, Ard Biesheuvel, Jordan Justen, Tom Lendacky,
	Laszlo Ersek

Update VirtioNetTransmit() function, to map the callers transmit buffer
host address to a device address.

Since the transmit buffers are returned back to caller in
VirtioNetGetStatus() hence we maintain a simple list to maintain 1:1
mapping between host address to device address. The list is consulted
when we return back the callers buffer after data is successfully
transmitted.

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        |  17 +++
 OvmfPkg/VirtioNetDxe/SnpGetStatus.c     |  29 ++++-
 OvmfPkg/VirtioNetDxe/SnpSharedHelpers.c | 119 ++++++++++++++++++++
 OvmfPkg/VirtioNetDxe/SnpTransmit.c      |  30 +++--
 4 files changed, 184 insertions(+), 11 deletions(-)

diff --git a/OvmfPkg/VirtioNetDxe/VirtioNet.h b/OvmfPkg/VirtioNetDxe/VirtioNet.h
index 3efe95a735d8..ac75bdeeb449 100644
--- a/OvmfPkg/VirtioNetDxe/VirtioNet.h
+++ b/OvmfPkg/VirtioNetDxe/VirtioNet.h
@@ -269,6 +269,23 @@ VirtioNetShutdownTx (
   IN OUT VNET_DEV *Dev
   );
 
+EFI_STATUS
+EFIAPI
+VirtioMapTxBuf (
+  IN  VNET_DEV              *Dev,
+  IN  EFI_PHYSICAL_ADDRESS  HostAddress,
+  IN  UINTN                 NumberOfBytes,
+  OUT EFI_PHYSICAL_ADDRESS  *DeviceAddress
+  );
+
+EFI_STATUS
+EFIAPI
+VirtioUnmapTxBuf (
+  IN  VNET_DEV              *Dev,
+  OUT EFI_PHYSICAL_ADDRESS  *HostAddress,
+  IN  EFI_PHYSICAL_ADDRESS  DeviceAddress
+  );
+
 //
 // event callbacks
 //
diff --git a/OvmfPkg/VirtioNetDxe/SnpGetStatus.c b/OvmfPkg/VirtioNetDxe/SnpGetStatus.c
index 694940ea1d97..d532551456d0 100644
--- a/OvmfPkg/VirtioNetDxe/SnpGetStatus.c
+++ b/OvmfPkg/VirtioNetDxe/SnpGetStatus.c
@@ -5,6 +5,7 @@
 
   Copyright (C) 2013, Red Hat, Inc.
   Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2017, AMD Inc, All rights reserved.<BR>
 
   This program and the accompanying materials are licensed and made available
   under the terms and conditions of the BSD License which accompanies this
@@ -47,7 +48,8 @@
   @retval EFI_INVALID_PARAMETER One or more of the parameters has an
                                 unsupported value.
   @retval EFI_DEVICE_ERROR      The command could not be sent to the network
-                                interface.
+                                interface or failed to map TxBuf to bus master
+                                address.
   @retval EFI_UNSUPPORTED       This function is not supported by the network
                                 interface.
 
@@ -126,8 +128,10 @@ VirtioNetGetStatus (
       *TxBuf = NULL;
     }
     else {
-      UINT16 UsedElemIdx;
-      UINT32 DescIdx;
+      UINT16                UsedElemIdx;
+      UINT32                DescIdx;
+      EFI_PHYSICAL_ADDRESS  BufferAddress;
+      EFI_PHYSICAL_ADDRESS  DeviceAddress;
 
       //
       // fetch the first descriptor among those that the hypervisor reports
@@ -141,9 +145,26 @@ VirtioNetGetStatus (
       ASSERT (DescIdx < (UINT32) (2 * Dev->TxMaxPending - 1));
 
       //
+      // Ring descriptor contains the device address of buffer.
+      // Lets unmap the device address and get its corresponding
+      // host buffer address.
+      //
+      DeviceAddress = Dev->TxRing.Desc[DescIdx + 1].Addr;
+      Status = VirtioUnmapTxBuf (
+                 Dev,
+                 &BufferAddress,
+                 DeviceAddress
+                 );
+      if (EFI_ERROR (Status)) {
+        Status = EFI_DEVICE_ERROR;
+        goto Exit;
+      }
+
+      //
+      //
       // report buffer address to caller that has been enqueued by caller
       //
-      *TxBuf = (VOID *)(UINTN) Dev->TxRing.Desc[DescIdx + 1].Addr;
+      *TxBuf = (VOID *)(UINTN) BufferAddress;
 
       //
       // now this descriptor can be used again to enqueue a transmit buffer
diff --git a/OvmfPkg/VirtioNetDxe/SnpSharedHelpers.c b/OvmfPkg/VirtioNetDxe/SnpSharedHelpers.c
index aeb9e6605f0d..5e1c610c4a18 100644
--- a/OvmfPkg/VirtioNetDxe/SnpSharedHelpers.c
+++ b/OvmfPkg/VirtioNetDxe/SnpSharedHelpers.c
@@ -14,10 +14,29 @@
 
 **/
 
+#include <Library/BaseLib.h>
 #include <Library/MemoryAllocationLib.h>
 
 #include "VirtioNet.h"
 
+#define PRIVATE_TXBUF_SIGNATURE  SIGNATURE_32 ('t', 'x', 'b', 'f')
+typedef struct {
+  UINT32                Signature;
+  LIST_ENTRY            Link;
+  EFI_PHYSICAL_ADDRESS  HostAddress;
+  EFI_PHYSICAL_ADDRESS  DeviceAddress;
+  VOID                  *Mapping;
+} PRIVATE_TXBUF_ENTRY;
+#define PRIVATE_TXBUF_FROM_LINK(a) CR (a, PRIVATE_TXBUF_ENTRY, Link, \
+                                       PRIVATE_TXBUF_SIGNATURE)
+
+//
+// List of Txbuf queued
+//
+STATIC LIST_ENTRY mTxBufMapList = INITIALIZE_LIST_HEAD_VARIABLE (
+                                    mTxBufMapList
+                                    );
+
 /**
   Release RX and TX resources on the boundary of the
   EfiSimpleNetworkInitialized state.
@@ -63,3 +82,103 @@ VirtioNetShutdownTx (
 
   FreePool (Dev->TxFreeStack);
 }
+
+EFI_STATUS
+EFIAPI
+VirtioMapTxBuf (
+  IN  VNET_DEV               *Dev,
+  IN  EFI_PHYSICAL_ADDRESS   HostAddress,
+  IN  UINTN                  NumberOfBytes,
+  OUT EFI_PHYSICAL_ADDRESS   *DeviceAddress
+  )
+{
+  EFI_STATUS             Status;
+  PRIVATE_TXBUF_ENTRY   *Private;
+
+  Private = AllocatePool (sizeof (*Private));
+  if (Private == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Private->Signature = PRIVATE_TXBUF_SIGNATURE;
+  Private->HostAddress = HostAddress;
+
+  Status = VirtioMapAllBytesInSharedBuffer (
+             Dev->VirtIo,
+             VirtioOperationBusMasterRead,
+             (VOID *) (UINTN) Private->HostAddress,
+             NumberOfBytes,
+             &Private->DeviceAddress,
+             &Private->Mapping
+             );
+  if (EFI_ERROR (Status)) {
+    goto FreePool;
+  }
+
+  *DeviceAddress = Private->DeviceAddress;
+
+  //
+  // Add the mapping information into internal list so that we can retrieve
+  // the HostAddress from Unmap().
+  //
+  InsertTailList (&mTxBufMapList, &Private->Link);
+
+  return EFI_SUCCESS;
+
+FreePool:
+  FreePool (Private);
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+VirtioUnmapTxBuf (
+  IN  VNET_DEV               *Dev,
+  OUT EFI_PHYSICAL_ADDRESS   *HostAddress,
+  IN  EFI_PHYSICAL_ADDRESS   DeviceAddress
+  )
+{
+  EFI_STATUS             Status;
+  PRIVATE_TXBUF_ENTRY   *Private;
+  LIST_ENTRY            *Link;
+  BOOLEAN                Found;
+
+  //
+  //set Private to suppress incorrect compiler/analyzer warnings
+  //
+  Private = NULL;
+
+  //
+  // Iterate through internal txbuf list to find mapping for a given
+  // DeviceAddress.
+  //
+  Found = FALSE;
+  for (Link = GetFirstNode (&mTxBufMapList)
+       ; !IsNull (&mTxBufMapList, Link)
+       ; Link = GetNextNode (&mTxBufMapList, Link)
+      ) {
+    Private = PRIVATE_TXBUF_FROM_LINK (Link);
+    if (Private->DeviceAddress == DeviceAddress) {
+      Found = TRUE;
+      break;
+    }
+  }
+
+  //
+  // We failed to find mapping for the given DeviceAddress
+  // (this should never happen)
+  //
+  ASSERT (Found);
+
+  Status = Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Private->Mapping);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  *HostAddress = Private->HostAddress;
+
+  RemoveEntryList (&Private->Link);
+  FreePool (Private);
+
+  return EFI_SUCCESS;
+}
diff --git a/OvmfPkg/VirtioNetDxe/SnpTransmit.c b/OvmfPkg/VirtioNetDxe/SnpTransmit.c
index 7ca40d5d0650..f71953c92c99 100644
--- a/OvmfPkg/VirtioNetDxe/SnpTransmit.c
+++ b/OvmfPkg/VirtioNetDxe/SnpTransmit.c
@@ -55,7 +55,8 @@
   @retval EFI_INVALID_PARAMETER One or more of the parameters has an
                                 unsupported value.
   @retval EFI_DEVICE_ERROR      The command could not be sent to the network
-                                interface.
+                                interface or failed to map the Buffer to
+                                bus master address.
   @retval EFI_UNSUPPORTED       This function is not supported by the network
                                 interface.
 
@@ -73,11 +74,12 @@ VirtioNetTransmit (
   IN UINT16                      *Protocol OPTIONAL
   )
 {
-  VNET_DEV   *Dev;
-  EFI_TPL    OldTpl;
-  EFI_STATUS Status;
-  UINT16     DescIdx;
-  UINT16     AvailIdx;
+  VNET_DEV              *Dev;
+  EFI_TPL               OldTpl;
+  EFI_STATUS            Status;
+  UINT16                DescIdx;
+  UINT16                AvailIdx;
+  EFI_PHYSICAL_ADDRESS  DeviceAddress;
 
   if (This == NULL || BufferSize == 0 || Buffer == NULL) {
     return EFI_INVALID_PARAMETER;
@@ -144,10 +146,24 @@ VirtioNetTransmit (
   }
 
   //
+  // Map the transmit buffer HostAddress to a DeviceAddress
+  //
+  Status = VirtioMapTxBuf (
+             Dev,
+             (EFI_PHYSICAL_ADDRESS) (UINTN) Buffer,
+             BufferSize,
+             &DeviceAddress
+             );
+  if (EFI_ERROR (Status)) {
+    Status = EFI_DEVICE_ERROR;
+    goto Exit;
+  }
+
+  //
   // virtio-0.9.5, 2.4.1 Supplying Buffers to The Device
   //
   DescIdx = Dev->TxFreeStack[Dev->TxCurPending++];
-  Dev->TxRing.Desc[DescIdx + 1].Addr  = (UINTN) Buffer;
+  Dev->TxRing.Desc[DescIdx + 1].Addr  = (UINTN) DeviceAddress;
   Dev->TxRing.Desc[DescIdx + 1].Len   = (UINT32) BufferSize;
 
   //
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 19/23] OvmfPkg/Virtio10: define VIRITO_F_IOMMU_PLATFORM feature bit
  2017-08-23 12:22 [PATCH v3 00/21] OvmfPkg/Virtio: introduce IOMMU-like member functions Brijesh Singh
                   ` (17 preceding siblings ...)
  2017-08-23 12:22 ` [PATCH v3 18/23] OvmfPkg/VirtioNetDxe: map transmit buffer host address to device address Brijesh Singh
@ 2017-08-23 12:22 ` Brijesh Singh
  2017-08-23 23:04   ` Laszlo Ersek
  2017-08-23 12:22 ` [PATCH v3 20/23] OvmfPkg/VirtioRngDxe: negotiate VIRITO_F_IOMMU_PLATFORM Brijesh Singh
                   ` (4 subsequent siblings)
  23 siblings, 1 reply; 46+ messages in thread
From: Brijesh Singh @ 2017-08-23 12:22 UTC (permalink / raw)
  To: edk2-devel
  Cc: Brijesh Singh, Ard Biesheuvel, Jordan Justen, Tom Lendacky,
	Laszlo Ersek

This feature indicates that the device is behind an IOMMU that translates
bus addresses from the device into physical addresses in memory.  If this
feature bit is set to 0, then the device emits physical addresses which
are not translated further, even though an IOMMU may be present.
see [1] for more infromation

[1] https://lists.oasis-open.org/archives/virtio-dev/201610/msg00121.html

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/Include/IndustryStandard/Virtio10.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/OvmfPkg/Include/IndustryStandard/Virtio10.h b/OvmfPkg/Include/IndustryStandard/Virtio10.h
index 4c9b62a3cf59..c5efb5cfcb8a 100644
--- a/OvmfPkg/Include/IndustryStandard/Virtio10.h
+++ b/OvmfPkg/Include/IndustryStandard/Virtio10.h
@@ -2,6 +2,7 @@
   Definitions from the VirtIo 1.0 specification (csprd05).
 
   Copyright (C) 2016, Red Hat, Inc.
+  Copyright (C) 2017, AMD, Inc.
 
   This program and the accompanying materials are licensed and made available
   under the terms and conditions of the BSD License which accompanies this
@@ -81,6 +82,7 @@ typedef struct {
 //
 // VirtIo 1.0 reserved (device-independent) feature bits
 //
-#define VIRTIO_F_VERSION_1 BIT32
+#define VIRTIO_F_VERSION_1      BIT32
+#define VIRTIO_F_IOMMU_PLATFORM BIT33
 
 #endif // _VIRTIO_1_0_H_
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 20/23] OvmfPkg/VirtioRngDxe: negotiate VIRITO_F_IOMMU_PLATFORM
  2017-08-23 12:22 [PATCH v3 00/21] OvmfPkg/Virtio: introduce IOMMU-like member functions Brijesh Singh
                   ` (18 preceding siblings ...)
  2017-08-23 12:22 ` [PATCH v3 19/23] OvmfPkg/Virtio10: define VIRITO_F_IOMMU_PLATFORM feature bit Brijesh Singh
@ 2017-08-23 12:22 ` Brijesh Singh
  2017-08-23 23:21   ` Laszlo Ersek
  2017-08-23 12:22 ` [PATCH v3 21/23] OvmfPkg/VirtioBlkDxe: " Brijesh Singh
                   ` (3 subsequent siblings)
  23 siblings, 1 reply; 46+ messages in thread
From: Brijesh Singh @ 2017-08-23 12:22 UTC (permalink / raw)
  To: edk2-devel
  Cc: Brijesh Singh, Ard Biesheuvel, Jordan Justen, Tom Lendacky,
	Laszlo Ersek

In previous patches, we have implemented IOMMU-like member functions in
VIRTIO_DEVICE_PROTOCOL to translate the physical address to bus address
and virtio drivers are updated to use those member functions. We do not
need to do anything special when VIRTIO_F_IOMMU_PLATFORM bit is present
hence treat it in parallel with VIRTIO_F_VERSION_1.

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/VirtioRngDxe/VirtioRng.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/OvmfPkg/VirtioRngDxe/VirtioRng.c b/OvmfPkg/VirtioRngDxe/VirtioRng.c
index 59f32d343179..32512d882f7d 100644
--- a/OvmfPkg/VirtioRngDxe/VirtioRng.c
+++ b/OvmfPkg/VirtioRngDxe/VirtioRng.c
@@ -278,7 +278,7 @@ VirtioRngInit (
     goto Failed;
   }
 
-  Features &= VIRTIO_F_VERSION_1;
+  Features &= VIRTIO_F_VERSION_1 | VIRTIO_F_IOMMU_PLATFORM;
 
   //
   // In virtio-1.0, feature negotiation is expected to complete before queue
@@ -359,7 +359,7 @@ VirtioRngInit (
   // step 5 -- Report understood features and guest-tuneables.
   //
   if (Dev->VirtIo->Revision < VIRTIO_SPEC_REVISION (1, 0, 0)) {
-    Features &= ~(UINT64)VIRTIO_F_VERSION_1;
+    Features &= ~(UINT64)VIRTIO_F_VERSION_1 | VIRTIO_F_IOMMU_PLATFORM;
     Status = Dev->VirtIo->SetGuestFeatures (Dev->VirtIo, Features);
     if (EFI_ERROR (Status)) {
       goto UnmapQueue;
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 21/23] OvmfPkg/VirtioBlkDxe: negotiate VIRITO_F_IOMMU_PLATFORM
  2017-08-23 12:22 [PATCH v3 00/21] OvmfPkg/Virtio: introduce IOMMU-like member functions Brijesh Singh
                   ` (19 preceding siblings ...)
  2017-08-23 12:22 ` [PATCH v3 20/23] OvmfPkg/VirtioRngDxe: negotiate VIRITO_F_IOMMU_PLATFORM Brijesh Singh
@ 2017-08-23 12:22 ` Brijesh Singh
  2017-08-23 12:22 ` [PATCH v3 22/23] OvmfPkg/VirtioScsiDxe: " Brijesh Singh
                   ` (2 subsequent siblings)
  23 siblings, 0 replies; 46+ messages in thread
From: Brijesh Singh @ 2017-08-23 12:22 UTC (permalink / raw)
  To: edk2-devel
  Cc: Brijesh Singh, Ard Biesheuvel, Jordan Justen, Tom Lendacky,
	Laszlo Ersek

In previous patches, we have implemented IOMMU-like member functions in
VIRTIO_DEVICE_PROTOCOL to translate the physical address to bus address
and virtio drivers are updated to use those member functions. We do not
need to do anything special when VIRTIO_F_IOMMU_PLATFORM bit is present
hence treat it in parallel with VIRTIO_F_VERSION_1.

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/VirtioBlkDxe/VirtioBlk.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
index e23762743f75..fa6c527c0d28 100644
--- a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
+++ b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
@@ -824,7 +824,8 @@ VirtioBlkInit (
   }
 
   Features &= VIRTIO_BLK_F_BLK_SIZE | VIRTIO_BLK_F_TOPOLOGY | VIRTIO_BLK_F_RO |
-              VIRTIO_BLK_F_FLUSH | VIRTIO_F_VERSION_1;
+              VIRTIO_BLK_F_FLUSH | VIRTIO_F_VERSION_1 |
+              VIRTIO_F_IOMMU_PLATFORM;
 
   //
   // In virtio-1.0, feature negotiation is expected to complete before queue
@@ -902,7 +903,7 @@ VirtioBlkInit (
   // step 5 -- Report understood features.
   //
   if (Dev->VirtIo->Revision < VIRTIO_SPEC_REVISION (1, 0, 0)) {
-    Features &= ~(UINT64)VIRTIO_F_VERSION_1;
+    Features &= ~(UINT64)VIRTIO_F_VERSION_1 | VIRTIO_F_IOMMU_PLATFORM;
     Status = Dev->VirtIo->SetGuestFeatures (Dev->VirtIo, Features);
     if (EFI_ERROR (Status)) {
       goto UnmapQueue;
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 22/23] OvmfPkg/VirtioScsiDxe: negotiate VIRITO_F_IOMMU_PLATFORM
  2017-08-23 12:22 [PATCH v3 00/21] OvmfPkg/Virtio: introduce IOMMU-like member functions Brijesh Singh
                   ` (20 preceding siblings ...)
  2017-08-23 12:22 ` [PATCH v3 21/23] OvmfPkg/VirtioBlkDxe: " Brijesh Singh
@ 2017-08-23 12:22 ` Brijesh Singh
  2017-08-23 12:22 ` [PATCH v3 23/23] OvmfPkg/VirtioNetDxe: " Brijesh Singh
  2017-08-24  0:26 ` [PATCH v3 00/21] OvmfPkg/Virtio: introduce IOMMU-like member functions Laszlo Ersek
  23 siblings, 0 replies; 46+ messages in thread
From: Brijesh Singh @ 2017-08-23 12:22 UTC (permalink / raw)
  To: edk2-devel
  Cc: Brijesh Singh, Ard Biesheuvel, Jordan Justen, Tom Lendacky,
	Laszlo Ersek

In previous patches, we have implemented IOMMU-like member functions in
VIRTIO_DEVICE_PROTOCOL to translate the physical address to bus address
and virtio drivers are updated to use those member functions. We do not
need to do anything special when VIRTIO_F_IOMMU_PLATFORM bit is present
hence treat it in parallel with VIRTIO_F_VERSION_1.

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/VirtioScsiDxe/VirtioScsi.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/OvmfPkg/VirtioScsiDxe/VirtioScsi.c b/OvmfPkg/VirtioScsiDxe/VirtioScsi.c
index ed7fd1dd58a8..91a008b2caa4 100644
--- a/OvmfPkg/VirtioScsiDxe/VirtioScsi.c
+++ b/OvmfPkg/VirtioScsiDxe/VirtioScsi.c
@@ -934,7 +934,8 @@ VirtioScsiInit (
     goto Failed;
   }
 
-  Features &= VIRTIO_SCSI_F_INOUT | VIRTIO_F_VERSION_1;
+  Features &= VIRTIO_SCSI_F_INOUT | VIRTIO_F_VERSION_1 |
+              VIRTIO_F_IOMMU_PLATFORM;
 
   //
   // In virtio-1.0, feature negotiation is expected to complete before queue
@@ -1014,7 +1015,7 @@ VirtioScsiInit (
   // step 5 -- Report understood features and guest-tuneables.
   //
   if (Dev->VirtIo->Revision < VIRTIO_SPEC_REVISION (1, 0, 0)) {
-    Features &= ~(UINT64)VIRTIO_F_VERSION_1;
+    Features &= ~(UINT64)VIRTIO_F_VERSION_1 | VIRTIO_F_IOMMU_PLATFORM;
     Status = Dev->VirtIo->SetGuestFeatures (Dev->VirtIo, Features);
     if (EFI_ERROR (Status)) {
       goto UnmapQueue;
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 23/23] OvmfPkg/VirtioNetDxe: negotiate VIRITO_F_IOMMU_PLATFORM
  2017-08-23 12:22 [PATCH v3 00/21] OvmfPkg/Virtio: introduce IOMMU-like member functions Brijesh Singh
                   ` (21 preceding siblings ...)
  2017-08-23 12:22 ` [PATCH v3 22/23] OvmfPkg/VirtioScsiDxe: " Brijesh Singh
@ 2017-08-23 12:22 ` Brijesh Singh
  2017-08-24  0:26 ` [PATCH v3 00/21] OvmfPkg/Virtio: introduce IOMMU-like member functions Laszlo Ersek
  23 siblings, 0 replies; 46+ messages in thread
From: Brijesh Singh @ 2017-08-23 12:22 UTC (permalink / raw)
  To: edk2-devel
  Cc: Brijesh Singh, Ard Biesheuvel, Jordan Justen, Tom Lendacky,
	Laszlo Ersek

In previous patches, we have implemented IOMMU-like member functions in
VIRTIO_DEVICE_PROTOCOL to translate the physical address to bus address
and virtio drivers are updated to use those member functions. We do not
need to do anything special when VIRTIO_F_IOMMU_PLATFORM bit is present
hence treat it in parallel with VIRTIO_F_VERSION_1.

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/SnpInitialize.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/OvmfPkg/VirtioNetDxe/SnpInitialize.c b/OvmfPkg/VirtioNetDxe/SnpInitialize.c
index 3d4eb70aa630..750cea10abe7 100644
--- a/OvmfPkg/VirtioNetDxe/SnpInitialize.c
+++ b/OvmfPkg/VirtioNetDxe/SnpInitialize.c
@@ -551,7 +551,8 @@ VirtioNetInitialize (
   ASSERT (Dev->Snm.MediaPresentSupported ==
     !!(Features & VIRTIO_NET_F_STATUS));
 
-  Features &= VIRTIO_NET_F_MAC | VIRTIO_NET_F_STATUS | VIRTIO_F_VERSION_1;
+  Features &= VIRTIO_NET_F_MAC | VIRTIO_NET_F_STATUS | VIRTIO_F_VERSION_1 |
+              VIRTIO_F_IOMMU_PLATFORM;
 
   //
   // In virtio-1.0, feature negotiation is expected to complete before queue
@@ -591,7 +592,7 @@ VirtioNetInitialize (
   // step 5 -- keep only the features we want
   //
   if (Dev->VirtIo->Revision < VIRTIO_SPEC_REVISION (1, 0, 0)) {
-    Features &= ~(UINT64)VIRTIO_F_VERSION_1;
+    Features &= ~(UINT64)VIRTIO_F_VERSION_1 | VIRTIO_F_IOMMU_PLATFORM;
     Status = Dev->VirtIo->SetGuestFeatures (Dev->VirtIo, Features);
     if (EFI_ERROR (Status)) {
       goto ReleaseTxRing;
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 01/23] OvmfPkg: introduce IOMMU-like member functions to VIRTIO_DEVICE_PROTOCOL
  2017-08-23 12:22 ` [PATCH v3 01/23] OvmfPkg: introduce IOMMU-like member functions to VIRTIO_DEVICE_PROTOCOL Brijesh Singh
@ 2017-08-23 19:04   ` Laszlo Ersek
  0 siblings, 0 replies; 46+ messages in thread
From: Laszlo Ersek @ 2017-08-23 19:04 UTC (permalink / raw)
  To: Brijesh Singh, edk2-devel; +Cc: Jordan Justen, Tom Lendacky, Ard Biesheuvel

On 08/23/17 14:22, Brijesh Singh wrote:
> The patch extends VIRTIO_DEVICE_PROTOCOL to provide the following new
> member functions:
> 
> - AllocateSharedPages : allocate a memory region suitable for sharing
>    between guest and hypervisor (e.g ring buffer).
> 
> - FreeSharedPages: free the memory allocated using AllocateSharedPages ().
> 
> - MapSharedBuffer: map a host address to device address suitable to share
>    with device for bus master operations.
> 
> - UnmapSharedBuffer: unmap the device address obtained through the
>    MapSharedBuffer().
> 
> We're free to extend the protocol structure without changing the protocol
> GUID, or bumping any protocol version fields (of which we currently have
> none), because VIRTIO_DEVICE_PROTOCOL is internal to edk2 by design --
> see the disclaimers in "VirtioDevice.h".
> 
> The patch implements Laszlo's recommendation [1].
> 
> [1] http://mid.mail-archive.com/841bec5f-6f6e-8b1f-25ba-0fd37a915b72@redhat.com
> 
> 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>
> ---
>  OvmfPkg/Include/Protocol/VirtioDevice.h | 143 ++++++++++++++++++++
>  1 file changed, 143 insertions(+)

Reviewed-by: Laszlo Ersek <lersek@redhat.com>

Thanks!
Laszlo

> diff --git a/OvmfPkg/Include/Protocol/VirtioDevice.h b/OvmfPkg/Include/Protocol/VirtioDevice.h
> index fc166bd1a2b4..9a01932958a2 100644
> --- a/OvmfPkg/Include/Protocol/VirtioDevice.h
> +++ b/OvmfPkg/Include/Protocol/VirtioDevice.h
> @@ -5,6 +5,7 @@
>    and should not be used outside of the EDK II tree.
>  
>    Copyright (c) 2013, ARM Ltd. All rights reserved.<BR>
> +  Copyright (c) 2017, AMD Inc, All rights reserved.<BR>
>  
>    This program and the accompanying materials are licensed and made available
>    under the terms and conditions of the BSD License which accompanies this
> @@ -33,6 +34,25 @@
>  
>  typedef struct _VIRTIO_DEVICE_PROTOCOL  VIRTIO_DEVICE_PROTOCOL;
>  
> +//
> +// VIRTIO Operation for VIRTIO_MAP_SHARED
> +//
> +typedef enum {
> +  //
> +  // A read operation from system memory by a bus master
> +  //
> +  VirtioOperationBusMasterRead,
> +  //
> +  // A write operation to system memory by a bus master
> +  //
> +  VirtioOperationBusMasterWrite,
> +  //
> +  // Provides both read and write access to system memory by both the
> +  // processor and a bus master
> +  //
> +  VirtioOperationBusMasterCommonBuffer,
> +} VIRTIO_MAP_OPERATION;
> +
>  /**
>  
>    Read a word from the device-specific I/O region of the Virtio Header.
> @@ -321,6 +341,121 @@ EFI_STATUS
>    IN UINT8                   DeviceStatus
>    );
>  
> +/**
> +
> +  Allocates pages that are suitable for an VirtioOperationBusMasterCommonBuffer
> +  mapping. This means that the buffer allocated by this function supports
> +  simultaneous access by both the processor and the bus master. The device
> +  address that the bus master uses to access the buffer must be retrieved with
> +  a call to VIRTIO_MAP_SHARED.
> +
> +  @param[in]      This              The protocol instance pointer.
> +
> +  @param[in]      Pages             The number of pages to allocate.
> +
> +  @param[in,out]  HostAddress       A pointer to store the system memory base
> +                                    address of the allocated range.
> +
> +  @retval EFI_SUCCESS               The requested memory pages were allocated.
> +  @retval EFI_OUT_OF_RESOURCES      The memory pages could not be allocated.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *VIRTIO_ALLOCATE_SHARED)(
> +  IN     VIRTIO_DEVICE_PROTOCOL                   *This,
> +  IN     UINTN                                    Pages,
> +  IN OUT VOID                                     **HostAddress
> +  );
> +
> +/**
> +  Frees memory that was allocated with VIRTIO_ALLOCATE_SHARED.
> +
> +  @param[in]  This           The protocol instance pointer.
> +
> +  @param[in]  Pages          The number of pages to free.
> +
> +  @param[in]  HostAddress    The system memory base address of the allocated
> +                             range.
> +
> +**/
> +typedef
> +VOID
> +(EFIAPI *VIRTIO_FREE_SHARED)(
> +  IN  VIRTIO_DEVICE_PROTOCOL                   *This,
> +  IN  UINTN                                    Pages,
> +  IN  VOID                                     *HostAddress
> +  );
> +
> +/**
> +  Provides the virtio device address required to access system memory from a
> +  DMA bus master.
> +
> +  The interface follows the same usage pattern as defined in UEFI spec 2.6
> +  (Section 13.2 PCI Root Bridge I/O Protocol)
> +
> +  @param[in]     This             The protocol instance pointer.
> +
> +  @param[in]     Operation        Indicates if the bus master is going to
> +                                  read or write to system memory.
> +
> +  @param[in]     HostAddress      The system memory address to map to shared
> +                                  buffer address.
> +
> +  @param[in,out] NumberOfBytes    On input the number of bytes to map.
> +                                  On output the number of bytes that were
> +                                  mapped.
> +
> +  @param[out]    DeviceAddress    The resulting shared map address for the
> +                                  bus master to access the hosts HostAddress.
> +
> +  @param[out]    Mapping          A resulting token to pass to
> +                                  VIRTIO_UNMAP_SHARED.
> +
> +  @retval EFI_SUCCESS             The range was mapped for the returned
> +                                  NumberOfBytes.
> +  @retval EFI_UNSUPPORTED         The HostAddress cannot be mapped as a
> +                                  common buffer.
> +  @retval EFI_INVALID_PARAMETER   One or more parameters are invalid.
> +  @retval EFI_OUT_OF_RESOURCES    The request could not be completed due to
> +                                  a lack of resources.
> +  @retval EFI_DEVICE_ERROR        The system hardware could not map the
> +                                  requested address.
> +**/
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *VIRTIO_MAP_SHARED) (
> +  IN     VIRTIO_DEVICE_PROTOCOL       *This,
> +  IN     VIRTIO_MAP_OPERATION         Operation,
> +  IN     VOID                         *HostAddress,
> +  IN OUT UINTN                        *NumberOfBytes,
> +  OUT    EFI_PHYSICAL_ADDRESS         *DeviceAddress,
> +  OUT    VOID                         **Mapping
> +  );
> +
> +/**
> +  Completes the VIRTIO_MAP_SHARED operation and releases any corresponding
> +  resources.
> +
> +  @param[in]  This               The protocol instance pointer.
> +
> +  @param[in]  Mapping            The mapping token returned from
> +                                 VIRTIO_MAP_SHARED.
> +
> +  @retval EFI_SUCCESS            The range was unmapped.
> +  @retval EFI_INVALID_PARAMETER  Mapping is not a value that was returned by
> +                                 VIRTIO_MAP_SHARED. Passing an invalid Mapping
> +                                 token can cause undefined behavior.
> +  @retval EFI_DEVICE_ERROR       The data was not committed to the target
> +                                 system memory.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *VIRTIO_UNMAP_SHARED)(
> +  IN  VIRTIO_DEVICE_PROTOCOL    *This,
> +  IN  VOID                      *Mapping
> +  );
>  
>  ///
>  ///  This protocol provides an abstraction over the VirtIo transport layer
> @@ -361,6 +496,14 @@ struct _VIRTIO_DEVICE_PROTOCOL {
>    //
>    VIRTIO_DEVICE_WRITE         WriteDevice;
>    VIRTIO_DEVICE_READ          ReadDevice;
> +
> +  //
> +  // Functions to allocate, free, map and unmap shared buffer
> +  //
> +  VIRTIO_ALLOCATE_SHARED      AllocateSharedPages;
> +  VIRTIO_FREE_SHARED          FreeSharedPages;
> +  VIRTIO_MAP_SHARED           MapSharedBuffer;
> +  VIRTIO_UNMAP_SHARED         UnmapSharedBuffer;
>  };
>  
>  extern EFI_GUID gVirtioDeviceProtocolGuid;
> 



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 02/23] OvmfPkg/Virtio10Dxe: implement IOMMU-like member functions
  2017-08-23 12:22 ` [PATCH v3 02/23] OvmfPkg/Virtio10Dxe: implement IOMMU-like member functions Brijesh Singh
@ 2017-08-23 19:13   ` Laszlo Ersek
  0 siblings, 0 replies; 46+ messages in thread
From: Laszlo Ersek @ 2017-08-23 19:13 UTC (permalink / raw)
  To: Brijesh Singh, edk2-devel; +Cc: Jordan Justen, Tom Lendacky, Ard Biesheuvel

On 08/23/17 14:22, Brijesh Singh wrote:
> The patch implements the newly added IOMMU-like member functions by
> respectively delegating the job to:
> 
> - VIRTIO_DEVICE_PROTOCOL.AllocateSharedPages() ->
>     EFI_PCI_IO_PROTOCOL.AllocateBuffer()
> 
> - VIRTIO_DEVICE_PROTOCOL.FreeSharedPages() ->
>     EFI_PCI_IO_PROTOCOL.FreeBuffer()
> 
> - VIRTIO_DEVICE_PROTOCOL.MapSharedBuffer() ->
>     EFI_PCI_IO_PROTOCOL.Map()
> 
> - VIRTIO_DEVICE_PROTOCOL.UnmapSharedBuffer() ->
>     EFI_PCI_IO_PROTOCOL.Unmap()
> 
> 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>
> ---
>  OvmfPkg/Virtio10Dxe/Virtio10.c | 122 +++++++++++++++++++-
>  1 file changed, 120 insertions(+), 2 deletions(-)

Reviewed-by: Laszlo Ersek <lersek@redhat.com>

Thanks!
Laszlo

> diff --git a/OvmfPkg/Virtio10Dxe/Virtio10.c b/OvmfPkg/Virtio10Dxe/Virtio10.c
> index d7ea4432bcb6..89ccac8c1c04 100644
> --- a/OvmfPkg/Virtio10Dxe/Virtio10.c
> +++ b/OvmfPkg/Virtio10Dxe/Virtio10.c
> @@ -2,6 +2,7 @@
>    A non-transitional driver for VirtIo 1.0 PCI devices.
>  
>    Copyright (C) 2016, Red Hat, Inc.
> +  Copyright (C) 2017, AMD Inc, All rights reserved.<BR>
>  
>    This program and the accompanying materials are licensed and made available
>    under the terms and conditions of the BSD License which accompanies this
> @@ -15,6 +16,7 @@
>  #include <IndustryStandard/Pci.h>
>  #include <IndustryStandard/Virtio.h>
>  #include <Protocol/PciIo.h>
> +#include <Protocol/PciRootBridgeIo.h>
>  #include <Protocol/VirtioDevice.h>
>  #include <Library/BaseMemoryLib.h>
>  #include <Library/DebugLib.h>
> @@ -772,6 +774,117 @@ Virtio10ReadDevice (
>    return Status;
>  }
>  
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +Virtio10AllocateSharedPages (
> +  IN     VIRTIO_DEVICE_PROTOCOL  *This,
> +  IN     UINTN                   Pages,
> +  IN OUT VOID                    **HostAddress
> +  )
> +{
> +  VIRTIO_1_0_DEV *Dev;
> +  EFI_STATUS     Status;
> +
> +  Dev = VIRTIO_1_0_FROM_VIRTIO_DEVICE (This);
> +
> +  Status = Dev->PciIo->AllocateBuffer (
> +                         Dev->PciIo,
> +                         AllocateAnyPages,
> +                         EfiBootServicesData,
> +                         Pages,
> +                         HostAddress,
> +                         EFI_PCI_ATTRIBUTE_MEMORY_CACHED
> +                         );
> +  return Status;
> +}
> +
> +STATIC
> +VOID
> +EFIAPI
> +Virtio10FreeSharedPages (
> +  IN  VIRTIO_DEVICE_PROTOCOL  *This,
> +  IN  UINTN                   Pages,
> +  IN  VOID                    *HostAddress
> +  )
> +{
> +  VIRTIO_1_0_DEV *Dev;
> +
> +  Dev = VIRTIO_1_0_FROM_VIRTIO_DEVICE (This);
> +
> +  Dev->PciIo->FreeBuffer (
> +                Dev->PciIo,
> +                Pages,
> +                HostAddress
> +                );
> +}
> +
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +Virtio10MapSharedBuffer (
> +  IN     VIRTIO_DEVICE_PROTOCOL  *This,
> +  IN     VIRTIO_MAP_OPERATION    Operation,
> +  IN     VOID                    *HostAddress,
> +  IN OUT UINTN                   *NumberOfBytes,
> +  OUT    EFI_PHYSICAL_ADDRESS    *DeviceAddress,
> +  OUT    VOID                    **Mapping
> +  )
> +{
> +  EFI_STATUS                    Status;
> +  VIRTIO_1_0_DEV                *Dev;
> +  EFI_PCI_IO_PROTOCOL_OPERATION PciIoOperation;
> +
> +  Dev = VIRTIO_1_0_FROM_VIRTIO_DEVICE (This);
> +
> +  //
> +  // Map VIRTIO_MAP_OPERATION to EFI_PCI_IO_PROTOCOL_OPERATION
> +  //
> +  switch (Operation) {
> +  case VirtioOperationBusMasterRead:
> +    PciIoOperation = EfiPciIoOperationBusMasterRead;
> +    break;
> +  case VirtioOperationBusMasterWrite:
> +    PciIoOperation = EfiPciIoOperationBusMasterWrite;
> +    break;
> +  case VirtioOperationBusMasterCommonBuffer:
> +    PciIoOperation = EfiPciIoOperationBusMasterCommonBuffer;
> +    break;
> +  default:
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  Status = Dev->PciIo->Map (
> +                         Dev->PciIo,
> +                         PciIoOperation,
> +                         HostAddress,
> +                         NumberOfBytes,
> +                         DeviceAddress,
> +                         Mapping
> +                         );
> +  return Status;
> +}
> +
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +Virtio10UnmapSharedBuffer (
> +  IN  VIRTIO_DEVICE_PROTOCOL  *This,
> +  IN  VOID                    *Mapping
> +  )
> +{
> +  EFI_STATUS      Status;
> +  VIRTIO_1_0_DEV  *Dev;
> +
> +  Dev = VIRTIO_1_0_FROM_VIRTIO_DEVICE (This);
> +
> +  Status = Dev->PciIo->Unmap (
> +                         Dev->PciIo,
> +                         Mapping
> +                         );
> +
> +  return Status;
> +}
>  
>  STATIC CONST VIRTIO_DEVICE_PROTOCOL mVirtIoTemplate = {
>    VIRTIO_SPEC_REVISION (1, 0, 0),
> @@ -788,7 +901,11 @@ STATIC CONST VIRTIO_DEVICE_PROTOCOL mVirtIoTemplate = {
>    Virtio10GetDeviceStatus,
>    Virtio10SetDeviceStatus,
>    Virtio10WriteDevice,
> -  Virtio10ReadDevice
> +  Virtio10ReadDevice,
> +  Virtio10AllocateSharedPages,
> +  Virtio10FreeSharedPages,
> +  Virtio10MapSharedBuffer,
> +  Virtio10UnmapSharedBuffer
>  };
>  
>  
> @@ -906,7 +1023,8 @@ Virtio10BindingStart (
>      goto ClosePciIo;
>    }
>  
> -  SetAttributes = EFI_PCI_IO_ATTRIBUTE_BUS_MASTER;
> +  SetAttributes = (EFI_PCI_IO_ATTRIBUTE_BUS_MASTER |
> +                   EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE);
>    UpdateAttributes (&Device->CommonConfig, &SetAttributes);
>    UpdateAttributes (&Device->NotifyConfig, &SetAttributes);
>    UpdateAttributes (&Device->SpecificConfig, &SetAttributes);
> 



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 03/23] OvmfPkg/VirtioPciDeviceDxe: implement IOMMU-like member functions
  2017-08-23 12:22 ` [PATCH v3 03/23] OvmfPkg/VirtioPciDeviceDxe: " Brijesh Singh
@ 2017-08-23 19:16   ` Laszlo Ersek
  0 siblings, 0 replies; 46+ messages in thread
From: Laszlo Ersek @ 2017-08-23 19:16 UTC (permalink / raw)
  To: Brijesh Singh, edk2-devel; +Cc: Jordan Justen, Tom Lendacky, Ard Biesheuvel

On 08/23/17 14:22, Brijesh Singh wrote:
> The patch implements the newly added IOMMU-like member functions by
> respectively delegating the job to:
> 
> - VIRTIO_DEVICE_PROTOCOL.AllocateSharedPages () ->
>     MemoryAllocationLib.AllocatePages()
> 
> - VIRTIO_DEVICE_PROTOCOL.FreeSharedPages () ->
>     MemoryAllocationLib.FreePages ()
> 
> - VIRTIO_DEVICE_PROTOCOL.MapSharedBuffer () -> no-op
> 
> - VIRTIO_DEVICE_PROTOCOL.UnmapSharedBuffer () -> no-op
> 
> 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>
> ---
>  OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.h    | 34 ++++++++++++
>  OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c    |  7 ++-
>  OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c | 58 ++++++++++++++++++++
>  3 files changed, 98 insertions(+), 1 deletion(-)

Reviewed-by: Laszlo Ersek <lersek@redhat.com>

Thanks!
Laszlo

> diff --git a/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.h b/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.h
> index 6f51f816ef0f..41df5a98e560 100644
> --- a/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.h
> +++ b/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.h
> @@ -3,6 +3,7 @@
>    Internal definitions for the VirtIo PCI Device driver
>  
>    Copyright (C) 2013, ARM Ltd
> +  Copyright (c) 2017, AMD Inc, All rights reserved.<BR>
>  
>    This program and the accompanying materials are licensed and made available
>    under the terms and conditions of the BSD License which accompanies this
> @@ -156,4 +157,37 @@ VirtioPciSetDeviceStatus (
>    IN  UINT8                          DeviceStatus
>    );
>  
> +EFI_STATUS
> +EFIAPI
> +VirtioPciAllocateSharedPages (
> +  IN  VIRTIO_DEVICE_PROTOCOL        *This,
> +  IN  UINTN                         NumPages,
> +  OUT VOID                          **HostAddress
> +  );
> +
> +VOID
> +EFIAPI
> +VirtioPciFreeSharedPages (
> +  IN  VIRTIO_DEVICE_PROTOCOL        *This,
> +  IN  UINTN                         NumPages,
> +  IN  VOID                          *HostAddress
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +VirtioPciMapSharedBuffer (
> +  IN      VIRTIO_DEVICE_PROTOCOL        *This,
> +  IN      VIRTIO_MAP_OPERATION          Operation,
> +  IN      VOID                          *HostAddress,
> +  IN OUT  UINTN                         *NumberOfBytes,
> +  OUT     EFI_PHYSICAL_ADDRESS          *DeviceAddress,
> +  OUT     VOID                          **Mapping
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +VirtioPciUnmapSharedBuffer (
> +  IN  VIRTIO_DEVICE_PROTOCOL        *This,
> +  IN  VOID                          *Mapping
> +  );
>  #endif // _VIRTIO_PCI_DEVICE_DXE_H_
> diff --git a/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c b/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c
> index 8aae58e8b482..d4b4ec21c34d 100644
> --- a/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c
> +++ b/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c
> @@ -5,6 +5,7 @@
>    Copyright (C) 2012, Red Hat, Inc.
>    Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>
>    Copyright (C) 2013, ARM Ltd.
> +  Copyright (C) 2017, AMD Inc, All rights reserved.<BR>
>  
>    This program and the accompanying materials are licensed and made available
>    under the terms and conditions of the BSD License which accompanies this
> @@ -40,7 +41,11 @@ STATIC VIRTIO_DEVICE_PROTOCOL mDeviceProtocolTemplate = {
>    VirtioPciGetDeviceStatus,             // GetDeviceStatus
>    VirtioPciSetDeviceStatus,             // SetDeviceStatus
>    VirtioPciDeviceWrite,                 // WriteDevice
> -  VirtioPciDeviceRead                   // ReadDevice
> +  VirtioPciDeviceRead,                  // ReadDevice
> +  VirtioPciAllocateSharedPages,         // AllocateSharedPages
> +  VirtioPciFreeSharedPages,             // FreeSharedPages
> +  VirtioPciMapSharedBuffer,             // MapSharedBuffer
> +  VirtioPciUnmapSharedBuffer,           // UnmapSharedBuffer
>  };
>  
>  /**
> diff --git a/OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c b/OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c
> index 5f86914265ea..bd912cca9b29 100644
> --- a/OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c
> +++ b/OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c
> @@ -5,6 +5,7 @@
>    Copyright (C) 2012, Red Hat, Inc.
>    Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
>    Copyright (C) 2013, ARM Ltd.
> +  Copyright (C) 2017, AMD Inc, All rights reserved.<BR>
>  
>    This program and the accompanying materials are licensed and made available
>    under the terms and conditions of the BSD License which accompanies this
> @@ -271,3 +272,60 @@ VirtioPciSetDeviceStatus (
>    return VirtioPciIoWrite (Dev, VIRTIO_PCI_OFFSET_QUEUE_DEVICE_STATUS,
>        sizeof (UINT8), DeviceStatus);
>  }
> +
> +EFI_STATUS
> +EFIAPI
> +VirtioPciAllocateSharedPages (
> +  IN  VIRTIO_DEVICE_PROTOCOL  *This,
> +  IN  UINTN                   NumPages,
> +  OUT VOID                    **HostAddress
> +  )
> +{
> +  VOID        *Buffer;
> +
> +  Buffer = AllocatePages (NumPages);
> +  if (Buffer == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  *HostAddress = Buffer;
> +  return EFI_SUCCESS;
> +}
> +
> +VOID
> +EFIAPI
> +VirtioPciFreeSharedPages (
> +  IN  VIRTIO_DEVICE_PROTOCOL  *This,
> +  IN  UINTN                   NumPages,
> +  IN  VOID                    *HostAddress
> +  )
> +{
> +  FreePages (HostAddress, NumPages);
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +VirtioPciMapSharedBuffer (
> +  IN      VIRTIO_DEVICE_PROTOCOL  *This,
> +  IN      VIRTIO_MAP_OPERATION    Operation,
> +  IN      VOID                    *HostAddress,
> +  IN OUT  UINTN                   *NumberOfBytes,
> +  OUT     EFI_PHYSICAL_ADDRESS    *DeviceAddress,
> +  OUT     VOID                    **Mapping
> +  )
> +{
> +  *DeviceAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress;
> +  *Mapping = NULL;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +VirtioPciUnmapSharedBuffer (
> +  IN VIRTIO_DEVICE_PROTOCOL    *This,
> +  IN VOID                      *Mapping
> +  )
> +{
> +  return EFI_SUCCESS;
> +}
> 



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 04/23] OvmfPkg/VirtioMmioDeviceLib: implement IOMMU-like member functions
  2017-08-23 12:22 ` [PATCH v3 04/23] OvmfPkg/VirtioMmioDeviceLib: " Brijesh Singh
@ 2017-08-23 19:26   ` Laszlo Ersek
  0 siblings, 0 replies; 46+ messages in thread
From: Laszlo Ersek @ 2017-08-23 19:26 UTC (permalink / raw)
  To: Brijesh Singh, edk2-devel; +Cc: Jordan Justen, Tom Lendacky, Ard Biesheuvel

On 08/23/17 14:22, Brijesh Singh wrote:
> The patch implements the newly added IOMMU-like member functions by
> respectively delegating the job to:
> 
> - VIRTIO_DEVICE_PROTOCOL.AllocateSharedPages () ->
>     MemoryAllocationLib.AllocatePages()
> 
> - VIRTIO_DEVICE_PROTOCOL.FreeSharedPages () ->
>     MemoryAllocationLib.FreePages ()
> 
> - VIRTIO_DEVICE_PROTOCOL.MapSharedBuffer () -> no-op
> 
> - VIRTIO_DEVICE_PROTOCOL.UnmapSharedBuffer () -> no-op
> 
> 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>
> ---
>  OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.h          | 36 +++++++++++++
>  OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c          |  8 ++-
>  OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c | 57 ++++++++++++++++++++
>  3 files changed, 99 insertions(+), 2 deletions(-)

Reviewed-by: Laszlo Ersek <lersek@redhat.com>

Thanks,
Laszlo

> diff --git a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.h b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.h
> index bedd635e1a86..e5881d537f09 100644
> --- a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.h
> +++ b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.h
> @@ -3,6 +3,7 @@
>    Internal definitions for the VirtIo MMIO Device driver
>  
>    Copyright (C) 2013, ARM Ltd
> +  Copyright (C) 2017, AMD Inc. All rights reserved.<BR>
>  
>    This program and the accompanying materials are licensed and made available
>    under the terms and conditions of the BSD License which accompanies this
> @@ -25,6 +26,7 @@
>  #include <Library/IoLib.h>
>  #include <Library/UefiLib.h>
>  #include <Library/VirtioMmioDeviceLib.h>
> +#include <Library/MemoryAllocationLib.h>
>  
>  #define VIRTIO_MMIO_DEVICE_SIGNATURE  SIGNATURE_32 ('V', 'M', 'I', 'O')
>  
> @@ -137,4 +139,38 @@ VirtioMmioSetGuestFeatures (
>    IN UINT64                  Features
>    );
>  
> +EFI_STATUS
> +EFIAPI
> +VirtioMmioAllocateSharedPages (
> +  IN  VIRTIO_DEVICE_PROTOCOL        *This,
> +  IN  UINTN                         NumPages,
> +  OUT VOID                          **HostAddress
> +  );
> +
> +VOID
> +EFIAPI
> +VirtioMmioFreeSharedPages (
> +  IN  VIRTIO_DEVICE_PROTOCOL        *This,
> +  IN  UINTN                         NumPages,
> +  IN  VOID                          *HostAddress
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +VirtioMmioMapSharedBuffer (
> +  IN      VIRTIO_DEVICE_PROTOCOL        *This,
> +  IN      VIRTIO_MAP_OPERATION          Operation,
> +  IN      VOID                          *HostAddress,
> +  IN OUT  UINTN                         *NumberOfBytes,
> +  OUT     EFI_PHYSICAL_ADDRESS          *DeviceAddress,
> +  OUT     VOID                          **Mapping
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +VirtioMmioUnmapSharedBuffer (
> +  IN  VIRTIO_DEVICE_PROTOCOL        *This,
> +  IN  VOID                          *Mapping
> +  );
> +
>  #endif // _VIRTIO_MMIO_DEVICE_INTERNAL_H_
> diff --git a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c
> index b1d443ea7007..fce934e1e953 100644
> --- a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c
> +++ b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c
> @@ -3,6 +3,7 @@
>    This driver produces Virtio Device Protocol instances for Virtio Mmio devices.
>  
>    Copyright (C) 2013, ARM Ltd.
> +  Copyright (C) 2017, AMD Inc. All rights reserved.<BR>
>  
>    This program and the accompanying materials are licensed and made available
>    under the terms and conditions of the BSD License which accompanies this
> @@ -15,7 +16,6 @@
>  **/
>  
>  #include <Library/BaseMemoryLib.h>
> -#include <Library/MemoryAllocationLib.h>
>  #include <Library/UefiBootServicesTableLib.h>
>  
>  #include "VirtioMmioDevice.h"
> @@ -35,7 +35,11 @@ static VIRTIO_DEVICE_PROTOCOL mMmioDeviceProtocolTemplate = {
>      VirtioMmioGetDeviceStatus,             // GetDeviceStatus
>      VirtioMmioSetDeviceStatus,             // SetDeviceStatus
>      VirtioMmioDeviceWrite,                 // WriteDevice
> -    VirtioMmioDeviceRead                   // ReadDevice
> +    VirtioMmioDeviceRead,                  // ReadDevice
> +    VirtioMmioAllocateSharedPages,         // AllocateSharedPages
> +    VirtioMmioFreeSharedPages,             // FreeSharedPages
> +    VirtioMmioMapSharedBuffer,             // MapSharedBuffer
> +    VirtioMmioUnmapSharedBuffer            // UnmapSharedBuffer
>  };
>  
>  /**
> diff --git a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c
> index 9142d4a162c0..644ec65e1788 100644
> --- a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c
> +++ b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c
> @@ -293,3 +293,60 @@ VirtioMmioDeviceRead (
>  
>    return EFI_SUCCESS;
>  }
> +
> +EFI_STATUS
> +EFIAPI
> +VirtioMmioAllocateSharedPages (
> +  IN  VIRTIO_DEVICE_PROTOCOL  *This,
> +  IN  UINTN                   NumPages,
> +  OUT VOID                    **HostAddress
> +  )
> +{
> +  VOID        *Buffer;
> +
> +  Buffer = AllocatePages (NumPages);
> +  if (Buffer == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  *HostAddress = Buffer;
> +  return EFI_SUCCESS;
> +}
> +
> +VOID
> +EFIAPI
> +VirtioMmioFreeSharedPages (
> +  IN  VIRTIO_DEVICE_PROTOCOL  *This,
> +  IN  UINTN                   NumPages,
> +  IN  VOID                    *HostAddress
> +  )
> +{
> +  FreePages (HostAddress, NumPages);
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +VirtioMmioMapSharedBuffer (
> +  IN      VIRTIO_DEVICE_PROTOCOL  *This,
> +  IN      VIRTIO_MAP_OPERATION    Operation,
> +  IN      VOID                    *HostAddress,
> +  IN OUT  UINTN                   *NumberOfBytes,
> +  OUT     EFI_PHYSICAL_ADDRESS    *DeviceAddress,
> +  OUT     VOID                    **Mapping
> +  )
> +{
> +  *DeviceAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress;
> +  *Mapping = NULL;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +VirtioMmioUnmapSharedBuffer (
> +  IN VIRTIO_DEVICE_PROTOCOL    *This,
> +  IN VOID                      *Mapping
> +  )
> +{
> +  return EFI_SUCCESS;
> +}
> 



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 05/23] OvmfPkg/VirtioLib: add VirtioMapAllBytesInSharedBuffer() helper function
  2017-08-23 12:22 ` [PATCH v3 05/23] OvmfPkg/VirtioLib: add VirtioMapAllBytesInSharedBuffer() helper function Brijesh Singh
@ 2017-08-23 19:45   ` Laszlo Ersek
  0 siblings, 0 replies; 46+ messages in thread
From: Laszlo Ersek @ 2017-08-23 19:45 UTC (permalink / raw)
  To: Brijesh Singh, edk2-devel; +Cc: Jordan Justen, Tom Lendacky, Ard Biesheuvel

There are two trivial omissions in this patch:

On 08/23/17 14:22, Brijesh Singh wrote:
> The function can be used for mapping the system physical address to virtio
> device address using VIRTIO_DEVICE_PROTOCOL.MapSharedBuffer (). The
> function helps with centralizing error handling, and it allows the caller
> to pass in constant or other evaluated expressions for NumberOfBytes.
> 
> 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/Include/Library/VirtioLib.h   | 52 ++++++++++++
>  OvmfPkg/Library/VirtioLib/VirtioLib.c | 85 ++++++++++++++++++++
>  2 files changed, 137 insertions(+)
> 
> diff --git a/OvmfPkg/Include/Library/VirtioLib.h b/OvmfPkg/Include/Library/VirtioLib.h
> index 5badfb32917f..9ec9b91b59bb 100644
> --- a/OvmfPkg/Include/Library/VirtioLib.h
> +++ b/OvmfPkg/Include/Library/VirtioLib.h
> @@ -3,6 +3,7 @@
>    Declarations of utility functions used by virtio device drivers.
>  
>    Copyright (C) 2012-2016, Red Hat, Inc.
> +  Copyright (C) 2017, AMD Inc, All rights reserved.<BR>
>  
>    This program and the accompanying materials are licensed and made available
>    under the terms and conditions of the BSD License which accompanies this
> @@ -235,4 +236,55 @@ Virtio10WriteFeatures (
>    IN OUT UINT8                  *DeviceStatus
>    );
>  
> +/**
> +  Provides the virtio device address required to access system memory from a
> +  DMA bus master.
> +
> +  The interface follows the same usage pattern as defined in UEFI spec 2.6
> +  (Section 13.2 PCI Root Bridge I/O Protocol)
> +
> +  The VirtioMapAllBytesInSharedBuffer() is similar to VIRTIO_MAP_SHARED
> +  with exception that NumberOfBytes is IN-only parameter. The function
> +  maps all the bytes specified in NumberOfBytes param in one consecutive
> +  range.
> +
> +  @param[in]     This             The virtio device for which the mapping is
> +                                  requested.

(1) The parameter is called "VirtIo", not "This". (In my previous
review, I proposed a replacement that covered both the parameter name
and the parameter documentation, and I think you updated only the
documentation.)

> +
> +  @param[in]     Operation        Indicates if the bus master is going to
> +                                  read or write to system memory.
> +
> +  @param[in]     HostAddress      The system memory address to map to shared
> +                                  buffer address.
> +
> +  @param[in]     NumberOfBytes    Number of bytes to map.
> +
> +  @param[out]    DeviceAddress    The resulting shared map address for the
> +                                  bus master to access the hosts HostAddress.
> +
> +  @param[out]    Mapping          A resulting token to pass to
> +                                  VIRTIO_UNMAP_SHARED.
> +
> +
> +  @retval EFI_SUCCESS             The NumberOfBytes is succesfully mapped.
> +  @retval EFI_UNSUPPORTED         The HostAddress cannot be mapped as a
> +                                  common buffer.
> +  @retval EFI_INVALID_PARAMETER   One or more parameters are invalid.
> +  @retval EFI_OUT_OF_RESOURCES    The request could not be completed due to
> +                                  a lack of resources. This includes the case
> +                                  when NumberOfBytes bytes cannot be mapped
> +                                  in one consecutive range.
> +  @retval EFI_DEVICE_ERROR        The system hardware could not map the
> +                                  requested address.
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtioMapAllBytesInSharedBuffer (
> +  IN  VIRTIO_DEVICE_PROTOCOL  *VirtIo,
> +  IN  VIRTIO_MAP_OPERATION    Operation,
> +  IN  VOID                    *HostAddress,
> +  IN  UINTN                   NumberOfBytes,
> +  OUT EFI_PHYSICAL_ADDRESS    *DeviceAddress,
> +  OUT VOID                    **Mapping
> +  );
>  #endif // _VIRTIO_LIB_H_
> diff --git a/OvmfPkg/Library/VirtioLib/VirtioLib.c b/OvmfPkg/Library/VirtioLib/VirtioLib.c
> index 845f206369a3..c85cd8dba569 100644
> --- a/OvmfPkg/Library/VirtioLib/VirtioLib.c
> +++ b/OvmfPkg/Library/VirtioLib/VirtioLib.c
> @@ -4,6 +4,7 @@
>  
>    Copyright (C) 2012-2016, Red Hat, Inc.
>    Portion of Copyright (C) 2013, ARM Ltd.
> +  Copyright (C) 2017, AMD Inc, All rights reserved.<BR>
>  
>    This program and the accompanying materials are licensed and made available
>    under the terms and conditions of the BSD License which accompanies this
> @@ -414,3 +415,87 @@ Virtio10WriteFeatures (
>  
>    return Status;
>  }
> +
> +/**
> +  Provides the virtio device address required to access system memory from a
> +  DMA bus master.
> +
> +  The interface follows the same usage pattern as defined in UEFI spec 2.6
> +  (Section 13.2 PCI Root Bridge I/O Protocol)
> +
> +  The VirtioMapAllBytesInSharedBuffer() is similar to VIRTIO_MAP_SHARED
> +  with exception that NumberOfBytes is IN-only parameter. The function
> +  maps all the bytes specified in NumberOfBytes param in one consecutive
> +  range.
> +
> +  @param[in]     This             The virtio device for which the mapping is
> +                                  requested.

(2) Same as (1), the parameter is called "VirtIo", not "This".

My plan is to test and push the initial sequence of this series (if the
review progresses far enough without more serious remarks), so my plan
is to fix these up on commit myself.

With the above fixed (by you or by me; we'll see):

Reviewed-by: Laszlo Ersek <lersek@redhat.com>

Thanks
Laszlo


> +
> +  @param[in]     Operation        Indicates if the bus master is going to
> +                                  read or write to system memory.
> +
> +  @param[in]     HostAddress      The system memory address to map to shared
> +                                  buffer address.
> +
> +  @param[in]     NumberOfBytes    Number of bytes to map.
> +
> +  @param[out]    DeviceAddress    The resulting shared map address for the
> +                                  bus master to access the hosts HostAddress.
> +
> +  @param[out]    Mapping          A resulting token to pass to
> +                                  VIRTIO_UNMAP_SHARED.
> +
> +
> +  @retval EFI_SUCCESS             The NumberOfBytes is succesfully mapped.
> +  @retval EFI_UNSUPPORTED         The HostAddress cannot be mapped as a
> +                                  common buffer.
> +  @retval EFI_INVALID_PARAMETER   One or more parameters are invalid.
> +  @retval EFI_OUT_OF_RESOURCES    The request could not be completed due to
> +                                  a lack of resources. This includes the case
> +                                  when NumberOfBytes bytes cannot be mapped
> +                                  in one consecutive range.
> +  @retval EFI_DEVICE_ERROR        The system hardware could not map the
> +                                  requested address.
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtioMapAllBytesInSharedBuffer (
> +  IN  VIRTIO_DEVICE_PROTOCOL  *VirtIo,
> +  IN  VIRTIO_MAP_OPERATION    Operation,
> +  IN  VOID                    *HostAddress,
> +  IN  UINTN                   NumberOfBytes,
> +  OUT EFI_PHYSICAL_ADDRESS    *DeviceAddress,
> +  OUT VOID                    **Mapping
> +  )
> +{
> +  EFI_STATUS            Status;
> +  VOID                  *MapInfo;
> +  UINTN                 Size;
> +  EFI_PHYSICAL_ADDRESS  PhysicalAddress;
> +
> +  Size = NumberOfBytes;
> +  Status = VirtIo->MapSharedBuffer (
> +                     VirtIo,
> +                     Operation,
> +                     HostAddress,
> +                     &Size,
> +                     &PhysicalAddress,
> +                     &MapInfo
> +                     );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  if (Size < NumberOfBytes) {
> +    goto Failed;
> +  }
> +
> +  *Mapping = MapInfo;
> +  *DeviceAddress = PhysicalAddress;
> +
> +  return EFI_SUCCESS;
> +
> +Failed:
> +  VirtIo->UnmapSharedBuffer (VirtIo, MapInfo);
> +  return EFI_OUT_OF_RESOURCES;
> +}
> 



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 09/23] OvmfPkg/VirtioLib: add function to map VRING
  2017-08-23 12:22 ` [PATCH v3 09/23] OvmfPkg/VirtioLib: add function to map VRING Brijesh Singh
@ 2017-08-23 20:10   ` Laszlo Ersek
  0 siblings, 0 replies; 46+ messages in thread
From: Laszlo Ersek @ 2017-08-23 20:10 UTC (permalink / raw)
  To: Brijesh Singh, edk2-devel; +Cc: Jordan Justen, Tom Lendacky, Ard Biesheuvel

There's one trivial omission in this patch, wrt. the previous review
comments:

On 08/23/17 14:22, Brijesh Singh wrote:
> Add functions to map the ring buffer with BusMasterCommonBuffer so that

(1) s/functions/a function/

I'll fix it up before I push the initial subsequence.

Reviewed-by: Laszlo Ersek <lersek@redhat.com>

Thanks!
Laszlo

> ring can be accessed by both guest and hypervisor.
> 
> 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/Include/Library/VirtioLib.h   | 26 +++++++++++
>  OvmfPkg/Library/VirtioLib/VirtioLib.c | 45 ++++++++++++++++++++
>  2 files changed, 71 insertions(+)
> 
> diff --git a/OvmfPkg/Include/Library/VirtioLib.h b/OvmfPkg/Include/Library/VirtioLib.h
> index 40c51a2b3305..3d9314b3acaf 100644
> --- a/OvmfPkg/Include/Library/VirtioLib.h
> +++ b/OvmfPkg/Include/Library/VirtioLib.h
> @@ -62,6 +62,32 @@ VirtioRingInit (
>  
>  /**
>  
> +  Map the ring buffer so that it can be accessed equally by both guest
> +  and hypervisor.
> +
> +  @param[in]      VirtIo          The virtio device instance.
> +
> +  @param[in]      Ring            The virtio ring to map.
> +
> +  @param[out]     RingBaseShift   A resulting translation offset, to be
> +                                  passed to VirtIo->SetQueueAddress().
> +
> +  @param[out]     Mapping         A resulting token to pass to
> +                                  VirtIo->UnmapSharedBuffer().
> +
> +  @return         Status code from VirtIo->MapSharedBuffer()
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtioRingMap (
> +  IN  VIRTIO_DEVICE_PROTOCOL *VirtIo,
> +  IN  VRING                  *Ring,
> +  OUT UINT64                 *RingBaseShift,
> +  OUT VOID                   **Mapping
> +  );
> +
> +/**
> +
>    Tear down the internal resources of a configured virtio ring.
>  
>    The caller is responsible to stop the host from using this ring before
> diff --git a/OvmfPkg/Library/VirtioLib/VirtioLib.c b/OvmfPkg/Library/VirtioLib/VirtioLib.c
> index 8bc5b9aea4fc..535635ac0ba8 100644
> --- a/OvmfPkg/Library/VirtioLib/VirtioLib.c
> +++ b/OvmfPkg/Library/VirtioLib/VirtioLib.c
> @@ -505,3 +505,48 @@ Failed:
>    VirtIo->UnmapSharedBuffer (VirtIo, MapInfo);
>    return EFI_OUT_OF_RESOURCES;
>  }
> +
> +/**
> +
> +  Map the ring buffer so that it can be accessed equally by both guest
> +  and hypervisor.
> +
> +  @param[in]      VirtIo          The virtio device instance.
> +
> +  @param[in]      Ring            The virtio ring to map.
> +
> +  @param[out]     RingBaseShift   A resulting translation offset, to be
> +                                  passed to VirtIo->SetQueueAddress().
> +
> +  @param[out]     Mapping         A resulting token to pass to
> +                                  VirtIo->UnmapSharedBuffer().
> +
> +  @return         Status code from VirtIo->MapSharedBuffer()
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtioRingMap (
> +  IN  VIRTIO_DEVICE_PROTOCOL *VirtIo,
> +  IN  VRING                  *Ring,
> +  OUT UINT64                 *RingBaseShift,
> +  OUT VOID                   **Mapping
> +  )
> +{
> +  EFI_STATUS            Status;
> +  EFI_PHYSICAL_ADDRESS  DeviceAddress;
> +
> +  Status = VirtioMapAllBytesInSharedBuffer (
> +             VirtIo,
> +             VirtioOperationBusMasterCommonBuffer,
> +             Ring->Base,
> +             EFI_PAGES_TO_SIZE (Ring->NumPages),
> +             &DeviceAddress,
> +             Mapping
> +             );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  *RingBaseShift = DeviceAddress - (UINT64)(UINTN)Ring->Base;
> +  return EFI_SUCCESS;
> +}
> 



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 07/23] OvmfPkg/Virtio: take RingBaseShift in SetQueueAddress()
  2017-08-23 12:22 ` [PATCH v3 07/23] OvmfPkg/Virtio: take RingBaseShift in SetQueueAddress() Brijesh Singh
@ 2017-08-23 20:41   ` Laszlo Ersek
  2017-08-23 20:43     ` Laszlo Ersek
  0 siblings, 1 reply; 46+ messages in thread
From: Laszlo Ersek @ 2017-08-23 20:41 UTC (permalink / raw)
  To: Brijesh Singh, edk2-devel; +Cc: Jordan Justen, Tom Lendacky, Ard Biesheuvel

On 08/23/17 14:22, Brijesh Singh wrote:
> 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.
> 
> VirtioRingMap() maps the ring buffer system physical to a bus address.
> When an IOMMU is used for translating the address then bus address can
> start at a different offset from the system physical address.

(1) The paragraph that you now have as first paragraph above was my
suggestion, so thank you for picking it up. However, the second
paragraph should have been deleted; I suggested the now-first paragraph
as a replacement for the now-second one.

I wrote, "to keep our references within the virtio device protocol".
VirtioRingMap() is a VirtioLib function, which is a utility layer on top
of the virtio device protocol. So, as I said, VirtioLib patches may
refer to both VirtioLib and the protocol, but protocol patches should
preferably only refer to the protocol, and not VirtioLib.

  VirtioLib --+
   |  ^       |
   |  |       |
   |  +-------+
   |
   v
  VirtioDeviceProtocol --+
                ^        |
                |        |
                +--------+

This is also consistent with the reordering of the patches that I asked
for (and that you implemented well in v3, thank you for it).

So, apologies if I wasn't clear enough of this -- it's not a big deal at
all, I can remove the second paragraph when I push this.

Reviewed-by: Laszlo Ersek <lersek@redhat.com>

Thanks!
Laszlo

> 
> - 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>
> ---
>  OvmfPkg/Include/Protocol/VirtioDevice.h                         | 19 +++++++++++++++++--
>  OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.h          |  3 ++-
>  OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.h                    |  3 ++-
>  OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c |  5 ++++-
>  OvmfPkg/Virtio10Dxe/Virtio10.c                                  |  5 ++++-
>  OvmfPkg/VirtioBlkDxe/VirtioBlk.c                                |  2 +-
>  OvmfPkg/VirtioGpuDxe/Commands.c                                 |  6 +++++-
>  OvmfPkg/VirtioNetDxe/SnpInitialize.c                            |  2 +-
>  OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c                 |  5 ++++-
>  OvmfPkg/VirtioRngDxe/VirtioRng.c                                |  2 +-
>  OvmfPkg/VirtioScsiDxe/VirtioScsi.c                              |  2 +-
>  11 files changed, 42 insertions(+), 12 deletions(-)
> 
> diff --git a/OvmfPkg/Include/Protocol/VirtioDevice.h b/OvmfPkg/Include/Protocol/VirtioDevice.h
> index 9a01932958a2..2e3a6d6edf04 100644
> --- a/OvmfPkg/Include/Protocol/VirtioDevice.h
> +++ b/OvmfPkg/Include/Protocol/VirtioDevice.h
> @@ -156,7 +156,21 @@ EFI_STATUS
>    @param[in] This             This instance of VIRTIO_DEVICE_PROTOCOL
>  
>    @param[in] Ring             The initialized VRING object to take the
> -                              addresses from.
> +                              addresses from. The caller is responsible for
> +                              ensuring that on input, all Ring->NumPages pages,
> +                              starting at Ring->Base, have been successfully
> +                              mapped with a single call to
> +                              This->MapSharedBuffer() for CommonBuffer bus
> +                              master operation..
> +
> +  @param[in] RingBaseShift    Adding this value using UINT64 arithmetic to the
> +                              addresses found in Ring translates them from
> +                              system memory to bus addresses. The caller shall
> +                              calculate RingBaseShift as
> +                              (DeviceAddress - (UINT64)(UINTN)HostAddress),
> +                              where DeviceAddress and HostAddress (i.e.,
> +                              Ring->Base) were output and input parameters of
> +                              This->MapSharedBuffer(), respectively.
>  
>    @retval EFI_SUCCESS         The data was written successfully.
>    @retval EFI_UNSUPPORTED     The underlying IO device doesn't support the
> @@ -166,7 +180,8 @@ typedef
>  EFI_STATUS
>  (EFIAPI *VIRTIO_SET_QUEUE_ADDRESS) (
>    IN VIRTIO_DEVICE_PROTOCOL  *This,
> -  IN VRING                   *Ring
> +  IN VRING                   *Ring,
> +  IN UINT64                  RingBaseShift
>    );
>  
>  /**
> diff --git a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.h b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.h
> index e5881d537f09..e6279159f8ba 100644
> --- a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.h
> +++ b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.h
> @@ -115,7 +115,8 @@ VirtioMmioSetQueueSel (
>  EFI_STATUS
>  VirtioMmioSetQueueAddress (
>    IN VIRTIO_DEVICE_PROTOCOL  *This,
> -  IN VRING                   *Ring
> +  IN VRING                   *Ring,
> +  IN UINT64                  RingBaseShift
>    );
>  
>  EFI_STATUS
> diff --git a/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.h b/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.h
> index 41df5a98e560..1f0dc45d501e 100644
> --- a/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.h
> +++ b/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.h
> @@ -126,7 +126,8 @@ EFI_STATUS
>  EFIAPI
>  VirtioPciSetQueueAddress (
>    IN VIRTIO_DEVICE_PROTOCOL  *This,
> -  IN VRING                   *Ring
> +  IN VRING                   *Ring,
> +  IN UINT64                  RingBaseShift
>    );
>  
>  EFI_STATUS
> diff --git a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c
> index 644ec65e1788..67458e56231b 100644
> --- a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c
> +++ b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c
> @@ -181,11 +181,14 @@ VirtioMmioSetQueueSel (
>  EFI_STATUS
>  VirtioMmioSetQueueAddress (
>    IN VIRTIO_DEVICE_PROTOCOL  *This,
> -  IN VRING                   *Ring
> +  IN VRING                   *Ring,
> +  IN UINT64                  RingBaseShift
>    )
>  {
>    VIRTIO_MMIO_DEVICE *Device;
>  
> +  ASSERT (RingBaseShift == 0);
> +
>    Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
>  
>    VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_PFN,
> diff --git a/OvmfPkg/Virtio10Dxe/Virtio10.c b/OvmfPkg/Virtio10Dxe/Virtio10.c
> index 89ccac8c1c04..ef9a00710668 100644
> --- a/OvmfPkg/Virtio10Dxe/Virtio10.c
> +++ b/OvmfPkg/Virtio10Dxe/Virtio10.c
> @@ -489,7 +489,8 @@ EFI_STATUS
>  EFIAPI
>  Virtio10SetQueueAddress (
>    IN VIRTIO_DEVICE_PROTOCOL  *This,
> -  IN VRING                   *Ring
> +  IN VRING                   *Ring,
> +  IN UINT64                  RingBaseShift
>    )
>  {
>    VIRTIO_1_0_DEV *Dev;
> @@ -497,6 +498,8 @@ Virtio10SetQueueAddress (
>    UINT64         Address;
>    UINT16         Enable;
>  
> +  ASSERT (RingBaseShift == 0);
> +
>    Dev = VIRTIO_1_0_FROM_VIRTIO_DEVICE (This);
>  
>    Address = (UINTN)Ring->Desc;
> diff --git a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
> index 61b9cab4ff02..bff15fe3add1 100644
> --- a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
> +++ b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
> @@ -745,7 +745,7 @@ VirtioBlkInit (
>    //
>    // step 4c -- Report GPFN (guest-physical frame number) of queue.
>    //
> -  Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, &Dev->Ring);
> +  Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, &Dev->Ring, 0);
>    if (EFI_ERROR (Status)) {
>      goto ReleaseQueue;
>    }
> diff --git a/OvmfPkg/VirtioGpuDxe/Commands.c b/OvmfPkg/VirtioGpuDxe/Commands.c
> index c2e4d72feb67..5cb003161207 100644
> --- a/OvmfPkg/VirtioGpuDxe/Commands.c
> +++ b/OvmfPkg/VirtioGpuDxe/Commands.c
> @@ -132,7 +132,11 @@ VirtioGpuInit (
>    if (EFI_ERROR (Status)) {
>      goto Failed;
>    }
> -  Status = VgpuDev->VirtIo->SetQueueAddress (VgpuDev->VirtIo, &VgpuDev->Ring);
> +  Status = VgpuDev->VirtIo->SetQueueAddress (
> +                              VgpuDev->VirtIo,
> +                              &VgpuDev->Ring,
> +                              0
> +                              );
>    if (EFI_ERROR (Status)) {
>      goto ReleaseQueue;
>    }
> diff --git a/OvmfPkg/VirtioNetDxe/SnpInitialize.c b/OvmfPkg/VirtioNetDxe/SnpInitialize.c
> index 6d9b81a9f939..0ecfe044a977 100644
> --- a/OvmfPkg/VirtioNetDxe/SnpInitialize.c
> +++ b/OvmfPkg/VirtioNetDxe/SnpInitialize.c
> @@ -96,7 +96,7 @@ VirtioNetInitRing (
>    //
>    // step 4c -- report GPFN (guest-physical frame number) of queue
>    //
> -  Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, Ring);
> +  Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, Ring, 0);
>    if (EFI_ERROR (Status)) {
>      goto ReleaseQueue;
>    }
> diff --git a/OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c b/OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c
> index bd912cca9b29..b52060d13d97 100644
> --- a/OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c
> +++ b/OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c
> @@ -183,11 +183,14 @@ EFI_STATUS
>  EFIAPI
>  VirtioPciSetQueueAddress (
>    IN VIRTIO_DEVICE_PROTOCOL  *This,
> -  IN VRING                   *Ring
> +  IN VRING                   *Ring,
> +  IN UINT64                  RingBaseShift
>    )
>  {
>    VIRTIO_PCI_DEVICE *Dev;
>  
> +  ASSERT (RingBaseShift == 0);
> +
>    Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);
>  
>    return VirtioPciIoWrite (Dev, VIRTIO_PCI_OFFSET_QUEUE_ADDRESS, sizeof (UINT32),
> diff --git a/OvmfPkg/VirtioRngDxe/VirtioRng.c b/OvmfPkg/VirtioRngDxe/VirtioRng.c
> index e20602ac7225..0abca488e6cd 100644
> --- a/OvmfPkg/VirtioRngDxe/VirtioRng.c
> +++ b/OvmfPkg/VirtioRngDxe/VirtioRng.c
> @@ -298,7 +298,7 @@ VirtioRngInit (
>    //
>    // step 4c -- Report GPFN (guest-physical frame number) of queue.
>    //
> -  Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, &Dev->Ring);
> +  Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, &Dev->Ring, 0);
>    if (EFI_ERROR (Status)) {
>      goto ReleaseQueue;
>    }
> diff --git a/OvmfPkg/VirtioScsiDxe/VirtioScsi.c b/OvmfPkg/VirtioScsiDxe/VirtioScsi.c
> index c2f6f412ff40..a983b3df7b9c 100644
> --- a/OvmfPkg/VirtioScsiDxe/VirtioScsi.c
> +++ b/OvmfPkg/VirtioScsiDxe/VirtioScsi.c
> @@ -855,7 +855,7 @@ VirtioScsiInit (
>    //
>    // step 4c -- Report GPFN (guest-physical frame number) of queue.
>    //
> -  Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, &Dev->Ring);
> +  Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, &Dev->Ring, 0);
>    if (EFI_ERROR (Status)) {
>      goto ReleaseQueue;
>    }
> 



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 07/23] OvmfPkg/Virtio: take RingBaseShift in SetQueueAddress()
  2017-08-23 20:41   ` Laszlo Ersek
@ 2017-08-23 20:43     ` Laszlo Ersek
  2017-08-23 20:50       ` Brijesh Singh
  0 siblings, 1 reply; 46+ messages in thread
From: Laszlo Ersek @ 2017-08-23 20:43 UTC (permalink / raw)
  To: Brijesh Singh, edk2-devel; +Cc: Jordan Justen, Tom Lendacky, Ard Biesheuvel

On 08/23/17 22:41, Laszlo Ersek wrote:
> On 08/23/17 14:22, Brijesh Singh wrote:
>> 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.
>>
>> VirtioRingMap() maps the ring buffer system physical to a bus address.
>> When an IOMMU is used for translating the address then bus address can
>> start at a different offset from the system physical address.
> 
> (1) The paragraph that you now have as first paragraph above was my
> suggestion, so thank you for picking it up. However, the second
> paragraph should have been deleted; I suggested the now-first paragraph
> as a replacement for the now-second one.
> 
> I wrote, "to keep our references within the virtio device protocol".
> VirtioRingMap() is a VirtioLib function, which is a utility layer on top
> of the virtio device protocol. So, as I said, VirtioLib patches may
> refer to both VirtioLib and the protocol, but protocol patches should
> preferably only refer to the protocol, and not VirtioLib.
> 
>   VirtioLib --+
>    |  ^       |
>    |  |       |
>    |  +-------+
>    |
>    v
>   VirtioDeviceProtocol --+
>                 ^        |
>                 |        |
>                 +--------+
> 
> This is also consistent with the reordering of the patches that I asked
> for (and that you implemented well in v3, thank you for it).
> 
> So, apologies if I wasn't clear enough of this -- it's not a big deal at
> all, I can remove the second paragraph when I push this.
> 
> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
> 
> Thanks!
> Laszlo
> 
>>
>> - 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>
>> ---
>>  OvmfPkg/Include/Protocol/VirtioDevice.h                         | 19 +++++++++++++++++--
>>  OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.h          |  3 ++-
>>  OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.h                    |  3 ++-
>>  OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c |  5 ++++-
>>  OvmfPkg/Virtio10Dxe/Virtio10.c                                  |  5 ++++-
>>  OvmfPkg/VirtioBlkDxe/VirtioBlk.c                                |  2 +-
>>  OvmfPkg/VirtioGpuDxe/Commands.c                                 |  6 +++++-
>>  OvmfPkg/VirtioNetDxe/SnpInitialize.c                            |  2 +-
>>  OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c                 |  5 ++++-
>>  OvmfPkg/VirtioRngDxe/VirtioRng.c                                |  2 +-
>>  OvmfPkg/VirtioScsiDxe/VirtioScsi.c                              |  2 +-
>>  11 files changed, 42 insertions(+), 12 deletions(-)
>>
>> diff --git a/OvmfPkg/Include/Protocol/VirtioDevice.h b/OvmfPkg/Include/Protocol/VirtioDevice.h
>> index 9a01932958a2..2e3a6d6edf04 100644
>> --- a/OvmfPkg/Include/Protocol/VirtioDevice.h
>> +++ b/OvmfPkg/Include/Protocol/VirtioDevice.h
>> @@ -156,7 +156,21 @@ EFI_STATUS
>>    @param[in] This             This instance of VIRTIO_DEVICE_PROTOCOL
>>  
>>    @param[in] Ring             The initialized VRING object to take the
>> -                              addresses from.
>> +                              addresses from. The caller is responsible for
>> +                              ensuring that on input, all Ring->NumPages pages,
>> +                              starting at Ring->Base, have been successfully
>> +                              mapped with a single call to
>> +                              This->MapSharedBuffer() for CommonBuffer bus
>> +                              master operation..

(2) I'll also remove one of the periods.

Thanks
Laszlo


^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 07/23] OvmfPkg/Virtio: take RingBaseShift in SetQueueAddress()
  2017-08-23 20:43     ` Laszlo Ersek
@ 2017-08-23 20:50       ` Brijesh Singh
  0 siblings, 0 replies; 46+ messages in thread
From: Brijesh Singh @ 2017-08-23 20:50 UTC (permalink / raw)
  To: Laszlo Ersek, edk2-devel
  Cc: brijesh.singh, Jordan Justen, Tom Lendacky, Ard Biesheuvel



On 08/23/2017 03:43 PM, Laszlo Ersek wrote:
> On 08/23/17 22:41, Laszlo Ersek wrote:
>> On 08/23/17 14:22, Brijesh Singh wrote:
>>> 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.
>>>
>>> VirtioRingMap() maps the ring buffer system physical to a bus address.
>>> When an IOMMU is used for translating the address then bus address can
>>> start at a different offset from the system physical address.
>>
>> (1) The paragraph that you now have as first paragraph above was my
>> suggestion, so thank you for picking it up. However, the second
>> paragraph should have been deleted; I suggested the now-first paragraph
>> as a replacement for the now-second one.
>>
>> I wrote, "to keep our references within the virtio device protocol".
>> VirtioRingMap() is a VirtioLib function, which is a utility layer on top
>> of the virtio device protocol. So, as I said, VirtioLib patches may
>> refer to both VirtioLib and the protocol, but protocol patches should
>> preferably only refer to the protocol, and not VirtioLib.
>>
>>    VirtioLib --+
>>     |  ^       |
>>     |  |       |
>>     |  +-------+
>>     |
>>     v
>>    VirtioDeviceProtocol --+
>>                  ^        |
>>                  |        |
>>                  +--------+
>>
>> This is also consistent with the reordering of the patches that I asked
>> for (and that you implemented well in v3, thank you for it).
>>
>> So, apologies if I wasn't clear enough of this -- it's not a big deal at
>> all, I can remove the second paragraph when I push this.
>>
>> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
>>

Thanks Laszlo, Sorry I did not realize that second paragraph should have been
deleted. Thanks for fixing.

-Brijesh



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 08/23] OvmfPkg/Virtio10Dxe: add the RingBaseShift offset
  2017-08-23 12:22 ` [PATCH v3 08/23] OvmfPkg/Virtio10Dxe: add the RingBaseShift offset Brijesh Singh
@ 2017-08-23 20:51   ` Laszlo Ersek
  0 siblings, 0 replies; 46+ messages in thread
From: Laszlo Ersek @ 2017-08-23 20:51 UTC (permalink / raw)
  To: Brijesh Singh, edk2-devel; +Cc: Jordan Justen, Tom Lendacky, Ard Biesheuvel

On 08/23/17 14:22, Brijesh Singh wrote:
> virtio drivers use VIRTIO_DEVICE_PROTOCOL.MapSharedBuffer() to map the
> ring buffer host address to a device address. If an IOMMU is present then
> RingBaseShift contains the offset from the host address.
> 
> 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>
> ---
>  OvmfPkg/Virtio10Dxe/Virtio10.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)

Reviewed-by: Laszlo Ersek <lersek@redhat.com>

Thanks!
Laszlo

> diff --git a/OvmfPkg/Virtio10Dxe/Virtio10.c b/OvmfPkg/Virtio10Dxe/Virtio10.c
> index ef9a00710668..e9b50b6e437b 100644
> --- a/OvmfPkg/Virtio10Dxe/Virtio10.c
> +++ b/OvmfPkg/Virtio10Dxe/Virtio10.c
> @@ -498,11 +498,10 @@ Virtio10SetQueueAddress (
>    UINT64         Address;
>    UINT16         Enable;
>  
> -  ASSERT (RingBaseShift == 0);
> -
>    Dev = VIRTIO_1_0_FROM_VIRTIO_DEVICE (This);
>  
>    Address = (UINTN)Ring->Desc;
> +  Address += RingBaseShift;
>    Status = Virtio10Transfer (Dev->PciIo, &Dev->CommonConfig, TRUE,
>               OFFSET_OF (VIRTIO_PCI_COMMON_CFG, QueueDesc),
>               sizeof Address, &Address);
> @@ -511,6 +510,7 @@ Virtio10SetQueueAddress (
>    }
>  
>    Address = (UINTN)Ring->Avail.Flags;
> +  Address += RingBaseShift;
>    Status = Virtio10Transfer (Dev->PciIo, &Dev->CommonConfig, TRUE,
>               OFFSET_OF (VIRTIO_PCI_COMMON_CFG, QueueAvail),
>               sizeof Address, &Address);
> @@ -519,6 +519,7 @@ Virtio10SetQueueAddress (
>    }
>  
>    Address = (UINTN)Ring->Used.Flags;
> +  Address += RingBaseShift;
>    Status = Virtio10Transfer (Dev->PciIo, &Dev->CommonConfig, TRUE,
>               OFFSET_OF (VIRTIO_PCI_COMMON_CFG, QueueUsed),
>               sizeof Address, &Address);
> 



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 10/23] OvmfPkg/VirtioLib: alloc VRING buffer with AllocateSharedPages()
  2017-08-23 12:22 ` [PATCH v3 10/23] OvmfPkg/VirtioLib: alloc VRING buffer with AllocateSharedPages() Brijesh Singh
@ 2017-08-23 21:18   ` Laszlo Ersek
  0 siblings, 0 replies; 46+ messages in thread
From: Laszlo Ersek @ 2017-08-23 21:18 UTC (permalink / raw)
  To: Brijesh Singh, edk2-devel; +Cc: Jordan Justen, Tom Lendacky, Ard Biesheuvel

On 08/23/17 14:22, Brijesh Singh wrote:
> The VRING buffer is a communication area between guest and hypervisor.
> Allocate it using VIRTIO_DEVICE_PROTOCOL.AllocateSharedPages() so that
> it can be mapped later with VirtioRingMap() for bi-directional access.
> 
> 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/Library/VirtioLib/VirtioLib.inf |  1 -
>  OvmfPkg/Include/Library/VirtioLib.h     |  5 ++---
>  OvmfPkg/Library/VirtioLib/VirtioLib.c   | 22 +++++++++++++-------
>  3 files changed, 16 insertions(+), 12 deletions(-)
> 
> diff --git a/OvmfPkg/Library/VirtioLib/VirtioLib.inf b/OvmfPkg/Library/VirtioLib/VirtioLib.inf
> index fb5897a88ecf..e33856de38c4 100644
> --- a/OvmfPkg/Library/VirtioLib/VirtioLib.inf
> +++ b/OvmfPkg/Library/VirtioLib/VirtioLib.inf
> @@ -32,5 +32,4 @@ [LibraryClasses]
>    BaseLib
>    BaseMemoryLib
>    DebugLib
> -  MemoryAllocationLib
>    UefiBootServicesTableLib
> diff --git a/OvmfPkg/Include/Library/VirtioLib.h b/OvmfPkg/Include/Library/VirtioLib.h
> index 3d9314b3acaf..c3e56ea23b89 100644
> --- a/OvmfPkg/Include/Library/VirtioLib.h
> +++ b/OvmfPkg/Include/Library/VirtioLib.h
> @@ -42,9 +42,8 @@
>  
>    @param[out] Ring              The virtio ring to set up.
>  
> -  @retval EFI_OUT_OF_RESOURCES  AllocatePages() failed to allocate contiguous
> -                                pages for the requested QueueSize. Fields of
> -                                Ring have indeterminate value.
> +  @retval                       Status codes propagated from
> +                                VirtIo->AllocateSharedPages().

(1) The documentation has been updated (thanks for that), but I also
requested "@return", not "@retval". Can be fixed up on push.

>  
>    @retval EFI_SUCCESS           Allocation and setup successful. Ring->Base
>                                  (and nothing else) is responsible for
> diff --git a/OvmfPkg/Library/VirtioLib/VirtioLib.c b/OvmfPkg/Library/VirtioLib/VirtioLib.c
> index 535635ac0ba8..e5366e385f5d 100644
> --- a/OvmfPkg/Library/VirtioLib/VirtioLib.c
> +++ b/OvmfPkg/Library/VirtioLib/VirtioLib.c
> @@ -19,7 +19,6 @@
>  #include <Library/BaseLib.h>
>  #include <Library/BaseMemoryLib.h>
>  #include <Library/DebugLib.h>
> -#include <Library/MemoryAllocationLib.h>
>  #include <Library/UefiBootServicesTableLib.h>
>  
>  #include <Library/VirtioLib.h>
> @@ -44,9 +43,8 @@
>  
>    @param[out] Ring              The virtio ring to set up.
>  
> -  @retval EFI_OUT_OF_RESOURCES  AllocatePages() failed to allocate contiguous
> -                                pages for the requested QueueSize. Fields of
> -                                Ring have indeterminate value.
> +  @retval                       Status codes propagated from
> +                                VirtIo->AllocateSharedPages().

(2) Same as (1), should be @return.

Reviewed-by: Laszlo Ersek <lersek@redhat.com>

Thanks!
Laszlo

>  
>    @retval EFI_SUCCESS           Allocation and setup successful. Ring->Base
>                                  (and nothing else) is responsible for
> @@ -61,6 +59,7 @@ VirtioRingInit (
>    OUT VRING                  *Ring
>    )
>  {
> +  EFI_STATUS     Status;
>    UINTN          RingSize;
>    volatile UINT8 *RingPagesPtr;
>  
> @@ -79,10 +78,17 @@ VirtioRingInit (
>                  sizeof *Ring->Used.AvailEvent,
>                  EFI_PAGE_SIZE);
>  
> +  //
> +  // Allocate a shared ring buffer
> +  //
>    Ring->NumPages = EFI_SIZE_TO_PAGES (RingSize);
> -  Ring->Base = AllocatePages (Ring->NumPages);
> -  if (Ring->Base == NULL) {
> -    return EFI_OUT_OF_RESOURCES;
> +  Status = VirtIo->AllocateSharedPages (
> +                     VirtIo,
> +                     Ring->NumPages,
> +                     &Ring->Base
> +                     );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
>    }
>    SetMem (Ring->Base, RingSize, 0x00);
>    RingPagesPtr = Ring->Base;
> @@ -143,7 +149,7 @@ VirtioRingUninit (
>    IN OUT VRING                  *Ring
>    )
>  {
> -  FreePages (Ring->Base, Ring->NumPages);
> +  VirtIo->FreeSharedPages (VirtIo, Ring->NumPages, Ring->Base);
>    SetMem (Ring, sizeof *Ring, 0x00);
>  }
>  
> 



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 11/23] OvmfPkg/VirtioLib: change the parameter of VirtioAppendDesc() to UINT64
  2017-08-23 12:22 ` [PATCH v3 11/23] OvmfPkg/VirtioLib: change the parameter of VirtioAppendDesc() to UINT64 Brijesh Singh
@ 2017-08-23 21:38   ` Laszlo Ersek
  0 siblings, 0 replies; 46+ messages in thread
From: Laszlo Ersek @ 2017-08-23 21:38 UTC (permalink / raw)
  To: Brijesh Singh, edk2-devel; +Cc: Jordan Justen, Tom Lendacky, Ard Biesheuvel

On 08/23/17 14:22, Brijesh Singh wrote:
> The patch change the "BufferPhysAddr" parameter of VirtioAppendDesc()
> from type UINTN to UINT64.
> 
> UINTN is appropriate as long as we pass system memory references. After
> the introduction of this feature, that's no longer the case in general.

(1) s/this feature/bus master device addresses/

> Should we implement "real" IOMMU support at some point, UINTN could
> break in 32-bit builds of OVMF.
> 
> 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>
> ---
>  OvmfPkg/Include/Library/VirtioLib.h   | 35 +++++++++---------
>  OvmfPkg/Library/VirtioLib/VirtioLib.c | 38 ++++++++++----------
>  2 files changed, 37 insertions(+), 36 deletions(-)
> 
> diff --git a/OvmfPkg/Include/Library/VirtioLib.h b/OvmfPkg/Include/Library/VirtioLib.h
> index c3e56ea23b89..a966311ac941 100644
> --- a/OvmfPkg/Include/Library/VirtioLib.h
> +++ b/OvmfPkg/Include/Library/VirtioLib.h
> @@ -151,33 +151,34 @@ VirtioPrepare (
>    The caller is responsible for initializing *Indices with VirtioPrepare()
>    first.
>  
> -  @param[in,out] Ring        The virtio ring to append the buffer to, as a
> -                             descriptor.
> +  @param[in,out] Ring               The virtio ring to append the buffer to,
> +                                    as a descriptor.
>  
> -  @param[in] BufferPhysAddr  (Guest pseudo-physical) start address of the
> -                             transmit / receive buffer.
> +  @param[in] BufferDeviceAddress    (Bus master device)) start address of the

(2) Unbalanced parentheses

> +                                    transmit / receive buffer.
>  
> -  @param[in] BufferSize      Number of bytes to transmit or receive.
> +  @param[in] BufferSize             Number of bytes to transmit or receive.
>  
> -  @param[in] Flags           A bitmask of VRING_DESC_F_* flags. The caller
> -                             computes this mask dependent on further buffers to
> -                             append and transfer direction.
> -                             VRING_DESC_F_INDIRECT is unsupported. The
> -                             VRING_DESC.Next field is always set, but the host
> -                             only interprets it dependent on VRING_DESC_F_NEXT.
> +  @param[in] Flags                  A bitmask of VRING_DESC_F_* flags. The
> +                                    caller computes this mask dependent on
> +                                    further buffers to append and transfer
> +                                    direction. VRING_DESC_F_INDIRECT is
> +                                    unsupported. The VRING_DESC.Next field is
> +                                    always set, but the host only interprets
> +                                    it dependent on VRING_DESC_F_NEXT.
>  
> -  @param[in,out] Indices     Indices->HeadDescIdx is not accessed.
> -                             On input, Indices->NextDescIdx identifies the next
> -                             descriptor to carry the buffer. On output,
> -                             Indices->NextDescIdx is incremented by one, modulo
> -                             2^16.
> +  @param[in,out] Indices            Indices->HeadDescIdx is not accessed.
> +                                    On input, Indices->NextDescIdx identifies
> +                                    the next descriptor to carry the buffer.
> +                                    On output, Indices->NextDescIdx is
> +                                    incremented by one, modulo 2^16.
>  
>  **/
>  VOID
>  EFIAPI
>  VirtioAppendDesc (
>    IN OUT VRING        *Ring,
> -  IN     UINTN        BufferPhysAddr,
> +  IN     UINT64       BufferDeviceAddress,
>    IN     UINT32       BufferSize,
>    IN     UINT16       Flags,
>    IN OUT DESC_INDICES *Indices
> diff --git a/OvmfPkg/Library/VirtioLib/VirtioLib.c b/OvmfPkg/Library/VirtioLib/VirtioLib.c
> index e5366e385f5d..fcd484fffada 100644
> --- a/OvmfPkg/Library/VirtioLib/VirtioLib.c
> +++ b/OvmfPkg/Library/VirtioLib/VirtioLib.c
> @@ -189,7 +189,6 @@ VirtioPrepare (
>    Indices->NextDescIdx = Indices->HeadDescIdx;
>  }
>  
> -
>  /**
>  
>    Append a contiguous buffer for transmission / reception via the virtio ring.
> @@ -205,33 +204,34 @@ VirtioPrepare (
>    The caller is responsible for initializing *Indices with VirtioPrepare()
>    first.
>  
> -  @param[in,out] Ring        The virtio ring to append the buffer to, as a
> -                             descriptor.
> +  @param[in,out] Ring               The virtio ring to append the buffer to,
> +                                    as a descriptor.
>  
> -  @param[in] BufferPhysAddr  (Guest pseudo-physical) start address of the
> -                             transmit / receive buffer.
> +  @param[in] BufferDeviceAddress    (Bus master device)) start address of the

(3) Same as (2), unbalanced parens.


With these fixed up (which I plan to do before pushing the patches):

Reviewed-by: Laszlo Ersek <lersek@redhat.com>

Thanks
Laszlo

> +                                    transmit / receive buffer.
>  
> -  @param[in] BufferSize      Number of bytes to transmit or receive.
> +  @param[in] BufferSize             Number of bytes to transmit or receive.
>  
> -  @param[in] Flags           A bitmask of VRING_DESC_F_* flags. The caller
> -                             computes this mask dependent on further buffers to
> -                             append and transfer direction.
> -                             VRING_DESC_F_INDIRECT is unsupported. The
> -                             VRING_DESC.Next field is always set, but the host
> -                             only interprets it dependent on VRING_DESC_F_NEXT.
> +  @param[in] Flags                  A bitmask of VRING_DESC_F_* flags. The
> +                                    caller computes this mask dependent on
> +                                    further buffers to append and transfer
> +                                    direction. VRING_DESC_F_INDIRECT is
> +                                    unsupported. The VRING_DESC.Next field is
> +                                    always set, but the host only interprets
> +                                    it dependent on VRING_DESC_F_NEXT.
>  
> -  @param[in,out] Indices     Indices->HeadDescIdx is not accessed.
> -                             On input, Indices->NextDescIdx identifies the next
> -                             descriptor to carry the buffer. On output,
> -                             Indices->NextDescIdx is incremented by one, modulo
> -                             2^16.
> +  @param[in,out] Indices            Indices->HeadDescIdx is not accessed.
> +                                    On input, Indices->NextDescIdx identifies
> +                                    the next descriptor to carry the buffer.
> +                                    On output, Indices->NextDescIdx is
> +                                    incremented by one, modulo 2^16.
>  
>  **/
>  VOID
>  EFIAPI
>  VirtioAppendDesc (
>    IN OUT VRING        *Ring,
> -  IN     UINTN        BufferPhysAddr,
> +  IN     UINT64       BufferDeviceAddress,
>    IN     UINT32       BufferSize,
>    IN     UINT16       Flags,
>    IN OUT DESC_INDICES *Indices
> @@ -240,7 +240,7 @@ VirtioAppendDesc (
>    volatile VRING_DESC *Desc;
>  
>    Desc        = &Ring->Desc[Indices->NextDescIdx++ % Ring->QueueSize];
> -  Desc->Addr  = BufferPhysAddr;
> +  Desc->Addr  = BufferDeviceAddress;
>    Desc->Len   = BufferSize;
>    Desc->Flags = Flags;
>    Desc->Next  = Indices->NextDescIdx % Ring->QueueSize;
> 



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 12/23] OvmfPkg/VirtioRngDxe: map host address to device address
  2017-08-23 12:22 ` [PATCH v3 12/23] OvmfPkg/VirtioRngDxe: map host address to device address Brijesh Singh
@ 2017-08-23 22:54   ` Laszlo Ersek
  0 siblings, 0 replies; 46+ messages in thread
From: Laszlo Ersek @ 2017-08-23 22:54 UTC (permalink / raw)
  To: Brijesh Singh, edk2-devel; +Cc: Jordan Justen, Tom Lendacky, Ard Biesheuvel

On 08/23/17 14:22, Brijesh Singh wrote:
> patch maps the host address to a device address for buffers (including
> rings, device specifc request and response pointed by vring descriptor,
> and any further memory reference by those request and response).
> 
> 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/VirtioRngDxe/VirtioRng.h |  1 +
>  OvmfPkg/VirtioRngDxe/VirtioRng.c | 82 +++++++++++++++++---
>  2 files changed, 74 insertions(+), 9 deletions(-)
> 
> diff --git a/OvmfPkg/VirtioRngDxe/VirtioRng.h b/OvmfPkg/VirtioRngDxe/VirtioRng.h
> index 998f9fae48c2..389c8ddc8d31 100644
> --- a/OvmfPkg/VirtioRngDxe/VirtioRng.h
> +++ b/OvmfPkg/VirtioRngDxe/VirtioRng.h
> @@ -38,6 +38,7 @@ typedef struct {
>    EFI_EVENT                 ExitBoot;       // DriverBindingStart   0
>    VRING                     Ring;           // VirtioRingInit       2
>    EFI_RNG_PROTOCOL          Rng;            // VirtioRngInit        1
> +  VOID                      *RingMap;       // VirtioRingMap        2
>  } VIRTIO_RNG_DEV;
>  
>  #define VIRTIO_ENTROPY_SOURCE_FROM_RNG(RngPointer) \
> diff --git a/OvmfPkg/VirtioRngDxe/VirtioRng.c b/OvmfPkg/VirtioRngDxe/VirtioRng.c
> index 0abca488e6cd..59f32d343179 100644
> --- a/OvmfPkg/VirtioRngDxe/VirtioRng.c
> +++ b/OvmfPkg/VirtioRngDxe/VirtioRng.c
> @@ -140,6 +140,8 @@ VirtioRngGetRNG (
>    UINT32                    Len;
>    UINT32                    BufferSize;
>    EFI_STATUS                Status;
> +  EFI_PHYSICAL_ADDRESS      DeviceAddress;
> +  VOID                      *Mapping;
>  
>    if (This == NULL || RNGValueLength == 0 || RNGValue == NULL) {
>      return EFI_INVALID_PARAMETER;
> @@ -159,6 +161,20 @@ VirtioRngGetRNG (
>    }
>  
>    Dev = VIRTIO_ENTROPY_SOURCE_FROM_RNG (This);
> +  //
> +  // Map Buffer's system phyiscal address to device address
> +  //
> +  Status = VirtioMapAllBytesInSharedBuffer (
> +             Dev->VirtIo,
> +             VirtioOperationBusMasterWrite,
> +             (VOID *)Buffer,
> +             RNGValueLength,
> +             &DeviceAddress,
> +             &Mapping
> +             );
> +  if (EFI_ERROR (Status)) {
> +    goto FreeBuffer;
> +  }

(1) Sorry, I missed this in my previous review:

According to the interface contract of this protocol member function, we
should set Status to EFI_DEVICE_ERROR here, before jumping to the
FreeBuffer label. (Both old code, and new code other than this, do it.)

I can fix this up.

With that:

Reviewed-by: Laszlo Ersek <lersek@redhat.com>

Thanks,
Laszlo

>  
>    //
>    // The Virtio RNG device may return less data than we asked it to, and can
> @@ -170,7 +186,7 @@ VirtioRngGetRNG (
>  
>      VirtioPrepare (&Dev->Ring, &Indices);
>      VirtioAppendDesc (&Dev->Ring,
> -      (UINTN)Buffer + Index,
> +      DeviceAddress + Index,
>        BufferSize,
>        VRING_DESC_F_WRITE,
>        &Indices);
> @@ -178,17 +194,35 @@ VirtioRngGetRNG (
>      if (VirtioFlush (Dev->VirtIo, 0, &Dev->Ring, &Indices, &Len) !=
>          EFI_SUCCESS) {
>        Status = EFI_DEVICE_ERROR;
> -      goto FreeBuffer;
> +      goto UnmapBuffer;
>      }
>      ASSERT (Len > 0);
>      ASSERT (Len <= BufferSize);
>    }
>  
> +  //
> +  // Unmap the device buffer before accessing it.
> +  //
> +  Status = Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Mapping);
> +  if (EFI_ERROR (Status)) {
> +    Status = EFI_DEVICE_ERROR;
> +    goto FreeBuffer;
> +  }
> +
>    for (Index = 0; Index < RNGValueLength; Index++) {
>      RNGValue[Index] = Buffer[Index];
>    }
>    Status = EFI_SUCCESS;
>  
> +UnmapBuffer:
> +  //
> +  // If we are reached here due to the error then unmap the buffer otherwise
> +  // the buffer is already unmapped after VirtioFlush().
> +  //
> +  if (EFI_ERROR (Status)) {
> +    Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Mapping);
> +  }
> +
>  FreeBuffer:
>    FreePool ((VOID *)Buffer);
>    return Status;
> @@ -205,6 +239,7 @@ VirtioRngInit (
>    EFI_STATUS Status;
>    UINT16     QueueSize;
>    UINT64     Features;
> +  UINT64     RingBaseShift;
>  
>    //
>    // Execute virtio-0.9.5, 2.2.1 Device Initialization Sequence.
> @@ -282,25 +317,42 @@ VirtioRngInit (
>    }
>  
>    //
> +  // If anything fails from here on, we must release the ring resources.
> +  //
> +  Status = VirtioRingMap (
> +             Dev->VirtIo,
> +             &Dev->Ring,
> +             &RingBaseShift,
> +             &Dev->RingMap
> +             );
> +  if (EFI_ERROR (Status)) {
> +    goto ReleaseQueue;
> +  }
> +
> +  //
>    // Additional steps for MMIO: align the queue appropriately, and set the
> -  // size. If anything fails from here on, we must release the ring resources.
> +  // size. If anything fails from here on, we must unmap the ring resources.
>    //
>    Status = Dev->VirtIo->SetQueueNum (Dev->VirtIo, QueueSize);
>    if (EFI_ERROR (Status)) {
> -    goto ReleaseQueue;
> +    goto UnmapQueue;
>    }
>  
>    Status = Dev->VirtIo->SetQueueAlign (Dev->VirtIo, EFI_PAGE_SIZE);
>    if (EFI_ERROR (Status)) {
> -    goto ReleaseQueue;
> +    goto UnmapQueue;
>    }
>  
>    //
>    // step 4c -- Report GPFN (guest-physical frame number) of queue.
>    //
> -  Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, &Dev->Ring, 0);
> +  Status = Dev->VirtIo->SetQueueAddress (
> +                          Dev->VirtIo,
> +                          &Dev->Ring,
> +                          RingBaseShift
> +                          );
>    if (EFI_ERROR (Status)) {
> -    goto ReleaseQueue;
> +    goto UnmapQueue;
>    }
>  
>    //
> @@ -310,7 +362,7 @@ VirtioRngInit (
>      Features &= ~(UINT64)VIRTIO_F_VERSION_1;
>      Status = Dev->VirtIo->SetGuestFeatures (Dev->VirtIo, Features);
>      if (EFI_ERROR (Status)) {
> -      goto ReleaseQueue;
> +      goto UnmapQueue;
>      }
>    }
>  
> @@ -320,7 +372,7 @@ VirtioRngInit (
>    NextDevStat |= VSTAT_DRIVER_OK;
>    Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
>    if (EFI_ERROR (Status)) {
> -    goto ReleaseQueue;
> +    goto UnmapQueue;
>    }
>  
>    //
> @@ -331,6 +383,9 @@ VirtioRngInit (
>  
>    return EFI_SUCCESS;
>  
> +UnmapQueue:
> +  Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->RingMap);
> +
>  ReleaseQueue:
>    VirtioRingUninit (Dev->VirtIo, &Dev->Ring);
>  
> @@ -359,6 +414,9 @@ VirtioRngUninit (
>    // the old comms area.
>    //
>    Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
> +
> +  Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->RingMap);
> +
>    VirtioRingUninit (Dev->VirtIo, &Dev->Ring);
>  }
>  
> @@ -385,6 +443,12 @@ VirtioRngExitBoot (
>    //
>    Dev = Context;
>    Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
> +
> +  //
> +  // Unmap the ring buffer so that hypervisor will not be able to get readable
> +  // data after device reset.
> +  //
> +  Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->RingMap);
>  }
>  
>  
> 



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 19/23] OvmfPkg/Virtio10: define VIRITO_F_IOMMU_PLATFORM feature bit
  2017-08-23 12:22 ` [PATCH v3 19/23] OvmfPkg/Virtio10: define VIRITO_F_IOMMU_PLATFORM feature bit Brijesh Singh
@ 2017-08-23 23:04   ` Laszlo Ersek
  0 siblings, 0 replies; 46+ messages in thread
From: Laszlo Ersek @ 2017-08-23 23:04 UTC (permalink / raw)
  To: Brijesh Singh, edk2-devel; +Cc: Jordan Justen, Tom Lendacky, Ard Biesheuvel

(1) The subject line contains a super-sneaky typo which I missed in my
previous review: VIR-I-T-O vs. VIR-T-I-O.

     vv
  VIRITO_F_IOMMU_PLATFORM
  VIRTIO_F_IOMMU_PLATFORM
     ^^

The code is correct.

With the subject fixed (which I plan to do):

Reviewed-by: Laszlo Ersek <lersek@redhat.com>

Thanks
Laszlo



On 08/23/17 14:22, Brijesh Singh wrote:
> This feature indicates that the device is behind an IOMMU that translates
> bus addresses from the device into physical addresses in memory.  If this
> feature bit is set to 0, then the device emits physical addresses which
> are not translated further, even though an IOMMU may be present.
> see [1] for more infromation
> 
> [1] https://lists.oasis-open.org/archives/virtio-dev/201610/msg00121.html
> 
> 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/Include/IndustryStandard/Virtio10.h | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/OvmfPkg/Include/IndustryStandard/Virtio10.h b/OvmfPkg/Include/IndustryStandard/Virtio10.h
> index 4c9b62a3cf59..c5efb5cfcb8a 100644
> --- a/OvmfPkg/Include/IndustryStandard/Virtio10.h
> +++ b/OvmfPkg/Include/IndustryStandard/Virtio10.h
> @@ -2,6 +2,7 @@
>    Definitions from the VirtIo 1.0 specification (csprd05).
>  
>    Copyright (C) 2016, Red Hat, Inc.
> +  Copyright (C) 2017, AMD, Inc.
>  
>    This program and the accompanying materials are licensed and made available
>    under the terms and conditions of the BSD License which accompanies this
> @@ -81,6 +82,7 @@ typedef struct {
>  //
>  // VirtIo 1.0 reserved (device-independent) feature bits
>  //
> -#define VIRTIO_F_VERSION_1 BIT32
> +#define VIRTIO_F_VERSION_1      BIT32
> +#define VIRTIO_F_IOMMU_PLATFORM BIT33
>  
>  #endif // _VIRTIO_1_0_H_
> 



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 20/23] OvmfPkg/VirtioRngDxe: negotiate VIRITO_F_IOMMU_PLATFORM
  2017-08-23 12:22 ` [PATCH v3 20/23] OvmfPkg/VirtioRngDxe: negotiate VIRITO_F_IOMMU_PLATFORM Brijesh Singh
@ 2017-08-23 23:21   ` Laszlo Ersek
  2017-08-23 23:24     ` Brijesh Singh
  0 siblings, 1 reply; 46+ messages in thread
From: Laszlo Ersek @ 2017-08-23 23:21 UTC (permalink / raw)
  To: Brijesh Singh, edk2-devel; +Cc: Jordan Justen, Tom Lendacky, Ard Biesheuvel

(1) Please replace "VIRITO_F_IOMMU_PLATFORM" with
"VIRTIO_F_IOMMU_PLATFORM" in the subjects of the remaining patches
(including this one).

On 08/23/17 14:22, Brijesh Singh wrote:
> In previous patches, we have implemented IOMMU-like member functions in
> VIRTIO_DEVICE_PROTOCOL to translate the physical address to bus address
> and virtio drivers are updated to use those member functions. We do not
> need to do anything special when VIRTIO_F_IOMMU_PLATFORM bit is present
> hence treat it in parallel with VIRTIO_F_VERSION_1.
> 
> 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/VirtioRngDxe/VirtioRng.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/OvmfPkg/VirtioRngDxe/VirtioRng.c b/OvmfPkg/VirtioRngDxe/VirtioRng.c
> index 59f32d343179..32512d882f7d 100644
> --- a/OvmfPkg/VirtioRngDxe/VirtioRng.c
> +++ b/OvmfPkg/VirtioRngDxe/VirtioRng.c
> @@ -278,7 +278,7 @@ VirtioRngInit (
>      goto Failed;
>    }
>  
> -  Features &= VIRTIO_F_VERSION_1;
> +  Features &= VIRTIO_F_VERSION_1 | VIRTIO_F_IOMMU_PLATFORM;
>  
>    //
>    // In virtio-1.0, feature negotiation is expected to complete before queue
> @@ -359,7 +359,7 @@ VirtioRngInit (
>    // step 5 -- Report understood features and guest-tuneables.
>    //
>    if (Dev->VirtIo->Revision < VIRTIO_SPEC_REVISION (1, 0, 0)) {
> -    Features &= ~(UINT64)VIRTIO_F_VERSION_1;
> +    Features &= ~(UINT64)VIRTIO_F_VERSION_1 | VIRTIO_F_IOMMU_PLATFORM;

While all of the VIRTIO_F_VERSION_1 locations in this driver are covered
now, this change is invalid:

The bitwise-complement operator "~" has stronger binding than the
bitwise-or operator "|". The cast operator "(type)" also binds more
strongly than the bitwise-or operator "|".

The purpose of the above assignment is to clear both of the listed bits.
Therefore,

(2) parentheses are necessary tightly around the bitwise-or operator,
like I suggested in
<http://mid.mail-archive.com/82cb5dda-f02d-9e38-c47e-3723184dea08@redhat.com>,
point (4):

    Features &= ~(UINT64)(VIRTIO_F_VERSION_1 | VIRTIO_F_IOMMU_PLATFORM);

I think this comment too applies to the rest of the patches.

Thanks,
Laszlo

>      Status = Dev->VirtIo->SetGuestFeatures (Dev->VirtIo, Features);
>      if (EFI_ERROR (Status)) {
>        goto UnmapQueue;
> 



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 20/23] OvmfPkg/VirtioRngDxe: negotiate VIRITO_F_IOMMU_PLATFORM
  2017-08-23 23:21   ` Laszlo Ersek
@ 2017-08-23 23:24     ` Brijesh Singh
  0 siblings, 0 replies; 46+ messages in thread
From: Brijesh Singh @ 2017-08-23 23:24 UTC (permalink / raw)
  To: Laszlo Ersek, edk2-devel
  Cc: brijesh.singh, Jordan Justen, Tom Lendacky, Ard Biesheuvel



On 8/23/17 6:21 PM, Laszlo Ersek wrote:
> (1) Please replace "VIRITO_F_IOMMU_PLATFORM" with
> "VIRTIO_F_IOMMU_PLATFORM" in the subjects of the remaining patches
> (including this one).

I will fix it in v4.

> On 08/23/17 14:22, Brijesh Singh wrote:
>> In previous patches, we have implemented IOMMU-like member functions in
>> VIRTIO_DEVICE_PROTOCOL to translate the physical address to bus address
>> and virtio drivers are updated to use those member functions. We do not
>> need to do anything special when VIRTIO_F_IOMMU_PLATFORM bit is present
>> hence treat it in parallel with VIRTIO_F_VERSION_1.
>>
>> 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/VirtioRngDxe/VirtioRng.c | 4 ++--
>>  1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/OvmfPkg/VirtioRngDxe/VirtioRng.c b/OvmfPkg/VirtioRngDxe/VirtioRng.c
>> index 59f32d343179..32512d882f7d 100644
>> --- a/OvmfPkg/VirtioRngDxe/VirtioRng.c
>> +++ b/OvmfPkg/VirtioRngDxe/VirtioRng.c
>> @@ -278,7 +278,7 @@ VirtioRngInit (
>>      goto Failed;
>>    }
>>  
>> -  Features &= VIRTIO_F_VERSION_1;
>> +  Features &= VIRTIO_F_VERSION_1 | VIRTIO_F_IOMMU_PLATFORM;
>>  
>>    //
>>    // In virtio-1.0, feature negotiation is expected to complete before queue
>> @@ -359,7 +359,7 @@ VirtioRngInit (
>>    // step 5 -- Report understood features and guest-tuneables.
>>    //
>>    if (Dev->VirtIo->Revision < VIRTIO_SPEC_REVISION (1, 0, 0)) {
>> -    Features &= ~(UINT64)VIRTIO_F_VERSION_1;
>> +    Features &= ~(UINT64)VIRTIO_F_VERSION_1 | VIRTIO_F_IOMMU_PLATFORM;
> While all of the VIRTIO_F_VERSION_1 locations in this driver are covered
> now, this change is invalid:
>
> The bitwise-complement operator "~" has stronger binding than the
> bitwise-or operator "|". The cast operator "(type)" also binds more
> strongly than the bitwise-or operator "|".
>
> The purpose of the above assignment is to clear both of the listed bits.
> Therefore,
>
> (2) parentheses are necessary tightly around the bitwise-or operator,
> like I suggested in
> <http://mid.mail-archive.com/82cb5dda-f02d-9e38-c47e-3723184dea08@redhat.com>,
> point (4):
>
>     Features &= ~(UINT64)(VIRTIO_F_VERSION_1 | VIRTIO_F_IOMMU_PLATFORM);

Agreed, thanks. I will fix it in v4.

> I think this comment too applies to the rest of the patches.
>
> Thanks,
> Laszlo
>
>>      Status = Dev->VirtIo->SetGuestFeatures (Dev->VirtIo, Features);
>>      if (EFI_ERROR (Status)) {
>>        goto UnmapQueue;
>>



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 00/21] OvmfPkg/Virtio: introduce IOMMU-like member functions
  2017-08-23 12:22 [PATCH v3 00/21] OvmfPkg/Virtio: introduce IOMMU-like member functions Brijesh Singh
                   ` (22 preceding siblings ...)
  2017-08-23 12:22 ` [PATCH v3 23/23] OvmfPkg/VirtioNetDxe: " Brijesh Singh
@ 2017-08-24  0:26 ` Laszlo Ersek
  2017-08-24  0:54   ` Brijesh Singh
  2017-08-25  8:58   ` Laszlo Ersek
  23 siblings, 2 replies; 46+ messages in thread
From: Laszlo Ersek @ 2017-08-24  0:26 UTC (permalink / raw)
  To: Brijesh Singh, edk2-devel; +Cc: Jordan Justen, Tom Lendacky, Ard Biesheuvel

Hi Brijesh,

so here's what I'd like to do with v3:

On 08/23/17 14:22, Brijesh Singh wrote:
> Brijesh Singh (23):
>   OvmfPkg: introduce IOMMU-like member functions to
>     VIRTIO_DEVICE_PROTOCOL
>   OvmfPkg/Virtio10Dxe: implement IOMMU-like member functions
>   OvmfPkg/VirtioPciDeviceDxe: implement IOMMU-like member functions
>   OvmfPkg/VirtioMmioDeviceLib: implement IOMMU-like member functions
>   OvmfPkg/VirtioLib: add VirtioMapAllBytesInSharedBuffer() helper
>     function
>   OvmfPkg/VirtioLib: take VirtIo instance in
>     VirtioRingInit/VirtioRingUninit
>   OvmfPkg/Virtio: take RingBaseShift in SetQueueAddress()
>   OvmfPkg/Virtio10Dxe: add the RingBaseShift offset
>   OvmfPkg/VirtioLib: add function to map VRING
>   OvmfPkg/VirtioLib: alloc VRING buffer with AllocateSharedPages()
>   OvmfPkg/VirtioLib: change the parameter of VirtioAppendDesc() to
>     UINT64

(1) I'll take the first 11 patches (which work on the transports and
VirtioLib), fix up the trivial stuff I've found in the v3 review, and
add my R-b tags.


>   OvmfPkg/VirtioRngDxe: map host address to device address

(2) I'll do the same for the VirtioRngDxe driver.


(3) I'll test this initial sequence in various scenarios. I think that
the protocol / transport / VirtioLib changes are good at this point, and
the simplest driver (VirtioRngDxe) demonstrates how to put those new
features to use. It also enables regression testing.

Importantly, I also plan to regression-test the remaining (not yet
converted) drivers at this point. Those drivers are affected only by the
"alloc VRING buffer with AllocateSharedPages" patch, as follows:

- On legacy virtio-pci and virtio-mmio transports, the change is a
no-op, because the AllocateSharedPages() and FreeSharedPages() VirtIo
members are backed by MemoryAllocationLib's AllocatePages() /
FreePages(). So the behavior of VirtioRingInit() / VirtioRingUninit()
remains identical.

- On the virtio-1.0 transport, the direct AllocatePages() call in
VirtioRingInit() will be replaced with VirtIo.AllocateSharedPages ->
PciIo.AllocateBuffer -> PciRootBridgeIo.AllocateBuffer.

- The last function will either branch to gBS->AllocatePages -- if
there's no IoMmu protocol, i.e. no SEV -- which is identical to current
behavior, or branch to IoMmu.AllocateBuffer.

- in IoMmuAllocateBuffer(), we'll allocate StashBuffer on the side
(which is no problem), and the actual allocation (for HostAddress) will
be done with gBS->AllocatePages().

The end result is that at this point, the unconverted drivers won't yet
work on SEV, but they will continue working if SEV is absent. The only
difference is (dependent on transport) longer call chains to memory
allocation and freeing, and larger memory footprint. But, no regressions
in functionality.

If I'm satisfied with the above test results, I'll add my
Regression-tested-by tags as well, and push the first 12 patches.

This will provide a foundation for further driver work (incl. my
VirtioGpuDxe work).


>   OvmfPkg/VirtioBlkDxe: map host address to device address
>   OvmfPkg/VirtioScsiDxe: map host address to device address

(4) I've looked at these patches briefly. They are possibly fine now,
but they've grown way too big. I struggled with the verification of the
VirtioRngDxe driver patch, and each of these two is more than twice as big.

So please, split *each* of these two patches in two parts (a logical
build-up):
- the first part should map and unmap the vring (all relevant contexts),
- the second part should map the requests.


(5) (I think this is my most important point), with the foundation in
place, I suggest we switch to one series per driver. For each driver, I
have to look at the virtio spec, and "page-in" how the requests are
structured, what they do etc. It's not a mechanical process. All that
virtio stuff is easier to re-digest if we proceed device by device.

Should we need later tweaks for the foundation, then at this point I
prefer small incremental patches for that.


>   OvmfPkg/VirtioNetDxe: alloc Tx and Rx rings using AllocateSharedPage()
>   OvmfPkg/VirtioNetDxe: alloc RxBuf using AllocateSharedPages()
>   OvmfPkg/VirtioNetDxe: dynamically alloc transmit header
>   OvmfPkg/VirtioNetDxe: map transmit buffer host address to device
>     address

(6) This is obviously the most complex driver. I've only snuck a peek. I
have one comment at this point: *if* we have to do random lookups, then
lists aren't optimal.

Please consider using the following library class:

  MdePkg/Include/Library/OrderedCollectionLib.h

It is already resolved in the OVMF DSC files to the following instance:

  MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/

Examples for use:
- various modules in OvmfPkg,
- AppPkg/Applications/OrderedCollectionTest


>   OvmfPkg/Virtio10: define VIRITO_F_IOMMU_PLATFORM feature bit
>   OvmfPkg/VirtioRngDxe: negotiate VIRITO_F_IOMMU_PLATFORM

(7) I would have liked to include these two patches in my "initial
push", but minimally the second patch needs fixes from you.

After I'm done with point (3), please repost these patches *only*.


>   OvmfPkg/VirtioBlkDxe: negotiate VIRITO_F_IOMMU_PLATFORM
>   OvmfPkg/VirtioScsiDxe: negotiate VIRITO_F_IOMMU_PLATFORM
>   OvmfPkg/VirtioNetDxe: negotiate VIRITO_F_IOMMU_PLATFORM

(8) After these patches are fixed up, I suggest that you please post
each one of them at the end of the matching driver series.


> TODO:
>  * add VirtioGpuDxe (i will take Laszlo's offer that he can help with
>    this driver)

OK, will do, thank you!

In this work I'll also seek to follow the series layout proposed above.

>  * I did minimal test on aarch64 - I was running into some Linux
>    bootup issues with Fedora aarch64 iso. The issue does not appear to
>    be releated to virtio changes. If anyone can help doing additional
>    test with their aarch images that will be great ! thanks

I'll test on aarch64 too.

Thanks!
Laszlo


^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 00/21] OvmfPkg/Virtio: introduce IOMMU-like member functions
  2017-08-24  0:26 ` [PATCH v3 00/21] OvmfPkg/Virtio: introduce IOMMU-like member functions Laszlo Ersek
@ 2017-08-24  0:54   ` Brijesh Singh
  2017-08-24  1:22     ` Laszlo Ersek
  2017-08-25  8:58   ` Laszlo Ersek
  1 sibling, 1 reply; 46+ messages in thread
From: Brijesh Singh @ 2017-08-24  0:54 UTC (permalink / raw)
  To: Laszlo Ersek, edk2-devel
  Cc: brijesh.singh, Jordan Justen, Tom Lendacky, Ard Biesheuvel

Hi Laszlo,


On 8/23/17 7:26 PM, Laszlo Ersek wrote:
> Hi Brijesh,
>
> so here's what I'd like to do with v3:
>
> On 08/23/17 14:22, Brijesh Singh wrote:
>> Brijesh Singh (23):
>>   OvmfPkg: introduce IOMMU-like member functions to
>>     VIRTIO_DEVICE_PROTOCOL
>>   OvmfPkg/Virtio10Dxe: implement IOMMU-like member functions
>>   OvmfPkg/VirtioPciDeviceDxe: implement IOMMU-like member functions
>>   OvmfPkg/VirtioMmioDeviceLib: implement IOMMU-like member functions
>>   OvmfPkg/VirtioLib: add VirtioMapAllBytesInSharedBuffer() helper
>>     function
>>   OvmfPkg/VirtioLib: take VirtIo instance in
>>     VirtioRingInit/VirtioRingUninit
>>   OvmfPkg/Virtio: take RingBaseShift in SetQueueAddress()
>>   OvmfPkg/Virtio10Dxe: add the RingBaseShift offset
>>   OvmfPkg/VirtioLib: add function to map VRING
>>   OvmfPkg/VirtioLib: alloc VRING buffer with AllocateSharedPages()
>>   OvmfPkg/VirtioLib: change the parameter of VirtioAppendDesc() to
>>     UINT64
> (1) I'll take the first 11 patches (which work on the transports and
> VirtioLib), fix up the trivial stuff I've found in the v3 review, and
> add my R-b tags.

Thanks

>
>>   OvmfPkg/VirtioRngDxe: map host address to device address
> (2) I'll do the same for the VirtioRngDxe driver.
>

Thanks

> (3) I'll test this initial sequence in various scenarios. I think that
> the protocol / transport / VirtioLib changes are good at this point, and
> the simplest driver (VirtioRngDxe) demonstrates how to put those new
> features to use. It also enables regression testing.
>
> Importantly, I also plan to regression-test the remaining (not yet
> converted) drivers at this point. Those drivers are affected only by the
> "alloc VRING buffer with AllocateSharedPages" patch, as follows:
>
> - On legacy virtio-pci and virtio-mmio transports, the change is a
> no-op, because the AllocateSharedPages() and FreeSharedPages() VirtIo
> members are backed by MemoryAllocationLib's AllocatePages() /
> FreePages(). So the behavior of VirtioRingInit() / VirtioRingUninit()
> remains identical.
>
> - On the virtio-1.0 transport, the direct AllocatePages() call in
> VirtioRingInit() will be replaced with VirtIo.AllocateSharedPages ->
> PciIo.AllocateBuffer -> PciRootBridgeIo.AllocateBuffer.
>
> - The last function will either branch to gBS->AllocatePages -- if
> there's no IoMmu protocol, i.e. no SEV -- which is identical to current
> behavior, or branch to IoMmu.AllocateBuffer.
>
> - in IoMmuAllocateBuffer(), we'll allocate StashBuffer on the side
> (which is no problem), and the actual allocation (for HostAddress) will
> be done with gBS->AllocatePages().
>
> The end result is that at this point, the unconverted drivers won't yet
> work on SEV, but they will continue working if SEV is absent. The only
> difference is (dependent on transport) longer call chains to memory
> allocation and freeing, and larger memory footprint. But, no regressions
> in functionality.
>
> If I'm satisfied with the above test results, I'll add my
> Regression-tested-by tags as well, and push the first 12 patches.
>
> This will provide a foundation for further driver work (incl. my
> VirtioGpuDxe work).

I agree with you. Sounds like a good plan.
>
>>   OvmfPkg/VirtioBlkDxe: map host address to device address
>>   OvmfPkg/VirtioScsiDxe: map host address to device address
> (4) I've looked at these patches briefly. They are possibly fine now,
> but they've grown way too big. I struggled with the verification of the
> VirtioRngDxe driver patch, and each of these two is more than twice as big.
Great thanks, I agree the series is getting bigger. After v1 feedbacks,
I was almost tempted to say that lets work to enable the base first then
will do one driver at a time. I was repeating the same mistake in each
patch and that was causing trouble to you and also I had to rework the
all drivers.

> So please, split *each* of these two patches in two parts (a logical
> build-up):
> - the first part should map and unmap the vring (all relevant contexts),
> - the second part should map the requests.
>
>
> (5) (I think this is my most important point), with the foundation in
> place, I suggest we switch to one series per driver. For each driver, I
> have to look at the virtio spec, and "page-in" how the requests are
> structured, what they do etc. It's not a mechanical process. All that
> virtio stuff is easier to re-digest if we proceed device by device.
>
> Should we need later tweaks for the foundation, then at this point I
> prefer small incremental patches for that.
>
>
>>   OvmfPkg/VirtioNetDxe: alloc Tx and Rx rings using AllocateSharedPage()
>>   OvmfPkg/VirtioNetDxe: alloc RxBuf using AllocateSharedPages()
>>   OvmfPkg/VirtioNetDxe: dynamically alloc transmit header
>>   OvmfPkg/VirtioNetDxe: map transmit buffer host address to device
>>     address
> (6) This is obviously the most complex driver. I've only snuck a peek. I
> have one comment at this point: *if* we have to do random lookups, then
> lists aren't optimal.
>
> Please consider using the following library class:
>
>   MdePkg/Include/Library/OrderedCollectionLib.h
>
> It is already resolved in the OVMF DSC files to the following instance:
>
>   MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/
>
> Examples for use:
> - various modules in OvmfPkg,
> - AppPkg/Applications/OrderedCollectionTest

Okay, I will look into it - thanks for the tip. I wanted to actually use
the Simple array (because we know the maximum number of buffer we can
queue) but was  not sure about your preferences hence I went to with
list. If you are okay then I can use array's too.
>
>>   OvmfPkg/Virtio10: define VIRITO_F_IOMMU_PLATFORM feature bit
>>   OvmfPkg/VirtioRngDxe: negotiate VIRITO_F_IOMMU_PLATFORM
> (7) I would have liked to include these two patches in my "initial
> push", but minimally the second patch needs fixes from you.
>
> After I'm done with point (3), please repost these patches *only*.

Sure will do. thanks
>
>>   OvmfPkg/VirtioBlkDxe: negotiate VIRITO_F_IOMMU_PLATFORM
>>   OvmfPkg/VirtioScsiDxe: negotiate VIRITO_F_IOMMU_PLATFORM
>>   OvmfPkg/VirtioNetDxe: negotiate VIRITO_F_IOMMU_PLATFORM
> (8) After these patches are fixed up, I suggest that you please post
> each one of them at the end of the matching driver series.
>

Will do.

>> TODO:
>>  * add VirtioGpuDxe (i will take Laszlo's offer that he can help with
>>    this driver)
> OK, will do, thank you!
>
> In this work I'll also seek to follow the series layout proposed above.
>
>>  * I did minimal test on aarch64 - I was running into some Linux
>>    bootup issues with Fedora aarch64 iso. The issue does not appear to
>>    be releated to virtio changes. If anyone can help doing additional
>>    test with their aarch images that will be great ! thanks
> I'll test on aarch64 too.

thank you.

-Brijesh


^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 00/21] OvmfPkg/Virtio: introduce IOMMU-like member functions
  2017-08-24  0:54   ` Brijesh Singh
@ 2017-08-24  1:22     ` Laszlo Ersek
  2017-08-24  2:06       ` Brijesh Singh
  0 siblings, 1 reply; 46+ messages in thread
From: Laszlo Ersek @ 2017-08-24  1:22 UTC (permalink / raw)
  To: Brijesh Singh, edk2-devel; +Cc: Jordan Justen, Tom Lendacky, Ard Biesheuvel

On 08/24/17 02:54, Brijesh Singh wrote:
> On 8/23/17 7:26 PM, Laszlo Ersek wrote:
>> On 08/23/17 14:22, Brijesh Singh wrote:

>>>   OvmfPkg/VirtioBlkDxe: map host address to device address
>>>   OvmfPkg/VirtioScsiDxe: map host address to device address

>> (4) I've looked at these patches briefly. They are possibly fine now,
>> but they've grown way too big. I struggled with the verification of the
>> VirtioRngDxe driver patch, and each of these two is more than twice as big.

> Great thanks, I agree the series is getting bigger. After v1 feedbacks,
> I was almost tempted to say that lets work to enable the base first then
> will do one driver at a time. I was repeating the same mistake in each
> patch and that was causing trouble to you and also I had to rework the
> all drivers.

Unfortunately (for both of us! :) ), this churn is unavoidable in the
first few versions of a large set -- the foundation is not dictated by
some "divine design", it is dictated only by what the higher level
drivers need. And we only find out what the higher level drivers need if
you at least prototype the patches for them, and I at least skim-review
those patches.

It's regrettable that it requires so much wasted work, but I don't know
how to do it better, save for knowing the future. :)

I trust at this point the base has stabilized enough, and if we need
further changes, we can solve that with small incremental patches.

>> (6) This is obviously the most complex driver. I've only snuck a peek. I
>> have one comment at this point: *if* we have to do random lookups, then
>> lists aren't optimal.
>>
>> Please consider using the following library class:
>>
>>   MdePkg/Include/Library/OrderedCollectionLib.h
>>
>> It is already resolved in the OVMF DSC files to the following instance:
>>
>>   MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/
>>
>> Examples for use:
>> - various modules in OvmfPkg,
>> - AppPkg/Applications/OrderedCollectionTest
> 
> Okay, I will look into it - thanks for the tip. I wanted to actually use
> the Simple array (because we know the maximum number of buffer we can
> queue) but was  not sure about your preferences hence I went to with
> list. If you are okay then I can use array's too.

My concern isn't about memory consumption (if our queue is full (64
elements, IIRC), we just reject the transmit request and let the caller
deal with the error).

Instead, I'd like to avoid an O(n) lookup time (where n is the number of
pending requests), for whatever lookup is necessary now (I haven't
checked the specifics yet). BaseOrderedCollectionRedBlackTreeLib would
give you O(log n) lookup time.

Without having looked at the details, I think an array would have O(n)
lookup time as well (linear search, right?).

(Let's not try to do O(1) with a hash function -- that's quite out of
scope for now, and with a hash table, one has to think about collisions
too, etc. When I contributed BaseOrderedCollectionRedBlackTreeLib, I
wanted it to become *the* go-to associative data structure for edk2 --
at least in such DXE and UEFI driver contexts where frequent pool
allocations and releases are not a problem. Plus, RB trees double as
fast priority queues, can be used for one-off sorting, have worst-case
(not just on-average) O(log n) time guarantees... I think they're
versatile.)

Cheers
Laszlo


^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 00/21] OvmfPkg/Virtio: introduce IOMMU-like member functions
  2017-08-24  1:22     ` Laszlo Ersek
@ 2017-08-24  2:06       ` Brijesh Singh
  2017-08-24 10:07         ` Laszlo Ersek
  0 siblings, 1 reply; 46+ messages in thread
From: Brijesh Singh @ 2017-08-24  2:06 UTC (permalink / raw)
  To: Laszlo Ersek, edk2-devel
  Cc: brijesh.singh, Jordan Justen, Tom Lendacky, Ard Biesheuvel



On 8/23/17 8:22 PM, Laszlo Ersek wrote:Okay, I will look into it -
thanks for the tip. I wanted to actually use
>> the Simple array (because we know the maximum number of buffer we can
>> queue) but was  not sure about your preferences hence I went to with
>> list. If you are okay then I can use array's too.
> My concern isn't about memory consumption (if our queue is full (64
> elements, IIRC), we just reject the transmit request and let the caller
> deal with the error).
>
> Instead, I'd like to avoid an O(n) lookup time (where n is the number of
> pending requests), for whatever lookup is necessary now (I haven't
> checked the specifics yet). BaseOrderedCollectionRedBlackTreeLib would
> give you O(log n) lookup time.
>
> Without having looked at the details, I think an array would have O(n)
> lookup time as well (linear search, right?).
>
> (Let's not try to do O(1) with a hash function -- that's quite out of
> scope for now, and with a hash table, one has to think about collisions
> too, etc. When I contributed BaseOrderedCollectionRedBlackTreeLib, I
> wanted it to become *the* go-to associative data structure for edk2 --
> at least in such DXE and UEFI driver contexts where frequent pool
> allocations and releases are not a problem. Plus, RB trees double as
> fast priority queues, can be used for one-off sorting, have worst-case
> (not just on-average) O(log n) time guarantees... I think they're
> versatile.)

To my understanding the network packet enqueued in the transmit ring
will be completed in same order, hence I was thinking about the queue
data structure and was not concern about the search time. I was mostly
concerned about the memory consumption but if my understanding is wrong
then I agree that we need to pick right data structure. Since the
RedBlack tree is already implemented hence I have no issue using it. thanks

-Brijesh
 



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 00/21] OvmfPkg/Virtio: introduce IOMMU-like member functions
  2017-08-24  2:06       ` Brijesh Singh
@ 2017-08-24 10:07         ` Laszlo Ersek
  0 siblings, 0 replies; 46+ messages in thread
From: Laszlo Ersek @ 2017-08-24 10:07 UTC (permalink / raw)
  To: Brijesh Singh, edk2-devel; +Cc: Jordan Justen, Tom Lendacky, Ard Biesheuvel

On 08/24/17 04:06, Brijesh Singh wrote:
> 
> 
> On 8/23/17 8:22 PM, Laszlo Ersek wrote:Okay, I will look into it -
> thanks for the tip. I wanted to actually use
>>> the Simple array (because we know the maximum number of buffer we can
>>> queue) but was  not sure about your preferences hence I went to with
>>> list. If you are okay then I can use array's too.
>> My concern isn't about memory consumption (if our queue is full (64
>> elements, IIRC), we just reject the transmit request and let the caller
>> deal with the error).
>>
>> Instead, I'd like to avoid an O(n) lookup time (where n is the number of
>> pending requests), for whatever lookup is necessary now (I haven't
>> checked the specifics yet). BaseOrderedCollectionRedBlackTreeLib would
>> give you O(log n) lookup time.
>>
>> Without having looked at the details, I think an array would have O(n)
>> lookup time as well (linear search, right?).
>>
>> (Let's not try to do O(1) with a hash function -- that's quite out of
>> scope for now, and with a hash table, one has to think about collisions
>> too, etc. When I contributed BaseOrderedCollectionRedBlackTreeLib, I
>> wanted it to become *the* go-to associative data structure for edk2 --
>> at least in such DXE and UEFI driver contexts where frequent pool
>> allocations and releases are not a problem. Plus, RB trees double as
>> fast priority queues, can be used for one-off sorting, have worst-case
>> (not just on-average) O(log n) time guarantees... I think they're
>> versatile.)
> 
> To my understanding the network packet enqueued in the transmit ring
> will be completed in same order,

The current code does not make this assumption -- please see the very
last paragraph in "OvmfPkg/VirtioNetDxe/TechNotes.txt" --, and it would
be good to keep it that way.

> hence I was thinking about the queue
> data structure and was not concern about the search time. I was mostly
> concerned about the memory consumption but if my understanding is wrong
> then I agree that we need to pick right data structure. Since the
> RedBlack tree is already implemented hence I have no issue using it. thanks

OK, thanks!
Laszlo


^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 00/21] OvmfPkg/Virtio: introduce IOMMU-like member functions
  2017-08-24  0:26 ` [PATCH v3 00/21] OvmfPkg/Virtio: introduce IOMMU-like member functions Laszlo Ersek
  2017-08-24  0:54   ` Brijesh Singh
@ 2017-08-25  8:58   ` Laszlo Ersek
  1 sibling, 0 replies; 46+ messages in thread
From: Laszlo Ersek @ 2017-08-25  8:58 UTC (permalink / raw)
  To: Brijesh Singh, edk2-devel; +Cc: Jordan Justen, Ard Biesheuvel, Tom Lendacky

On 08/24/17 02:26, Laszlo Ersek wrote:
> Hi Brijesh,
>
> so here's what I'd like to do with v3:
>
> On 08/23/17 14:22, Brijesh Singh wrote:
>> Brijesh Singh (23):
>>   OvmfPkg: introduce IOMMU-like member functions to
>>     VIRTIO_DEVICE_PROTOCOL
>>   OvmfPkg/Virtio10Dxe: implement IOMMU-like member functions
>>   OvmfPkg/VirtioPciDeviceDxe: implement IOMMU-like member functions
>>   OvmfPkg/VirtioMmioDeviceLib: implement IOMMU-like member functions
>>   OvmfPkg/VirtioLib: add VirtioMapAllBytesInSharedBuffer() helper
>>     function
>>   OvmfPkg/VirtioLib: take VirtIo instance in
>>     VirtioRingInit/VirtioRingUninit
>>   OvmfPkg/Virtio: take RingBaseShift in SetQueueAddress()
>>   OvmfPkg/Virtio10Dxe: add the RingBaseShift offset
>>   OvmfPkg/VirtioLib: add function to map VRING
>>   OvmfPkg/VirtioLib: alloc VRING buffer with AllocateSharedPages()
>>   OvmfPkg/VirtioLib: change the parameter of VirtioAppendDesc() to
>>     UINT64
>
> (1) I'll take the first 11 patches (which work on the transports and
> VirtioLib), fix up the trivial stuff I've found in the v3 review, and
> add my R-b tags.
>
>
>>   OvmfPkg/VirtioRngDxe: map host address to device address
>
> (2) I'll do the same for the VirtioRngDxe driver.
>
>
> (3) I'll test this initial sequence in various scenarios. I think that
> the protocol / transport / VirtioLib changes are good at this point,
> and the simplest driver (VirtioRngDxe) demonstrates how to put those
> new features to use. It also enables regression testing.
>
> Importantly, I also plan to regression-test the remaining (not yet
> converted) drivers at this point. Those drivers are affected only by
> the "alloc VRING buffer with AllocateSharedPages" patch, as follows:
>
> - On legacy virtio-pci and virtio-mmio transports, the change is a
> no-op, because the AllocateSharedPages() and FreeSharedPages() VirtIo
> members are backed by MemoryAllocationLib's AllocatePages() /
> FreePages(). So the behavior of VirtioRingInit() / VirtioRingUninit()
> remains identical.
>
> - On the virtio-1.0 transport, the direct AllocatePages() call in
> VirtioRingInit() will be replaced with VirtIo.AllocateSharedPages ->
> PciIo.AllocateBuffer -> PciRootBridgeIo.AllocateBuffer.
>
> - The last function will either branch to gBS->AllocatePages -- if
> there's no IoMmu protocol, i.e. no SEV -- which is identical to
> current behavior, or branch to IoMmu.AllocateBuffer.
>
> - in IoMmuAllocateBuffer(), we'll allocate StashBuffer on the side
> (which is no problem), and the actual allocation (for HostAddress)
> will be done with gBS->AllocatePages().
>
> The end result is that at this point, the unconverted drivers won't
> yet work on SEV, but they will continue working if SEV is absent. The
> only difference is (dependent on transport) longer call chains to
> memory allocation and freeing, and larger memory footprint. But, no
> regressions in functionality.
>
> If I'm satisfied with the above test results, I'll add my
> Regression-tested-by tags as well, and push the first 12 patches.

For patches v3 1-12:

Regression-tested-by: Laszlo Ersek <lersek@redhat.com>

I've pushed those patches now; commit range c69071bd7e21..0a568ccbcbd1.

The testing took incredibly long. For AARCH64 testing, I used my Mustang
(KVM). For IA32 and X64, I used my laptop (also KVM). This was all
without SEV (hence "regression testing".) Here's the matrix and some
remarks:

                            virtio-mmio  legacy PCI        modern PCI
                            -----------  ----------------- --------------------------
  device  test scenario     AARCH64      IA32     X64      IA32     X64      AARCH64
  ------  ----------------  -----------  -------- -------- -------- -------- --------
  rng     shell RECONNECT   PASS         PASS     PASS     PASS     PASS     PASS

  rng     RngTest.efi       PASS         PASS     PASS     PASS     PASS     PASS

  rng     ExitBootServices  PASS         PASS     PASS     PASS     PASS     PASS

  blk     shell RECONNECT   PASS         PASS     PASS     PASS     PASS     PASS

  blk     shell LS/TYPE     PASS         PASS     PASS     PASS     PASS     PASS

  blk     ExitBootServices  PASS         PASS     PASS     PASS     PASS     PASS

  scsi    shell RECONNECT   PASS         PASS     PASS     PASS     PASS     PASS

  scsi    OS boot           PASS         PASS     PASS     PASS     PASS     PASS

  scsi    ExitBootServices  PASS         PASS     PASS     PASS     PASS     PASS

  net     shell RECONNECT   PASS         PASS     PASS     PASS     PASS     PASS
          (parent, child)

  net     DHCP +            PASS[06]     SKIP[08] SKIP[10] SKIP[08] SKIP[10] PASS[03]
          DataSink.efi

  net     DHCP +            PASS[05]     SKIP[07] PASS[11] SKIP[07] PASS[09] PASS[04]
          DataSource.efi

  net     DHCP + PXE boot   PASS         PASS     PASS     PASS     PASS     PASS

  net     ExitBootServices  PASS         PASS     PASS     PASS     PASS     PASS

  gpu     shell RECONNECT   N/A[01]      N/A[01]  N/A[01]  N/A[02]  N/A[02]  PASS
          (parent, child)

  gpu     shell MODE        N/A[01]      N/A[01]  N/A[01]  N/A[02]  N/A[02]  PASS

  gpu     ExitBootServices  N/A[01]      N/A[01]  N/A[01]  N/A[02]  N/A[02]  PASS

Remarks:

[01] virtio-gpu is modern-only

[02] Libvirt maps the "virtio" video model to "virtio-vga" on IA32/X64,
     which is bound by QemuVideoDxe, and to "virtio-gpu-pci" on AARCH64,
     which is bound by VirtioGpuDxe.

[03] transferred 200 MB, average speed 1.3-1.6 MB/s

[04] transferred 20 MB, average speed 280 KB/s

[05] transferred 20 MB, average speed 96 KB/s

[06] transferred 80 MB, average speed 374 KB/s

[07] 295 KB were transferred, but when DataSource.efi wanted to print
     the first stats line, it crashed with a divide error:

     !!!! IA32 Exception Type - 00(#DE - Divide Error)  CPU Apic ID - 00000000 !!!!
     EIP  - 7CD2077A, CS  - 00000010, EFLAGS - 00010246
     EAX  - 00000000, ECX - 00000000, EDX - 00000000, EBX - 00000000
     ESP  - 7EEBE2EC, EBP - 7EEBE328, ESI - 000004D2, EDI - 00000000
     DS   - 00000008, ES  - 00000008, FS  - 00000008, GS  - 00000008, SS - 00000008
     CR0  - 00000033, CR2 - 00000000, CR3 - 00000000, CR4 - 00000640
     DR0  - 00000000, DR1 - 00000000, DR2 - 00000000, DR3 - 00000000
     DR6  - FFFF0FF0, DR7 - 00000400
     GDTR - 7EE07A90 00000047, IDTR - 7DDB7010 000007FF
     LDTR - 00000000, TR - 00000000
     FXSAVE_STATE - 7EEBE030
     !!!! Find image
     Build/AppPkg/NOOPT_GCC48/IA32/AppPkg/Applications/Sockets/DataSource/DataSource/DEBUG/DataSource.dll
     (ImageBase=000000007CCF3000, EntryPoint=000000007CCF3220) !!!!

     0002d770 <InternalMathDivRemU64x32>:
        2d770:       8b 4c 24 0c             mov    0xc(%esp),%ecx
        2d774:       8b 44 24 08             mov    0x8(%esp),%eax
        2d778:       31 d2                   xor    %edx,%edx
     -> 2d77a:       f7 f1                   div    %ecx
        2d77c:       50                      push   %eax
        2d77d:       8b 44 24 08             mov    0x8(%esp),%eax
        2d781:       f7 f1                   div    %ecx
        2d783:       8b 4c 24 14             mov    0x14(%esp),%ecx
        2d787:       e3 02                   jecxz  2d78b <InternalMathDivRemU64x32.0>
        2d789:       89 11                   mov    %edx,(%ecx)

     The same symptom reproduces without applying Brijesh's patches.

[08] after the connection is established, DataSink.efi crashes

     !!!! IA32 Exception Type - 00(#DE - Divide Error)  CPU Apic ID - 00000000 !!!!
     EIP  - 7CD211CA, CS  - 00000010, EFLAGS - 00010246
     EAX  - 00000000, ECX - 00000000, EDX - 00000000, EBX - 00000000
     ESP  - 7EEBE23C, EBP - 7EEBE278, ESI - 00000002, EDI - 00000000
     DS   - 00000008, ES  - 00000008, FS  - 00000008, GS  - 00000008, SS - 00000008
     CR0  - 00000033, CR2 - 00000000, CR3 - 00000000, CR4 - 00000640
     DR0  - 00000000, DR1 - 00000000, DR2 - 00000000, DR3 - 00000000
     DR6  - FFFF0FF0, DR7 - 00000400
     GDTR - 7EE07A90 00000047, IDTR - 7DDB7010 000007FF
     LDTR - 00000000, TR - 00000000
     FXSAVE_STATE - 7EEBDF80
     !!!! Find image
     Build/AppPkg/NOOPT_GCC48/IA32/AppPkg/Applications/Sockets/DataSink/DataSink/DEBUG/DataSink.dll
     (ImageBase=000000007CCFA000, EntryPoint=000000007CCFA220) !!!!

     000271c0 <InternalMathDivRemU64x32>:
        271c0:       8b 4c 24 0c             mov    0xc(%esp),%ecx
        271c4:       8b 44 24 08             mov    0x8(%esp),%eax
        271c8:       31 d2                   xor    %edx,%edx
     -> 271ca:       f7 f1                   div    %ecx
        271cc:       50                      push   %eax
        271cd:       8b 44 24 08             mov    0x8(%esp),%eax
        271d1:       f7 f1                   div    %ecx
        271d3:       8b 4c 24 14             mov    0x14(%esp),%ecx
        271d7:       e3 02                   jecxz  271db <InternalMathDivRemU64x32.0>
        271d9:       89 11                   mov    %edx,(%ecx)

     The same symptom reproduces without applying Brijesh's patches.

[09] transferred 30MB, average speed 282 KB/s

[10] DataSink.efi hangs. The connection is established (according to
     "netstat"), but no data is transferred. The OVMF log contains
     repeated messages

     TcpInput: sequence acceptance test failed for segment of TCB 7CF52998
     Tcp4Input: Discard a packet

     The same symptom reproduces without applying Brijesh's patches.

[11] transferred 10.2MB, average speed 282 KB/s


The DataSource.efi and DataSink.efi applications seem quite brittle to
me, so I think in the future I might switch to different tools for
testing virtio-net with TCP. HTTP boot looks like a good candidate
<https://github.com/tianocore/tianocore.github.io/wiki/HTTP-Boot>;
perhaps I'll try it out.

Brijesh, can you please proceed with step (7) below?

Thank you,
Laszlo

>
> This will provide a foundation for further driver work (incl. my
> VirtioGpuDxe work).
>
>
>>   OvmfPkg/VirtioBlkDxe: map host address to device address
>>   OvmfPkg/VirtioScsiDxe: map host address to device address
>
> (4) I've looked at these patches briefly. They are possibly fine now,
> but they've grown way too big. I struggled with the verification of
> the VirtioRngDxe driver patch, and each of these two is more than
> twice as big.
>
> So please, split *each* of these two patches in two parts (a logical
> build-up):
> - the first part should map and unmap the vring (all relevant
>   contexts),
> - the second part should map the requests.
>
>
> (5) (I think this is my most important point), with the foundation in
> place, I suggest we switch to one series per driver. For each driver,
> I have to look at the virtio spec, and "page-in" how the requests are
> structured, what they do etc. It's not a mechanical process. All that
> virtio stuff is easier to re-digest if we proceed device by device.
>
> Should we need later tweaks for the foundation, then at this point I
> prefer small incremental patches for that.
>
>
>>   OvmfPkg/VirtioNetDxe: alloc Tx and Rx rings using AllocateSharedPage()
>>   OvmfPkg/VirtioNetDxe: alloc RxBuf using AllocateSharedPages()
>>   OvmfPkg/VirtioNetDxe: dynamically alloc transmit header
>>   OvmfPkg/VirtioNetDxe: map transmit buffer host address to device
>>     address
>
> (6) This is obviously the most complex driver. I've only snuck a peek.
> I have one comment at this point: *if* we have to do random lookups,
> then lists aren't optimal.
>
> Please consider using the following library class:
>
>   MdePkg/Include/Library/OrderedCollectionLib.h
>
> It is already resolved in the OVMF DSC files to the following
> instance:
>
>   MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/
>
> Examples for use:
> - various modules in OvmfPkg,
> - AppPkg/Applications/OrderedCollectionTest
>
>
>>   OvmfPkg/Virtio10: define VIRITO_F_IOMMU_PLATFORM feature bit
>>   OvmfPkg/VirtioRngDxe: negotiate VIRITO_F_IOMMU_PLATFORM
>
> (7) I would have liked to include these two patches in my "initial
> push", but minimally the second patch needs fixes from you.
>
> After I'm done with point (3), please repost these patches *only*.
>
>
>>   OvmfPkg/VirtioBlkDxe: negotiate VIRITO_F_IOMMU_PLATFORM
>>   OvmfPkg/VirtioScsiDxe: negotiate VIRITO_F_IOMMU_PLATFORM
>>   OvmfPkg/VirtioNetDxe: negotiate VIRITO_F_IOMMU_PLATFORM
>
> (8) After these patches are fixed up, I suggest that you please post
> each one of them at the end of the matching driver series.
>
>
>> TODO:
>>  * add VirtioGpuDxe (i will take Laszlo's offer that he can help with
>>    this driver)
>
> OK, will do, thank you!
>
> In this work I'll also seek to follow the series layout proposed
> above.
>
>>  * I did minimal test on aarch64 - I was running into some Linux
>>    bootup issues with Fedora aarch64 iso. The issue does not appear
>>    to be releated to virtio changes. If anyone can help doing
>>    additional test with their aarch images that will be great !
>>    thanks
>
> I'll test on aarch64 too.
>
> Thanks!
> Laszlo
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
>



^ permalink raw reply	[flat|nested] 46+ messages in thread

end of thread, other threads:[~2017-08-25  8:55 UTC | newest]

Thread overview: 46+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-08-23 12:22 [PATCH v3 00/21] OvmfPkg/Virtio: introduce IOMMU-like member functions Brijesh Singh
2017-08-23 12:22 ` [PATCH v3 01/23] OvmfPkg: introduce IOMMU-like member functions to VIRTIO_DEVICE_PROTOCOL Brijesh Singh
2017-08-23 19:04   ` Laszlo Ersek
2017-08-23 12:22 ` [PATCH v3 02/23] OvmfPkg/Virtio10Dxe: implement IOMMU-like member functions Brijesh Singh
2017-08-23 19:13   ` Laszlo Ersek
2017-08-23 12:22 ` [PATCH v3 03/23] OvmfPkg/VirtioPciDeviceDxe: " Brijesh Singh
2017-08-23 19:16   ` Laszlo Ersek
2017-08-23 12:22 ` [PATCH v3 04/23] OvmfPkg/VirtioMmioDeviceLib: " Brijesh Singh
2017-08-23 19:26   ` Laszlo Ersek
2017-08-23 12:22 ` [PATCH v3 05/23] OvmfPkg/VirtioLib: add VirtioMapAllBytesInSharedBuffer() helper function Brijesh Singh
2017-08-23 19:45   ` Laszlo Ersek
2017-08-23 12:22 ` [PATCH v3 06/23] OvmfPkg/VirtioLib: take VirtIo instance in VirtioRingInit/VirtioRingUninit Brijesh Singh
2017-08-23 12:22 ` [PATCH v3 07/23] OvmfPkg/Virtio: take RingBaseShift in SetQueueAddress() Brijesh Singh
2017-08-23 20:41   ` Laszlo Ersek
2017-08-23 20:43     ` Laszlo Ersek
2017-08-23 20:50       ` Brijesh Singh
2017-08-23 12:22 ` [PATCH v3 08/23] OvmfPkg/Virtio10Dxe: add the RingBaseShift offset Brijesh Singh
2017-08-23 20:51   ` Laszlo Ersek
2017-08-23 12:22 ` [PATCH v3 09/23] OvmfPkg/VirtioLib: add function to map VRING Brijesh Singh
2017-08-23 20:10   ` Laszlo Ersek
2017-08-23 12:22 ` [PATCH v3 10/23] OvmfPkg/VirtioLib: alloc VRING buffer with AllocateSharedPages() Brijesh Singh
2017-08-23 21:18   ` Laszlo Ersek
2017-08-23 12:22 ` [PATCH v3 11/23] OvmfPkg/VirtioLib: change the parameter of VirtioAppendDesc() to UINT64 Brijesh Singh
2017-08-23 21:38   ` Laszlo Ersek
2017-08-23 12:22 ` [PATCH v3 12/23] OvmfPkg/VirtioRngDxe: map host address to device address Brijesh Singh
2017-08-23 22:54   ` Laszlo Ersek
2017-08-23 12:22 ` [PATCH v3 13/23] OvmfPkg/VirtioBlkDxe: " Brijesh Singh
2017-08-23 12:22 ` [PATCH v3 14/23] OvmfPkg/VirtioScsiDxe: " Brijesh Singh
2017-08-23 12:22 ` [PATCH v3 15/23] OvmfPkg/VirtioNetDxe: alloc Tx and Rx rings using AllocateSharedPage() Brijesh Singh
2017-08-23 12:22 ` [PATCH v3 16/23] OvmfPkg/VirtioNetDxe: alloc RxBuf using AllocateSharedPages() Brijesh Singh
2017-08-23 12:22 ` [PATCH v3 17/23] OvmfPkg/VirtioNetDxe: dynamically alloc transmit header Brijesh Singh
2017-08-23 12:22 ` [PATCH v3 18/23] OvmfPkg/VirtioNetDxe: map transmit buffer host address to device address Brijesh Singh
2017-08-23 12:22 ` [PATCH v3 19/23] OvmfPkg/Virtio10: define VIRITO_F_IOMMU_PLATFORM feature bit Brijesh Singh
2017-08-23 23:04   ` Laszlo Ersek
2017-08-23 12:22 ` [PATCH v3 20/23] OvmfPkg/VirtioRngDxe: negotiate VIRITO_F_IOMMU_PLATFORM Brijesh Singh
2017-08-23 23:21   ` Laszlo Ersek
2017-08-23 23:24     ` Brijesh Singh
2017-08-23 12:22 ` [PATCH v3 21/23] OvmfPkg/VirtioBlkDxe: " Brijesh Singh
2017-08-23 12:22 ` [PATCH v3 22/23] OvmfPkg/VirtioScsiDxe: " Brijesh Singh
2017-08-23 12:22 ` [PATCH v3 23/23] OvmfPkg/VirtioNetDxe: " Brijesh Singh
2017-08-24  0:26 ` [PATCH v3 00/21] OvmfPkg/Virtio: introduce IOMMU-like member functions Laszlo Ersek
2017-08-24  0:54   ` Brijesh Singh
2017-08-24  1:22     ` Laszlo Ersek
2017-08-24  2:06       ` Brijesh Singh
2017-08-24 10:07         ` Laszlo Ersek
2017-08-25  8:58   ` Laszlo Ersek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox