From 5dafa13d623a764648221ebb644f880c3cb1198f Mon Sep 17 00:00:00 2001 From: Abdul Lateef Attar Date: Thu, 29 Aug 2024 14:28:17 +0000 Subject: [PATCH] DynamicTablesPkg: Adds WSMT generator for X64 Adds ACPI WSMT table generator library. Updates acpi standard table enum with wsmt. Updates X64 namespace object. Updates the object parser. Updates the Readme. Cc: Sami Mujawar Cc: Pierre Gondois Signed-off-by: Abdul Lateef Attar --- DynamicTablesPkg/DynamicTables.dsc.inc | 6 + DynamicTablesPkg/Include/AcpiTableGenerator.h | 4 + .../Include/X64NameSpaceObjects.h | 14 +- .../Acpi/X64/AcpiWsmtLib/AcpiWsmtLib.inf | 35 +++ .../Acpi/X64/AcpiWsmtLib/WsmtGenerator.c | 288 ++++++++++++++++++ .../ConfigurationManagerObjectParser.c | 7 + DynamicTablesPkg/Readme.md | 1 + 7 files changed, 353 insertions(+), 2 deletions(-) create mode 100644 DynamicTablesPkg/Library/Acpi/X64/AcpiWsmtLib/AcpiWsmtLib.inf create mode 100644 DynamicTablesPkg/Library/Acpi/X64/AcpiWsmtLib/WsmtGenerator.c diff --git a/DynamicTablesPkg/DynamicTables.dsc.inc b/DynamicTablesPkg/DynamicTables.dsc.inc index dc363dc802..f4866c2dd7 100644 --- a/DynamicTablesPkg/DynamicTables.dsc.inc +++ b/DynamicTablesPkg/DynamicTables.dsc.inc @@ -52,6 +52,11 @@ DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf [Components.IA32, Components.X64] + # + # Generators (IA32/X64 specific) + # + DynamicTablesPkg/Library/Acpi/X64/AcpiWsmtLib/AcpiWsmtLib.inf + # # Dynamic Table Factory Dxe # @@ -60,6 +65,7 @@ # Generators # Common NULL|DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/AcpiFadtLib.inf + NULL|DynamicTablesPkg/Library/Acpi/X64/AcpiWsmtLib/AcpiWsmtLib.inf } [Components.ARM, Components.AARCH64] diff --git a/DynamicTablesPkg/Include/AcpiTableGenerator.h b/DynamicTablesPkg/Include/AcpiTableGenerator.h index 778a908bcd..761a5ec6d3 100644 --- a/DynamicTablesPkg/Include/AcpiTableGenerator.h +++ b/DynamicTablesPkg/Include/AcpiTableGenerator.h @@ -2,6 +2,7 @@ Copyright (c) 2017 - 2022, Arm Limited. All rights reserved.
Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+ Copyright (c) 2024 Advanced Micro Devices, Inc. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent @@ -72,6 +73,8 @@ The Dynamic Tables Framework implements the following ACPI table generators: The SSDT Pci Express generator collates the Pci Express information from the Configuration Manager and generates a SSDT table describing a Pci Express bus. + - WSMT : The WSMT generator collates the WSMT protection flag information + from the Configuration Manager and builds the WSMT table. */ /** The ACPI_TABLE_GENERATOR_ID type describes ACPI table generator ID. @@ -101,6 +104,7 @@ typedef enum StdAcpiTableId { EStdAcpiTableIdSsdtPciExpress, ///< SSDT Pci Express Generator EStdAcpiTableIdPcct, ///< PCCT Generator EStdAcpiTableIdTpm2, ///< TPM2 Generator + EStdAcpiTableIdWsmt, ///< WSMT Generator EStdAcpiTableIdMax } ESTD_ACPI_TABLE_ID; diff --git a/DynamicTablesPkg/Include/X64NameSpaceObjects.h b/DynamicTablesPkg/Include/X64NameSpaceObjects.h index 2fa696b4c3..d897051d88 100644 --- a/DynamicTablesPkg/Include/X64NameSpaceObjects.h +++ b/DynamicTablesPkg/Include/X64NameSpaceObjects.h @@ -30,8 +30,9 @@ typedef enum X64ObjectID { EX64ObjFadtXgpeBlockInfo, ///< 6 - FADT 64-bit GPE block info EX64ObjFadtSleepBlockInfo, ///< 7 - FADT Sleep block info EX64ObjFadtResetBlockInfo, ///< 8 - FADT Reset block info - EX64ObjFadtMiscInfo, ///< 0 - FADT Legacy fields info - EX64ObjMax ///< 10 - Maximum Object ID + EX64ObjFadtMiscInfo, ///< 9 - FADT Legacy fields info + EX64ObjWsmtFlagsInfo, ///< 10 - WSMT protection flags info + EX64ObjMax ///< 11 - Maximum Object ID } EX64_OBJECT_ID; /** A structure that describes the @@ -167,4 +168,13 @@ typedef struct CmX64FadtFadtMiscInfo { UINT8 Century; } CM_X64_FADT_MISC_INFO; +/** + A structure that describes the WSMT protection flags information. + + ID: EX64ObjWsmtFlagsInfo +*/ +typedef struct CmX64WsmtFlagsInfo { + UINT32 ProtectionFlags; +} CM_X64_WSMT_FLAGS_INFO; + #endif // X64_NAMESPACE_OBJECTS_H_ diff --git a/DynamicTablesPkg/Library/Acpi/X64/AcpiWsmtLib/AcpiWsmtLib.inf b/DynamicTablesPkg/Library/Acpi/X64/AcpiWsmtLib/AcpiWsmtLib.inf new file mode 100644 index 0000000000..06e8f8cd3f --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/X64/AcpiWsmtLib/AcpiWsmtLib.inf @@ -0,0 +1,35 @@ +## @file +# WSMT Table Generator +# +# Copyright (c) 2024 Advanced Micro Devices, Inc. All rights reserved. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 1.30 + BASE_NAME = AcpiWsmtLib + FILE_GUID = FA6B175A-0AAF-4BFA-843A-1D885206C070 + VERSION_STRING = 1.0 + MODULE_TYPE = DXE_DRIVER + LIBRARY_CLASS = NULL|DXE_DRIVER + CONSTRUCTOR = AcpiWsmtLibConstructor + DESTRUCTOR = AcpiWsmtLibDestructor + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources.IA32, Sources.X64] + WsmtGenerator.c + +[Packages] + DynamicTablesPkg/DynamicTablesPkg.dec + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib + DebugLib diff --git a/DynamicTablesPkg/Library/Acpi/X64/AcpiWsmtLib/WsmtGenerator.c b/DynamicTablesPkg/Library/Acpi/X64/AcpiWsmtLib/WsmtGenerator.c new file mode 100644 index 0000000000..97622948f5 --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/X64/AcpiWsmtLib/WsmtGenerator.c @@ -0,0 +1,288 @@ +/** @file + WSMT Table Generator Implementation. + + This file implements the WSMT Table Generator. + The WSMT table is used to specify the security mitigation + that are enabled in the Windows OS. + + Copyright (c) 2024 Advanced Micro Devices, Inc. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define WSMT_PROTECTION_VALID_FLAGS \ + (EFI_WSMT_PROTECTION_FLAGS_FIXED_COMM_BUFFERS | \ + EFI_WSMT_PROTECTION_FLAGS_COMM_BUFFER_NESTED_PTR_PROTECTION | \ + EFI_WSMT_PROTECTION_FLAGS_SYSTEM_RESOURCE_PROTECTION) + +/** This macro expands to a function that retrieves the + WSMT protection flags information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceX64, + EX64ObjWsmtFlagsInfo, + CM_X64_WSMT_FLAGS_INFO + ); + +/** The ACPI WSMT Table. +*/ +STATIC +EFI_ACPI_WSMT_TABLE AcpiWsmt = { + ACPI_HEADER ( + EFI_ACPI_WINDOWS_SMM_SECURITY_MITIGATION_TABLE_SIGNATURE, + EFI_ACPI_WSMT_TABLE, + EFI_WSMT_TABLE_REVISION + ), + // ProtectionFlags + 0 +}; + +/** Update the protection flags information in the WSMT Table. + + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The required object was not found. + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration + Manager is less than the Object size for the + requested object. + @retval EFI_UNSUPPORTED If invalid protection flags provided. +**/ +STATIC +EFI_STATUS +EFIAPI +WsmtAddProtectionFlagsInfo ( + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol + ) +{ + EFI_STATUS Status; + CM_X64_WSMT_FLAGS_INFO *WsmtFlagInfo; + + ASSERT (CfgMgrProtocol != NULL); + + // Get the WSMT protection flag from the Platform Configuration Manager + Status = GetEX64ObjWsmtFlagsInfo ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &WsmtFlagInfo, + NULL + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: WSMT: Failed to get WSMT protection flag information." \ + " Status = %r\n", + Status + )); + return Status; + } + + DEBUG (( + DEBUG_INFO, + "WSMT: Protection flags = 0x%x\n", + WsmtFlagInfo->ProtectionFlags + )); + + // Validate the protection flags + if ((WsmtFlagInfo->ProtectionFlags & ~WSMT_PROTECTION_VALID_FLAGS) != 0) { + DEBUG (( + DEBUG_ERROR, + "ERROR: WSMT: Invalid protection flags = 0x%x\n", + WsmtFlagInfo->ProtectionFlags + )); + return EFI_UNSUPPORTED; + } + + if ((WsmtFlagInfo->ProtectionFlags & EFI_WSMT_PROTECTION_FLAGS_COMM_BUFFER_NESTED_PTR_PROTECTION) != 0) { + if ((WsmtFlagInfo->ProtectionFlags & EFI_WSMT_PROTECTION_FLAGS_FIXED_COMM_BUFFERS) == 0) { + DEBUG (( + DEBUG_ERROR, + "ERROR: WSMT: Invalid protection flags. EFI_WSMT_PROTECTION_FLAGS_FIXED_COMM_BUFFERS not set.\n" + )); + return EFI_UNSUPPORTED; + } + } + + AcpiWsmt.ProtectionFlags = WsmtFlagInfo->ProtectionFlags; + return Status; +} + +/** Construct the WSMT table. + + This function invokes the Configuration Manager protocol interface + to get the required information for generating the ACPI table. + + If this function allocates any resources then they must be freed + in the FreeXXXXTableResources function. + + @param [in] This Pointer to the table generator. + @param [in] AcpiTableInfo Pointer to the ACPI Table Info. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [out] Table Pointer to the constructed ACPI Table. + + @retval EFI_SUCCESS Table generated successfully. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The required object was not found. + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration + Manager is less than the Object size for the + requested object. +**/ +STATIC +EFI_STATUS +EFIAPI +BuildWsmtTable ( + IN CONST ACPI_TABLE_GENERATOR *CONST This, + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table + ) +{ + EFI_STATUS Status; + + ASSERT (This != NULL); + ASSERT (AcpiTableInfo != NULL); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (Table != NULL); + ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); + ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); + + if ((AcpiTableInfo->AcpiTableRevision < This->MinAcpiTableRevision) || + (AcpiTableInfo->AcpiTableRevision > This->AcpiTableRevision)) + { + DEBUG (( + DEBUG_ERROR, + "ERROR: WSMT: Requested table revision = %d, is not supported." + "Supported table revision: Minimum = %d, Maximum = %d\n", + AcpiTableInfo->AcpiTableRevision, + This->MinAcpiTableRevision, + This->AcpiTableRevision + )); + return EFI_INVALID_PARAMETER; + } + + *Table = NULL; + + Status = AddAcpiHeader ( + CfgMgrProtocol, + This, + (EFI_ACPI_DESCRIPTION_HEADER *)&AcpiWsmt, + AcpiTableInfo, + sizeof (EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE) + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: WSMT: Failed to add ACPI header. Status = %r\n", + Status + )); + goto error_handler; + } + + // Update protection flags Info + Status = WsmtAddProtectionFlagsInfo (CfgMgrProtocol); + if (EFI_ERROR (Status)) { + goto error_handler; + } + + *Table = (EFI_ACPI_DESCRIPTION_HEADER *)&AcpiWsmt; +error_handler: + return Status; +} + +/** This macro defines the WSMT Table Generator revision. +*/ +#define WSMT_GENERATOR_REVISION CREATE_REVISION (1, 0) + +/** The interface for the WSMT Table Generator. +*/ +STATIC +CONST +ACPI_TABLE_GENERATOR WsmtGenerator = { + // Generator ID + CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdWsmt), + // Generator Description + L"ACPI.STD.WSMT.GENERATOR", + // ACPI Table Signature + EFI_ACPI_WINDOWS_SMM_SECURITY_MITIGATION_TABLE_SIGNATURE, + // ACPI Table Revision supported by this Generator + EFI_WSMT_TABLE_REVISION, + // Minimum supported ACPI Table Revision + EFI_WSMT_TABLE_REVISION, + // Creator ID + TABLE_GENERATOR_CREATOR_ID_ARM, + // Creator Revision + WSMT_GENERATOR_REVISION, + // Build Table function + BuildWsmtTable, + // No additional resources are allocated by the generator. + // Hence the Free Resource function is not required. + NULL, + // Extended build function not needed + NULL, + // Extended build function not implemented by the generator. + // Hence extended free resource function is not required. + NULL +}; + +/** Register the Generator with the ACPI Table Factory. + + @param [in] ImageHandle The handle to the image. + @param [in] SystemTable Pointer to the System Table. + + @retval EFI_SUCCESS The Generator is registered. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_ALREADY_STARTED The Generator for the Table ID + is already registered. +**/ +EFI_STATUS +EFIAPI +AcpiWsmtLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = RegisterAcpiTableGenerator (&WsmtGenerator); + DEBUG ((DEBUG_INFO, "WSMT: Register Generator. Status = %r\n", Status)); + ASSERT_EFI_ERROR (Status); + return Status; +} + +/** Deregister the Generator from the ACPI Table Factory. + + @param [in] ImageHandle The handle to the image. + @param [in] SystemTable Pointer to the System Table. + + @retval EFI_SUCCESS The Generator is deregistered. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The Generator is not registered. +**/ +EFI_STATUS +EFIAPI +AcpiWsmtLibDestructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = DeregisterAcpiTableGenerator (&WsmtGenerator); + DEBUG ((DEBUG_INFO, "WSMT: Deregister Generator. Status = %r\n", Status)); + ASSERT_EFI_ERROR (Status); + return Status; +} diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c index eceb91a6d8..c9737f67c3 100644 --- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c +++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c @@ -850,6 +850,12 @@ STATIC CONST CM_OBJ_PARSER CmX64ObjFadtMiscInfoParser[] = { { "Century", 1, "0x%x", NULL } }; +/** A parser for EX64ObjWsmtFlagsInfo. +*/ +STATIC CONST CM_OBJ_PARSER CmX64ObjWsmtFlagsInfoParser[] = { + { "WsmtFlags", 4, "0x%x", NULL } +}; + /** A parser for X64 namespace objects. */ STATIC CONST CM_OBJ_PARSER_ARRAY X64NamespaceObjectParser[] = { @@ -863,6 +869,7 @@ STATIC CONST CM_OBJ_PARSER_ARRAY X64NamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EX64ObjFadtSleepBlockInfo,CmX64ObjFadtSleepBlockInfoParser), CM_PARSER_ADD_OBJECT (EX64ObjFadtResetBlockInfo,CmX64ObjFadtResetBlockInfoParser), CM_PARSER_ADD_OBJECT (EX64ObjFadtMiscInfo, CmX64ObjFadtMiscInfoParser), + CM_PARSER_ADD_OBJECT (EX64ObjWsmtFlagsInfo, CmX64ObjWsmtFlagsInfoParser), CM_PARSER_ADD_OBJECT_RESERVED (EX64ObjMax) }; diff --git a/DynamicTablesPkg/Readme.md b/DynamicTablesPkg/Readme.md index b2230aff46..84d7ca9faf 100644 --- a/DynamicTablesPkg/Readme.md +++ b/DynamicTablesPkg/Readme.md @@ -514,4 +514,5 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 7 | Sleep Block Info | | | 8 | Reset Block Info | | | 9 | Miscellaneous Block Info | | +| 10 | Windows protection flag Info | | | `*` | All other values are reserved. | |