return Size;\r
}\r
\r
+/**\r
+ This function check if the memory region is in GCD MMIO region.\r
+\r
+ @param Addr The memory region start address to be checked.\r
+ @param Size The memory region length to be checked.\r
+\r
+ @retval TRUE This memory region is in GCD MMIO region.\r
+ @retval FALSE This memory region is not in GCD MMIO region.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+OpalIsValidMmioSpace (\r
+ IN EFI_PHYSICAL_ADDRESS Addr,\r
+ IN UINTN Size\r
+ )\r
+{\r
+ UINTN Index;\r
+ EFI_GCD_MEMORY_SPACE_DESCRIPTOR *Desc;\r
+\r
+ for (Index = 0; Index < mNumberOfDescriptors; Index ++) {\r
+ Desc = &mGcdMemSpace[Index];\r
+ if ((Desc->GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) && (Addr >= Desc->BaseAddress) && ((Addr + Size) <= (Desc->BaseAddress + Desc->Length))) {\r
+ return TRUE;\r
+ }\r
+ }\r
+\r
+ return FALSE;\r
+}\r
/**\r
Get AHCI mode base address registers' Value.\r
\r
//\r
// Check if the AHCI Bar region is in SMRAM to avoid malicious attack by modifying MMIO Bar to point to SMRAM.\r
//\r
- if (!SmmIsBufferOutsideSmmValid ((EFI_PHYSICAL_ADDRESS)mAhciBar, Size)) {\r
+ if (!OpalIsValidMmioSpace ((EFI_PHYSICAL_ADDRESS)mAhciBar, Size)) {\r
return EFI_UNSUPPORTED;\r
}\r
\r
// NVME\r
NVME_CONTEXT mNvmeContext;\r
\r
+EFI_GCD_MEMORY_SPACE_DESCRIPTOR *mGcdMemSpace = NULL;\r
+UINTN mNumberOfDescriptors = 0;\r
+\r
/**\r
Add new bridge node or nvme device info to the device list.\r
\r
return Status;\r
}\r
\r
+/**\r
+ OpalPassword Notification for SMM EndOfDxe protocol.\r
+\r
+ @param[in] Protocol Points to the protocol's unique identifier.\r
+ @param[in] Interface Points to the interface instance.\r
+ @param[in] Handle The handle on which the interface was installed.\r
+\r
+ @retval EFI_SUCCESS Notification runs successfully.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+OpalPasswordEndOfDxeNotification (\r
+ IN CONST EFI_GUID *Protocol,\r
+ IN VOID *Interface,\r
+ IN EFI_HANDLE Handle\r
+ )\r
+{\r
+ UINTN NumberOfDescriptors;\r
+ EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemSpaceMap;\r
+ EFI_STATUS Status;\r
+\r
+ Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemSpaceMap);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ mGcdMemSpace = AllocateCopyPool (NumberOfDescriptors * sizeof (EFI_GCD_MEMORY_SPACE_DESCRIPTOR), MemSpaceMap);\r
+ if (EFI_ERROR (Status)) {\r
+ gBS->FreePool (MemSpaceMap);\r
+ return Status;\r
+ }\r
+\r
+ mNumberOfDescriptors = NumberOfDescriptors;\r
+ gBS->FreePool (MemSpaceMap);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
/**\r
Main entry for this driver.\r
\r
EFI_SMM_VARIABLE_PROTOCOL *SmmVariable;\r
OPAL_EXTRA_INFO_VAR OpalExtraInfo;\r
UINTN DataSize;\r
+ EFI_EVENT EndOfDxeEvent;\r
EFI_PHYSICAL_ADDRESS Address;\r
\r
mBuffer = NULL;\r
//\r
mSwSmiValue = (UINT8) Context.SwSmiInputValue;\r
\r
+ //\r
+ // Create event to record GCD descriptors at end of dxe for judging AHCI/NVMe PCI Bar\r
+ // is in MMIO space to avoid attack.\r
+ //\r
+ Status = gSmst->SmmRegisterProtocolNotify (&gEfiSmmEndOfDxeProtocolGuid, OpalPasswordEndOfDxeNotification, &EndOfDxeEvent);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG((DEBUG_ERROR, "OpalPasswordSmm: Register SmmEndOfDxe fail, Status: %r\n", Status));\r
+ goto EXIT;\r
+ }\r
Status = gSmst->SmmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID**)&SmmVariable);\r
if (!EFI_ERROR (Status)) {\r
DataSize = sizeof (OPAL_EXTRA_INFO_VAR);\r
#include <Protocol/SmmReadyToLock.h>\r
#include <Protocol/SmmVariable.h>\r
#include <Protocol/VariableLock.h>\r
+#include <Protocol/SmmEndOfDxe.h>\r
#include <Protocol/StorageSecurityCommand.h>\r
\r
#include <Library/OpalPasswordSupportLib.h>\r
#include <Library/UefiLib.h>\r
#include <Library/S3BootScriptLib.h>\r
#include <Library/DevicePathLib.h>\r
-#include <Library/SmmMemLib.h>\r
-\r
#include <Library/DxeServicesTableLib.h>\r
\r
#include <IndustryStandard/Pci22.h>\r
\r
extern VOID *mBuffer;\r
\r
+extern EFI_GCD_MEMORY_SPACE_DESCRIPTOR *mGcdMemSpace;\r
+extern UINTN mNumberOfDescriptors;\r
#pragma pack(1)\r
\r
typedef struct {\r