Implement the newly defined PPI that permits the PEI core and DXE IPL to
manage memory permissions on ranges of DRAM, for doing things like
mapping the stack non-executable, or granting executable permissions to
shadowed PEIMs.

Signed-off-by: Ard Biesheuvel <a...@kernel.org>
---
 ArmPkg/Drivers/CpuPei/CpuPei.c   | 78 ++++++++++++++++++--
 ArmPkg/Drivers/CpuPei/CpuPei.inf |  4 +
 2 files changed, 74 insertions(+), 8 deletions(-)

diff --git a/ArmPkg/Drivers/CpuPei/CpuPei.c b/ArmPkg/Drivers/CpuPei/CpuPei.c
index 85ef5ec07b9fdafa..d5996673260544c8 100644
--- a/ArmPkg/Drivers/CpuPei/CpuPei.c
+++ b/ArmPkg/Drivers/CpuPei/CpuPei.c
@@ -3,17 +3,10 @@
 Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
 Copyright (c) 2011 Hewlett Packard Corporation. All rights reserved.<BR>
 Copyright (c) 2011-2013, ARM Limited. All rights reserved.<BR>
+Copyright (c) 2023, Google, LLC. All rights reserved.<BR>
 
 SPDX-License-Identifier: BSD-2-Clause-Patent
 
-Module Name:
-
-  MemoryInit.c
-
-Abstract:
-
-  PEIM to provide fake memory init
-
 **/
 
 //
@@ -24,6 +17,7 @@ Module Name:
 // The protocols, PPI and GUID definitions for this module
 //
 #include <Ppi/ArmMpCoreInfo.h>
+#include <Ppi/MemoryAttribute.h>
 
 //
 // The Library classes this module consumes
@@ -34,6 +28,71 @@ Module Name:
 #include <Library/PcdLib.h>
 #include <Library/HobLib.h>
 #include <Library/ArmLib.h>
+#include <Library/ArmMmuLib.h>
+
+/**
+  Set the requested memory permission attributes on a region of memory.
+
+  BaseAddress and Length must be aligned to EFI_PAGE_SIZE.
+
+  Both SetMask and ClearMask may contain any combination of EFI_MEMORY_RP,
+  EFI_MEMORY_RO and EFI_MEMORY_XP, with the following restrictions:
+  - each constant may appear in either SetMask or ClearMask, but not in both;
+  - SetMask or ClearMask may be 0x0, but not both.
+
+  @param[in]  This            The protocol instance pointer.
+  @param[in]  BaseAddress     The physical address that is the start address of
+                              a memory region.
+  @param[in]  Length          The size in bytes of the memory region.
+  @param[in]  SetMask         Mask of memory attributes to set.
+  @param[in]  ClearMask       Mask of memory attributes to clear.
+
+  @retval EFI_SUCCESS           The attributes were set for the memory region.
+  @retval EFI_INVALID_PARAMETER Length is zero.
+                                Invalid combination of SetMask and ClearMask.
+                                BaseAddress or Length is not suitably aligned.
+  @retval EFI_UNSUPPORTED       The processor does not support one or more
+                                bytes of the memory resource range specified
+                                by BaseAddress and Length.
+                                The bit mask of attributes is not supported for
+                                the memory resource range specified by
+                                BaseAddress and Length.
+  @retval EFI_OUT_OF_RESOURCES  Requested attributes cannot be applied due to
+                                lack of system resources.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SetMemoryPermissions (
+  IN  EDKII_MEMORY_ATTRIBUTE_PPI  *This,
+  IN  EFI_PHYSICAL_ADDRESS        BaseAddress,
+  IN  UINT64                      Length,
+  IN  UINT64                      SetMask,
+  IN  UINT64                      ClearMask
+  )
+{
+  if ((Length == 0) ||
+      ((SetMask & ClearMask) != 0) ||
+      (((SetMask | ClearMask) & (EFI_MEMORY_RP | EFI_MEMORY_RO | 
EFI_MEMORY_XP)) == 0) ||
+      (((SetMask | ClearMask) & ~(UINT64)(EFI_MEMORY_RP | EFI_MEMORY_RO | 
EFI_MEMORY_XP)) != 0) ||
+      (((BaseAddress | Length) & EFI_PAGE_MASK) != 0))
+  {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return ArmSetMemoryAttributes (BaseAddress, Length, SetMask, SetMask | 
ClearMask);
+}
+
+STATIC CONST EDKII_MEMORY_ATTRIBUTE_PPI  mMemoryAttributePpi = {
+  SetMemoryPermissions
+};
+
+STATIC CONST EFI_PEI_PPI_DESCRIPTOR  mMemoryAttributePpiDesc = {
+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+  &gEdkiiMemoryAttributePpiGuid,
+  (VOID *)&mMemoryAttributePpi
+};
 
 /*++
 
@@ -79,5 +138,8 @@ InitializeCpuPeim (
     }
   }
 
+  Status = PeiServicesInstallPpi (&mMemoryAttributePpiDesc);
+  ASSERT_EFI_ERROR (Status);
+
   return EFI_SUCCESS;
 }
diff --git a/ArmPkg/Drivers/CpuPei/CpuPei.inf b/ArmPkg/Drivers/CpuPei/CpuPei.inf
index 648f27adf9402435..2ca4f795c62de394 100644
--- a/ArmPkg/Drivers/CpuPei/CpuPei.inf
+++ b/ArmPkg/Drivers/CpuPei/CpuPei.inf
@@ -3,6 +3,7 @@
 #
 # This module provides platform specific function to detect boot mode.
 # Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2023, Google, LLC. All rights reserved.<BR>
 #
 #  SPDX-License-Identifier: BSD-2-Clause-Patent
 #
@@ -28,6 +29,7 @@ [Sources]
   CpuPei.c
 
 [Packages]
+  MdeModulePkg/MdeModulePkg.dec
   MdePkg/MdePkg.dec
   EmbeddedPkg/EmbeddedPkg.dec
   ArmPkg/ArmPkg.dec
@@ -37,9 +39,11 @@ [LibraryClasses]
   DebugLib
   HobLib
   ArmLib
+  ArmMmuLib
 
 [Ppis]
   gArmMpCoreInfoPpiGuid
+  gEdkiiMemoryAttributePpiGuid
 
 [Guids]
   gArmMpCoreInfoGuid
-- 
2.39.2



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#105306): https://edk2.groups.io/g/devel/message/105306
Mute This Topic: https://groups.io/mt/99131185/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-


Reply via email to