From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pf1-f171.google.com (mail-pf1-f171.google.com [209.85.210.171]) by mx.groups.io with SMTP id smtpd.web10.1959.1687809600028713612 for ; Mon, 26 Jun 2023 13:00:00 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20221208 header.b=X2bxta5+; spf=pass (domain: gmail.com, ip: 209.85.210.171, mailfrom: kuqin12@gmail.com) Received: by mail-pf1-f171.google.com with SMTP id d2e1a72fcca58-6686a05bc66so2214612b3a.1 for ; Mon, 26 Jun 2023 12:59:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1687809599; x=1690401599; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=MucgjfCde/wxuj9WqDshPSdmW1SiN19uUDIjKsW2Bw4=; b=X2bxta5+gTlIxKEeMmMdQs4vWOIa4noz3Cbnx0MRGqJIUrQK7Zyu6HeY6EZPuHqKD1 jdm2LswphKT3GFwAug7cE1gBY0q1Tk3Oq7wCXra3JXY0eXJBuWBDl7OY7g6u1ESzH2SL 1U/+GjBgCl9OJvIncZu943yuA4mAmh6NhtEZtXZ9SUhzcXd8E78/8vedOFZaysKVoV5U ErFcB0qfzerVvaJCjG9KfSwAYNYAoBepxctuzah+oeaKJJQqkT+/8i+oneFwGbZK8wP/ WpDfl/DcDU/YkjWeGnO7EQWS4zxvEvAV18vO7IMeAlP9pMR+EhB6rXtvHkUSJAJdkdRV jJjQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687809599; x=1690401599; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=MucgjfCde/wxuj9WqDshPSdmW1SiN19uUDIjKsW2Bw4=; b=Z/F8KQLcWSQVYep8ONuAcH3Bc96BaKQ+GglD7/SGLYyQDc/sbFDuvdoCks+Avhwojc 4bj5qxsaezjSM/JR8BjJNbcm98SWicc2LG1YJDpIF0MHQcPRaDApALcHstUEdRSwQqnw ixNC6gM82//dUkfawgPkZkZHM+WvOsuqK1P58tQbyXkHswyHFzlvaDLX8xaUJ8AAq9NS jc+vIrmyPF2a7xZkVMuaCdE5Cc2mATHCkA1xnVMN1lWURLQ0YVLK4D2uQ++orleJfycl shg+fasL/3pPFO2sOtdcG/VHz9iHyx8y2USq9PsOdrCy8NWUR40pSBYGzaNM3O+apnnc z7vA== X-Gm-Message-State: AC+VfDyu59QAQ11iA8yBHElWubC/ZqdUkdMpQvit+9v83kvVrCnN5ikC AgfeSAqA3Ycx0gwscn8leZDFhJkCQ5c= X-Google-Smtp-Source: ACHHUZ5Cl4erQ+xO1yRJCWOix9TirKH7bAHnzVmHnqCG0VKqOXQpPMeqwKI9Zxa/fUpnyt+pPX5LWg== X-Received: by 2002:a05:6a00:2289:b0:67b:8602:aa1b with SMTP id f9-20020a056a00228900b0067b8602aa1bmr1527771pfe.27.1687809599072; Mon, 26 Jun 2023 12:59:59 -0700 (PDT) Return-Path: Received: from MININT-0U7P5GU.redmond.corp.microsoft.com ([2001:4898:80e8:1:3ddb:b5a5:d301:15a6]) by smtp.gmail.com with ESMTPSA id j18-20020a62e912000000b00666add7f047sm4122755pfh.207.2023.06.26.12.59.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 26 Jun 2023 12:59:58 -0700 (PDT) From: "Kun Qin" To: devel@edk2.groups.io Cc: Leif Lindholm , Ard Biesheuvel , Sami Mujawar , Ronny Hansen , Shriram Masanamuthu Chinnathurai , Preshit Harlikar Subject: [PATCH v2 1/2] ArmPkg: MmCommunicationPei: Introduce MM communicate in PEI Date: Mon, 26 Jun 2023 12:59:51 -0700 Message-ID: <20230626195953.1807-2-kuqin12@gmail.com> X-Mailer: git-send-email 2.41.0.windows.1 In-Reply-To: <20230626195953.1807-1-kuqin12@gmail.com> References: <20230626195953.1807-1-kuqin12@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Kun Qin REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D4464 This change introduced the MM communicate support in PEI phase for ARM based platforms. Similar to the DXE counterpart, `PcdMmBufferBase` is used as communicate buffer and SMC will be invoked to communicate to TrustZone when MMI is requested. Cc: Leif Lindholm Cc: Ard Biesheuvel Cc: Sami Mujawar Co-authored-by: Ronny Hansen Co-authored-by: Shriram Masanamuthu Chinnathurai Co-authored-by: Preshit Harlikar Signed-off-by: Kun Qin --- Notes: v2: - Adjustment to CommSize checks [Sami] - Added more debug prints for error returns. ArmPkg/Drivers/MmCommunicationPei/MmCommunicationPei.c | 212 +++++++++++= +++++++++ ArmPkg/ArmPkg.dsc | 2 + ArmPkg/Drivers/MmCommunicationPei/MmCommunicationPei.h | 76 +++++++ ArmPkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf | 41 ++++ 4 files changed, 331 insertions(+) diff --git a/ArmPkg/Drivers/MmCommunicationPei/MmCommunicationPei.c b/ArmPk= g/Drivers/MmCommunicationPei/MmCommunicationPei.c new file mode 100644 index 000000000000..8661f0c8ee49 --- /dev/null +++ b/ArmPkg/Drivers/MmCommunicationPei/MmCommunicationPei.c @@ -0,0 +1,212 @@ +/** @file -- MmCommunicationPei.c=0D + Provides an interface to send MM request in PEI=0D +=0D + Copyright (c) 2016-2021, Arm Limited. All rights reserved.
=0D + Copyright (c) Microsoft Corporation.=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +=0D +#include "MmCommunicationPei.h"=0D +=0D +//=0D +// Module globals=0D +//=0D +EFI_PEI_MM_COMMUNICATION_PPI mPeiMmCommunication =3D {=0D + MmCommunicationPeim=0D +};=0D +=0D +EFI_PEI_PPI_DESCRIPTOR mPeiMmCommunicationPpi =3D {=0D + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),=0D + &gEfiPeiMmCommunicationPpiGuid,=0D + &mPeiMmCommunication=0D +};=0D +=0D +/**=0D + Entry point of PEI MM Communication driver=0D +=0D + @param FileHandle Handle of the file being invoked.=0D + Type EFI_PEI_FILE_HANDLE is defined in FfsFindNextF= ile().=0D + @param PeiServices General purpose services available to every PEIM.=0D +=0D + @retval EFI_SUCCESS If the interface could be successfully installed=0D + @retval Others Returned from PeiServicesInstallPpi()=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +MmCommunicationPeiInitialize (=0D + IN EFI_PEI_FILE_HANDLE FileHandle,=0D + IN CONST EFI_PEI_SERVICES **PeiServices=0D + )=0D +{=0D + return PeiServicesInstallPpi (&mPeiMmCommunicationPpi);=0D +}=0D +=0D +/**=0D + MmCommunicationPeim=0D + Communicates with a registered handler.=0D + This function provides a service to send and receive messages from a reg= istered UEFI service during PEI.=0D +=0D + @param[in] This The EFI_PEI_MM_COMMUNICATION_PPI instanc= e.=0D + @param[in, out] CommBuffer Pointer to the data buffer=0D + @param[in, out] CommSize The size of the data buffer being passed= in. On exit, the=0D + size of data being returned. Zero if the= handler does not=0D + wish to reply with any data.=0D +=0D + @retval EFI_SUCCESS The message was successfully posted.=0D + @retval EFI_INVALID_PARAMETER CommBuffer or CommSize was NULL, or *Com= mSize does not=0D + match MessageLength + sizeof (EFI_MM_COM= MUNICATE_HEADER).=0D + @retval EFI_BAD_BUFFER_SIZE The buffer is too large for the MM imple= mentation.=0D + If this error is returned, the MessageLe= ngth field=0D + in the CommBuffer header or the integer = pointed by=0D + CommSize, are updated to reflect the max= imum payload=0D + size the implementation can accommodate.= =0D + @retval EFI_ACCESS_DENIED The CommunicateBuffer parameter or CommS= ize parameter,=0D + if not omitted, are in address range tha= t cannot be=0D + accessed by the MM environment.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +MmCommunicationPeim (=0D + IN CONST EFI_PEI_MM_COMMUNICATION_PPI *This,=0D + IN OUT VOID *CommBuffer,=0D + IN OUT UINTN *CommSize=0D + )=0D +{=0D + EFI_MM_COMMUNICATE_HEADER *CommunicateHeader;=0D + EFI_MM_COMMUNICATE_HEADER *TempCommHeader;=0D + ARM_SMC_ARGS CommunicateSmcArgs;=0D + EFI_STATUS Status;=0D + UINTN BufferSize;=0D +=0D + ZeroMem (&CommunicateSmcArgs, sizeof (ARM_SMC_ARGS));=0D +=0D + // Check that our static buffer is looking good.=0D + // We are using PcdMmBufferBase to transfer variable data.=0D + // We are not using the full size of the buffer since there is a cost=0D + // of copying data between Normal and Secure World.=0D + ASSERT (PcdGet64 (PcdMmBufferSize) > 0 && PcdGet64 (PcdMmBufferBase) != =3D 0);=0D +=0D + //=0D + // Check parameters=0D + //=0D + if ((CommBuffer =3D=3D NULL) || (CommSize =3D=3D NULL)) {=0D + DEBUG ((=0D + DEBUG_ERROR,=0D + "%a One or more incoming pointers are NULL %p and %p!\n",=0D + __func__,=0D + CommBuffer,=0D + CommSize=0D + ));=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + // If the length of the CommBuffer is 0 then return the expected length.= =0D + // This case can be used by the consumer of this driver to find out the= =0D + // max size that can be used for allocating CommBuffer.=0D + if ((*CommSize =3D=3D 0) || (*CommSize > (UINTN)PcdGet64 (PcdMmBufferSiz= e))) {=0D + DEBUG ((=0D + DEBUG_ERROR,=0D + "%a Invalid CommSize value 0x%llx!\n",=0D + __func__,=0D + *CommSize=0D + ));=0D + *CommSize =3D (UINTN)PcdGet64 (PcdMmBufferSize);=0D + return EFI_BAD_BUFFER_SIZE;=0D + }=0D +=0D + // Given CommBuffer is not NULL here, we use it to test the legitimacy o= f CommSize.=0D + TempCommHeader =3D (EFI_MM_COMMUNICATE_HEADER *)(UINTN)CommBuffer;=0D +=0D + // CommBuffer is a mandatory parameter. Hence, Rely on=0D + // MessageLength + Header to ascertain the=0D + // total size of the communication payload rather than=0D + // rely on optional CommSize parameter=0D + BufferSize =3D TempCommHeader->MessageLength +=0D + sizeof (TempCommHeader->HeaderGuid) +=0D + sizeof (TempCommHeader->MessageLength);=0D +=0D + //=0D + // If CommSize is supplied it must match MessageLength + sizeof (EFI_MM_= COMMUNICATE_HEADER);=0D + //=0D + if (*CommSize !=3D BufferSize) {=0D + DEBUG ((=0D + DEBUG_ERROR,=0D + "%a Unexpected CommSize value, has: 0x%llx vs. expected: 0x%llx!\n",= =0D + __func__,=0D + *CommSize,=0D + BufferSize=0D + ));=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + // Now we know that the size is something we can handle, copy it over to= the designated comm buffer.=0D + CommunicateHeader =3D (EFI_MM_COMMUNICATE_HEADER *)(UINTN)(PcdGet64 (Pcd= MmBufferBase));=0D +=0D + CopyMem ((VOID *)CommunicateHeader, CommBuffer, *CommSize);=0D +=0D + // SMC Function ID=0D + CommunicateSmcArgs.Arg0 =3D ARM_SMC_ID_MM_COMMUNICATE_AARCH64;=0D +=0D + // Cookie=0D + CommunicateSmcArgs.Arg1 =3D 0;=0D +=0D + // comm_buffer_address (64-bit physical address)=0D + CommunicateSmcArgs.Arg2 =3D (UINTN)CommunicateHeader;=0D +=0D + // comm_size_address (not used, indicated by setting to zero)=0D + CommunicateSmcArgs.Arg3 =3D 0;=0D +=0D + // Call the Standalone MM environment.=0D + ArmCallSmc (&CommunicateSmcArgs);=0D +=0D + switch (CommunicateSmcArgs.Arg0) {=0D + case ARM_SMC_MM_RET_SUCCESS:=0D + // On successful return, the size of data being returned is inferred= from=0D + // MessageLength + Header.=0D + BufferSize =3D CommunicateHeader->MessageLength +=0D + sizeof (CommunicateHeader->HeaderGuid) +=0D + sizeof (CommunicateHeader->MessageLength);=0D + if (BufferSize > (UINTN)PcdGet64 (PcdMmBufferSize)) {=0D + // Something bad has happened, we should have landed in ARM_SMC_MM= _RET_NO_MEMORY=0D + DEBUG ((=0D + DEBUG_ERROR,=0D + "%a Returned buffer exceeds communication buffer limit. Has: 0x%= llx vs. max: 0x%llx!\n",=0D + __func__,=0D + BufferSize,=0D + (UINTN)PcdGet64 (PcdMmBufferSize)=0D + ));=0D + Status =3D EFI_BAD_BUFFER_SIZE;=0D + break;=0D + }=0D +=0D + CopyMem (CommBuffer, (VOID *)CommunicateHeader, BufferSize);=0D + if (CommSize !=3D NULL) {=0D + *CommSize =3D BufferSize;=0D + }=0D +=0D + Status =3D EFI_SUCCESS;=0D + break;=0D +=0D + case ARM_SMC_MM_RET_INVALID_PARAMS:=0D + Status =3D EFI_INVALID_PARAMETER;=0D + break;=0D +=0D + case ARM_SMC_MM_RET_DENIED:=0D + Status =3D EFI_ACCESS_DENIED;=0D + break;=0D +=0D + case ARM_SMC_MM_RET_NO_MEMORY:=0D + // Unexpected error since the CommSize was checked for zero length=0D + // prior to issuing the SMC=0D + Status =3D EFI_OUT_OF_RESOURCES;=0D + ASSERT (0);=0D + break;=0D +=0D + default:=0D + Status =3D EFI_ACCESS_DENIED;=0D + ASSERT (0);=0D + break;=0D + }=0D +=0D + return Status;=0D +}=0D diff --git a/ArmPkg/ArmPkg.dsc b/ArmPkg/ArmPkg.dsc index 6b938ce8b671..4939b3d59b7f 100644 --- a/ArmPkg/ArmPkg.dsc +++ b/ArmPkg/ArmPkg.dsc @@ -162,6 +162,8 @@ [Components.common] ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscDxe.inf=0D ArmPkg/Universal/Smbios/OemMiscLibNull/OemMiscLibNull.inf=0D =0D + ArmPkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf=0D +=0D [Components.AARCH64]=0D ArmPkg/Drivers/ArmPsciMpServicesDxe/ArmPsciMpServicesDxe.inf=0D ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.inf=0D diff --git a/ArmPkg/Drivers/MmCommunicationPei/MmCommunicationPei.h b/ArmPk= g/Drivers/MmCommunicationPei/MmCommunicationPei.h new file mode 100644 index 000000000000..a99baa2496a9 --- /dev/null +++ b/ArmPkg/Drivers/MmCommunicationPei/MmCommunicationPei.h @@ -0,0 +1,76 @@ +/** @file -- MmCommunicationPei.h=0D + Provides an interface to send MM request in PEI=0D +=0D + Copyright (c) Microsoft Corporation.=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +=0D +#ifndef MM_COMMUNICATION_PEI_H_=0D +#define MM_COMMUNICATION_PEI_H_=0D +=0D +#include =0D +=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +#include =0D +=0D +#include =0D +=0D +#include =0D +=0D +/**=0D + Entry point of PEI MM Communication driver=0D +=0D + @param FileHandle Handle of the file being invoked.=0D + Type EFI_PEI_FILE_HANDLE is defined in FfsFindNextF= ile().=0D + @param PeiServices General purpose services available to every PEIM.=0D +=0D + @retval EFI_SUCCESS If the interface could be successfully installed=0D + @retval Others Returned from PeiServicesInstallPpi()=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +MmCommunicationPeiInitialize (=0D + IN EFI_PEI_FILE_HANDLE FileHandle,=0D + IN CONST EFI_PEI_SERVICES **PeiServices=0D + );=0D +=0D +/**=0D + MmCommunicationPeim=0D + Communicates with a registered handler.=0D + This function provides a service to send and receive messages from a reg= istered UEFI service during PEI.=0D +=0D + @param[in] This The EFI_PEI_MM_COMMUNICATION_PPI instanc= e.=0D + @param[in, out] CommBuffer Pointer to the data buffer=0D + @param[in, out] CommSize The size of the data buffer being passed= in. On exit, the=0D + size of data being returned. Zero if the= handler does not=0D + wish to reply with any data.=0D +=0D + @retval EFI_SUCCESS The message was successfully posted.=0D + @retval EFI_INVALID_PARAMETER CommBuffer was NULL or *CommSize does no= t match=0D + MessageLength + sizeof (EFI_MM_COMMUNICA= TE_HEADER).=0D + @retval EFI_BAD_BUFFER_SIZE The buffer is too large for the MM imple= mentation.=0D + If this error is returned, the MessageLe= ngth field=0D + in the CommBuffer header or the integer = pointed by=0D + CommSize, are updated to reflect the max= imum payload=0D + size the implementation can accommodate.= =0D + @retval EFI_ACCESS_DENIED The CommunicateBuffer parameter or CommS= ize parameter,=0D + if not omitted, are in address range tha= t cannot be=0D + accessed by the MM environment.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +MmCommunicationPeim (=0D + IN CONST EFI_PEI_MM_COMMUNICATION_PPI *This,=0D + IN OUT VOID *CommBuffer,=0D + IN OUT UINTN *CommSize=0D + );=0D +=0D +#endif /* MM_COMMUNICATION_PEI_H_ */=0D diff --git a/ArmPkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf b/Arm= Pkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf new file mode 100644 index 000000000000..7a0adbd9bd2f --- /dev/null +++ b/ArmPkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf @@ -0,0 +1,41 @@ +## @file -- MmCommunicationPei.inf=0D +# PEI MM Communicate driver=0D +#=0D +# Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.
=0D +# Copyright (c) Microsoft Corporation.=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +##=0D +=0D +[Defines]=0D + INF_VERSION =3D 0x0001001B=0D + BASE_NAME =3D MmCommunicationPei=0D + FILE_GUID =3D 58FFB346-1B75-42C7-AD69-37C652423C1A= =0D + MODULE_TYPE =3D PEIM=0D + VERSION_STRING =3D 1.0=0D + ENTRY_POINT =3D MmCommunicationPeiInitialize=0D +=0D +[Sources]=0D + MmCommunicationPei.c=0D + MmCommunicationPei.h=0D +=0D +[Packages]=0D + MdePkg/MdePkg.dec=0D + MdeModulePkg/MdeModulePkg.dec=0D + ArmPkg/ArmPkg.dec=0D +=0D +[LibraryClasses]=0D + DebugLib=0D + ArmSmcLib=0D + PeimEntryPoint=0D + PeiServicesLib=0D + HobLib=0D +=0D +[Pcd]=0D + gArmTokenSpaceGuid.PcdMmBufferBase=0D + gArmTokenSpaceGuid.PcdMmBufferSize=0D +=0D +[Ppis]=0D + gEfiPeiMmCommunicationPpiGuid ## PRODUCES=0D +=0D +[Depex]=0D + TRUE=0D --=20 2.41.0.windows.1