public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH 00/14] Implement Dynamic Memory Protections
@ 2023-07-11 23:52 Taylor Beebe
  2023-07-11 23:52 ` [PATCH 01/14] MdeModulePkg: Add DXE and MM Memory Protection Settings Definitions Taylor Beebe
                   ` (16 more replies)
  0 siblings, 17 replies; 24+ messages in thread
From: Taylor Beebe @ 2023-07-11 23:52 UTC (permalink / raw)
  To: devel
  Cc: Jian J Wang, Liming Gao, Dandan Bi, Ard Biesheuvel, Jiewen Yao,
	Jordan Justen, Gerd Hoffmann, Leif Lindholm, Sami Mujawar,
	Andrew Fish, Ray Ni, Eric Dong, Rahul Kumar, Guo Dong,
	Sean Rhodes, James Lu, Gua Guo

In the past, memory protection settings were configured via FixedAtBuild PCDs,
which resulted in a build-time configuration of memory mitigations. This
approach limited the flexibility of applying mitigations to the
system and made it difficult to update or adjust the settings post-build.

In a design, the configuration interface has been revised to allow for dynamic
configuration. This is achieved with HOBs that are published prior to invocation
of the HandoffToDxe() function.

OvmfPkg/PlatformPei/Platform.c contains an example of how to publish the HOB
for DXE and MM.

To check the memory protection settings after PEI, the HOB can be easily consumed,
sanity checked, and put into a global for access via the inclusion of the DXE
or MM HOB libraries.

This patch series also increases the memory protection level for OvmfPkg and
ArmVirtPkg.

Reference: https://github.com/tianocore/edk2/pull/4566

Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Dandan Bi <dandan.bi@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Sami Mujawar <sami.mujawar@arm.com>
Cc: Andrew Fish <afish@apple.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Guo Dong <guo.dong@intel.com>
Cc: Sean Rhodes <sean@starlabs.systems>
Cc: James Lu <james.lu@intel.com>
Cc: Gua Guo <gua.guo@intel.com>

Taylor Beebe (14):
  MdeModulePkg: Add DXE and MM Memory Protection Settings Definitions
  MdeModulePkg: Add MemoryProtectionHobLib Definitions and NULL Libs
  MdeModulePkg: Add Phase-Specific MemoryProtectionHobLib
    Implementations
  OvmfPkg: Create the memory protection settings HOB
  ArmVirtPkg: Create memory protection settings HOB
  ArmPkg: Update to use memory protection HOB
  EmulatorPkg: Update to use memory protection HOB
  MdeModulePkg: Update to use memory protection HOB
  OvmfPkg: Update to use memory protection HOB
  UefiCpuPkg: Update to use memory protection HOB
  UefiPayloadPkg: Update to use memory protection HOB
  OvmfPkg: Delete Memory Protection PCDs
  ArmVirtPkg: Delete Memory Protection PCDs
  MdeModulePkg: Delete Memory Protection PCDs

 ArmPkg/ArmPkg.dsc                             |   1 +
 ArmPkg/Drivers/CpuDxe/CpuDxe.c                |   5 +-
 ArmPkg/Drivers/CpuDxe/CpuDxe.inf              |   2 +-
 ArmVirtPkg/ArmVirt.dsc.inc                    |  24 +-
 ArmVirtPkg/ArmVirtCloudHv.dsc                 |   5 -
 ArmVirtPkg/ArmVirtQemu.dsc                    |   5 -
 ArmVirtPkg/MemoryInitPei/MemoryInitPeim.c     |  25 +-
 ArmVirtPkg/MemoryInitPei/MemoryInitPeim.inf   |   2 +
 EmulatorPkg/EmulatorPkg.dsc                   |   2 +-
 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 +-
 .../Guid/DxeMemoryProtectionSettings.h        | 413 ++++++++++++++++++
 .../Include/Guid/MmMemoryProtectionSettings.h | 211 +++++++++
 .../Library/DxeMemoryProtectionHobLib.h       |  20 +
 .../Library/MmMemoryProtectionHobLib.h        |  20 +
 .../DxeMemoryProtectionHobLib.c               | 132 ++++++
 .../DxeMemoryProtectionHobLib.inf             |  34 ++
 .../MmCommonMemoryProtectionHobLib.c          |  89 ++++
 .../SmmMemoryProtectionHobLib.c               |  37 ++
 .../SmmMemoryProtectionHobLib.inf             |  35 ++
 .../StandaloneMmMemoryProtectionHobLib.c      |  37 ++
 .../StandaloneMmMemoryProtectionHobLib.inf    |  36 ++
 .../DxeMemoryProtectionHobLibNull.c           |  13 +
 .../DxeMemoryProtectionHobLibNull.inf         |  28 ++
 .../MmMemoryProtectionHobLibNull.c            |  13 +
 .../MmMemoryProtectionHobLibNull.inf          |  28 ++
 MdeModulePkg/MdeModulePkg.dec                 | 187 +-------
 MdeModulePkg/MdeModulePkg.dsc                 |  11 +
 MdeModulePkg/MdeModulePkg.uni                 | 153 -------
 OvmfPkg/AmdSev/AmdSevX64.dsc                  |   5 +-
 OvmfPkg/Bhyve/BhyveX64.dsc                    |   5 +-
 OvmfPkg/Bhyve/PlatformPei/PlatformPei.inf     |   1 -
 OvmfPkg/CloudHv/CloudHvX64.dsc                |   5 +-
 OvmfPkg/Fdt/HighMemDxe/HighMemDxe.c           |   5 +-
 OvmfPkg/Fdt/HighMemDxe/HighMemDxe.inf         |   4 +-
 .../Dsc/MemoryProtectionLibraries.dsc.inc     |  15 +
 OvmfPkg/Include/Library/PlatformInitLib.h     |  13 -
 OvmfPkg/IntelTdx/IntelTdxX64.dsc              |   5 +-
 OvmfPkg/Library/PeilessStartupLib/DxeLoad.c   |  25 +-
 .../PeilessStartupLib/PeilessStartup.c        |   3 -
 .../PeilessStartupLib/PeilessStartupLib.inf   |   5 +-
 .../PeilessStartupLib/X64/PageTables.h        |  23 +-
 .../PeilessStartupLib/X64/VirtualMemory.c     | 107 ++---
 OvmfPkg/Library/PlatformInitLib/Platform.c    |  15 -
 OvmfPkg/Microvm/MicrovmX64.dsc                |   5 +-
 OvmfPkg/OvmfPkgIa32.dsc                       |   5 +-
 OvmfPkg/OvmfPkgIa32X64.dsc                    |   5 +-
 OvmfPkg/OvmfPkgX64.dsc                        |   5 +-
 OvmfPkg/OvmfXen.dsc                           |   5 +-
 OvmfPkg/PlatformPei/IntelTdx.c                |   2 -
 OvmfPkg/PlatformPei/Platform.c                |  43 +-
 OvmfPkg/PlatformPei/PlatformPei.inf           |   3 +-
 OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf         |   2 +-
 OvmfPkg/QemuVideoDxe/VbeShim.c                |   5 +-
 OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc           |  13 -
 OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc           |   1 +
 OvmfPkg/TdxDxe/TdxDxe.c                       |   7 +-
 OvmfPkg/TdxDxe/TdxDxe.inf                     |   1 -
 UefiCpuPkg/CpuDxe/CpuDxe.c                    |   2 +-
 UefiCpuPkg/CpuDxe/CpuDxe.h                    |  11 +-
 UefiCpuPkg/CpuDxe/CpuDxe.inf                  |   4 +-
 UefiCpuPkg/CpuDxe/CpuMp.c                     |   2 +-
 UefiCpuPkg/CpuDxeRiscV64/CpuDxeRiscV64.inf    |   3 -
 UefiCpuPkg/CpuMpPei/CpuMpPei.c                |   8 +-
 UefiCpuPkg/CpuMpPei/CpuMpPei.h                |   3 +-
 UefiCpuPkg/CpuMpPei/CpuMpPei.inf              |   1 -
 UefiCpuPkg/CpuMpPei/CpuPaging.c               |  14 +-
 .../DxeCpuExceptionHandlerLib.inf             |   1 -
 .../PeiCpuExceptionHandlerLib.inf             |   1 -
 .../SecPeiCpuExceptionHandlerLib.inf          |   1 -
 .../SmmCpuExceptionHandlerLib.inf             |   1 -
 .../UnitTest/CpuExceptionHandlerTest.h        |   3 +-
 .../UnitTest/CpuExceptionHandlerTestCommon.c  |  27 +-
 .../DxeCpuExceptionHandlerLibUnitTest.inf     |   2 +-
 .../PeiCpuExceptionHandlerLibUnitTest.inf     |   4 +-
 UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf |   3 +-
 UefiCpuPkg/Library/MpInitLib/DxeMpLib.c       |   3 +-
 UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c      |   2 +-
 UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf  |   3 +-
 .../PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c   |  13 +-
 UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c        |   2 +-
 .../PiSmmCpuDxeSmm/SmmProfileInternal.h       |  10 +-
 UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c       |   2 +-
 UefiCpuPkg/UefiCpuPkg.dec                     |   7 +-
 UefiCpuPkg/UefiCpuPkg.dsc                     |   2 +
 UefiCpuPkg/UefiCpuPkg.uni                     |  10 +-
 .../UefiPayloadEntry/Ia32/DxeLoadFunc.c       | 149 +------
 UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c |  26 ++
 .../UefiPayloadEntry/UefiPayloadEntry.h       |  15 +
 .../UefiPayloadEntry/UefiPayloadEntry.inf     |   9 +-
 .../UniversalPayloadEntry.inf                 |   9 +-
 .../UefiPayloadEntry/X64/DxeLoadFunc.c        |  25 +-
 .../UefiPayloadEntry/X64/VirtualMemory.c      |  78 ++--
 .../UefiPayloadEntry/X64/VirtualMemory.h      |  23 +-
 UefiPayloadPkg/UefiPayloadPkg.dsc             |   1 +
 115 files changed, 1888 insertions(+), 1321 deletions(-)
 create mode 100644 MdeModulePkg/Include/Guid/DxeMemoryProtectionSettings.h
 create mode 100644 MdeModulePkg/Include/Guid/MmMemoryProtectionSettings.h
 create mode 100644 MdeModulePkg/Include/Library/DxeMemoryProtectionHobLib.h
 create mode 100644 MdeModulePkg/Include/Library/MmMemoryProtectionHobLib.h
 create mode 100644 MdeModulePkg/Library/MemoryProtectionHobLib/DxeMemoryProtectionHobLib.c
 create mode 100644 MdeModulePkg/Library/MemoryProtectionHobLib/DxeMemoryProtectionHobLib.inf
 create mode 100644 MdeModulePkg/Library/MemoryProtectionHobLib/MmCommonMemoryProtectionHobLib.c
 create mode 100644 MdeModulePkg/Library/MemoryProtectionHobLib/SmmMemoryProtectionHobLib.c
 create mode 100644 MdeModulePkg/Library/MemoryProtectionHobLib/SmmMemoryProtectionHobLib.inf
 create mode 100644 MdeModulePkg/Library/MemoryProtectionHobLib/StandaloneMmMemoryProtectionHobLib.c
 create mode 100644 MdeModulePkg/Library/MemoryProtectionHobLib/StandaloneMmMemoryProtectionHobLib.inf
 create mode 100644 MdeModulePkg/Library/MemoryProtectionHobLibNull/DxeMemoryProtectionHobLibNull.c
 create mode 100644 MdeModulePkg/Library/MemoryProtectionHobLibNull/DxeMemoryProtectionHobLibNull.inf
 create mode 100644 MdeModulePkg/Library/MemoryProtectionHobLibNull/MmMemoryProtectionHobLibNull.c
 create mode 100644 MdeModulePkg/Library/MemoryProtectionHobLibNull/MmMemoryProtectionHobLibNull.inf
 create mode 100644 OvmfPkg/Include/Dsc/MemoryProtectionLibraries.dsc.inc

-- 
2.41.0.windows.2


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH 01/14] MdeModulePkg: Add DXE and MM Memory Protection Settings Definitions
  2023-07-11 23:52 [PATCH 00/14] Implement Dynamic Memory Protections Taylor Beebe
