回复: 回复: [edk2-devel] [PATCH v1 2/2] MdeModulePkg: Variable: Introduce MM based variable read service in PEI

gaoliming via groups.io gaoliming=byosoft.com.cn at groups.io
Tue Jun 27 00:53:38 UTC 2023


Kun:
  Thanks for your update. I have no other comments for this patch. Reviewed-by: Liming Gao <gaoliming at byosoft.com.cn>

Thanks
Liming
> -----邮件原件-----
> 发件人: devel at edk2.groups.io <devel at edk2.groups.io> 代表 Kun Qin
> 发送时间: 2023年6月27日 4:11
> 收件人: devel at edk2.groups.io; gaoliming at byosoft.com.cn
> 抄送: 'Hao A Wu' <hao.a.wu at intel.com>; 'Jian J Wang'
> <jian.j.wang at intel.com>; 'Ronny Hansen' <hansen.ronny at microsoft.com>;
> 'Shriram Masanamuthu Chinnathurai' <shriramma at microsoft.com>; 'Preshit
> Harlikar' <pharlikar at 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 at edk2.groups.io <devel at edk2.groups.io> 代表 Kun Qin
> >> 发送时间: 2023年6月9日 4:45
> >> 收件人: devel at edk2.groups.io
> >> 抄送: Hao A Wu <hao.a.wu at intel.com>; Liming Gao
> >> <gaoliming at byosoft.com.cn>; Jian J Wang <jian.j.wang at intel.com>;
> Ronny
> >> Hansen <hansen.ronny at microsoft.com>; Shriram Masanamuthu
> >> Chinnathurai <shriramma at microsoft.com>; Preshit Harlikar
> >> <pharlikar at microsoft.com>
> >> 主题: [edk2-devel] [PATCH v1 2/2] MdeModulePkg: Variable: Introduce
> MM
> >> based variable read service in PEI
> >>
> >> From: Kun Qin <kuqin at 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 at intel.com>
> >> Cc: Liming Gao <gaoliming at byosoft.com.cn>
> >> Cc: Jian J Wang <jian.j.wang at intel.com>
> >>
> >> Co-authored-by: Ronny Hansen <hansen.ronny at microsoft.com>
> >> Co-authored-by: Shriram Masanamuthu Chinnathurai
> >> <shriramma at microsoft.com>
> >> Co-authored-by: Preshit Harlikar <pharlikar at microsoft.com>
> >> Signed-off-by: Kun Qin <kuqin at 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 at edk2.groups.io
> >> Unsubscribe: https://edk2.groups.io/g/devel/unsub
> >> [gaoliming at byosoft.com.cn]
> >> -=-=-=-=-=-=
> >>
> >
> >
> >
> >
> >
> >
> >
> 
> 
> 
> 





-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#106409): https://edk2.groups.io/g/devel/message/106409
Mute This Topic: https://groups.io/mt/99801350/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-




More information about the edk2-devel-archive mailing list