From: "gaoliming" <gaoliming@byosoft.com.cn>
To: <devel@edk2.groups.io>, <kuqin12@gmail.com>
Cc: "'Hao A Wu'" <hao.a.wu@intel.com>,
"'Jian J Wang'" <jian.j.wang@intel.com>,
"'Ronny Hansen'" <hansen.ronny@microsoft.com>,
"'Shriram Masanamuthu Chinnathurai'" <shriramma@microsoft.com>,
"'Preshit Harlikar'" <pharlikar@microsoft.com>
Subject: 回复: 回复: [edk2-devel] [PATCH v1 2/2] MdeModulePkg: Variable: Introduce MM based variable read service in PEI
Date: Tue, 27 Jun 2023 08:53:38 +0800 [thread overview]
Message-ID: <00e701d9a891$cf6cab30$6e460190$@byosoft.com.cn> (raw)
In-Reply-To: <e77b778c-050c-c9bc-e2d3-442ccacdb69a@gmail.com>
Kun:
Thanks for your update. I have no other comments for this patch. Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn>
Thanks
Liming
> -----邮件原件-----
> 发件人: devel@edk2.groups.io <devel@edk2.groups.io> 代表 Kun Qin
> 发送时间: 2023年6月27日 4:11
> 收件人: devel@edk2.groups.io; gaoliming@byosoft.com.cn
> 抄送: 'Hao A Wu' <hao.a.wu@intel.com>; 'Jian J Wang'
> <jian.j.wang@intel.com>; 'Ronny Hansen' <hansen.ronny@microsoft.com>;
> 'Shriram Masanamuthu Chinnathurai' <shriramma@microsoft.com>; 'Preshit
> Harlikar' <pharlikar@microsoft.com>
> 主题: Re: 回复: [edk2-devel] [PATCH v1 2/2] MdeModulePkg: Variable:
> Introduce MM based variable read service in PEI
>
> Hi Liming,
>
> Thanks for catching that. I have removed the PCD usage and resend the
> patch here:
> https://edk2.groups.io/g/devel/message/106372
>
> Could you please let me know if you have any other feedback?
>
> Per your functionality question, yes, the functionality was verified on
> both virtual
> and physical ARM platforms. I also added this statement to the v2 cover
> letter.
>
> Thanks,
> Kun
>
> On 6/24/2023 7:23 PM, gaoliming via groups.io wrote:
> > Kun:
> > Seemly, PcdMaxVariableSize is not used by this module. It can be
> removed.
> >
> > And, has its functionality been verified in the real platform?
> >
> > Thanks
> > Liming
> >> -----邮件原件-----
> >> 发件人: devel@edk2.groups.io <devel@edk2.groups.io> 代表 Kun Qin
> >> 发送时间: 2023年6月9日 4:45
> >> 收件人: devel@edk2.groups.io
> >> 抄送: Hao A Wu <hao.a.wu@intel.com>; Liming Gao
> >> <gaoliming@byosoft.com.cn>; Jian J Wang <jian.j.wang@intel.com>;
> Ronny
> >> Hansen <hansen.ronny@microsoft.com>; Shriram Masanamuthu
> >> Chinnathurai <shriramma@microsoft.com>; Preshit Harlikar
> >> <pharlikar@microsoft.com>
> >> 主题: [edk2-devel] [PATCH v1 2/2] MdeModulePkg: Variable: Introduce
> MM
> >> based variable read service in PEI
> >>
> >> From: Kun Qin <kuqin@microsoft.com>
> >>
> >> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4464
> >>
> >> This change introduced the Standalone MM based variable read capability
> >> in PEI phase for applicable platforms (such as ARM platforms).
> >>
> >> Similar to the x86 counterpart, MM communicate PPI is used to request
> >> variable information from Standalone MM environment.
> >>
> >> Cc: Hao A Wu <hao.a.wu@intel.com>
> >> Cc: Liming Gao <gaoliming@byosoft.com.cn>
> >> Cc: Jian J Wang <jian.j.wang@intel.com>
> >>
> >> Co-authored-by: Ronny Hansen <hansen.ronny@microsoft.com>
> >> Co-authored-by: Shriram Masanamuthu Chinnathurai
> >> <shriramma@microsoft.com>
> >> Co-authored-by: Preshit Harlikar <pharlikar@microsoft.com>
> >> Signed-off-by: Kun Qin <kuqin@microsoft.com>
> >> ---
> >> MdeModulePkg/Universal/Variable/MmVariablePei/MmVariablePei.c
> |
> >> 381 ++++++++++++++++++++
> >> MdeModulePkg/MdeModulePkg.dsc
> >> | 1 +
> >> MdeModulePkg/Universal/Variable/MmVariablePei/MmVariablePei.h
> |
> >> 134 +++++++
> >> MdeModulePkg/Universal/Variable/MmVariablePei/MmVariablePei.inf
> |
> >> 43 +++
> >> 4 files changed, 559 insertions(+)
> >>
> >> diff --git
> >> a/MdeModulePkg/Universal/Variable/MmVariablePei/MmVariablePei.c
> >> b/MdeModulePkg/Universal/Variable/MmVariablePei/MmVariablePei.c
> >> new file mode 100644
> >> index 000000000000..4f937e22e89e
> >> --- /dev/null
> >> +++
> b/MdeModulePkg/Universal/Variable/MmVariablePei/MmVariablePei.c
> >> @@ -0,0 +1,381 @@
> >> +/** @file -- MmVariablePei.c
> >>
> >> + Provides interface for reading Secure System Variables during PEI.
> >>
> >> +
> >>
> >> + Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
> >>
> >> + Copyright (c) Microsoft Corporation.<BR>
> >>
> >> + SPDX-License-Identifier: BSD-2-Clause-Patent
> >>
> >> +**/
> >>
> >> +
> >>
> >> +#include "MmVariablePei.h"
> >>
> >> +
> >>
> >> +#define MM_VARIABLE_COMM_BUFFER_OFFSET
> >> (SMM_COMMUNICATE_HEADER_SIZE +
> >> SMM_VARIABLE_COMMUNICATE_HEADER_SIZE)
> >>
> >> +
> >>
> >> +//
> >>
> >> +// Module globals
> >>
> >> +//
> >>
> >> +EFI_PEI_READ_ONLY_VARIABLE2_PPI mPeiSecureVariableRead = {
> >>
> >> + PeiMmGetVariable,
> >>
> >> + PeiMmGetNextVariableName
> >>
> >> +};
> >>
> >> +
> >>
> >> +EFI_PEI_PPI_DESCRIPTOR mPeiMmVariablePpi = {
> >>
> >> + (EFI_PEI_PPI_DESCRIPTOR_PPI |
> >> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
> >>
> >> + &gEfiPeiReadOnlyVariable2PpiGuid,
> >>
> >> + &mPeiSecureVariableRead
> >>
> >> +};
> >>
> >> +
> >>
> >> +/**
> >>
> >> + Entry point of PEI Secure Variable read driver
> >>
> >> +
> >>
> >> + @param FileHandle Handle of the file being invoked.
> >>
> >> + Type EFI_PEI_FILE_HANDLE is defined in
> >> FfsFindNextFile().
> >>
> >> + @param PeiServices General purpose services available to every
> >> PEIM.
> >>
> >> +
> >>
> >> + @retval EFI_SUCCESS If the interface could be successfully installed
> >>
> >> + @retval Others Returned from PeiServicesInstallPpi()
> >>
> >> +**/
> >>
> >> +EFI_STATUS
> >>
> >> +EFIAPI
> >>
> >> +PeiMmVariableInitialize (
> >>
> >> + IN EFI_PEI_FILE_HANDLE FileHandle,
> >>
> >> + IN CONST EFI_PEI_SERVICES **PeiServices
> >>
> >> + )
> >>
> >> +{
> >>
> >> + return PeiServicesInstallPpi (&mPeiMmVariablePpi);
> >>
> >> +}
> >>
> >> +
> >>
> >> +/**
> >>
> >> + Helper function to populate MM communicate header and variable
> >> communicate header
> >>
> >> + and then communicate to PEI.
> >>
> >> +
> >>
> >> + @param[in, out] CommunicateBuffer Size of the variable
> name.
> >>
> >> + @param[in] CommunicateBufferSize The entire buffer size to
> be
> >> sent to MM.
> >>
> >> + @param[in] Function The MM variable
> function
> >> value.
> >>
> >> +
> >>
> >> + @retval EFI_INVALID_PARAMETER Invalid parameter.
> >>
> >> + @retval EFI_SUCCESS Find the specified variable.
> >>
> >> + @retval Others Errors returned by MM
> >> communicate or variable service.
> >>
> >> +
> >>
> >> +**/
> >>
> >> +EFI_STATUS
> >>
> >> +PopulateHeaderAndCommunicate (
> >>
> >> + IN OUT UINT8 *CommunicateBuffer,
> >>
> >> + IN UINTN CommunicateBufferSize,
> >>
> >> + IN UINTN Function
> >>
> >> + )
> >>
> >> +{
> >>
> >> + EFI_STATUS Status;
> >>
> >> + EFI_PEI_MM_COMMUNICATION_PPI *MmCommunicationPpi;
> >>
> >> + EFI_MM_COMMUNICATE_HEADER
> *MmCommunicateHeader;
> >>
> >> + SMM_VARIABLE_COMMUNICATE_HEADER *MmVarCommsHeader;
> >>
> >> +
> >>
> >> + // Minimal sanity check
> >>
> >> + if ((CommunicateBuffer == NULL) ||
> >>
> >> + (CommunicateBufferSize <
> >> MM_VARIABLE_COMM_BUFFER_OFFSET))
> >>
> >> + {
> >>
> >> + Status = EFI_INVALID_PARAMETER;
> >>
> >> + DEBUG ((DEBUG_ERROR, "%a: Invalid incoming parameters: %p and
> >> 0x%x\n", __func__, CommunicateBuffer, CommunicateBufferSize));
> >>
> >> + goto Exit;
> >>
> >> + }
> >>
> >> +
> >>
> >> + if ((Function !=
> >> SMM_VARIABLE_FUNCTION_GET_NEXT_VARIABLE_NAME) &&
> >>
> >> + (Function != SMM_VARIABLE_FUNCTION_GET_VARIABLE))
> >>
> >> + {
> >>
> >> + Status = EFI_INVALID_PARAMETER;
> >>
> >> + DEBUG ((DEBUG_ERROR, "%a: Invalid function value: 0x%x\n",
> >> __func__, Function));
> >>
> >> + goto Exit;
> >>
> >> + }
> >>
> >> +
> >>
> >> + Status = PeiServicesLocatePpi (&gEfiPeiMmCommunicationPpiGuid, 0,
> >> NULL, (VOID **)&MmCommunicationPpi);
> >>
> >> + if (EFI_ERROR (Status)) {
> >>
> >> + DEBUG ((DEBUG_ERROR, "%a: Failed to locate PEI MM
> Communication
> >> PPI: %r\n", __func__, Status));
> >>
> >> + goto Exit;
> >>
> >> + }
> >>
> >> +
> >>
> >> + // Zero the entire Communication Buffer Header
> >>
> >> + MmCommunicateHeader = (EFI_MM_COMMUNICATE_HEADER
> >> *)CommunicateBuffer;
> >>
> >> +
> >>
> >> + ZeroMem (MmCommunicateHeader,
> >> SMM_COMMUNICATE_HEADER_SIZE);
> >>
> >> +
> >>
> >> + // Use gEfiSmmVariableProtocolGuid to request the MM variable
> service
> >> in Standalone MM
> >>
> >> + CopyMem ((VOID *)&MmCommunicateHeader->HeaderGuid,
> >> &gEfiSmmVariableProtocolGuid, sizeof (GUID));
> >>
> >> +
> >>
> >> + // Program the MM header size
> >>
> >> + MmCommunicateHeader->MessageLength = CommunicateBufferSize -
> >> SMM_COMMUNICATE_HEADER_SIZE;
> >>
> >> +
> >>
> >> + MmVarCommsHeader = (SMM_VARIABLE_COMMUNICATE_HEADER
> >> *)(CommunicateBuffer + SMM_COMMUNICATE_HEADER_SIZE);
> >>
> >> +
> >>
> >> + // We are only supporting GetVariable and GetNextVariableName
> >>
> >> + MmVarCommsHeader->Function = Function;
> >>
> >> +
> >>
> >> + // Send the MM request using MmCommunicationPei
> >>
> >> + Status = MmCommunicationPpi->Communicate
> (MmCommunicationPpi,
> >> CommunicateBuffer, &CommunicateBufferSize);
> >>
> >> + if (EFI_ERROR (Status)) {
> >>
> >> + // Received an error from MM interface.
> >>
> >> + DEBUG ((DEBUG_ERROR, "%a - MM Interface Error: %r\n",
> __func__,
> >> Status));
> >>
> >> + goto Exit;
> >>
> >> + }
> >>
> >> +
> >>
> >> + // MM request was successfully handled by the framework.
> >>
> >> + // Set status to the Variable Service Status Code
> >>
> >> + Status = MmVarCommsHeader->ReturnStatus;
> >>
> >> + if (EFI_ERROR (Status)) {
> >>
> >> + // We received an error from Variable Service.
> >>
> >> + // We cant do anymore so return Status
> >>
> >> + if (Status != EFI_BUFFER_TOO_SMALL) {
> >>
> >> + DEBUG ((DEBUG_ERROR, "%a - Variable Service Error: %r\n",
> >> __func__, Status));
> >>
> >> + }
> >>
> >> +
> >>
> >> + goto Exit;
> >>
> >> + }
> >>
> >> +
> >>
> >> +Exit:
> >>
> >> + return Status;
> >>
> >> +}
> >>
> >> +
> >>
> >> +/**
> >>
> >> + This service retrieves a variable's value using its name and GUID.
> >>
> >> +
> >>
> >> + This function is using the Secure Variable Store. If the Data
> >>
> >> + buffer is too small to hold the contents of the variable, the error
> >>
> >> + EFI_BUFFER_TOO_SMALL is returned and DataSize is set to the
> required
> >> buffer
> >>
> >> + size to obtain the data.
> >>
> >> +
> >>
> >> + @param This A pointer to this instance of the
> >> EFI_PEI_READ_ONLY_VARIABLE2_PPI.
> >>
> >> + @param VariableName A pointer to a null-terminated
> string
> >> that is the variable's name.
> >>
> >> + @param VariableGuid A pointer to an EFI_GUID that is
> the
> >> variable's GUID. The combination of
> >>
> >> + VariableGuid and VariableName
> >> must be unique.
> >>
> >> + @param Attributes If non-NULL, on return, points to
> the
> >> variable's attributes.
> >>
> >> + @param DataSize On entry, points to the size in
> bytes
> >> of the Data buffer.
> >>
> >> + On return, points to the size of
> the
> >> data returned in Data.
> >>
> >> + @param Data Points to the buffer which will
> hold
> >> the returned variable value.
> >>
> >> + May be NULL with a zero
> DataSize in
> >> order to determine the size of the buffer needed.
> >>
> >> +
> >>
> >> + @retval EFI_SUCCESS The variable was read successfully.
> >>
> >> + @retval EFI_NOT_FOUND The variable was not found.
> >>
> >> + @retval EFI_BUFFER_TOO_SMALL The DataSize is too small for the
> >> resulting data.
> >>
> >> + DataSize is updated with the size
> >> required for
> >>
> >> + the specified variable.
> >>
> >> + @retval EFI_INVALID_PARAMETER VariableName, VariableGuid,
> DataSize
> >> or Data is NULL.
> >>
> >> + @retval EFI_DEVICE_ERROR The variable could not be retrieved
> >> because of a device error.
> >>
> >> +
> >>
> >> +**/
> >>
> >> +EFI_STATUS
> >>
> >> +EFIAPI
> >>
> >> +PeiMmGetVariable (
> >>
> >> + IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI *This,
> >>
> >> + IN CONST CHAR16 *VariableName,
> >>
> >> + IN CONST EFI_GUID *VariableGuid,
> >>
> >> + OUT UINT32 *Attributes, OPTIONAL
> >>
> >> + IN OUT UINTN *DataSize,
> >>
> >> + OUT VOID *Data
> OPTIONAL
> >>
> >> + )
> >>
> >> +{
> >>
> >> + EFI_STATUS Status;
> >>
> >> + UINTN MessageSize;
> >>
> >> + SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE
> >> *MmVarAccessHeader;
> >>
> >> + UINT8
> >> *MmCommunicateBuffer;
> >>
> >> + UINTN RequiredPages;
> >>
> >> +
> >>
> >> + // Check input parameters
> >>
> >> + if ((VariableName == NULL) || (VariableGuid == NULL) || (DataSize ==
> >> NULL)) {
> >>
> >> + return EFI_INVALID_PARAMETER;
> >>
> >> + }
> >>
> >> +
> >>
> >> + if (VariableName[0] == 0) {
> >>
> >> + return EFI_NOT_FOUND;
> >>
> >> + }
> >>
> >> +
> >>
> >> + if ((*DataSize > 0) && (Data == NULL)) {
> >>
> >> + return EFI_INVALID_PARAMETER;
> >>
> >> + }
> >>
> >> +
> >>
> >> + // Allocate required pages to send MM request
> >>
> >> + MessageSize = MM_VARIABLE_COMM_BUFFER_OFFSET +
> >>
> >> + OFFSET_OF
> >> (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) +
> >>
> >> + StrSize (VariableName) + *DataSize;
> >>
> >> +
> >>
> >> + RequiredPages = EFI_SIZE_TO_PAGES (MessageSize);
> >>
> >> + MmCommunicateBuffer = (UINT8 *)AllocatePages (RequiredPages);
> >>
> >> +
> >>
> >> + if (MmCommunicateBuffer == NULL) {
> >>
> >> + Status = EFI_OUT_OF_RESOURCES;
> >>
> >> + DEBUG ((DEBUG_ERROR, "%a: Failed to allocate memory: %r\n",
> >> __func__, Status));
> >>
> >> + return Status;
> >>
> >> + }
> >>
> >> +
> >>
> >> + // Zero the entire Communication Buffer
> >>
> >> + ZeroMem (MmCommunicateBuffer, (RequiredPages * EFI_PAGE_SIZE));
> >>
> >> +
> >>
> >> + //
> >>
> >> + // Program all payload structure contents
> >>
> >> + //
> >>
> >> + MmVarAccessHeader =
> >> (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE
> >> *)(MmCommunicateBuffer + MM_VARIABLE_COMM_BUFFER_OFFSET);
> >>
> >> +
> >>
> >> + // Variable GUID
> >>
> >> + CopyMem ((VOID *)&MmVarAccessHeader->Guid, VariableGuid, sizeof
> >> (GUID));
> >>
> >> +
> >>
> >> + // Program the max amount of data we accept.
> >>
> >> + MmVarAccessHeader->DataSize = *DataSize;
> >>
> >> +
> >>
> >> + // Get size of the variable name
> >>
> >> + MmVarAccessHeader->NameSize = StrSize (VariableName);
> >>
> >> +
> >>
> >> + // Populate incoming variable name
> >>
> >> + CopyMem ((VOID *)&MmVarAccessHeader->Name, VariableName,
> >> MmVarAccessHeader->NameSize);
> >>
> >> +
> >>
> >> + Status = PopulateHeaderAndCommunicate (MmCommunicateBuffer,
> >> MessageSize, SMM_VARIABLE_FUNCTION_GET_VARIABLE);
> >>
> >> + if (EFI_ERROR (Status)) {
> >>
> >> + // We received an error from either communicate or Variable
> Service.
> >>
> >> + if (Status != EFI_BUFFER_TOO_SMALL) {
> >>
> >> + DEBUG ((DEBUG_ERROR, "%a - Communite to MM for variable
> >> service errored: %r\n", __func__, Status));
> >>
> >> + }
> >>
> >> +
> >>
> >> + goto Exit;
> >>
> >> + }
> >>
> >> +
> >>
> >> + Status = EFI_SUCCESS;
> >>
> >> +
> >>
> >> + // User provided buffer is too small
> >>
> >> + if (*DataSize < MmVarAccessHeader->DataSize) {
> >>
> >> + Status = EFI_BUFFER_TOO_SMALL;
> >>
> >> + }
> >>
> >> +
> >>
> >> +Exit:
> >>
> >> + // Check if we need to set Attributes
> >>
> >> + if (Attributes != NULL) {
> >>
> >> + *Attributes = MmVarAccessHeader->Attributes;
> >>
> >> + }
> >>
> >> +
> >>
> >> + *DataSize = MmVarAccessHeader->DataSize;
> >>
> >> +
> >>
> >> + if (Status == EFI_SUCCESS) {
> >>
> >> + CopyMem ((VOID *)Data, (UINT8 *)MmVarAccessHeader->Name +
> >> MmVarAccessHeader->NameSize, *DataSize);
> >>
> >> + }
> >>
> >> +
> >>
> >> + // Free the Communication Buffer
> >>
> >> + if (MmCommunicateBuffer != NULL) {
> >>
> >> + FreePages (MmCommunicateBuffer, RequiredPages);
> >>
> >> + }
> >>
> >> +
> >>
> >> + return Status;
> >>
> >> +}
> >>
> >> +
> >>
> >> +/**
> >>
> >> + Return the next variable name and GUID.
> >>
> >> +
> >>
> >> + This function is called multiple times to retrieve the VariableName
> >>
> >> + and VariableGuid of all variables currently available in the system.
> >>
> >> + On each call, the previous results are passed into the interface,
> >>
> >> + and, on return, the interface returns the data for the next
> >>
> >> + interface. When the entire variable list has been returned,
> >>
> >> + EFI_NOT_FOUND is returned.
> >>
> >> +
> >>
> >> + @param This A pointer to this instance of the
> >> EFI_PEI_READ_ONLY_VARIABLE2_PPI.
> >>
> >> +
> >>
> >> + @param VariableNameSize On entry, points to the size of the
> buffer
> >> pointed to by VariableName.
> >>
> >> + On return, the size of the variable
> name
> >> buffer.
> >>
> >> + @param VariableName On entry, a pointer to a
> null-terminated
> >> string that is the variable's name.
> >>
> >> + On return, points to the next variable's
> >> null-terminated name string.
> >>
> >> +
> >>
> >> + @param VariableGuid On entry, a pointer to an EFI_GUID that
> is
> >> the variable's GUID.
> >>
> >> + On return, a pointer to the next
> variable's
> >> GUID.
> >>
> >> +
> >>
> >> + @retval EFI_SUCCESS The variable was read successfully.
> >>
> >> + @retval EFI_NOT_FOUND The variable could not be found.
> >>
> >> + @retval EFI_BUFFER_TOO_SMALL The VariableNameSize is too
> small
> >> for the resulting
> >>
> >> + data. VariableNameSize is
> updated
> >> with the size
> >>
> >> + required for the specified
> variable.
> >>
> >> + @retval EFI_INVALID_PARAMETER VariableName, VariableGuid or
> >>
> >> + VariableNameSize is NULL.
> >>
> >> + @retval EFI_DEVICE_ERROR The variable could not be retrieved
> >> because of a device error.
> >>
> >> +**/
> >>
> >> +EFI_STATUS
> >>
> >> +EFIAPI
> >>
> >> +PeiMmGetNextVariableName (
> >>
> >> + IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI *This,
> >>
> >> + IN OUT UINTN
> *VariableNameSize,
> >>
> >> + IN OUT CHAR16 *VariableName,
> >>
> >> + IN OUT EFI_GUID *VariableGuid
> >>
> >> + )
> >>
> >> +{
> >>
> >> + EFI_STATUS Status;
> >>
> >> + UINTN
> >> MessageSize;
> >>
> >> + UINT8
> >> *MmCommunicateBuffer;
> >>
> >> + SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME
> >> *MmVarGetNextVarHeader;
> >>
> >> + UINTN
> >> RequiredPages;
> >>
> >> +
> >>
> >> + // Check input parameters
> >>
> >> + if ((VariableName == NULL) ||
> >>
> >> + (VariableGuid == NULL) ||
> >>
> >> + (VariableNameSize == NULL) ||
> >>
> >> + (*VariableNameSize == 0))
> >>
> >> + {
> >>
> >> + return EFI_INVALID_PARAMETER;
> >>
> >> + }
> >>
> >> +
> >>
> >> + // Allocate required pages to send MM request
> >>
> >> + MessageSize = MM_VARIABLE_COMM_BUFFER_OFFSET +
> >>
> >> + OFFSET_OF
> >> (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) +
> >>
> >> + StrSize (VariableName) + *VariableNameSize;
> >>
> >> +
> >>
> >> + RequiredPages = EFI_SIZE_TO_PAGES (MessageSize);
> >>
> >> + MmCommunicateBuffer = (UINT8 *)AllocatePages (RequiredPages);
> >>
> >> +
> >>
> >> + if (MmCommunicateBuffer == NULL) {
> >>
> >> + Status = EFI_OUT_OF_RESOURCES;
> >>
> >> + DEBUG ((DEBUG_ERROR, "%a: Failed to allocate memory: %r\n",
> >> __func__, Status));
> >>
> >> + return Status;
> >>
> >> + }
> >>
> >> +
> >>
> >> + // Zero the entire Communication Buffer
> >>
> >> + ZeroMem (MmCommunicateBuffer, (RequiredPages * EFI_PAGE_SIZE));
> >>
> >> +
> >>
> >> + //
> >>
> >> + // Program all payload structure contents
> >>
> >> + //
> >>
> >> + MmVarGetNextVarHeader =
> >> (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME
> >> *)(MmCommunicateBuffer + MM_VARIABLE_COMM_BUFFER_OFFSET);
> >>
> >> +
> >>
> >> + // Variable GUID
> >>
> >> + CopyMem ((VOID *)&MmVarGetNextVarHeader->Guid, VariableGuid,
> >> sizeof (GUID));
> >>
> >> +
> >>
> >> + // Program the maximal length of name we can accept.
> >>
> >> + MmVarGetNextVarHeader->NameSize = *VariableNameSize;
> >>
> >> +
> >>
> >> + // Populate incoming variable name
> >>
> >> + CopyMem ((VOID *)&MmVarGetNextVarHeader->Name,
> VariableName,
> >> MmVarGetNextVarHeader->NameSize);
> >>
> >> +
> >>
> >> + // Send the MM request using MmCommunicationPei
> >>
> >> + Status = PopulateHeaderAndCommunicate (MmCommunicateBuffer,
> >> MessageSize, SMM_VARIABLE_FUNCTION_GET_NEXT_VARIABLE_NAME);
> >>
> >> + if (EFI_ERROR (Status)) {
> >>
> >> + // We received an error from either communicate or Variable
> Service.
> >>
> >> + if (Status != EFI_BUFFER_TOO_SMALL) {
> >>
> >> + DEBUG ((DEBUG_ERROR, "%a - Communite to MM for variable
> >> service errored: %r\n", __func__, Status));
> >>
> >> + }
> >>
> >> +
> >>
> >> + goto Exit;
> >>
> >> + }
> >>
> >> +
> >>
> >> + Status = EFI_SUCCESS;
> >>
> >> +
> >>
> >> + // User provided buffer is too small
> >>
> >> + if (*VariableNameSize < MmVarGetNextVarHeader->NameSize) {
> >>
> >> + Status = EFI_BUFFER_TOO_SMALL;
> >>
> >> + }
> >>
> >> +
> >>
> >> +Exit:
> >>
> >> + // Update the name size to be returned
> >>
> >> + *VariableNameSize = MmVarGetNextVarHeader->NameSize;
> >>
> >> +
> >>
> >> + if (Status == EFI_SUCCESS) {
> >>
> >> + CopyMem ((VOID *)VariableName, (UINT8
> >> *)MmVarGetNextVarHeader->Name, *VariableNameSize);
> >>
> >> + CopyMem ((VOID *)VariableGuid, (UINT8
> >> *)&(MmVarGetNextVarHeader->Guid), sizeof (EFI_GUID));
> >>
> >> + }
> >>
> >> +
> >>
> >> + // Free the Communication Buffer
> >>
> >> + if (MmCommunicateBuffer != NULL) {
> >>
> >> + FreePages (MmCommunicateBuffer, RequiredPages);
> >>
> >> + }
> >>
> >> +
> >>
> >> + return Status;
> >>
> >> +}
> >>
> >> diff --git a/MdeModulePkg/MdeModulePkg.dsc
> >> b/MdeModulePkg/MdeModulePkg.dsc
> >> index 5b1f50e9c084..1aedfe280ae1 100644
> >> --- a/MdeModulePkg/MdeModulePkg.dsc
> >> +++ b/MdeModulePkg/MdeModulePkg.dsc
> >> @@ -400,6 +400,7 @@ [Components]
> >> MdeModulePkg/Application/VariableInfo/VariableInfo.inf
> >>
> >>
> >>
> MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf
> >>
> >> MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
> >>
> >> + MdeModulePkg/Universal/Variable/MmVariablePei/MmVariablePei.inf
> >>
> >> MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
> >>
> >> MdeModulePkg/Universal/TimestampDxe/TimestampDxe.inf
> >>
> >>
> >>
> MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
> >>
> >> diff --git
> >> a/MdeModulePkg/Universal/Variable/MmVariablePei/MmVariablePei.h
> >> b/MdeModulePkg/Universal/Variable/MmVariablePei/MmVariablePei.h
> >> new file mode 100644
> >> index 000000000000..0feed8cd1cb6
> >> --- /dev/null
> >> +++
> b/MdeModulePkg/Universal/Variable/MmVariablePei/MmVariablePei.h
> >> @@ -0,0 +1,134 @@
> >> +/** @file -- MmVariablePei.h
> >>
> >> + Provides interface for reading Secure System Variables during PEI.
> >>
> >> +
> >>
> >> + Copyright (c) Microsoft Corporation.
> >>
> >> + SPDX-License-Identifier: BSD-2-Clause-Patent
> >>
> >> +**/
> >>
> >> +
> >>
> >> +#ifndef PEI_MM_VARIABLE_LIB_H_
> >>
> >> +#define PEI_MM_VARIABLE_LIB_H_
> >>
> >> +
> >>
> >> +#include <PiPei.h>
> >>
> >> +#include <Uefi/UefiSpec.h>
> >>
> >> +
> >>
> >> +#include <Library/DebugLib.h>
> >>
> >> +#include <Library/PcdLib.h>
> >>
> >> +#include <Library/BaseMemoryLib.h>
> >>
> >> +#include <Library/PeimEntryPoint.h>
> >>
> >> +#include <Library/PeiServicesLib.h>
> >>
> >> +#include <Library/MemoryAllocationLib.h>
> >>
> >> +#include <Library/HobLib.h>
> >>
> >> +
> >>
> >> +#include <Guid/SmmVariableCommon.h>
> >>
> >> +
> >>
> >> +#include <Ppi/ReadOnlyVariable2.h>
> >>
> >> +#include <Ppi/MmCommunication.h>
> >>
> >> +
> >>
> >> +#include <Protocol/SmmVariable.h>
> >>
> >> +#include <Protocol/MmCommunication.h>
> >>
> >> +
> >>
> >> +/**
> >>
> >> + Entry point of PEI Secure Variable read driver
> >>
> >> +
> >>
> >> + @param FileHandle Handle of the file being invoked.
> >>
> >> + Type EFI_PEI_FILE_HANDLE is defined in
> >> FfsFindNextFile().
> >>
> >> + @param PeiServices General purpose services available to every
> >> PEIM.
> >>
> >> +
> >>
> >> + @retval EFI_SUCCESS If the interface could be successfully installed
> >>
> >> + @retval Others Returned from PeiServicesInstallPpi()
> >>
> >> +**/
> >>
> >> +EFI_STATUS
> >>
> >> +EFIAPI
> >>
> >> +PeiMmVariableInitialize (
> >>
> >> + IN EFI_PEI_FILE_HANDLE FileHandle,
> >>
> >> + IN CONST EFI_PEI_SERVICES **PeiServices
> >>
> >> + );
> >>
> >> +
> >>
> >> +/**
> >>
> >> +
> >>
> >> + This function enables the read of Secure Variables during PEI.
> >>
> >> +
> >>
> >> + This function is using the Secure Variable Store.If the Data
> >>
> >> + buffer is too small to hold the contents of the variable, the error
> >>
> >> + EFI_BUFFER_TOO_SMALL is returned and DataSize is set to the
> required
> >> buffer
> >>
> >> + size to obtain the data.
> >>
> >> +
> >>
> >> + The function performs the following:
> >>
> >> +
> >>
> >> + 1) Creates an MM request
> >>
> >> + 2) Fills out the following data structures for the Secure Variable
> > Service
> >> +
> >>
> SMM_VARIABLE_COMMUNICATE_HEADER/SMM_VARIABLE_COMMUNICAT
> >> E_ACCESS_VARIABLE
> >>
> >> + 3) Adds the MM data structures to the MM request.
> >>
> >> + 4) Sends the MM request to EL3 using MmCommunicationPeiLib.
> >>
> >> + 5) The MM request is sent to S-EL0.
> >>
> >> + 6) The MM request is then handled by the registered handler with
> GUID:
> >> gEfiSmmVariableProtocolGuid
> >>
> >> +
> >>
> >> + @param This A pointer to this instance of the
> >> EFI_PEI_READ_ONLY_VARIABLE2_PPI.
> >>
> >> + @param VariableName A pointer to a null-terminated
> string
> >> that is the variable's name.
> >>
> >> + @param VariableGuid A pointer to an EFI_GUID that is
> the
> >> variable's GUID. The combination of
> >>
> >> + VariableGuid and VariableName
> >> must be unique.
> >>
> >> + @param Attributes If non-NULL, on return, points to
> the
> >> variable's attributes.
> >>
> >> + @param DataSize On entry, points to the size in
> bytes
> >> of the Data buffer.
> >>
> >> + On return, points to the size of
> the
> >> data returned in Data.
> >>
> >> + @param Data Points to the buffer which will
> hold
> >> the returned variable value.
> >>
> >> + May be NULL with a zero
> DataSize in
> >> order to determine the size of the buffer needed.
> >>
> >> +
> >>
> >> + @retval EFI_SUCCESS The variable was read successfully.
> >>
> >> + @retval EFI_NOT_FOUND The variable was not found.
> >>
> >> + @retval EFI_BUFFER_TOO_SMALL The DataSize is too small for the
> >> resulting data.
> >>
> >> + DataSize is updated with the size
> >> required for
> >>
> >> + the specified variable.
> >>
> >> + @retval EFI_INVALID_PARAMETER VariableName, VariableGuid,
> DataSize
> >> or Data is NULL.
> >>
> >> + @retval EFI_DEVICE_ERROR The variable could not be retrieved
> >> because of a device error.
> >>
> >> +
> >>
> >> +**/
> >>
> >> +EFI_STATUS
> >>
> >> +EFIAPI
> >>
> >> +PeiMmGetVariable (
> >>
> >> + IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI *This,
> >>
> >> + IN CONST CHAR16 *VariableName,
> >>
> >> + IN CONST EFI_GUID *VariableGuid,
> >>
> >> + OUT UINT32 *Attributes,
> >>
> >> + IN OUT UINTN *DataSize,
> >>
> >> + OUT VOID *Data
> OPTIONAL
> >>
> >> + );
> >>
> >> +
> >>
> >> +/**
> >>
> >> + Return the next variable name and GUID.
> >>
> >> +
> >>
> >> + This function is called multiple times to retrieve the VariableName
> >>
> >> + and VariableGuid of all variables currently available in the system.
> >>
> >> + On each call, the previous results are passed into the interface,
> >>
> >> + and, on return, the interface returns the data for the next
> >>
> >> + interface. When the entire variable list has been returned,
> >>
> >> + EFI_NOT_FOUND is returned.
> >>
> >> +
> >>
> >> + @param This A pointer to this instance of the
> >> EFI_PEI_READ_ONLY_VARIABLE2_PPI.
> >>
> >> +
> >>
> >> + @param VariableNameSize On entry, points to the size of the
> buffer
> >> pointed to by VariableName.
> >>
> >> + On return, the size of the variable
> name
> >> buffer.
> >>
> >> + @param VariableName On entry, a pointer to a
> null-terminated
> >> string that is the variable's name.
> >>
> >> + On return, points to the next variable's
> >> null-terminated name string.
> >>
> >> +
> >>
> >> + @param VariableGuid On entry, a pointer to an EFI_GUID that
> is
> >> the variable's GUID.
> >>
> >> + On return, a pointer to the next
> variable's
> >> GUID.
> >>
> >> +
> >>
> >> + @retval EFI_SUCCESS The variable was read successfully.
> >>
> >> + @retval EFI_NOT_FOUND The variable could not be found.
> >>
> >> + @retval EFI_BUFFER_TOO_SMALL The VariableNameSize is too
> small
> >> for the resulting
> >>
> >> + data. VariableNameSize is
> updated
> >> with the size
> >>
> >> + required for the specified
> variable.
> >>
> >> + @retval EFI_INVALID_PARAMETER VariableName, VariableGuid or
> >>
> >> + VariableNameSize is NULL.
> >>
> >> + @retval EFI_DEVICE_ERROR The variable could not be retrieved
> >> because of a device error.
> >>
> >> +**/
> >>
> >> +EFI_STATUS
> >>
> >> +EFIAPI
> >>
> >> +PeiMmGetNextVariableName (
> >>
> >> + IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI *This,
> >>
> >> + IN OUT UINTN
> *VariableNameSize,
> >>
> >> + IN OUT CHAR16 *VariableName,
> >>
> >> + IN OUT EFI_GUID *VariableGuid
> >>
> >> + );
> >>
> >> +
> >>
> >> +#endif /* PEI_MM_VARIABLE_LIB_H_ */
> >>
> >> diff --git
> >> a/MdeModulePkg/Universal/Variable/MmVariablePei/MmVariablePei.inf
> >> b/MdeModulePkg/Universal/Variable/MmVariablePei/MmVariablePei.inf
> >> new file mode 100644
> >> index 000000000000..d122703e9b5d
> >> --- /dev/null
> >> +++
> b/MdeModulePkg/Universal/Variable/MmVariablePei/MmVariablePei.inf
> >> @@ -0,0 +1,43 @@
> >> +## @file -- MmVariablePei.inf
> >>
> >> +# Provides interface for reading Secure System Variables during PEI.
> >>
> >> +#
> >>
> >> +# Copyright (c) Microsoft Corporation.
> >>
> >> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> >>
> >> +##
> >>
> >> +
> >>
> >> +
> >>
> >> +[Defines]
> >>
> >> + INF_VERSION = 0x00010005
> >>
> >> + BASE_NAME = MmVariablePei
> >>
> >> + FILE_GUID =
> >> CD660A87-454B-4346-A35C-3D89BF8ECFAF
> >>
> >> + MODULE_TYPE = PEIM
> >>
> >> + VERSION_STRING = 1.0
> >>
> >> + ENTRY_POINT = PeiMmVariableInitialize
> >>
> >> +
> >>
> >> +[Sources]
> >>
> >> + MmVariablePei.c
> >>
> >> + MmVariablePei.h
> >>
> >> +
> >>
> >> +[Packages]
> >>
> >> + MdePkg/MdePkg.dec
> >>
> >> + MdeModulePkg/MdeModulePkg.dec
> >>
> >> +
> >>
> >> +[LibraryClasses]
> >>
> >> + PcdLib
> >>
> >> + PeiServicesLib
> >>
> >> + PeimEntryPoint
> >>
> >> + MemoryAllocationLib
> >>
> >> + HobLib
> >>
> >> +
> >>
> >> +[Pcd]
> >>
> >> + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize
> >>
> >> +
> >>
> >> +[Protocols]
> >>
> >> + gEfiSmmVariableProtocolGuid ## CONSUMES
> >>
> >> +
> >>
> >> +[Ppis]
> >>
> >> + gEfiPeiReadOnlyVariable2PpiGuid ## PRODUCES
> >>
> >> + gEfiPeiMmCommunicationPpiGuid ## CONSUMES
> >>
> >> +
> >>
> >> +[Depex]
> >>
> >> + gEfiPeiMmCommunicationPpiGuid
> >>
> >> --
> >> 2.40.1.windows.1
> >>
> >>
> >>
> >> -=-=-=-=-=-=
> >> Groups.io Links: You receive all messages sent to this group.
> >> View/Reply Online (#105956):
> >> https://edk2.groups.io/g/devel/message/105956
> >> Mute This Topic: https://groups.io/mt/99415826/4905953
> >> Group Owner: devel+owner@edk2.groups.io
> >> Unsubscribe: https://edk2.groups.io/g/devel/unsub
> >> [gaoliming@byosoft.com.cn]
> >> -=-=-=-=-=-=
> >>
> >
> >
> >
> >
> >
> >
> >
>
>
>
>
prev parent reply other threads:[~2023-06-27 0:53 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-06-08 20:44 [PATCH v1 0/2] Support MM based variable services in PEI for ARM Kun Qin
2023-06-08 20:44 ` [PATCH v1 1/2] ArmPkg: MmCommunicationPei: Introduce MM communicate in PEI Kun Qin
2023-06-22 19:17 ` Sami Mujawar
2023-06-26 20:07 ` Kun Qin
2023-06-08 20:44 ` [PATCH v1 2/2] MdeModulePkg: Variable: Introduce MM based variable read service " Kun Qin
2023-06-25 2:23 ` 回复: [edk2-devel] " gaoliming
2023-06-26 20:10 ` Kun Qin
2023-06-27 0:53 ` gaoliming [this message]
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='00e701d9a891$cf6cab30$6e460190$@byosoft.com.cn' \
--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