> -----Original Message----- > From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of > Wu, Hao A > Sent: Thursday, June 27, 2019 9:08 AM > To: Albecki, Mateusz; devel@edk2.groups.io > Subject: Re: [edk2-devel] [PATCH v2] MdeModulePkg/UfsPassThruDxe: Fix > unaligned data transfer handling > > > -----Original Message----- > > From: Albecki, Mateusz > > Sent: Wednesday, June 26, 2019 5:55 PM > > To: Wu, Hao A; devel@edk2.groups.io > > Subject: RE: [PATCH v2] MdeModulePkg/UfsPassThruDxe: Fix unaligned > data > > transfer handling > > > > Hi, > > > > No concerns from my side. I just didn't think ZeroMem would be useful > > there since buffer doesn't contain any data from device at that point so I > > didn't add it. > > > My concern is that the data in 'Packet->OutDataBuffer' (from caller) may > contain information. > > Caller can clean up the content in 'Packet->OutDataBuffer' after the > PassThru call but cannot control the auxiliary buffer within UFS driver. > > Best Regards, > Hao Wu > > > > > > Thanks, > > Mateusz > > > > > -----Original Message----- > > > From: Wu, Hao A > > > Sent: Wednesday, June 26, 2019 2:19 AM > > > To: Albecki, Mateusz <mateusz.albe...@intel.com>; > devel@edk2.groups.io > > > Subject: RE: [PATCH v2] MdeModulePkg/UfsPassThruDxe: Fix unaligned > > data > > > transfer handling > > > > > > > -----Original Message----- > > > > From: Albecki, Mateusz > > > > Sent: Tuesday, June 25, 2019 5:44 PM > > > > To: devel@edk2.groups.io > > > > Cc: Albecki, Mateusz; Wu, Hao A > > > > Subject: [PATCH v2] MdeModulePkg/UfsPassThruDxe: Fix unaligned > data > > > > transfer handling > > > > > > > > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1341 > > > > > > > > Since UFS specification requirs the data buffer specified in PRDT to > > > > be DWORD aligned in size we had a code in UfsInitUtpPrdt that aligned > > > > the data buffer by rounding down the buffer size to DWORD boundary. > > > > This meant that for SCSI commands that wanted to perform unaligned > > > > data transfer(such as SENSE command) we specified to small buffer for > > > > the data to fit and transfer was aborted. This change introduces code > > > > that allocates auxiliary DWORD aligned data buffer for unaligned > > > > transfer. Device transfers data to aligned buffer and when data > > > > transfer is over driver copies data from aligned buffer to data buffer > > > > passed by user. > > > > > > > > Cc: Hao A Wu <hao.a...@intel.com> > > > > Signed-off-by: Mateusz Albecki <mateusz.albe...@intel.com> > > > > --- > > > > MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.h | 2 + > > > > .../Bus/Ufs/UfsPassThruDxe/UfsPassThruHci.c | 198 > > > +++++++++++++++- > > > > ----- > > > > 2 files changed, 146 insertions(+), 54 deletions(-) > > > > > > > > diff --git a/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.h > > > > b/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.h > > > > index 6c98b3a76a..9b68db5ffe 100644 > > > > --- a/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.h > > > > +++ b/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.h > > > > @@ -92,6 +92,8 @@ typedef struct { > > > > UINT32 CmdDescSize; > > > > VOID *CmdDescHost; > > > > VOID *CmdDescMapping; > > > > + VOID *AlignedDataBuf; > > > > + UINTN AlignedDataBufSize; > > > > VOID *DataBufMapping; > > > > > > > > EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet; > > > > diff --git a/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThruHci.c > > > > b/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThruHci.c > > > > index 4b93821f38..4f41183504 100644 > > > > --- a/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThruHci.c > > > > +++ b/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThruHci.c > > > > @@ -394,17 +394,13 @@ UfsInitUtpPrdt ( > > > > UINT8 *Remaining; > > > > UINTN PrdtNumber; > > > > > > > > - if ((BufferSize & (BIT0 | BIT1)) != 0) { > > > > - BufferSize &= ~(BIT0 | BIT1); > > > > - DEBUG ((DEBUG_WARN, "UfsInitUtpPrdt: The BufferSize [%d] is not > > > > dword-aligned!\n", BufferSize)); > > > > - } > > > > + ASSERT (((UINTN)Buffer & (BIT0 | BIT1)) == 0); ASSERT ((BufferSize > > > > + & (BIT1 | BIT0)) == 0); > > > > > > > > if (BufferSize == 0) { > > > > return EFI_SUCCESS; > > > > } > > > > > > > > - ASSERT (((UINTN)Buffer & (BIT0 | BIT1)) == 0); > > > > - > > > > RemainingLen = BufferSize; > > > > Remaining = Buffer; > > > > PrdtNumber = (UINTN)DivU64x32 ((UINT64)BufferSize + > > > > UFS_MAX_DATA_LEN_PER_PRD - 1, UFS_MAX_DATA_LEN_PER_PRD); > > > @@ -1317,6 > > > > +1313,139 @@ Exit: > > > > return Status; > > > > } > > > > > > > > +/** > > > > + Cleanup data buffers after data transfer. This function > > > > + also takes care to copy all data to user memory pool for > > > > + unaligned data transfers. > > > > + > > > > + @param[in] Private Pointer to the UFS_PASS_THRU_PRIVATE_DATA > > > > + @param[in] TransReq Pointer to the transfer request **/ VOID > > > > +UfsReconcileDataTransferBuffer ( > > > > + IN UFS_PASS_THRU_PRIVATE_DATA *Private, > > > > + IN UFS_PASS_THRU_TRANS_REQ *TransReq > > > > + ) > > > > +{ > > > > + if (TransReq->DataBufMapping != NULL) { > > > > + Private->UfsHostController->Unmap ( > > > > + Private->UfsHostController, > > > > + TransReq->DataBufMapping > > > > + ); > > > > + } > > > > + > > > > + // > > > > + // Check if unaligned transfer was performed. If it was and we read > > > > + // data from device copy memory to user data buffers before cleanup. > > > > + // The assumption is if auxiliary aligned data buffer is not NULL > > > > + then // unaligned transfer has been performed. > > > > + // > > > > + if (TransReq->AlignedDataBuf != NULL) { > > > > + if (TransReq->Packet->DataDirection == > > > > EFI_EXT_SCSI_DATA_DIRECTION_READ) { > > > > + CopyMem (TransReq->Packet->InDataBuffer, TransReq- > > > > >AlignedDataBuf, TransReq->Packet->InTransferLength); > > > > + } > > > > + // > > > > + // Wipe out the transfer buffer in case it contains sensitive data. > > > > + // > > > > + ZeroMem (TransReq->AlignedDataBuf, TransReq- > > >AlignedDataBufSize); > > > > + FreeAlignedPages (TransReq->AlignedDataBuf, EFI_SIZE_TO_PAGES > > > > (TransReq->AlignedDataBufSize)); > > > > + TransReq->AlignedDataBuf = NULL; > > > > + } > > > > +} > > > > + > > > > +/** > > > > + Prepare data buffer for transfer > > > > + > > > > + @param[in] Private Pointer to the > > UFS_PASS_THRU_PRIVATE_DATA > > > > + @param[in, out] TransReq Pointer to the transfer request > > > > + > > > > + @retval EFI_DEVICE_ERROR Failed to prepare buffer for transfer > > > > + @retval EFI_SUCCESS Buffer ready for transfer > > > > +**/ > > > > +EFI_STATUS > > > > +UfsPrepareDataTransferBuffer ( > > > > + IN UFS_PASS_THRU_PRIVATE_DATA *Private, > > > > + IN OUT UFS_PASS_THRU_TRANS_REQ *TransReq > > > > + ) > > > > +{ > > > > + EFI_STATUS Status; > > > > + VOID *DataBuf; > > > > + UINT32 DataLen; > > > > + UINTN MapLength; > > > > + EFI_PHYSICAL_ADDRESS DataBufPhyAddr; > > > > + EDKII_UFS_HOST_CONTROLLER_OPERATION Flag; > > > > + UTP_TR_PRD *PrdtBase; > > > > + > > > > + DataBufPhyAddr = (EFI_PHYSICAL_ADDRESS) NULL;
Changed the above line from: DataBufPhyAddr = (EFI_PHYSICAL_ADDRESS) NULL; to: DataBufPhyAddr = 0; to address a build failure for GCC. With this change and my previous 'Reviewed-by' tag, pushed via commit a37e18f6fc. Best Regards, Hao Wu > > > > + DataBuf = NULL; > > > > + > > > > + // > > > > + // For unaligned data transfers we allocate auxiliary DWORD aligned > > > > memory pool. > > > > + // When command is finished auxiliary memory pool is copied into > > > > + actual > > > > user memory. > > > > + // This is requiered to assure data transfer safety(DWORD alignment > > > > required by UFS spec.) > > > > + // > > > > + if (TransReq->Packet->DataDirection == > > > > EFI_EXT_SCSI_DATA_DIRECTION_READ) { > > > > + if (((UINTN)TransReq->Packet->InDataBuffer % 4 != 0) || > > > > + (TransReq- > > > > >Packet->InTransferLength % 4 != 0)) { > > > > + DataLen = TransReq->Packet->InTransferLength + (4 - (TransReq- > > > > >Packet->InTransferLength % 4)); > > > > + DataBuf = AllocateAlignedPages (EFI_SIZE_TO_PAGES (DataLen), 4); > > > > + if (DataBuf == NULL) { > > > > + return EFI_DEVICE_ERROR; > > > > + } > > > > + ZeroMem (DataBuf, DataLen); > > > > + TransReq->AlignedDataBuf = DataBuf; > > > > + TransReq->AlignedDataBufSize = DataLen; > > > > + } else { > > > > + DataLen = TransReq->Packet->InTransferLength; > > > > + DataBuf = TransReq->Packet->InDataBuffer; > > > > + } > > > > + Flag = EdkiiUfsHcOperationBusMasterWrite; > > > > + } else { > > > > + if (((UINTN)TransReq->Packet->OutDataBuffer % 4 != 0) || > > > > + (TransReq- > > > > >Packet->OutTransferLength % 4 != 0)) { > > > > + DataLen = TransReq->Packet->OutTransferLength + (4 - (TransReq- > > > > >Packet->OutTransferLength % 4)); > > > > + DataBuf = AllocateAlignedPages (EFI_SIZE_TO_PAGES (DataLen), 4); > > > > + if (DataBuf == NULL) { > > > > + return EFI_DEVICE_ERROR; > > > > + } > > > > + CopyMem (DataBuf, TransReq->Packet->OutDataBuffer, TransReq- > > > > >Packet->OutTransferLength); > > > > + TransReq->AlignedDataBuf = DataBuf; > > > > + TransReq->AlignedDataBufSize = DataLen; > > > > + } else { > > > > + DataLen = TransReq->Packet->OutTransferLength; > > > > + DataBuf = TransReq->Packet->OutDataBuffer; > > > > + } > > > > + Flag = EdkiiUfsHcOperationBusMasterRead; > > > > + } > > > > + > > > > + if (DataLen != 0) { > > > > + MapLength = DataLen; > > > > + Status = Private->UfsHostController->Map ( > > > > + > > > > Private->UfsHostController, > > > > + Flag, > > > > + DataBuf, > > > > + &MapLength, > > > > + &DataBufPhyAddr, > > > > + &TransReq->DataBufMapping > > > > + ); > > > > + > > > > + if (EFI_ERROR (Status) || (DataLen != MapLength)) { > > > > + if (TransReq->AlignedDataBuf != NULL) { > > > > > > > > > Hello, > > > > > > I will also add > > > > > > ZeroMem (TransReq->AlignedDataBuf, TransReq->AlignedDataBufSize); > > > > > > here before freeing the auxiliary buffer when pushing the patch. > > > Please help to raise if there is any concern. > > > > > > With that, > > > Reviewed-by: Hao A Wu <hao.a...@intel.com> > > > > > > Best Regards, > > > Hao Wu > > > > > > > > > > + FreeAlignedPages (TransReq->AlignedDataBuf, > EFI_SIZE_TO_PAGES > > > > (TransReq->AlignedDataBufSize)); > > > > + TransReq->AlignedDataBuf = NULL; > > > > + } > > > > + return EFI_DEVICE_ERROR; > > > > + } > > > > + } > > > > + > > > > + // > > > > + // Fill PRDT table of Command UPIU for executed SCSI cmd. > > > > + // > > > > + PrdtBase = (UTP_TR_PRD*)((UINT8*)TransReq->CmdDescHost + > > > > ROUNDUP8 (sizeof (UTP_COMMAND_UPIU)) + ROUNDUP8 (sizeof > > > > (UTP_RESPONSE_UPIU))); > > > > + ASSERT (PrdtBase != NULL); > > > > + UfsInitUtpPrdt (PrdtBase, (VOID*)(UINTN)DataBufPhyAddr, > DataLen); > > > > + > > > > + return EFI_SUCCESS; > > > > +} > > > > + > > > > /** > > > > Sends a UFS-supported SCSI Request Packet to a UFS device that is > > > > attached to the UFS host controller. > > > > > > > > @@ -1353,24 +1482,19 @@ UfsExecScsiCmds ( > > > > UTP_RESPONSE_UPIU *Response; > > > > UINT16 SenseDataLen; > > > > UINT32 ResTranCount; > > > > - VOID *DataBuf; > > > > - EFI_PHYSICAL_ADDRESS DataBufPhyAddr; > > > > - UINT32 DataLen; > > > > - UINTN MapLength; > > > > - EDKII_UFS_HOST_CONTROLLER_PROTOCOL *UfsHc; > > > > - EDKII_UFS_HOST_CONTROLLER_OPERATION Flag; > > > > - UTP_TR_PRD *PrdtBase; > > > > EFI_TPL OldTpl; > > > > UFS_PASS_THRU_TRANS_REQ *TransReq; > > > > + EDKII_UFS_HOST_CONTROLLER_PROTOCOL *UfsHc; > > > > > > > > - TransReq = AllocateZeroPool (sizeof > > (UFS_PASS_THRU_TRANS_REQ)); > > > > + TransReq = AllocateZeroPool (sizeof > (UFS_PASS_THRU_TRANS_REQ)); > > > > if (TransReq == NULL) { > > > > return EFI_OUT_OF_RESOURCES; > > > > } > > > > > > > > TransReq->Signature = UFS_PASS_THRU_TRANS_REQ_SIG; > > > > TransReq->TimeoutRemain = Packet->Timeout; > > > > - DataBufPhyAddr = 0; > > > > + TransReq->Packet = Packet; > > > > + > > > > UfsHc = Private->UfsHostController; > > > > // > > > > // Find out which slot of transfer request list is available. > > > > @@ -1399,44 +1523,16 @@ UfsExecScsiCmds ( > > > > > > > > TransReq->CmdDescSize = TransReq->Trd->PrdtO * sizeof (UINT32) + > > > > TransReq->Trd->PrdtL * sizeof (UTP_TR_PRD); > > > > > > > > - if (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ) > { > > > > - DataBuf = Packet->InDataBuffer; > > > > - DataLen = Packet->InTransferLength; > > > > - Flag = EdkiiUfsHcOperationBusMasterWrite; > > > > - } else { > > > > - DataBuf = Packet->OutDataBuffer; > > > > - DataLen = Packet->OutTransferLength; > > > > - Flag = EdkiiUfsHcOperationBusMasterRead; > > > > - } > > > > - > > > > - if (DataLen != 0) { > > > > - MapLength = DataLen; > > > > - Status = UfsHc->Map ( > > > > - UfsHc, > > > > - Flag, > > > > - DataBuf, > > > > - &MapLength, > > > > - &DataBufPhyAddr, > > > > - &TransReq->DataBufMapping > > > > - ); > > > > - > > > > - if (EFI_ERROR (Status) || (DataLen != MapLength)) { > > > > - goto Exit1; > > > > - } > > > > + Status = UfsPrepareDataTransferBuffer (Private, TransReq); if > > > > + (EFI_ERROR (Status)) { > > > > + goto Exit1; > > > > } > > > > - // > > > > - // Fill PRDT table of Command UPIU for executed SCSI cmd. > > > > - // > > > > - PrdtBase = (UTP_TR_PRD*)((UINT8*)TransReq->CmdDescHost + > > > > ROUNDUP8 (sizeof (UTP_COMMAND_UPIU)) + ROUNDUP8 (sizeof > > > > (UTP_RESPONSE_UPIU))); > > > > - ASSERT (PrdtBase != NULL); > > > > - UfsInitUtpPrdt (PrdtBase, (VOID*)(UINTN)DataBufPhyAddr, DataLen); > > > > > > > > // > > > > // Insert the async SCSI cmd to the Async I/O list > > > > // > > > > if (Event != NULL) { > > > > OldTpl = gBS->RaiseTPL (TPL_NOTIFY); > > > > - TransReq->Packet = Packet; > > > > TransReq->CallerEvent = Event; > > > > InsertTailList (&Private->Queue, &TransReq->TransferList); > > > > gBS->RestoreTPL (OldTpl); > > > > @@ -1515,9 +1611,7 @@ Exit: > > > > > > > > UfsStopExecCmd (Private, TransReq->Slot); > > > > > > > > - if (TransReq->DataBufMapping != NULL) { > > > > - UfsHc->Unmap (UfsHc, TransReq->DataBufMapping); > > > > - } > > > > + UfsReconcileDataTransferBuffer (Private, TransReq); > > > > > > > > Exit1: > > > > if (TransReq->CmdDescMapping != NULL) { @@ -1532,7 +1626,6 @@ > > > > Exit1: > > > > return Status; > > > > } > > > > > > > > - > > > > /** > > > > Sent UIC DME_LINKSTARTUP command to start the link startup > > procedure. > > > > > > > > @@ -2100,7 +2193,6 @@ UfsControllerStop ( > > > > return EFI_SUCCESS; > > > > } > > > > > > > > - > > > > /** > > > > Internal helper function which will signal the caller event and > > > > clean up > > > > resources. > > > > @@ -2132,9 +2224,7 @@ SignalCallerEvent ( > > > > > > > > UfsStopExecCmd (Private, TransReq->Slot); > > > > > > > > - if (TransReq->DataBufMapping != NULL) { > > > > - UfsHc->Unmap (UfsHc, TransReq->DataBufMapping); > > > > - } > > > > + UfsReconcileDataTransferBuffer (Private, TransReq); > > > > > > > > if (TransReq->CmdDescMapping != NULL) { > > > > UfsHc->Unmap (UfsHc, TransReq->CmdDescMapping); > > > > -- > > > > 2.14.1.windows.1 > > > -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#43051): https://edk2.groups.io/g/devel/message/43051 Mute This Topic: https://groups.io/mt/32201696/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-