public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: Nikita Leshenko <nikita.leshchenko@oracle.com>
To: edk2-devel@lists.01.org
Cc: liran.alon@oracle.com, Nikita Leshenko <nikita.leshchenko@oracle.com>
Subject: [PATCH 14/14] OvmfPkg/MptScsiDxe: Support packets with pointers above 4G
Date: Thu, 31 Jan 2019 12:07:24 +0200	[thread overview]
Message-ID: <20190131100724.20907-15-nikita.leshchenko@oracle.com> (raw)
In-Reply-To: <20190131100724.20907-1-nikita.leshchenko@oracle.com>

Users of this device might pass data pointers which are above 4G, in which case
we can't pass the pointers directly to the controller because the descriptors
contain 32-bit pointers.

Instead of failing the request, use below-4G memory to support the request.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Nikita Leshenko <nikita.leshchenko@oracle.com>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Reviewed-by: Aaron Young <aaron.young@oracle.com>
Reviewed-by: Liran Alon <liran.alon@oracle.com>
---
 OvmfPkg/MptScsiDxe/MptScsi.c | 50 +++++++++++++++++++++++++++++++-----
 1 file changed, 44 insertions(+), 6 deletions(-)

diff --git a/OvmfPkg/MptScsiDxe/MptScsi.c b/OvmfPkg/MptScsiDxe/MptScsi.c
index 0b888a1c56..9e803735d2 100644
--- a/OvmfPkg/MptScsiDxe/MptScsi.c
+++ b/OvmfPkg/MptScsiDxe/MptScsi.c
@@ -160,6 +160,9 @@ typedef struct {
   UINT8                           MaxTarget;
   MPT_SCSI_IO_ERROR_REPLY         IoErrorReply;
   MPT_SCSI_REQUEST_WITH_SG        IoRequest;
+
+  UINT8                           SenseBuffer[MAX_UINT8];
+  UINT8                           DataBuffer[0x2000];
 } MPT_SCSI_DEV;
 
 #define MPT_SCSI_FROM_PASS_THRU(PassThruPtr) \
@@ -323,6 +326,18 @@ MptScsiPopulateRequest (
     return EFI_INVALID_PARAMETER;
   }
 