@ 2023-07-11 23:52 ` Taylor Beebe
  2023-07-11 23:52 ` [PATCH 02/14] MdeModulePkg: Add MemoryProtectionHobLib Definitions and NULL Libs Taylor Beebe
                   ` (15 subsequent siblings)
  16 siblings, 0 replies; 24+ messages in thread
From: Taylor Beebe @ 2023-07-11 23:52 UTC (permalink / raw)
  To: devel; +Cc: Jian J Wang, Liming Gao, Dandan Bi

From: Taylor Beebe <tabeebe@microsoft.com>

These headers provide settings definitions for memory protections,
settings profiles for easily enabling memory protections,
and the GUIDs used for producing the memory protection HOB.

The settings options are functionally 1:1 with the existing
PCD bitfield definitions. Instead of setting a fixed at build
PCD, memory protection settings will be created via a HOB
at runtime.

Signed-off-by: Taylor Beebe <t@taylorbeebe.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Dandan Bi <dandan.bi@intel.com>
---
 .../Guid/DxeMemoryProtectionSettings.h        | 413 ++++++++++++++++++
 .../Include/Guid/MmMemoryProtectionSettings.h | 211 +++++++++
 MdeModulePkg/MdeModulePkg.dec                 |  10 +
 3 files changed, 634 insertions(+)
 create mode 100644 MdeModulePkg/Include/Guid/DxeMemoryProtectionSettings.h
 create mode 100644 MdeModulePkg/Include/Guid/MmMemoryProtectionSettings.h

diff --git a/MdeModulePkg/Include/Guid/DxeMemoryProtectionSettings.h b/MdeModulePkg/Include/Guid/DxeMemoryProtectionSettings.h
new file mode 100644
index 0000000000..93144494d5
--- /dev/null
+++ b/MdeModulePkg/Include/Guid/DxeMemoryProtectionSettings.h
@@ -0,0 +1,413 @@
+/** @file
+
+Defines memory protection settings guid and struct for DXE.
+
+Copyright (C) Microsoft Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef DXE_MEMORY_PROTECTION_SETTINGS_H_
+#define DXE_MEMORY_PROTECTION_SETTINGS_H_
+
+#include <Library/BaseMemoryLib.h>
+
+// Current iteration of DXE_MEMORY_PROTECTION_SETTINGS
+#define DXE_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION  1
+
+#define OEM_RESERVED_MPS_MEMORY_TYPE     EfiMaxMemoryType
+#define OS_RESERVED_MPS_MEMORY_TYPE      (EfiMaxMemoryType + 1)
+#define MAX_DXE_MPS_MEMORY_TYPE          (EfiMaxMemoryType + 2)
+#define DXE_MPS_MEMORY_TYPE_BUFFER_SIZE  (MAX_DXE_MPS_MEMORY_TYPE * sizeof (BOOLEAN))
+
+typedef struct {
+  BOOLEAN    Enabled            : 1;
+  BOOLEAN    DisableEndOfDxe    : 1;
+  BOOLEAN    NonstopModeEnabled : 1;
+} DXE_NULL_DETECTION_POLICY;
+
+typedef struct {
+  BOOLEAN    ProtectImageFromUnknown : 1;
+  BOOLEAN    ProtectImageFromFv      : 1;
+} DXE_IMAGE_PROTECTION_POLICY;
+
+typedef struct {
+  BOOLEAN    PageGuardEnabled        : 1;
+  BOOLEAN    PoolGuardEnabled        : 1;
+  BOOLEAN    FreedMemoryGuardEnabled : 1;
+  BOOLEAN    NonstopModeEnabled      : 1;
+  BOOLEAN    GuardAlignedToTail      : 1;
+} DXE_HEAP_GUARD_POLICY;
+
+typedef struct {
+  BOOLEAN    EnabledForType[MAX_DXE_MPS_MEMORY_TYPE];
+} DXE_MPS_MEMORY_TYPES;
+
+typedef UINT8 DXE_MEMORY_PROTECTION_SETTINGS_VERSION;
+
+//
+// Memory Protection Settings struct
+//
+typedef struct {
+  // The current version of the structure definition. This is used to ensure there isn't a
+  // definition mismatch if modules have differing iterations of this header. When creating
+  // this struct, use the DXE_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION macro.
+  DXE_MEMORY_PROTECTION_SETTINGS_VERSION    StructVersion;
+
+  // If enabled, the page at the top of the stack will be invalidated to catch stack overflow.
+  BOOLEAN                                   CpuStackGuardEnabled;
+
+  // If enabled, the stack will be marked non-executable.
+  BOOLEAN                                   StackExecutionProtectionEnabled;
+
+  // If enabled, accessing the NULL address in UEFI will be caught by marking
+  // the NULL page as not present.
+  //   .NullDetectionEnabled    : Enable NULL pointer detection.
+  //   .DisableEndOfDxe         : Disable NULL pointer detection just after EndOfDxe.
+  //                              This is a workaround for those unsolvable NULL access issues in
+  //                              OptionROM, boot loader, etc. It can also help to avoid unnecessary
+  //                              exception caused by legacy memory (0-4095) access after EndOfDxe,
+  //                              such as Windows 7 boot on Qemu.
+  //   .NonstopModeEnabled      : If enabled the debug flag will be raised when a fault occurs
+  //                              to break into debugger.
+  DXE_NULL_DETECTION_POLICY    NullPointerDetection;
+
+  // Set image protection policy.
+  //
+  //  .ProtectImageFromUnknown          : If set, images from unknown devices will be protected by
+  //                                      DxeCore if they are aligned. The code section becomes
+  //                                      read-only, and the data section becomes non-executable.
+  //  .ProtectImageFromFv               : If set, images from firmware volumes will be protected by
+  //                                      DxeCore if they are aligned. The code section becomes
+  //                                      read-only, and the data section becomes non-executable.
+  DXE_IMAGE_PROTECTION_POLICY    ImageProtection;
+
+  // If a bit is set, memory regions of the associated type will be mapped non-executable.
+  //
+  // The execution protection setting for EfiBootServicesData and EfiConventionalMemory must
+  // be the same.
+  DXE_MPS_MEMORY_TYPES           ExecutionProtection;
+
+  //  Configures general heap guard behavior.
+  //
+  //  .PageGuardEnabled         : Enable page guard.
+  //  .PoolGuardEnabled         : Enable pool guard.
+  //  .FreedMemoryGuardEnabled  : Enable freed-memory guard (Use-After-Free memory detection).
+  //  .NonstopModeEnabled       : If enabled the debug flag will be raised when a fault occurs
+  //                              to break into debugger.
+  //  .GuardAlignedToTail       : TRUE if the pool is aligned to tail guard page. If FALSE, the
+  //                              pool is aligned to head guard page.
+  //
+  //  Note:
+  //  a) Due to the limit of pool memory implementation and the alignment
+  //     requirement of UEFI spec, HeapGuard.GuardAlignedToTail is a try-best
+  //     setting which cannot guarantee that the returned pool is exactly
+  //     adjacent to head or tail guard page.
+  //  b) Freed-memory guard and pool/page guard cannot be enabled
+  //     at the same time.
+  DXE_HEAP_GUARD_POLICY    HeapGuard;
+
+  // Indicates which type allocation need guard page.
+  //
+  // If bit is set, a head guard page and a tail guard page will be added just
+  // before and after corresponding type of pages which the allocated pool occupies,
+  // if there's enough free memory for all of them.
+  //
+  // These settings are only valid if HeapGuard.PoolGuardEnabled is TRUE.
+  DXE_MPS_MEMORY_TYPES    PoolGuard;
+
+  // Indicates which type allocation need guard page.
+  //
+  // If a bit is set, a head guard page and a tail guard page will be added just
+  // before and after corresponding type of pages allocated if there's enough
+  // free pages for all of them.
+  //
+  // These settings are only valid if HeapGuard.PageGuardEnabled is TRUE.
+  DXE_MPS_MEMORY_TYPES    PageGuard;
+} DXE_MEMORY_PROTECTION_SETTINGS;
+
+#define DXE_MPS_IS_STRUCT_VALID(DxeMpsPtr) \
+  (((DXE_MEMORY_PROTECTION_SETTINGS *)DxeMpsPtr)->StructVersion == DXE_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION)
+
+#define DXE_MPS_IS_ANY_MEMORY_TYPE_ACTIVE(MpsMemoryTypesPtr) \
+  (!IsZeroBuffer (&((DXE_MPS_MEMORY_TYPES *)MpsMemoryTypesPtr)->EnabledForType, DXE_MPS_MEMORY_TYPE_BUFFER_SIZE))
+
+#define DXE_MPS_IS_IMAGE_PROTECTION_ENABLED(DxeMpsPtr) \
+  (((DXE_MEMORY_PROTECTION_SETTINGS*)DxeMpsPtr)->ImageProtection.ProtectImageFromFv || \
+  ((DXE_MEMORY_PROTECTION_SETTINGS*)DxeMpsPtr)->ImageProtection.ProtectImageFromUnknown)
+
+#define DXE_MPS_IS_EXECUTION_PROTECTION_ENABLED(DxeMpsPtr) \
+  DXE_MPS_IS_ANY_MEMORY_TYPE_ACTIVE(&((DXE_MEMORY_PROTECTION_SETTINGS*)DxeMpsPtr)->ExecutionProtection)
+
+#define DXE_MPS_ARE_PAGE_GUARDS_ENABLED(DxeMpsPtr) \
+  (((DXE_MEMORY_PROTECTION_SETTINGS*)DxeMpsPtr)->HeapGuard.PageGuardEnabled  && \
+  DXE_MPS_IS_ANY_MEMORY_TYPE_ACTIVE(&((DXE_MEMORY_PROTECTION_SETTINGS*)DxeMpsPtr)->PageGuard))
+
+#define DXE_MPS_ARE_POOL_GUARDS_ENABLED(DxeMpsPtr) \
+  (((DXE_MEMORY_PROTECTION_SETTINGS*)DxeMpsPtr)->HeapGuard.PoolGuardEnabled  && \
+  DXE_MPS_IS_ANY_MEMORY_TYPE_ACTIVE(&((DXE_MEMORY_PROTECTION_SETTINGS*)DxeMpsPtr)->PoolGuard))
+
+#define DXE_MPS_IS_MEMORY_PROTECTION_ACTIVE(DxeMpsPtr)                                   \
+  (DXE_MPS_IS_STRUCT_VALID(DxeMpsPtr)                                               &&   \
+   (((DXE_MEMORY_PROTECTION_SETTINGS*)DxeMpsPtr)->CpuStackGuardEnabled              ||   \
+    ((DXE_MEMORY_PROTECTION_SETTINGS*)DxeMpsPtr)->StackExecutionProtectionEnabled   ||   \
+    ((DXE_MEMORY_PROTECTION_SETTINGS*)DxeMpsPtr)->NullPointerDetection.Enabled      ||   \
+    DXE_MPS_IS_IMAGE_PROTECTION_ENABLED(DxeMpsPtr)                                  ||   \
+    DXE_MPS_IS_EXECUTION_PROTECTION_ENABLED(DxeMpsPtr)                              ||   \
+    DXE_MPS_ARE_PAGE_GUARDS_ENABLED(DxeMpsPtr)                                      ||   \
+    DXE_MPS_ARE_POOL_GUARDS_ENABLED(DxeMpsPtr))                                          \
+  )
+
+#define HOB_DXE_MEMORY_PROTECTION_SETTINGS_GUID  \
+  { \
+    { 0x9ABFD639, 0xD1D0, 0x4EFF, { 0xBD, 0xB6, 0x7E, 0xC4, 0x19, 0x0D, 0x17, 0xD5 } } \
+  }
+
+extern GUID  gDxeMemoryProtectionSettingsGuid;
+
+//
+//  A memory profile with strict settings ideal for development scenarios.
+//
+#define DXE_MEMORY_PROTECTION_SETTINGS_DEBUG  {                 \
+            DXE_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION,     \
+            TRUE, /* Stack Guard */                             \
+            TRUE, /* Stack Execution Protection */              \
+            {     /* NULL Pointer Detection */                  \
+              .Enabled                                = TRUE,   \
+              .DisableEndOfDxe                        = FALSE,  \
+              .NonstopModeEnabled                     = TRUE    \
+            },                                                  \
+            { /* Image Protection */                            \
+              .ProtectImageFromUnknown                = TRUE,   \
+              .ProtectImageFromFv                     = TRUE    \
+            },                                                  \
+            { /* Execution Protection */                        \
+              .EnabledForType = {                               \
+                [EfiReservedMemoryType]               = TRUE,   \
+                [EfiLoaderCode]                       = FALSE,  \
+                [EfiLoaderData]                       = TRUE,   \
+                [EfiBootServicesCode]                 = FALSE,  \
+                [EfiBootServicesData]                 = TRUE,   \
+                [EfiRuntimeServicesCode]              = FALSE,  \
+                [EfiRuntimeServicesData]              = TRUE,   \
+                [EfiConventionalMemory]               = TRUE,   \
+                [EfiUnusableMemory]                   = TRUE,   \
+                [EfiACPIReclaimMemory]                = TRUE,   \
+                [EfiACPIMemoryNVS]                    = TRUE,   \
+                [EfiMemoryMappedIO]                   = TRUE,   \
+                [EfiMemoryMappedIOPortSpace]          = TRUE,   \
+                [EfiPalCode]                          = TRUE,   \
+                [EfiPersistentMemory]                 = FALSE,  \
+                [EfiUnacceptedMemoryType]             = TRUE,   \
+                [OEM_RESERVED_MPS_MEMORY_TYPE]        = TRUE,   \
+                [OS_RESERVED_MPS_MEMORY_TYPE]         = TRUE    \
+              }                                                 \
+            },                                                  \
+            { /* Heap Guard */                                  \
+              .PageGuardEnabled                       = TRUE,   \
+              .PoolGuardEnabled                       = TRUE,   \
+              .FreedMemoryGuardEnabled                = FALSE,  \
+              .NonstopModeEnabled                     = TRUE,   \
+              .GuardAlignedToTail                     = FALSE   \
+            },                                                  \
+            { /* Pool Guard */                                  \
+              .EnabledForType = {                               \
+                [EfiReservedMemoryType]               = TRUE,   \
+                [EfiLoaderCode]                       = TRUE,   \
+                [EfiLoaderData]                       = TRUE,   \
+                [EfiBootServicesCode]                 = TRUE,   \
+                [EfiBootServicesData]                 = TRUE,   \
+                [EfiRuntimeServicesCode]              = TRUE,   \
+                [EfiRuntimeServicesData]              = TRUE,   \
+                [EfiConventionalMemory]               = FALSE,  \
+                [EfiUnusableMemory]                   = TRUE,   \
+                [EfiACPIReclaimMemory]                = TRUE,   \
+                [EfiACPIMemoryNVS]                    = TRUE,   \
+                [EfiMemoryMappedIO]                   = TRUE,   \
+                [EfiMemoryMappedIOPortSpace]          = TRUE,   \
+                [EfiPalCode]                          = TRUE,   \
+                [EfiPersistentMemory]                 = FALSE,  \
+                [EfiUnacceptedMemoryType]             = TRUE,   \
+                [OEM_RESERVED_MPS_MEMORY_TYPE]        = TRUE,   \
+                [OS_RESERVED_MPS_MEMORY_TYPE]         = TRUE    \
+              }                                                 \
+            },                                                  \
+            { /* Page Guard */                                  \
+              .EnabledForType = {                               \
+                [EfiReservedMemoryType]               = TRUE,   \
+                [EfiLoaderCode]                       = TRUE,   \
+                [EfiLoaderData]                       = TRUE,   \
+                [EfiBootServicesCode]                 = TRUE,   \
+                [EfiBootServicesData]                 = TRUE,   \
+                [EfiRuntimeServicesCode]              = TRUE,   \
+                [EfiRuntimeServicesData]              = TRUE,   \
+                [EfiConventionalMemory]               = FALSE,  \
+                [EfiUnusableMemory]                   = TRUE,   \
+                [EfiACPIReclaimMemory]                = TRUE,   \
+                [EfiACPIMemoryNVS]                    = TRUE,   \
+                [EfiMemoryMappedIO]                   = TRUE,   \
+                [EfiMemoryMappedIOPortSpace]          = TRUE,   \
+                [EfiPalCode]                          = TRUE,   \
+                [EfiPersistentMemory]                 = FALSE,  \
+                [EfiUnacceptedMemoryType]             = TRUE,   \
+                [OEM_RESERVED_MPS_MEMORY_TYPE]        = TRUE,   \
+                [OS_RESERVED_MPS_MEMORY_TYPE]         = TRUE    \
+              }                                                 \
+            }                                                   \
+          };
+
+//
+//  A memory profile recommended for production. Compared to the debug
+//  settings, this profile removes the pool guards and uses page guards
+//  for fewer memory types.
+//
+#define DXE_MEMORY_PROTECTION_SETTINGS_PROD_MODE                \
+          {                                                     \
+            DXE_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION,     \
+            TRUE, /* Stack Guard */                             \
+            TRUE, /* Stack Execution Protection */              \
+            {     /* NULL Pointer Detection */                  \
+              .Enabled                                = TRUE,   \
+              .DisableEndOfDxe                        = FALSE,  \
+              .NonstopModeEnabled                     = FALSE   \
+            },                                                  \
+            { /* Image Protection */                            \
+              .ProtectImageFromUnknown                = FALSE,  \
+              .ProtectImageFromFv                     = TRUE    \
+            },                                                  \
+            { /* Execution Protection */                        \
+              .EnabledForType = {                               \
+                [EfiReservedMemoryType]               = TRUE,   \
+                [EfiLoaderCode]                       = FALSE,  \
+                [EfiLoaderData]                       = TRUE,   \
+                [EfiBootServicesCode]                 = FALSE,  \
+                [EfiBootServicesData]                 = TRUE,   \
+                [EfiRuntimeServicesCode]              = FALSE,  \
+                [EfiRuntimeServicesData]              = TRUE,   \
+                [EfiConventionalMemory]               = TRUE,   \
+                [EfiUnusableMemory]                   = TRUE,   \
+                [EfiACPIReclaimMemory]                = TRUE,   \
+                [EfiACPIMemoryNVS]                    = TRUE,   \
+                [EfiMemoryMappedIO]                   = TRUE,   \
+                [EfiMemoryMappedIOPortSpace]          = TRUE,   \
+                [EfiPalCode]                          = TRUE,   \
+                [EfiPersistentMemory]                 = FALSE,  \
+                [EfiUnacceptedMemoryType]             = TRUE,   \
+                [OEM_RESERVED_MPS_MEMORY_TYPE]        = TRUE,   \
+                [OS_RESERVED_MPS_MEMORY_TYPE]         = TRUE    \
+              }                                                 \
+            },                                                  \
+            { /* Heap Guard */                                  \
+              .PageGuardEnabled                       = TRUE,   \
+              .PoolGuardEnabled                       = FALSE,  \
+              .FreedMemoryGuardEnabled                = FALSE,  \
+              .NonstopModeEnabled                     = FALSE,  \
+              .GuardAlignedToTail                     = FALSE   \
+            },                                                  \
+            { /* Pool Guard */                                  \
+              0                                                 \
+            },                                                  \
+            { /* Page Guard */                                  \
+              .EnabledForType = {                               \
+                [EfiReservedMemoryType]               = FALSE,  \
+                [EfiLoaderCode]                       = FALSE,  \
+                [EfiLoaderData]                       = FALSE,  \
+                [EfiBootServicesCode]                 = FALSE,  \
+                [EfiBootServicesData]                 = TRUE,   \
+                [EfiRuntimeServicesCode]              = FALSE,  \
+                [EfiRuntimeServicesData]              = TRUE,   \
+                [EfiConventionalMemory]               = FALSE,  \
+                [EfiUnusableMemory]                   = FALSE,  \
+                [EfiACPIReclaimMemory]                = FALSE,  \
+                [EfiACPIMemoryNVS]                    = FALSE,  \
+                [EfiMemoryMappedIO]                   = FALSE,  \
+                [EfiMemoryMappedIOPortSpace]          = FALSE,  \
+                [EfiPalCode]                          = FALSE,  \
+                [EfiPersistentMemory]                 = FALSE,  \
+                [EfiUnacceptedMemoryType]             = FALSE,  \
+                [OEM_RESERVED_MPS_MEMORY_TYPE]        = FALSE,  \
+                [OS_RESERVED_MPS_MEMORY_TYPE]         = FALSE   \
+              }                                                 \
+            }                                                   \
+          };
+
+//
+//  A memory profile which mirrors DXE_MEMORY_PROTECTION_SETTINGS_PROD_MODE
+//  but doesn't include page guards.
+//
+#define DXE_MEMORY_PROTECTION_SETTINGS_PROD_MODE_NO_PAGE_GUARDS \
+          {                                                     \
+            DXE_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION,     \
+            TRUE, /* Stack Guard */                             \
+            TRUE, /* Stack Execution Protection */              \
+            {     /* NULL Pointer Detection */                  \
+              .Enabled                                = TRUE,   \
+              .DisableEndOfDxe                        = FALSE,  \
+              .NonstopModeEnabled                     = FALSE   \
+            },                                                  \
+            { /* Image Protection */                            \
+              .ProtectImageFromUnknown                = FALSE,  \
+              .ProtectImageFromFv                     = TRUE    \
+            },                                                  \
+            { /* Execution Protection */                        \
+              .EnabledForType = {                               \
+                [EfiReservedMemoryType]               = TRUE,   \
+                [EfiLoaderCode]                       = FALSE,  \
+                [EfiLoaderData]                       = TRUE,   \
+                [EfiBootServicesCode]                 = FALSE,  \
+                [EfiBootServicesData]                 = TRUE,   \
+                [EfiRuntimeServicesCode]              = FALSE,  \
+                [EfiRuntimeServicesData]              = TRUE,   \
+                [EfiConventionalMemory]               = TRUE,   \
+                [EfiUnusableMemory]                   = TRUE,   \
+                [EfiACPIReclaimMemory]                = TRUE,   \
+                [EfiACPIMemoryNVS]                    = TRUE,   \
+                [EfiMemoryMappedIO]                   = TRUE,   \
+                [EfiMemoryMappedIOPortSpace]          = TRUE,   \
+                [EfiPalCode]                          = TRUE,   \
+                [EfiPersistentMemory]                 = FALSE,  \
+                [EfiUnacceptedMemoryType]             = TRUE,   \
+                [OEM_RESERVED_MPS_MEMORY_TYPE]        = TRUE,   \
+                [OS_RESERVED_MPS_MEMORY_TYPE]         = TRUE    \
+              }                                                 \
+            },                                                  \
+            { /* Heap Guard */                                  \
+              0                                                 \
+            },                                                  \
+            { /* Pool Guard */                                  \
+              0                                                 \
+            },                                                  \
+            { /* Page Guard */                                  \
+              0                                                 \
+            }                                                   \
+          };
+
+//
+//  A memory profile which disables all DXE memory protection settings.
+//
+#define DXE_MEMORY_PROTECTION_SETTINGS_OFF                      \
+          {                                                     \
+            DXE_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION,     \
+            FALSE, /* Stack Guard */                            \
+            FALSE, /* Stack Execution Protection */             \
+            {      /* NULL Pointer Detection */                 \
+              0                                                 \
+            },                                                  \
+            { /* Image Protection */                            \
+              0                                                 \
+            },                                                  \
+            { /* Execution Protection */                        \
+              0                                                 \
+            },                                                  \
+            { /* Heap Guard */                                  \
+              0                                                 \
+            },                                                  \
+            { /* Pool Guard */                                  \
+              0                                                 \
+            },                                                  \
+            { /* Page Guard */                                  \
+              0                                                 \
+            }                                                   \
+          };
+
+#endif
diff --git a/MdeModulePkg/Include/Guid/MmMemoryProtectionSettings.h b/MdeModulePkg/Include/Guid/MmMemoryProtectionSettings.h
new file mode 100644
index 0000000000..383788b8f3
--- /dev/null
+++ b/MdeModulePkg/Include/Guid/MmMemoryProtectionSettings.h
@@ -0,0 +1,211 @@
+/** @file
+
+Defines memory protection settings guid and struct for MM.
+
+Copyright (C) Microsoft Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef MM_MEMORY_PROTECTION_SETTINGS_H_
+#define MM_MEMORY_PROTECTION_SETTINGS_H_
+
+#include <Library/BaseMemoryLib.h>
+
+// Current iteration of MM_MEMORY_PROTECTION_SETTINGS
+#define MM_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION  1
+
+#define OEM_RESERVED_MPS_MEMORY_TYPE    EfiMaxMemoryType
+#define OS_RESERVED_MPS_MEMORY_TYPE     (EfiMaxMemoryType + 1)
+#define MAX_MM_MPS_MEMORY_TYPE          (EfiMaxMemoryType + 2)
+#define MM_MPS_MEMORY_TYPE_BUFFER_SIZE  (MAX_MM_MPS_MEMORY_TYPE * sizeof (BOOLEAN))
+
+typedef struct {
+  BOOLEAN    Enabled            : 1;
+  BOOLEAN    NonstopModeEnabled : 1;
+} MM_NULL_DETECTION_POLICY;
+
+typedef struct {
+  BOOLEAN    PageGuardEnabled   : 1;
+  BOOLEAN    PoolGuardEnabled   : 1;
+  BOOLEAN    NonstopModeEnabled : 1;
+  BOOLEAN    GuardAlignedToTail : 1;
+} MM_HEAP_GUARD_POLICY;
+
+typedef struct {
+  BOOLEAN    EnabledForType[MAX_MM_MPS_MEMORY_TYPE];
+} MM_MPS_MEMORY_TYPES;
+
+typedef UINT8 MM_MEMORY_PROTECTION_SETTINGS_VERSION;
+
+//
+// Memory Protection Settings struct
+//
+typedef struct {
+  // The current version of the structure definition. This is used to ensure there isn't a
+  // definition mismatch if modules have differing iterations of this header. When creating
+  // this struct, use the MM_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION macro.
+  MM_MEMORY_PROTECTION_SETTINGS_VERSION    StructVersion;
+
+  // If enabled, accessing the NULL address in MM will be caught by marking
+  // the NULL page as not present.
+  //   .NullDetectionEnabled    : Enable NULL pointer detection.
+  //   .NonstopModeEnabled      : If enabled the debug flag will be raised when a fault occurs
+  //                              to break into debugger.
+  MM_NULL_DETECTION_POLICY                 NullPointerDetection;
+
+  //  Configures general heap guard behavior.
+  //
+  // Note:
+  //  a) Due to the limit of pool memory implementation and the alignment
+  //     requirement of UEFI spec, HeapGuard.GuardAlignedToTail is a try-best
+  //     setting which cannot guarantee that the returned pool is exactly
+  //     adjacent to head or tail guard page.
+  //
+  //  .PageGuardEnabled          : Enable page guard.
+  //  .PoolGuardEnabled          : Enable pool guard.
+  //  .NonstopModeEnabled        : If enabled the debug flag will be raised when a fault occurs
+  //                               to break into debugger.
+  //  .GuardAlignedToTail        : TRUE if the pool is aligned to tail guard page. If FALSE, the
+  //                               pool is aligned to head guard page.
+  MM_HEAP_GUARD_POLICY    HeapGuard;
+
+  // Indicates which type allocation need guard page.
+  //
+  // If bit is set, a head guard page and a tail guard page will be added just
+  // before and after corresponding type of pages which the allocated pool occupies,
+  // if there's enough free memory for all of them.
+  //
+  // These settings are only valid if PoolGuardEnabled is TRUE in HeapGuard.
+  MM_MPS_MEMORY_TYPES    PoolGuard;
+
+  // Indicates which type allocation need guard page.
+  //
+  // If a bit is set, a head guard page and a tail guard page will be added just
+  // before and after corresponding type of pages allocated if there's enough
+  // free pages for all of them.
+  //
+  // This bitfield is only valid if PageGuardEnabled is TRUE in HeapGuard.
+  MM_MPS_MEMORY_TYPES    PageGuard;
+} MM_MEMORY_PROTECTION_SETTINGS;
+
+#define MM_MPS_IS_STRUCT_VALID(MmMpsPtr) \
+  (((MM_MEMORY_PROTECTION_SETTINGS *)MmMpsPtr)->StructVersion == MM_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION)
+
+#define MM_MPS_IS_ANY_MEMORY_TYPE_ACTIVE(MpsMemoryTypesPtr) \
+  (!IsZeroBuffer (&((MM_MPS_MEMORY_TYPES *)MpsMemoryTypesPtr)->EnabledForType, MM_MPS_MEMORY_TYPE_BUFFER_SIZE))
+
+#define MM_MPS_IS_IMAGE_PROTECTION_ENABLED(MmMpsPtr) \
+  (((MM_MEMORY_PROTECTION_SETTINGS*)MmMpsPtr)->ImageProtection.ProtectImageFromFv || \
+  ((MM_MEMORY_PROTECTION_SETTINGS*)MmMpsPtr)->ImageProtection.ProtectImageFromUnknown)
+
+#define MM_MPS_IS_EXECUTION_PROTECTION_ENABLED(MmMpsPtr) \
+  MM_MPS_IS_ANY_MEMORY_TYPE_ACTIVE(&((MM_MEMORY_PROTECTION_SETTINGS*)MmMpsPtr)->ExecutionProtection)
+
+#define MM_MPS_ARE_PAGE_GUARDS_ENABLED(MmMpsPtr) \
+  (((MM_MEMORY_PROTECTION_SETTINGS*)MmMpsPtr)->HeapGuard.PageGuardEnabled  && \
+  MM_MPS_IS_ANY_MEMORY_TYPE_ACTIVE(&((MM_MEMORY_PROTECTION_SETTINGS*)MmMpsPtr)->PageGuard))
+
+#define MM_MPS_ARE_POOL_GUARDS_ENABLED(MmMpsPtr) \
+  (((MM_MEMORY_PROTECTION_SETTINGS*)MmMpsPtr)->HeapGuard.PoolGuardEnabled  && \
+  MM_MPS_IS_ANY_MEMORY_TYPE_ACTIVE(&((MM_MEMORY_PROTECTION_SETTINGS*)MmMpsPtr)->PoolGuard))
+
+#define MM_MPS_IS_MEMORY_PROTECTION_ACTIVE(MmMpsPtr)                                   \
+  (MM_MPS_IS_STRUCT_VALID(MmMpsPtr)                                               &&   \
+   (((MM_MEMORY_PROTECTION_SETTINGS*)MmMpsPtr)->CpuStackGuardEnabled              ||   \
+    ((MM_MEMORY_PROTECTION_SETTINGS*)MmMpsPtr)->StackExecutionProtectionEnabled   ||   \
+    ((MM_MEMORY_PROTECTION_SETTINGS*)MmMpsPtr)->NullPointerDetection.Enabled      ||   \
+    MM_MPS_IS_IMAGE_PROTECTION_ENABLED(MmMpsPtr)                                  ||   \
+    MM_MPS_IS_EXECUTION_PROTECTION_ENABLED(MmMpsPtr)                              ||   \
+    MM_MPS_ARE_PAGE_GUARDS_ENABLED(MmMpsPtr)                                      ||   \
+    MM_MPS_ARE_POOL_GUARDS_ENABLED(MmMpsPtr))                                          \
+  )
+
+#define HOB_MM_MEMORY_PROTECTION_SETTINGS_GUID \
+  { \
+    { 0x0CF445DD, 0xA67C, 0x4F8C, { 0x81, 0x9B, 0xB7, 0xB6, 0x86, 0xED, 0x7C, 0x75 } } \
+  }
+
+extern GUID  gMmMemoryProtectionSettingsGuid;
+
+//
+//  A memory profile ideal for development scenarios.
+//
+#define MM_MEMORY_PROTECTION_SETTINGS_DEBUG  {               \
+            MM_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION,   \
+            { /* NULL Pointer Detection */                   \
+              .Enabled                             = TRUE,   \
+              .NonstopModeEnabled                  = TRUE    \
+            },                                               \
+            { /* Heap Guard */                               \
+              .PageGuardEnabled                    = TRUE,   \
+              .PoolGuardEnabled                    = TRUE,   \
+              .NonstopModeEnabled                  = TRUE,   \
+              .GuardAlignedToTail                  = FALSE   \
+            },                                               \
+            { /* Pool Guard */                               \
+              .EnabledForType = {                            \
+                [EfiReservedMemoryType]            = FALSE,  \
+                [EfiLoaderCode]                    = FALSE,  \
+                [EfiLoaderData]                    = FALSE,  \
+                [EfiBootServicesCode]              = FALSE,  \
+                [EfiBootServicesData]              = TRUE,   \
+                [EfiRuntimeServicesCode]           = FALSE,  \
+                [EfiRuntimeServicesData]           = TRUE,   \
+                [EfiConventionalMemory]            = FALSE,  \
+                [EfiUnusableMemory]                = FALSE,  \
+                [EfiACPIReclaimMemory]             = FALSE,  \
+                [EfiACPIMemoryNVS]                 = FALSE,  \
+                [EfiMemoryMappedIO]                = FALSE,  \
+                [EfiMemoryMappedIOPortSpace]       = FALSE,  \
+                [EfiPalCode]                       = FALSE,  \
+                [EfiPersistentMemory]              = FALSE,  \
+                [EfiUnacceptedMemoryType]          = FALSE,  \
+                [OEM_RESERVED_MPS_MEMORY_TYPE]     = FALSE,  \
+                [OS_RESERVED_MPS_MEMORY_TYPE]      = FALSE   \
+              }                                              \
+            },                                               \
+            { /* Page Guard */                               \
+              .EnabledForType = {                            \
+                [EfiReservedMemoryType]            = FALSE,  \
+                [EfiLoaderCode]                    = FALSE,  \
+                [EfiLoaderData]                    = FALSE,  \
+                [EfiBootServicesCode]              = FALSE,  \
+                [EfiBootServicesData]              = TRUE,   \
+                [EfiRuntimeServicesCode]           = FALSE,  \
+                [EfiRuntimeServicesData]           = TRUE,   \
+                [EfiConventionalMemory]            = FALSE,  \
+                [EfiUnusableMemory]                = FALSE,  \
+                [EfiACPIReclaimMemory]             = FALSE,  \
+                [EfiACPIMemoryNVS]                 = FALSE,  \
+                [EfiMemoryMappedIO]                = FALSE,  \
+                [EfiMemoryMappedIOPortSpace]       = FALSE,  \
+                [EfiPalCode]                       = FALSE,  \
+                [EfiPersistentMemory]              = FALSE,  \
+                [EfiUnacceptedMemoryType]          = FALSE,  \
+                [OEM_RESERVED_MPS_MEMORY_TYPE]     = FALSE,  \
+                [OS_RESERVED_MPS_MEMORY_TYPE]      = FALSE   \
+              }                                              \
+            }                                                \
+          }
+
+//
+//  A memory profile which disables all MM memory protection settings.
+//
+#define MM_MEMORY_PROTECTION_SETTINGS_OFF  {                 \
+            MM_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION,   \
+            { /* NULL Pointer Detection */                   \
+              0                                              \
+            },                                               \
+            { /* Heap Guard */                               \
+              0                                              \
+            },                                               \
+            { /* Pool Guard */                               \
+              0                                              \
+            },                                               \
+            { /* Page Guard */                               \
+              0                                              \
+            }                                                \
+          }
+
+#endif
diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
index d65dae18aa..f8c0fb4e93 100644
--- a/MdeModulePkg/MdeModulePkg.dec
+++ b/MdeModulePkg/MdeModulePkg.dec
@@ -399,6 +399,16 @@
   ## Include/Guid/EndofS3Resume.h
   gEdkiiEndOfS3ResumeGuid = { 0x96f5296d, 0x05f7, 0x4f3c, {0x84, 0x67, 0xe4, 0x56, 0x89, 0x0e, 0x0c, 0xb5 } }
 
+  ## DXE Memory Protection Settings Guid. Used to create and fetch the DXE memory protection settings HOB entry.
+  #
+  # Include/Guid/DxeMemoryProtectionSettings
+  gDxeMemoryProtectionSettingsGuid = { 0x9ABFD639, 0xD1D0, 0x4EFF, { 0xBD, 0xB6, 0x7E, 0xC4, 0x19, 0x0D, 0x17, 0xD5 }}
+
+  ## SMM Memory Protection Settings Guid. Used to create and fetch the SMM memory protection settings HOB entry.
+  #
+  # Include/Guid/MmMemoryProtectionSettings
+  gMmMemoryProtectionSettingsGuid = { 0x0CF445DD, 0xA67C, 0x4F8C, { 0x81, 0x9B, 0xB7, 0xB6, 0x86, 0xED, 0x7C, 0x75 }}
+
   ## Used (similar to Variable Services) to communicate policies to the enforcement engine.
   # {DA1B0D11-D1A7-46C4-9DC9-F3714875C6EB}
   gVarCheckPolicyLibMmiHandlerGuid = { 0xda1b0d11, 0xd1a7, 0x46c4, { 0x9d, 0xc9, 0xf3, 0x71, 0x48, 0x75, 0xc6, 0xeb }}
-- 
2.41.0.windows.2


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 02/14] MdeModulePkg: Add MemoryProtectionHobLib Definitions and NULL Libs
  2023-07-11 23:52 [PATCH 00/14] Implement Dynamic Memory Protections Taylor Beebe
  2023-07-11 23:52 ` [PATCH 01/14] MdeModulePkg: Add DXE and MM Memory Protection Settings Definitions Taylor Beebe
@ 2023-07-11 23:52 ` Taylor Beebe
  2023-07-11 23:52 ` [PATCH 03/14] MdeModulePkg: Add Phase-Specific MemoryProtectionHobLib Implementations Taylor Beebe
                   ` (14 subsequent siblings)
  16 siblings, 0 replies; 24+ messages in thread
From: Taylor Beebe @ 2023-07-11 23:52 UTC (permalink / raw)
  To: devel; +Cc: Jian J Wang, Liming Gao, Dandan Bi

From: Taylor Beebe <tabeebe@microsoft.com>

DxeMemoryProtectionHobLib and MmMemoryProtectionHobLib will fetch
the memory protection settings HOB entry for their respective phase,
validate the settings, and populate a global for access.

Memory protection settings are currently dictated via
FixedAtBuild PCDs where the settings needed to be masked.
A future patch series will replace instances of checking the
PCDs with checks to the memory protection globals populated by
MemoryProtectionHobLib.

Signed-off-by: Taylor Beebe <t@taylorbeebe.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Dandan Bi <dandan.bi@intel.com>
---
 .../Library/DxeMemoryProtectionHobLib.h       | 20 +++++++++++++
 .../Library/MmMemoryProtectionHobLib.h        | 20 +++++++++++++
 .../DxeMemoryProtectionHobLibNull.c           | 13 +++++++++
 .../DxeMemoryProtectionHobLibNull.inf         | 28 +++++++++++++++++++
 .../MmMemoryProtectionHobLibNull.c            | 13 +++++++++
 .../MmMemoryProtectionHobLibNull.inf          | 28 +++++++++++++++++++
 MdeModulePkg/MdeModulePkg.dec                 |  8 ++++++
 MdeModulePkg/MdeModulePkg.dsc                 |  8 ++++++
 8 files changed, 138 insertions(+)
 create mode 100644 MdeModulePkg/Include/Library/DxeMemoryProtectionHobLib.h
 create mode 100644 MdeModulePkg/Include/Library/MmMemoryProtectionHobLib.h
 create mode 100644 MdeModulePkg/Library/MemoryProtectionHobLibNull/DxeMemoryProtectionHobLibNull.c
 create mode 100644 MdeModulePkg/Library/MemoryProtectionHobLibNull/DxeMemoryProtectionHobLibNull.inf
 create mode 100644 MdeModulePkg/Library/MemoryProtectionHobLibNull/MmMemoryProtectionHobLibNull.c
 create mode 100644 MdeModulePkg/Library/MemoryProtectionHobLibNull/MmMemoryProtectionHobLibNull.inf

diff --git a/MdeModulePkg/Include/Library/DxeMemoryProtectionHobLib.h b/MdeModulePkg/Include/Library/DxeMemoryProtectionHobLib.h
new file mode 100644
index 0000000000..a6809e564c
--- /dev/null
+++ b/MdeModulePkg/Include/Library/DxeMemoryProtectionHobLib.h
@@ -0,0 +1,20 @@
+/** @file
+
+Library for accessing memory protection settings.
+
+Copyright (C) Microsoft Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef DXE_MEMORY_PROTECTION_HOB_LIB_H_
+#define DXE_MEMORY_PROTECTION_HOB_LIB_H_
+
+#include <Guid/DxeMemoryProtectionSettings.h>
+
+//
+//  The global used to access current Memory Protection Settings
+//
+extern DXE_MEMORY_PROTECTION_SETTINGS  gDxeMps;
+
+#endif
diff --git a/MdeModulePkg/Include/Library/MmMemoryProtectionHobLib.h b/MdeModulePkg/Include/Library/MmMemoryProtectionHobLib.h
new file mode 100644
index 0000000000..09c25e878e
--- /dev/null
+++ b/MdeModulePkg/Include/Library/MmMemoryProtectionHobLib.h
@@ -0,0 +1,20 @@
+/** @file
+
+Library for accessing memory protection settings.
+
+Copyright (C) Microsoft Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef MM_MEMORY_PROTECTION_HOB_LIB_H_
+#define MM_MEMORY_PROTECTION_HOB_LIB_H_
+
+#include <Guid/MmMemoryProtectionSettings.h>
+
+//
+//  The global used to access current Memory Protection Settings
+//
+extern MM_MEMORY_PROTECTION_SETTINGS  gMmMps;
+
+#endif
diff --git a/MdeModulePkg/Library/MemoryProtectionHobLibNull/DxeMemoryProtectionHobLibNull.c b/MdeModulePkg/Library/MemoryProtectionHobLibNull/DxeMemoryProtectionHobLibNull.c
new file mode 100644
index 0000000000..2191a136b7
--- /dev/null
+++ b/MdeModulePkg/Library/MemoryProtectionHobLibNull/DxeMemoryProtectionHobLibNull.c
@@ -0,0 +1,13 @@
+/** @file
+Library defines the gDxeMps global
+
+Copyright (c) Microsoft Corporation.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi.h>
+#include <Library/DxeMemoryProtectionHobLib.h>
+
+// A global variable which is uninitialized will be zero.
+// The net effect is memory protections will be OFF.
+DXE_MEMORY_PROTECTION_SETTINGS  gDxeMps;
diff --git a/MdeModulePkg/Library/MemoryProtectionHobLibNull/DxeMemoryProtectionHobLibNull.inf b/MdeModulePkg/Library/MemoryProtectionHobLibNull/DxeMemoryProtectionHobLibNull.inf
new file mode 100644
index 0000000000..65f66936e3
--- /dev/null
+++ b/MdeModulePkg/Library/MemoryProtectionHobLibNull/DxeMemoryProtectionHobLibNull.inf
@@ -0,0 +1,28 @@
+## @file
+# NULL library which defines gDxeMps
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = DxeMemoryProtectionHobLibNull
+  FILE_GUID                      = a35c1dc1-0769-421b-a8bc-9db69fae4334
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = DxeMemoryProtectionHobLib
+
+#
+#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
+#
+
+[Sources]
+  DxeMemoryProtectionHobLibNull.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+  BaseMemoryLib
diff --git a/MdeModulePkg/Library/MemoryProtectionHobLibNull/MmMemoryProtectionHobLibNull.c b/MdeModulePkg/Library/MemoryProtectionHobLibNull/MmMemoryProtectionHobLibNull.c
new file mode 100644
index 0000000000..6b3f6bae8d
--- /dev/null
+++ b/MdeModulePkg/Library/MemoryProtectionHobLibNull/MmMemoryProtectionHobLibNull.c
@@ -0,0 +1,13 @@
+/** @file
+Library defines the gMmMps global
+
+Copyright (c) Microsoft Corporation.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi.h>
+#include <Library/MmMemoryProtectionHobLib.h>
+
+// A global variable which is uninitialized will be zero.
+// The net effect is memory protections will be OFF.
+MM_MEMORY_PROTECTION_SETTINGS  gMmMps;
diff --git a/MdeModulePkg/Library/MemoryProtectionHobLibNull/MmMemoryProtectionHobLibNull.inf b/MdeModulePkg/Library/MemoryProtectionHobLibNull/MmMemoryProtectionHobLibNull.inf
new file mode 100644
index 0000000000..5621ccbdb6
--- /dev/null
+++ b/MdeModulePkg/Library/MemoryProtectionHobLibNull/MmMemoryProtectionHobLibNull.inf
@@ -0,0 +1,28 @@
+## @file
+# NULL library which defines gMmMps
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = MmMemoryProtectionHobLibNull
+  FILE_GUID                      = 4e3f6fd9-4ab5-4911-b80b-009d3338b4b2
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = MmMemoryProtectionHobLib
+
+#
+#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
+#
+
+[Sources]
+  MmMemoryProtectionHobLibNull.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+  BaseMemoryLib
diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
index f8c0fb4e93..2541b2b044 100644
--- a/MdeModulePkg/MdeModulePkg.dec
+++ b/MdeModulePkg/MdeModulePkg.dec
@@ -164,6 +164,14 @@
   #
   VariableFlashInfoLib|Include/Library/VariableFlashInfoLib.h
 
+  ## @libraryclass Provides a way to toggle DXE memory protection settings
+  #
+  DxeMemoryProtectionHobLib|Include/Library/DxeMemoryProtectionHobLib.h
+
+  ## @libraryclass Provides a way to toggle SMM memory protection settings
+  #
+  MmMemoryProtectionHobLib|Include/Library/MmMemoryProtectionHobLib.h
+
 [Guids]
   ## MdeModule package token space guid
   # Include/Guid/MdeModulePkgTokenSpace.h
diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc
index 1aedfe280a..3fad493c7f 100644
--- a/MdeModulePkg/MdeModulePkg.dsc
+++ b/MdeModulePkg/MdeModulePkg.dsc
@@ -107,6 +107,12 @@
   VariableFlashInfoLib|MdeModulePkg/Library/BaseVariableFlashInfoLib/BaseVariableFlashInfoLib.inf
   IpmiCommandLib|MdeModulePkg/Library/BaseIpmiCommandLibNull/BaseIpmiCommandLibNull.inf
 
+[LibraryClasses.common.DXE_DRIVER, LibraryClasses.common.DXE_CORE, LibraryClasses.common.UEFI_APPLICATION]
+  DxeMemoryProtectionHobLib|MdeModulePkg/Library/MemoryProtectionHobLibNull/DxeMemoryProtectionHobLibNull.inf
+
+[LibraryClasses.common.SMM_CORE, LibraryClasses.common.DXE_SMM_DRIVER, LibraryClasses.common.MM_CORE_STANDALONE, LibraryClasses.common.MM_STANDALONE]
+  MmMemoryProtectionHobLib|MdeModulePkg/Library/MemoryProtectionHobLibNull/MmMemoryProtectionHobLibNull.inf
+
 [LibraryClasses.EBC.PEIM]
   IoLib|MdePkg/Library/PeiIoLibCpuIo/PeiIoLibCpuIo.inf
 
@@ -231,6 +237,8 @@
   MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
   MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf
   MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf
+  MdeModulePkg/Library/MemoryProtectionHobLibNull/DxeMemoryProtectionHobLibNull.inf
+  MdeModulePkg/Library/MemoryProtectionHobLibNull/MmMemoryProtectionHobLibNull.inf
   MdeModulePkg/Library/PciHostBridgeLibNull/PciHostBridgeLibNull.inf
   MdeModulePkg/Library/PiSmmCoreSmmServicesTableLib/PiSmmCoreSmmServicesTableLib.inf
   MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
-- 
2.41.0.windows.2


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 03/14] MdeModulePkg: Add Phase-Specific MemoryProtectionHobLib Implementations
  2023-07-11 23:52 [PATCH 00/14] Implement Dynamic Memory Protections Taylor Beebe
  2023-07-11 23:52 ` [PATCH 01/14] MdeModulePkg: Add DXE and MM Memory Protection Settings Definitions Taylor Beebe
  2023-07-11 23:52 ` [PATCH 02/14] MdeModulePkg: Add MemoryProtectionHobLib Definitions and NULL Libs Taylor Beebe
@ 2023-07-11 23:52 ` Taylor Beebe
  2023-07-11 23:52 ` [PATCH 04/14] OvmfPkg: Create the memory protection settings HOB Taylor Beebe
                   ` (13 subsequent siblings)
  16 siblings, 0 replies; 24+ messages in thread
