]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/Tcg/Opal/OpalPasswordSmm/OpalPasswordSmm.c
SecurityPkg OpalPasswordSmm: Consume SmmIoLib.
[mirror_edk2.git] / SecurityPkg / Tcg / Opal / OpalPasswordSmm / OpalPasswordSmm.c
index 47b570f343424feb118126bfeba49db26865d53c..0ea92b15c067720cee0c94bb5a05d186dac36e7d 100644 (file)
@@ -61,9 +61,6 @@ VOID                 *mBuffer = NULL; // DMA can not read/write Data to smram, s
 // 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
@@ -483,6 +480,53 @@ done:
   return Status;\r
 }\r
 \r
+/**\r
+  The function extracts device information from OpalDeviceList and creat SmmDeviceList used for S3.\r
+\r
+  @param[in]       OpalDeviceList   Opal device list created at POST which contains the information of OPAL_DISK_AND_PASSWORD_INFO\r
+  @param[in,out]   SmmDeviceList    Opal Smm device list to be created and used for unlocking devices at S3 resume.\r
+\r
+  @retval EFI_SUCCESS            Create SmmDeviceList successfully.\r
+  @retval Others                 Other execution results.\r
+**/\r
+EFI_STATUS\r
+CreateSmmDeviceList (\r
+  IN     LIST_ENTRY                 *OpalDeviceList,\r
+  IN OUT LIST_ENTRY                 *SmmDeviceList\r
+  )\r
+{\r
+  LIST_ENTRY                        *Entry;\r
+  OPAL_DISK_AND_PASSWORD_INFO       *PciDev;\r
+  OPAL_SMM_DEVICE                   *SmmDev;\r
+\r
+  for (Entry = OpalDeviceList->ForwardLink; Entry != OpalDeviceList; Entry = Entry->ForwardLink) {\r
+    PciDev = BASE_CR (Entry, OPAL_DISK_AND_PASSWORD_INFO, Link);\r
+\r
+    SmmDev = AllocateZeroPool (sizeof (OPAL_SMM_DEVICE));\r
+    if (SmmDev == NULL) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+    SmmDev->Signature = OPAL_SMM_DEVICE_SIGNATURE;\r
+\r
+    ExtractDeviceInfoFromDevicePath(&PciDev->OpalDevicePath, SmmDev);\r
+\r
+    SmmDev->PasswordLength = PciDev->PasswordLength;\r
+    CopyMem(&(SmmDev->Password), PciDev->Password, OPAL_PASSWORD_MAX_LENGTH);\r
+\r
+    SmmDev->Sscp.ReceiveData = SecurityReceiveData;\r
+    SmmDev->Sscp.SendData = SecuritySendData;\r
+\r
+    DEBUG ((DEBUG_INFO, "Opal SMM: Insert device node to SmmDeviceList:\n"));\r
+    DEBUG ((DEBUG_INFO, "DeviceType:%x, Bus:%d, Dev:%d, Fun:%d\n", \\r
+      SmmDev->DeviceType, SmmDev->BusNum, SmmDev->DevNum, SmmDev->FuncNum));\r
+    DEBUG ((DEBUG_INFO, "SataPort:%x, MultiplierPort:%x, NvmeNamespaceId:%x\n", \\r
+      SmmDev->SataPort, SmmDev->SataPortMultiplierPort, SmmDev->NvmeNamespaceId));\r
+\r
+    InsertHeadList (SmmDeviceList, &SmmDev->Link);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
 \r
 /**\r
   Main entry point for an SMM handler dispatch or communicate-based callback.\r
@@ -521,7 +565,6 @@ S3SleepEntryCallBack (
   UINT64                            Address;\r
   S3_BOOT_SCRIPT_LIB_WIDTH          Width;\r
   UINT32                            Data;\r
-  OPAL_DISK_AND_PASSWORD_INFO       *PciDev;\r
   OPAL_HC_PCI_REGISTER_SAVE         *HcRegisterSaveListPtr;\r
   UINTN                             Count;\r
   OPAL_SMM_DEVICE                   *SmmDev;\r
@@ -530,25 +573,28 @@ S3SleepEntryCallBack (
   Status   = EFI_SUCCESS;\r
 \r
   mOpalDeviceList = OpalSupportGetOpalDeviceList();\r
+  if (IsListEmpty (mOpalDeviceList)) {\r
+    //\r
+    // No Opal enabled device. Do nothing.\r
+    //\r
+    return EFI_SUCCESS;\r
+  }\r
 \r
-  for (Entry = mOpalDeviceList->ForwardLink; Entry != mOpalDeviceList; Entry = Entry->ForwardLink) {\r
-    PciDev   = BASE_CR (Entry, OPAL_DISK_AND_PASSWORD_INFO, Link);\r
-\r
-    SmmDev = AllocateZeroPool (sizeof (OPAL_SMM_DEVICE));\r
-    if (SmmDev == NULL) {\r
-      return EFI_OUT_OF_RESOURCES;\r
+  if (IsListEmpty (&mSmmDeviceList)) {\r
+    //\r
+    // mSmmDeviceList for S3 is empty, creat it by mOpalDeviceList.\r
+    //\r
+    Status = CreateSmmDeviceList (mOpalDeviceList, &mSmmDeviceList);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
     }\r
-    SmmDev->Signature = OPAL_SMM_DEVICE_SIGNATURE;\r
-\r
-    ExtractDeviceInfoFromDevicePath(&PciDev->OpalDevicePath, SmmDev);\r
-\r
-    SmmDev->PasswordLength = PciDev->PasswordLength;\r
-    CopyMem(&(SmmDev->Password), PciDev->Password, OPAL_PASSWORD_MAX_LENGTH);\r
-\r
-    SmmDev->Sscp.ReceiveData = SecurityReceiveData;\r
-    SmmDev->Sscp.SendData = SecuritySendData;\r
+  }\r
 \r
-    InsertHeadList (&mSmmDeviceList, &SmmDev->Link);\r
+  //\r
+  // Go through SmmDeviceList to save register data for S3\r
+  //\r
+  for (Entry = mSmmDeviceList.ForwardLink; Entry != &mSmmDeviceList; Entry = Entry->ForwardLink) {\r
+    SmmDev = BASE_CR (Entry, OPAL_SMM_DEVICE, Link);\r
 \r
     if (SmmDev->DeviceType == OPAL_DEVICE_TYPE_NVME) {\r
       continue;\r
@@ -592,52 +638,12 @@ S3SleepEntryCallBack (
     }\r
   }\r
 \r
-  if (!IsListEmpty (mOpalDeviceList)) {\r
-    Status = S3BootScriptSaveIoWrite (S3BootScriptWidthUint8, 0xB2, 1, &mSwSmiValue);\r
-    ASSERT_EFI_ERROR (Status);\r
-  }\r
+  Status = S3BootScriptSaveIoWrite (S3BootScriptWidthUint8, 0xB2, 1, &mSwSmiValue);\r
+  ASSERT_EFI_ERROR (Status);\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
@@ -664,7 +670,6 @@ OpalPasswordSmmInit (
   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
@@ -773,15 +778,6 @@ OpalPasswordSmmInit (
   //\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