From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=141.146.126.79; helo=aserp2130.oracle.com; envelope-from=nikita.leshchenko@oracle.com; receiver=edk2-devel@lists.01.org Received: from aserp2130.oracle.com (aserp2130.oracle.com [141.146.126.79]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 17B0321CAD998 for ; Thu, 31 Jan 2019 02:08:23 -0800 (PST) Received: from pps.filterd (aserp2130.oracle.com [127.0.0.1]) by aserp2130.oracle.com (8.16.0.22/8.16.0.22) with SMTP id x0VA4X2v154186 for ; Thu, 31 Jan 2019 10:08:22 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=corp-2018-07-02; bh=LZKTTirvmR23G6Yrn1ncTlUhUBKAWhM8I6Ms8mGu9mE=; b=SC+AUt+N9TkpSUySs05XGJYCglc37bLKIeaD0XmzAdVDAsXgs2graEDJDdEHhmHqs57X OT4BeTM1rhWBJpG2Hw+N3rOFbcpjtaNHZKouwgDnDgnK6IDdwxedHh57EuX5mTpD5Q9e tATfD768Td2cHESCpSPDmCirninrNIlqi7lEvWQhh5sJAhziKshn6Ss6sGw0dAvZhMSh qojNInSjpHnBngHznGRqHM5NVLiozNvl1i4XA4IfySSAmF6aDfKaMg7HWP64eKQ2puLe N9TuXOil+KWzrq1cKd0AJ5hLH7AfO6NqN1pk8x9tmmhNcLawqCezdZHbPZbkf0MHO1gI TQ== Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by aserp2130.oracle.com with ESMTP id 2q8d2efvb8-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Thu, 31 Jan 2019 10:08:22 +0000 Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0022.oracle.com (8.14.4/8.14.4) with ESMTP id x0VA8Lqo009455 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Thu, 31 Jan 2019 10:08:21 GMT Received: from abhmp0013.oracle.com (abhmp0013.oracle.com [141.146.116.19]) by userv0122.oracle.com (8.14.4/8.14.4) with ESMTP id x0VA8LFD019920 for ; Thu, 31 Jan 2019 10:08:21 GMT Received: from spark.ravello.local (/213.57.127.2) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Thu, 31 Jan 2019 02:08:20 -0800 From: Nikita Leshenko To: edk2-devel@lists.01.org Cc: liran.alon@oracle.com, Nikita Leshenko Date: Thu, 31 Jan 2019 12:07:24 +0200 Message-Id: <20190131100724.20907-15-nikita.leshchenko@oracle.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190131100724.20907-1-nikita.leshchenko@oracle.com> References: <20190131100724.20907-1-nikita.leshchenko@oracle.com> MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9152 signatures=668682 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=1 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=781 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1901310080 Subject: [PATCH 14/14] OvmfPkg/MptScsiDxe: Support packets with pointers above 4G X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 31 Jan 2019 10:08:23 -0000 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Konrad Rzeszutek Wilk Reviewed-by: Aaron Young Reviewed-by: Liran Alon --- 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