From: Taylor Beebe @ 2023-07-11 23:52 UTC (permalink / raw)
  To: devel; +Cc: Jian J Wang, Liming Gao, Dandan Bi

From: Taylor Beebe <tabeebe@microsoft.com>

Add DXE, SMM, and STANDALONE MM implementations of the
MemoryProtectionHobLib.

Signed-off-by: Taylor Beebe <t@taylorbeebe.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Dandan Bi <dandan.bi@intel.com>
---
 .../DxeMemoryProtectionHobLib.c               | 132 ++++++++++++++++++
 .../DxeMemoryProtectionHobLib.inf             |  34 +++++
 .../MmCommonMemoryProtectionHobLib.c          |  89 ++++++++++++
 .../SmmMemoryProtectionHobLib.c               |  37 +++++
 .../SmmMemoryProtectionHobLib.inf             |  35 +++++
 .../StandaloneMmMemoryProtectionHobLib.c      |  37 +++++
 .../StandaloneMmMemoryProtectionHobLib.inf    |  36 +++++
 MdeModulePkg/MdeModulePkg.dsc                 |   3 +
 8 files changed, 403 insertions(+)
 create mode 100644 MdeModulePkg/Library/MemoryProtectionHobLib/DxeMemoryProtectionHobLib.c
 create mode 100644 MdeModulePkg/Library/MemoryProtectionHobLib/DxeMemoryProtectionHobLib.inf
 create mode 100644 MdeModulePkg/Library/MemoryProtectionHobLib/MmCommonMemoryProtectionHobLib.c
 create mode 100644 MdeModulePkg/Library/MemoryProtectionHobLib/SmmMemoryProtectionHobLib.c
 create mode 100644 MdeModulePkg/Library/MemoryProtectionHobLib/SmmMemoryProtectionHobLib.inf
 create mode 100644 MdeModulePkg/Library/MemoryProtectionHobLib/StandaloneMmMemoryProtectionHobLib.c
 create mode 100644 MdeModulePkg/Library/MemoryProtectionHobLib/StandaloneMmMemoryProtectionHobLib.inf

