From: "Sami Mujawar" <sami.mujawar@arm.com>
To: Omkar Anand Kulkarni <omkar.kulkarni@arm.com>, devel@edk2.groups.io
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>, nd <nd@arm.com>
Subject: Re: [PATCH v2 3/4] ArmPlatformPkg: retreive error source descriptors from MM
Date: Tue, 3 Aug 2021 15:46:22 +0100 [thread overview]
Message-ID: <38e5bdd4-17e2-a8de-193c-be98c2166220@arm.com> (raw)
In-Reply-To: <20210710161831.30433-4-omkar.kulkarni@arm.com>
[-- Attachment #1: Type: text/plain, Size: 32470 bytes --]
Hi Omkar,
Please find my response inline marked [SAMI].
Regards,
Sami Mujawar
On 10/07/2021 05:18 PM, Omkar Anand Kulkarni wrote:
> Add a driver that retreives error source descriptors from MM and
> populates those into the HEST ACPI table. The error source descriptors
> that are available from the MM side are retreived using MM Communicate 2
> protocol.
>
> The first call into the MM returns the size of MM Communicate buffer
> required to hold all error source descriptor info. The communication
> buffer of that size is then allocated and the second call into MM
> returns the error source descriptors in the communication buffer.
> The retreived error source descriptors are then appended to the HEST
> table.
>
> Co-authored-by: Thomas Abraham<thomas.abraham@arm.com>
> Signed-off-by: Omkar Anand Kulkarni<omkar.kulkarni@arm.com>
> ---
> ArmPlatformPkg/ArmPlatformPkg.dec | 7 +
> ArmPlatformPkg/Drivers/HestMmErrorSources/HestErrorSourceDxe.inf | 44 +++
> ArmPlatformPkg/Drivers/HestMmErrorSources/HestErrorSourceStandaloneMm.inf | 51 ++++
> ArmPlatformPkg/Drivers/HestMmErrorSources/HestMmErrorSourceCommon.h | 37 +++
> ArmPlatformPkg/Drivers/HestMmErrorSources/HestErrorSourceDxe.c | 308 +++++++++++++++++++
> ArmPlatformPkg/Drivers/HestMmErrorSources/HestErrorSourceStandaloneMm.c | 312 ++++++++++++++++++++
[SAMI] Should this patch be split into 2?
> 6 files changed, 759 insertions(+)
>
> diff --git a/ArmPlatformPkg/ArmPlatformPkg.dec b/ArmPlatformPkg/ArmPlatformPkg.dec
> index 4f062292663b..846b3e863aa9 100644
> --- a/ArmPlatformPkg/ArmPlatformPkg.dec
> +++ b/ArmPlatformPkg/ArmPlatformPkg.dec
> @@ -52,6 +52,8 @@
>
> [Guids.common]
> gArmPlatformTokenSpaceGuid = { 0x9c0aaed4, 0x74c5, 0x4043, { 0xb4, 0x17, 0xa3, 0x22, 0x38, 0x14, 0xce, 0x76 } }
> + gArmPlatformHestErrorSourcesGuid = { 0x76b8ab43, 0x822d, 0x4b00, { 0x9f, 0xd0, 0xf4, 0xa5, 0x35, 0x82, 0x47, 0x0a } }
> + gMmHestGetErrorSourceInfoGuid = { 0x7d602951, 0x678e, 0x4cc4, { 0x98, 0xd9, 0xe3, 0x76, 0x04, 0xf6, 0x93, 0x0d } }
>
> [PcdsFeatureFlag.common]
> gArmPlatformTokenSpaceGuid.PcdSendSgiToBringUpSecondaryCores|FALSE|BOOLEAN|0x00000004
> @@ -128,6 +130,11 @@
>
> gArmPlatformTokenSpaceGuid.PcdWatchdogCount|0x0|UINT32|0x00000033
>
> +[PcdsFixedAtBuild, PcdsPatchableInModule]
> + ## ACPI CPER memory space
> + gArmPlatformTokenSpaceGuid.PcdGhesGenericErrorDataMmBufferBase|0x00000000|UINT64|0x00000046
> + gArmPlatformTokenSpaceGuid.PcdGhesGenericErrorDataMmBufferSize|0x00000000|UINT64|0x00000047
> +
> [Protocols.common]
> ## Arm Platform HEST table generation protocol
> gHestTableProtocolGuid = { 0x705bdcd9, 0x8c47, 0x457e, { 0xad, 0x0d, 0xf7, 0x86, 0xf3, 0x4a, 0x0d, 0x63 } }
> diff --git a/ArmPlatformPkg/Drivers/HestMmErrorSources/HestErrorSourceDxe.inf b/ArmPlatformPkg/Drivers/HestMmErrorSources/HestErrorSourceDxe.inf
> new file mode 100644
> index 000000000000..5227dea91630
> --- /dev/null
> +++ b/ArmPlatformPkg/Drivers/HestMmErrorSources/HestErrorSourceDxe.inf
> @@ -0,0 +1,44 @@
> +## @file
> +# DXE driver to get secure error sources.
> +#
> +# DXE driver to retrieve the error source descriptors from Standalone MM and
> +# append those to the HEST table.
> +#
> +# Copyright (c) 2020 - 2021, ARM Limited. All rights reserved.
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x0001001A
> + BASE_NAME = HestMmErrorSourceDxe
> + FILE_GUID = 76b8ab43-822d-4b00-9fd0-f4a53582470a
> + MODULE_TYPE = DXE_DRIVER
> + VERSION_STRING = 1.0
> + ENTRY_POINT = HestErrorSourceInitialize
> +
> +[Sources.common]
> + HestErrorSourceDxe.c
> +
> +[Packages]
> + ArmPkg/ArmPkg.dec
> + ArmPlatformPkg/ArmPlatformPkg.dec
> + MdePkg/MdePkg.dec
> + StandaloneMmPkg/StandaloneMmPkg.dec
> +
> +[LibraryClasses]
> + BaseMemoryLib
> + DebugLib
> + DxeServicesTableLib
> + UefiDriverEntryPoint
> + UefiLib
> +
> +[Guids]
> + gMmHestGetErrorSourceInfoGuid ## PRODUCES
> +
> +[Protocols]
> + gHestTableProtocolGuid ## CONSUMES
> + gEfiMmCommunication2ProtocolGuid
> +
> +[Depex]
> + gHestTableProtocolGuid AND gEfiMmCommunication2ProtocolGuid
> diff --git a/ArmPlatformPkg/Drivers/HestMmErrorSources/HestErrorSourceStandaloneMm.inf b/ArmPlatformPkg/Drivers/HestMmErrorSources/HestErrorSourceStandaloneMm.inf
> new file mode 100644
> index 000000000000..9d566de9bec3
> --- /dev/null
> +++ b/ArmPlatformPkg/Drivers/HestMmErrorSources/HestErrorSourceStandaloneMm.inf
> @@ -0,0 +1,51 @@
> +## @file
> +# HEST error source gateway Standalone MM driver.
> +#
> +# Collects HEST error source descriptors,by communicating with all the MM
> +# drivers implementing the HEST error source descriptor protocol.
> +#
> +# Copyright (c) 2020 - 2021, ARM Limited. All rights reserved.
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x0001001A
> + BASE_NAME = HestErrorSourceStandaloneMm
> + FILE_GUID = 3ddbebcc-9841-4ef8-87fa-305843c1922d
> + MODULE_TYPE = MM_STANDALONE
> + VERSION_STRING = 1.0
> + PI_SPECIFICATION_VERSION = 0x00010032
> + ENTRY_POINT = StandaloneMmHestErrorSourceInitialize
> +
> +[Sources]
> + HestErrorSourceStandaloneMm.c
> +
> +[Packages]
> + ArmPkg/ArmPkg.dec
> + ArmPlatformPkg/ArmPlatformPkg.dec
> + MdeModulePkg/MdeModulePkg.dec
> + MdePkg/MdePkg.dec
> + StandaloneMmPkg/StandaloneMmPkg.dec
> +
> +[LibraryClasses]
> + ArmLib
> + ArmSvcLib
> + BaseMemoryLib
> + DebugLib
> + MemoryAllocationLib
> + StandaloneMmDriverEntryPoint
> +
> +[Protocols]
> + gMmHestErrorSourceDescProtocolGuid
> +
> +[Guids]
> + gMmHestGetErrorSourceInfoGuid ##PRODUCES
> + gEfiStandaloneMmNonSecureBufferGuid
> +
> +[FixedPcd]
> + gArmPlatformTokenSpaceGuid.PcdGhesGenericErrorDataMmBufferBase
> + gArmPlatformTokenSpaceGuid.PcdGhesGenericErrorDataMmBufferSize
> +
> +[Depex]
> + TRUE
> diff --git a/ArmPlatformPkg/Drivers/HestMmErrorSources/HestMmErrorSourceCommon.h b/ArmPlatformPkg/Drivers/HestMmErrorSources/HestMmErrorSourceCommon.h
> new file mode 100644
> index 000000000000..6ddc6bd21922
> --- /dev/null
> +++ b/ArmPlatformPkg/Drivers/HestMmErrorSources/HestMmErrorSourceCommon.h
> @@ -0,0 +1,37 @@
> +/** @file
> + Data structures for error source descriptor information.
> +
> + This data structure forms the CommBuffer part of the MM Communication
> + protocol used for communicating the Hardware Error sources form MM to
> + Non-MM environment.
> +
> + Copyright (c) 2020 - 2021, ARM Limited. All rights reserved.
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef HEST_ERROR_SOURCE_DESCRIPTOR_H_
> +#define HEST_ERROR_SOURCE_DESCRIPTOR_H_
> +
> +#define HEST_ERROR_SOURCE_DESC_INFO_SIZE \
> + (OFFSET_OF (HEST_ERROR_SOURCE_DESC_INFO, ErrSourceDescList))
[SAMI] I feel there can be a simple way to do this, see the comments below.
> +
> +//
> +// Data Structure to communicate the error source descriptor information from
> +// Standalone MM.
> +//
> +typedef struct {
> + //
> + // Total count of error source descriptors.
> + //
> + UINTN ErrSourceDescCount;
> + //
> + // Total size of all the error source descriptors.
> + //
[SAMI] Does the Total size also include the size of ErrSourceDescCount
and ErrSourceDescSize?
> + UINTN ErrSourceDescSize;
[SAMI] Can the first 2 fields of this structure be moved to a structure
called HEST_ERROR_SOURCE_DESC_HEADER? I think it may simplify computing
of the size of HEST_ERROR_SOURCE_DESC_INFO.
[/SAMI]
> + //
> + // Array of error source descriptors that is ErrSourceDescSize in size.
> + //
> + UINT8 ErrSourceDescList[1];
> +} HEST_ERROR_SOURCE_DESC_INFO;
> +
> +#endif // HEST_ERROR_SOURCE_DESCRIPTOR_H_
> diff --git a/ArmPlatformPkg/Drivers/HestMmErrorSources/HestErrorSourceDxe.c b/ArmPlatformPkg/Drivers/HestMmErrorSources/HestErrorSourceDxe.c
> new file mode 100644
> index 000000000000..acfb0fc9e838
> --- /dev/null
> +++ b/ArmPlatformPkg/Drivers/HestMmErrorSources/HestErrorSourceDxe.c
> @@ -0,0 +1,308 @@
> +/** @file
> + Collects and appends the HEST error source descriptors from the MM drivers.
> +
> + The drivers entry point locates the MM Communication protocol and calls into
> + Standalone MM to get the HEST error sources length and count. It also
> + retrieves descriptor information. The information is then used to build the
> + HEST table using the HEST table generation protocol.
> +
> + This driver collects the secure error source descriptor information from the
> + MM drviers that implement HEST error source protocol. Instead of directly
> + communicating with the individual MM drivers, it calls into
> + HestErrorSourceStandaloneMM driver which is a gatway MM driver. This MM driver
> + in-turn communicates with individual MM drivers collecting the error source
> + descriptor information.
> +
> + Once all the error source descriptor information is retrieved the driver
> + appends the descriptors to HEST table using the HestDxe driver.
> +
> + Copyright (c) 2020 - 2021, ARM Limited. All rights reserved.
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <IndustryStandard/Acpi.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DxeServicesTableLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Protocol/MmCommunication2.h>
> +#include <Protocol/HestTable.h>
> +#include "HestMmErrorSourceCommon.h"
> +
> +#define MM_COMMUNICATE_HEADER_SIZE (OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data))
[SAMI] Can this definition be moved to
MdePkg\Include\Protocol\MmCommunication.h, please ?
> +
> +STATIC HEST_TABLE_PROTOCOL *mHestProtocol;
> +STATIC EFI_MM_COMMUNICATION2_PROTOCOL *mMmCommunication2;
> +
> +/**
> + Retrieve the error source descriptors from Standalone MM.
> +
> + Initialize the MM comminication buffer by assigning the MM service to
> + invoke as gMmHestGetErrorSourceInfoGuid. Use the MM communication
> + protocol to retrieve the error source descriptors.
> +
> + @param[in] CommBuffSize Size of communicate buffer.
> + @param[in, out] CommBuffer The communicate buffer.
> +
> + @retval EFI_SUCCESS MM Communicate protocol call successful.
> + @retval Other MM Communicate protocol call failed.
> +**/
> +STATIC
> +EFI_STATUS
> +GetErrorSourceDescriptors (
> + IN UINTN CommBuffSize,
> + IN OUT EFI_MM_COMMUNICATE_HEADER **CommBuffer
> + )
> +{
> + EFI_STATUS Status;
> +
> + //
> + // Initialize the CommBuffer with MM Communicate metadata.
> + //
> + CopyGuid (&(*CommBuffer)->HeaderGuid, &gMmHestGetErrorSourceInfoGuid);
> + (*CommBuffer)->MessageLength =
> + CommBuffSize -
> + sizeof ((*CommBuffer)->HeaderGuid) -
> + sizeof ((*CommBuffer)->MessageLength);
> +
> + //
> + // Call into the Standalone MM using the MM Communicate protocol.
> + //
> + Status = mMmCommunication2->Communicate (
> + mMmCommunication2,
> + (VOID *)*CommBuffer,
> + (VOID *)*CommBuffer,
[SAMI] Can you check if the third parameter to Communicate() is correct,
please?
> + NULL
> + );
> +
> + return Status;
> +}
> +
> +/**
> + Collect HEST error source descriptors from all Standalone MM drivers and
> + append them to the HEST table.
> +
> + Use MM Communication Protocol to communicate and collect the error source
> + descriptor information from Standalone MM. Check for the required buffer size
> + returned by the MM driver. Allocate buffer of adequate size and call again
> + into MM.
> +
> + @retval EFI_SUCCESS Successful to collect and append the error
> + source.
> + descriptors to HEST table.
> + @retval EFI_OUT_OF_RESOURCES Memory allocation failure.
> + @retval Other For any other error.
> +**/
> +STATIC
> +EFI_STATUS
> +AppendMmErrorSources (VOID)
[SAMI] VOID and ) should be on a separate line. Can you check the other
patches in this series as well, please?
> +{
> + EFI_MM_COMMUNICATE_HEADER *CommunicationHeader = NULL;
> + HEST_ERROR_SOURCE_DESC_INFO *ErrorSourceDescInfo;
> + EFI_STATUS Status;
> + UINTN CommBufferSize;
> +
> + //
> + // Retrieve the count, length and the actual eror source descriptors from
> + // the MM drivers. Do this by performing two MM Communicate calls, in the
> + // first call pass CommBuffer which is atleast of the size of error source
> + // descriptor info structure. Followed by another communicate call with
> + // CommBuffer allocated to required buffer size to hold all descriptors.
> + //
> + // Allocate CommBuffer atleast the size of error source descriptor info
> + // structure.
> + CommBufferSize =
> + MM_COMMUNICATE_HEADER_SIZE + HEST_ERROR_SOURCE_DESC_INFO_SIZE;
> + CommunicationHeader = AllocatePool (CommBufferSize);
[SAMI] Would it be better to use AllocateZeroPool() ?
> + if (CommunicationHeader == NULL) {
> + DEBUG ((
> + DEBUG_ERROR,
> + "%a: Failed to allocate memory for CommunicationHeader\n",
> + __FUNCTION__
> + ));
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + //
> + // Make the first MM Communicate call to HestErrorSourceStandaloneMM gateway
> + // driver, which returns the required buffer size adequate to hold all the
> + // desctriptor information.
> + //
> + Status = GetErrorSourceDescriptors (CommBufferSize, &CommunicationHeader);
> + if ((EFI_ERROR (Status)) &&
> + (Status != EFI_BAD_BUFFER_SIZE)) {
> + DEBUG ((
> + DEBUG_ERROR,
> + "%a: MM Communicate protocol call failed, status: %r\n",
> + __FUNCTION__,
> + Status
> + ));
> + FreePool (CommunicationHeader);
> + return Status;
> + }
> +
> + // Check for the length of Error Source descriptors.
> + ErrorSourceDescInfo =
> + (HEST_ERROR_SOURCE_DESC_INFO *)(CommunicationHeader->Data);
> + if ((ErrorSourceDescInfo->ErrSourceDescSize == 0) ||
> + (ErrorSourceDescInfo->ErrSourceDescCount == 0)) {
> + DEBUG ((
> + DEBUG_INFO,
> + "HesErrorSourceDxe: HEST error source(s) not found\n"
> + ));
> + FreePool (CommunicationHeader);
> + return EFI_SUCCESS;
[SAMI] return EFI_NOT_FOUND ?
> + }
> +
> + //
> + // Allocate CommBuffer of required size to accomodate all the error source
> + // descriptors. Required size of communication buffer =
> + // MM communicate metadata. + (error source desc info struct + error source
> + // descriptor size).
> + //
> + CommBufferSize =
> + MM_COMMUNICATE_HEADER_SIZE +
> + HEST_ERROR_SOURCE_DESC_INFO_SIZE +
> + ErrorSourceDescInfo->ErrSourceDescSize;
> +
> + // Free old MM Communicate buffer and allocate a new buffer of required size.
> + FreePool (CommunicationHeader);
> + CommunicationHeader = AllocatePool (CommBufferSize);
> + if (CommunicationHeader == NULL) {
> + DEBUG ((
> + DEBUG_ERROR,
> + "%a: Failed to allocate memory for CommunicationHeader\n",
> + __FUNCTION__
> + ));
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + //
> + // Make second MM Communicate call to HestErrorSourceStandaloneMM driver to
> + // get the error source descriptors from the MM drivers.
> + //
> + Status = GetErrorSourceDescriptors (CommBufferSize, &CommunicationHeader);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((
> + DEBUG_ERROR,
> + "%a: MM Communicate protocol failed, status: %r\n",
> + __FUNCTION__,
> + Status
> + ));
> + FreePool (CommunicationHeader);
> + return Status;
> + }
> +
> + //
> + // Retrieve the HEST error source descriptor information. Ensure that there
> + // is a valid list of error source descriptors.
> + //
> + ErrorSourceDescInfo =
> + (HEST_ERROR_SOURCE_DESC_INFO *)(CommunicationHeader->Data);
> + if (ErrorSourceDescInfo->ErrSourceDescList == NULL) {
> + DEBUG ((
> + DEBUG_INFO,
> + "HestErrorSourceDxe: Error source descriptor list is empty"
> + ));
> + FreePool (CommunicationHeader);
> + return EFI_SUCCESS;
[SAMI] Can EFI_NOT_FOUND be returned here?
> + }
> +
> + DEBUG ((
> + DEBUG_INFO,
> + "HestErrorSourceDxe: ErrorSources: TotalCount = %d TotalLength = %d \n",
> + ErrorSourceDescInfo->ErrSourceDescCount,
> + ErrorSourceDescInfo->ErrSourceDescSize
> + ));
> +
> + //
> + // Append the error source descriptors to HEST table using the HEST table
> + // generation protocol.
> + //
> + Status = mHestProtocol->AppendErrorSourceDescriptors (
> + ErrorSourceDescInfo->ErrSourceDescList,
> + ErrorSourceDescInfo->ErrSourceDescSize,
> + ErrorSourceDescInfo->ErrSourceDescCount
> + );
> + if (EFI_ERROR (Status)) {
> + DEBUG ((
> + DEBUG_ERROR,
> + "%a: Failed to append error source(s), status: %r\n",
> + __FUNCTION__,
> + Status
> + ));
> + }
> +
> + FreePool (CommunicationHeader);
> + return Status;
> +}
> +
> +/**
> + The Entry Point for HEST Error Source Dxe driver.
> +
> + Locates the HEST Table generation and MM Communication2 protocols. Using the
> + MM Communication2, the driver collects the Error Source Descriptor(s) from
> + Standalone MM. It then appends those Error Source Descriptor(s) to the Hest
> + table using the HEST Table generation protocol.
> +
> + @param[in] ImageHandle The firmware allocated handle for the Efi image.
> + @param[in] SystemTable A pointer to the Efi System Table.
> +
> + @retval EFI_SUCCESS The entry point is executed successfully.
> + @retval Other Some error occurred when executing this entry point.
> +**/
> +EFI_STATUS
> +EFIAPI
> +HestErrorSourceInitialize (
> + IN EFI_HANDLE ImageHandle,
> + IN EFI_SYSTEM_TABLE *SystemTable
> + )
> +{
> + EFI_STATUS Status;
> +
> + Status = gBS->LocateProtocol (
> + &gHestTableProtocolGuid,
> + NULL,
> + (VOID **)&mHestProtocol
> + );
> + if (EFI_ERROR (Status)) {
> + DEBUG ((
> + DEBUG_ERROR,
> + "%a: Failed to locate HEST table generation protocol, status:%r\n",
> + __FUNCTION__,
> + Status
> + ));
> + return Status;
> + }
> +
> + Status = gBS->LocateProtocol (
> + &gEfiMmCommunication2ProtocolGuid,
> + NULL,
> + (VOID **)&mMmCommunication2
> + );
> + if (EFI_ERROR (Status)) {
> + DEBUG ((
> + DEBUG_ERROR,
> + "%a: Failed to locate MMCommunication2 driver protocol, status:%r\n",
> + __FUNCTION__,
> + Status
> + ));
> + return Status;
> + }
> +
> + //
> + // Append HEST error sources retrieved from StandaloneMM, if any, into the
> + // HEST ACPI table.
> + //
> + Status = AppendMmErrorSources ();
> + if (EFI_ERROR (Status)) {
> + DEBUG ((
> + DEBUG_ERROR,
> + "%a: Failed appending error source desc to HEST table, status:%r\n",
> + __FUNCTION__,
> + Status
> + ));
> + }
> + return EFI_SUCCESS;
> +}
> diff --git a/ArmPlatformPkg/Drivers/HestMmErrorSources/HestErrorSourceStandaloneMm.c b/ArmPlatformPkg/Drivers/HestMmErrorSources/HestErrorSourceStandaloneMm.c
> new file mode 100644
> index 000000000000..c7b2304fc494
> --- /dev/null
> +++ b/ArmPlatformPkg/Drivers/HestMmErrorSources/HestErrorSourceStandaloneMm.c
> @@ -0,0 +1,312 @@
> +/** @file
> + MM HEST error source gateway driver.
> +
> + This MM driver installs a handler which can be used to retrieve the error
> + source descriptors from the all MM drivers implementing the HEST error source
> + descriptor protocol.
> +
> + The MM driver acts as a single point of contact to collect secure hardware
> + error sources from the MM drivers. It loops over all the MM drivers that
> + implement HEST error source descriptor protocol and collects error source
> + descriptor information along with the error source count and length.
> +
> + Copyright (c) 2020 - 2021, ARM Limited. All rights reserved.
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Base.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Protocol/HestErrorSourceInfo.h>
> +
> +#include "HestMmErrorSourceCommon.h"
> +
> +STATIC EFI_MM_SYSTEM_TABLE *mMmst = NULL;
> +
> +/**
> + Returns an array of handles that implement the HEST error source descriptor
> + protocol.
> +
> + Passing HandleBuffer as NULL will return the actual size of the buffer
> + required to hold the array of handles implementing the protocol.
> +
> + @param[in, out] HandleBufferSize The size of the HandleBuffer.
> + @param[out] HandleBuffer A pointer to the buffer containing the list
> + of handles.
> +
> + @retval EFI_SUCCESS The array of handles returned in HandleBuffer.
> + @retval EFI_NOT_FOUND No implementation present for the protocol.
> + @retval Other For any other error.
> +**/
> +STATIC
> +EFI_STATUS
> +GetHestErrorSourceProtocolHandles (
> + IN OUT UINTN *HandleBufferSize,
> + OUT EFI_HANDLE **HandleBuffer
> + )
> +{
> + EFI_STATUS Status;
> +
> + Status = mMmst->MmLocateHandle (
> + ByProtocol,
> + &gMmHestErrorSourceDescProtocolGuid,
> + NULL,
> + HandleBufferSize,
> + *HandleBuffer
> + );
> + if ((EFI_ERROR (Status)) &&
> + (Status != EFI_BUFFER_TOO_SMALL))
> + {
> + DEBUG ((
> + DEBUG_ERROR,
> + "%a: No implementation of MmHestErrorSourceDescProtocol found, \
> + Status:%r\n",
> + __FUNCTION__,
> + Status
> + ));
> + return EFI_NOT_FOUND;
> + }
> +
> + return Status;
> +}
> +
> +/**
> + Mmi handler to retrieve HEST error source descriptor information.
> +
> + Handler for Mmi service that returns the supported HEST error source
> + descriptors in MM. This handler populates the CommBuffer with the
> + list of all error source descriptors, prepended with the length and
> + the number of descriptors populated into CommBuffer.
> +
> + @param[in] DispatchHandle The unique handle assigned to this handler by
> + MmiHandlerRegister().
> + @param[in] Context Points to an optional handler context that
> + is specified when the handler was registered.
> + @param[in, out] CommBuffer Buffer used for communication of HEST error
> + source descriptors.
> + @param[in, out] CommBufferSize The size of the CommBuffer.
> +
> + @retval EFI_SUCCESS CommBuffer has valid data.
> + @retval EFI_BAD_BUFFER_SIZE CommBufferSize not adequate.
> + @retval EFI_OUT_OF_RESOURCES System out of memory resources.
> + @retval EFI_INVALID_PARAMETER Invalid CommBufferSize recieved.
> + @retval Other For any other error.
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +HestErrorSourcesInfoMmiHandler (
> + IN EFI_HANDLE DispatchHandle,
> + IN CONST VOID *Context, OPTIONAL
> + IN OUT VOID *CommBuffer, OPTIONAL
> + IN OUT UINTN *CommBufferSize OPTIONAL
> + )
> +{
> + MM_HEST_ERROR_SOURCE_DESC_PROTOCOL *HestErrSourceDescProtocolHandle;
> + HEST_ERROR_SOURCE_DESC_INFO *ErrorSourceInfoList;
> + EFI_HANDLE *HandleBuffer;
> + EFI_STATUS Status;
> + UINTN HandleCount;
> + UINTN HandleBufferSize;
> + UINTN Index;
> + UINTN SourceCount = 0;
> + UINTN SourceLength = 0;
> + VOID *ErrorSourcePtr;
> + UINTN TotalSourceLength = 0;
> + UINTN TotalSourceCount = 0;
> +
> + if (*CommBufferSize < HEST_ERROR_SOURCE_DESC_INFO_SIZE) {
> + //
> + // Ensures that the communication buffer has enough space to atleast hold
> + // the ErrSourceDescCount and ErrSourceDescSize elements of the
> + // HEST_ERROR_SOURCE_DESC_INFO structure.
> + //
> + DEBUG ((
> + DEBUG_ERROR,
> + "%a: Invalid CommBufferSize parameter\n",
> + __FUNCTION__
> + ));
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + //
> + // Get all handles that implement the HEST error source descriptor protocol.
> + // Get the buffer size required to store list of handles for the protocol.
> + //
> + HandleBuffer = NULL;
> + HandleBufferSize = 0;
> + Status = GetHestErrorSourceProtocolHandles (&HandleBufferSize, &HandleBuffer);
> + if ((Status == EFI_NOT_FOUND) ||
> + (HandleBufferSize == 0))
> + {
> + return Status;
> + }
> +
> + // Allocate memory for HandleBuffer of size HandleBufferSize.
> + HandleBuffer = AllocatePool (HandleBufferSize);
[SAMI] AllocateZeroPool() ?
> + if (HandleBuffer == NULL) {
> + DEBUG ((
> + DEBUG_ERROR,
> + "%a: Failed to allocate memory for HandleBuffer\n",
> + __FUNCTION__
> + ));
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + // Get the list of handles.
> + Status = GetHestErrorSourceProtocolHandles (&HandleBufferSize, &HandleBuffer);
> + if ((EFI_ERROR (Status)) ||
> + (HandleBuffer == NULL))
[SAMI] Is check for HandleBuffer == NULL right here?
> + {
> + FreePool (HandleBuffer);
> + return Status;
> + }
> +
> + // Count of handles for the protocol.
> + HandleCount = HandleBufferSize / sizeof (EFI_HANDLE);
> +
> + //
> + // Loop to get the count and length of the error source descriptors.
> + //
> + // This loop collects and adds the length of error source descriptors and
> + // its count from all the the MM drivers implementing HEST error source.
> + // descriptor protocol. The total length and count values retrieved help
> + // to determine weather the CommBuffer is big enough to hold the descriptor
> + // information.
> + // As mentioned in the HEST error source descriptor protocol definition,
> + // Buffer parameter set to NULL ensures only length and the count values
> + // are returned from the driver and no error source information is copied to
> + // Buffer.
> + //
> + for (Index = 0; Index < HandleCount; ++Index) {
> + Status = mMmst->MmHandleProtocol (
> + HandleBuffer[Index],
> + &gMmHestErrorSourceDescProtocolGuid,
> + (VOID **)&HestErrSourceDescProtocolHandle
> + );
> + if (EFI_ERROR (Status)) {
> + continue;
> + }
> +
> + //
> + // Protocol called with Buffer parameter passed as NULL, must return
> + // error source length and error count for that driver.
> + //
> + Status = HestErrSourceDescProtocolHandle->GetHestErrorSourceDescriptors (
> + HestErrSourceDescProtocolHandle,
> + NULL,
> + &SourceLength,
> + &SourceCount
> + );
> + if (Status == EFI_INVALID_PARAMETER) {
[SAMI] I think the error handling in this function and the error return
implementation in GetHestErrorSourceDescriptors() could be improved.
e.g. GetHestErrorSourceDescriptors() could first check for the
SourceLength & SourceCount and if it is less than what is required, it
returns EFI_BUFFER_TOO_SMALL.
The next check would be to check ErrorSourcePtr and return
EFI_INVALID_PARAMETER if it is NULL.
[/SAMI]
> + TotalSourceLength += SourceLength;
> + TotalSourceCount += SourceCount;
> + }
> + }
> +
> + // Set the count and length in the error source descriptor.
> + ErrorSourceInfoList = (HEST_ERROR_SOURCE_DESC_INFO *)(CommBuffer);
> + ErrorSourceInfoList->ErrSourceDescCount = TotalSourceCount;
> + ErrorSourceInfoList->ErrSourceDescSize = TotalSourceLength;
> +
> + //
> + // Check the size of CommBuffer, it should atleast be of size
> + // TotalSourceLength + HEST_ERROR_SOURCE_DESC_INFO_SIZE.
> + //
> + TotalSourceLength = TotalSourceLength + HEST_ERROR_SOURCE_DESC_INFO_SIZE;
> + if ((*CommBufferSize) < TotalSourceLength) {
> + DEBUG ((
> + DEBUG_ERROR,
> + "%a: Invalid CommBufferSize parameter\n",
> + __FUNCTION__
> + ));
> + FreePool (HandleBuffer);
> + return EFI_BAD_BUFFER_SIZE;
[SAMI] Should the return code be EFI_BUFFER_TOO_SMALL? The difference
being, the caller can attempt to call again with a larger buffer if
EFI_BUFFER_TOO_SMALL is returned.
CommBufferSize is declared as an OUT paramter, was the intent to return
the required buffer size?
[/SAMI]
> + }
> +
> + //
> + // CommBuffer size is adequate to return all the error source descriptors.
> + // So go ahead and populate it with the error source descriptor information.
> + //
> +
> + // Buffer pointer to append the Error Descriptors data.
> + ErrorSourcePtr = ErrorSourceInfoList->ErrSourceDescList;
> +
> + //
> + // Loop to retrieve error source descriptors information.
> + //
> + // Calls into each MM driver that implement the HEST error source descriptor
> + // protocol. Here the Buffer parameter passed to the protocol service is
> + // valid. So the MM driver when called copies the descriptor information.
> + //
> + for (Index = 0; Index < HandleCount; ++Index) {
> + Status = mMmst->MmHandleProtocol (
> + HandleBuffer[Index],
> + &gMmHestErrorSourceDescProtocolGuid,
> + (VOID **)&HestErrSourceDescProtocolHandle
> + );
> + if (EFI_ERROR (Status)) {
> + continue;
> + }
> +
> + Status = HestErrSourceDescProtocolHandle->GetHestErrorSourceDescriptors (
> + HestErrSourceDescProtocolHandle,
> + (VOID **)&ErrorSourcePtr,
> + &SourceLength,
> + &SourceCount
> + );
> + if (Status == EFI_SUCCESS) {
> + ErrorSourcePtr += SourceLength;
> + }
> + }
> +
> + // Free the buffer holding all the protocol handles.
> + FreePool (HandleBuffer);
> +
> + return EFI_SUCCESS;
[SAMI] return Status of last operation.
> +}
> +
> +/**
> + Entry point for this Stanalone MM driver.
> +
> + Registers an Mmi handler that retrieves the error source descriptors from all
> + the MM drivers implementing the MM_HEST_ERROR_SOURCE_DESC_PROTOCOL.
> +
> + @param[in] ImageHandle The firmware allocated handle for the EFI image.
> + @param[in] SystemTable A pointer to the EFI System Table.
> +
> + @retval EFI_SUCCESS The entry point registered handler successfully.
> + @retval Other Some error occurred when executing this entry point.
> +**/
> +EFI_STATUS
> +EFIAPI
> +StandaloneMmHestErrorSourceInitialize (
> + IN EFI_HANDLE ImageHandle,
> + IN EFI_MM_SYSTEM_TABLE *SystemTable
> + )
> +{
> + EFI_HANDLE DispatchHandle;
> + EFI_STATUS Status;
> +
> + ASSERT (SystemTable != NULL);
> + mMmst = SystemTable;
> +
> + Status = mMmst->MmiHandlerRegister (
> + HestErrorSourcesInfoMmiHandler,
> + &gMmHestGetErrorSourceInfoGuid,
> + &DispatchHandle
> + );
> + if (EFI_ERROR(Status)) {
> + DEBUG ((
> + DEBUG_ERROR,
> + "%a: Mmi handler registration failed with status : %r\n",
> + __FUNCTION__,
> + Status
> + ));
> + return Status;
> + }
> +
> + return EFI_SUCCESS;
[SAMI] return Status of last operation.
> +}
[-- Attachment #2: Type: text/html, Size: 34142 bytes --]
next prev parent reply other threads:[~2021-08-03 14:46 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-07-10 16:18 [PATCH v2 0/4] ArmPlatformPkg: Add support to generate HEST ACPI table Omkar Anand Kulkarni
2021-07-10 16:18 ` [PATCH v2 1/4] ArmPlatformPkg: Allow dynamic generation of " Omkar Anand Kulkarni
2021-08-02 12:50 ` Sami Mujawar
2021-08-24 5:22 ` Omkar Anand Kulkarni
2021-07-10 16:18 ` [PATCH v2 2/4] ArmPlatformPkg: add definition for MM_HEST_ERROR_SOURCE_DESC_PROTOCOL Omkar Anand Kulkarni
2021-08-03 14:45 ` Sami Mujawar
2021-08-24 5:23 ` Omkar Anand Kulkarni
2021-07-10 16:18 ` [PATCH v2 3/4] ArmPlatformPkg: retreive error source descriptors from MM Omkar Anand Kulkarni
2021-08-03 14:46 ` Sami Mujawar [this message]
2021-08-24 5:29 ` Omkar Anand Kulkarni
2021-07-10 16:18 ` [PATCH v2 4/4] ArmPlatformPkg: Add helpers for HEST table generation Omkar Anand Kulkarni
2021-08-03 15:09 ` Sami Mujawar
2021-08-24 5:30 ` Omkar Anand Kulkarni
2021-08-02 12:49 ` [PATCH v2 0/4] ArmPlatformPkg: Add support to generate HEST ACPI table Sami Mujawar
2021-08-03 15:14 ` Sami Mujawar
2021-08-24 5:19 ` Omkar Anand Kulkarni
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=38e5bdd4-17e2-a8de-193c-be98c2166220@arm.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox