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
next prev 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