[edk2-devel] [RFC PATCH 06/10] ArmPkg/CpuPei: Implement the memory attributes PPI

Ard Biesheuvel posted 10 patches 1 year, 3 months ago
There is a newer version of this series
[edk2-devel] [RFC PATCH 06/10] ArmPkg/CpuPei: Implement the memory attributes PPI
Posted by Ard Biesheuvel 1 year, 3 months ago
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 <ardb@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/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-