From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=104.47.1.78; helo=eur01-ve1-obe.outbound.protection.outlook.com; envelope-from=supreeth.venkatesh@arm.com; receiver=edk2-devel@lists.01.org Received: from EUR01-VE1-obe.outbound.protection.outlook.com (mail-ve1eur01on0078.outbound.protection.outlook.com [104.47.1.78]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id E35B8203BEA3A for ; Fri, 4 May 2018 16:30:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector1-arm-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=JlWddciH0vOO4av1ET9ebAtkITDGtgdlNsDd0H4FgW8=; b=oU+OTHlRslq8Qi8QMUtv77drKA7Zju0tDwhyjM0jkNyYc6Leh16MCDO8hANV6rt1ldkDvAjkR2iYOfCG1Y0gMnY7fuGoQlycl3cpVj6sEitbDGY/XWpOcZbv+BsxjWK6vb2FU02gUhC0VvrOpk3LjhvjMHgzS+X8yq4zZGAJGB8= Received: from AM4PR0802MB2306.eurprd08.prod.outlook.com (10.172.218.15) by AM4PR0802MB2276.eurprd08.prod.outlook.com (10.172.218.9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.735.16; Fri, 4 May 2018 23:30:03 +0000 Received: from AM4PR0802MB2306.eurprd08.prod.outlook.com ([fe80::e117:6f62:6a9b:6be4]) by AM4PR0802MB2306.eurprd08.prod.outlook.com ([fe80::e117:6f62:6a9b:6be4%8]) with mapi id 15.20.0735.016; Fri, 4 May 2018 23:30:03 +0000 From: Supreeth Venkatesh To: Achin Gupta CC: "edk2-devel@lists.01.org" , "leif.lindholm@linaro.org" , "ard.biesheuvel@linaro.org" Thread-Topic: [PATCH v1 15/18] ArmPkg: Extra action to update permissions for S-ELO MM Image. Thread-Index: AQHTzbWs/INyJXrE+EiXe2lFeotA0qQZ3TKAgASdN9A= Date: Fri, 4 May 2018 23:30:03 +0000 Message-ID: References: <20180406144223.10931-1-supreeth.venkatesh@arm.com> <20180406144223.10931-16-supreeth.venkatesh@arm.com> <20180430194911.GZ663@e104320-lin> In-Reply-To: <20180430194911.GZ663@e104320-lin> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: spf=none (sender IP is ) smtp.mailfrom=Supreeth.Venkatesh@arm.com; x-originating-ip: [217.140.111.135] x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1; AM4PR0802MB2276; 7:4OrQaNtxfCxRVKGQgKcWjlA8vy5b3i0juAJCSdJhqW2QKtue/r0Wa5MSYw7Az+AbFX0aU7oajkZgtrOw94+2fnFMxZjISuStNA05MN+oAjouT767dkcegw9OSlO/e/wF2GlfcxBy8jhLUaEuYu4IzqxrzE5HSOnV3SAO8+RYDPs9XIPgsB751gyIXUZEMis2JkAWylGrPUWn/wwqPBl6slh8MHDphoXLVVlBS8+5JdVB2pYco40Vr74Waps4m3Pt x-ms-exchange-antispam-srfa-diagnostics: SOS;SOR; x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(48565401081)(5600026)(2017052603328)(7153060)(7193020); SRVR:AM4PR0802MB2276; x-ms-traffictypediagnostic: AM4PR0802MB2276: x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:(180628864354917)(162533806227266)(228905959029699); x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(8121501046)(5005006)(10201501046)(93006095)(93001095)(3231254)(944501410)(52105095)(3002001)(6055026)(6041310)(20161123564045)(20161123562045)(20161123560045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123558120)(6072148)(201708071742011); SRVR:AM4PR0802MB2276; BCL:0; PCL:0; RULEID:; SRVR:AM4PR0802MB2276; x-forefront-prvs: 06628F7CA4 x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(39860400002)(396003)(366004)(346002)(376002)(39380400002)(199004)(189003)(13464003)(40434004)(53936002)(81166006)(6636002)(4326008)(7736002)(55016002)(6862004)(9686003)(8936002)(6116002)(15650500001)(2900100001)(3846002)(5250100002)(97736004)(6246003)(68736007)(5890100001)(8676002)(25786009)(229853002)(72206003)(86362001)(3660700001)(478600001)(59450400001)(7696005)(6436002)(3280700002)(106356001)(102836004)(26005)(105586002)(11346002)(6506007)(305945005)(33656002)(76176011)(66066001)(5660300001)(14454004)(81156014)(316002)(99286004)(74316002)(53546011)(476003)(446003)(2906002)(54906003)(486006); DIR:OUT; SFP:1101; SCL:1; SRVR:AM4PR0802MB2276; H:AM4PR0802MB2306.eurprd08.prod.outlook.com; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:; received-spf: None (protection.outlook.com: arm.com does not designate permitted sender hosts) x-microsoft-antispam-message-info: Khhddm7b1550FqrIKcNT+5RBDcXOjtd58SwTQDx5XIrwzrmmsQ+/+eiExFpGY+D/vxXtM41Cb0UWS5Ua7lixEtZBs+HhbUIVDLZargywQlUyqRnZPQjze01E0DIATkDs3aX6kkhbnsqdPwAmO8KO+G/98yl6rqt9sBCu2xFPP03JoQcFZlxTP99eBfegVX9E spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM MIME-Version: 1.0 X-MS-Office365-Filtering-Correlation-Id: 4ea99359-0eef-45d5-7a0e-08d5b216f626 X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-Network-Message-Id: 4ea99359-0eef-45d5-7a0e-08d5b216f626 X-MS-Exchange-CrossTenant-originalarrivaltime: 04 May 2018 23:30:03.0753 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM4PR0802MB2276 Subject: Re: [PATCH v1 15/18] ArmPkg: Extra action to update permissions for S-ELO MM Image. X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 04 May 2018 23:30:21 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable My response inline. -----Original Message----- From: Achin Gupta Sent: Monday, April 30, 2018 2:49 PM To: Supreeth Venkatesh Cc: edk2-devel@lists.01.org; michael.d.kinney@intel.com; liming.gao@intel.c= om; jiewen.yao@intel.com; leif.lindholm@linaro.org; ard.biesheuvel@linaro.o= rg; nd Subject: Re: [PATCH v1 15/18] ArmPkg: Extra action to update permissions fo= r S-ELO MM Image. Hi Supreeth, This file was originally contributed by Ard a while back so worth poking hi= m and Leif for review. If MM is expected to be the only use case of this li= brary then it might make sense to pull in under the StandaloneMmPkg instead= of relying on PcdStandaloneMmEnable. [Supreeth] I will let Ard and Leif comment on it. It's basically a debate between code duplication of the entire library in S= tandaloneMmPkg Vs addition of one PCD check and one function in existing Ar= mPkg library. Cheers, Achin On Fri, Apr 06, 2018 at 03:42:20PM +0100, Supreeth Venkatesh wrote: > The Standalone MM drivers runs in S-EL0 in AArch64 on ARM Standard > Platforms and is deployed during SEC phase. The memory allocated to > the Standalone MM drivers should be marked as RO+X. > > During PE/COFF Image section parsing, this patch implements extra > action "UpdatePeCoffPermissions" to request the privileged firmware in > EL3 to update the permissions. > > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Achin Gupta > Signed-off-by: Supreeth Venkatesh > --- > .../DebugPeCoffExtraActionLib.c | 185 +++++++++++++++= ++++-- > .../DebugPeCoffExtraActionLib.inf | 7 + > 2 files changed, 181 insertions(+), 11 deletions(-) > > diff --git > a/ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.c > b/ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.c > index f298e58cdf..c87aaf05c7 100644 > --- > a/ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.c > +++ b/ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionL > +++ ib.c > @@ -15,14 +15,165 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, E= ITHER EXPRESS OR IMPLIED. > **/ > > #include > -#include > > +#include > #include > -#include > #include > +#include > +#include > +#include > #include #include > > > +typedef RETURN_STATUS (*REGION_PERMISSION_UPDATE_FUNC) ( > + IN EFI_PHYSICAL_ADDRESS BaseAddress, > + IN UINT64 Length > + ); > + > +STATIC > +RETURN_STATUS > +UpdatePeCoffPermissions ( > + IN CONST PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, > + IN REGION_PERMISSION_UPDATE_FUNC NoExecUpdater, > + IN REGION_PERMISSION_UPDATE_FUNC ReadOnlyUpdater > + ) > +{ > + RETURN_STATUS Status; > + EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; > + EFI_IMAGE_OPTIONAL_HEADER_UNION HdrData; > + UINTN Size; > + UINTN ReadSize; > + UINT32 SectionHeaderOffset; > + UINTN NumberOfSections; > + UINTN Index; > + EFI_IMAGE_SECTION_HEADER SectionHeader; > + PE_COFF_LOADER_IMAGE_CONTEXT TmpContext; > + EFI_PHYSICAL_ADDRESS Base; > + > + // > + // We need to copy ImageContext since PeCoffLoaderGetImageInfo () > + // will mangle the ImageAddress field // CopyMem (&TmpContext, > + ImageContext, sizeof (TmpContext)); > + > + if (TmpContext.PeCoffHeaderOffset =3D=3D 0) { > + Status =3D PeCoffLoaderGetImageInfo (&TmpContext); > + if (RETURN_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, > + "%a: PeCoffLoaderGetImageInfo () failed (Status =3D %r)\n", > + __FUNCTION__, Status)); > + return Status; > + } > + } > + > + if (TmpContext.IsTeImage && > + TmpContext.ImageAddress =3D=3D ImageContext->ImageAddress) { > + DEBUG ((DEBUG_INFO, "%a: ignoring XIP TE image at 0x%lx\n", __FUNCTI= ON__, > + ImageContext->ImageAddress)); > + return RETURN_SUCCESS; > + } > + > + if (TmpContext.SectionAlignment < EFI_PAGE_SIZE) { > + // > + // The sections need to be at least 4 KB aligned, since that is the > + // granularity at which we can tighten permissions. So just clear th= e > + // noexec permissions on the entire region. > + // > + if (!TmpContext.IsTeImage) { > + DEBUG ((DEBUG_WARN, > + "%a: non-TE Image at 0x%lx has SectionAlignment < 4 KB (%lu)\n", > + __FUNCTION__, ImageContext->ImageAddress, TmpContext.SectionAlig= nment)); > + } > + Base =3D ImageContext->ImageAddress & ~(EFI_PAGE_SIZE - 1); > + Size =3D ImageContext->ImageAddress - Base + ImageContext->ImageSize= ; > + return NoExecUpdater (Base, ALIGN_VALUE (Size, EFI_PAGE_SIZE)); > + } > + > + // > + // Read the PE/COFF Header. For PE32 (32-bit) this will read in too > + much // data, but that should not hurt anything. > + Hdr.Pe32->OptionalHeader.Magic // determines if this is a PE32 or > + PE32+ image. The magic is in the same // location in both images. > + // > + Hdr.Union =3D &HdrData; > + Size =3D sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION); > + ReadSize =3D Size; > + Status =3D TmpContext.ImageRead (TmpContext.Handle, > + TmpContext.PeCoffHeaderOffset, &Size, > + Hdr.Pe32); if (RETURN_ERROR (Status) || (Size !=3D ReadSize)) { > + DEBUG ((DEBUG_ERROR, > + "%a: TmpContext.ImageRead () failed (Status =3D %r)\n", > + __FUNCTION__, Status)); > + return Status; > + } > + > + ASSERT (Hdr.Pe32->Signature =3D=3D EFI_IMAGE_NT_SIGNATURE); > + > + SectionHeaderOffset =3D TmpContext.PeCoffHeaderOffset + sizeof (UINT32= ) + > + sizeof (EFI_IMAGE_FILE_HEADER); > + NumberOfSections =3D (UINTN)(Hdr.Pe32->FileHeader.NumberOfSections)= ; > + > + switch (Hdr.Pe32->OptionalHeader.Magic) { > + case EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC: > + SectionHeaderOffset +=3D Hdr.Pe32->FileHeader.SizeOfOptionalHeader= ; > + break; > + case EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC: > + SectionHeaderOffset +=3D Hdr.Pe32Plus->FileHeader.SizeOfOptionalHe= ader; > + break; > + default: > + ASSERT (FALSE); > + } > + > + // > + // Iterate over the sections > + // > + for (Index =3D 0; Index < NumberOfSections; Index++) { > + // > + // Read section header from file > + // > + Size =3D sizeof (EFI_IMAGE_SECTION_HEADER); > + ReadSize =3D Size; > + Status =3D TmpContext.ImageRead (TmpContext.Handle, SectionHeaderOff= set, > + &Size, &SectionHeader); > + if (RETURN_ERROR (Status) || (Size !=3D ReadSize)) { > + DEBUG ((DEBUG_ERROR, > + "%a: TmpContext.ImageRead () failed (Status =3D %r)\n", > + __FUNCTION__, Status)); > + return Status; > + } > + > + Base =3D TmpContext.ImageAddress + SectionHeader.VirtualAddress; > + > + if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_MEM_EXECUTE) > + =3D=3D 0) { > + > + if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_MEM_WRITE) =3D= =3D 0 && > + TmpContext.ImageType !=3D > + EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) { > + > + DEBUG ((DEBUG_INFO, > + "%a: Mapping section %d of image at 0x%lx with RO-XN permissio= ns and size 0x%x\n", > + __FUNCTION__, Index, Base, SectionHeader.Misc.VirtualSize)); > + ReadOnlyUpdater (Base, SectionHeader.Misc.VirtualSize); > + } else { > + DEBUG ((DEBUG_WARN, > + "%a: Mapping section %d of image at 0x%lx with RW-XN permissio= ns and size 0x%x\n", > + __FUNCTION__, Index, Base, SectionHeader.Misc.VirtualSize)); > + } > + } else { > + DEBUG ((DEBUG_INFO, > + "%a: Mapping section %d of image at 0x%lx with RO-XN permissio= ns and size 0x%x\n", > + __FUNCTION__, Index, Base, SectionHeader.Misc.VirtualSize)); > + ReadOnlyUpdater (Base, SectionHeader.Misc.VirtualSize); > + > + DEBUG ((DEBUG_INFO, > + "%a: Mapping section %d of image at 0x%lx with RO-X permission= s and size 0x%x\n", > + __FUNCTION__, Index, Base, SectionHeader.Misc.VirtualSize)); > + NoExecUpdater (Base, SectionHeader.Misc.VirtualSize); > + } > + > + SectionHeaderOffset +=3D sizeof (EFI_IMAGE_SECTION_HEADER); > + } > + return RETURN_SUCCESS; > +} > > /** > If the build is done on cygwin the paths are cygpaths. > @@ -83,23 +234,29 @@ PeCoffLoaderRelocateImageExtraAction ( > CHAR8 Temp[512]; > #endif > > + if (PcdGetBool(PcdStandaloneMmEnable) =3D=3D TRUE) { > + UpdatePeCoffPermissions (ImageContext, ArmClearMemoryRegionNoExec, > + ArmSetMemoryRegionReadOnly); } > + > if (ImageContext->PdbPointer) { > #ifdef __CC_ARM > #if (__ARMCC_VERSION < 500000) > // Print out the command for the RVD debugger to load symbols for th= is image > - DEBUG ((EFI_D_LOAD | EFI_D_INFO, "load /a /ni /np %a &0x%p\n", DeCyg= winPathIfNeeded (ImageContext->PdbPointer, Temp, sizeof (Temp)), (UINTN)(Im= ageContext->ImageAddress + ImageContext->SizeOfHeaders))); > + DEBUG ((DEBUG_LOAD | DEBUG_INFO, "load /a /ni /np %a &0x%p\n", > + DeCygwinPathIfNeeded (ImageContext->PdbPointer, Temp, sizeof > + (Temp)), (UINTN)(ImageContext->ImageAddress + > + ImageContext->SizeOfHeaders))); > #else > // Print out the command for the DS-5 to load symbols for this image > - DEBUG ((EFI_D_LOAD | EFI_D_INFO, "add-symbol-file %a 0x%p\n", DeCygw= inPathIfNeeded (ImageContext->PdbPointer, Temp, sizeof (Temp)), (UINTN)(Ima= geContext->ImageAddress + ImageContext->SizeOfHeaders))); > + DEBUG ((DEBUG_LOAD | DEBUG_INFO, "add-symbol-file %a 0x%p\n", > + DeCygwinPathIfNeeded (ImageContext->PdbPointer, Temp, sizeof > + (Temp)), (UINTN)(ImageContext->ImageAddress + > + ImageContext->SizeOfHeaders))); > #endif > #elif __GNUC__ > // This may not work correctly if you generate PE/COFF directlyas th= en the Offset would not be required > - DEBUG ((EFI_D_LOAD | EFI_D_INFO, "add-symbol-file %a 0x%p\n", DeCygw= inPathIfNeeded (ImageContext->PdbPointer, Temp, sizeof (Temp)), (UINTN)(Ima= geContext->ImageAddress + ImageContext->SizeOfHeaders))); > + DEBUG ((DEBUG_LOAD | DEBUG_INFO, "add-symbol-file %a 0x%p\n", > + DeCygwinPathIfNeeded (ImageContext->PdbPointer, Temp, sizeof > + (Temp)), (UINTN)(ImageContext->ImageAddress + > + ImageContext->SizeOfHeaders))); > #else > - DEBUG ((EFI_D_LOAD | EFI_D_INFO, "Loading driver at 0x%11p EntryPoin= t=3D0x%11p\n", (VOID *)(UINTN) ImageContext->ImageAddress, FUNCTION_ENTRY_P= OINT (ImageContext->EntryPoint))); > + DEBUG ((DEBUG_LOAD | DEBUG_INFO, "Loading driver at 0x%11p > + EntryPoint=3D0x%11p\n", (VOID *)(UINTN) ImageContext->ImageAddress, > + FUNCTION_ENTRY_POINT (ImageContext->EntryPoint))); > #endif > } else { > - DEBUG ((EFI_D_LOAD | EFI_D_INFO, "Loading driver at 0x%11p EntryPoin= t=3D0x%11p\n", (VOID *)(UINTN) ImageContext->ImageAddress, FUNCTION_ENTRY_P= OINT (ImageContext->EntryPoint))); > + DEBUG ((DEBUG_LOAD | DEBUG_INFO, "Loading driver at 0x%11p > + EntryPoint=3D0x%11p\n", (VOID *)(UINTN) ImageContext->ImageAddress, > + FUNCTION_ENTRY_POINT (ImageContext->EntryPoint))); > } > } > > @@ -125,17 +282,23 @@ PeCoffLoaderUnloadImageExtraAction ( > CHAR8 Temp[512]; > #endif > > + if (PcdGetBool(PcdStandaloneMmEnable) =3D=3D TRUE) { > + UpdatePeCoffPermissions (ImageContext, ArmSetMemoryRegionNoExec, > + ArmClearMemoryRegionReadOnly); } > + > if (ImageContext->PdbPointer) { > #ifdef __CC_ARM > // Print out the command for the RVD debugger to load symbols for th= is image > - DEBUG ((EFI_D_ERROR, "unload symbols_only %a\n", DeCygwinPathIfNeede= d (ImageContext->PdbPointer, Temp, sizeof (Temp)))); > + DEBUG ((DEBUG_ERROR, "unload symbols_only %a\n", > + DeCygwinPathIfNeeded (ImageContext->PdbPointer, Temp, sizeof > + (Temp)))); > #elif __GNUC__ > // This may not work correctly if you generate PE/COFF directlyas th= en the Offset would not be required > - DEBUG ((EFI_D_ERROR, "remove-symbol-file %a 0x%08x\n", DeCygwinPathI= fNeeded (ImageContext->PdbPointer, Temp, sizeof (Temp)), (UINTN)(ImageConte= xt->ImageAddress + ImageContext->SizeOfHeaders))); > + DEBUG ((DEBUG_ERROR, "remove-symbol-file %a 0x%08x\n", > + DeCygwinPathIfNeeded (ImageContext->PdbPointer, Temp, sizeof > + (Temp)), (UINTN)(ImageContext->ImageAddress + > + ImageContext->SizeOfHeaders))); > #else > - DEBUG ((EFI_D_ERROR, "Unloading %a\n", ImageContext->PdbPointer)); > + DEBUG ((DEBUG_ERROR, "Unloading %a\n", > + ImageContext->PdbPointer)); > #endif > } else { > - DEBUG ((EFI_D_ERROR, "Unloading driver at 0x%11p\n", (VOID *)(UINTN)= ImageContext->ImageAddress)); > + DEBUG ((DEBUG_ERROR, "Unloading driver at 0x%11p\n", (VOID > + *)(UINTN) ImageContext->ImageAddress)); > } > } > diff --git > a/ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.i > nf > b/ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.i > nf > index c1f717e5bd..38bf3993ae 100644 > --- > a/ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.i > nf > +++ b/ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionL > +++ ib.inf > @@ -33,7 +33,14 @@ > DebugPeCoffExtraActionLib.c > > [Packages] > + ArmPkg/ArmPkg.dec > MdePkg/MdePkg.dec > + StandaloneMmPkg/StandaloneMmPkg.dec > + > +[FeaturePcd] > + gStandaloneMmPkgTokenSpaceGuid.PcdStandaloneMmEnable > > [LibraryClasses] > + ArmMmuLib > DebugLib > + PcdLib > -- > 2.16.2 > IMPORTANT NOTICE: The contents of this email and any attachments are confid= ential and may also be privileged. If you are not the intended recipient, p= lease notify the sender immediately and do not disclose the contents to any= other person, use it for any purpose, or store or copy the information in = any medium. Thank you.