+  // If the buffers are above 4G, make sure that we can buffer that data
+  if ((UINTN) Packet->InDataBuffer > MAX_UINT32 &&
+      Packet->InTransferLength > sizeof (Dev->DataBuffer)) {
+    Packet->InTransferLength = sizeof (Dev->DataBuffer);
+    return EFI_BAD_BUFFER_SIZE;
+  }
+  if ((UINTN) Packet->OutDataBuffer > MAX_UINT32 &&
+      Packet->OutTransferLength > sizeof (Dev->DataBuffer)) {
+    Packet->OutTransferLength = sizeof (Dev->DataBuffer);
+    return EFI_BAD_BUFFER_SIZE;
+  }
+
   if (Packet->InTransferLength > MPT_SG_ENTRY_SIMPLE_MAX_LENGTH) {
     Packet->InTransferLength = MPT_SG_ENTRY_SIMPLE_MAX_LENGTH;
     return EFI_BAD_BUFFER_SIZE;
@@ -343,8 +358,14 @@ MptScsiPopulateRequest (
   CopyMem (Request->Header.CDB, Packet->Cdb, Packet->CdbLength);
 
   Request->Header.SenseBufferLength = Packet->SenseDataLength;
-  ASSERT ((UINTN) Packet->SenseData <= MAX_UINT32);
-  Request->Header.SenseBufferLowAddress = (UINT32)(UINTN) Packet->SenseData;
+  // If sense is above 4G, we can't pass it directly to controller
+  if ((UINTN) Packet->SenseData > MAX_UINT32) {
+    // Zero because the controller doesn't report the resulting sense data size
+    ZeroMem (&Dev->SenseBuffer, Packet->SenseDataLength);
+    Request->Header.SenseBufferLowAddress = (UINT32)(UINTN) &Dev->SenseBuffer;
+  } else {
+    Request->Header.SenseBufferLowAddress = (UINT32)(UINTN) Packet->SenseData;
+  }
 
   Request->Sg.EndOfList = 1;
   Request->Sg.EndOfBuffer = 1;
@@ -356,15 +377,24 @@ MptScsiPopulateRequest (
   case EFI_EXT_SCSI_DATA_DIRECTION_READ:
     Request->Header.DataLength = Packet->InTransferLength;
     Request->Sg.Length = Packet->InTransferLength;
-    ASSERT ((UINTN) Packet->InDataBuffer <= MAX_UINT32);
-    Request->Sg.DataBufferAddress = (UINT32)(UINTN) Packet->InDataBuffer;
+    // If buffer is above 4G, we can't pass it directly to controller
+    if ((UINTN) Packet->InDataBuffer > MAX_UINT32) {
+      Request->Sg.DataBufferAddress = (UINT32)(UINTN) &Dev->DataBuffer;
+    } else {
+      Request->Sg.DataBufferAddress = (UINT32)(UINTN) Packet->InDataBuffer;
+    }
     Request->Header.Control = MPT_SCSIIO_REQUEST_CONTROL_TXDIR_READ;
     break;
   case EFI_EXT_SCSI_DATA_DIRECTION_WRITE:
     Request->Header.DataLength = Packet->OutTransferLength;
     Request->Sg.Length = Packet->OutTransferLength;
-    ASSERT ((UINTN) Packet->OutDataBuffer <= MAX_UINT32);
-    Request->Sg.DataBufferAddress = (UINT32)(UINTN) Packet->OutDataBuffer;
+    // If buffer is above 4G, we can't pass it directly to controller
+    if ((UINTN) Packet->OutDataBuffer > MAX_UINT32) {
+      CopyMem (&Dev->DataBuffer, Packet->OutDataBuffer, Packet->OutTransferLength);
+      Request->Sg.DataBufferAddress = (UINT32)(UINTN) &Dev->DataBuffer;
+    } else {
+      Request->Sg.DataBufferAddress = (UINT32)(UINTN) Packet->OutDataBuffer;
+    }
     Request->Header.Control = MPT_SCSIIO_REQUEST_CONTROL_TXDIR_WRITE;
     Request->Sg.BufferContainsData = 1;
     break;
@@ -451,6 +481,14 @@ MptScsiHandleReply (
   OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET    *Packet
   )
 {
+  if ((UINTN) Packet->SenseData > MAX_UINT32) {
+    CopyMem (Packet->SenseData, &Dev->SenseBuffer, Packet->SenseDataLength);
+  }
+  if ((UINTN) Packet->InDataBuffer > MAX_UINT32 &&
+      Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ) {
+    CopyMem (Packet->InDataBuffer, &Dev->DataBuffer, Packet->InTransferLength);
+  }
+
   if (Reply == Request->Header.MessageContext) {
     // Everything is good
     Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OK;
-- 
2.20.1



  parent reply	other threads:[~2019-01-31 10:08 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-31 10:07 OvmfPkg: Support booting from Fusion-MPT SCSI controllers Nikita Leshenko
2019-01-31 10:07 ` [PATCH 01/14] OvmfPkg/MptScsiDxe: Create empty driver Nikita Leshenko
2019-02-01  2:16   ` Bi, Dandan
2019-02-01 10:07     ` Laszlo Ersek
2019-02-01  9:57   ` Laszlo Ersek
2019-01-31 10:07 ` [PATCH 02/14] OvmfPkg/MptScsiDxe: Install DriverBinding Protocol Nikita Leshenko
2019-02-01 10:21   ` Laszlo Ersek
2019-01-31 10:07 ` [PATCH 03/14] OvmfPkg/MptScsiDxe: Report name of driver Nikita Leshenko
2019-02-01 10:25   ` Laszlo Ersek
2019-02-01 15:13     ` Carsey, Jaben
2019-01-31 10:07 ` [PATCH 04/14] OvmfPkg/MptScsiDxe: Probe PCI devices and look for MptScsi Nikita Leshenko
2019-02-01 11:48   ` Laszlo Ersek
2019-01-31 10:07 ` [PATCH 05/14] OvmfPkg/MptScsiDxe: Install stubbed EXT_SCSI_PASS_THRU Nikita Leshenko
2019-01-31 10:07 ` [PATCH 06/14] OvmfPkg/MptScsiDxe: Report one Target and one LUN Nikita Leshenko
2019-01-31 10:07 ` [PATCH 07/14] OvmfPkg/MptScsiDxe: Build DevicePath for discovered devices Nikita Leshenko
2019-01-31 10:07 ` [PATCH 08/14] OvmfPkg/MptScsiDxe: Implement GetTargetLun Nikita Leshenko
2019-01-31 10:07 ` [PATCH 09/14] OvmfPkg/MptScsiDxe: Open PciIo protocol for later use Nikita Leshenko
2019-01-31 10:07 ` [PATCH 10/14] OvmfPkg/MptScsiDxe: Set and restore PCI attributes Nikita Leshenko
2019-01-31 10:07 ` [PATCH 11/14] OvmfPkg/MptScsiDxe: Initialize hardware Nikita Leshenko
2019-02-01 12:14   ` Laszlo Ersek
2019-01-31 10:07 ` [PATCH 12/14] OvmfPkg/MptScsiDxe: Implement the PassThru method Nikita Leshenko
2019-02-01 12:55   ` Laszlo Ersek
2019-01-31 10:07 ` [PATCH 13/14] OvmfPkg/MptScsiDxe: Report multiple targets Nikita Leshenko
2019-01-31 10:07 ` Nikita Leshenko [this message]
2019-02-01  9:48 ` OvmfPkg: Support booting from Fusion-MPT SCSI controllers Laszlo Ersek
2019-02-01 10:43 ` Laszlo Ersek

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=20190131100724.20907-15-nikita.leshchenko@oracle.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

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

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