]> git.proxmox.com Git - mirror_edk2.git/commitdiff
SecurityPkg OpalPasswordSmm: Fix S3 resume failure.
authorEric Dong <eric.dong@intel.com>
Tue, 11 Oct 2016 08:00:21 +0000 (16:00 +0800)
committerStar Zeng <star.zeng@intel.com>
Wed, 12 Oct 2016 05:19:47 +0000 (13:19 +0800)
Changes includes:
1.Check SMM device list before update it to avoid duplicate creation.
2.Clean up the configuration buffer before use it in S3 resume phase.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Feng Tian <feng.tian@intel.com>
SecurityPkg/Tcg/Opal/OpalPasswordSmm/OpalNvmeMode.c
SecurityPkg/Tcg/Opal/OpalPasswordSmm/OpalPasswordSmm.c

index 3826698709ceaa23e6a00164fff159ddab6c79a4..9e90d5442977c8edd1444905486d85c21a56882d 100644 (file)
@@ -1691,6 +1691,14 @@ NvmeControllerInit (
   Nvme->Cid[0] = 0;\r
   Nvme->Cid[1] = 0;\r
 \r
+  Nvme->Pt[0]  = 0;\r
+  Nvme->Pt[1]  = 0;\r
+\r
+  ZeroMem ((VOID *)(UINTN)(&(Nvme->SqTdbl[0])), sizeof (NVME_SQTDBL) * NVME_MAX_IO_QUEUES);\r
+  ZeroMem ((VOID *)(UINTN)(&(Nvme->CqHdbl[0])), sizeof (NVME_CQHDBL) * NVME_MAX_IO_QUEUES);\r
+\r
+  ZeroMem ((VOID *)(UINTN)Nvme->BaseMem, NVME_MEM_MAX_SIZE);\r
+\r
   Status = NvmeDisableController (Nvme);\r
   if (EFI_ERROR(Status)) {\r
     DEBUG ((DEBUG_ERROR, "NvmeDisableController fail, Status: %r\n", Status));\r
index 47b570f343424feb118126bfeba49db26865d53c..2f2a1d9c13e44f4ee289cd2c1679f4a3e44de777 100644 (file)
@@ -483,6 +483,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 +568,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 +576,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,10 +641,8 @@ 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