In case device is constrained by IOMMU or guest is running under AMD SEV,
input/output buffers provided to device (DataBuffer and SenseData) needs
to be explicitly mapped to device by PciIo->Map().

To avoid the overhead of mapping/unmapping the DataBuffer and SenseData
to the device for every SCSI requst (and to simplify code), introduce a
single DMA communication buffer that will be mapped to device on
initialization. When a SCSI request needs to be sent to device, the
DataBuffer and SenseData will be copied from/to the DMA communication
buffer as required. This will be done by the following commits.

Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2567
Signed-off-by: Liran Alon <liran.a...@oracle.com>
---
 OvmfPkg/PvScsiDxe/PvScsi.c | 60 ++++++++++++++++++++++++++++++--------
 OvmfPkg/PvScsiDxe/PvScsi.h | 20 +++++++++++++
 2 files changed, 68 insertions(+), 12 deletions(-)

diff --git a/OvmfPkg/PvScsiDxe/PvScsi.c b/OvmfPkg/PvScsiDxe/PvScsi.c
index c7d367e83a2d..6e350bb2d6e0 100644
--- a/OvmfPkg/PvScsiDxe/PvScsi.c
+++ b/OvmfPkg/PvScsiDxe/PvScsi.c
@@ -677,6 +677,19 @@ PvScsiInit (
     goto RestorePciAttributes;
   }
 
+  //
+  // Allocate DMA communication buffer
+  //
+  Status = PvScsiAllocateSharedPages (
+             Dev,
+             EFI_SIZE_TO_PAGES (sizeof (*Dev->DmaBuf)),
+             (VOID **)&Dev->DmaBuf,
+             &Dev->DmaBufDmaDesc
+             );
+  if (EFI_ERROR (Status)) {
+    goto FreeRings;
+  }
+
   //
   // Populate the exported interface's attributes
   //
@@ -708,18 +721,7 @@ PvScsiInit (
 
   return EFI_SUCCESS;
 
-RestorePciAttributes:
-  PvScsiRestorePciAttributes (Dev);
-
-  return Status;
-}
-
-STATIC
-VOID
-PvScsiUninit (
-  IN OUT PVSCSI_DEV *Dev
-  )
-{
+FreeRings:
   //
   // Reset device to stop device usage of the rings.
   // This is required to safely free the rings.
@@ -728,6 +730,40 @@ PvScsiUninit (
 
   PvScsiFreeRings (Dev);
 
+RestorePciAttributes:
+  PvScsiRestorePciAttributes (Dev);
+
+  return Status;
+}
+
+STATIC
+VOID
+PvScsiUninit (
+  IN OUT PVSCSI_DEV *Dev
+  )
+{
+  //
+  // Reset device to:
+  // - Make device stop processing all requests.
+  // - Stop device usage of the rings.
+  //
+  // This is required to safely free the DMA communication buffer
+  // and the rings.
+  //
+  PvScsiResetAdapter (Dev);
+
+  //
+  // Free DMA communication buffer
+  //
+  PvScsiFreeSharedPages (
+    Dev,
+    EFI_SIZE_TO_PAGES (sizeof (*Dev->DmaBuf)),
+    Dev->DmaBuf,
+    &Dev->DmaBufDmaDesc
+    );
+
+  PvScsiFreeRings (Dev);
+
   PvScsiRestorePciAttributes (Dev);
 }
 
diff --git a/OvmfPkg/PvScsiDxe/PvScsi.h b/OvmfPkg/PvScsiDxe/PvScsi.h
index 6d23b6e1eccf..fff12146dc75 100644
--- a/OvmfPkg/PvScsiDxe/PvScsi.h
+++ b/OvmfPkg/PvScsiDxe/PvScsi.h
@@ -31,6 +31,21 @@ typedef struct {
   PVSCSI_DMA_DESC      RingCmpsDmaDesc;
 } PVSCSI_RING_DESC;
 
+typedef struct {
+  //
+  // As EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET.SenseDataLength is defined
+  // as UINT8, defining here SenseData size to MAX_UINT8 will guarantee it
+  // cannot overflow when passed to device.
+  //
+  UINT8     SenseData[MAX_UINT8];
+  //
+  // This size of the data is arbitrarily chosen.
+  // It seems to be sufficient for all I/O requests sent through
+  // EFI_SCSI_PASS_THRU_PROTOCOL.PassThru() for common boot scenarios.
+  //
+  UINT8     Data[0x2000];
+} PVSCSI_DMA_BUFFER;
+
 #define PVSCSI_SIG SIGNATURE_32 ('P', 'S', 'C', 'S')
 
 typedef struct {
@@ -38,6 +53,8 @@ typedef struct {
   EFI_PCI_IO_PROTOCOL             *PciIo;
   UINT64                          OriginalPciAttributes;
   PVSCSI_RING_DESC                RingDesc;
+  PVSCSI_DMA_BUFFER               *DmaBuf;
+  PVSCSI_DMA_DESC                 DmaBufDmaDesc;
   UINT8                           MaxTarget;
   UINT8                           MaxLun;
   EFI_EXT_SCSI_PASS_THRU_PROTOCOL PassThru;
@@ -47,4 +64,7 @@ typedef struct {
 #define PVSCSI_FROM_PASS_THRU(PassThruPointer) \
   CR (PassThruPointer, PVSCSI_DEV, PassThru, PVSCSI_SIG)
 
+#define PVSCSI_DMA_BUF_DEV_ADDR(Dev, MemberName) \
+  (Dev->DmaBufDmaDesc.DeviceAddress + OFFSET_OF(PVSCSI_DMA_BUFFER, MemberName))
+
 #endif // __PVSCSI_DXE_H_
-- 
2.20.1


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#56547): https://edk2.groups.io/g/devel/message/56547
Mute This Topic: https://groups.io/mt/72617148/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to