MdeModulePkg NvmExpressDxe: Add buffer alignment check in PassThru API

According to the UEFI spec, the 'TransferBuffer' and 'MetadataBuffer' used
in a data transfer should be aligned on the boundary specified by the
IoAlign field in the EFI_NVM_EXPRESS_PASS_THRU_MODE structure.

This commit adds this check to follow the spec.

Cc: Feng Tian <feng.tian@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Hao Wu <hao.a.wu@intel.com>
Reviewed-by: Feng Tian <feng.tian@intel.com>
This commit is contained in:
Hao Wu 2016-08-22 13:55:52 +08:00
parent 114358eaa8
commit 3c52deafda

View File

@ -357,27 +357,28 @@ NvmExpressPassThru (
IN EFI_EVENT Event OPTIONAL IN EFI_EVENT Event OPTIONAL
) )
{ {
NVME_CONTROLLER_PRIVATE_DATA *Private; NVME_CONTROLLER_PRIVATE_DATA *Private;
EFI_STATUS Status; EFI_STATUS Status;
EFI_PCI_IO_PROTOCOL *PciIo; EFI_PCI_IO_PROTOCOL *PciIo;
NVME_SQ *Sq; NVME_SQ *Sq;
NVME_CQ *Cq; NVME_CQ *Cq;
UINT16 QueueId; UINT16 QueueId;
UINT32 Bytes; UINT32 Bytes;
UINT16 Offset; UINT16 Offset;
EFI_EVENT TimerEvent; EFI_EVENT TimerEvent;
EFI_PCI_IO_PROTOCOL_OPERATION Flag; EFI_PCI_IO_PROTOCOL_OPERATION Flag;
EFI_PHYSICAL_ADDRESS PhyAddr; EFI_PHYSICAL_ADDRESS PhyAddr;
VOID *MapData; VOID *MapData;
VOID *MapMeta; VOID *MapMeta;
VOID *MapPrpList; VOID *MapPrpList;
UINTN MapLength; UINTN MapLength;
UINT64 *Prp; UINT64 *Prp;
VOID *PrpListHost; VOID *PrpListHost;
UINTN PrpListNo; UINTN PrpListNo;
UINT32 Data; UINT32 IoAlign;
NVME_PASS_THRU_ASYNC_REQ *AsyncRequest; UINT32 Data;
EFI_TPL OldTpl; NVME_PASS_THRU_ASYNC_REQ *AsyncRequest;
EFI_TPL OldTpl;
// //
// check the data fields in Packet parameter. // check the data fields in Packet parameter.
@ -394,6 +395,18 @@ NvmExpressPassThru (
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
//
// Buffer alignment check for TransferBuffer & MetadataBuffer.
//
IoAlign = This->Mode->IoAlign;
if (IoAlign > 0 && (((UINTN) Packet->TransferBuffer & (IoAlign - 1)) != 0)) {
return EFI_INVALID_PARAMETER;
}
if (IoAlign > 0 && (((UINTN) Packet->MetadataBuffer & (IoAlign - 1)) != 0)) {
return EFI_INVALID_PARAMETER;
}
Private = NVME_CONTROLLER_PRIVATE_DATA_FROM_PASS_THRU (This); Private = NVME_CONTROLLER_PRIVATE_DATA_FROM_PASS_THRU (This);
PciIo = Private->PciIo; PciIo = Private->PciIo;
MapData = NULL; MapData = NULL;