From: Subash Lakkimsetti <subash.lakkimse...@intel.com>

Bootloader supports multiple payload and TPM2 ACPI tables are updated
at bootloader phase. When UEFI is used payload these will be duplicates.
The tables are to be uninstalled before updating the TCG2ACPI tables
to avoid duplicates.

Cc: Qi Zhang <qi1.zh...@intel.com>
Cc: Rahul Kumar <rahul1.ku...@intel.com>
Signed-off-by: Subash Lakkimsetti <subash.lakkimse...@intel.com>
---
 SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.c   | 251 ++++++++++++++++++++++++++
 SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.inf |   3 +
 2 files changed, 254 insertions(+)

diff --git a/SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.c 
b/SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.c
index e8822cbeb0..4b35796ba7 100644
--- a/SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.c
+++ b/SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.c
@@ -39,6 +39,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include <Library/Tpm2CommandLib.h>
 #include <Library/UefiLib.h>
 #include <Library/MmUnblockMemoryLib.h>
+#include <IndustryStandard/Acpi.h>
+#include <Protocol/AcpiSystemDescriptionTable.h>
 
 //
 // Physical Presence Interface Version supported by Platform
@@ -867,6 +869,245 @@ PublishTpm2 (
   return Status;
 }
 
+/**
+  Uninstall TPM2 SSDT ACPI table
+
+  This performs uninstallation of TPM2 SSDT tables published by
+  bootloaders.
+
+  @retval   EFI_SUCCESS     The TPM2 ACPI table is uninstalled successfully if 
found.
+  @retval   Others          Operation error.
+
+**/
+EFI_STATUS
+UnInstallTpm2SSDTAcpiTables (
+  )
+{
+  UINTN                    TableIndex;
+  UINTN                    TableKey;
+  EFI_ACPI_TABLE_VERSION   TableVersion;
+  VOID                     *TableHeader;
+  EFI_STATUS               Status;
+  EFI_ACPI_SDT_PROTOCOL    *mAcpiSdtProtocol;
+  EFI_ACPI_TABLE_PROTOCOL  *mAcpiTableProtocol;
+  CHAR8                    TableIdString[8];
+  UINT64                   TableIdSignature;
+
+  //
+  // Determine whether there is a TPM2 SSDT already in the ACPI table.
+  //
+  Status             = EFI_SUCCESS;
+  TableIndex         = 0;
+  TableKey           = 0;
+  TableHeader        = NULL;
+  mAcpiTableProtocol = NULL;
+  mAcpiSdtProtocol   = NULL;
+
+  //
+  // Locate the EFI_ACPI_TABLE_PROTOCOL.
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiAcpiTableProtocolGuid,
+                  NULL,
+                  (VOID **)&mAcpiTableProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_INFO,
+      "UnInstallTpm2SSDTAcpiTables: Cannot locate the EFI ACPI Table Protocol 
\n "
+      ));
+    return Status;
+  }
+
+  //
+  // Locate the EFI_ACPI_SDT_PROTOCOL.
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiAcpiSdtProtocolGuid,
+                  NULL,
+                  (VOID **)&mAcpiSdtProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_INFO,
+      "UnInstallTpm2SSDTAcpiTables: Cannot locate the EFI ACPI Sdt Protocol, "
+      "\n"
+      ));
+    return Status;
+  }
+
+  while (!EFI_ERROR (Status)) {
+    Status = mAcpiSdtProtocol->GetAcpiTable (
+                                 TableIndex,
+                                 (EFI_ACPI_SDT_HEADER **)&TableHeader,
+                                 &TableVersion,
+                                 &TableKey
+                                 );
+
+    if (!EFI_ERROR (Status)) {
+      TableIndex++;
+
+      if (((EFI_ACPI_SDT_HEADER *)TableHeader)->Signature == SIGNATURE_32 
('S', 'S', 'D', 'T')) {
+        CopyMem ((VOID *)TableIdString, (VOID *)((EFI_ACPI_SDT_HEADER 
*)TableHeader)->OemTableId, sizeof (TableIdString));
+
+        TableIdSignature = SIGNATURE_64 (
+                             TableIdString[0],
+                             TableIdString[1],
+                             TableIdString[2],
+                             TableIdString[3],
+                             TableIdString[4],
+                             TableIdString[5],
+                             TableIdString[6],
+                             TableIdString[7]
+                             );
+
+        if (TableIdSignature == SIGNATURE_64 ('T', 'p', 'm', '2', 'T', 'a', 
'b', 'l')) {
+          DEBUG ((DEBUG_INFO, "Found Tpm2 SSDT Table for Physical 
Presence\n"));
+          break;
+        }
+      }
+    }
+  }
+
+  if (!EFI_ERROR (Status)) {
+    //
+    // A TPM2 SSDT is already in the ACPI table.
+    //
+    DEBUG ((
+      DEBUG_INFO,
+      "A TPM2 SSDT is already exist in the ACPI Table.\n"
+      ));
+
+    //
+    // Uninstall the origin TPM2 SSDT from the ACPI table.
+    //
+    Status = mAcpiTableProtocol->UninstallAcpiTable (
+                                   mAcpiTableProtocol,
+                                   TableKey
+                                   );
+    ASSERT_EFI_ERROR (Status);
+
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_INFO, "UnInstall Tpm2SSDTAcpiTables failed \n "));
+
+      return Status;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Uninstall TPM2 table
+
+  This performs uninstallation of TPM2 tables published by
+  bootloaders.
+
+  @retval   EFI_SUCCESS     The TPM2 table is uninstalled successfully if its 
found.
+  @retval   Others          Operation error.
+
+**/
+EFI_STATUS
+UnInstallTpm2Tables (
+  )
+{
+  UINTN                    TableIndex;
+  UINTN                    TableKey;
+  EFI_ACPI_TABLE_VERSION   TableVersion;
+  VOID                     *TableHeader;
+  EFI_STATUS               Status;
+  EFI_ACPI_SDT_PROTOCOL    *mAcpiSdtProtocol;
+  EFI_ACPI_TABLE_PROTOCOL  *mAcpiTableProtocol;
+
+  //
+  // Determine whether there is a TPM2 SSDT already in the ACPI table.
+  //
+  Status             = EFI_SUCCESS;
+  TableIndex         = 0;
+  TableKey           = 0;
+  TableHeader        = NULL;
+  mAcpiTableProtocol = NULL;
+  mAcpiSdtProtocol   = NULL;
+
+  //
+  // Locate the EFI_ACPI_TABLE_PROTOCOL.
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiAcpiTableProtocolGuid,
+                  NULL,
+                  (VOID **)&mAcpiTableProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_INFO,
+      "UnInstallTpm2Tables: Cannot locate the EFI ACPI Table Protocol \n "
+      ));
+    return Status;
+  }
+
+  //
+  // Locate the EFI_ACPI_SDT_PROTOCOL.
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiAcpiSdtProtocolGuid,
+                  NULL,
+                  (VOID **)&mAcpiSdtProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_INFO,
+      "UnInstallTpm2Tables: Cannot locate the EFI ACPI Sdt Protocol, "
+      "\n"
+      ));
+    return Status;
+  }
+
+  while (!EFI_ERROR (Status)) {
+    Status = mAcpiSdtProtocol->GetAcpiTable (
+                                 TableIndex,
+                                 (EFI_ACPI_SDT_HEADER **)&TableHeader,
+                                 &TableVersion,
+                                 &TableKey
+                                 );
+
+    if (!EFI_ERROR (Status)) {
+      TableIndex++;
+
+      if (((EFI_ACPI_SDT_HEADER *)TableHeader)->Signature == 
EFI_ACPI_5_0_TRUSTED_COMPUTING_PLATFORM_2_TABLE_SIGNATURE ) {
+        DEBUG ((DEBUG_INFO, "Found Tpm2 Table ..\n"));
+        break;
+      }
+    }
+  }
+
+  if (!EFI_ERROR (Status)) {
+    //
+    // A TPM2 SSDT is already in the ACPI table.
+    //
+    DEBUG ((
+      DEBUG_INFO,
+      "A TPM2 table  is already exist in the ACPI Table.\n"
+      ));
+
+    //
+    // Uninstall the origin TPM2 SSDT from the ACPI table.
+    //
+    Status = mAcpiTableProtocol->UninstallAcpiTable (
+                                   mAcpiTableProtocol,
+                                   TableKey
+                                   );
+    ASSERT_EFI_ERROR (Status);
+
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_INFO, "UnInstall Tpm2Tables failed \n "));
+
+      return Status;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
 /**
   The driver's entry point.
 
@@ -894,6 +1135,16 @@ InitializeTcgAcpi (
     return EFI_UNSUPPORTED;
   }
 
+  //
+  // Bootloader might pulish the TPM2 ACPT tables
+  // Uninstall TPM tables if it exists
+  //
+  Status = UnInstallTpm2SSDTAcpiTables ();
+  ASSERT_EFI_ERROR (Status);
+
+  Status = UnInstallTpm2Tables ();
+  ASSERT_EFI_ERROR (Status);
+
   Status = PublishAcpiTable ();
   ASSERT_EFI_ERROR (Status);
 
diff --git a/SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.inf 
b/SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.inf
index f1c6ae5b1c..7e639b0522 100644
--- a/SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.inf
+++ b/SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.inf
@@ -63,10 +63,13 @@
   gEfiTpmDeviceInstanceTpm20DtpmGuid                            ## PRODUCES    
       ## GUID       # TPM device identifier
   gTpmNvsMmGuid                                                 ## CONSUMES
   gEdkiiPiSmmCommunicationRegionTableGuid                       ## CONSUMES
+  gEfiAcpiTableGuid
 
 [Protocols]
   gEfiAcpiTableProtocolGuid                                     ## CONSUMES
   gEfiMmCommunicationProtocolGuid                               ## CONSUMES
+  gEfiAcpiSdtProtocolGuid                        ## CONSUMES
+
 
 [FixedPcd]
   gEfiSecurityPkgTokenSpaceGuid.PcdSmiCommandIoPort             ## CONSUMES
-- 
2.39.1.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#101580): https://edk2.groups.io/g/devel/message/101580
Mute This Topic: https://groups.io/mt/97777996/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-


Reply via email to