diff --git a/MdeModulePkg/Library/MemoryProtectionHobLib/DxeMemoryProtectionHobLib.c b/MdeModulePkg/Library/MemoryProtectionHobLib/DxeMemoryProtectionHobLib.c
new file mode 100644
index 0000000000..fde568fcee
--- /dev/null
+++ b/MdeModulePkg/Library/MemoryProtectionHobLib/DxeMemoryProtectionHobLib.c
@@ -0,0 +1,132 @@
+/** @file
+Library fills out gDxeMps global
+
+Copyright (c) Microsoft Corporation.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi.h>
+#include <Pi/PiMultiPhase.h>
+#include <Uefi/UefiMultiPhase.h>
+
+#include <Library/DxeMemoryProtectionHobLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/BaseMemoryLib.h>
+
+DXE_MEMORY_PROTECTION_SETTINGS  gDxeMps;
+
+/**
+  This function checks the memory protection settings and provides warnings of settings conflicts.
+  For compatibility, this logic will only ever turn off protections to create consistency,
+  never turn others on.
+**/
+VOID
+DxeMemoryProtectionSettingsConsistencyCheck (
+  VOID
+  )
+{
+  if ((gDxeMps.HeapGuard.PoolGuardEnabled || gDxeMps.HeapGuard.PageGuardEnabled) &&
+      gDxeMps.HeapGuard.FreedMemoryGuardEnabled)
+  {
+    DEBUG ((
+      DEBUG_WARN,
+      "%a: - HeapGuard.FreedMemoryGuardEnabled and "
+      "UEFI HeapGuard.PoolGuardEnabled/HeapGuard.PageGuardEnabled "
+      "cannot be active at the same time. Setting all three to ZERO in "
+      "the memory protection settings global.\n",
+      __func__
+      ));
+    ASSERT (
+      !(gDxeMps.HeapGuard.FreedMemoryGuardEnabled &&
+        (gDxeMps.HeapGuard.PoolGuardEnabled || gDxeMps.HeapGuard.PageGuardEnabled))
+      );
+    gDxeMps.HeapGuard.PoolGuardEnabled        = FALSE;
+    gDxeMps.HeapGuard.PageGuardEnabled        = FALSE;
+    gDxeMps.HeapGuard.FreedMemoryGuardEnabled = FALSE;
+  }
+
+  if (DXE_MPS_IS_ANY_MEMORY_TYPE_ACTIVE (&gDxeMps.PoolGuard) &&
+      (!(gDxeMps.HeapGuard.PoolGuardEnabled)))
+  {
+    DEBUG ((
+      DEBUG_WARN,
+      "%a: - PoolGuard protections are active "
+      "but HeapGuard.PoolGuardEnabled is inactive.\n",
+      __func__
+      ));
+  }
+
+  if (DXE_MPS_IS_ANY_MEMORY_TYPE_ACTIVE (&gDxeMps.PageGuard) &&
+      (!(gDxeMps.HeapGuard.PageGuardEnabled)))
+  {
+    DEBUG ((
+      DEBUG_WARN,
+      "%a: - PageGuard protections are active "
+      "but HeapGuard.PageGuardEnabled is inactive\n",
+      __func__
+      ));
+  }
+
+  if (gDxeMps.ExecutionProtection.EnabledForType[EfiBootServicesData] !=
+      gDxeMps.ExecutionProtection.EnabledForType[EfiConventionalMemory])
+  {
+    DEBUG ((
+      DEBUG_WARN,
+      "%a: - EfiBootServicesData and EfiConventionalMemory must have the same "
+      "ExecutionProtection value. Setting both to ZERO in the memory protection "
+      "settings global.\n",
+      __func__
+      ));
+    ASSERT (
+      gDxeMps.ExecutionProtection.EnabledForType[EfiBootServicesData] ==
+      gDxeMps.ExecutionProtection.EnabledForType[EfiConventionalMemory]
+      );
+    gDxeMps.ExecutionProtection.EnabledForType[EfiBootServicesData]   = FALSE;
+    gDxeMps.ExecutionProtection.EnabledForType[EfiConventionalMemory] = FALSE;
+  }
+}
+
+/**
+  Populates gDxeMps global with the data present in the HOB. If the HOB entry does not exist,
+  this constructor will zero the memory protection settings.
+
+  @param[in]  ImageHandle   The firmware allocated handle for the EFI image.
+  @param[in]  SystemTable   A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.
+**/
+EFI_STATUS
+EFIAPI
+DxeMemoryProtectionHobLibConstructor (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  VOID                            *Ptr;
+  DXE_MEMORY_PROTECTION_SETTINGS  *DxeMps;
+
+  Ptr = GetFirstGuidHob (&gDxeMemoryProtectionSettingsGuid);
+
+  //
+  // Cache the Memory Protection Settings HOB entry
+  //
+  if (Ptr != NULL) {
+    DxeMps = (DXE_MEMORY_PROTECTION_SETTINGS *)GET_GUID_HOB_DATA (Ptr);
+    if (!DXE_MPS_IS_STRUCT_VALID (DxeMps)) {
+      DEBUG ((
+        DEBUG_ERROR,
+        "%a: - Version number of the DXE Memory Protection Settings HOB is invalid!\n",
+        __func__
+        ));
+      ASSERT (DXE_MPS_IS_STRUCT_VALID (DxeMps));
+      ZeroMem (&gDxeMps, sizeof (gDxeMps));
+      return EFI_SUCCESS;
+    }
+
+    CopyMem (&gDxeMps, DxeMps, sizeof (DXE_MEMORY_PROTECTION_SETTINGS));
+    DxeMemoryProtectionSettingsConsistencyCheck ();
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/MdeModulePkg/Library/MemoryProtectionHobLib/DxeMemoryProtectionHobLib.inf b/MdeModulePkg/Library/MemoryProtectionHobLib/DxeMemoryProtectionHobLib.inf
new file mode 100644
index 0000000000..57ca55446b
--- /dev/null
+++ b/MdeModulePkg/Library/MemoryProtectionHobLib/DxeMemoryProtectionHobLib.inf
@@ -0,0 +1,34 @@
+## @file
+# DXE library instance to support platform-specific global controls for all memory protections.
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = DxeMemoryProtectionHobLib
+  FILE_GUID                      = f497f7de-b9ab-4b9f-807e-89778922542d
+  MODULE_TYPE                    = UEFI_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = DxeMemoryProtectionHobLib|DXE_DRIVER DXE_CORE UEFI_APPLICATION UEFI_DRIVER
+  CONSTRUCTOR                    = DxeMemoryProtectionHobLibConstructor
+
+#
+#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
+#
+
+[Sources]
+  DxeMemoryProtectionHobLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+  HobLib
+  DebugLib
+  BaseMemoryLib
+
+[Guids]
+  gDxeMemoryProtectionSettingsGuid
diff --git a/MdeModulePkg/Library/MemoryProtectionHobLib/MmCommonMemoryProtectionHobLib.c b/MdeModulePkg/Library/MemoryProtectionHobLib/MmCommonMemoryProtectionHobLib.c
new file mode 100644
index 0000000000..73f4b0cd88
--- /dev/null
+++ b/MdeModulePkg/Library/MemoryProtectionHobLib/MmCommonMemoryProtectionHobLib.c
@@ -0,0 +1,89 @@
+/** @file
+Library fills out gMmMps global
+
+Copyright (c) Microsoft Corporation.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi.h>
+#include <Pi/PiMultiPhase.h>
+#include <Uefi/UefiMultiPhase.h>
+
+#include <Library/MmMemoryProtectionHobLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/BaseMemoryLib.h>
+
+MM_MEMORY_PROTECTION_SETTINGS  gMmMps;
+
+/**
+  This function checks the memory protection settings and provides warnings of settings conflicts.
+  For compatibility, this logic will only ever turn off protections to create consistency,
+  never turn others on.
+**/
+VOID
+MmMemoryProtectionSettingsConsistencyCheck (
+  VOID
+  )
+{
+  if (MM_MPS_IS_ANY_MEMORY_TYPE_ACTIVE (&gMmMps.PoolGuard) &&
+      (!gMmMps.HeapGuard.PoolGuardEnabled))
+  {
+    DEBUG ((
+      DEBUG_WARN,
+      "%a: - PoolGuard protections are active "
+      "but HeapGuard.PoolGuardEnabled is inactive.\n",
+      __func__
+      ));
+  }
+
+  if (MM_MPS_IS_ANY_MEMORY_TYPE_ACTIVE (&gMmMps.PageGuard) &&
+      (!gMmMps.HeapGuard.PageGuardEnabled))
+  {
+    DEBUG ((
+      DEBUG_WARN,
+      "%a: - PageGuard protections are active "
+      "but HeapGuard.PageGuardEnabled is inactive\n",
+      __func__
+      ));
+  }
+}
+
+/**
+  Abstraction layer for library constructor of Standalone MM and SMM instances.
+
+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.
+**/
+EFI_STATUS
+EFIAPI
+MmMemoryProtectionHobLibConstructorCommon (
+  VOID
+  )
+{
+  VOID                           *Ptr;
+  MM_MEMORY_PROTECTION_SETTINGS  *MmMps;
+
+  Ptr = GetFirstGuidHob (&gMmMemoryProtectionSettingsGuid);
+
+  //
+  // Cache the Memory Protection Settings HOB entry
+  //
+  if (Ptr != NULL) {
+    MmMps = (MM_MEMORY_PROTECTION_SETTINGS *)GET_GUID_HOB_DATA (Ptr);
+    if (!MM_MPS_IS_STRUCT_VALID (MmMps)) {
+      DEBUG ((
+        DEBUG_ERROR,
+        "%a: - Version number of the MM Memory Protection Settings HOB is invalid!\n",
+        __func__
+        ));
+      ASSERT (MM_MPS_IS_STRUCT_VALID (MmMps));
+      ZeroMem (&gMmMps, sizeof (gMmMps));
+      return EFI_SUCCESS;
+    }
+
+    CopyMem (&gMmMps, MmMps, sizeof (MM_MEMORY_PROTECTION_SETTINGS));
+    MmMemoryProtectionSettingsConsistencyCheck ();
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/MdeModulePkg/Library/MemoryProtectionHobLib/SmmMemoryProtectionHobLib.c b/MdeModulePkg/Library/MemoryProtectionHobLib/SmmMemoryProtectionHobLib.c
new file mode 100644
index 0000000000..fffc90a721
--- /dev/null
+++ b/MdeModulePkg/Library/MemoryProtectionHobLib/SmmMemoryProtectionHobLib.c
@@ -0,0 +1,37 @@
+/** @file
+Library fills out gMmMps global
+
+Copyright (c) Microsoft Corporation.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiSmm.h>
+
+/**
+  Abstraction layer for library constructor of Standalone MM and SMM instances.
+
+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.
+**/
+EFI_STATUS
+EFIAPI
+MmMemoryProtectionHobLibConstructorCommon (
+  VOID
+  );
+
+/**
+  Library constructor of SMM instance.
+
+  @param[in]  ImageHandle   The firmware allocated handle for the EFI image.
+  @param[in]  SystemTable   A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.
+**/
+EFI_STATUS
+EFIAPI
+SmmMemoryProtectionHobLibConstructor (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  return MmMemoryProtectionHobLibConstructorCommon ();
+}
diff --git a/MdeModulePkg/Library/MemoryProtectionHobLib/SmmMemoryProtectionHobLib.inf b/MdeModulePkg/Library/MemoryProtectionHobLib/SmmMemoryProtectionHobLib.inf
new file mode 100644
index 0000000000..4651158bd4
--- /dev/null
+++ b/MdeModulePkg/Library/MemoryProtectionHobLib/SmmMemoryProtectionHobLib.inf
@@ -0,0 +1,35 @@
+## @file
+# SMM library instance to support platform-specific global controls for all memory protections.
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SmmMemoryProtectionHobLib
+  FILE_GUID                      = dc9666f4-917f-400d-8026-2b3beeeff195
+  MODULE_TYPE                    = DXE_SMM_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = MmMemoryProtectionHobLib|SMM_CORE DXE_SMM_DRIVER
+  CONSTRUCTOR                    = SmmMemoryProtectionHobLibConstructor
+
+#
+#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
+#
+
+[Sources]
+  MmCommonMemoryProtectionHobLib.c
+  SmmMemoryProtectionHobLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+  HobLib
+  DebugLib
+  BaseMemoryLib
+
+[Guids]
+  gMmMemoryProtectionSettingsGuid
diff --git a/MdeModulePkg/Library/MemoryProtectionHobLib/StandaloneMmMemoryProtectionHobLib.c b/MdeModulePkg/Library/MemoryProtectionHobLib/StandaloneMmMemoryProtectionHobLib.c
new file mode 100644
index 0000000000..3fd8b9f259
--- /dev/null
+++ b/MdeModulePkg/Library/MemoryProtectionHobLib/StandaloneMmMemoryProtectionHobLib.c
@@ -0,0 +1,37 @@
+/** @file
+Library fills out gMmMps global
+
+Copyright (c) Microsoft Corporation.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiMm.h>
+
+/**
+  Abstraction layer for library constructor of Standalone MM and SMM instances.
+
+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.
+**/
+EFI_STATUS
+EFIAPI
+MmMemoryProtectionHobLibConstructorCommon (
+  VOID
+  );
+
+/**
+  Library constructor of Standalone MM instance.
+
+  @param[in]  ImageHandle   The firmware allocated handle for the EFI image.
+  @param[in]  SystemTable   A pointer to the EFI MM System Table.
+
+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.
+**/
+EFI_STATUS
+EFIAPI
+StandaloneMmMemoryProtectionHobLibConstructor (
+  IN EFI_HANDLE           ImageHandle,
+  IN EFI_MM_SYSTEM_TABLE  *SystemTable
+  )
+{
+  return MmMemoryProtectionHobLibConstructorCommon ();
+}
diff --git a/MdeModulePkg/Library/MemoryProtectionHobLib/StandaloneMmMemoryProtectionHobLib.inf b/MdeModulePkg/Library/MemoryProtectionHobLib/StandaloneMmMemoryProtectionHobLib.inf
new file mode 100644
index 0000000000..3cadb5ec6e
--- /dev/null
+++ b/MdeModulePkg/Library/MemoryProtectionHobLib/StandaloneMmMemoryProtectionHobLib.inf
@@ -0,0 +1,36 @@
+## @file
+# SMM library instance to support platform-specific global controls for all memory protections.
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = StandaloneMmMemoryProtectionHobLib
+  FILE_GUID                      = C0A0D9C4-A249-483A-86EA-D73146D397B3
+  MODULE_TYPE                    = MM_CORE_STANDALONE
+  PI_SPECIFICATION_VERSION       = 0x00010032
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = MmMemoryProtectionHobLib|MM_CORE_STANDALONE MM_STANDALONE
+  CONSTRUCTOR                    = StandaloneMmMemoryProtectionHobLibConstructor
+
+#
+#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
+#
+
+[Sources]
+  MmCommonMemoryProtectionHobLib.c
+  StandaloneMmMemoryProtectionHobLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+  HobLib
+  DebugLib
+  BaseMemoryLib
+
+[Guids]
+  gMmMemoryProtectionSettingsGuid
diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc
index 3fad493c7f..ec3c8913ad 100644
--- a/MdeModulePkg/MdeModulePkg.dsc
+++ b/MdeModulePkg/MdeModulePkg.dsc
@@ -237,6 +237,9 @@
   MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
   MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf
   MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf
+  MdeModulePkg/Library/MemoryProtectionHobLib/DxeMemoryProtectionHobLib.inf
+  MdeModulePkg/Library/MemoryProtectionHobLib/SmmMemoryProtectionHobLib.inf
+  MdeModulePkg/Library/MemoryProtectionHobLib/StandaloneMmMemoryProtectionHobLib.inf
   MdeModulePkg/Library/MemoryProtectionHobLibNull/DxeMemoryProtectionHobLibNull.inf
   MdeModulePkg/Library/MemoryProtectionHobLibNull/MmMemoryProtectionHobLibNull.inf
   MdeModulePkg/Library/PciHostBridgeLibNull/PciHostBridgeLibNull.inf
-- 
2.41.0.windows.2


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 04/14] OvmfPkg: Create the memory protection settings HOB
  2023-07-11 23:52 [PATCH 00/14] Implement Dynamic Memory Protections Taylor Beebe
                   ` (2 preceding siblings ...)
  2023-07-11 23:52 ` [PATCH 03/14] MdeModulePkg: Add Phase-Specific MemoryProtectionHobLib Implementations Taylor Beebe
@ 2023-07-11 23:52 ` Taylor Beebe
  2023-07-11 23:52 ` [PATCH 05/14] ArmVirtPkg: Create " Taylor Beebe
                   ` (12 subsequent siblings)
  16 siblings, 0 replies; 24+ messages in thread
From: Taylor Beebe @ 2023-07-11 23:52 UTC (permalink / raw)
  To: devel; +Cc: Ard Biesheuvel, Jiewen Yao, Jordan Justen, Gerd Hoffmann

From: Taylor Beebe <tabeebe@microsoft.com>

Create the memory protection settings HOB on Ovmf platforms with
DEBUG settings.

Signed-off-by: Taylor Beebe <t@taylorbeebe.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
---
 OvmfPkg/AmdSev/AmdSevX64.dsc                  |  2 ++
 OvmfPkg/Bhyve/BhyveX64.dsc                    |  2 ++
 OvmfPkg/CloudHv/CloudHvX64.dsc                |  2 ++
 .../Dsc/MemoryProtectionLibraries.dsc.inc     | 15 +++++++++++
 OvmfPkg/IntelTdx/IntelTdxX64.dsc              |  2 ++
 OvmfPkg/Microvm/MicrovmX64.dsc                |  2 ++
 OvmfPkg/OvmfPkgIa32.dsc                       |  2 ++
 OvmfPkg/OvmfPkgIa32X64.dsc                    |  2 ++
 OvmfPkg/OvmfPkgX64.dsc                        |  2 ++
 OvmfPkg/OvmfXen.dsc                           |  2 ++
 OvmfPkg/PlatformPei/Platform.c                | 27 +++++++++++++++++--
 OvmfPkg/PlatformPei/PlatformPei.inf           |  2 ++
 OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc           |  1 +
 13 files changed, 61 insertions(+), 2 deletions(-)
 create mode 100644 OvmfPkg/Include/Dsc/MemoryProtectionLibraries.dsc.inc

diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc
index 2c6ed7c974..ce028fcb5c 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.dsc
+++ b/OvmfPkg/AmdSev/AmdSevX64.dsc
@@ -370,6 +370,8 @@
 !endif
   PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
 
+!include OvmfPkg/Include/Dsc/MemoryProtectionLibraries.dsc.inc
+
 ################################################################################
 #
 # Pcd Section - list of all EDK II PCD Entries defined by this Platform.
diff --git a/OvmfPkg/Bhyve/BhyveX64.dsc b/OvmfPkg/Bhyve/BhyveX64.dsc
index 7fa40998ae..248b6020ed 100644
--- a/OvmfPkg/Bhyve/BhyveX64.dsc
+++ b/OvmfPkg/Bhyve/BhyveX64.dsc
@@ -411,6 +411,8 @@
 !endif
   PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
 
+!include OvmfPkg/Include/Dsc/MemoryProtectionLibraries.dsc.inc
+
 ################################################################################
 #
 # Pcd Section - list of all EDK II PCD Entries defined by this Platform.
diff --git a/OvmfPkg/CloudHv/CloudHvX64.dsc b/OvmfPkg/CloudHv/CloudHvX64.dsc
index e000deed9e..8828e298ca 100644
--- a/OvmfPkg/CloudHv/CloudHvX64.dsc
+++ b/OvmfPkg/CloudHv/CloudHvX64.dsc
@@ -451,6 +451,8 @@
 !endif
   PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
 
+!include OvmfPkg/Include/Dsc/MemoryProtectionLibraries.dsc.inc
+
 ################################################################################
 #
 # Pcd Section - list of all EDK II PCD Entries defined by this Platform.
diff --git a/OvmfPkg/Include/Dsc/MemoryProtectionLibraries.dsc.inc b/OvmfPkg/Include/Dsc/MemoryProtectionLibraries.dsc.inc
new file mode 100644
index 0000000000..cd8552de0d
--- /dev/null
+++ b/OvmfPkg/Include/Dsc/MemoryProtectionLibraries.dsc.inc
@@ -0,0 +1,15 @@
+##
+#    SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+#
+# Memory Protection Libraries
+#
+[LibraryClasses.common.DXE_DRIVER, LibraryClasses.common.DXE_CORE, LibraryClasses.common.UEFI_APPLICATION, LibraryClasses.common.UEFI_DRIVER]
+  DxeMemoryProtectionHobLib|MdeModulePkg/Library/MemoryProtectionHobLib/DxeMemoryProtectionHobLib.inf
+
+[LibraryClasses.common.SMM_CORE, LibraryClasses.common.DXE_SMM_DRIVER]
+  MmMemoryProtectionHobLib|MdeModulePkg/Library/MemoryProtectionHobLib/SmmMemoryProtectionHobLib.inf
+
+[LibraryClasses.common.MM_CORE_STANDALONE, LibraryClasses.common.MM_STANDALONE]
+  MmMemoryProtectionHobLib|MdeModulePkg/Library/MemoryProtectionHobLib/StandaloneMmMemoryProtectionHobLib.inf
diff --git a/OvmfPkg/IntelTdx/IntelTdxX64.dsc b/OvmfPkg/IntelTdx/IntelTdxX64.dsc
index 193657ff2d..27b9d4bf26 100644
--- a/OvmfPkg/IntelTdx/IntelTdxX64.dsc
+++ b/OvmfPkg/IntelTdx/IntelTdxX64.dsc
@@ -363,6 +363,8 @@
 !endif
   PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
 
+!include OvmfPkg/Include/Dsc/MemoryProtectionLibraries.dsc.inc
+
 ################################################################################
 #
 # Pcd Section - list of all EDK II PCD Entries defined by this Platform.
diff --git a/OvmfPkg/Microvm/MicrovmX64.dsc b/OvmfPkg/Microvm/MicrovmX64.dsc
index 2f75856393..611d64a6a0 100644
--- a/OvmfPkg/Microvm/MicrovmX64.dsc
+++ b/OvmfPkg/Microvm/MicrovmX64.dsc
@@ -452,6 +452,8 @@
   PciPcdProducerLib|OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf
   PciExpressLib|OvmfPkg/Library/BaseCachingPciExpressLib/BaseCachingPciExpressLib.inf
 
+!include OvmfPkg/Include/Dsc/MemoryProtectionLibraries.dsc.inc
+
 ################################################################################
 #
 # Pcd Section - list of all EDK II PCD Entries defined by this Platform.
diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index ed36935770..810d69651c 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -458,6 +458,8 @@
 !endif
   PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
 
+!include OvmfPkg/Include/Dsc/MemoryProtectionLibraries.dsc.inc
+
 ################################################################################
 #
 # Pcd Section - list of all EDK II PCD Entries defined by this Platform.
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index 919315e4cb..13e141a352 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -465,6 +465,8 @@
 !endif
   PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
 
+!include OvmfPkg/Include/Dsc/MemoryProtectionLibraries.dsc.inc
+
 ################################################################################
 #
 # Pcd Section - list of all EDK II PCD Entries defined by this Platform.
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index 823de0d0f9..418c3a0f54 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -484,6 +484,8 @@
 !endif
   PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
 
+!include OvmfPkg/Include/Dsc/MemoryProtectionLibraries.dsc.inc
+
 ################################################################################
 #
 # Pcd Section - list of all EDK II PCD Entries defined by this Platform.
diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc
index 210578c1d7..94d455e2d6 100644
--- a/OvmfPkg/OvmfXen.dsc
+++ b/OvmfPkg/OvmfXen.dsc
@@ -350,6 +350,8 @@
   ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
   PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
 
+!include OvmfPkg/Include/Dsc/MemoryProtectionLibraries.dsc.inc
+
 ################################################################################
 #
 # Pcd Section - list of all EDK II PCD Entries defined by this Platform.
diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c
index f5dc41c3a8..075de3fce6 100644
--- a/OvmfPkg/PlatformPei/Platform.c
+++ b/OvmfPkg/PlatformPei/Platform.c
@@ -38,6 +38,8 @@
 #include <IndustryStandard/QemuCpuHotplug.h>
 #include <Library/MemEncryptSevLib.h>
 #include <OvmfPlatforms.h>
+#include <Guid/DxeMemoryProtectionSettings.h>
+#include <Guid/MmMemoryProtectionSettings.h>
 
 #include "Platform.h"
 
@@ -304,8 +306,29 @@ InitializePlatform (
   IN CONST EFI_PEI_SERVICES     **PeiServices
   )
 {
-  EFI_HOB_PLATFORM_INFO  *PlatformInfoHob;
-  EFI_STATUS             Status;
+  EFI_HOB_PLATFORM_INFO           *PlatformInfoHob;
+  EFI_STATUS                      Status;
+  DXE_MEMORY_PROTECTION_SETTINGS  DxeSettings;
+  MM_MEMORY_PROTECTION_SETTINGS   MmSettings;
+
+  DxeSettings = (DXE_MEMORY_PROTECTION_SETTINGS)DXE_MEMORY_PROTECTION_SETTINGS_DEBUG;
+  MmSettings  = (MM_MEMORY_PROTECTION_SETTINGS)MM_MEMORY_PROTECTION_SETTINGS_DEBUG;
+
+  DxeSettings.NullPointerDetection.DisableEndOfDxe = TRUE;
+  MmSettings.HeapGuard.PageGuardEnabled            = FALSE;
+  MmSettings.HeapGuard.PoolGuardEnabled            = FALSE;
+
+  BuildGuidDataHob (
+    &gDxeMemoryProtectionSettingsGuid,
+    &DxeSettings,
+    sizeof (DxeSettings)
+    );
+
+  BuildGuidDataHob (
+    &gMmMemoryProtectionSettingsGuid,
+    &MmSettings,
+    sizeof (MmSettings)
+    );
 
   DEBUG ((DEBUG_INFO, "Platform PEIM Loaded\n"));
   PlatformInfoHob = BuildPlatformInfoHob ();
diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf
index 3934aeed95..9e30d616eb 100644
--- a/OvmfPkg/PlatformPei/PlatformPei.inf
+++ b/OvmfPkg/PlatformPei/PlatformPei.inf
@@ -45,6 +45,8 @@
   gEfiMemoryTypeInformationGuid
   gFdtHobGuid
   gUefiOvmfPkgPlatformInfoGuid
+  gDxeMemoryProtectionSettingsGuid
+  gMmMemoryProtectionSettingsGuid
 
 [LibraryClasses]
   BaseLib
diff --git a/OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc b/OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc
index 34b2037824..09bb83dc0f 100644
--- a/OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc
+++ b/OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc
@@ -126,6 +126,7 @@
   PciExpressLib|OvmfPkg/Library/BaseCachingPciExpressLib/BaseCachingPciExpressLib.inf
 
 #!include NetworkPkg/NetworkBuildOptions.dsc.inc
+!include OvmfPkg/Include/Dsc/MemoryProtectionLibraries.dsc.inc
 
 ################################################################################
 #
-- 
2.41.0.windows.2


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 05/14] ArmVirtPkg: Create memory protection settings HOB
  2023-07-11 23:52 [PATCH 00/14] Implement Dynamic Memory Protections Taylor Beebe
                   ` (3 preceding siblings ...)
  2023-07-11 23:52 ` [PATCH 04/14] OvmfPkg: Create the memory protection settings HOB Taylor Beebe
@ 2023-07-11 23:52 ` Taylor Beebe
  2023-07-11 23:52 ` [PATCH 06/14] ArmPkg: Update to use memory protection HOB Taylor Beebe
                   ` (11 subsequent siblings)
  16 siblings, 0 replies; 24+ messages in thread
From: Taylor Beebe @ 2023-07-11 23:52 UTC (permalink / raw)
  To: devel; +Cc: Ard Biesheuvel, Leif Lindholm, Sami Mujawar, Gerd Hoffmann

From: Taylor Beebe <tabeebe@microsoft.com>

Create the memory protection settings HOBs on Arm virtual platforms.
These platforms will use the DEBUG memory protection profile.

Signed-off-by: Taylor Beebe <t@taylorbeebe.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Sami Mujawar <sami.mujawar@arm.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
---
 ArmVirtPkg/ArmVirt.dsc.inc                  |  9 ++++++++
 ArmVirtPkg/MemoryInitPei/MemoryInitPeim.c   | 25 +++++++++++++++++++--
 ArmVirtPkg/MemoryInitPei/MemoryInitPeim.inf |  2 ++
 3 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc
index 2443e8351c..3174b19e51 100644
--- a/ArmVirtPkg/ArmVirt.dsc.inc
+++ b/ArmVirtPkg/ArmVirt.dsc.inc
@@ -256,6 +256,15 @@
 [LibraryClasses.ARM]
   ArmSoftFloatLib|ArmPkg/Library/ArmSoftFloatLib/ArmSoftFloatLib.inf
 
+[LibraryClasses.common.DXE_DRIVER, LibraryClasses.common.DXE_CORE, LibraryClasses.common.UEFI_APPLICATION, LibraryClasses.common.UEFI_DRIVER]
+  DxeMemoryProtectionHobLib|MdeModulePkg/Library/MemoryProtectionHobLib/DxeMemoryProtectionHobLib.inf
+
+[LibraryClasses.common.SMM_CORE, LibraryClasses.common.DXE_SMM_DRIVER]
+  MmMemoryProtectionHobLib|MdeModulePkg/Library/MemoryProtectionHobLib/SmmMemoryProtectionHobLib.inf
+
+[LibraryClasses.common.MM_CORE_STANDALONE, LibraryClasses.common.MM_STANDALONE]
+  MmMemoryProtectionHobLib|MdeModulePkg/Library/MemoryProtectionHobLib/StandaloneMmMemoryProtectionHobLib.inf
+
 [BuildOptions]
   GCC:RELEASE_*_*_CC_FLAGS  = -DMDEPKG_NDEBUG
 
diff --git a/ArmVirtPkg/MemoryInitPei/MemoryInitPeim.c b/ArmVirtPkg/MemoryInitPei/MemoryInitPeim.c
index ef88a9df1d..2033df1a01 100644
--- a/ArmVirtPkg/MemoryInitPei/MemoryInitPeim.c
+++ b/ArmVirtPkg/MemoryInitPei/MemoryInitPeim.c
@@ -14,7 +14,9 @@
 #include <Library/PeimEntryPoint.h>
 #include <Library/PeiServicesLib.h>
 #include <Library/PcdLib.h>
+#include <Guid/DxeMemoryProtectionSettings.h>
 #include <Guid/MemoryTypeInformation.h>
+#include <Guid/MmMemoryProtectionSettings.h>
 
 EFI_STATUS
 EFIAPI
@@ -76,8 +78,10 @@ InitializeMemory (
   IN CONST EFI_PEI_SERVICES     **PeiServices
   )
 {
-  UINTN       UefiMemoryBase;
-  EFI_STATUS  Status;
+  UINTN                           UefiMemoryBase;
+  EFI_STATUS                      Status;
+  DXE_MEMORY_PROTECTION_SETTINGS  DxeSettings;
+  MM_MEMORY_PROTECTION_SETTINGS   MmSettings;
 
   ASSERT (FixedPcdGet64 (PcdSystemMemoryBase) < (UINT64)MAX_ALLOC_ADDRESS);
 
@@ -100,5 +104,22 @@ InitializeMemory (
              );
   ASSERT_EFI_ERROR (Status);
 
+  DxeSettings = (DXE_MEMORY_PROTECTION_SETTINGS)DXE_MEMORY_PROTECTION_SETTINGS_DEBUG;
+  MmSettings  = (MM_MEMORY_PROTECTION_SETTINGS)MM_MEMORY_PROTECTION_SETTINGS_DEBUG;
+
+  DxeSettings.NullPointerDetection.DisableEndOfDxe = TRUE;
+
+  BuildGuidDataHob (
+    &gDxeMemoryProtectionSettingsGuid,
+    &DxeSettings,
+    sizeof (DxeSettings)
+    );
+
+  BuildGuidDataHob (
+    &gMmMemoryProtectionSettingsGuid,
+    &MmSettings,
+    sizeof (MmSettings)
+    );
+
   return Status;
 }
diff --git a/ArmVirtPkg/MemoryInitPei/MemoryInitPeim.inf b/ArmVirtPkg/MemoryInitPei/MemoryInitPeim.inf
index 2039f71a0e..044542ecb2 100644
--- a/ArmVirtPkg/MemoryInitPei/MemoryInitPeim.inf
+++ b/ArmVirtPkg/MemoryInitPei/MemoryInitPeim.inf
@@ -37,6 +37,8 @@
 
 [Guids]
   gEfiMemoryTypeInformationGuid
+  gDxeMemoryProtectionSettingsGuid
+  gMmMemoryProtectionSettingsGuid
 
 [FeaturePcd]
   gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob
-- 
2.41.0.windows.2


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 06/14] ArmPkg: Update to use memory protection HOB
  2023-07-11 23:52 [PATCH 00/14] Implement Dynamic Memory Protections Taylor Beebe
                   ` (4 preceding siblings ...)
  2023-07-11 23:52 ` [PATCH 05/14] ArmVirtPkg: Create " Taylor Beebe
@ 2023-07-11 23:52 ` Taylor Beebe
  2023-07-11 23:52 ` [PATCH 07/14] EmulatorPkg: " Taylor Beebe
                   ` (10 subsequent siblings)
  16 siblings, 0 replies; 24+ messages in thread
From: Taylor Beebe @ 2023-07-11 23:52 UTC (permalink / raw)
  To: devel; +Cc: Leif Lindholm, Ard Biesheuvel, Sami Mujawar

From: Taylor Beebe <tabeebe@microsoft.com>

Replace references to the memory protection PCDs to instead
reference the memory protection HOB.

Signed-off-by: Taylor Beebe <t@taylorbeebe.com>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Sami Mujawar <sami.mujawar@arm.com>
---
 ArmPkg/ArmPkg.dsc                | 1 +
 ArmPkg/Drivers/CpuDxe/CpuDxe.c   | 5 ++---
 ArmPkg/Drivers/CpuDxe/CpuDxe.inf | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/ArmPkg/ArmPkg.dsc b/ArmPkg/ArmPkg.dsc
index 4939b3d59b..3d3605921f 100644
--- a/ArmPkg/ArmPkg.dsc
+++ b/ArmPkg/ArmPkg.dsc
@@ -57,6 +57,7 @@
   PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
   PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
   PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
+  DxeMemoryProtectionHobLib|MdeModulePkg/Library/MemoryProtectionHobLibNull/DxeMemoryProtectionHobLibNull.inf
 
   UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
   HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
diff --git a/ArmPkg/Drivers/CpuDxe/CpuDxe.c b/ArmPkg/Drivers/CpuDxe/CpuDxe.c
index fc63e52784..6518a7130a 100644
--- a/ArmPkg/Drivers/CpuDxe/CpuDxe.c
+++ b/ArmPkg/Drivers/CpuDxe/CpuDxe.c
@@ -12,6 +12,7 @@
 #include <Guid/IdleLoopEvent.h>
 
 #include <Library/MemoryAllocationLib.h>
+#include <Library/DxeMemoryProtectionHobLib.h>
 
 BOOLEAN  mIsFlushingGCD;
 
@@ -241,7 +242,6 @@ RemapUnusedMemoryNx (
   VOID
   )
 {
-  UINT64                 TestBit;
   UINTN                  MemoryMapSize;
   UINTN                  MapKey;
   UINTN                  DescriptorSize;
@@ -251,8 +251,7 @@ RemapUnusedMemoryNx (
   EFI_MEMORY_DESCRIPTOR  *MemoryMapEnd;
   EFI_STATUS             Status;
 
-  TestBit = LShiftU64 (1, EfiBootServicesData);
-  if ((PcdGet64 (PcdDxeNxMemoryProtectionPolicy) & TestBit) == 0) {
+  if (!gDxeMps.ExecutionProtection.EnabledForType[EfiBootServicesData]) {
     return;
   }
 
diff --git a/ArmPkg/Drivers/CpuDxe/CpuDxe.inf b/ArmPkg/Drivers/CpuDxe/CpuDxe.inf
index 7d8132200e..a0f94bc567 100644
--- a/ArmPkg/Drivers/CpuDxe/CpuDxe.inf
+++ b/ArmPkg/Drivers/CpuDxe/CpuDxe.inf
@@ -46,6 +46,7 @@
   CpuExceptionHandlerLib
   DebugLib
   DefaultExceptionHandlerLib
+  DxeMemoryProtectionHobLib
   DxeServicesTableLib
   HobLib
   MemoryAllocationLib
@@ -65,7 +66,6 @@
 
 [Pcd.common]
   gArmTokenSpaceGuid.PcdVFPEnabled
-  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy
 
 [FeaturePcd.common]
   gArmTokenSpaceGuid.PcdDebuggerExceptionSupport
-- 
2.41.0.windows.2


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 07/14] EmulatorPkg: Update to use memory protection HOB
  2023-07-11 23:52 [PATCH 00/14] Implement Dynamic Memory Protections Taylor Beebe
                   ` (5 preceding siblings ...)
  2023-07-11 23:52 ` [PATCH 06/14] ArmPkg: Update to use memory protection HOB Taylor Beebe
@ 2023-07-11 23:52 ` Taylor Beebe
  2023-07-11 23:52 ` [PATCH 08/14] MdeModulePkg: " Taylor Beebe
                   ` (9 subsequent siblings)
  16 siblings, 0 replies; 24+ messages in thread
From: Taylor Beebe @ 2023-07-11 23:52 UTC (permalink / raw)
  To: devel; +Cc: Andrew Fish, Ray Ni

From: Taylor Beebe <tabeebe@microsoft.com>

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

Signed-off-by: Taylor Beebe <t@taylorbeebe.com>
Cc: Andrew Fish <afish@apple.com>
Cc: Ray Ni <ray.ni@intel.com>
---
 EmulatorPkg/EmulatorPkg.dsc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/EmulatorPkg/EmulatorPkg.dsc b/EmulatorPkg/EmulatorPkg.dsc
index b44435d7e6..132ba5e294 100644
--- a/EmulatorPkg/EmulatorPkg.dsc
+++ b/EmulatorPkg/EmulatorPkg.dsc
@@ -126,6 +126,7 @@
   SortLib|MdeModulePkg/Library/BaseSortLib/BaseSortLib.inf
   ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
   FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
+  DxeMemoryProtectionHobLib|MdeModulePkg/Library/MemoryProtectionHobLibNull/DxeMemoryProtectionHobLibNull.inf
 
 !if $(SECURE_BOOT_ENABLE) == TRUE
   RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf
@@ -216,7 +217,6 @@
   gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplBuildPageTables|FALSE
 
 [PcdsFixedAtBuild]
-  gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x00000000
   gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
   gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000040
   gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x0f
-- 
2.41.0.windows.2


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 08/14] MdeModulePkg: Update to use memory protection HOB
  2023-07-11 23:52 [PATCH 00/14] Implement Dynamic Memory Protections Taylor Beebe
                   ` (6 preceding siblings ...)
  2023-07-11 23:52 ` [PATCH 07/14] EmulatorPkg: " Taylor Beebe
@ 2023-07-11 23:52 ` Taylor Beebe
  2023-07-11 23:52 ` [PATCH 09/14] OvmfPkg: " Taylor Beebe
                   ` (8 subsequent siblings)
  16 siblings, 0 replies; 24+ messages in thread
From: Taylor Beebe @ 2023-07-11 23:52 UTC (permalink / raw)
  To: devel; +Cc: Jian J Wang, Liming Gao, Dandan Bi

From: Taylor Beebe <tabeebe@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@taylorbeebe.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Dandan Bi <dandan.bi@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


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 09/14] OvmfPkg: Update to use memory protection HOB
  2023-07-11 23:52 [PATCH 00/14] Implement Dynamic Memory Protections Taylor Beebe
                   ` (7 preceding siblings ...)
  2023-07-11 23:52 ` [PATCH 08/14] MdeModulePkg: " Taylor Beebe
@ 2023-07-11 23:52 ` Taylor Beebe
  2023-07-11 23:52 ` [PATCH 10/14] UefiCpuPkg: " Taylor Beebe
                   ` (7 subsequent siblings)
  16 siblings, 0 replies; 24+ messages in thread
From: Taylor Beebe @ 2023-07-11 23:52 UTC (permalink / raw)
  To: devel; +Cc: Ard Biesheuvel, Jiewen Yao, Jordan Justen, Gerd Hoffmann

From: Taylor Beebe <tabeebe@microsoft.com>

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

The stack NX setting will no longer be fetched from the QEMU
configuration file and will instead be determined via the
HOB published in PlatformPei/Platform.c. PeilessStartup
will check the HOB when creating the page tables
at DXE handoff.

Signed-off-by: Taylor Beebe <t@taylorbeebe.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
---
 OvmfPkg/Bhyve/PlatformPei/PlatformPei.inf     |   1 -
 OvmfPkg/Fdt/HighMemDxe/HighMemDxe.c           |   5 +-
 OvmfPkg/Fdt/HighMemDxe/HighMemDxe.inf         |   4 +-
 OvmfPkg/Include/Library/PlatformInitLib.h     |  13 ---
 OvmfPkg/Library/PeilessStartupLib/DxeLoad.c   |  25 ++--
 .../PeilessStartupLib/PeilessStartup.c        |   3 -
 .../PeilessStartupLib/PeilessStartupLib.inf   |   5 +-
 .../PeilessStartupLib/X64/PageTables.h        |  23 +---
 .../PeilessStartupLib/X64/VirtualMemory.c     | 107 ++++++------------
 OvmfPkg/Library/PlatformInitLib/Platform.c    |  15 ---
 OvmfPkg/PlatformPei/IntelTdx.c                |   2 -
 OvmfPkg/PlatformPei/Platform.c                |  16 ---
 OvmfPkg/PlatformPei/PlatformPei.inf           |   1 -
 OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf         |   2 +-
 OvmfPkg/QemuVideoDxe/VbeShim.c                |   5 +-
 OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc           |  13 ---
 OvmfPkg/TdxDxe/TdxDxe.c                       |   7 +-
 OvmfPkg/TdxDxe/TdxDxe.inf                     |   1 -
 18 files changed, 68 insertions(+), 180 deletions(-)

diff --git a/OvmfPkg/Bhyve/PlatformPei/PlatformPei.inf b/OvmfPkg/Bhyve/PlatformPei/PlatformPei.inf
index 739d63098b..27b4a595fe 100644
--- a/OvmfPkg/Bhyve/PlatformPei/PlatformPei.inf
+++ b/OvmfPkg/Bhyve/PlatformPei/PlatformPei.inf
@@ -88,7 +88,6 @@
   gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved
   gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode
   gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable
-  gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack
   gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable
   gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask
   gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy
diff --git a/OvmfPkg/Fdt/HighMemDxe/HighMemDxe.c b/OvmfPkg/Fdt/HighMemDxe/HighMemDxe.c
index 779bf5c827..93bce776a9 100644
--- a/OvmfPkg/Fdt/HighMemDxe/HighMemDxe.c
+++ b/OvmfPkg/Fdt/HighMemDxe/HighMemDxe.c
@@ -13,6 +13,7 @@
 #include <Library/DxeServicesTableLib.h>
 #include <Library/PcdLib.h>
 #include <Library/UefiBootServicesTableLib.h>
+#include <Library/DxeMemoryProtectionHobLib.h>
 
 #include <Protocol/Cpu.h>
 #include <Protocol/FdtClient.h>
@@ -148,9 +149,7 @@ InitializeHighMemDxe (
         // on the page table mappings by going through the cpu arch protocol.
         //
         Attributes = EFI_MEMORY_WB;
-        if ((PcdGet64 (PcdDxeNxMemoryProtectionPolicy) &
-             (1U << (UINT32)EfiConventionalMemory)) != 0)
-        {
+        if (gDxeMps.ExecutionProtection.EnabledForType[EfiConventionalMemory]) {
           Attributes |= EFI_MEMORY_XP;
         }
 
diff --git a/OvmfPkg/Fdt/HighMemDxe/HighMemDxe.inf b/OvmfPkg/Fdt/HighMemDxe/HighMemDxe.inf
index c7dde9f455..2d3add492b 100644
--- a/OvmfPkg/Fdt/HighMemDxe/HighMemDxe.inf
+++ b/OvmfPkg/Fdt/HighMemDxe/HighMemDxe.inf
@@ -33,13 +33,11 @@
   PcdLib
   UefiBootServicesTableLib
   UefiDriverEntryPoint
+  DxeMemoryProtectionHobLib
 
 [Protocols]
   gEfiCpuArchProtocolGuid                 ## CONSUMES
   gFdtClientProtocolGuid                  ## CONSUMES
 
-[Pcd]
-  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy
-
 [Depex]
   gEfiCpuArchProtocolGuid AND gFdtClientProtocolGuid
diff --git a/OvmfPkg/Include/Library/PlatformInitLib.h b/OvmfPkg/Include/Library/PlatformInitLib.h
index 57b18b94d9..b2468f2063 100644
--- a/OvmfPkg/Include/Library/PlatformInitLib.h
+++ b/OvmfPkg/Include/Library/PlatformInitLib.h
@@ -32,7 +32,6 @@ typedef struct {
   UINT32               Uc32Base;
   UINT32               Uc32Size;
 
-  BOOLEAN              PcdSetNxForStack;
   UINT64               PcdTdxSharedBitMask;
 
   UINT64               PcdPciMmio64Base;
@@ -182,18 +181,6 @@ PlatformMemMapInitialization (
   IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
   );
 
-/**
- * Fetch "opt/ovmf/PcdSetNxForStack" from QEMU
- *
- * @param Setting     The pointer to the setting of "/opt/ovmf/PcdSetNxForStack".
- * @return EFI_SUCCESS  Successfully fetch the settings.
- */
-EFI_STATUS
-EFIAPI
-PlatformNoexecDxeInitialization (
-  IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
-  );
-
 VOID
 EFIAPI
 PlatformMiscInitialization (
diff --git a/OvmfPkg/Library/PeilessStartupLib/DxeLoad.c b/OvmfPkg/Library/PeilessStartupLib/DxeLoad.c
index d34690eb8a..169b4931a6 100644
--- a/OvmfPkg/Library/PeilessStartupLib/DxeLoad.c
+++ b/OvmfPkg/Library/PeilessStartupLib/DxeLoad.c
@@ -11,18 +11,21 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include <Library/DebugLib.h>
 #include <Library/BaseLib.h>
 #include <Library/BaseMemoryLib.h>
+#include <Library/HobLib.h>
 #include <Library/MemoryAllocationLib.h>
 #include <Library/PcdLib.h>
 #include <Guid/MemoryTypeInformation.h>
 #include <Guid/MemoryAllocationHob.h>
 #include <Guid/PcdDataBaseSignatureGuid.h>
+#include <Guid/DxeMemoryProtectionSettings.h>
 #include <Register/Intel/Cpuid.h>
 #include <Library/PrePiLib.h>
 #include "X64/PageTables.h"
 #include <Library/ReportStatusCodeLib.h>
 
 #define STACK_SIZE  0x20000
-extern EFI_GUID  gEfiNonCcFvGuid;
+extern EFI_GUID                 gEfiNonCcFvGuid;
+DXE_MEMORY_PROTECTION_SETTINGS  mDxeMps;
 
 /**
    Transfers control to DxeCore.
@@ -41,13 +44,21 @@ HandOffToDxeCore (
   VOID   *BaseOfStack;
   VOID   *TopOfStack;
   UINTN  PageTables;
+  VOID   *Ptr;
 
-  //
-  // Clear page 0 and mark it as allocated if NULL pointer detection is enabled.
-  //
-  if (IsNullDetectionEnabled ()) {
-    ClearFirst4KPage (GetHobList ());
-    BuildMemoryAllocationHob (0, EFI_PAGES_TO_SIZE (1), EfiBootServicesData);
+  Ptr = GetFirstGuidHob (&gDxeMemoryProtectionSettingsGuid);
+
+  if ((Ptr != NULL) && DXE_MPS_IS_STRUCT_VALID (GET_GUID_HOB_DATA (Ptr))) {
+    CopyMem (&mDxeMps, GET_GUID_HOB_DATA (Ptr), sizeof (DXE_MEMORY_PROTECTION_SETTINGS));
+  } else {
+    ZeroMem (&mDxeMps, sizeof (DXE_MEMORY_PROTECTION_SETTINGS));
+  }
+
+  if (mDxeMps.NullPointerDetection.Enabled) {
+    ASSERT (CanAllocateNullPage (GetHobList ()));
+    // 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);
   }
 
   //
diff --git a/OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c b/OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c
index 164aa2d619..581413cd47 100644
--- a/OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c
+++ b/OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c
@@ -104,12 +104,9 @@ InitializePlatform (
 
   PlatformMemMapInitialization (PlatformInfoHob);
 
-  PlatformNoexecDxeInitialization (PlatformInfoHob);
-
   if (TdIsEnabled ()) {
     PlatformInfoHob->PcdConfidentialComputingGuestAttr = CCAttrIntelTdx;
     PlatformInfoHob->PcdTdxSharedBitMask               = TdSharedPageMask ();
-    PlatformInfoHob->PcdSetNxForStack                  = TRUE;
   }
 
   PlatformMiscInitialization (PlatformInfoHob);
diff --git a/OvmfPkg/Library/PeilessStartupLib/PeilessStartupLib.inf b/OvmfPkg/Library/PeilessStartupLib/PeilessStartupLib.inf
index 7719b5031d..1e0879bb50 100644
--- a/OvmfPkg/Library/PeilessStartupLib/PeilessStartupLib.inf
+++ b/OvmfPkg/Library/PeilessStartupLib/PeilessStartupLib.inf
@@ -65,6 +65,7 @@
   gPcdDataBaseHobGuid
   gCcEventEntryHobGuid
   gEfiNonCcFvGuid
+  gDxeMemoryProtectionSettingsGuid
 
 [Pcd]
   gUefiOvmfPkgTokenSpaceGuid.PcdBfvBase
@@ -75,11 +76,7 @@
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase
   gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplBuildPageTables       ## CONSUMES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard               ## CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable              ## SOMETIMES_CONSUMES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy ## SOMETIMES_CONSUMES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy       ## SOMETIMES_CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask    ## CONSUMES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask    ## CONSUMES
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize
diff --git a/OvmfPkg/Library/PeilessStartupLib/X64/PageTables.h b/OvmfPkg/Library/PeilessStartupLib/X64/PageTables.h
index a0d0d3547b..ab2ff8b38b 100644
--- a/OvmfPkg/Library/PeilessStartupLib/X64/PageTables.h
+++ b/OvmfPkg/Library/PeilessStartupLib/X64/PageTables.h
@@ -179,28 +179,17 @@ CreateIdentityMappingPageTables (
   );
 
 /**
-  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
   );
 
 #endif
diff --git a/OvmfPkg/Library/PeilessStartupLib/X64/VirtualMemory.c b/OvmfPkg/Library/PeilessStartupLib/X64/VirtualMemory.c
index e2c1bac5e0..25187e730c 100644
--- a/OvmfPkg/Library/PeilessStartupLib/X64/VirtualMemory.c
+++ b/OvmfPkg/Library/PeilessStartupLib/X64/VirtualMemory.c
@@ -17,6 +17,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include <Library/PcdLib.h>
 #include <Guid/MemoryTypeInformation.h>
 #include <Guid/MemoryAllocationHob.h>
+#include <Guid/DxeMemoryProtectionSettings.h>
 #include <Register/Intel/Cpuid.h>
 #include <Library/PlatformInitLib.h>
 #include "PageTables.h"
@@ -45,49 +46,37 @@ UINT64  mLevelSize[5] = {
   SIZE_512GB
 };
 
-BOOLEAN
-IsSetNxForStack (
-  VOID
-  )
-{
-  EFI_HOB_GUID_TYPE      *GuidHob;
-  EFI_HOB_PLATFORM_INFO  *PlatformInfo;
-
-  GuidHob = GetFirstGuidHob (&gUefiOvmfPkgPlatformInfoGuid);
-  if (GuidHob == NULL) {
-    ASSERT (FALSE);
-    return FALSE;
-  }
-
-  PlatformInfo = (EFI_HOB_PLATFORM_INFO *)GET_GUID_HOB_DATA (GuidHob);
-
-  return PlatformInfo->PcdSetNxForStack;
-}
+extern DXE_MEMORY_PROTECTION_SETTINGS  mDxeMps;
 
 /**
-  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,
@@ -95,9 +84,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.
       //
@@ -106,10 +95,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;
         }
 
@@ -122,27 +111,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;
 }
 
 /**
@@ -188,17 +157,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 (IsSetNxForStack () ||
-          FixedPcdGet64 (PcdDxeNxMemoryProtectionPolicy) != 0 ||
-          PcdGet32 (PcdImageProtectionPolicy) != 0);
+  return IsExecuteDisableBitAvailable ();
 }
 
 /**
@@ -237,17 +196,17 @@ ToSplitPageTable (
   IN UINTN                 StackSize
   )
 {
-  if (IsNullDetectionEnabled () && (Address == 0)) {
+  if (mDxeMps.NullPointerDetection.Enabled && (Address == (UINTN)NULL)) {
     return TRUE;
   }
 
-  if (FixedPcdGetBool (PcdCpuStackGuard)) {
+  if (mDxeMps.CpuStackGuardEnabled) {
     if ((StackBase >= Address) && (StackBase < (Address + Size))) {
       return TRUE;
     }
   }
 
-  if (IsSetNxForStack ()) {
+  if (mDxeMps.StackExecutionProtectionEnabled) {
     if ((Address < StackBase + StackSize) && ((Address + Size) > StackBase)) {
       return TRUE;
     }
@@ -426,17 +385,17 @@ Split2MPageTo4K (
     PageTableEntry->Uint64         = (UINT64)PhysicalAddress4K;
     PageTableEntry->Bits.ReadWrite = 1;
 
-    if ((IsNullDetectionEnabled () && (PhysicalAddress4K == 0)) ||
-        (FixedPcdGetBool (PcdCpuStackGuard) && (PhysicalAddress4K == StackBase)))
+    if ((mDxeMps.NullPointerDetection.Enabled && (PhysicalAddress4K == (UINTN)NULL)) ||
+        (mDxeMps.CpuStackGuardEnabled && (PhysicalAddress4K == StackBase)))
     {
       PageTableEntry->Bits.Present = 0;
     } else {
       PageTableEntry->Bits.Present = 1;
     }
 
-    if (  IsSetNxForStack ()
-       && (PhysicalAddress4K >= StackBase)
-       && (PhysicalAddress4K < StackBase + StackSize))
+    if (mDxeMps.StackExecutionProtectionEnabled &&
+        (PhysicalAddress4K >= StackBase) &&
+        (PhysicalAddress4K < StackBase + StackSize))
     {
       //
       // Set Nx bit for stack.
diff --git a/OvmfPkg/Library/PlatformInitLib/Platform.c b/OvmfPkg/Library/PlatformInitLib/Platform.c
index f48bf16ae3..bc9becc401 100644
--- a/OvmfPkg/Library/PlatformInitLib/Platform.c
+++ b/OvmfPkg/Library/PlatformInitLib/Platform.c
@@ -249,21 +249,6 @@ PlatformMemMapInitialization (
   PlatformInfoHob->PcdPciIoSize = PciIoSize;
 }
 
-/**
- * Fetch "opt/ovmf/PcdSetNxForStack" from QEMU
- *
- * @param Setting     The pointer to the setting of "/opt/ovmf/PcdSetNxForStack".
- * @return EFI_SUCCESS  Successfully fetch the settings.
- */
-EFI_STATUS
-EFIAPI
-PlatformNoexecDxeInitialization (
-  IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
-  )
-{
-  return QemuFwCfgParseBool ("opt/ovmf/PcdSetNxForStack", &PlatformInfoHob->PcdSetNxForStack);
-}
-
 VOID
 PciExBarInitialization (
   VOID
diff --git a/OvmfPkg/PlatformPei/IntelTdx.c b/OvmfPkg/PlatformPei/IntelTdx.c
index 3d625cabd8..1cb6729e56 100644
--- a/OvmfPkg/PlatformPei/IntelTdx.c
+++ b/OvmfPkg/PlatformPei/IntelTdx.c
@@ -48,7 +48,5 @@ IntelTdxInitialize (
   PcdStatus = PcdSet64S (PcdTdxSharedBitMask, TdSharedPageMask ());
   ASSERT_RETURN_ERROR (PcdStatus);
 
-  PcdStatus = PcdSetBoolS (PcdSetNxForStack, TRUE);
-  ASSERT_RETURN_ERROR (PcdStatus);
  #endif
 }
diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c
index 075de3fce6..2ed76f81a4 100644
--- a/OvmfPkg/PlatformPei/Platform.c
+++ b/OvmfPkg/PlatformPei/Platform.c
@@ -75,21 +75,6 @@ MemMapInitialization (
   ASSERT_RETURN_ERROR (PcdStatus);
 }
 
-STATIC
-VOID
-NoexecDxeInitialization (
-  IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
-  )
-{
-  RETURN_STATUS  Status;
-
-  Status = PlatformNoexecDxeInitialization (PlatformInfoHob);
-  if (!RETURN_ERROR (Status)) {
-    Status = PcdSetBoolS (PcdSetNxForStack, PlatformInfoHob->PcdSetNxForStack);
-    ASSERT_RETURN_ERROR (Status);
-  }
-}
-
 static const UINT8  EmptyFdt[] = {
   0xd0, 0x0d, 0xfe, 0xed, 0x00, 0x00, 0x00, 0x48,
   0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x48,
@@ -377,7 +362,6 @@ InitializePlatform (
     PeiFvInitialization (PlatformInfoHob);
     MemTypeInfoInitialization (PlatformInfoHob);
     MemMapInitialization (PlatformInfoHob);
-    NoexecDxeInitialization (PlatformInfoHob);
   }
 
   InstallClearCacheCallback ();
diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf
index 9e30d616eb..d06ac422ac 100644
--- a/OvmfPkg/PlatformPei/PlatformPei.inf
+++ b/OvmfPkg/PlatformPei/PlatformPei.inf
@@ -104,7 +104,6 @@
   gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved
   gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode
   gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable
-  gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack
   gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable
   gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask
   gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase
diff --git a/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf b/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf
index 43a6e07faa..cb451b6211 100644
--- a/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf
+++ b/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf
@@ -55,6 +55,7 @@
   UefiBootServicesTableLib
   UefiDriverEntryPoint
   UefiLib
+  DxeMemoryProtectionHobLib
 
 [Protocols]
   gEfiGraphicsOutputProtocolGuid                # PROTOCOL BY_START
@@ -64,6 +65,5 @@
 [Pcd]
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId
   gUefiOvmfPkgTokenSpaceGuid.PcdVideoResolutionSource
-  gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask
   gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution
   gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution
diff --git a/OvmfPkg/QemuVideoDxe/VbeShim.c b/OvmfPkg/QemuVideoDxe/VbeShim.c
index 8f151b96f9..aa042b2e97 100644
--- a/OvmfPkg/QemuVideoDxe/VbeShim.c
+++ b/OvmfPkg/QemuVideoDxe/VbeShim.c
@@ -19,6 +19,7 @@
 #include <Library/DebugLib.h>
 #include <Library/PciLib.h>
 #include <Library/PrintLib.h>
+#include <Library/DxeMemoryProtectionHobLib.h>
 #include <OvmfPlatforms.h>
 
 #include "Qemu.h"
@@ -69,7 +70,9 @@ InstallVbeShim (
   UINTN                 Printed;
   VBE_MODE_INFO         *VbeModeInfo;
 
-  if ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & (BIT0|BIT7)) == BIT0) {
+  if (gDxeMps.NullPointerDetection.Enabled &&
+      !gDxeMps.NullPointerDetection.DisableEndOfDxe)
+  {
     DEBUG ((
       DEBUG_WARN,
       "%a: page 0 protected, not installing VBE shim\n",
diff --git a/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc b/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc
index 731f54f73f..edb4782e2f 100644
--- a/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc
+++ b/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc
@@ -270,19 +270,6 @@
   gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode|20
   gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData|0
 
-  #
-  # Enable strict image permissions for all images. (This applies
-  # only to images that were built with >= 4 KB section alignment.)
-  #
-  gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x3
-
-  #
-  # Enable NX memory protection for all non-code regions, including OEM and OS
-  # reserved ones, with the exception of LoaderData regions, of which OS loaders
-  # (i.e., GRUB) may assume that its contents are executable.
-  #
-  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xC000000000007FD5
-
 [Components.common]
   #
   # Ramdisk support
diff --git a/OvmfPkg/TdxDxe/TdxDxe.c b/OvmfPkg/TdxDxe/TdxDxe.c
index 30732f421b..5e497ba662 100644
--- a/OvmfPkg/TdxDxe/TdxDxe.c
+++ b/OvmfPkg/TdxDxe/TdxDxe.c
@@ -131,15 +131,12 @@ SetPcdSettings (
 
   PcdStatus = PcdSet64S (PcdConfidentialComputingGuestAttr, PlatformInfoHob->PcdConfidentialComputingGuestAttr);
   ASSERT_RETURN_ERROR (PcdStatus);
-  PcdStatus = PcdSetBoolS (PcdSetNxForStack, PlatformInfoHob->PcdSetNxForStack);
-  ASSERT_RETURN_ERROR (PcdStatus);
 
   DEBUG ((
     DEBUG_INFO,
-    "HostBridgeDevId=0x%x, CCAttr=0x%x, SetNxForStack=%x\n",
+    "HostBridgeDevId=0x%x, CCAttr=0x%x\n",
     PlatformInfoHob->HostBridgeDevId,
-    PlatformInfoHob->PcdConfidentialComputingGuestAttr,
-    PlatformInfoHob->PcdSetNxForStack
+    PlatformInfoHob->PcdConfidentialComputingGuestAttr
     ));
 
   PcdStatus = PcdSet32S (PcdCpuBootLogicalProcessorNumber, PlatformInfoHob->PcdCpuBootLogicalProcessorNumber);
diff --git a/OvmfPkg/TdxDxe/TdxDxe.inf b/OvmfPkg/TdxDxe/TdxDxe.inf
index 9793562884..42317228c1 100644
--- a/OvmfPkg/TdxDxe/TdxDxe.inf
+++ b/OvmfPkg/TdxDxe/TdxDxe.inf
@@ -68,6 +68,5 @@
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress
   gEfiMdePkgTokenSpaceGuid.PcdConfidentialComputingGuestAttr
   gEfiMdeModulePkgTokenSpaceGuid.PcdTdxSharedBitMask
-  gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack
   gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved
   gUefiOvmfPkgTokenSpaceGuid.PcdTdxAcceptPageSize
-- 
2.41.0.windows.2


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 10/14] UefiCpuPkg: Update to use memory protection HOB
  2023-07-11 23:52 [PATCH 00/14] Implement Dynamic Memory Protections Taylor Beebe
                   ` (8 preceding siblings ...)
  2023-07-11 23:52 ` [PATCH 09/14] OvmfPkg: " Taylor Beebe
@ 2023-07-11 23:52 ` Taylor Beebe
  2023-07-11 23:52 ` [PATCH 11/14] UefiPayloadPkg: " Taylor Beebe
                   ` (6 subsequent siblings)
  16 siblings, 0 replies; 24+ messages in thread
From: Taylor Beebe @ 2023-07-11 23:52 UTC (permalink / raw)
  To: devel; +Cc: Eric Dong, Ray Ni, Rahul Kumar, Gerd Hoffmann

From: Taylor Beebe <tabeebe@microsoft.com>

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

Stack guard will always be initialized after memory discovery
in PEI, but the memory protection HOB will be checked when
applying stack guard in DxeIpl when the page tables are
rebuilt.

Signed-off-by: Taylor Beebe <t@taylorbeebe.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com> 
Cc: Gerd Hoffmann <kraxel@redhat.com>
---
 UefiCpuPkg/CpuDxe/CpuDxe.c                    |  2 +-
 UefiCpuPkg/CpuDxe/CpuDxe.h                    | 11 +++++---
 UefiCpuPkg/CpuDxe/CpuDxe.inf                  |  4 +--
 UefiCpuPkg/CpuDxe/CpuMp.c                     |  2 +-
 UefiCpuPkg/CpuDxeRiscV64/CpuDxeRiscV64.inf    |  3 ---
 UefiCpuPkg/CpuMpPei/CpuMpPei.c                |  8 +++---
 UefiCpuPkg/CpuMpPei/CpuMpPei.h                |  3 ++-
 UefiCpuPkg/CpuMpPei/CpuMpPei.inf              |  1 -
 UefiCpuPkg/CpuMpPei/CpuPaging.c               | 14 +++++-----
 .../DxeCpuExceptionHandlerLib.inf             |  1 -
 .../PeiCpuExceptionHandlerLib.inf             |  1 -
 .../SecPeiCpuExceptionHandlerLib.inf          |  1 -
 .../SmmCpuExceptionHandlerLib.inf             |  1 -
 .../UnitTest/CpuExceptionHandlerTest.h        |  3 ++-
 .../UnitTest/CpuExceptionHandlerTestCommon.c  | 27 +++++++++++++++----
 .../DxeCpuExceptionHandlerLibUnitTest.inf     |  2 +-
 .../PeiCpuExceptionHandlerLibUnitTest.inf     |  4 ++-
 UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf |  3 ++-
 UefiCpuPkg/Library/MpInitLib/DxeMpLib.c       |  3 ++-
 UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c      |  2 +-
 UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf  |  3 +--
 .../PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c   | 13 ++++-----
 UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c        |  2 +-
 .../PiSmmCpuDxeSmm/SmmProfileInternal.h       | 10 ++++---
 UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c       |  2 +-
 UefiCpuPkg/UefiCpuPkg.dec                     |  7 +++--
 UefiCpuPkg/UefiCpuPkg.dsc                     |  2 ++
 UefiCpuPkg/UefiCpuPkg.uni                     | 10 +++----
 28 files changed, 80 insertions(+), 65 deletions(-)

diff --git a/UefiCpuPkg/CpuDxe/CpuDxe.c b/UefiCpuPkg/CpuDxe/CpuDxe.c
index 804ef5d1fe..b12c43f4c1 100644
--- a/UefiCpuPkg/CpuDxe/CpuDxe.c
+++ b/UefiCpuPkg/CpuDxe/CpuDxe.c
@@ -399,7 +399,7 @@ CpuSetMemoryAttributes (
   // During memory attributes updating, new pages may be allocated to setup
   // smaller granularity of page table. Page allocation action might then cause
   // another calling of CpuSetMemoryAttributes() recursively, due to memory
-  // protection policy configured (such as PcdDxeNxMemoryProtectionPolicy).
+  // protection policy configured (such as the DXE NX Protection Policy).
   // Since this driver will always protect memory used as page table by itself,
   // there's no need to apply protection policy requested from memory service.
   // So it's safe to just return EFI_SUCCESS if this time of calling is caused
diff --git a/UefiCpuPkg/CpuDxe/CpuDxe.h b/UefiCpuPkg/CpuDxe/CpuDxe.h
index 0e7d88dd35..10eabd9b66 100644
--- a/UefiCpuPkg/CpuDxe/CpuDxe.h
+++ b/UefiCpuPkg/CpuDxe/CpuDxe.h
@@ -35,15 +35,18 @@
 #include <Library/ReportStatusCodeLib.h>
 #include <Library/MpInitLib.h>
 #include <Library/TimerLib.h>
+#include <Library/DxeMemoryProtectionHobLib.h>
 
 #include <Guid/IdleLoopEvent.h>
 #include <Guid/VectorHandoffTable.h>
 
-#define HEAP_GUARD_NONSTOP_MODE       \
-        ((PcdGet8 (PcdHeapGuardPropertyMask) & (BIT6|BIT4|BIT1|BIT0)) > BIT6)
+#define HEAP_GUARD_NONSTOP_MODE      (gDxeMps.HeapGuard.NonstopModeEnabled        &&  \
+                                     (gDxeMps.HeapGuard.PageGuardEnabled          ||  \
+                                      gDxeMps.HeapGuard.PoolGuardEnabled          ||  \
+                                      gDxeMps.HeapGuard.FreedMemoryGuardEnabled))     \
 
-#define NULL_DETECTION_NONSTOP_MODE   \
-        ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & (BIT6|BIT0)) > BIT6)
+#define NULL_DETECTION_NONSTOP_MODE  (gDxeMps.NullPointerDetection.Enabled && \
+                                      gDxeMps.NullPointerDetection.NonstopModeEnabled)
 
 /**
   Flush CPU data cache. If the instruction cache is fully coherent
diff --git a/UefiCpuPkg/CpuDxe/CpuDxe.inf b/UefiCpuPkg/CpuDxe/CpuDxe.inf
index 1d3e9f8cdb..ab2bd96d97 100644
--- a/UefiCpuPkg/CpuDxe/CpuDxe.inf
+++ b/UefiCpuPkg/CpuDxe/CpuDxe.inf
@@ -40,6 +40,7 @@
   MpInitLib
   TimerLib
   PeCoffGetEntryPointLib
+  DxeMemoryProtectionHobLib
 
 [Sources]
   CpuDxe.c
@@ -74,9 +75,6 @@
 
 [Pcd]
   gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask    ## CONSUMES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard                       ## CONSUMES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask               ## CONSUMES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask    ## CONSUMES
   gUefiCpuPkgTokenSpaceGuid.PcdCpuStackSwitchExceptionList              ## CONSUMES
   gUefiCpuPkgTokenSpaceGuid.PcdCpuKnownGoodStackSize                    ## CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdTdxSharedBitMask                    ## CONSUMES
diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c
index e7575d9b80..c06049a894 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.c
+++ b/UefiCpuPkg/CpuDxe/CpuMp.c
@@ -734,7 +734,7 @@ InitializeMpExceptionHandlers (
   //
   // Setup stack switch for Stack Guard feature.
   //
-  if (PcdGetBool (PcdCpuStackGuard)) {
+  if (gDxeMps.CpuStackGuardEnabled) {
     InitializeMpExceptionStackSwitchHandlers ();
   }
 }
diff --git a/UefiCpuPkg/CpuDxeRiscV64/CpuDxeRiscV64.inf b/UefiCpuPkg/CpuDxeRiscV64/CpuDxeRiscV64.inf
index e8fa25446a..ca552f347d 100644
--- a/UefiCpuPkg/CpuDxeRiscV64/CpuDxeRiscV64.inf
+++ b/UefiCpuPkg/CpuDxeRiscV64/CpuDxeRiscV64.inf
@@ -54,9 +54,6 @@
   gEfiSecPlatformInformationPpiGuid             ## UNDEFINED # HOB
 
 [Pcd]
-  gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard                       ## CONSUMES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask               ## CONSUMES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask    ## CONSUMES
   gUefiCpuPkgTokenSpaceGuid.PcdCpuStackSwitchExceptionList              ## CONSUMES
   gUefiCpuPkgTokenSpaceGuid.PcdCpuKnownGoodStackSize                    ## CONSUMES
   gUefiCpuPkgTokenSpaceGuid.PcdCpuCoreCrystalClockFrequency             ## CONSUMES
diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.c b/UefiCpuPkg/CpuMpPei/CpuMpPei.c
index b504bea3cf..ca0c6bdb4b 100644
--- a/UefiCpuPkg/CpuMpPei/CpuMpPei.c
+++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.c
@@ -469,10 +469,6 @@ InitializeMpExceptionStackSwitchHandlers (
   EFI_STATUS                      Status;
   UINT8                           *Buffer;
 
-  if (!PcdGetBool (PcdCpuStackGuard)) {
-    return;
-  }
-
   Status = MpInitLibGetNumberOfProcessors (&NumberOfProcessors, NULL);
   ASSERT_EFI_ERROR (Status);
 
@@ -589,7 +585,9 @@ InitializeCpuMpWorker (
   //
   // Special initialization for the sake of Stack Guard
   //
-  InitializeMpExceptionStackSwitchHandlers ();
+  if (mInitStackGuard) {
+    InitializeMpExceptionStackSwitchHandlers ();
+  }
 
   //
   // Update and publish CPU BIST information
diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.h b/UefiCpuPkg/CpuMpPei/CpuMpPei.h
index 1b9a94e18f..d0db4e480e 100644
--- a/UefiCpuPkg/CpuMpPei/CpuMpPei.h
+++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.h
@@ -31,6 +31,7 @@
 #include <Library/CpuPageTableLib.h>
 
 extern EFI_PEI_PPI_DESCRIPTOR  mPeiCpuMpPpiDesc;
+extern BOOLEAN                 mInitStackGuard;
 
 /**
   This service retrieves the number of logical processor in the platform
@@ -426,7 +427,7 @@ InitializeCpuMpWorker (
   );
 
 /**
-  Enable/setup stack guard for each processor if PcdCpuStackGuard is set to TRUE.
+  Enable/setup stack guard for each processor.
 
   Doing this in the memory-discovered callback is to make sure the Stack Guard
   feature to cover as most PEI code as possible.
diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.inf b/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
index 865be5627e..6a98775412 100644
--- a/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
+++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
@@ -64,7 +64,6 @@
 
 [Pcd]
   gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask    ## CONSUMES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard                       ## CONSUMES
   gUefiCpuPkgTokenSpaceGuid.PcdCpuStackSwitchExceptionList              ## SOMETIMES_CONSUMES
   gUefiCpuPkgTokenSpaceGuid.PcdCpuKnownGoodStackSize                    ## SOMETIMES_CONSUMES
   gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize                           ## SOMETIMES_CONSUMES
diff --git a/UefiCpuPkg/CpuMpPei/CpuPaging.c b/UefiCpuPkg/CpuMpPei/CpuPaging.c
index b7ddb0005b..b389d5ff67 100644
--- a/UefiCpuPkg/CpuMpPei/CpuPaging.c
+++ b/UefiCpuPkg/CpuMpPei/CpuPaging.c
@@ -68,6 +68,8 @@ EFI_PEI_NOTIFY_DESCRIPTOR  mPostMemNotifyList[] = {
   }
 };
 
+BOOLEAN  mInitStackGuard = FALSE;
+
 /**
   The function will check if IA32 PAE is supported.
 
@@ -553,7 +555,6 @@ MemoryDiscoveredPpiNotifyCallback (
   )
 {
   EFI_STATUS              Status;
-  BOOLEAN                 InitStackGuard;
   EDKII_MIGRATED_FV_INFO  *MigratedFvInfo;
   EFI_PEI_HOB_POINTERS    Hob;
   IA32_CR0                Cr0;
@@ -563,11 +564,10 @@ MemoryDiscoveredPpiNotifyCallback (
   // initialization later will not contain paging information and then fail
   // the task switch (for the sake of stack switch).
   //
-  InitStackGuard = FALSE;
-  Hob.Raw        = NULL;
+  Hob.Raw = NULL;
   if (IsIa32PaeSupported ()) {
-    Hob.Raw        = GetFirstGuidHob (&gEdkiiMigratedFvInfoGuid);
-    InitStackGuard = PcdGetBool (PcdCpuStackGuard);
+    Hob.Raw         = GetFirstGuidHob (&gEdkiiMigratedFvInfoGuid);
+    mInitStackGuard = TRUE;
   }
 
   //
@@ -575,7 +575,7 @@ MemoryDiscoveredPpiNotifyCallback (
   // is to enable paging if it is not enabled (only in 32bit mode).
   //
   Cr0.UintN = AsmReadCr0 ();
-  if ((Cr0.Bits.PG == 0) && (InitStackGuard || (Hob.Raw != NULL))) {
+  if ((Cr0.Bits.PG == 0) && (mInitStackGuard || (Hob.Raw != NULL))) {
     ASSERT (sizeof (UINTN) == sizeof (UINT32));
 
     Status = EnablePaePageTable ();
@@ -588,7 +588,7 @@ MemoryDiscoveredPpiNotifyCallback (
   Status = InitializeCpuMpWorker ((CONST EFI_PEI_SERVICES **)PeiServices);
   ASSERT_EFI_ERROR (Status);
 
-  if (InitStackGuard) {
+  if (mInitStackGuard) {
     SetupStackGuardPage ();
   }
 
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
index fdbebadab9..1fddf15b70 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
@@ -39,7 +39,6 @@
   DxeException.c
 
 [Pcd]
-  gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard
   gUefiCpuPkgTokenSpaceGuid.PcdCpuStackSwitchExceptionList
   gUefiCpuPkgTokenSpaceGuid.PcdCpuKnownGoodStackSize
 
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf
index 3bcaff5c5f..348f7ed56c 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf
@@ -55,7 +55,6 @@
   CcExitLib
 
 [Pcd]
-  gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard    # CONSUMES
   gUefiCpuPkgTokenSpaceGuid.PcdCpuKnownGoodStackSize
   gUefiCpuPkgTokenSpaceGuid.PcdCpuStackSwitchExceptionList
 
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
index e7b1144f69..0217c983d7 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
@@ -51,7 +51,6 @@
   CcExitLib
 
 [Pcd]
-  gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard
   gUefiCpuPkgTokenSpaceGuid.PcdCpuStackSwitchExceptionList
   gUefiCpuPkgTokenSpaceGuid.PcdCpuKnownGoodStackSize
 
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf
index 27f0b96fa9..6dc09b447f 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf
@@ -54,7 +54,6 @@
   CcExitLib
 
 [Pcd]
-  gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard
   gUefiCpuPkgTokenSpaceGuid.PcdCpuStackSwitchExceptionList
   gUefiCpuPkgTokenSpaceGuid.PcdCpuKnownGoodStackSize
 
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/CpuExceptionHandlerTest.h b/UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/CpuExceptionHandlerTest.h
index bad3387db5..3f55e004cb 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/CpuExceptionHandlerTest.h
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/CpuExceptionHandlerTest.h
@@ -27,7 +27,7 @@
     In this test case, stack overflow is triggered by a funtion which calls itself continuously. This test case triggers stack
     overflow in both BSP and AP. All AP use same Idt with Bsp. The expectation is:
       1. PF exception is triggered (leading to a DF if sepereated stack is not prepared for PF) when Rsp <= StackBase + SIZE_4KB
-         since [StackBase, StackBase + SIZE_4KB] is marked as not present in page table when PcdCpuStackGuard is TRUE.
+         since [StackBase, StackBase + SIZE_4KB] is marked as not present in page table when CpuStackGuard is TRUE.
       2. Stack for PF/DF exception handler in both Bsp and AP is succussfully switched by InitializeSeparateExceptionStacks.
 
 **/
@@ -48,6 +48,7 @@
 #include <Library/HobLib.h>
 #include <Library/CpuPageTableLib.h>
 #include <Guid/MemoryAllocationHob.h>
+#include <Guid/DxeMemoryProtectionSettings.h>
 #include <Protocol/MpService.h>
 #include <PiPei.h>
 #include <Ppi/MpServices2.h>
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/CpuExceptionHandlerTestCommon.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/CpuExceptionHandlerTestCommon.c
index 9ba70c5b73..c5058a88a2 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/CpuExceptionHandlerTestCommon.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/CpuExceptionHandlerTestCommon.c
@@ -708,6 +708,27 @@ InitializeMpExceptionStackSwitchHandlers (
   return SwitchStackData;
 }
 
+/**
+  Checks if the memory protection HOB entry is available and if stack guard is enabled.
+
+  @param Context The unit test context
+**/
+UNIT_TEST_STATUS
+EFIAPI
+IsStackGuardEnabled (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  VOID  *Ptr;
+
+  Ptr = GetFirstGuidHob (&gDxeMemoryProtectionSettingsGuid);
+  UT_ASSERT_NOT_NULL (Ptr);
+  UT_ASSERT_TRUE (DXE_MPS_IS_STRUCT_VALID (GET_GUID_HOB_DATA (Ptr)));
+  UT_ASSERT_TRUE (((DXE_MEMORY_PROTECTION_SETTINGS *)GET_GUID_HOB_DATA (Ptr))->CpuStackGuardEnabled);
+
+  return UNIT_TEST_PASSED;
+}
+
 /**
   Test if stack overflow is captured by CpuStackGuard in both Bsp and AP.
 
@@ -743,10 +764,6 @@ TestCpuStackGuardInBspAndAp (
   VOID                            *NewIdtr;
   UINTN                           *CpuStackBaseBuffer;
 
-  if (!PcdGetBool (PcdCpuStackGuard)) {
-    return UNIT_TEST_PASSED;
-  }
-
   //
   // Get MP Service Protocol
   //
@@ -846,7 +863,7 @@ AddCommonTestCase (
   AddTestCase (CpuExceptionLibUnitTestSuite, "Check if exception handler can be registered/unregistered for GP and PF", "TestRegisterHandlerForGPAndPF", TestRegisterHandlerForGPAndPF, NULL, NULL, NULL);
 
   AddTestCase (CpuExceptionLibUnitTestSuite, "Check if Cpu Context is consistent before and after exception.", "TestCpuContextConsistency", TestCpuContextConsistency, NULL, NULL, NULL);
-  AddTestCase (CpuExceptionLibUnitTestSuite, "Check if stack overflow is captured by CpuStackGuard in Bsp and AP", "TestCpuStackGuardInBspAndAp", TestCpuStackGuardInBspAndAp, NULL, NULL, NULL);
+  AddTestCase (CpuExceptionLibUnitTestSuite, "Check if stack overflow is captured by CpuStackGuard in Bsp and AP", "TestCpuStackGuardInBspAndAp", TestCpuStackGuardInBspAndAp, IsStackGuardEnabled, NULL, NULL);
 
   return EFI_SUCCESS;
 }
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/DxeCpuExceptionHandlerLibUnitTest.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/DxeCpuExceptionHandlerLibUnitTest.inf
index a904eb2504..4392d42fc4 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/DxeCpuExceptionHandlerLibUnitTest.inf
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/DxeCpuExceptionHandlerLibUnitTest.inf
@@ -46,9 +46,9 @@
 
 [Guids]
   gEfiHobMemoryAllocStackGuid
+  gDxeMemoryProtectionSettingsGuid
 
 [Pcd]
-  gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard       ## CONSUMES
   gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize           ## CONSUMES
 
 [Protocols]
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/PeiCpuExceptionHandlerLibUnitTest.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/PeiCpuExceptionHandlerLibUnitTest.inf
index 25f8f8dbe0..12746ea018 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/PeiCpuExceptionHandlerLibUnitTest.inf
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/PeiCpuExceptionHandlerLibUnitTest.inf
@@ -50,12 +50,14 @@
   PeiServicesTablePointerLib
 
 [Pcd]
-  gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard   ## CONSUMES
   gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize       ## CONSUMES
 
 [Ppis]
   gEdkiiPeiMpServices2PpiGuid                       ## CONSUMES
 
+[Guids]
+  gDxeMemoryProtectionSettingsGuid                  ## CONSUMES
+
 [Depex]
   gEdkiiPeiMpServices2PpiGuid AND
   gEfiPeiMemoryDiscoveredPpiGuid
diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
index 7d45d3ad4d..345dc0afb1 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
@@ -58,6 +58,8 @@
   PcdLib
   CcExitLib
   MicrocodeLib
+  DxeMemoryProtectionHobLib
+
 [LibraryClasses.X64]
   CpuPageTableLib
 
@@ -81,6 +83,5 @@
   gUefiCpuPkgTokenSpaceGuid.PcdCpuApStatusCheckIntervalInMicroSeconds  ## CONSUMES
   gUefiCpuPkgTokenSpaceGuid.PcdGhcbHypervisorFeatures                  ## CONSUMES
   gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase                       ## SOMETIMES_CONSUMES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard                      ## CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase                           ## CONSUMES
   gEfiMdePkgTokenSpaceGuid.PcdConfidentialComputingGuestAttr           ## CONSUMES
diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
index 57ddb86600..2dfaf0df69 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
@@ -13,6 +13,7 @@
 #include <Library/DebugAgentLib.h>
 #include <Library/DxeServicesTableLib.h>
 #include <Library/CcExitLib.h>
+#include <Library/DxeMemoryProtectionHobLib.h>
 #include <Register/Amd/Fam17Msr.h>
 #include <Register/Amd/Ghcb.h>
 
@@ -497,7 +498,7 @@ InitMpGlobalData (
     return;
   }
 
-  if (PcdGetBool (PcdCpuStackGuard)) {
+  if (gDxeMps.CpuStackGuardEnabled) {
     //
     // One extra page at the bottom of the stack is needed for Guard page.
     //
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c
index b11264ce4a..1a2312a248 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c
@@ -160,7 +160,7 @@ SmiPFHandler (
     //
     // If NULL pointer was just accessed
     //
-    if (((PcdGet8 (PcdNullPointerDetectionPropertyMask) & BIT1) != 0) &&
+    if (gMmMps.NullPointerDetection.Enabled &&
         (PFAddress < EFI_PAGE_SIZE))
     {
       DumpCpuContext (InterruptType, SystemContext);
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
index 5d52ed7d13..8f9bdf8374 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
@@ -103,6 +103,7 @@
   PerformanceLib
   CpuPageTableLib
   MmSaveStateLib
+  MmMemoryProtectionHobLib
 
 [Protocols]
   gEfiSmmAccess2ProtocolGuid               ## CONSUMES
@@ -146,8 +147,6 @@
   gUefiCpuPkgTokenSpaceGuid.PcdCpuFeaturesInitOnS3Resume           ## CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable                   ## CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask    ## CONSUMES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask    ## CONSUMES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask               ## CONSUMES
   gEfiMdePkgTokenSpaceGuid.PcdControlFlowEnforcementPropertyMask        ## CONSUMES
 
 [FixedPcd]
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c
index 6f49866615..29552b11ce 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c
@@ -1679,7 +1679,7 @@ GenSmmPageTable (
     }
   }
 
-  if ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & BIT1) != 0) {
+  if (gMmMps.NullPointerDetection.Enabled) {
     //
     // Mark [0, 4k] as non-present
     //
@@ -1834,13 +1834,13 @@ IfReadOnlyPageTableNeeded (
   //
   // Don't mark page table memory as read-only if
   //  - no restriction on access to non-SMRAM memory; or
-  //  - SMM heap guard feature enabled; or
-  //      BIT2: SMM page guard enabled
-  //      BIT3: SMM pool guard enabled
+  //  - SMM page guard enabled
+  //  - SMM pool guard enabled
   //  - SMM profile feature enabled
   //
   if (!IsRestrictedMemoryAccess () ||
-      ((PcdGet8 (PcdHeapGuardPropertyMask) & (BIT3 | BIT2)) != 0) ||
+      (gMmMps.HeapGuard.PageGuardEnabled) ||
+      (gMmMps.HeapGuard.PoolGuardEnabled) ||
       FeaturePcdGet (PcdCpuSmmProfileEnable))
   {
     if (sizeof (UINTN) == sizeof (UINT64)) {
@@ -1849,7 +1849,8 @@ IfReadOnlyPageTableNeeded (
       //
       ASSERT (
         !(IsRestrictedMemoryAccess () &&
-          (PcdGet8 (PcdHeapGuardPropertyMask) & (BIT3 | BIT2)) != 0)
+          ((gMmMps.HeapGuard.PageGuardEnabled) ||
+           (gMmMps.HeapGuard.PoolGuardEnabled)))
         );
 
       //
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c
index 7ac3c66f91..eceb0a565c 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c
@@ -610,7 +610,7 @@ InitPaging (
   //
   // [0, 4k] may be non-present.
   //
-  PreviousAddress = ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & BIT1) != 0) ? BASE_4KB : 0;
+  PreviousAddress = (gMmMps.NullPointerDetection.Enabled) ? BASE_4KB : 0;
 
   DEBUG ((DEBUG_INFO, "Patch page table start ...\n"));
   if (FeaturePcdGet (PcdCpuSmmProfileEnable)) {
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h
index 964dd52817..50397e4750 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h
@@ -15,6 +15,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include <Library/DxeServicesTableLib.h>
 #include <Library/CpuLib.h>
 #include <IndustryStandard/Acpi.h>
+#include <Library/MmMemoryProtectionHobLib.h>
 
 #include "SmmProfileArch.h"
 
@@ -57,11 +58,12 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #define   MSR_DEBUG_CTL_BTINT  0x100
 #define MSR_DS_AREA            0x600
 
-#define HEAP_GUARD_NONSTOP_MODE      \
-        ((PcdGet8 (PcdHeapGuardPropertyMask) & (BIT6|BIT3|BIT2)) > BIT6)
+#define HEAP_GUARD_NONSTOP_MODE      (gMmMps.HeapGuard.NonstopModeEnabled  &&  \
+                                     (gMmMps.HeapGuard.PageGuardEnabled    ||  \
+                                      gMmMps.HeapGuard.PoolGuardEnabled))      \
 
-#define NULL_DETECTION_NONSTOP_MODE  \
-        ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & (BIT6|BIT1)) > BIT6)
+#define NULL_DETECTION_NONSTOP_MODE  (gMmMps.NullPointerDetection.NonstopModeEnabled   &&  \
+                                      gMmMps.NullPointerDetection.Enabled)
 
 typedef struct {
   EFI_PHYSICAL_ADDRESS    Base;
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c
index ddd9be66b5..28eaa18689 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c
@@ -932,7 +932,7 @@ SmiPFHandler (
     //
     // If NULL pointer was just accessed
     //
-    if (((PcdGet8 (PcdNullPointerDetectionPropertyMask) & BIT1) != 0) &&
+    if (gMmMps.NullPointerDetection.Enabled &&
         (PFAddress < EFI_PAGE_SIZE))
     {
       DumpCpuContext (InterruptType, SystemContext);
diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec
index 25126c9136..4649bdef5d 100644
--- a/UefiCpuPkg/UefiCpuPkg.dec
+++ b/UefiCpuPkg/UefiCpuPkg.dec
@@ -187,13 +187,13 @@
 
 [PcdsFixedAtBuild]
   ## List of exception vectors which need switching stack.
-  #  This PCD will only take into effect if PcdCpuStackGuard is enabled.
+  #  This PCD will only take into effect if the CPU Stack Guard is enabled.
   #  By default exception #DD(8), #PF(14) are supported.
   # @Prompt Specify exception vectors which need switching stack.
   gUefiCpuPkgTokenSpaceGuid.PcdCpuStackSwitchExceptionList|{0x08, 0x0E}|VOID*|0x30002000
 
   ## Size of good stack for an exception.
-  #  This PCD will only take into effect if PcdCpuStackGuard is enabled.
+  #  This PCD will only take into effect if the CPU Stack Guard is enabled.
   # @Prompt Specify size of good stack of exception which need switching stack.
   gUefiCpuPkgTokenSpaceGuid.PcdCpuKnownGoodStackSize|2048|UINT32|0x30002001
 
@@ -372,9 +372,8 @@
   #  and the memory occupied by page table is protected by page table itself as read-only.
   #  In X64 build, it cannot be enabled at the same time with SMM profile feature (PcdCpuSmmProfileEnable).
   #  In X64 build, it could not be enabled also at the same time with heap guard feature for SMM
-  #  (PcdHeapGuardPropertyMask in MdeModulePkg).
   #  In IA32 build, page table memory is not marked as read-only when either SMM profile feature (PcdCpuSmmProfileEnable)
-  #  or heap guard feature for SMM (PcdHeapGuardPropertyMask in MdeModulePkg) is enabled.
+  #  or heap guard feature for SMM is enabled.
   #   TRUE  - Access to non-SMRAM memory is restricted to reserved, runtime and ACPI NVS type after SmmReadyToLock.<BR>
   #   FALSE - Access to any type of non-SMRAM memory after SmmReadyToLock is allowed.<BR>
   # @Prompt Access to non-SMRAM memory is restricted to reserved, runtime and ACPI NVS type after SmmReadyToLock.
diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc
index 45726b9efc..bff7fc5bd5 100644
--- a/UefiCpuPkg/UefiCpuPkg.dsc
+++ b/UefiCpuPkg/UefiCpuPkg.dsc
@@ -66,6 +66,8 @@
   UnitTestLib|UnitTestFrameworkPkg/Library/UnitTestLib/UnitTestLib.inf
   UnitTestPersistenceLib|UnitTestFrameworkPkg/Library/UnitTestPersistenceLibNull/UnitTestPersistenceLibNull.inf
   UnitTestResultReportLib|UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLibDebugLib.inf
+  DxeMemoryProtectionHobLib|MdeModulePkg/Library/MemoryProtectionHobLibNull/DxeMemoryProtectionHobLibNull.inf
+  MmMemoryProtectionHobLib|MdeModulePkg/Library/MemoryProtectionHobLibNull/MmMemoryProtectionHobLibNull.inf
 
 [LibraryClasses.common.SEC]
   PlatformSecLib|UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.inf
diff --git a/UefiCpuPkg/UefiCpuPkg.uni b/UefiCpuPkg/UefiCpuPkg.uni
index d17bcfd10c..5719917a04 100644
--- a/UefiCpuPkg/UefiCpuPkg.uni
+++ b/UefiCpuPkg/UefiCpuPkg.uni
@@ -170,8 +170,7 @@
                                                                                      "If enabled, SMM will not use on-demand paging. SMM will build static page table for all memory.\n"
                                                                                      "This flag only impacts X64 build, because SMM always builds static page table for IA32.\n"
                                                                                      "It could not be enabled at the same time with SMM profile feature (PcdCpuSmmProfileEnable).\n"
-                                                                                     "It could not be enabled also at the same time with heap guard feature for SMM\n"
-                                                                                     "(PcdHeapGuardPropertyMask in MdeModulePkg).<BR><BR>\n"
+                                                                                     "It could not be enabled also at the same time with heap guard feature for SMM.<BR><BR>\n"
                                                                                      "TRUE  - SMM uses static page table for all memory.<BR>\n"
                                                                                      "FALSE - SMM uses static page table for below 4G memory and use on-demand paging for above 4G memory.<BR>"
 
@@ -217,9 +216,8 @@
                                                                                             "and the memory occupied by page table is protected by page table itself as read-only.<BR>\n"
                                                                                             "In X64 build, it cannot be enabled at the same time with SMM profile feature (PcdCpuSmmProfileEnable).<BR>\n"
                                                                                             "In X64 build, it could not be enabled also at the same time with heap guard feature for SMM<BR>\n"
-                                                                                            "(PcdHeapGuardPropertyMask in MdeModulePkg).<BR>\n"
                                                                                             "In IA32 build, page table memory is not marked as read-only when either SMM profile feature (PcdCpuSmmProfileEnable)<BR>\n"
-                                                                                            "or heap guard feature for SMM (PcdHeapGuardPropertyMask in MdeModulePkg) is enabled.<BR>\n"
+                                                                                            "or heap guard feature for SMM is enabled.<BR>\n"
                                                                                             "TRUE  - Access to non-SMRAM memory is restricted to reserved, runtime and ACPI NVS type after SmmReadyToLock.<BR>\n"
                                                                                             "FALSE - Access to any type of non-SMRAM memory after SmmReadyToLock is allowed.<BR>"
 
@@ -266,13 +264,13 @@
 #string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuStackSwitchExceptionList_PROMPT  #language en-US "Specify exception vectors which need switching stack."
 
 #string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuStackSwitchExceptionList_HELP  #language en-US "List of exception vectors which need switching stack.\n"
-                                                                                           "This PCD will only take into effect if PcdCpuStackGuard is enabled.n"
+                                                                                           "This PCD will only take into effect if the CPU Stack Guard is enabled.n"
                                                                                            "By default exception #DD(8), #PF(14) are supported.n"
 
 #string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuKnownGoodStackSize_PROMPT  #language en-US "Specify size of good stack of exception which need switching stack."
 
 #string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuKnownGoodStackSize_HELP  #language en-US "Size of good stack for an exception.\n"
-                                                                                     "This PCD will only take into effect if PcdCpuStackGuard is enabled.\n"
+                                                                                     "This PCD will only take into effect if the CPU Stack Guard is enabled.\n"
 
 #string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuCoreCrystalClockFrequency_PROMPT  #language en-US "Specifies CPUID Leaf 0x15 Time Stamp Counter and Nominal Core Crystal Clock Frequency."
 
-- 
2.41.0.windows.2


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 11/14] UefiPayloadPkg: Update to use memory protection HOB
  2023-07-11 23:52 [PATCH 00/14] Implement Dynamic Memory Protections Taylor Beebe
                   ` (9 preceding siblings ...)
  2023-07-11 23:52 ` [PATCH 10/14] UefiCpuPkg: " Taylor Beebe
@ 2023-07-11 23:52 ` Taylor Beebe
  2023-07-11 23:52 ` [PATCH 12/14] OvmfPkg: Delete Memory Protection PCDs Taylor Beebe
                   ` (5 subsequent siblings)
  16 siblings, 0 replies; 24+ messages in thread
From: Taylor Beebe @ 2023-07-11 23:52 UTC (permalink / raw)
  To: devel; +Cc: Guo Dong, Sean Rhodes, James Lu, Gua Guo

From: Taylor Beebe <tabeebe@microsoft.com>

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

The X64/DxeLoadFunc.c will check the PcdDxeIplBuildPageTables
PCD to determine if page tables should be built wheras before
they would check both the PcdDxeIplBuildPageTables PCD and the
memory protection settings. If PcdDxeIplBuildPageTables is
FALSE but memory protections are active, ASSERT on X64.

The Ia32/DxeLoadFunc.c was hard-coded to always build the page
tables, and that is unchanged in this patch. However,
this does remove the unused Create4GPageTablesIa32Pae() function
in Ia32/DxeLoadFunc.c.

Signed-off-by: Taylor Beebe <t@taylorbeebe.com>
Cc: Guo Dong <guo.dong@intel.com>
Cc: Sean Rhodes <sean@starlabs.systems>
Cc: James Lu <james.lu@intel.com>
Cc: Gua Guo <gua.guo@intel.com>
---
 .../UefiPayloadEntry/Ia32/DxeLoadFunc.c       | 149 +-----------------
 UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c |  26 +++
 .../UefiPayloadEntry/UefiPayloadEntry.h       |  15 ++
 .../UefiPayloadEntry/UefiPayloadEntry.inf     |   9 +-
 .../UniversalPayloadEntry.inf                 |   9 +-
 .../UefiPayloadEntry/X64/DxeLoadFunc.c        |  25 ++-
 .../UefiPayloadEntry/X64/VirtualMemory.c      |  78 ++++-----
 .../UefiPayloadEntry/X64/VirtualMemory.h      |  23 +--
 UefiPayloadPkg/UefiPayloadPkg.dsc             |   1 +
 9 files changed, 98 insertions(+), 237 deletions(-)

diff --git a/UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFunc.c b/UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFunc.c
index 61a9f01ec9..fa1fa53aea 100644
--- a/UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFunc.c
+++ b/UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFunc.c
@@ -78,107 +78,6 @@ GLOBAL_REMOVE_IF_UNREFERENCED  IA32_DESCRIPTOR  gLidtDescriptor = {
   0
 };
 
-/**
-  Allocates and fills in the Page Directory and Page Table Entries to
-  establish a 4G page table.
-
-  @param[in] StackBase  Stack base address.
-  @param[in] StackSize  Stack size.
-
-  @return The address of page table.
-
-**/
-UINTN
-Create4GPageTablesIa32Pae (
-  IN EFI_PHYSICAL_ADDRESS  StackBase,
-  IN UINTN                 StackSize
-  )
-{
-  UINT8                           PhysicalAddressBits;
-  EFI_PHYSICAL_ADDRESS            PhysicalAddress;
-  UINTN                           IndexOfPdpEntries;
-  UINTN                           IndexOfPageDirectoryEntries;
-  UINT32                          NumberOfPdpEntriesNeeded;
-  PAGE_MAP_AND_DIRECTORY_POINTER  *PageMap;
-  PAGE_MAP_AND_DIRECTORY_POINTER  *PageDirectoryPointerEntry;
-  PAGE_TABLE_ENTRY                *PageDirectoryEntry;
-  UINTN                           TotalPagesNum;
-  UINTN                           PageAddress;
-  UINT64                          AddressEncMask;
-
-  //
-  // Make sure AddressEncMask is contained to smallest supported address field
-  //
-  AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & PAGING_1G_ADDRESS_MASK_64;
-
-  PhysicalAddressBits = 32;
-
-  //
-  // Calculate the table entries needed.
-  //
-  NumberOfPdpEntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - 30));
-
-  TotalPagesNum = NumberOfPdpEntriesNeeded + 1;
-  PageAddress   = (UINTN)AllocatePageTableMemory (TotalPagesNum);
-  ASSERT (PageAddress != 0);
-
-  PageMap      = (VOID *)PageAddress;
-  PageAddress += SIZE_4KB;
-
-  PageDirectoryPointerEntry = PageMap;
-  PhysicalAddress           = 0;
-
-  for (IndexOfPdpEntries = 0; IndexOfPdpEntries < NumberOfPdpEntriesNeeded; IndexOfPdpEntries++, PageDirectoryPointerEntry++) {
-    //
-    // Each Directory Pointer entries points to a page of Page Directory entires.
-    // So allocate space for them and fill them in in the IndexOfPageDirectoryEntries loop.
-    //
-    PageDirectoryEntry = (VOID *)PageAddress;
-    PageAddress       += SIZE_4KB;
-
-    //
-    // Fill in a Page Directory Pointer Entries
-    //
-    PageDirectoryPointerEntry->Uint64       = (UINT64)(UINTN)PageDirectoryEntry | AddressEncMask;
-    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)))
-      {
-        //
-        // Need to split this 2M page that covers stack range.
-        //
-        Split2MPageTo4K (PhysicalAddress, (UINT64 *)PageDirectoryEntry, StackBase, StackSize, 0, 0);
-      } else {
-        //
-        // Fill in the Page Directory entries
-        //
-        PageDirectoryEntry->Uint64         = (UINT64)PhysicalAddress | AddressEncMask;
-        PageDirectoryEntry->Bits.ReadWrite = 1;
-        PageDirectoryEntry->Bits.Present   = 1;
-        PageDirectoryEntry->Bits.MustBe1   = 1;
-      }
-    }
-  }
-
-  for ( ; IndexOfPdpEntries < 512; IndexOfPdpEntries++, PageDirectoryPointerEntry++) {
-    ZeroMem (
-      PageDirectoryPointerEntry,
-      sizeof (PAGE_MAP_AND_DIRECTORY_POINTER)
-      );
-  }
-
-  //
-  // Protect the page table by marking the memory used for page table to be
-  // read-only.
-  //
-  EnablePageTableProtection ((UINTN)PageMap, FALSE);
-
-  return (UINTN)PageMap;
-}
-
 /**
   The function will check if IA32 PAE is supported.
 
@@ -207,41 +106,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.
 
@@ -268,12 +132,13 @@ HandOffToDxeCore (
   UINT32                   Index;
   X64_IDT_TABLE            *IdtTableForX64;
 
-  //
-  // 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);
   }
 
   BaseOfStack = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocatePages (EFI_SIZE_TO_PAGES (STACK_SIZE));
diff --git a/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c b/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c
index 898d610951..407afbe404 100644
--- a/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c
+++ b/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c
@@ -8,6 +8,8 @@
 
 #include "UefiPayloadEntry.h"
 
+DXE_MEMORY_PROTECTION_SETTINGS  mDxeMps;
+
 /**
   Allocate pages for code.
 
@@ -359,3 +361,27 @@ UniversalLoadDxeCore (
 
   return EFI_SUCCESS;
 }
+
+/**
+  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/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h
index ad8a9fd22b..56fd767036 100644
--- a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h
+++ b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h
@@ -30,6 +30,7 @@
 #include <Guid/MemoryMapInfoGuid.h>
 #include <Guid/AcpiBoardInfoGuid.h>
 #include <Guid/GraphicsInfoHob.h>
+#include <Guid/DxeMemoryProtectionSettings.h>
 #include <UniversalPayload/SmbiosTable.h>
 #include <UniversalPayload/AcpiTable.h>
 #include <UniversalPayload/UniversalPayload.h>
@@ -51,6 +52,8 @@
 #define E820_PMEM       7
 #define E820_UNDEFINED  8
 
+extern DXE_MEMORY_PROTECTION_SETTINGS  mDxeMps;
+
 /**
   Auto-generated function that calls the library constructors for all of the module's
   dependent libraries.
@@ -216,4 +219,16 @@ BuildHobFromAcpi (
   IN   UINT64  AcpiTableBase
   );
 
+/**
+  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
+  );
+
 #endif
diff --git a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf
index e2af8a4b7c..8d5600b6ce 100644
--- a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf
+++ b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf
@@ -65,6 +65,7 @@
   gUniversalPayloadSmbiosTableGuid
   gUniversalPayloadAcpiTableGuid
   gUniversalPayloadSerialPortInfoGuid
+  gDxeMemoryProtectionSettingsGuid
 
 [FeaturePcd.IA32]
   gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode      ## CONSUMES
@@ -76,9 +77,6 @@
 [Pcd.IA32,Pcd.X64]
   gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable                      ## SOMETIMES_CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask    ## CONSUMES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask    ## CONSUMES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask               ## CONSUMES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard                       ## CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase                            ## CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbSize                            ## CONSUMES
 
@@ -91,8 +89,3 @@
   gUefiPayloadPkgTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType
   gUefiPayloadPkgTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData
   gUefiPayloadPkgTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode
-
-  gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack               ## SOMETIMES_CONSUMES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy ## SOMETIMES_CONSUMES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy       ## SOMETIMES_CONSUMES
-
diff --git a/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf b/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf
index 5112cdc1e5..e03f25d982 100644
--- a/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf
+++ b/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf
@@ -69,6 +69,7 @@
   gUniversalPayloadAcpiTableGuid
   gUniversalPayloadPciRootBridgeInfoGuid
   gUniversalPayloadSmbios3TableGuid
+  gDxeMemoryProtectionSettingsGuid
 
 [FeaturePcd.IA32]
   gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode      ## CONSUMES
@@ -81,17 +82,9 @@
   gUefiPayloadPkgTokenSpaceGuid.PcdPcdDriverFile
   gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable                      ## SOMETIMES_CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask    ## CONSUMES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask    ## CONSUMES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask               ## CONSUMES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard                       ## CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase                            ## CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbSize                            ## CONSUMES
 
   gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemBase
   gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemSize
   gUefiPayloadPkgTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
-
-  gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack               ## SOMETIMES_CONSUMES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy ## SOMETIMES_CONSUMES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy       ## SOMETIMES_CONSUMES
-
diff --git a/UefiPayloadPkg/UefiPayloadEntry/X64/DxeLoadFunc.c b/UefiPayloadPkg/UefiPayloadEntry/X64/DxeLoadFunc.c
index 346e3feb04..53bfa3f8b4 100644
--- a/UefiPayloadPkg/UefiPayloadEntry/X64/DxeLoadFunc.c
+++ b/UefiPayloadPkg/UefiPayloadEntry/X64/DxeLoadFunc.c
@@ -40,12 +40,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);
   }
 
   //
@@ -78,17 +79,9 @@ 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);
-  }
-
-  if (FeaturePcdGet (PcdDxeIplBuildPageTables)) {
     AsmWriteCr3 (PageTables);
+  } else {
+    ASSERT (!DXE_MPS_IS_MEMORY_PROTECTION_ACTIVE (&mDxeMps));
   }
 
   //
diff --git a/UefiPayloadPkg/UefiPayloadEntry/X64/VirtualMemory.c b/UefiPayloadPkg/UefiPayloadEntry/X64/VirtualMemory.c
index 1899404b24..f01ed175c6 100644
--- a/UefiPayloadPkg/UefiPayloadEntry/X64/VirtualMemory.c
+++ b/UefiPayloadPkg/UefiPayloadEntry/X64/VirtualMemory.c
@@ -30,37 +30,45 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include <Library/PcdLib.h>
 #include <Library/HobLib.h>
 #include <Register/Intel/Cpuid.h>
+#include <Guid/DxeMemoryProtectionSettings.h>
 #include "VirtualMemory.h"
 
+extern DXE_MEMORY_PROTECTION_SETTINGS  mDxeMps;
+
 //
 // Global variable to keep track current available memory used as page table.
 //
 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;
 
-  RscHob.Raw = HobStart;
-  MemHob.Raw = HobStart;
-  DoClear    = FALSE;
+  if (HobStart == NULL) {
+    ASSERT (HobStart != NULL);
+    return 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,
@@ -68,9 +76,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.
       //
@@ -79,10 +87,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;
         }
 
@@ -95,27 +103,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;
 }
 
 /**
@@ -169,9 +157,7 @@ IsEnableNonExecNeeded (
   // 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 TRUE;
 }
 
 /**
@@ -214,7 +200,7 @@ ToSplitPageTable (
   IN UINTN                 GhcbSize
   )
 {
-  if (IsNullDetectionEnabled () && (Address == 0)) {
+  if ((Address == (UINTN)NULL) && mDxeMps.NullPointerDetection.Enabled) {
     return TRUE;
   }
 
@@ -398,17 +384,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/UefiPayloadPkg/UefiPayloadEntry/X64/VirtualMemory.h b/UefiPayloadPkg/UefiPayloadEntry/X64/VirtualMemory.h
index 616ebe42b0..c27bf68a04 100644
--- a/UefiPayloadPkg/UefiPayloadEntry/X64/VirtualMemory.h
+++ b/UefiPayloadPkg/UefiPayloadEntry/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/UefiPayloadPkg/UefiPayloadPkg.dsc b/UefiPayloadPkg/UefiPayloadPkg.dsc
index 47812048dd..a7282f197b 100644
--- a/UefiPayloadPkg/UefiPayloadPkg.dsc
+++ b/UefiPayloadPkg/UefiPayloadPkg.dsc
@@ -207,6 +207,7 @@
   OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
   RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf
   HobLib|UefiPayloadPkg/Library/DxeHobLib/DxeHobLib.inf
+  DxeMemoryProtectionHobLib|MdeModulePkg/Library/MemoryProtectionHobLib/DxeMemoryProtectionHobLib.inf
 
   #
   # UEFI & PI
-- 
2.41.0.windows.2


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 12/14] OvmfPkg: Delete Memory Protection PCDs
  2023-07-11 23:52 [PATCH 00/14] Implement Dynamic Memory Protections Taylor Beebe
                   ` (10 preceding siblings ...)
  2023-07-11 23:52 ` [PATCH 11/14] UefiPayloadPkg: " Taylor Beebe
@ 2023-07-11 23:52 ` Taylor Beebe
  2023-07-11 23:52 ` [PATCH 14/14] MdeModulePkg: " Taylor Beebe
                   ` (4 subsequent siblings)
  16 siblings, 0 replies; 24+ messages in thread
From: Taylor Beebe @ 2023-07-11 23:52 UTC (permalink / raw)
  To: devel; +Cc: Ard Biesheuvel, Jiewen Yao, Jordan Justen, Gerd Hoffmann

From: Taylor Beebe <tabeebe@microsoft.com>

Now that references in the rest of the codebase have been updated
to reference the memory protection HOB, delete the memory protection PCDs.

Signed-off-by: Taylor Beebe <t@taylorbeebe.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
---
 OvmfPkg/AmdSev/AmdSevX64.dsc     | 3 ---
 OvmfPkg/Bhyve/BhyveX64.dsc       | 3 ---
 OvmfPkg/CloudHv/CloudHvX64.dsc   | 3 ---
 OvmfPkg/IntelTdx/IntelTdxX64.dsc | 3 ---
 OvmfPkg/Microvm/MicrovmX64.dsc   | 3 ---
 OvmfPkg/OvmfPkgIa32.dsc          | 3 ---
 OvmfPkg/OvmfPkgIa32X64.dsc       | 3 ---
 OvmfPkg/OvmfPkgX64.dsc           | 3 ---
 OvmfPkg/OvmfXen.dsc              | 3 ---
 9 files changed, 27 deletions(-)

diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc
index ce028fcb5c..abaaf59df8 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.dsc
+++ b/OvmfPkg/AmdSev/AmdSevX64.dsc
@@ -508,9 +508,6 @@
   gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosDocRev|0x0
   gUefiOvmfPkgTokenSpaceGuid.PcdQemuSmbiosValidated|FALSE
 
-  # Noexec settings for DXE.
-  gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack|FALSE
-
   # UefiCpuPkg PCDs related to initial AP bringup and general AP management.
   gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|64
   gUefiCpuPkgTokenSpaceGuid.PcdCpuBootLogicalProcessorNumber|0
diff --git a/OvmfPkg/Bhyve/BhyveX64.dsc b/OvmfPkg/Bhyve/BhyveX64.dsc
index 248b6020ed..1ea9ac3bc4 100644
--- a/OvmfPkg/Bhyve/BhyveX64.dsc
+++ b/OvmfPkg/Bhyve/BhyveX64.dsc
@@ -552,9 +552,6 @@
   gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosDocRev|0x0
   gUefiOvmfPkgTokenSpaceGuid.PcdQemuSmbiosValidated|FALSE
 
-  # Noexec settings for DXE.
-  gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack|FALSE
-
   # UefiCpuPkg PCDs related to initial AP bringup and general AP management.
   gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|64
   gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds|50000
diff --git a/OvmfPkg/CloudHv/CloudHvX64.dsc b/OvmfPkg/CloudHv/CloudHvX64.dsc
index 8828e298ca..b852bb5ad0 100644
--- a/OvmfPkg/CloudHv/CloudHvX64.dsc
+++ b/OvmfPkg/CloudHv/CloudHvX64.dsc
@@ -601,9 +601,6 @@
   gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosDocRev|0x0
   gUefiOvmfPkgTokenSpaceGuid.PcdQemuSmbiosValidated|FALSE
 
-  # Noexec settings for DXE.
-  gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack|FALSE
-
   # UefiCpuPkg PCDs related to initial AP bringup and general AP management.
   gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|64
   gUefiCpuPkgTokenSpaceGuid.PcdCpuBootLogicalProcessorNumber|0
diff --git a/OvmfPkg/IntelTdx/IntelTdxX64.dsc b/OvmfPkg/IntelTdx/IntelTdxX64.dsc
index 27b9d4bf26..f6cc473a06 100644
--- a/OvmfPkg/IntelTdx/IntelTdxX64.dsc
+++ b/OvmfPkg/IntelTdx/IntelTdxX64.dsc
@@ -503,9 +503,6 @@
   gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosDocRev|0x0
   gUefiOvmfPkgTokenSpaceGuid.PcdQemuSmbiosValidated|FALSE
 
-  # Noexec settings for DXE.
-  gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack|TRUE
-
   # UefiCpuPkg PCDs related to initial AP bringup and general AP management.
   gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|64
   gUefiCpuPkgTokenSpaceGuid.PcdCpuBootLogicalProcessorNumber|0
diff --git a/OvmfPkg/Microvm/MicrovmX64.dsc b/OvmfPkg/Microvm/MicrovmX64.dsc
index 611d64a6a0..d4a612a7e5 100644
--- a/OvmfPkg/Microvm/MicrovmX64.dsc
+++ b/OvmfPkg/Microvm/MicrovmX64.dsc
@@ -615,9 +615,6 @@
   gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosDocRev|0x0
   gUefiOvmfPkgTokenSpaceGuid.PcdQemuSmbiosValidated|FALSE
 
-  # Noexec settings for DXE.
-  gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack|FALSE
-
   # UefiCpuPkg PCDs related to initial AP bringup and general AP management.
   gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|64
   gUefiCpuPkgTokenSpaceGuid.PcdCpuBootLogicalProcessorNumber|0
diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index 810d69651c..7dec146841 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -628,9 +628,6 @@
   gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosDocRev|0x0
   gUefiOvmfPkgTokenSpaceGuid.PcdQemuSmbiosValidated|FALSE
 
-  # Noexec settings for DXE.
-  gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack|FALSE
-
   # UefiCpuPkg PCDs related to initial AP bringup and general AP management.
   gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|64
   gUefiCpuPkgTokenSpaceGuid.PcdCpuBootLogicalProcessorNumber|0
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index 13e141a352..b9a35d43b9 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -646,9 +646,6 @@
   gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosDocRev|0x0
   gUefiOvmfPkgTokenSpaceGuid.PcdQemuSmbiosValidated|FALSE
 
-  # Noexec settings for DXE.
-  gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack|FALSE
-
   # UefiCpuPkg PCDs related to initial AP bringup and general AP management.
   gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|64
   gUefiCpuPkgTokenSpaceGuid.PcdCpuBootLogicalProcessorNumber|0
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index 418c3a0f54..cf8529ac7d 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -664,9 +664,6 @@
   gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosDocRev|0x0
   gUefiOvmfPkgTokenSpaceGuid.PcdQemuSmbiosValidated|FALSE
 
-  # Noexec settings for DXE.
-  gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack|FALSE
-
   # UefiCpuPkg PCDs related to initial AP bringup and general AP management.
   gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|64
   gUefiCpuPkgTokenSpaceGuid.PcdCpuBootLogicalProcessorNumber|0
diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc
index 94d455e2d6..8a1d1ef3e4 100644
--- a/OvmfPkg/OvmfXen.dsc
+++ b/OvmfPkg/OvmfXen.dsc
@@ -498,9 +498,6 @@
   gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosDocRev|0x0
   gUefiOvmfPkgTokenSpaceGuid.PcdQemuSmbiosValidated|FALSE
 
-  # Noexec settings for DXE.
-  gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack|FALSE
-
   # Set memory encryption mask
   gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask|0x0
 
-- 
2.41.0.windows.2


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 14/14] MdeModulePkg: Delete Memory Protection PCDs
  2023-07-11 23:52 [PATCH 00/14] Implement Dynamic Memory Protections Taylor Beebe
                   ` (11 preceding siblings ...)
  2023-07-11 23:52 ` [PATCH 12/14] OvmfPkg: Delete Memory Protection PCDs Taylor Beebe
@ 2023-07-11 23:52 ` Taylor Beebe
  2023-07-11 23:52 ` Taylor Beebe
                   ` (3 subsequent siblings)
  16 siblings, 0 replies; 24+ messages in thread
From: Taylor Beebe @ 2023-07-11 23:52 UTC (permalink / raw)
  To: devel; +Cc: Ard Biesheuvel, Leif Lindholm, Sami Mujawar, Gerd Hoffmann

From: Taylor Beebe <tabeebe@microsoft.com>

Now that references in the rest of the codebase have been updated
to reference the memory protection HOB, delete the memory protection PCDs.

Signed-off-by: Taylor Beebe <t@taylorbeebe.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Sami Mujawar <sami.mujawar@arm.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
---
 ArmVirtPkg/ArmVirt.dsc.inc    | 15 ---------------
 ArmVirtPkg/ArmVirtCloudHv.dsc |  5 -----
 ArmVirtPkg/ArmVirtQemu.dsc    |  5 -----
 3 files changed, 25 deletions(-)

diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc
index 3174b19e51..e1eb189077 100644
--- a/ArmVirtPkg/ArmVirt.dsc.inc
+++ b/ArmVirtPkg/ArmVirt.dsc.inc
@@ -363,21 +363,6 @@
   gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode|20
   gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData|0
 
-  #
-  # Enable strict image permissions for all images. (This applies
-  # only to images that were built with >= 4 KB section alignment.)
-  #
-  gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x3
-
-  #
-  # Enable NX memory protection for all non-code regions, including OEM and OS
-  # reserved ones, with the exception of LoaderData regions, of which OS loaders
-  # (i.e., GRUB) may assume that its contents are executable.
-  #
-  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xC000000000007FD5
-
-  gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard|TRUE
-
 [Components.common]
   #
   # Ramdisk support
diff --git a/ArmVirtPkg/ArmVirtCloudHv.dsc b/ArmVirtPkg/ArmVirtCloudHv.dsc
index c975e139a2..c4c3e0da44 100644
--- a/ArmVirtPkg/ArmVirtCloudHv.dsc
+++ b/ArmVirtPkg/ArmVirtCloudHv.dsc
@@ -140,11 +140,6 @@
   #
   gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|16
 
-  #
-  # Enable the non-executable DXE stack. (This gets set up by DxeIpl)
-  #
-  gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack|TRUE
-
 !if $(SECURE_BOOT_ENABLE) == TRUE
   # override the default values from SecurityPkg to ensure images from all sources are verified in secure boot
   gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy|0x04
diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc
index 1e0225951a..214e08b789 100644
--- a/ArmVirtPkg/ArmVirtQemu.dsc
+++ b/ArmVirtPkg/ArmVirtQemu.dsc
@@ -212,11 +212,6 @@
   #
   gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|16
 
-  #
-  # Enable the non-executable DXE stack. (This gets set up by DxeIpl)
-  #
-  gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack|TRUE
-
 !if $(SECURE_BOOT_ENABLE) == TRUE
   # override the default values from SecurityPkg to ensure images from all sources are verified in secure boot
   gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy|0x04
-- 
2.41.0.windows.2


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 14/14] MdeModulePkg: Delete Memory Protection PCDs
  2023-07-11 23:52 [PATCH 00/14] Implement Dynamic Memory Protections Taylor Beebe
                   ` (12 preceding siblings ...)
  2023-07-11 23:52 ` [PATCH 14/14] MdeModulePkg: " Taylor Beebe
@ 2023-07-11 23:52 ` Taylor Beebe
       [not found] ` <1770F551E2E594C0.16575@groups.io>
                   ` (2 subsequent siblings)
  16 siblings, 0 replies; 24+ messages in thread
From: Taylor Beebe @ 2023-07-11 23:52 UTC (permalink / raw)
  To: devel; +Cc: Jian J Wang, Liming Gao, Dandan Bi

From: Taylor Beebe <tabeebe@microsoft.com>

Delete the memory protection PCDs

Signed-off-by: Taylor Beebe <t@taylorbeebe.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Dandan Bi <dandan.bi@intel.com>
---
 MdeModulePkg/MdeModulePkg.dec | 169 ----------------------------------
 MdeModulePkg/MdeModulePkg.uni | 153 ------------------------------
 2 files changed, 322 deletions(-)

diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
index 2541b2b044..9456e5cdfb 100644
--- a/MdeModulePkg/MdeModulePkg.dec
+++ b/MdeModulePkg/MdeModulePkg.dec
@@ -1006,119 +1006,12 @@
   # @ValidList  0x80000006 | 0x03058002
   gEfiMdeModulePkgTokenSpaceGuid.PcdErrorCodeSetVariable|0x03058002|UINT32|0x30001040
 
-  ## Mask to control the NULL address detection in code for different phases.
-  #  If enabled, accessing NULL address in UEFI or SMM code can be caught.<BR><BR>
-  #    BIT0    - Enable NULL pointer detection for UEFI.<BR>
-  #    BIT1    - Enable NULL pointer detection for SMM.<BR>
-  #    BIT2..5 - Reserved for future uses.<BR>
-  #    BIT6    - Enable non-stop mode.<BR>
-  #    BIT7    - Disable NULL pointer detection just after EndOfDxe. <BR>
-  #              This is a workaround for those unsolvable NULL access issues in
-  #              OptionROM, boot loader, etc. It can also help to avoid unnecessary
-  #              exception caused by legacy memory (0-4095) access after EndOfDxe,
-  #              such as Windows 7 boot on Qemu.<BR>
-  # @Prompt Enable NULL address detection.
-  gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask|0x0|UINT8|0x30001050
-
   ## Init Value in Temp Stack to be shared between SEC and PEI_CORE
   # SEC fills the full temp stack with this values. When switch stack, PeiCore can check
   # this value in the temp stack to know how many stack has been used.
   # @Prompt Init Value in Temp Stack
   gEfiMdeModulePkgTokenSpaceGuid.PcdInitValueInTempStack|0x5AA55AA5|UINT32|0x30001051
 
-  ## Indicates which type allocation need guard page.
-  #
-  # If a bit is set, a head guard page and a tail guard page will be added just
-  # before and after corresponding type of pages allocated if there's enough
-  # free pages for all of them. The page allocation for the type related to
-  # cleared bits keeps the same as ususal.
-  #
-  # This PCD is only valid if BIT0 and/or BIT2 are set in PcdHeapGuardPropertyMask.
-  #
-  # Below is bit mask for this PCD: (Order is same as UEFI spec)<BR>
-  #  EfiReservedMemoryType             0x0000000000000001<BR>
-  #  EfiLoaderCode                     0x0000000000000002<BR>
-  #  EfiLoaderData                     0x0000000000000004<BR>
-  #  EfiBootServicesCode               0x0000000000000008<BR>
-  #  EfiBootServicesData               0x0000000000000010<BR>
-  #  EfiRuntimeServicesCode            0x0000000000000020<BR>
-  #  EfiRuntimeServicesData            0x0000000000000040<BR>
-  #  EfiConventionalMemory             0x0000000000000080<BR>
-  #  EfiUnusableMemory                 0x0000000000000100<BR>
-  #  EfiACPIReclaimMemory              0x0000000000000200<BR>
-  #  EfiACPIMemoryNVS                  0x0000000000000400<BR>
-  #  EfiMemoryMappedIO                 0x0000000000000800<BR>
-  #  EfiMemoryMappedIOPortSpace        0x0000000000001000<BR>
-  #  EfiPalCode                        0x0000000000002000<BR>
-  #  EfiPersistentMemory               0x0000000000004000<BR>
-  #  OEM Reserved                      0x4000000000000000<BR>
-  #  OS Reserved                       0x8000000000000000<BR>
-  # e.g. LoaderCode+LoaderData+BootServicesCode+BootServicesData are needed, 0x1E should be used.<BR>
-  # @Prompt The memory type mask for Page Guard.
-  gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPageType|0x0|UINT64|0x30001052
-
-  ## Indicates which type allocation need guard page.
-  #
-  # If a bit is set, a head guard page and a tail guard page will be added just
-  # before and after corresponding type of pages which the allocated pool occupies,
-  # if there's enough free memory for all of them. The pool allocation for the
-  # type related to cleared bits keeps the same as ususal.
-  #
-  # This PCD is only valid if BIT1 and/or BIT3 are set in PcdHeapGuardPropertyMask.
-  #
-  # Below is bit mask for this PCD: (Order is same as UEFI spec)<BR>
-  #  EfiReservedMemoryType             0x0000000000000001<BR>
-  #  EfiLoaderCode                     0x0000000000000002<BR>
-  #  EfiLoaderData                     0x0000000000000004<BR>
-  #  EfiBootServicesCode               0x0000000000000008<BR>
-  #  EfiBootServicesData               0x0000000000000010<BR>
-  #  EfiRuntimeServicesCode            0x0000000000000020<BR>
-  #  EfiRuntimeServicesData            0x0000000000000040<BR>
-  #  EfiConventionalMemory             0x0000000000000080<BR>
-  #  EfiUnusableMemory                 0x0000000000000100<BR>
-  #  EfiACPIReclaimMemory              0x0000000000000200<BR>
-  #  EfiACPIMemoryNVS                  0x0000000000000400<BR>
-  #  EfiMemoryMappedIO                 0x0000000000000800<BR>
-  #  EfiMemoryMappedIOPortSpace        0x0000000000001000<BR>
-  #  EfiPalCode                        0x0000000000002000<BR>
-  #  EfiPersistentMemory               0x0000000000004000<BR>
-  #  OEM Reserved                      0x4000000000000000<BR>
-  #  OS Reserved                       0x8000000000000000<BR>
-  # e.g. LoaderCode+LoaderData+BootServicesCode+BootServicesData are needed, 0x1E should be used.<BR>
-  # @Prompt The memory type mask for Pool Guard.
-  gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPoolType|0x0|UINT64|0x30001053
-
-  ## This mask is to control Heap Guard behavior.
-  #
-  # Note:
-  #   a) Heap Guard is for debug purpose and should not be enabled in product
-  #      BIOS.
-  #   b) Due to the limit of pool memory implementation and the alignment
-  #      requirement of UEFI spec, BIT7 is a try-best setting which cannot
-  #      guarantee that the returned pool is exactly adjacent to head guard
-  #      page or tail guard page.
-  #   c) UEFI freed-memory guard and UEFI pool/page guard cannot be enabled
-  #      at the same time.
-  #
-  #   BIT0 - Enable UEFI page guard.<BR>
-  #   BIT1 - Enable UEFI pool guard.<BR>
-  #   BIT2 - Enable SMM page guard.<BR>
-  #   BIT3 - Enable SMM pool guard.<BR>
-  #   BIT4 - Enable UEFI freed-memory guard (Use-After-Free memory detection).<BR>
-  #   BIT6 - Enable non-stop mode.<BR>
-  #   BIT7 - The direction of Guard Page for Pool Guard.
-  #          0 - The returned pool is near the tail guard page.<BR>
-  #          1 - The returned pool is near the head guard page.<BR>
-  # @Prompt The Heap Guard feature mask
-  gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask|0x0|UINT8|0x30001054
-
-  ## Indicates if UEFI Stack Guard will be enabled.
-  #  If enabled, stack overflow in UEFI can be caught, preventing chaotic consequences.<BR><BR>
-  #   TRUE  - UEFI Stack Guard will be enabled.<BR>
-  #   FALSE - UEFI Stack Guard will be disabled.<BR>
-  # @Prompt Enable UEFI Stack Guard.
-  gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard|FALSE|BOOLEAN|0x30001055
-
   ## Indicate debug level of Trace Hub.
   #   0x0 - TraceHubDebugLevelError.<BR>
   #   0x1 - TraceHubDebugLevelErrorWarning.<BR>
@@ -1395,54 +1288,6 @@
   # @Prompt Memory profile driver path.
   gEfiMdeModulePkgTokenSpaceGuid.PcdMemoryProfileDriverPath|{0x0}|VOID*|0x00001043
 
-  ## Set image protection policy. The policy is bitwise.
-  #  If a bit is set, the image will be protected by DxeCore if it is aligned.
-  #   The code section becomes read-only, and the data section becomes non-executable.
-  #  If a bit is clear, nothing will be done to image code/data sections.<BR><BR>
-  #    BIT0       - Image from unknown device. <BR>
-  #    BIT1       - Image from firmware volume.<BR>
-  #  <BR>
-  #  Note: If a bit is cleared, the data section could be still non-executable if
-  #  PcdDxeNxMemoryProtectionPolicy is enabled for EfiLoaderData, EfiBootServicesData
-  #  and/or EfiRuntimeServicesData.<BR>
-  #  <BR>
-  # @Prompt Set image protection policy.
-  # @ValidRange 0x80000002 | 0x00000000 - 0x0000001F
-  gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x00000002|UINT32|0x00001047
-
-  ## Set DXE memory protection policy. The policy is bitwise.
-  #  If a bit is set, memory regions of the associated type will be mapped
-  #  non-executable.<BR>
-  #  If a bit is cleared, nothing will be done to associated type of memory.<BR>
-  #  <BR>
-  # Below is bit mask for this PCD: (Order is same as UEFI spec)<BR>
-  #  EfiReservedMemoryType          0x0001<BR>
-  #  EfiLoaderCode                  0x0002<BR>
-  #  EfiLoaderData                  0x0004<BR>
-  #  EfiBootServicesCode            0x0008<BR>
-  #  EfiBootServicesData            0x0010<BR>
-  #  EfiRuntimeServicesCode         0x0020<BR>
-  #  EfiRuntimeServicesData         0x0040<BR>
-  #  EfiConventionalMemory          0x0080<BR>
-  #  EfiUnusableMemory              0x0100<BR>
-  #  EfiACPIReclaimMemory           0x0200<BR>
-  #  EfiACPIMemoryNVS               0x0400<BR>
-  #  EfiMemoryMappedIO              0x0800<BR>
-  #  EfiMemoryMappedIOPortSpace     0x1000<BR>
-  #  EfiPalCode                     0x2000<BR>
-  #  EfiPersistentMemory            0x4000<BR>
-  #  OEM Reserved       0x4000000000000000<BR>
-  #  OS Reserved        0x8000000000000000<BR>
-  #
-  # NOTE: User must NOT set NX protection for EfiLoaderCode / EfiBootServicesCode / EfiRuntimeServicesCode. <BR>
-  #       User MUST set the same NX protection for EfiBootServicesData and EfiConventionalMemory. <BR>
-  #
-  # e.g. 0x7FD5 can be used for all memory except Code. <BR>
-  # e.g. 0x7BD4 can be used for all memory except Code and ACPINVS/Reserved. <BR>
-  #
-  # @Prompt Set DXE memory protection policy.
-  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0x0000000|UINT64|0x00001048
-
   ## PCI Serial Device Info. It is an array of Device, Function, and Power Management
   #  information that describes the path that contains zero or more PCI to PCI bridges
   #  followed by a PCI serial device.  Each array entry is 4-bytes in length.  The
@@ -2031,20 +1876,6 @@
   # @Prompt Default Creator Revision for ACPI table creation.
   gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision|0x01000013|UINT32|0x30001038
 
-  ## Indicates if to set NX for stack.<BR><BR>
-  #  For the DxeIpl and the DxeCore are both X64, set NX for stack feature also require PcdDxeIplBuildPageTables be TRUE.<BR>
-  #  For the DxeIpl and the DxeCore are both IA32 (PcdDxeIplSwitchToLongMode is FALSE), set NX for stack feature also require
-  #  IA32 PAE is supported and Execute Disable Bit is available.<BR>
-  #  <BR>
-  #   TRUE  - Set NX for stack.<BR>
-  #   FALSE - Do nothing for stack.<BR>
-  #  <BR>
-  #  Note: If this PCD is set to FALSE, NX could be still applied to stack due to PcdDxeNxMemoryProtectionPolicy enabled for
-  #  EfiBootServicesData.<BR>
-  #  <BR>
-  # @Prompt Set NX for stack.
-  gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack|FALSE|BOOLEAN|0x0001006f
-
   ## This PCD specifies the PCI-based SD/MMC host controller mmio base address.
   # Define the mmio base address of the pci-based SD/MMC host controller. If there are multiple SD/MMC
   # host controllers, their mmio base addresses are calculated one by one from this base address.
diff --git a/MdeModulePkg/MdeModulePkg.uni b/MdeModulePkg/MdeModulePkg.uni
index a17d34d60b..afbbc44761 100644
--- a/MdeModulePkg/MdeModulePkg.uni
+++ b/MdeModulePkg/MdeModulePkg.uni
@@ -330,16 +330,6 @@
 
 #string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdSerialRegisterStride_HELP  #language en-US "The number of bytes between registers in serial device.  The default is 1 byte."
 
-#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdSetNxForStack_PROMPT  #language en-US "Set NX for stack"
-
-#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdSetNxForStack_HELP  #language en-US "Indicates if to set NX for stack.<BR><BR>"
-                                                                                  "For the DxeIpl and the DxeCore are both X64, set NX for stack feature also require PcdDxeIplBuildPageTables be TRUE.<BR>"
-                                                                                  "For the DxeIpl and the DxeCore are both IA32 (PcdDxeIplSwitchToLongMode is FALSE), set NX for stack feature also require"
-                                                                                  "IA32 PAE is supported and Execute Disable Bit is available.<BR>"
-                                                                                  "TRUE  - Set NX for stack.<BR>"
-                                                                                  "FALSE - Do nothing for stack.<BR>"
-                                                                                  "Note: If this PCD is set to FALSE, NX could be still applied to stack due to PcdDxeNxMemoryProtectionPolicy enabled for EfiBootServicesData.<BR>"
-
 #string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdAcpiS3Enable_PROMPT  #language en-US "ACPI S3 Enable"
 
 #string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdAcpiS3Enable_HELP  #language en-US "Indicates if ACPI S3 will be enabled.<BR><BR>"
@@ -1096,51 +1086,6 @@
 #string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdSmiHandlerProfilePropertyMask_HELP  #language en-US "The mask is used to control SmiHandlerProfile behavior.<BR><BR>\n"
                                                                                                   "BIT0 - Enable SmiHandlerProfile.<BR>"
 
-#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdImageProtectionPolicy_PROMPT  #language en-US "Set image protection policy."
-
-#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdImageProtectionPolicy_HELP  #language en-US "Set image protection policy. The policy is bitwise.\n"
-                                                                                          "If a bit is set, the image will be protected by DxeCore if it is aligned.\n"
-                                                                                          "The code section becomes read-only, and the data section becomes non-executable.\n"
-                                                                                          "If a bit is clear, nothing will be done to image code/data sections.<BR><BR>\n"
-                                                                                          "BIT0       - Image from unknown device. <BR>\n"
-                                                                                          "BIT1       - Image from firmware volume.<BR>"
-                                                                                          "Note: If a bit is cleared, the data section could be still non-executable if\n"
-                                                                                          "PcdDxeNxMemoryProtectionPolicy is enabled for EfiLoaderData, EfiBootServicesData\n"
-                                                                                          "and/or EfiRuntimeServicesData.<BR>"
-
-#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdDxeNxMemoryProtectionPolicy_PROMPT  #language en-US "Set DXE memory protection policy."
-
-#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdDxeNxMemoryProtectionPolicy_HELP  #language en-US "Set DXE memory protection policy. The policy is bitwise.\n"
-                                                                                                "If a bit is set, memory regions of the associated type will be mapped\n"
-                                                                                                "non-executable.<BR>\n"
-                                                                                                "If a bit is cleared, nothing will be done to associated type of memory.<BR><BR>\n"
-                                                                                                "\n"
-                                                                                                "Below is bit mask for this PCD: (Order is same as UEFI spec)<BR>\n"
-                                                                                                "EfiReservedMemoryType          0x0001<BR>\n"
-                                                                                                "EfiLoaderCode                  0x0002<BR>\n"
-                                                                                                "EfiLoaderData                  0x0004<BR>\n"
-                                                                                                "EfiBootServicesCode            0x0008<BR>\n"
-                                                                                                "EfiBootServicesData            0x0010<BR>\n"
-                                                                                                "EfiRuntimeServicesCode         0x0020<BR>\n"
-                                                                                                "EfiRuntimeServicesData         0x0040<BR>\n"
-                                                                                                "EfiConventionalMemory          0x0080<BR>\n"
-                                                                                                "EfiUnusableMemory              0x0100<BR>\n"
-                                                                                                "EfiACPIReclaimMemory           0x0200<BR>\n"
-                                                                                                "EfiACPIMemoryNVS               0x0400<BR>\n"
-                                                                                                "EfiMemoryMappedIO              0x0800<BR>\n"
-                                                                                                "EfiMemoryMappedIOPortSpace     0x1000<BR>\n"
-                                                                                                "EfiPalCode                     0x2000<BR>\n"
-                                                                                                "EfiPersistentMemory            0x4000<BR>\n"
-                                                                                                "OEM Reserved       0x4000000000000000<BR>\n"
-                                                                                                "OS Reserved        0x8000000000000000<BR>\n"
-                                                                                                "\n"
-                                                                                                "NOTE: User must NOT set NX protection for EfiLoaderCode / EfiBootServicesCode / EfiRuntimeServicesCode. <BR>\n"
-                                                                                                "User MUST set the same NX protection for EfiBootServicesData and EfiConventionalMemory. <BR>\n"
-                                                                                                "\n"
-                                                                                                "e.g. 0x7FD5 can be used for all memory except Code. <BR>\n"
-                                                                                                "e.g. 0x7BD4 can be used for all memory except Code and ACPINVS/Reserved. <BR>\n"
-                                                                                                ""
-
 #string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdPteMemoryEncryptionAddressOrMask_PROMPT  #language en-US "The address mask when memory encryption is enabled."
 
 #string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdPteMemoryEncryptionAddressOrMask_HELP  #language en-US "This PCD holds the address mask for page table entries when memory encryption is\n"
@@ -1186,110 +1131,12 @@
 #string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdCodRelocationDevPath_HELP  #language en-US   "Full device path of platform specific device to store Capsule On Disk temp relocation file.<BR>"
                                                                                            "If this PCD is set, Capsule On Disk temp relocation file will be stored in the device specified by this PCD, instead of the EFI System Partition that stores capsule image file."
 
-#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdNullPointerDetectionPropertyMask_PROMPT  #language en-US "Enable NULL pointer detection"
-
-#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdNullPointerDetectionPropertyMask_HELP    #language en-US "Mask to control the NULL address detection in code for different phases.\n"
-                                                                                                       " If enabled, accessing NULL address in UEFI or SMM code can be caught.\n\n"
-                                                                                                       "   BIT0    - Enable NULL pointer detection for UEFI.\n"
-                                                                                                       "   BIT1    - Enable NULL pointer detection for SMM.\n"
-                                                                                                       "   BIT2..6 - Reserved for future uses.\n"
-                                                                                                       "   BIT7    - Disable NULL pointer detection just after EndOfDxe."
-                                                                                                       " This is a workaround for those unsolvable NULL access issues in"
-                                                                                                       " OptionROM, boot loader, etc. It can also help to avoid unnecessary"
-                                                                                                       " exception caused by legacy memory (0-4095) access after EndOfDxe,"
-                                                                                                       " such as Windows 7 boot on Qemu.\n"
-
 #string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdInitValueInTempStack_PROMPT  #language en-US "Init Value in Temp Stack"
 
 #string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdInitValueInTempStack_HELP    #language en-US "Init Value in Temp Stack to be shared between SEC and PEI_CORE\n"
                                                                                            "SEC fills the full temp stack with this values. When switch stack, PeiCore can check\n"
                                                                                            "this value in the temp stack to know how many stack has been used.\n"
 
-#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdHeapGuardPageType_PROMPT  #language en-US "The memory type mask for Page Guard"
-
-#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdHeapGuardPageType_HELP    #language en-US "Indicates which type allocation need guard page.\n\n"
-                                                                                        " If a bit is set, a head guard page and a tail guard page will be added just\n"
-                                                                                        " before and after corresponding type of pages allocated if there's enough\n"
-                                                                                        " free pages for all of them. The page allocation for the type related to\n"
-                                                                                        " cleared bits keeps the same as ususal.\n\n"
-                                                                                        " This PCD is only valid if BIT0 and/or BIT2 are set in PcdHeapGuardPropertyMask.\n\n"
-                                                                                        " Below is bit mask for this PCD: (Order is same as UEFI spec)<BR>\n"
-                                                                                        "  EfiReservedMemoryType             0x0000000000000001\n"
-                                                                                        "  EfiLoaderCode                     0x0000000000000002\n"
-                                                                                        "  EfiLoaderData                     0x0000000000000004\n"
-                                                                                        "  EfiBootServicesCode               0x0000000000000008\n"
-                                                                                        "  EfiBootServicesData               0x0000000000000010\n"
-                                                                                        "  EfiRuntimeServicesCode            0x0000000000000020\n"
-                                                                                        "  EfiRuntimeServicesData            0x0000000000000040\n"
-                                                                                        "  EfiConventionalMemory             0x0000000000000080\n"
-                                                                                        "  EfiUnusableMemory                 0x0000000000000100\n"
-                                                                                        "  EfiACPIReclaimMemory              0x0000000000000200\n"
-                                                                                        "  EfiACPIMemoryNVS                  0x0000000000000400\n"
-                                                                                        "  EfiMemoryMappedIO                 0x0000000000000800\n"
-                                                                                        "  EfiMemoryMappedIOPortSpace        0x0000000000001000\n"
-                                                                                        "  EfiPalCode                        0x0000000000002000\n"
-                                                                                        "  EfiPersistentMemory               0x0000000000004000\n"
-                                                                                        "  OEM Reserved                      0x4000000000000000\n"
-                                                                                        "  OS Reserved                       0x8000000000000000\n"
-                                                                                        " e.g. LoaderCode+LoaderData+BootServicesCode+BootServicesData are needed, 0x1E should be used.<BR>"
-
-#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdHeapGuardPoolType_PROMPT  #language en-US "The memory type mask for Pool Guard"
-
-#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdHeapGuardPoolType_HELP    #language en-US "Indicates which type allocation need guard page.\n\n"
-                                                                                        " If a bit is set, a head guard page and a tail guard page will be added just\n"
-                                                                                        " before and after corresponding type of pages which the allocated pool occupies,\n"
-                                                                                        " if there's enough free memory for all of them. The pool allocation for the\n"
-                                                                                        " type related to cleared bits keeps the same as ususal.\n\n"
-                                                                                        " This PCD is only valid if BIT1 and/or BIT3 are set in PcdHeapGuardPropertyMask.\n\n"
-                                                                                        " Below is bit mask for this PCD: (Order is same as UEFI spec)<BR>\n"
-                                                                                        "  EfiReservedMemoryType             0x0000000000000001\n"
-                                                                                        "  EfiLoaderCode                     0x0000000000000002\n"
-                                                                                        "  EfiLoaderData                     0x0000000000000004\n"
-                                                                                        "  EfiBootServicesCode               0x0000000000000008\n"
-                                                                                        "  EfiBootServicesData               0x0000000000000010\n"
-                                                                                        "  EfiRuntimeServicesCode            0x0000000000000020\n"
-                                                                                        "  EfiRuntimeServicesData            0x0000000000000040\n"
-                                                                                        "  EfiConventionalMemory             0x0000000000000080\n"
-                                                                                        "  EfiUnusableMemory                 0x0000000000000100\n"
-                                                                                        "  EfiACPIReclaimMemory              0x0000000000000200\n"
-                                                                                        "  EfiACPIMemoryNVS                  0x0000000000000400\n"
-                                                                                        "  EfiMemoryMappedIO                 0x0000000000000800\n"
-                                                                                        "  EfiMemoryMappedIOPortSpace        0x0000000000001000\n"
-                                                                                        "  EfiPalCode                        0x0000000000002000\n"
-                                                                                        "  EfiPersistentMemory               0x0000000000004000\n"
-                                                                                        "  OEM Reserved                      0x4000000000000000\n"
-                                                                                        "  OS Reserved                       0x8000000000000000\n"
-                                                                                        " e.g. LoaderCode+LoaderData+BootServicesCode+BootServicesData are needed, 0x1E should be used.<BR>"
-
-
-#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdHeapGuardPropertyMask_PROMPT  #language en-US "The Heap Guard feature mask"
-
-#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdHeapGuardPropertyMask_HELP    #language en-US "This mask is to control Heap Guard behavior.\n"
-                                                                                            " Note:\n"
-                                                                                            "   a) Heap Guard is for debug purpose and should not be enabled in product"
-                                                                                            "      BIOS.\n"
-                                                                                            "   b) Due to the limit of pool memory implementation and the alignment"
-                                                                                            "      requirement of UEFI spec, BIT7 is a try-best setting which cannot"
-                                                                                            "      guarantee that the returned pool is exactly adjacent to head guard"
-                                                                                            "      page or tail guard page.\n"
-                                                                                            "   c) UEFI freed-memory guard and UEFI pool/page guard cannot be enabled"
-                                                                                            "      at the same time.\n"
-                                                                                            "   BIT0 - Enable UEFI page guard.<BR>\n"
-                                                                                            "   BIT1 - Enable UEFI pool guard.<BR>\n"
-                                                                                            "   BIT2 - Enable SMM page guard.<BR>\n"
-                                                                                            "   BIT3 - Enable SMM pool guard.<BR>\n"
-                                                                                            "   BIT4 - Enable UEFI freed-memory guard (Use-After-Free memory detection).<BR>\n"
-                                                                                            "   BIT7 - The direction of Guard Page for Pool Guard.\n"
-                                                                                            "          0 - The returned pool is near the tail guard page.<BR>\n"
-                                                                                            "          1 - The returned pool is near the head guard page.<BR>"
-
-#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdCpuStackGuard_PROMPT  #language en-US "Enable UEFI Stack Guard"
-
-#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdCpuStackGuard_HELP    #language en-US "Indicates if UEFI Stack Guard will be enabled.\n"
-                                                                                    "  If enabled, stack overflow in UEFI can be caught, preventing chaotic consequences.<BR><BR>\n"
-                                                                                    "   TRUE  - UEFI Stack Guard will be enabled.<BR>\n"
-                                                                                    "   FALSE - UEFI Stack Guard will be disabled.<BR>"
-
 #string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdTraceHubDebugLevel_PROMPT  #language en-US "Debug level of Trace Hub."
 
 #string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdTraceHubDebugLevel_HELP    #language en-US "Indicate debug level of Trace Hub"
-- 
2.41.0.windows.2


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: [edk2-devel] [PATCH 14/14] MdeModulePkg: Delete Memory Protection PCDs
       [not found] ` <1770F551E2E594C0.16575@groups.io>
@ 2023-07-12  0:01   ` Taylor Beebe
  0 siblings, 0 replies; 24+ messages in thread
From: Taylor Beebe @ 2023-07-12  0:01 UTC (permalink / raw)
  To: devel; +Cc: Ard Biesheuvel, Leif Lindholm, Sami Mujawar, Gerd Hoffmann

Looks like the title of this patch in the series was mixed up
with the title of the following patch. I'll wait for feedback
before sending out a v2, but the title of this patch
should be:

[PATCH 13/14] ArmVirtPkg: Delete Memory Protection PCDs

On 7/11/2023 4:52 PM, Taylor Beebe via groups.io wrote:
> From: Taylor Beebe <tabeebe@microsoft.com>
> 
> Now that references in the rest of the codebase have been updated
> to reference the memory protection HOB, delete the memory protection PCDs.
> 
> Signed-off-by: Taylor Beebe <t@taylorbeebe.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Leif Lindholm <quic_llindhol@quicinc.com>
> Cc: Sami Mujawar <sami.mujawar@arm.com>
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> ---
>   ArmVirtPkg/ArmVirt.dsc.inc    | 15 ---------------
>   ArmVirtPkg/ArmVirtCloudHv.dsc |  5 -----
>   ArmVirtPkg/ArmVirtQemu.dsc    |  5 -----
>   3 files changed, 25 deletions(-)
> 
> diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc
> index 3174b19e51..e1eb189077 100644
> --- a/ArmVirtPkg/ArmVirt.dsc.inc
> +++ b/ArmVirtPkg/ArmVirt.dsc.inc
> @@ -363,21 +363,6 @@
>     gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode|20
>     gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData|0
>   
> -  #
> -  # Enable strict image permissions for all images. (This applies
> -  # only to images that were built with >= 4 KB section alignment.)
> -  #
> -  gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x3
> -
> -  #
> -  # Enable NX memory protection for all non-code regions, including OEM and OS
> -  # reserved ones, with the exception of LoaderData regions, of which OS loaders
> -  # (i.e., GRUB) may assume that its contents are executable.
> -  #
> -  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xC000000000007FD5
> -
> -  gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard|TRUE
> -
>   [Components.common]
>     #
>     # Ramdisk support
> diff --git a/ArmVirtPkg/ArmVirtCloudHv.dsc b/ArmVirtPkg/ArmVirtCloudHv.dsc
> index c975e139a2..c4c3e0da44 100644
> --- a/ArmVirtPkg/ArmVirtCloudHv.dsc
> +++ b/ArmVirtPkg/ArmVirtCloudHv.dsc
> @@ -140,11 +140,6 @@
>     #
>     gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|16
>   
> -  #
> -  # Enable the non-executable DXE stack. (This gets set up by DxeIpl)
> -  #
> -  gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack|TRUE
> -
>   !if $(SECURE_BOOT_ENABLE) == TRUE
>     # override the default values from SecurityPkg to ensure images from all sources are verified in secure boot
>     gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy|0x04
> diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc
> index 1e0225951a..214e08b789 100644
> --- a/ArmVirtPkg/ArmVirtQemu.dsc
> +++ b/ArmVirtPkg/ArmVirtQemu.dsc
> @@ -212,11 +212,6 @@
>     #
>     gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|16
>   
> -  #
> -  # Enable the non-executable DXE stack. (This gets set up by DxeIpl)
> -  #
> -  gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack|TRUE
> -
>   !if $(SECURE_BOOT_ENABLE) == TRUE
>     # override the default values from SecurityPkg to ensure images from all sources are verified in secure boot
>     gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy|0x04

-- 
Taylor Beebe
Software Engineer @ Microsoft

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 00/14] Implement Dynamic Memory Protections
  2023-07-11 23:52 [PATCH 00/14] Implement Dynamic Memory Protections Taylor Beebe
                   ` (14 preceding siblings ...)
       [not found] ` <1770F551E2E594C0.16575@groups.io>
@ 2023-07-12 10:05 ` Gerd Hoffmann
  2023-07-12 21:54   ` Taylor Beebe
  2023-07-17 16:15 ` Pedro Falcato
  16 siblings, 1 reply; 24+ messages in thread
From: Gerd Hoffmann @ 2023-07-12 10:05 UTC (permalink / raw)
  To: Taylor Beebe
  Cc: devel, Jian J Wang, Liming Gao, Dandan Bi, Ard Biesheuvel,
	Jiewen Yao, Jordan Justen, Leif Lindholm, Sami Mujawar,
	Andrew Fish, Ray Ni, Eric Dong, Rahul Kumar, Guo Dong,
	Sean Rhodes, James Lu, Gua Guo

On Tue, Jul 11, 2023 at 04:52:37PM -0700, Taylor Beebe wrote:
> In the past, memory protection settings were configured via FixedAtBuild PCDs,
> which resulted in a build-time configuration of memory mitigations. This
> approach limited the flexibility of applying mitigations to the
> system and made it difficult to update or adjust the settings post-build.

Can we have both?

Being able to adjust settings at runtime is great.  But being able to
set them at compile time on the command line (via build --pcd), without
patching code, is very useful too.

I'd suggest to keep the PCDs, create a profile from PCD settings and use
that profile by default.  At least for the transition phase and while we
don't have good support (yet) to actually manage profiles.

Speaking of profile management: What is the longer-term vision here?

Have a configuration form in the uefi firmware setup (aka UiApp)?

Try adapt settings automatically, for example pick a less strict profile
in case an old/broken bootloader triggers a page fault due to using the
wrong memory type for allocations?

For virtual machine firmware it a good idea to allow picking up the
profile configuration from the host.  For qemu that can use fw_cfg,
similar to the PcdSetNxForStack option we have today.

> This patch series also increases the memory protection level for OvmfPkg and
> ArmVirtPkg.

Not a good idea, especially not using the 'debug' profile (which turns
on all guard bits) because that slows down firmware boot alot.

take care,
  Gerd


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 00/14] Implement Dynamic Memory Protections
  2023-07-12 10:05 ` [PATCH 00/14] Implement Dynamic Memory Protections Gerd Hoffmann
@ 2023-07-12 21:54   ` Taylor Beebe
  2023-07-17 11:14     ` [edk2-devel] " Gerd Hoffmann
  0 siblings, 1 reply; 24+ messages in thread
From: Taylor Beebe @ 2023-07-12 21:54 UTC (permalink / raw)
  To: Gerd Hoffmann
  Cc: devel, Jian J Wang, Liming Gao, Dandan Bi, Ard Biesheuvel,
	Jiewen Yao, Jordan Justen, Leif Lindholm, Sami Mujawar,
	Andrew Fish, Ray Ni, Eric Dong, Rahul Kumar, Guo Dong,
	Sean Rhodes, James Lu, Gua Guo



On 7/12/2023 3:05 AM, Gerd Hoffmann wrote:
> On Tue, Jul 11, 2023 at 04:52:37PM -0700, Taylor Beebe wrote:
>> In the past, memory protection settings were configured via FixedAtBuild PCDs,
>> which resulted in a build-time configuration of memory mitigations. This
>> approach limited the flexibility of applying mitigations to the
>> system and made it difficult to update or adjust the settings post-build.
> 
> Can we have both?
> 
> Being able to adjust settings at runtime is great.  But being able to
> set them at compile time on the command line (via build --pcd), without
> patching code, is very useful too.
> 
> I'd suggest to keep the PCDs, create a profile from PCD settings and use
> that profile by default.  At least for the transition phase and while we
> don't have good support (yet) to actually manage profiles.
> 

Hey, Gerd.

The idea to keep PCDs around as another method of configuring 
protections is good, but I don't think there would be a way to tell if a 
zero-ed PCD value was an explicit setting or just the default without 
adding another PCD to indicate which value should be used. I think if 
the HOB is produced by the platform those settings should be used by 
default. Is that what you're envisioning as well?

The flow in this case would be: DxeIpl before handoff will search for 
the memory protection HOB entry. If it exists, do nothing. If the HOB 
was not produced, create a HOB entry using the PCD values.

I suppose we could also do some sort of hybrid where the logic always 
uses the PCD values if they are non-zero, but that may be confusing for 
platform developers.

> Speaking of profile management: What is the longer-term vision here?
> 
> Have a configuration form in the uefi firmware setup (aka UiApp)?
> 
> Try adapt settings automatically, for example pick a less strict profile
> in case an old/broken bootloader triggers a page fault due to using the
> wrong memory type for allocations?
> 

Overall, the idea is to empower platform developers with more 
configuration and compatibility options to encourage the use of memory 
protections in debug and production scenarios.

On Surface products, we've made certain memory protections a necessary 
feature of the trusted boot path with the ability to fall back to an 
unverified boot path if a page fault occurs. We also added a 
configuration feature to only allow the trusted boot path which can be 
managed via enterprise policy or through the UEFI menu.

There are lots of ways OEMs might want to configure their platform 
security and I think it's an open question what sorts of profile 
management tools would be useful to add to EDK2.

> For virtual machine firmware it a good idea to allow picking up the
> profile configuration from the host.  For qemu that can use fw_cfg,
> similar to the PcdSetNxForStack option we have today.

I don't have much experience using the fw_cfg so I'd need to look into 
the details, but would it make sense to expand the options which can be 
passed via fw_cfg to be the gamut of memory protection configuration 
settings? I can add it to the v2 if you think so.

>> This patch series also increases the memory protection level for OvmfPkg and
>> ArmVirtPkg.
> 
> Not a good idea, especially not using the 'debug' profile (which turns
> on all guard bits) because that slows down firmware boot alot.
> 

I haven't done performance testing, but I don't notice much slowdown. 
Isn't development the primary use case for these virtual platforms? Is 
there another profile you think would work better?

Thanks for your feedback :)

> take care,
>    Gerd
> 

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [edk2-devel] [PATCH 00/14] Implement Dynamic Memory Protections
  2023-07-12 21:54   ` Taylor Beebe
@ 2023-07-17 11:14     ` Gerd Hoffmann
  0 siblings, 0 replies; 24+ messages in thread
From: Gerd Hoffmann @ 2023-07-17 11:14 UTC (permalink / raw)
  To: Taylor Beebe
  Cc: devel, Jian J Wang, Liming Gao, Dandan Bi, Ard Biesheuvel,
	Jiewen Yao, Jordan Justen, Leif Lindholm, Sami Mujawar,
	Andrew Fish, Ray Ni, Eric Dong, Rahul Kumar, Guo Dong,
	Sean Rhodes, James Lu, Gua Guo

  Hi,

> > Can we have both?
> > 
> > Being able to adjust settings at runtime is great.  But being able to
> > set them at compile time on the command line (via build --pcd), without
> > patching code, is very useful too.
> > 
> > I'd suggest to keep the PCDs, create a profile from PCD settings and use
> > that profile by default.  At least for the transition phase and while we
> > don't have good support (yet) to actually manage profiles.
> 
> Hey, Gerd.
> 
> The idea to keep PCDs around as another method of configuring protections is
> good, but I don't think there would be a way to tell if a zero-ed PCD value
> was an explicit setting or just the default without adding another PCD to
> indicate which value should be used. I think if the HOB is produced by the
> platform those settings should be used by default. Is that what you're
> envisioning as well?

See below, I'll come back to that in a moment.

> > Speaking of profile management: What is the longer-term vision here?

> There are lots of ways OEMs might want to configure their platform security
> and I think it's an open question what sorts of profile management tools
> would be useful to add to EDK2.

I think it makes sense to have the concept of named profiles in edk2.
Right now there are a bunch of #defines with profiles, I think it would
be nice to have names and descriptions attached to them.  Could be as
simple as an array in the library:

struct {
   CHAR16 *Name;
   CHAR16 *Description;
   DXE_MEMORY_PROTECTION_SETTINGS Settings;
} MemoryProtectionProfiles[] = {
   {
      .Name        = "debug",
      .Description = "development profile",
      .Settings    = DXE_MEMORY_PROTECTION_SETTINGS_DEBUG,
   },{
      /* ... */
   }
}

Platforms could just loop over the list and add the profiles to the
platform configuration menu in uefi firmware settings.  Maybe it makes
sense to have a MemoryProtectionConfigDxe instead so platforms can
easily share the Hii code for that.

One of the profiles could be created from PCDs:

    {
	.Name               = "pcd",
	.Description        = "legacy PCD based settings",
	.Settings.PoolGuard = PcdGetU32(PcdHeapGuardPoolType),
        /* ... */
    }

> > For virtual machine firmware it a good idea to allow picking up the
> > profile configuration from the host.  For qemu that can use fw_cfg,
> > similar to the PcdSetNxForStack option we have today.
> 
> I don't have much experience using the fw_cfg so I'd need to look into the
> details, but would it make sense to expand the options which can be passed
> via fw_cfg to be the gamut of memory protection configuration settings?

I think being able to select a named profile is good enough, for example
this way:

qemu -fw_cfg name=opt/org.tianocore/MemoryProtectionProfile,string=debug

> > > This patch series also increases the memory protection level for OvmfPkg and
> > > ArmVirtPkg.
> > 
> > Not a good idea, especially not using the 'debug' profile (which turns
> > on all guard bits) because that slows down firmware boot alot.
> 
> I haven't done performance testing, but I don't notice much slowdown.

Page guard isn't much of a problem.

Heap guard has significant overhead in both performance and memory
usage.

> Isn't development the primary use case for these virtual platforms?

Development is surely one important use case   Linux-based VM hosting
often runs OVMF in production though.

> Is there
> another profile you think would work better?

"pcd" (or "production") would IMHO be a better default.

thanks & take care,
  Gerd



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#106963): https://edk2.groups.io/g/devel/message/106963
Mute This Topic: https://groups.io/mt/100090629/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [edk2-devel] [PATCH 00/14] Implement Dynamic Memory Protections
  2023-07-11 23:52 [PATCH 00/14] Implement Dynamic Memory Protections Taylor Beebe
                   ` (15 preceding siblings ...)
  2023-07-12 10:05 ` [PATCH 00/14] Implement Dynamic Memory Protections Gerd Hoffmann
@ 2023-07-17 16:15 ` Pedro Falcato
  2023-07-17 16:25   ` Ard Biesheuvel
  16 siblings, 1 reply; 24+ messages in thread
From: Pedro Falcato @ 2023-07-17 16:15 UTC (permalink / raw)
  To: devel, t
  Cc: Jian J Wang, Liming Gao, Dandan Bi, Ard Biesheuvel, Jiewen Yao,
	Jordan Justen, Gerd Hoffmann, Leif Lindholm, Sami Mujawar,
	Andrew Fish, Ray Ni, Eric Dong, Rahul Kumar, Guo Dong,
	Sean Rhodes, James Lu, Gua Guo

On Wed, Jul 12, 2023 at 12:53 AM Taylor Beebe <t@taylorbeebe.com> wrote:
>
> In the past, memory protection settings were configured via FixedAtBuild PCDs,
> which resulted in a build-time configuration of memory mitigations. This
> approach limited the flexibility of applying mitigations to the
> system and made it difficult to update or adjust the settings post-build.

How do you mitigate the possibility of an attack overwriting the
dynamic configuration data (the HOBs)?
It seems most dangerous to me to publish this sort of
security-sensitive configuration knobs dynamically such that an
attacker can change them.

-- 
Pedro


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#106965): https://edk2.groups.io/g/devel/message/106965
Mute This Topic: https://groups.io/mt/100090629/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [edk2-devel] [PATCH 00/14] Implement Dynamic Memory Protections
  2023-07-17 16:15 ` Pedro Falcato
@ 2023-07-17 16:25   ` Ard Biesheuvel
  2023-07-17 16:49     ` Pedro Falcato
  2023-07-18  6:11     ` Ni, Ray
  0 siblings, 2 replies; 24+ messages in thread
From: Ard Biesheuvel @ 2023-07-17 16:25 UTC (permalink / raw)
  To: Pedro Falcato
  Cc: devel, t, Jian J Wang, Liming Gao, Dandan Bi, Ard Biesheuvel,
	Jiewen Yao, Jordan Justen, Gerd Hoffmann, Leif Lindholm,
	Sami Mujawar, Andrew Fish, Ray Ni, Eric Dong, Rahul Kumar,
	Guo Dong, Sean Rhodes, James Lu, Gua Guo

On Mon, 17 Jul 2023 at 18:15, Pedro Falcato <pedro.falcato@gmail.com> wrote:
>
> On Wed, Jul 12, 2023 at 12:53 AM Taylor Beebe <t@taylorbeebe.com> wrote:
> >
> > In the past, memory protection settings were configured via FixedAtBuild PCDs,
> > which resulted in a build-time configuration of memory mitigations. This
> > approach limited the flexibility of applying mitigations to the
> > system and made it difficult to update or adjust the settings post-build.
>
> How do you mitigate the possibility of an attack overwriting the
> dynamic configuration data (the HOBs)?
> It seems most dangerous to me to publish this sort of
> security-sensitive configuration knobs dynamically such that an
> attacker can change them.
>

That is a very good point. One of the things I have on my TODO list
for the memory attributes PEI work is to remap HOB memory read-only
before entering DXE. They are conceptually read-only anyway when PEI
completes, so they should never be modified afterwards.


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#106966): https://edk2.groups.io/g/devel/message/106966
Mute This Topic: https://groups.io/mt/100090629/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [edk2-devel] [PATCH 00/14] Implement Dynamic Memory Protections
  2023-07-17 16:25   ` Ard Biesheuvel
@ 2023-07-17 16:49     ` Pedro Falcato
  2023-07-18  2:45       ` Taylor Beebe
  2023-07-18  6:11     ` Ni, Ray
  1 sibling, 1 reply; 24+ messages in thread
From: Pedro Falcato @ 2023-07-17 16:49 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: devel, t, Jian J Wang, Liming Gao, Dandan Bi, Ard Biesheuvel,
	Jiewen Yao, Jordan Justen, Gerd Hoffmann, Leif Lindholm,
	Sami Mujawar, Andrew Fish, Ray Ni, Eric Dong, Rahul Kumar,
	Guo Dong, Sean Rhodes, James Lu, Gua Guo

On Mon, Jul 17, 2023 at 5:26 PM Ard Biesheuvel <ardb@kernel.org> wrote:
>
> On Mon, 17 Jul 2023 at 18:15, Pedro Falcato <pedro.falcato@gmail.com> wrote:
> >
> > On Wed, Jul 12, 2023 at 12:53 AM Taylor Beebe <t@taylorbeebe.com> wrote:
> > >
> > > In the past, memory protection settings were configured via FixedAtBuild PCDs,
> > > which resulted in a build-time configuration of memory mitigations. This
> > > approach limited the flexibility of applying mitigations to the
> > > system and made it difficult to update or adjust the settings post-build.
> >
> > How do you mitigate the possibility of an attack overwriting the
> > dynamic configuration data (the HOBs)?
> > It seems most dangerous to me to publish this sort of
> > security-sensitive configuration knobs dynamically such that an
> > attacker can change them.
> >
>
> That is a very good point. One of the things I have on my TODO list
> for the memory attributes PEI work is to remap HOB memory read-only
> before entering DXE. They are conceptually read-only anyway when PEI
> completes, so they should never be modified afterwards.

I agree, but it also seems that this patch set needs some sort of
__ro_after_init capabilities. For example, in
https://github.com/tianocore/edk2/pull/4566/commits/e485459b6efb1e49591c6f3011d9da14746c52bc#diff-02c0ef19d024b43162043efdd9ed95e0eef1653bcb5bef1e2f2b77587aee2622R101
(DxeMemoryProtectionHobLibConstructor), a copy of this same HOB is
made onto .data, while it should be RO-protected as well.
With both the HOB list and this sort of __ro_after_init protected, the
only remaining exploits would be to DMA over those pages (addressed by
IOMMU, not in this scope), to remap those pages (requires ring 0
access, therefore irrelevant) or to toggle some sort of WP-like bit
(CR0.WP, other archs may have equivalents), which already bypasses
most of the memory protections and therefore isn't all that concerning
to me.

-- 
Pedro


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#106967): https://edk2.groups.io/g/devel/message/106967
Mute This Topic: https://groups.io/mt/100090629/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [edk2-devel] [PATCH 00/14] Implement Dynamic Memory Protections
  2023-07-17 16:49     ` Pedro Falcato
@ 2023-07-18  2:45       ` Taylor Beebe
  0 siblings, 0 replies; 24+ messages in thread
From: Taylor Beebe @ 2023-07-18  2:45 UTC (permalink / raw)
  To: Pedro Falcato, Ard Biesheuvel
  Cc: devel, Jian J Wang, Liming Gao, Dandan Bi, Ard Biesheuvel,
	Jiewen Yao, Jordan Justen, Gerd Hoffmann, Leif Lindholm,
	Sami Mujawar, Andrew Fish, Ray Ni, Eric Dong, Rahul Kumar,
	Guo Dong, Sean Rhodes, James Lu, Gua Guo



On 7/17/23 9:49 AM, Pedro Falcato wrote:
> On Mon, Jul 17, 2023 at 5:26 PM Ard Biesheuvel <ardb@kernel.org> wrote:
>>
>> On Mon, 17 Jul 2023 at 18:15, Pedro Falcato <pedro.falcato@gmail.com> wrote:
>>>
>>> On Wed, Jul 12, 2023 at 12:53 AM Taylor Beebe <t@taylorbeebe.com> wrote:
>>>>
>>>> In the past, memory protection settings were configured via FixedAtBuild PCDs,
>>>> which resulted in a build-time configuration of memory mitigations. This
>>>> approach limited the flexibility of applying mitigations to the
>>>> system and made it difficult to update or adjust the settings post-build.
>>>
>>> How do you mitigate the possibility of an attack overwriting the
>>> dynamic configuration data (the HOBs)?
>>> It seems most dangerous to me to publish this sort of
>>> security-sensitive configuration knobs dynamically such that an
>>> attacker can change them.
>>>
>>
>> That is a very good point. One of the things I have on my TODO list
>> for the memory attributes PEI work is to remap HOB memory read-only
>> before entering DXE. They are conceptually read-only anyway when PEI
>> completes, so they should never be modified afterwards.
> 
> I agree, but it also seems that this patch set needs some sort of
> __ro_after_init capabilities. For example, in
> https://github.com/tianocore/edk2/pull/4566/commits/e485459b6efb1e49591c6f3011d9da14746c52bc#diff-02c0ef19d024b43162043efdd9ed95e0eef1653bcb5bef1e2f2b77587aee2622R101
> (DxeMemoryProtectionHobLibConstructor), a copy of this same HOB is
> made onto .data, while it should be RO-protected as well.
> With both the HOB list and this sort of __ro_after_init protected, the
> only remaining exploits would be to DMA over those pages (addressed by
> IOMMU, not in this scope), to remap those pages (requires ring 0
> access, therefore irrelevant) or to toggle some sort of WP-like bit
> (CR0.WP, other archs may have equivalents), which already bypasses
> most of the memory protections and therefore isn't all that concerning
> to me.
> 

Thank you both for you time and feedback.

Ard, do you think it's sufficient to use the Memory Attribute PPI to
mark HOB list memory as RO before handoff, or should the HOB list
memory be marked RO upon memory discovery and the PEI core
HOB logic be updated to manipulate protection attributes
with the PPI as it manipulates the HOB list?

-Taylor


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#106976): https://edk2.groups.io/g/devel/message/106976
Mute This Topic: https://groups.io/mt/100090629/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [edk2-devel] [PATCH 00/14] Implement Dynamic Memory Protections
  2023-07-17 16:25   ` Ard Biesheuvel
  2023-07-17 16:49     ` Pedro Falcato
@ 2023-07-18  6:11     ` Ni, Ray
  1 sibling, 0 replies; 24+ messages in thread
From: Ni, Ray @ 2023-07-18  6:11 UTC (permalink / raw)
  To: Ard Biesheuvel, Pedro Falcato
  Cc: devel@edk2.groups.io, t@taylorbeebe.com, Wang, Jian J,
	Gao, Liming, Bi, Dandan, Ard Biesheuvel, Yao, Jiewen,
	Justen, Jordan L, Gerd Hoffmann, Leif Lindholm, Sami Mujawar,
	Andrew Fish, Dong, Eric, Kumar, Rahul R, Dong, Guo, Rhodes, Sean,
	Lu, James, Guo, Gua



> -----Original Message-----
> From: Ard Biesheuvel <ardb@kernel.org>
> Sent: Tuesday, July 18, 2023 12:26 AM
> To: Pedro Falcato <pedro.falcato@gmail.com>
> Cc: devel@edk2.groups.io; t@taylorbeebe.com; Wang, Jian J
> <jian.j.wang@intel.com>; Gao, Liming <gaoliming@byosoft.com.cn>; Bi,
> Dandan <dandan.bi@intel.com>; Ard Biesheuvel
> <ardb+tianocore@kernel.org>; Yao, Jiewen <jiewen.yao@intel.com>; Justen,
> Jordan L <jordan.l.justen@intel.com>; Gerd Hoffmann <kraxel@redhat.com>;
> Leif Lindholm <quic_llindhol@quicinc.com>; Sami Mujawar
> <sami.mujawar@arm.com>; Andrew Fish <afish@apple.com>; Ni, Ray
> <ray.ni@intel.com>; Dong, Eric <eric.dong@intel.com>; Kumar, Rahul R
> <rahul.r.kumar@intel.com>; Dong, Guo <guo.dong@intel.com>; Rhodes, Sean
> <sean@starlabs.systems>; Lu, James <james.lu@intel.com>; Guo, Gua
> <gua.guo@intel.com>
> Subject: Re: [edk2-devel] [PATCH 00/14] Implement Dynamic Memory
> Protections
> 
> On Mon, 17 Jul 2023 at 18:15, Pedro Falcato <pedro.falcato@gmail.com>
> wrote:
> >
> > On Wed, Jul 12, 2023 at 12:53 AM Taylor Beebe <t@taylorbeebe.com>
> wrote:
> > >
> > > In the past, memory protection settings were configured via FixedAtBuild
> PCDs,
> > > which resulted in a build-time configuration of memory mitigations. This
> > > approach limited the flexibility of applying mitigations to the
> > > system and made it difficult to update or adjust the settings post-build.
> >
> > How do you mitigate the possibility of an attack overwriting the
> > dynamic configuration data (the HOBs)?
> > It seems most dangerous to me to publish this sort of
> > security-sensitive configuration knobs dynamically such that an
> > attacker can change them.
> >
> 
> That is a very good point. One of the things I have on my TODO list
> for the memory attributes PEI work is to remap HOB memory read-only
> before entering DXE. They are conceptually read-only anyway when PEI
> completes, so they should never be modified afterwards.

DXE Core migrates the HOB to a new location. So the protection needs to be re-done
after that.


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#106980): https://edk2.groups.io/g/devel/message/106980
Mute This Topic: https://groups.io/mt/100090629/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/leave/12367111/7686176/1913456212/xyzzy [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2023-07-18  6:11 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-07-11 23:52 [PATCH 00/14] Implement Dynamic Memory Protections Taylor Beebe
2023-07-11 23:52 ` [PATCH 01/14] MdeModulePkg: Add DXE and MM Memory Protection Settings Definitions Taylor Beebe
2023-07-11 23:52 ` [PATCH 02/14] MdeModulePkg: Add MemoryProtectionHobLib Definitions and NULL Libs Taylor Beebe
2023-07-11 23:52 ` [PATCH 03/14] MdeModulePkg: Add Phase-Specific MemoryProtectionHobLib Implementations Taylor Beebe
2023-07-11 23:52 ` [PATCH 04/14] OvmfPkg: Create the memory protection settings HOB Taylor Beebe
2023-07-11 23:52 ` [PATCH 05/14] ArmVirtPkg: Create " Taylor Beebe
2023-07-11 23:52 ` [PATCH 06/14] ArmPkg: Update to use memory protection HOB Taylor Beebe
2023-07-11 23:52 ` [PATCH 07/14] EmulatorPkg: " Taylor Beebe
2023-07-11 23:52 ` [PATCH 08/14] MdeModulePkg: " Taylor Beebe
2023-07-11 23:52 ` [PATCH 09/14] OvmfPkg: " Taylor Beebe
2023-07-11 23:52 ` [PATCH 10/14] UefiCpuPkg: " Taylor Beebe
2023-07-11 23:52 ` [PATCH 11/14] UefiPayloadPkg: " Taylor Beebe
2023-07-11 23:52 ` [PATCH 12/14] OvmfPkg: Delete Memory Protection PCDs Taylor Beebe
2023-07-11 23:52 ` [PATCH 14/14] MdeModulePkg: " Taylor Beebe
2023-07-11 23:52 ` Taylor Beebe
     [not found] ` <1770F551E2E594C0.16575@groups.io>
2023-07-12  0:01   ` [edk2-devel] " Taylor Beebe
2023-07-12 10:05 ` [PATCH 00/14] Implement Dynamic Memory Protections Gerd Hoffmann
2023-07-12 21:54   ` Taylor Beebe
2023-07-17 11:14     ` [edk2-devel] " Gerd Hoffmann
2023-07-17 16:15 ` Pedro Falcato
2023-07-17 16:25   ` Ard Biesheuvel
2023-07-17 16:49     ` Pedro Falcato
2023-07-18  2:45       ` Taylor Beebe
2023-07-18  6:11     ` Ni, Ray

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox