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.t...@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Hao Wu <hao.a...@intel.com>
---
 .../Bus/Pci/NvmExpressDxe/NvmExpressPassthru.c     | 55 +++++++++++++---------
 1 file changed, 34 insertions(+), 21 deletions(-)

diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressPassthru.c 
b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressPassthru.c
index ec7507e..6b29260 100644
--- a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressPassthru.c
+++ b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressPassthru.c
@@ -357,27 +357,28 @@ NvmExpressPassThru (
   IN     EFI_EVENT                                   Event OPTIONAL
   )
 {
-  NVME_CONTROLLER_PRIVATE_DATA  *Private;
-  EFI_STATUS                    Status;
-  EFI_PCI_IO_PROTOCOL           *PciIo;
-  NVME_SQ                       *Sq;
-  NVME_CQ                       *Cq;
-  UINT16                        QueueId;
-  UINT32                        Bytes;
-  UINT16                        Offset;
-  EFI_EVENT                     TimerEvent;
-  EFI_PCI_IO_PROTOCOL_OPERATION Flag;
-  EFI_PHYSICAL_ADDRESS          PhyAddr;
-  VOID                          *MapData;
-  VOID                          *MapMeta;
-  VOID                          *MapPrpList;
-  UINTN                         MapLength;
-  UINT64                        *Prp;
-  VOID                          *PrpListHost;
-  UINTN                         PrpListNo;
-  UINT32                        Data;
-  NVME_PASS_THRU_ASYNC_REQ      *AsyncRequest;
-  EFI_TPL                       OldTpl;
+  NVME_CONTROLLER_PRIVATE_DATA   *Private;
+  EFI_STATUS                     Status;
+  EFI_PCI_IO_PROTOCOL            *PciIo;
+  NVME_SQ                        *Sq;
+  NVME_CQ                        *Cq;
+  UINT16                         QueueId;
+  UINT32                         Bytes;
+  UINT16                         Offset;
+  EFI_EVENT                      TimerEvent;
+  EFI_PCI_IO_PROTOCOL_OPERATION  Flag;
+  EFI_PHYSICAL_ADDRESS           PhyAddr;
+  VOID                           *MapData;
+  VOID                           *MapMeta;
+  VOID                           *MapPrpList;
+  UINTN                          MapLength;
+  UINT64                         *Prp;
+  VOID                           *PrpListHost;
+  UINTN                          PrpListNo;
+  UINT32                         IoAlign;
+  UINT32                         Data;
+  NVME_PASS_THRU_ASYNC_REQ       *AsyncRequest;
+  EFI_TPL                        OldTpl;
 
   //
   // check the data fields in Packet parameter.
@@ -394,6 +395,18 @@ NvmExpressPassThru (
     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);
   PciIo       = Private->PciIo;
   MapData     = NULL;
-- 
1.9.5.msysgit.0

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to