[edk2-devel] [PATCH 08/14] MdeModulePkg: Update to use memory protection HOB

Taylor Beebe t at taylorbeebe.com
Tue Jul 11 23:52:45 UTC 2023


From: Taylor Beebe <tabeebe at microsoft.com>

Replace references to the memory protection PCDs with references
to the memory protection HOB.

The memory protection HOB will be ingested during handoff to check
the memory proteciton settings when creating the page tables.

This patch also adjusts the logic for the memory protection callback
to apply protections one at a time (first NX, then stack protections,
then NULL protection etc.) with a debug print before each application
to help narrow down memory integrity related issues if they occur
when applying protections.

Signed-off-by: Taylor Beebe <t at taylorbeebe.com>
Cc: Jian J Wang <jian.j.wang at intel.com>
Cc: Liming Gao <gaoliming at byosoft.com.cn>
Cc: Dandan Bi <dandan.bi at intel.com>
---
 MdeModulePkg/Core/Dxe/DxeMain.h               |   1 +
 MdeModulePkg/Core/Dxe/DxeMain.inf             |   9 +-
 MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c       |   8 +-
 MdeModulePkg/Core/Dxe/Mem/HeapGuard.c         |  88 ++---
 MdeModulePkg/Core/Dxe/Mem/HeapGuard.h         |  24 +-
 MdeModulePkg/Core/Dxe/Mem/Page.c              |   4 +-
 MdeModulePkg/Core/Dxe/Mem/Pool.c              |   6 +-
 MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c | 338 ++++++++++--------
 MdeModulePkg/Core/DxeIplPeim/DxeHandoff.c     |   4 +-
 MdeModulePkg/Core/DxeIplPeim/DxeIpl.h         |  15 +
 MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf       |  13 +-
 MdeModulePkg/Core/DxeIplPeim/DxeLoad.c        |  26 ++
 .../Core/DxeIplPeim/Ia32/DxeLoadFunc.c        |  57 +--
 .../Core/DxeIplPeim/X64/DxeLoadFunc.c         |  20 +-
 .../Core/DxeIplPeim/X64/VirtualMemory.c       |  87 ++---
 .../Core/DxeIplPeim/X64/VirtualMemory.h       |  23 +-
 MdeModulePkg/Core/PiSmmCore/HeapGuard.c       |  60 +---
 MdeModulePkg/Core/PiSmmCore/HeapGuard.h       |  20 +-
 MdeModulePkg/Core/PiSmmCore/Page.c            |   6 +-
 MdeModulePkg/Core/PiSmmCore/PiSmmCore.h       |   1 +
 MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf     |   4 +-
 MdeModulePkg/Core/PiSmmCore/Pool.c            |   9 +-
 22 files changed, 367 insertions(+), 456 deletions(-)

diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h
index 43daa037be..9da87a33a9 100644
--- a/MdeModulePkg/Core/Dxe/DxeMain.h
+++ b/MdeModulePkg/Core/Dxe/DxeMain.h
@@ -84,6 +84,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include <Library/DxeServicesLib.h>
 #include <Library/DebugAgentLib.h>
 #include <Library/CpuExceptionHandlerLib.h>
+#include <Library/DxeMemoryProtectionHobLib.h>
 
 //
 // attributes for reserved memory before it is promoted to system memory
diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf
index 35d5bf0dee..3cbd1ae923 100644
--- a/MdeModulePkg/Core/Dxe/DxeMain.inf
+++ b/MdeModulePkg/Core/Dxe/DxeMain.inf
@@ -94,6 +94,7 @@
   DebugAgentLib
   CpuExceptionHandlerLib
   PcdLib
+  DxeMemoryProtectionHobLib
 
 [Guids]
   gEfiEventMemoryMapChangeGuid                  ## PRODUCES             ## Event
@@ -123,6 +124,7 @@
   gEfiMemoryAttributesTableGuid                 ## SOMETIMES_PRODUCES   ## SystemTable
   gEfiEndOfDxeEventGroupGuid                    ## SOMETIMES_CONSUMES   ## Event
   gEfiHobMemoryAllocStackGuid                   ## SOMETIMES_CONSUMES   ## SystemTable
+  gDxeMemoryProtectionSettingsGuid              ## CONSUMES             ## HOB
 
 [Ppis]
   gEfiVectorHandoffInfoPpiGuid                  ## UNDEFINED # HOB
@@ -179,13 +181,6 @@
   gEfiMdeModulePkgTokenSpaceGuid.PcdMemoryProfileMemoryType                 ## CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdMemoryProfilePropertyMask               ## CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdMemoryProfileDriverPath                 ## CONSUMES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy                   ## CONSUMES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy             ## CONSUMES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask        ## CONSUMES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPageType                       ## CONSUMES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPoolType                       ## CONSUMES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask                   ## CONSUMES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard                           ## CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdFwVolDxeMaxEncapsulationDepth           ## CONSUMES
 
 # [Hob]
diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c
index 0e0f9769b9..5bcef4f399 100644
--- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c
+++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c
@@ -257,9 +257,13 @@ DxeMain (
   ASSERT_EFI_ERROR (Status);
 
   //
-  // Setup Stack Guard
+  // Get the memory protection HOB entry and setup stack guard
   //
-  if (PcdGetBool (PcdCpuStackGuard)) {
+  GuidHob = GetFirstGuidHob (&gDxeMemoryProtectionSettingsGuid);
+  if ((GuidHob != NULL) &&
+      DXE_MPS_IS_STRUCT_VALID (GET_GUID_HOB_DATA (GuidHob)) &&
+      ((DXE_MEMORY_PROTECTION_SETTINGS *)GET_GUID_HOB_DATA (GuidHob))->CpuStackGuardEnabled)
+  {
     Status = InitializeSeparateExceptionStacks (NULL, NULL);
     ASSERT_EFI_ERROR (Status);
   }
diff --git a/MdeModulePkg/Core/Dxe/Mem/HeapGuard.c b/MdeModulePkg/Core/Dxe/Mem/HeapGuard.c
index 9377f620c5..0b9008ad51 100644
--- a/MdeModulePkg/Core/Dxe/Mem/HeapGuard.c
+++ b/MdeModulePkg/Core/Dxe/Mem/HeapGuard.c
@@ -553,7 +553,7 @@ UnsetGuardPage (
   // memory.
   //
   Attributes = 0;
-  if ((PcdGet64 (PcdDxeNxMemoryProtectionPolicy) & (1 << EfiConventionalMemory)) != 0) {
+  if (gDxeMps.ExecutionProtection.EnabledForType[EfiConventionalMemory]) {
     Attributes |= EFI_MEMORY_XP;
   }
 
@@ -577,7 +577,7 @@ UnsetGuardPage (
 
   @param[in]  MemoryType      Memory type to check.
   @param[in]  AllocateType    Allocation type to check.
-  @param[in]  PageOrPool      Indicate a page allocation or pool allocation.
+  @param[in]  HeapGuardType   Indicates the heap guard type.
 
 
   @return TRUE  The given type of memory should be guarded.
@@ -587,41 +587,32 @@ BOOLEAN
 IsMemoryTypeToGuard (
   IN EFI_MEMORY_TYPE    MemoryType,
   IN EFI_ALLOCATE_TYPE  AllocateType,
-  IN UINT8              PageOrPool
+  IN HEAP_GUARD_TYPE    HeapGuardType
   )
 {
-  UINT64  TestBit;
-  UINT64  ConfigBit;
-
   if (AllocateType == AllocateAddress) {
     return FALSE;
   }
 
-  if ((PcdGet8 (PcdHeapGuardPropertyMask) & PageOrPool) == 0) {
-    return FALSE;
-  }
-
-  if (PageOrPool == GUARD_HEAP_TYPE_POOL) {
-    ConfigBit = PcdGet64 (PcdHeapGuardPoolType);
-  } else if (PageOrPool == GUARD_HEAP_TYPE_PAGE) {
-    ConfigBit = PcdGet64 (PcdHeapGuardPageType);
-  } else {
-    ConfigBit = (UINT64)-1;
-  }
+  UINT32  TestMemoryType;
 
   if ((UINT32)MemoryType >= MEMORY_TYPE_OS_RESERVED_MIN) {
-    TestBit = BIT63;
+    TestMemoryType = OS_RESERVED_MPS_MEMORY_TYPE;
   } else if ((UINT32)MemoryType >= MEMORY_TYPE_OEM_RESERVED_MIN) {
-    TestBit = BIT62;
-  } else if (MemoryType < EfiMaxMemoryType) {
-    TestBit = LShiftU64 (1, MemoryType);
-  } else if (MemoryType == EfiMaxMemoryType) {
-    TestBit = (UINT64)-1;
+    TestMemoryType = OEM_RESERVED_MPS_MEMORY_TYPE;
+  } else if (MemoryType >= EfiMaxMemoryType) {
+    return TRUE;
   } else {
-    TestBit = 0;
+    TestMemoryType = MemoryType;
+  }
+
+  if ((HeapGuardType == HeapGuardTypePool) && gDxeMps.HeapGuard.PoolGuardEnabled) {
+    return gDxeMps.PoolGuard.EnabledForType[TestMemoryType];
+  } else if ((HeapGuardType == HeapGuardTypePage) && gDxeMps.HeapGuard.PageGuardEnabled) {
+    return gDxeMps.PageGuard.EnabledForType[TestMemoryType];
   }
 
-  return ((ConfigBit & TestBit) != 0);
+  return FALSE;
 }
 
 /**
@@ -641,7 +632,7 @@ IsPoolTypeToGuard (
   return IsMemoryTypeToGuard (
            MemoryType,
            AllocateAnyPages,
-           GUARD_HEAP_TYPE_POOL
+           HeapGuardTypePool
            );
 }
 
@@ -660,22 +651,7 @@ IsPageTypeToGuard (
   IN EFI_ALLOCATE_TYPE  AllocateType
   )
 {
-  return IsMemoryTypeToGuard (MemoryType, AllocateType, GUARD_HEAP_TYPE_PAGE);
-}
-
-/**
-  Check to see if the heap guard is enabled for page and/or pool allocation.
-
-  @param[in]  GuardType   Specify the sub-type(s) of Heap Guard.
-
-  @return TRUE/FALSE.
-**/
-BOOLEAN
-IsHeapGuardEnabled (
-  UINT8  GuardType
-  )
-{
-  return IsMemoryTypeToGuard (EfiMaxMemoryType, AllocateAnyPages, GuardType);
+  return IsMemoryTypeToGuard (MemoryType, AllocateType, HeapGuardTypePage);
 }
 
 /**
@@ -835,7 +811,7 @@ AdjustMemoryS (
   // indicated to put the pool near the Tail Guard, we need extra bytes to
   // make sure alignment of the returned pool address.
   //
-  if ((PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) == 0) {
+  if (gDxeMps.HeapGuard.GuardAlignedToTail) {
     SizeRequested = ALIGN_VALUE (SizeRequested, 8);
   }
 
@@ -1019,7 +995,7 @@ AdjustPoolHeadA (
   IN UINTN                 Size
   )
 {
-  if ((Memory == 0) || ((PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) != 0)) {
+  if ((Memory == 0) || (!gDxeMps.HeapGuard.GuardAlignedToTail)) {
     //
     // Pool head is put near the head Guard
     //
@@ -1045,7 +1021,7 @@ AdjustPoolHeadF (
   IN EFI_PHYSICAL_ADDRESS  Memory
   )
 {
-  if ((Memory == 0) || ((PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) != 0)) {
+  if ((Memory == 0) || (!gDxeMps.HeapGuard.GuardAlignedToTail)) {
     //
     // Pool head is put near the head Guard
     //
@@ -1344,7 +1320,7 @@ GuardFreedPagesChecked (
   IN  UINTN                 Pages
   )
 {
-  if (IsHeapGuardEnabled (GUARD_HEAP_TYPE_FREED)) {
+  if (gDxeMps.HeapGuard.FreedMemoryGuardEnabled) {
     GuardFreedPages (BaseAddress, Pages);
   }
 }
@@ -1469,7 +1445,7 @@ MergeGuardPages (
   UINT64                Bitmap;
   INTN                  Pages;
 
-  if (!IsHeapGuardEnabled (GUARD_HEAP_TYPE_FREED) ||
+  if ((!gDxeMps.HeapGuard.FreedMemoryGuardEnabled) ||
       (MemoryMapEntry->Type >= EfiMemoryMappedIO))
   {
     return;
@@ -1525,7 +1501,7 @@ PromoteGuardedFreePages (
   UINT64                Bitmap;
   EFI_PHYSICAL_ADDRESS  Start;
 
-  if (!IsHeapGuardEnabled (GUARD_HEAP_TYPE_FREED)) {
+  if (!gDxeMps.HeapGuard.FreedMemoryGuardEnabled) {
     return FALSE;
   }
 
@@ -1594,18 +1570,21 @@ HeapGuardCpuArchProtocolNotify (
 {
   ASSERT (gCpu != NULL);
 
-  if (IsHeapGuardEnabled (GUARD_HEAP_TYPE_PAGE|GUARD_HEAP_TYPE_POOL) &&
-      IsHeapGuardEnabled (GUARD_HEAP_TYPE_FREED))
+  if ((gDxeMps.HeapGuard.PageGuardEnabled ||
+       gDxeMps.HeapGuard.PoolGuardEnabled) &&
+      gDxeMps.HeapGuard.FreedMemoryGuardEnabled)
   {
     DEBUG ((DEBUG_ERROR, "Heap guard and freed memory guard cannot be enabled at the same time.\n"));
     CpuDeadLoop ();
   }
 
-  if (IsHeapGuardEnabled (GUARD_HEAP_TYPE_PAGE|GUARD_HEAP_TYPE_POOL)) {
+  if (gDxeMps.HeapGuard.PageGuardEnabled ||
+      gDxeMps.HeapGuard.PoolGuardEnabled)
+  {
     SetAllGuardPages ();
   }
 
-  if (IsHeapGuardEnabled (GUARD_HEAP_TYPE_FREED)) {
+  if (gDxeMps.HeapGuard.FreedMemoryGuardEnabled) {
     GuardAllFreedPages ();
   }
 }
@@ -1660,7 +1639,10 @@ DumpGuardedMemoryBitmap (
   CHAR8   *Ruler1;
   CHAR8   *Ruler2;
 
-  if (!IsHeapGuardEnabled (GUARD_HEAP_TYPE_ALL)) {
+  if (!gDxeMps.HeapGuard.FreedMemoryGuardEnabled &&
+      !gDxeMps.HeapGuard.PageGuardEnabled &&
+      !gDxeMps.HeapGuard.PoolGuardEnabled)
+  {
     return;
   }
 
diff --git a/MdeModulePkg/Core/Dxe/Mem/HeapGuard.h b/MdeModulePkg/Core/Dxe/Mem/HeapGuard.h
index 9a32b4dd51..b90afae615 100644
--- a/MdeModulePkg/Core/Dxe/Mem/HeapGuard.h
+++ b/MdeModulePkg/Core/Dxe/Mem/HeapGuard.h
@@ -150,13 +150,13 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
   }
 
 //
-// Memory type to guard (matching the related PCD definition)
+// Heap guard types
 //
-#define GUARD_HEAP_TYPE_PAGE   BIT0
-#define GUARD_HEAP_TYPE_POOL   BIT1
-#define GUARD_HEAP_TYPE_FREED  BIT4
-#define GUARD_HEAP_TYPE_ALL         \
-        (GUARD_HEAP_TYPE_PAGE|GUARD_HEAP_TYPE_POOL|GUARD_HEAP_TYPE_FREED)
+typedef enum {
+  HeapGuardTypePage,
+  HeapGuardTypePool,
+  HeapGuardTypeMax
+} HEAP_GUARD_TYPE;
 
 //
 // Debug message level
@@ -386,18 +386,6 @@ AdjustPoolHeadF (
   IN EFI_PHYSICAL_ADDRESS  Memory
   );
 
-/**
-  Check to see if the heap guard is enabled for page and/or pool allocation.
-
-  @param[in]  GuardType   Specify the sub-type(s) of Heap Guard.
-
-  @return TRUE/FALSE.
-**/
-BOOLEAN
-IsHeapGuardEnabled (
-  UINT8  GuardType
-  );
-
 /**
   Notify function used to set all Guard pages after CPU Arch Protocol installed.
 **/
diff --git a/MdeModulePkg/Core/Dxe/Mem/Page.c b/MdeModulePkg/Core/Dxe/Mem/Page.c
index 41af50b3d5..848562ff21 100644
--- a/MdeModulePkg/Core/Dxe/Mem/Page.c
+++ b/MdeModulePkg/Core/Dxe/Mem/Page.c
@@ -181,7 +181,7 @@ CoreAddRange (
   // used for other purposes.
   //
   if ((Type == EfiConventionalMemory) && (Start == 0) && (End >= EFI_PAGE_SIZE - 1)) {
-    if ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & BIT0) == 0) {
+    if (!gDxeMps.NullPointerDetection.Enabled) {
       SetMem ((VOID *)(UINTN)Start, EFI_PAGE_SIZE, 0);
     }
   }
@@ -918,7 +918,7 @@ CoreConvertPagesEx (
     // Add our new range in. Don't do this for freed pages if freed-memory
     // guard is enabled.
     //
-    if (!IsHeapGuardEnabled (GUARD_HEAP_TYPE_FREED) ||
+    if (!gDxeMps.HeapGuard.FreedMemoryGuardEnabled ||
         !ChangingType ||
         (MemType != EfiConventionalMemory))
     {
diff --git a/MdeModulePkg/Core/Dxe/Mem/Pool.c b/MdeModulePkg/Core/Dxe/Mem/Pool.c
index b20cbfdedb..65f90f7922 100644
--- a/MdeModulePkg/Core/Dxe/Mem/Pool.c
+++ b/MdeModulePkg/Core/Dxe/Mem/Pool.c
@@ -385,8 +385,8 @@ CoreAllocatePoolI (
   //
 
   HasPoolTail = !(NeedGuard &&
-                  ((PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) == 0));
-  PageAsPool = (IsHeapGuardEnabled (GUARD_HEAP_TYPE_FREED) && !mOnGuarding);
+                  gDxeMps.HeapGuard.GuardAlignedToTail);
+  PageAsPool = (gDxeMps.HeapGuard.FreedMemoryGuardEnabled && !mOnGuarding);
 
   //
   // Adjusting the Size to be of proper alignment so that
@@ -717,7 +717,7 @@ CoreFreePoolI (
   IsGuarded = IsPoolTypeToGuard (Head->Type) &&
               IsMemoryGuarded ((EFI_PHYSICAL_ADDRESS)(UINTN)Head);
   HasPoolTail = !(IsGuarded &&
-                  ((PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) == 0));
+                  gDxeMps.HeapGuard.GuardAlignedToTail);
   PageAsPool = (Head->Signature == POOLPAGE_HEAD_SIGNATURE);
 
   if (HasPoolTail) {
diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c
index 7cc829b174..75aefa7514 100644
--- a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c
+++ b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c
@@ -9,7 +9,7 @@
   2) This policy is applied only if the UEFI image meets the page alignment
      requirement.
   3) This policy is applied only if the Source UEFI image matches the
-     PcdImageProtectionPolicy definition.
+     Image Protection Policy definition.
   4) This policy is not applied to the non-PE image region.
 
   The DxeCore calls CpuArchProtocol->SetMemoryAttributes() to protect
@@ -60,7 +60,9 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #define PREVIOUS_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \
   ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) - (Size)))
 
-UINT32  mImageProtectionPolicy;
+STATIC BOOLEAN  mIsExecutionProtectionActive = FALSE;
+
+STATIC BOOLEAN  mIsPageOrPoolGuardActive = FALSE;
 
 extern LIST_ENTRY  mGcdMemorySpaceMap;
 
@@ -149,11 +151,13 @@ GetProtectionPolicyFromImageType (
   IN UINT32  ImageType
   )
 {
-  if ((ImageType & mImageProtectionPolicy) == 0) {
-    return DO_NOT_PROTECT;
-  } else {
+  if (((ImageType == IMAGE_UNKNOWN) && gDxeMps.ImageProtection.ProtectImageFromUnknown) ||
+      ((ImageType == IMAGE_FROM_FV) && gDxeMps.ImageProtection.ProtectImageFromFv))
+  {
     return PROTECT_IF_ALIGNED_ELSE_ALLOW;
   }
+
+  return DO_NOT_PROTECT;
 }
 
 /**
@@ -611,27 +615,25 @@ UnprotectUefiImage (
   IMAGE_PROPERTIES_RECORD  *ImageRecord;
   LIST_ENTRY               *ImageRecordLink;
 
-  if (PcdGet32 (PcdImageProtectionPolicy) != 0) {
-    for (ImageRecordLink = mProtectedImageRecordList.ForwardLink;
-         ImageRecordLink != &mProtectedImageRecordList;
-         ImageRecordLink = ImageRecordLink->ForwardLink)
-    {
-      ImageRecord = CR (
-                      ImageRecordLink,
-                      IMAGE_PROPERTIES_RECORD,
-                      Link,
-                      IMAGE_PROPERTIES_RECORD_SIGNATURE
-                      );
-
-      if (ImageRecord->ImageBase == (EFI_PHYSICAL_ADDRESS)(UINTN)LoadedImage->ImageBase) {
-        SetUefiImageMemoryAttributes (
-          ImageRecord->ImageBase,
-          ImageRecord->ImageSize,
-          0
-          );
-        FreeImageRecord (ImageRecord);
-        return;
-      }
+  for (ImageRecordLink = mProtectedImageRecordList.ForwardLink;
+       ImageRecordLink != &mProtectedImageRecordList;
+       ImageRecordLink = ImageRecordLink->ForwardLink)
+  {
+    ImageRecord = CR (
+                    ImageRecordLink,
+                    IMAGE_PROPERTIES_RECORD,
+                    Link,
+                    IMAGE_PROPERTIES_RECORD_SIGNATURE
+                    );
+
+    if (ImageRecord->ImageBase == (EFI_PHYSICAL_ADDRESS)(UINTN)LoadedImage->ImageBase) {
+      SetUefiImageMemoryAttributes (
+        ImageRecord->ImageBase,
+        ImageRecord->ImageSize,
+        0
+        );
+      FreeImageRecord (ImageRecord);
+      return;
     }
   }
 }
@@ -648,21 +650,24 @@ GetPermissionAttributeForMemoryType (
   IN EFI_MEMORY_TYPE  MemoryType
   )
 {
-  UINT64  TestBit;
+  UINT32  TestMemoryType;
 
   if ((UINT32)MemoryType >= MEMORY_TYPE_OS_RESERVED_MIN) {
-    TestBit = BIT63;
+    TestMemoryType = OS_RESERVED_MPS_MEMORY_TYPE;
   } else if ((UINT32)MemoryType >= MEMORY_TYPE_OEM_RESERVED_MIN) {
-    TestBit = BIT62;
+    TestMemoryType = OEM_RESERVED_MPS_MEMORY_TYPE;
+  } else if (MemoryType >= EfiMaxMemoryType) {
+    // If the memory type is not defined in the UEFI spec, return EFI_MEMORY_XP
+    return EFI_MEMORY_XP;
   } else {
-    TestBit = LShiftU64 (1, MemoryType);
+    TestMemoryType = MemoryType;
   }
 
-  if ((PcdGet64 (PcdDxeNxMemoryProtectionPolicy) & TestBit) != 0) {
+  if (gDxeMps.ExecutionProtection.EnabledForType[TestMemoryType]) {
     return EFI_MEMORY_XP;
-  } else {
-    return 0;
   }
+
+  return 0;
 }
 
 /**
@@ -771,8 +776,8 @@ MergeMemoryMapForProtectionPolicy (
 }
 
 /**
-  Remove exec permissions from all regions whose type is identified by
-  PcdDxeNxMemoryProtectionPolicy.
+  Remove execution permissions from all regions whose memory type is identified by
+  the DXE Execution Protection Policy.
 **/
 STATIC
 VOID
@@ -780,20 +785,17 @@ InitializeDxeNxMemoryProtectionPolicy (
   VOID
   )
 {
-  UINTN                      MemoryMapSize;
-  UINTN                      MapKey;
-  UINTN                      DescriptorSize;
-  UINT32                     DescriptorVersion;
-  EFI_MEMORY_DESCRIPTOR      *MemoryMap;
-  EFI_MEMORY_DESCRIPTOR      *MemoryMapEntry;
-  EFI_MEMORY_DESCRIPTOR      *MemoryMapEnd;
-  EFI_STATUS                 Status;
-  UINT64                     Attributes;
-  LIST_ENTRY                 *Link;
-  EFI_GCD_MAP_ENTRY          *Entry;
-  EFI_PEI_HOB_POINTERS       Hob;
-  EFI_HOB_MEMORY_ALLOCATION  *MemoryHob;
-  EFI_PHYSICAL_ADDRESS       StackBase;
+  UINTN                  MemoryMapSize;
+  UINTN                  MapKey;
+  UINTN                  DescriptorSize;
+  UINT32                 DescriptorVersion;
+  EFI_MEMORY_DESCRIPTOR  *MemoryMap;
+  EFI_MEMORY_DESCRIPTOR  *MemoryMapEntry;
+  EFI_MEMORY_DESCRIPTOR  *MemoryMapEnd;
+  EFI_STATUS             Status;
+  UINT64                 Attributes;
+  LIST_ENTRY             *Link;
+  EFI_GCD_MAP_ENTRY      *Entry;
 
   //
   // Get the EFI memory map.
@@ -826,41 +828,6 @@ InitializeDxeNxMemoryProtectionPolicy (
 
   ASSERT_EFI_ERROR (Status);
 
-  StackBase = 0;
-  if (PcdGetBool (PcdCpuStackGuard)) {
-    //
-    // Get the base of stack from Hob.
-    //
-    Hob.Raw = GetHobList ();
-    while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) {
-      MemoryHob = Hob.MemoryAllocation;
-      if (CompareGuid (&gEfiHobMemoryAllocStackGuid, &MemoryHob->AllocDescriptor.Name)) {
-        DEBUG ((
-          DEBUG_INFO,
-          "%a: StackBase = 0x%016lx  StackSize = 0x%016lx\n",
-          __func__,
-          MemoryHob->AllocDescriptor.MemoryBaseAddress,
-          MemoryHob->AllocDescriptor.MemoryLength
-          ));
-
-        StackBase = MemoryHob->AllocDescriptor.MemoryBaseAddress;
-        //
-        // Ensure the base of the stack is page-size aligned.
-        //
-        ASSERT ((StackBase & EFI_PAGE_MASK) == 0);
-        break;
-      }
-
-      Hob.Raw = GET_NEXT_HOB (Hob);
-    }
-
-    //
-    // Ensure the base of stack can be found from Hob when stack guard is
-    // enabled.
-    //
-    ASSERT (StackBase != 0);
-  }
-
   DEBUG ((
     DEBUG_INFO,
     "%a: applying strict permissions to active memory regions\n",
@@ -879,38 +846,6 @@ InitializeDxeNxMemoryProtectionPolicy (
         LShiftU64 (MemoryMapEntry->NumberOfPages, EFI_PAGE_SHIFT),
         Attributes
         );
-
-      //
-      // Add EFI_MEMORY_RP attribute for page 0 if NULL pointer detection is
-      // enabled.
-      //
-      if ((MemoryMapEntry->PhysicalStart == 0) &&
-          (PcdGet8 (PcdNullPointerDetectionPropertyMask) != 0))
-      {
-        ASSERT (MemoryMapEntry->NumberOfPages > 0);
-        SetUefiImageMemoryAttributes (
-          0,
-          EFI_PAGES_TO_SIZE (1),
-          EFI_MEMORY_RP | Attributes
-          );
-      }
-
-      //
-      // Add EFI_MEMORY_RP attribute for the first page of the stack if stack
-      // guard is enabled.
-      //
-      if ((StackBase != 0) &&
-          ((StackBase >= MemoryMapEntry->PhysicalStart) &&
-           (StackBase <  MemoryMapEntry->PhysicalStart +
-            LShiftU64 (MemoryMapEntry->NumberOfPages, EFI_PAGE_SHIFT))) &&
-          PcdGetBool (PcdCpuStackGuard))
-      {
-        SetUefiImageMemoryAttributes (
-          StackBase,
-          EFI_PAGES_TO_SIZE (1),
-          EFI_MEMORY_RP | Attributes
-          );
-      }
     }
 
     MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
@@ -968,18 +903,68 @@ InitializeDxeNxMemoryProtectionPolicy (
 }
 
 /**
-  A notification for CPU_ARCH protocol.
+  Initialize stack guard and stack execution protection.
+**/
+STATIC
+VOID
+InitializeDxeStackMemoryProtectionPolicy (
+  VOID
+  )
+{
+  EFI_HOB_MEMORY_ALLOCATION  *MemoryHob;
+  EFI_PEI_HOB_POINTERS       Hob;
+  EFI_PHYSICAL_ADDRESS       StackBase;
+  UINT64                     StackLength;
 
-  @param[in]  Event                 Event whose notification function is being invoked.
-  @param[in]  Context               Pointer to the notification function's context,
-                                    which is implementation-dependent.
+  StackBase   = 0;
+  StackLength = 0;
+
+  // Get the base of stack from the HOB.
+  Hob.Raw = GetHobList ();
+  while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) {
+    MemoryHob = Hob.MemoryAllocation;
+    if (CompareGuid (&gEfiHobMemoryAllocStackGuid, &MemoryHob->AllocDescriptor.Name)) {
+      StackBase   = MemoryHob->AllocDescriptor.MemoryBaseAddress;
+      StackLength = MemoryHob->AllocDescriptor.MemoryLength;
+
+      ASSERT ((StackBase & EFI_PAGE_MASK) == 0);
+      ASSERT ((StackLength & EFI_PAGE_MASK) == 0);
+      break;
+    }
+
+    Hob.Raw = GET_NEXT_HOB (Hob);
+  }
+
+  ASSERT (StackBase != 0);
+  ASSERT (StackLength != 0);
+  if ((StackBase != 0) && (StackLength != 0)) {
+    // Set EFI_MEMORY_XP if stack execution protection is enabled.
+    if (gDxeMps.StackExecutionProtectionEnabled) {
+      SetUefiImageMemoryAttributes (
+        StackBase,
+        StackLength,
+        EFI_MEMORY_XP
+        );
+    }
 
+    // Set EFI_MEMORY_RP if stack guard is enabled.
+    if (gDxeMps.CpuStackGuardEnabled) {
+      SetUefiImageMemoryAttributes (
+        StackBase,
+        EFI_PAGE_SIZE,
+        gDxeMps.StackExecutionProtectionEnabled ? (EFI_MEMORY_XP | EFI_MEMORY_RP) : EFI_MEMORY_RP
+        );
+    }
+  }
+}
+
+/**
+  Initialize the DXE image protection policy.
 **/
+STATIC
 VOID
-EFIAPI
-MemoryProtectionCpuArchProtocolNotify (
-  IN EFI_EVENT  Event,
-  IN VOID       *Context
+InitializeDxeImageMemoryProtectionPolicy (
+  VOID
   )
 {
   EFI_STATUS                 Status;
@@ -989,28 +974,6 @@ MemoryProtectionCpuArchProtocolNotify (
   EFI_HANDLE                 *HandleBuffer;
   UINTN                      Index;
 
-  DEBUG ((DEBUG_INFO, "MemoryProtectionCpuArchProtocolNotify:\n"));
-  Status = CoreLocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&gCpu);
-  if (EFI_ERROR (Status)) {
-    goto Done;
-  }
-
-  //
-  // Apply the memory protection policy on non-BScode/RTcode regions.
-  //
-  if (PcdGet64 (PcdDxeNxMemoryProtectionPolicy) != 0) {
-    InitializeDxeNxMemoryProtectionPolicy ();
-  }
-
-  //
-  // Call notify function meant for Heap Guard.
-  //
-  HeapGuardCpuArchProtocolNotify ();
-
-  if (mImageProtectionPolicy == 0) {
-    goto Done;
-  }
-
   Status = gBS->LocateHandleBuffer (
                   ByProtocol,
                   &gEfiLoadedImageProtocolGuid,
@@ -1019,7 +982,7 @@ MemoryProtectionCpuArchProtocolNotify (
                   &HandleBuffer
                   );
   if (EFI_ERROR (Status) && (NoHandles == 0)) {
-    goto Done;
+    return;
   }
 
   for (Index = 0; Index < NoHandles; Index++) {
@@ -1045,6 +1008,65 @@ MemoryProtectionCpuArchProtocolNotify (
   }
 
   FreePool (HandleBuffer);
+}
+
+/**
+  A notification for CPU_ARCH protocol.
+
+  @param[in]  Event                 Event whose notification function is being invoked.
+  @param[in]  Context               Pointer to the notification function's context,
+                                    which is implementation-dependent.
+
+**/
+VOID
+EFIAPI
+MemoryProtectionCpuArchProtocolNotify (
+  IN EFI_EVENT  Event,
+  IN VOID       *Context
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = CoreLocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&gCpu);
+  if (EFI_ERROR (Status)) {
+    goto Done;
+  }
+
+  if (DXE_MPS_IS_EXECUTION_PROTECTION_ENABLED (&gDxeMps)) {
+    DEBUG ((DEBUG_INFO, "Applying DXE Execution Protection Policy\n"));
+    mIsExecutionProtectionActive = TRUE;
+    InitializeDxeNxMemoryProtectionPolicy ();
+  }
+
+  if (gDxeMps.NullPointerDetection.Enabled) {
+    DEBUG ((DEBUG_INFO, "Applying NULL Detection\n"));
+    SetUefiImageMemoryAttributes (
+      (UINTN)NULL,
+      EFI_PAGE_SIZE,
+      gDxeMps.ExecutionProtection.EnabledForType[EfiBootServicesData] ?
+      (EFI_MEMORY_XP | EFI_MEMORY_RP) : EFI_MEMORY_RP
+      );
+  }
+
+  if (gDxeMps.CpuStackGuardEnabled || gDxeMps.StackExecutionProtectionEnabled) {
+    DEBUG ((DEBUG_INFO, "Applying DXE Stack Protection Policy\n"));
+    InitializeDxeStackMemoryProtectionPolicy ();
+  }
+
+  if (gDxeMps.HeapGuard.PageGuardEnabled ||
+      gDxeMps.HeapGuard.PoolGuardEnabled ||
+      gDxeMps.HeapGuard.FreedMemoryGuardEnabled)
+  {
+    DEBUG ((DEBUG_INFO, "Applying DXE Heap Guard Protection Policy\n"));
+    mIsPageOrPoolGuardActive = gDxeMps.HeapGuard.PageGuardEnabled ||
+                               gDxeMps.HeapGuard.PoolGuardEnabled;
+    HeapGuardCpuArchProtocolNotify ();
+  }
+
+  if (DXE_MPS_IS_IMAGE_PROTECTION_ENABLED (&gDxeMps)) {
+    DEBUG ((DEBUG_INFO, "Applying DXE Image Protection Policy\n"));
+    InitializeDxeImageMemoryProtectionPolicy ();
+  }
 
 Done:
   CoreCloseEvent (Event);
@@ -1070,7 +1092,7 @@ MemoryProtectionExitBootServicesCallback (
   // delay setting protections on RT code pages until after SetVirtualAddressMap().
   // OS may set protection on RT based upon EFI_MEMORY_ATTRIBUTES_TABLE later.
   //
-  if (mImageProtectionPolicy != 0) {
+  if (DXE_MPS_IS_IMAGE_PROTECTION_ENABLED (&gDxeMps)) {
     for (Link = gRuntime->ImageHead.ForwardLink; Link != &gRuntime->ImageHead; Link = Link->ForwardLink) {
       RuntimeImage = BASE_CR (Link, EFI_RUNTIME_IMAGE_ENTRY, Link);
       SetUefiImageMemoryAttributes ((UINT64)(UINTN)RuntimeImage->ImageBase, ALIGN_VALUE (RuntimeImage->ImageSize, EFI_PAGE_SIZE), 0);
@@ -1144,19 +1166,17 @@ CoreInitializeMemoryProtection (
   EFI_EVENT   EndOfDxeEvent;
   VOID        *Registration;
 
-  mImageProtectionPolicy = PcdGet32 (PcdImageProtectionPolicy);
-
   InitializeListHead (&mProtectedImageRecordList);
 
   //
-  // Sanity check the PcdDxeNxMemoryProtectionPolicy setting:
+  // Sanity check the DXE NX protection policy setting:
   // - code regions should have no EFI_MEMORY_XP attribute
   // - EfiConventionalMemory and EfiBootServicesData should use the
   //   same attribute
   //
-  ASSERT ((GetPermissionAttributeForMemoryType (EfiBootServicesCode) & EFI_MEMORY_XP) == 0);
-  ASSERT ((GetPermissionAttributeForMemoryType (EfiRuntimeServicesCode) & EFI_MEMORY_XP) == 0);
-  ASSERT ((GetPermissionAttributeForMemoryType (EfiLoaderCode) & EFI_MEMORY_XP) == 0);
+  ASSERT (!gDxeMps.ExecutionProtection.EnabledForType[EfiLoaderCode]);
+  ASSERT (!gDxeMps.ExecutionProtection.EnabledForType[EfiBootServicesCode]);
+  ASSERT (!gDxeMps.ExecutionProtection.EnabledForType[EfiRuntimeServicesCode]);
   ASSERT (
     GetPermissionAttributeForMemoryType (EfiBootServicesData) ==
     GetPermissionAttributeForMemoryType (EfiConventionalMemory)
@@ -1184,8 +1204,8 @@ CoreInitializeMemoryProtection (
   //
   // Register a callback to disable NULL pointer detection at EndOfDxe
   //
-  if ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & (BIT0|BIT7))
-      == (BIT0|BIT7))
+  if (gDxeMps.NullPointerDetection.Enabled &&
+      gDxeMps.NullPointerDetection.DisableEndOfDxe)
   {
     Status = CoreCreateEventEx (
                EVT_NOTIFY_SIGNAL,
@@ -1250,7 +1270,7 @@ ApplyMemoryProtectionPolicy (
   UINT64  NewAttributes;
 
   //
-  // The policy configured in PcdDxeNxMemoryProtectionPolicy
+  // The policy configured in DXE Execution Protection Policy
   // does not apply to allocations performed in SMM mode.
   //
   if (IsInSmm ()) {
@@ -1269,7 +1289,7 @@ ApplyMemoryProtectionPolicy (
   //
   // Check if a DXE memory protection policy has been configured
   //
-  if (PcdGet64 (PcdDxeNxMemoryProtectionPolicy) == 0) {
+  if (!mIsExecutionProtectionActive) {
     return EFI_SUCCESS;
   }
 
@@ -1277,7 +1297,7 @@ ApplyMemoryProtectionPolicy (
   // Don't overwrite Guard pages, which should be the first and/or last page,
   // if any.
   //
-  if (IsHeapGuardEnabled (GUARD_HEAP_TYPE_PAGE|GUARD_HEAP_TYPE_POOL)) {
+  if (mIsPageOrPoolGuardActive) {
     if (IsGuardPage (Memory)) {
       Memory += EFI_PAGE_SIZE;
       Length -= EFI_PAGE_SIZE;
diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeHandoff.c b/MdeModulePkg/Core/DxeIplPeim/DxeHandoff.c
index 60400da352..676e2c1355 100644
--- a/MdeModulePkg/Core/DxeIplPeim/DxeHandoff.c
+++ b/MdeModulePkg/Core/DxeIplPeim/DxeHandoff.c
@@ -33,13 +33,15 @@ HandOffToDxeCore (
   EFI_STATUS                  Status;
   EDKII_MEMORY_ATTRIBUTE_PPI  *MemoryPpi;
 
+  PopulateDxeMemoryProtectionSettings (&mDxeMps);
+
   //
   // Allocate 128KB for the Stack
   //
   BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (STACK_SIZE));
   ASSERT (BaseOfStack != NULL);
 
-  if (PcdGetBool (PcdSetNxForStack)) {
+  if (mDxeMps.StackExecutionProtectionEnabled) {
     Status = PeiServicesLocatePpi (
                &gEdkiiMemoryAttributePpiGuid,
                0,
diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.h b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.h
index 2f015befce..8e87a66908 100644
--- a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.h
+++ b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.h
@@ -27,6 +27,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include <Guid/MemoryTypeInformation.h>
 #include <Guid/MemoryAllocationHob.h>
 #include <Guid/FirmwareFileSystem2.h>
+#include <Guid/DxeMemoryProtectionSettings.h>
 
 #include <Library/DebugLib.h>
 #include <Library/PeimEntryPoint.h>
@@ -46,11 +47,25 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #define STACK_SIZE      0x20000
 #define BSP_STORE_SIZE  0x4000
 
+extern DXE_MEMORY_PROTECTION_SETTINGS  mDxeMps;
+
 //
 // This PPI is installed to indicate the end of the PEI usage of memory
 //
 extern CONST EFI_PEI_PPI_DESCRIPTOR  gEndOfPeiSignalPpi;
 
+/**
+  Populates mDxeMps global with the data present in the memory
+  protection HOB entry if it exists.
+
+  @param[in] DxeMps  Pointer to the DXE memory protection settings.
+**/
+VOID
+EFIAPI
+PopulateDxeMemoryProtectionSettings (
+  IN DXE_MEMORY_PROTECTION_SETTINGS  *DxeMps
+  );
+
 /**
    This function installs the PPIs that require permanent memory.
 
diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
index f1990eac77..ffc5cce31d 100644
--- a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+++ b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
@@ -88,11 +88,12 @@
   ## SOMETIMES_CONSUMES ## Variable:L"MemoryTypeInformation"
   ## SOMETIMES_PRODUCES ## HOB
   gEfiMemoryTypeInformationGuid
+  gDxeMemoryProtectionSettingsGuid ## CONSUMES
 
 [FeaturePcd.IA32]
   gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode      ## CONSUMES
 
-[FeaturePcd.X64]
+[FeaturePcd.IA32, FeaturePcd.X64]
   gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplBuildPageTables       ## CONSUMES
 
 [FeaturePcd]
@@ -101,20 +102,10 @@
 [Pcd.IA32,Pcd.X64]
   gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable                      ## SOMETIMES_CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask    ## CONSUMES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask    ## CONSUMES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask               ## CONSUMES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard                       ## CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdUse5LevelPageTable                  ## SOMETIMES_CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase                            ## CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbSize                            ## CONSUMES
 
-[Pcd.IA32,Pcd.X64,Pcd.ARM,Pcd.AARCH64]
-  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy ## SOMETIMES_CONSUMES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy       ## SOMETIMES_CONSUMES
-
-[Pcd]
-  gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack               ## SOMETIMES_CONSUMES
-
 [Depex]
   gEfiPeiLoadFilePpiGuid AND gEfiPeiMasterBootModePpiGuid
 
diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c b/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c
index 2c19f1a507..ac3456ecd6 100644
--- a/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c
+++ b/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c
@@ -50,6 +50,8 @@ CONST EFI_PEI_NOTIFY_DESCRIPTOR  mMemoryDiscoveredNotifyList = {
   InstallIplPermanentMemoryPpis
 };
 
+DXE_MEMORY_PROTECTION_SETTINGS  mDxeMps;
+
 /**
   Entry point of DXE IPL PEIM.
 
@@ -836,3 +838,27 @@ UpdateStackHob (
     Hob.Raw = GET_NEXT_HOB (Hob);
   }
 }
+
+/**
+  Populates mDxeMps global with the data present in the memory
+  protection HOB entry if it exists.
+
+  @param[in] DxeMps  Pointer to the DXE memory protection settings.
+**/
+VOID
+EFIAPI
+PopulateDxeMemoryProtectionSettings (
+  IN DXE_MEMORY_PROTECTION_SETTINGS  *DxeMps
+  )
+{
+  VOID  *Ptr;
+
+  Ptr = GetFirstGuidHob (&gDxeMemoryProtectionSettingsGuid);
+
+  // Cache the Memory Protection Settings HOB entry
+  if ((Ptr != NULL) && DXE_MPS_IS_STRUCT_VALID (GET_GUID_HOB_DATA (Ptr))) {
+    CopyMem (DxeMps, GET_GUID_HOB_DATA (Ptr), sizeof (DXE_MEMORY_PROTECTION_SETTINGS));
+  } else {
+    ZeroMem (DxeMps, sizeof (DXE_MEMORY_PROTECTION_SETTINGS));
+  }
+}
diff --git a/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c b/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c
index 4bc7b749b0..5395202b87 100644
--- a/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c
+++ b/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c
@@ -135,9 +135,8 @@ Create4GPageTablesIa32Pae (
     PageDirectoryPointerEntry->Bits.Present = 1;
 
     for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PhysicalAddress += SIZE_2MB) {
-      if (  (IsNullDetectionEnabled () && (PhysicalAddress == 0))
-         || (  (PhysicalAddress < StackBase + StackSize)
-            && ((PhysicalAddress + SIZE_2MB) > StackBase)))
+      if ((((mDxeMps.NullPointerDetection.Enabled) && (PhysicalAddress == (UINTN)NULL))) ||
+          ((PhysicalAddress < StackBase + StackSize) && ((PhysicalAddress + SIZE_2MB) > StackBase)))
       {
         //
         // Need to split this 2M page that covers stack range.
@@ -199,41 +198,6 @@ IsIa32PaeSupport (
   return Ia32PaeSupport;
 }
 
-/**
-  The function will check if page table should be setup or not.
-
-  @retval TRUE      Page table should be created.
-  @retval FALSE     Page table should not be created.
-
-**/
-BOOLEAN
-ToBuildPageTable (
-  VOID
-  )
-{
-  if (!IsIa32PaeSupport ()) {
-    return FALSE;
-  }
-
-  if (IsNullDetectionEnabled ()) {
-    return TRUE;
-  }
-
-  if (PcdGet8 (PcdHeapGuardPropertyMask) != 0) {
-    return TRUE;
-  }
-
-  if (PcdGetBool (PcdCpuStackGuard)) {
-    return TRUE;
-  }
-
-  if (IsEnableNonExecNeeded ()) {
-    return TRUE;
-  }
-
-  return FALSE;
-}
-
 /**
    Transfers control to DxeCore.
 
@@ -265,12 +229,13 @@ HandOffToDxeCore (
   EFI_PEI_VECTOR_HANDOFF_INFO_PPI  *VectorHandoffInfoPpi;
   BOOLEAN                          BuildPageTablesIa32Pae;
 
-  //
-  // Clear page 0 and mark it as allocated if NULL pointer detection is enabled.
-  //
-  if (IsNullDetectionEnabled ()) {
-    ClearFirst4KPage (HobList.Raw);
-    BuildMemoryAllocationHob (0, EFI_PAGES_TO_SIZE (1), EfiBootServicesData);
+  PopulateDxeMemoryProtectionSettings (&mDxeMps);
+
+  if (mDxeMps.NullPointerDetection.Enabled) {
+    ASSERT (CanAllocateNullPage (HobList.Raw));
+    // Clear NULL page and mark it as allocated for NULL detectiond.
+    SetMem (NULL, EFI_PAGE_SIZE, (UINTN)NULL);
+    BuildMemoryAllocationHob ((UINTN)NULL, EFI_PAGES_TO_SIZE (1), EfiBootServicesData);
   }
 
   Status = PeiServicesAllocatePages (EfiBootServicesData, EFI_SIZE_TO_PAGES (STACK_SIZE), &BaseOfStack);
@@ -420,12 +385,14 @@ HandOffToDxeCore (
     TopOfStack = (EFI_PHYSICAL_ADDRESS)(UINTN)ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);
 
     PageTables             = 0;
-    BuildPageTablesIa32Pae = ToBuildPageTable ();
+    BuildPageTablesIa32Pae = PcdGetBool (PcdDxeIplBuildPageTables);
     if (BuildPageTablesIa32Pae) {
       PageTables = Create4GPageTablesIa32Pae (BaseOfStack, STACK_SIZE);
       if (IsEnableNonExecNeeded ()) {
         EnableExecuteDisableBit ();
       }
+    } else {
+      ASSERT (!DXE_MPS_IS_MEMORY_PROTECTION_ACTIVE (&mDxeMps));
     }
 
     //
diff --git a/MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c b/MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c
index fa2050cf02..8565bc8171 100644
--- a/MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c
+++ b/MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c
@@ -36,12 +36,13 @@ HandOffToDxeCore (
   VOID                             *GhcbBase;
   UINTN                            GhcbSize;
 
-  //
-  // Clear page 0 and mark it as allocated if NULL pointer detection is enabled.
-  //
-  if (IsNullDetectionEnabled ()) {
-    ClearFirst4KPage (HobList.Raw);
-    BuildMemoryAllocationHob (0, EFI_PAGES_TO_SIZE (1), EfiBootServicesData);
+  PopulateDxeMemoryProtectionSettings (&mDxeMps);
+
+  if (mDxeMps.NullPointerDetection.Enabled) {
+    ASSERT (CanAllocateNullPage (HobList.Raw));
+    // Clear NULL page and mark it as allocated for NULL detection
+    SetMem (NULL, EFI_PAGE_SIZE, (UINTN)NULL);
+    BuildMemoryAllocationHob ((UINTN)NULL, EFI_PAGES_TO_SIZE (1), EfiBootServicesData);
   }
 
   //
@@ -99,13 +100,6 @@ HandOffToDxeCore (
                    (EFI_PHYSICAL_ADDRESS)(UINTN)GhcbBase,
                    GhcbSize
                    );
-  } else {
-    //
-    // Set NX for stack feature also require PcdDxeIplBuildPageTables be TRUE
-    // for the DxeIpl and the DxeCore are both X64.
-    //
-    ASSERT (PcdGetBool (PcdSetNxForStack) == FALSE);
-    ASSERT (PcdGetBool (PcdCpuStackGuard) == FALSE);
   }
 
   //
diff --git a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c
index 980c2002d4..6de8ddb4f8 100644
--- a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c
+++ b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c
@@ -32,29 +32,34 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 PAGE_TABLE_POOL  *mPageTablePool = NULL;
 
 /**
-  Clear legacy memory located at the first 4K-page, if available.
-
-  This function traverses the whole HOB list to check if memory from 0 to 4095
-  exists and has not been allocated, and then clear it if so.
+  Returns TRUE if the NULL page has not been allocated.
 
   @param HobStart                  The start of HobList passed to DxeCore.
 
+  @retval TRUE                     NULL page is unallocated
+  @retval FALSE                    NULL page cannot be allocated
+
 **/
-VOID
-ClearFirst4KPage (
+BOOLEAN
+CanAllocateNullPage (
   IN  VOID  *HobStart
   )
 {
   EFI_PEI_HOB_POINTERS  RscHob;
   EFI_PEI_HOB_POINTERS  MemHob;
-  BOOLEAN               DoClear;
+  BOOLEAN               CanAllocate;
+
+  if (HobStart == NULL) {
+    ASSERT (HobStart != NULL);
+    return FALSE;
+  }
 
-  RscHob.Raw = HobStart;
-  MemHob.Raw = HobStart;
-  DoClear    = FALSE;
+  RscHob.Raw  = HobStart;
+  MemHob.Raw  = HobStart;
+  CanAllocate = FALSE;
 
   //
-  // Check if page 0 exists and free
+  // Check if page 0 exists and is free
   //
   while ((RscHob.Raw = GetNextHob (
                          EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,
@@ -62,9 +67,9 @@ ClearFirst4KPage (
                          )) != NULL)
   {
     if ((RscHob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) &&
-        (RscHob.ResourceDescriptor->PhysicalStart == 0))
+        (RscHob.ResourceDescriptor->PhysicalStart == (UINTN)NULL))
     {
-      DoClear = TRUE;
+      CanAllocate = TRUE;
       //
       // Make sure memory at 0-4095 has not been allocated.
       //
@@ -73,10 +78,10 @@ ClearFirst4KPage (
                              MemHob.Raw
                              )) != NULL)
       {
-        if (MemHob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress
-            < EFI_PAGE_SIZE)
+        if ((MemHob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress >= (UINTN)NULL) &&
+            (MemHob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress < (UINTN)NULL + EFI_PAGE_SIZE))
         {
-          DoClear = FALSE;
+          CanAllocate = FALSE;
           break;
         }
 
@@ -89,27 +94,7 @@ ClearFirst4KPage (
     RscHob.Raw = GET_NEXT_HOB (RscHob);
   }
 
-  if (DoClear) {
-    DEBUG ((DEBUG_INFO, "Clearing first 4K-page!\r\n"));
-    SetMem (NULL, EFI_PAGE_SIZE, 0);
-  }
-
-  return;
-}
-
-/**
-  Return configure status of NULL pointer detection feature.
-
-  @return TRUE   NULL pointer detection feature is enabled
-  @return FALSE  NULL pointer detection feature is disabled
-
-**/
-BOOLEAN
-IsNullDetectionEnabled (
-  VOID
-  )
-{
-  return ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & BIT0) != 0);
+  return CanAllocate;
 }
 
 /**
@@ -155,17 +140,7 @@ IsEnableNonExecNeeded (
   VOID
   )
 {
-  if (!IsExecuteDisableBitAvailable ()) {
-    return FALSE;
-  }
-
-  //
-  // XD flag (BIT63) in page table entry is only valid if IA32_EFER.NXE is set.
-  // Features controlled by Following PCDs need this feature to be enabled.
-  //
-  return (PcdGetBool (PcdSetNxForStack) ||
-          PcdGet64 (PcdDxeNxMemoryProtectionPolicy) != 0 ||
-          PcdGet32 (PcdImageProtectionPolicy) != 0);
+  return IsExecuteDisableBitAvailable ();
 }
 
 /**
@@ -210,17 +185,17 @@ ToSplitPageTable (
   IN UINTN                 GhcbSize
   )
 {
-  if (IsNullDetectionEnabled () && (Address == 0)) {
+  if (mDxeMps.NullPointerDetection.Enabled && (Address == (UINTN)NULL)) {
     return TRUE;
   }
 
-  if (PcdGetBool (PcdCpuStackGuard)) {
+  if (mDxeMps.CpuStackGuardEnabled) {
     if ((StackBase >= Address) && (StackBase < (Address + Size))) {
       return TRUE;
     }
   }
 
-  if (PcdGetBool (PcdSetNxForStack)) {
+  if (mDxeMps.StackExecutionProtectionEnabled) {
     if ((Address < StackBase + StackSize) && ((Address + Size) > StackBase)) {
       return TRUE;
     }
@@ -402,17 +377,17 @@ Split2MPageTo4K (
 
     PageTableEntry->Bits.ReadWrite = 1;
 
-    if ((IsNullDetectionEnabled () && (PhysicalAddress4K == 0)) ||
-        (PcdGetBool (PcdCpuStackGuard) && (PhysicalAddress4K == StackBase)))
+    if ((mDxeMps.NullPointerDetection.Enabled && (PhysicalAddress4K == (UINTN)NULL)) ||
+        (mDxeMps.CpuStackGuardEnabled && (PhysicalAddress4K == StackBase)))
     {
       PageTableEntry->Bits.Present = 0;
     } else {
       PageTableEntry->Bits.Present = 1;
     }
 
-    if (  PcdGetBool (PcdSetNxForStack)
-       && (PhysicalAddress4K >= StackBase)
-       && (PhysicalAddress4K < StackBase + StackSize))
+    if (mDxeMps.StackExecutionProtectionEnabled &&
+        (PhysicalAddress4K >= StackBase) &&
+        (PhysicalAddress4K < StackBase + StackSize))
     {
       //
       // Set Nx bit for stack.
diff --git a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.h b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.h
index 616ebe42b0..c27bf68a04 100644
--- a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.h
+++ b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.h
@@ -265,28 +265,17 @@ AsmGetVectorTemplatInfo (
   );
 
 /**
-  Clear legacy memory located at the first 4K-page.
+  Returns TRUE if the NULL page has not been allocated.
 
-  This function traverses the whole HOB list to check if memory from 0 to 4095
-  exists and has not been allocated, and then clear it if so.
+  @param HobStart                  The start of HobList passed to DxeCore.
 
-  @param HobStart         The start of HobList passed to DxeCore.
+  @retval TRUE                     NULL page is unallocated
+  @retval FALSE                    NULL page cannot be allocated
 
 **/
-VOID
-ClearFirst4KPage (
-  IN  VOID  *HobStart
-  );
-
-/**
-  Return configure status of NULL pointer detection feature.
-
-  @return TRUE   NULL pointer detection feature is enabled
-  @return FALSE  NULL pointer detection feature is disabled
-**/
 BOOLEAN
-IsNullDetectionEnabled (
-  VOID
+CanAllocateNullPage (
+  IN  VOID  *HobStart
   );
 
 /**
diff --git a/MdeModulePkg/Core/PiSmmCore/HeapGuard.c b/MdeModulePkg/Core/PiSmmCore/HeapGuard.c
index 25310122ca..ed174b68e4 100644
--- a/MdeModulePkg/Core/PiSmmCore/HeapGuard.c
+++ b/MdeModulePkg/Core/PiSmmCore/HeapGuard.c
@@ -8,6 +8,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 
 #include "HeapGuard.h"
 
+#include <Library/MmMemoryProtectionHobLib.h>
+
 //
 // Global to avoid infinite reentrance of memory allocation when updating
 // page table attributes, which may need allocating pages for new PDE/PTE.
@@ -579,7 +581,7 @@ UnsetGuardPage (
 
   @param[in]  MemoryType      Memory type to check.
   @param[in]  AllocateType    Allocation type to check.
-  @param[in]  PageOrPool      Indicate a page allocation or pool allocation.
+  @param[in]  HeapGuardType   Indicates the heap guard type.
 
 
   @return TRUE  The given type of memory should be guarded.
@@ -589,39 +591,22 @@ BOOLEAN
 IsMemoryTypeToGuard (
   IN EFI_MEMORY_TYPE    MemoryType,
   IN EFI_ALLOCATE_TYPE  AllocateType,
-  IN UINT8              PageOrPool
+  IN HEAP_GUARD_TYPE    HeapGuardType
   )
 {
-  UINT64  TestBit;
-  UINT64  ConfigBit;
-
-  if (  ((PcdGet8 (PcdHeapGuardPropertyMask) & PageOrPool) == 0)
-     || mOnGuarding
-     || (AllocateType == AllocateAddress))
-  {
+  if (mOnGuarding || (AllocateType == AllocateAddress)) {
     return FALSE;
   }
 
-  ConfigBit = 0;
-  if ((PageOrPool & GUARD_HEAP_TYPE_POOL) != 0) {
-    ConfigBit |= PcdGet64 (PcdHeapGuardPoolType);
-  }
-
-  if ((PageOrPool & GUARD_HEAP_TYPE_PAGE) != 0) {
-    ConfigBit |= PcdGet64 (PcdHeapGuardPageType);
+  if ((HeapGuardType == HeapGuardTypePool) && gMmMps.HeapGuard.PoolGuardEnabled) {
+    return gMmMps.PoolGuard.EnabledForType[MemoryType];
   }
 
-  if ((MemoryType == EfiRuntimeServicesData) ||
-      (MemoryType == EfiRuntimeServicesCode))
-  {
-    TestBit = LShiftU64 (1, MemoryType);
-  } else if (MemoryType == EfiMaxMemoryType) {
-    TestBit = (UINT64)-1;
-  } else {
-    TestBit = 0;
+  if ((HeapGuardType == HeapGuardTypePage) && gMmMps.HeapGuard.PageGuardEnabled) {
+    return gMmMps.PageGuard.EnabledForType[MemoryType];
   }
 
-  return ((ConfigBit & TestBit) != 0);
+  return FALSE;
 }
 
 /**
@@ -641,7 +626,7 @@ IsPoolTypeToGuard (
   return IsMemoryTypeToGuard (
            MemoryType,
            AllocateAnyPages,
-           GUARD_HEAP_TYPE_POOL
+           HeapGuardTypePool
            );
 }
 
@@ -660,24 +645,7 @@ IsPageTypeToGuard (
   IN EFI_ALLOCATE_TYPE  AllocateType
   )
 {
-  return IsMemoryTypeToGuard (MemoryType, AllocateType, GUARD_HEAP_TYPE_PAGE);
-}
-
-/**
-  Check to see if the heap guard is enabled for page and/or pool allocation.
-
-  @return TRUE/FALSE.
-**/
-BOOLEAN
-IsHeapGuardEnabled (
-  VOID
-  )
-{
-  return IsMemoryTypeToGuard (
-           EfiMaxMemoryType,
-           AllocateAnyPages,
-           GUARD_HEAP_TYPE_POOL|GUARD_HEAP_TYPE_PAGE
-           );
+  return IsMemoryTypeToGuard (MemoryType, AllocateType, HeapGuardTypePage);
 }
 
 /**
@@ -951,7 +919,7 @@ AdjustPoolHeadA (
   IN UINTN                 Size
   )
 {
-  if ((Memory == 0) || ((PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) != 0)) {
+  if ((Memory == 0) || (!gMmMps.HeapGuard.GuardAlignedToTail)) {
     //
     // Pool head is put near the head Guard
     //
@@ -977,7 +945,7 @@ AdjustPoolHeadF (
   IN EFI_PHYSICAL_ADDRESS  Memory
   )
 {
-  if ((Memory == 0) || ((PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) != 0)) {
+  if ((Memory == 0) || (!gMmMps.HeapGuard.GuardAlignedToTail)) {
     //
     // Pool head is put near the head Guard
     //
diff --git a/MdeModulePkg/Core/PiSmmCore/HeapGuard.h b/MdeModulePkg/Core/PiSmmCore/HeapGuard.h
index 0a447ce2e8..0f3a860b1b 100644
--- a/MdeModulePkg/Core/PiSmmCore/HeapGuard.h
+++ b/MdeModulePkg/Core/PiSmmCore/HeapGuard.h
@@ -152,10 +152,14 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
   }
 
 //
-// Memory type to guard (matching the related PCD definition)
+// Heap guard types
 //
-#define GUARD_HEAP_TYPE_PAGE  BIT2
-#define GUARD_HEAP_TYPE_POOL  BIT3
+typedef enum {
+  HeapGuardTypePage,
+  HeapGuardTypePool,
+  HeapGuardTypeFreed,
+  HeapGuardTypeMax
+} HEAP_GUARD_TYPE;
 
 //
 // Debug message level
@@ -362,16 +366,6 @@ SmmInternalFreePagesExWithGuard (
   IN BOOLEAN               AddRegion
   );
 
-/**
-  Check to see if the heap guard is enabled for page and/or pool allocation.
-
-  @return TRUE/FALSE.
-**/
-BOOLEAN
-IsHeapGuardEnabled (
-  VOID
-  );
-
 /**
   Debug function used to verify if the Guard page is well set or not.
 
diff --git a/MdeModulePkg/Core/PiSmmCore/Page.c b/MdeModulePkg/Core/PiSmmCore/Page.c
index 255964c23a..e2db7ea114 100644
--- a/MdeModulePkg/Core/PiSmmCore/Page.c
+++ b/MdeModulePkg/Core/PiSmmCore/Page.c
@@ -943,8 +943,10 @@ SmmFreePages (
     return EFI_NOT_FOUND;
   }
 
-  IsGuarded = IsHeapGuardEnabled () && IsMemoryGuarded (Memory);
-  Status    = SmmInternalFreePages (Memory, NumberOfPages, IsGuarded);
+  IsGuarded = (gMmMps.HeapGuard.PageGuardEnabled ||
+               gMmMps.HeapGuard.PoolGuardEnabled) &&
+              IsMemoryGuarded (Memory);
+  Status = SmmInternalFreePages (Memory, NumberOfPages, IsGuarded);
   if (!EFI_ERROR (Status)) {
     SmmCoreUpdateProfile (
       (EFI_PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h
index b8a490a8c3..c17afdd097 100644
--- a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h
+++ b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h
@@ -55,6 +55,7 @@
 #include <Library/HobLib.h>
 #include <Library/SmmMemLib.h>
 #include <Library/SafeIntLib.h>
+#include <Library/MmMemoryProtectionHobLib.h>
 
 #include "PiSmmCorePrivateData.h"
 #include "HeapGuard.h"
diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf
index 3df44b38f1..66fdccc1a9 100644
--- a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf
+++ b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf
@@ -61,6 +61,7 @@
   HobLib
   SmmMemLib
   SafeIntLib
+  MmMemoryProtectionHobLib
 
 [Protocols]
   gEfiDxeSmmReadyToLockProtocolGuid             ## UNDEFINED # SmiHandlerRegister
@@ -94,9 +95,6 @@
   gEfiMdeModulePkgTokenSpaceGuid.PcdMemoryProfilePropertyMask           ## CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdMemoryProfileDriverPath             ## CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdSmiHandlerProfilePropertyMask       ## CONSUMES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPageType                   ## CONSUMES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPoolType                   ## CONSUMES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask               ## CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable                        ## CONSUMES
 
 [Guids]
diff --git a/MdeModulePkg/Core/PiSmmCore/Pool.c b/MdeModulePkg/Core/PiSmmCore/Pool.c
index e1ff40a8ea..7fb2305763 100644
--- a/MdeModulePkg/Core/PiSmmCore/Pool.c
+++ b/MdeModulePkg/Core/PiSmmCore/Pool.c
@@ -257,8 +257,7 @@ SmmInternalAllocatePool (
   }
 
   NeedGuard   = IsPoolTypeToGuard (PoolType);
-  HasPoolTail = !(NeedGuard &&
-                  ((PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) == 0));
+  HasPoolTail = !(NeedGuard && gMmMps.HeapGuard.GuardAlignedToTail);
 
   //
   // Adjust the size by the pool header & tail overhead
@@ -389,10 +388,10 @@ SmmInternalFreePool (
     return EFI_INVALID_PARAMETER;
   }
 
-  MemoryGuarded = IsHeapGuardEnabled () &&
+  MemoryGuarded = (gMmMps.HeapGuard.PageGuardEnabled ||
+                   gMmMps.HeapGuard.PoolGuardEnabled) &&
                   IsMemoryGuarded ((EFI_PHYSICAL_ADDRESS)(UINTN)FreePoolHdr);
-  HasPoolTail = !(MemoryGuarded &&
-                  ((PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) == 0));
+  HasPoolTail = !(MemoryGuarded && gMmMps.HeapGuard.GuardAlignedToTail);
 
   if (HasPoolTail) {
     PoolTail = HEAD_TO_TAIL (&FreePoolHdr->Header);
-- 
2.41.0.windows.2



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#106831): https://edk2.groups.io/g/devel/message/106831
Mute This Topic: https://groups.io/mt/100090641/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