public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [edk2-devel] [PATCH v2 0/9] Add ImagePropertiesRecordLib and Fix MAT Bugs
@ 2023-07-20  0:05 Taylor Beebe
  2023-07-20  0:05 ` [edk2-devel] [PATCH v2 1/9] MdeModulePkg: Add ImagePropertiesRecordLib Taylor Beebe
                   ` (9 more replies)
  0 siblings, 10 replies; 13+ messages in thread
From: Taylor Beebe @ 2023-07-20  0:05 UTC (permalink / raw)
  To: devel
  Cc: Andrew Fish, Ard Biesheuvel, Dandan Bi, Eric Dong, Gerd Hoffmann,
	Guo Dong, Gua Guo, James Lu, Jian J Wang, Jiewen Yao,
	Jordan Justen, Leif Lindholm, Liming Gao, Rahul Kumar, Ray Ni,
	Sami Mujawar, Sean Rhodes

v2:
- A one-line change in patch 3 was moved to patch 9 for correctness.

Reference: https://github.com/tianocore/edk2/pull/4590
Bugzilla: https://bugzilla.tianocore.org/show_bug.cgi?id=4492

The UEFI and SMM MAT logic contains duplicate logic for manipulating image
properties records which is used to track runtime images.
This patch series adds a new library, ImagePropertiesRecordLib,
which consolidates this logic and fixes the bugs which currently exist in
the MAT logic.

The first patch adds the ImagePropertiesRecordLib implementation which
is a copy of the UEFI MAT logic with minor modifications to remove the
reliance on globabl variables and make the code unit testable.

The second patch adds a unit test for the ImagePropertiesRecordLib. The
logic tests various potential layouts of the EFI memory map and runtime
images. 3/4 of these tests will fail which demonstrates the MAT logic
bugs.

The third patch fixes the logic in the ImagePropertiesRecordLib so
that all of the unit tests pass and the MAT logic can be fixed by
using the library.

The remaining patches add library instances to DSC files and remove
the image properties record logic from the SMM and UEFI MAT logic.

Cc: Andrew Fish <afish@apple.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Dandan Bi <dandan.bi@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Guo Dong <guo.dong@intel.com>
Cc: Gua Guo <gua.guo@intel.com>
Cc: James Lu <james.lu@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Sami Mujawar <sami.mujawar@arm.com>
Cc: Sean Rhodes <sean@starlabs.systems>
Taylor Beebe (9):
  MdeModulePkg: Add ImagePropertiesRecordLib
  MdeModulePkg: Add ImagePropertiesRecordLib Host-Based Unit Test
  MdeModulePkg: Fix Bugs in MAT Logic
  ArmVirtPkg: Add ImagePropertiesRecordLib Instance
  EmulatorPkg: Add ImagePropertiesRecordLib Instance
  OvmfPkg: Add ImagePropertiesRecordLib Instance
  UefiPayloadPkg: Add ImagePropertiesRecordLib Instance
  UefiCpuPkg: Use Attribute From SMM MemoryAttributesTable if Nonzero
  MdeModulePkg: Update UEFI and SMM MAT Logic To Use
    ImagePropertiesRecordLib

 MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c                                              | 786 +---------------
 MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c                                                   |  24 +-
 MdeModulePkg/Core/PiSmmCore/MemoryAttributesTable.c                                             | 785 +---------------
 MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c                        | 805 +++++++++++++++++
 MdeModulePkg/Library/ImagePropertiesRecordLib/UnitTest/ImagePropertiesRecordLibUnitTestHost.c   | 938 ++++++++++++++++++++
 UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c                                              |  19 +-
 ArmVirtPkg/ArmVirt.dsc.inc                                                                      |   1 +
 EmulatorPkg/EmulatorPkg.dsc                                                                     |   1 +
 MdeModulePkg/Core/Dxe/DxeMain.h                                                                 |  20 -
 MdeModulePkg/Core/Dxe/DxeMain.inf                                                               |   1 +
 MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf                                                       |   1 +
 MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h                                         | 151 ++++
 MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf                      |  28 +
 MdeModulePkg/Library/ImagePropertiesRecordLib/UnitTest/ImagePropertiesRecordLibUnitTestHost.inf |  35 +
 MdeModulePkg/MdeModulePkg.dec                                                                   |   5 +
 MdeModulePkg/MdeModulePkg.dsc                                                                   |   2 +
 MdeModulePkg/Test/MdeModulePkgHostTest.dsc                                                      |   5 +
 OvmfPkg/AmdSev/AmdSevX64.dsc                                                                    |   1 +
 OvmfPkg/Bhyve/BhyveX64.dsc                                                                      |   1 +
 OvmfPkg/CloudHv/CloudHvX64.dsc                                                                  |   1 +
 OvmfPkg/IntelTdx/IntelTdxX64.dsc                                                                |   1 +
 OvmfPkg/Microvm/MicrovmX64.dsc                                                                  |   1 +
 OvmfPkg/OvmfPkgIa32.dsc                                                                         |   1 +
 OvmfPkg/OvmfPkgIa32X64.dsc                                                                      |   1 +
 OvmfPkg/OvmfPkgX64.dsc                                                                          |   1 +
 OvmfPkg/OvmfXen.dsc                                                                             |   1 +
 OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc                                                             |   1 +
 UefiPayloadPkg/UefiPayloadPkg.dsc                                                               |   1 +
 28 files changed, 2039 insertions(+), 1579 deletions(-)
 create mode 100644 MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c
 create mode 100644 MdeModulePkg/Library/ImagePropertiesRecordLib/UnitTest/ImagePropertiesRecordLibUnitTestHost.c
 create mode 100644 MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h
 create mode 100644 MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
 create mode 100644 MdeModulePkg/Library/ImagePropertiesRecordLib/UnitTest/ImagePropertiesRecordLibUnitTestHost.inf

-- 
2.41.0.windows.2



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



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

* [edk2-devel] [PATCH v2 1/9] MdeModulePkg: Add ImagePropertiesRecordLib
  2023-07-20  0:05 [edk2-devel] [PATCH v2 0/9] Add ImagePropertiesRecordLib and Fix MAT Bugs Taylor Beebe
@ 2023-07-20  0:05 ` Taylor Beebe
  2023-07-20  0:05 ` [edk2-devel] [PATCH v2 2/9] MdeModulePkg: Add ImagePropertiesRecordLib Host-Based Unit Test Taylor Beebe
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Taylor Beebe @ 2023-07-20  0:05 UTC (permalink / raw)
  To: devel; +Cc: Jian J Wang, Liming Gao, Dandan Bi

Create a library for manipulating image properties records. Image
properties record logic is already present in both the SMM and
UEFI MAT logic, and this is a copy of the UEFI MAT logic with added
function arguments to remove dependencies on global variables.

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/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c   | 807 ++++++++++++++++++++
 MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h                    | 151 ++++
 MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf |  28 +
 MdeModulePkg/MdeModulePkg.dec                                              |   5 +
 MdeModulePkg/MdeModulePkg.dsc                                              |   2 +
 5 files changed, 993 insertions(+)

diff --git a/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c b/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c
new file mode 100644
index 000000000000..46f4f401a4d5
--- /dev/null
+++ b/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c
@@ -0,0 +1,807 @@
+/** @file
+
+  Provides definitions and functionality for manipulating Image Properties Records.
+
+  Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/ImagePropertiesRecordLib.h>
+
+#define PREVIOUS_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \
+  ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) - (Size)))
+
+#define NEXT_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \
+  ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) + (Size)))
+
+/**
+  Converts a number of EFI_PAGEs to a size in bytes.
+
+  NOTE: Do not use EFI_PAGES_TO_SIZE because it handles UINTN only.
+
+  @param  Pages     The number of EFI_PAGES.
+
+  @return  The number of bytes associated with the number of EFI_PAGEs specified
+           by Pages.
+**/
+STATIC
+UINT64
+EfiPagesToSize (
+  IN UINT64  Pages
+  )
+{
+  return LShiftU64 (Pages, EFI_PAGE_SHIFT);
+}
+
+/**
+  Converts a size, in bytes, to a number of EFI_PAGESs.
+
+  NOTE: Do not use EFI_SIZE_TO_PAGES because it handles UINTN only.
+
+  @param  Size      A size in bytes.
+
+  @return  The number of EFI_PAGESs associated with the number of bytes specified
+           by Size.
+
+**/
+STATIC
+UINT64
+EfiSizeToPages (
+  IN UINT64  Size
+  )
+{
+  return RShiftU64 (Size, EFI_PAGE_SHIFT) + ((((UINTN)Size) & EFI_PAGE_MASK) ? 1 : 0);
+}
+
+/**
+  Sort memory map entries based upon PhysicalStart, from low to high.
+
+  @param  MemoryMap              A pointer to the buffer in which firmware places
+                                 the current memory map.
+  @param  MemoryMapSize          Size, in bytes, of the MemoryMap buffer.
+  @param  DescriptorSize         Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
+**/
+STATIC
+VOID
+SortMemoryMap (
+  IN OUT EFI_MEMORY_DESCRIPTOR  *MemoryMap,
+  IN UINTN                      MemoryMapSize,
+  IN UINTN                      DescriptorSize
+  )
+{
+  EFI_MEMORY_DESCRIPTOR  *MemoryMapEntry;
+  EFI_MEMORY_DESCRIPTOR  *NextMemoryMapEntry;
+  EFI_MEMORY_DESCRIPTOR  *MemoryMapEnd;
+  EFI_MEMORY_DESCRIPTOR  TempMemoryMap;
+
+  MemoryMapEntry     = MemoryMap;
+  NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
+  MemoryMapEnd       = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + MemoryMapSize);
+  while (MemoryMapEntry < MemoryMapEnd) {
+    while (NextMemoryMapEntry < MemoryMapEnd) {
+      if (MemoryMapEntry->PhysicalStart > NextMemoryMapEntry->PhysicalStart) {
+        CopyMem (&TempMemoryMap, MemoryMapEntry, sizeof (EFI_MEMORY_DESCRIPTOR));
+        CopyMem (MemoryMapEntry, NextMemoryMapEntry, sizeof (EFI_MEMORY_DESCRIPTOR));
+        CopyMem (NextMemoryMapEntry, &TempMemoryMap, sizeof (EFI_MEMORY_DESCRIPTOR));
+      }
+
+      NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize);
+    }
+
+    MemoryMapEntry     = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
+    NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
+  }
+
+  return;
+}
+
+/**
+  Swap two code sections in image record.
+
+  @param  FirstImageRecordCodeSection    first code section in image record
+  @param  SecondImageRecordCodeSection   second code section in image record
+**/
+STATIC
+VOID
+SwapImageRecordCodeSection (
+  IN IMAGE_PROPERTIES_RECORD_CODE_SECTION  *FirstImageRecordCodeSection,
+  IN IMAGE_PROPERTIES_RECORD_CODE_SECTION  *SecondImageRecordCodeSection
+  )
+{
+  IMAGE_PROPERTIES_RECORD_CODE_SECTION  TempImageRecordCodeSection;
+
+  TempImageRecordCodeSection.CodeSegmentBase = FirstImageRecordCodeSection->CodeSegmentBase;
+  TempImageRecordCodeSection.CodeSegmentSize = FirstImageRecordCodeSection->CodeSegmentSize;
+
+  FirstImageRecordCodeSection->CodeSegmentBase = SecondImageRecordCodeSection->CodeSegmentBase;
+  FirstImageRecordCodeSection->CodeSegmentSize = SecondImageRecordCodeSection->CodeSegmentSize;
+
+  SecondImageRecordCodeSection->CodeSegmentBase = TempImageRecordCodeSection.CodeSegmentBase;
+  SecondImageRecordCodeSection->CodeSegmentSize = TempImageRecordCodeSection.CodeSegmentSize;
+}
+
+/**
+  Check if code section in image record is valid.
+
+  @param  ImageRecord    image record to be checked
+
+  @retval TRUE  image record is valid
+  @retval FALSE image record is invalid
+**/
+BOOLEAN
+EFIAPI
+IsImageRecordCodeSectionValid (
+  IN IMAGE_PROPERTIES_RECORD  *ImageRecord
+  )
+{
+  IMAGE_PROPERTIES_RECORD_CODE_SECTION  *ImageRecordCodeSection;
+  IMAGE_PROPERTIES_RECORD_CODE_SECTION  *LastImageRecordCodeSection;
+  LIST_ENTRY                            *ImageRecordCodeSectionLink;
+  LIST_ENTRY                            *ImageRecordCodeSectionEndLink;
+  LIST_ENTRY                            *ImageRecordCodeSectionList;
+
+  DEBUG ((DEBUG_VERBOSE, "ImageCode SegmentCount - 0x%x\n", ImageRecord->CodeSegmentCount));
+
+  ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList;
+
+  ImageRecordCodeSectionLink    = ImageRecordCodeSectionList->ForwardLink;
+  ImageRecordCodeSectionEndLink = ImageRecordCodeSectionList;
+  LastImageRecordCodeSection    = NULL;
+  while (ImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) {
+    ImageRecordCodeSection = CR (
+                               ImageRecordCodeSectionLink,
+                               IMAGE_PROPERTIES_RECORD_CODE_SECTION,
+                               Link,
+                               IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
+                               );
+    if (ImageRecordCodeSection->CodeSegmentSize == 0) {
+      return FALSE;
+    }
+
+    if (ImageRecordCodeSection->CodeSegmentBase < ImageRecord->ImageBase) {
+      return FALSE;
+    }
+
+    if (ImageRecordCodeSection->CodeSegmentBase >= MAX_ADDRESS - ImageRecordCodeSection->CodeSegmentSize) {
+      return FALSE;
+    }
+
+    if ((ImageRecordCodeSection->CodeSegmentBase + ImageRecordCodeSection->CodeSegmentSize) > (ImageRecord->ImageBase + ImageRecord->ImageSize)) {
+      return FALSE;
+    }
+
+    if (LastImageRecordCodeSection != NULL) {
+      if ((LastImageRecordCodeSection->CodeSegmentBase + LastImageRecordCodeSection->CodeSegmentSize) > ImageRecordCodeSection->CodeSegmentBase) {
+        return FALSE;
+      }
+    }
+
+    LastImageRecordCodeSection = ImageRecordCodeSection;
+    ImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;
+  }
+
+  return TRUE;
+}
+
+/**
+  Swap two image records.
+
+  @param  FirstImageRecord   first image record.
+  @param  SecondImageRecord  second image record.
+**/
+STATIC
+VOID
+SwapImageRecord (
+  IN IMAGE_PROPERTIES_RECORD  *FirstImageRecord,
+  IN IMAGE_PROPERTIES_RECORD  *SecondImageRecord
+  )
+{
+  IMAGE_PROPERTIES_RECORD  TempImageRecord;
+
+  TempImageRecord.ImageBase        = FirstImageRecord->ImageBase;
+  TempImageRecord.ImageSize        = FirstImageRecord->ImageSize;
+  TempImageRecord.CodeSegmentCount = FirstImageRecord->CodeSegmentCount;
+
+  FirstImageRecord->ImageBase        = SecondImageRecord->ImageBase;
+  FirstImageRecord->ImageSize        = SecondImageRecord->ImageSize;
+  FirstImageRecord->CodeSegmentCount = SecondImageRecord->CodeSegmentCount;
+
+  SecondImageRecord->ImageBase        = TempImageRecord.ImageBase;
+  SecondImageRecord->ImageSize        = TempImageRecord.ImageSize;
+  SecondImageRecord->CodeSegmentCount = TempImageRecord.CodeSegmentCount;
+
+  SwapListEntries (&FirstImageRecord->CodeSegmentList, &SecondImageRecord->CodeSegmentList);
+}
+
+/**
+  Sort code section in image record, based upon CodeSegmentBase from low to high.
+
+  @param  ImageRecord    image record to be sorted
+**/
+VOID
+EFIAPI
+SortImageRecordCodeSection (
+  IN IMAGE_PROPERTIES_RECORD  *ImageRecord
+  )
+{
+  IMAGE_PROPERTIES_RECORD_CODE_SECTION  *ImageRecordCodeSection;
+  IMAGE_PROPERTIES_RECORD_CODE_SECTION  *NextImageRecordCodeSection;
+  LIST_ENTRY                            *ImageRecordCodeSectionLink;
+  LIST_ENTRY                            *NextImageRecordCodeSectionLink;
+  LIST_ENTRY                            *ImageRecordCodeSectionEndLink;
+  LIST_ENTRY                            *ImageRecordCodeSectionList;
+
+  ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList;
+
+  ImageRecordCodeSectionLink     = ImageRecordCodeSectionList->ForwardLink;
+  NextImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;
+  ImageRecordCodeSectionEndLink  = ImageRecordCodeSectionList;
+  while (ImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) {
+    ImageRecordCodeSection = CR (
+                               ImageRecordCodeSectionLink,
+                               IMAGE_PROPERTIES_RECORD_CODE_SECTION,
+                               Link,
+                               IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
+                               );
+    while (NextImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) {
+      NextImageRecordCodeSection = CR (
+                                     NextImageRecordCodeSectionLink,
+                                     IMAGE_PROPERTIES_RECORD_CODE_SECTION,
+                                     Link,
+                                     IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
+                                     );
+      if (ImageRecordCodeSection->CodeSegmentBase > NextImageRecordCodeSection->CodeSegmentBase) {
+        SwapImageRecordCodeSection (ImageRecordCodeSection, NextImageRecordCodeSection);
+      }
+
+      NextImageRecordCodeSectionLink = NextImageRecordCodeSectionLink->ForwardLink;
+    }
+
+    ImageRecordCodeSectionLink     = ImageRecordCodeSectionLink->ForwardLink;
+    NextImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;
+  }
+}
+
+/**
+  Dump image record.
+
+  @param[in]  ImageRecordList  A list of IMAGE_PROPERTIES_RECORD entries
+**/
+VOID
+EFIAPI
+DumpImageRecord (
+  IN LIST_ENTRY  *ImageRecordList
+  )
+{
+  IMAGE_PROPERTIES_RECORD  *ImageRecord;
+  LIST_ENTRY               *ImageRecordLink;
+  UINTN                    Index;
+
+  for (ImageRecordLink = ImageRecordList->ForwardLink, Index = 0;
+       ImageRecordLink != ImageRecordList;
+       ImageRecordLink = ImageRecordLink->ForwardLink, Index++)
+  {
+    ImageRecord = CR (
+                    ImageRecordLink,
+                    IMAGE_PROPERTIES_RECORD,
+                    Link,
+                    IMAGE_PROPERTIES_RECORD_SIGNATURE
+                    );
+    DEBUG ((DEBUG_VERBOSE, "Image[%d]: 0x%016lx - 0x%016lx\n", Index, ImageRecord->ImageBase, ImageRecord->ImageSize));
+  }
+}
+
+/**
+  Sort image record based upon the ImageBase from low to high.
+
+  @param[in] ImageRecordList  A list of IMAGE_PROPERTIES_RECORD entries
+**/
+VOID
+EFIAPI
+SortImageRecord (
+  IN LIST_ENTRY  *ImageRecordList
+  )
+{
+  IMAGE_PROPERTIES_RECORD  *ImageRecord;
+  IMAGE_PROPERTIES_RECORD  *NextImageRecord;
+  LIST_ENTRY               *ImageRecordLink;
+  LIST_ENTRY               *NextImageRecordLink;
+  LIST_ENTRY               *ImageRecordEndLink;
+
+  ImageRecordLink     = ImageRecordList->ForwardLink;
+  NextImageRecordLink = ImageRecordLink->ForwardLink;
+  ImageRecordEndLink  = ImageRecordList;
+  while (ImageRecordLink != ImageRecordEndLink) {
+    ImageRecord = CR (
+                    ImageRecordLink,
+                    IMAGE_PROPERTIES_RECORD,
+                    Link,
+                    IMAGE_PROPERTIES_RECORD_SIGNATURE
+                    );
+    while (NextImageRecordLink != ImageRecordEndLink) {
+      NextImageRecord = CR (
+                          NextImageRecordLink,
+                          IMAGE_PROPERTIES_RECORD,
+                          Link,
+                          IMAGE_PROPERTIES_RECORD_SIGNATURE
+                          );
+      if (ImageRecord->ImageBase > NextImageRecord->ImageBase) {
+        SwapImageRecord (ImageRecord, NextImageRecord);
+      }
+
+      NextImageRecordLink = NextImageRecordLink->ForwardLink;
+    }
+
+    ImageRecordLink     = ImageRecordLink->ForwardLink;
+    NextImageRecordLink = ImageRecordLink->ForwardLink;
+  }
+}
+
+/**
+  Return the first image record, whose [ImageBase, ImageSize] covered by [Buffer, Length].
+
+  @param[in] Buffer           Start Address
+  @param[in] Length           Address length
+  @param[in] ImageRecordList  A list of IMAGE_PROPERTIES_RECORD entries to check against
+                              the memory range Buffer -> Buffer + Length
+
+  @return first image record covered by [buffer, length]
+**/
+STATIC
+IMAGE_PROPERTIES_RECORD *
+GetImageRecordByAddress (
+  IN EFI_PHYSICAL_ADDRESS  Buffer,
+  IN UINT64                Length,
+  IN LIST_ENTRY            *ImageRecordList
+  )
+{
+  IMAGE_PROPERTIES_RECORD  *ImageRecord;
+  LIST_ENTRY               *ImageRecordLink;
+
+  for (ImageRecordLink = ImageRecordList->ForwardLink;
+       ImageRecordLink != ImageRecordList;
+       ImageRecordLink = ImageRecordLink->ForwardLink)
+  {
+    ImageRecord = CR (
+                    ImageRecordLink,
+                    IMAGE_PROPERTIES_RECORD,
+                    Link,
+                    IMAGE_PROPERTIES_RECORD_SIGNATURE
+                    );
+
+    if ((Buffer <= ImageRecord->ImageBase) &&
+        (Buffer + Length >= ImageRecord->ImageBase + ImageRecord->ImageSize))
+    {
+      return ImageRecord;
+    }
+  }
+
+  return NULL;
+}
+
+/**
+  Set the memory map to new entries, according to one old entry,
+  based upon PE code section and data section in image record
+
+  @param  ImageRecord            An image record whose [ImageBase, ImageSize] covered
+                                 by old memory map entry.
+  @param  NewRecord              A pointer to several new memory map entries.
+                                 The caller gurantee the buffer size be 1 +
+                                 (SplitRecordCount * DescriptorSize) calculated
+                                 below.
+  @param  OldRecord              A pointer to one old memory map entry.
+  @param  DescriptorSize         Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
+**/
+STATIC
+UINTN
+SetNewRecord (
+  IN IMAGE_PROPERTIES_RECORD    *ImageRecord,
+  IN OUT EFI_MEMORY_DESCRIPTOR  *NewRecord,
+  IN EFI_MEMORY_DESCRIPTOR      *OldRecord,
+  IN UINTN                      DescriptorSize
+  )
+{
+  EFI_MEMORY_DESCRIPTOR                 TempRecord;
+  IMAGE_PROPERTIES_RECORD_CODE_SECTION  *ImageRecordCodeSection;
+  LIST_ENTRY                            *ImageRecordCodeSectionLink;
+  LIST_ENTRY                            *ImageRecordCodeSectionEndLink;
+  LIST_ENTRY                            *ImageRecordCodeSectionList;
+  UINTN                                 NewRecordCount;
+  UINT64                                PhysicalEnd;
+  UINT64                                ImageEnd;
+
+  CopyMem (&TempRecord, OldRecord, sizeof (EFI_MEMORY_DESCRIPTOR));
+  PhysicalEnd    = TempRecord.PhysicalStart + EfiPagesToSize (TempRecord.NumberOfPages);
+  NewRecordCount = 0;
+
+  ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList;
+
+  ImageRecordCodeSectionLink    = ImageRecordCodeSectionList->ForwardLink;
+  ImageRecordCodeSectionEndLink = ImageRecordCodeSectionList;
+  while (ImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) {
+    ImageRecordCodeSection = CR (
+                               ImageRecordCodeSectionLink,
+                               IMAGE_PROPERTIES_RECORD_CODE_SECTION,
+                               Link,
+                               IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
+                               );
+    ImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;
+
+    if (TempRecord.PhysicalStart <= ImageRecordCodeSection->CodeSegmentBase) {
+      //
+      // DATA
+      //
+      NewRecord->Type          = TempRecord.Type;
+      NewRecord->PhysicalStart = TempRecord.PhysicalStart;
+      NewRecord->VirtualStart  = 0;
+      NewRecord->NumberOfPages = EfiSizeToPages (ImageRecordCodeSection->CodeSegmentBase - NewRecord->PhysicalStart);
+      NewRecord->Attribute     = TempRecord.Attribute | EFI_MEMORY_XP;
+      if (NewRecord->NumberOfPages != 0) {
+        NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);
+        NewRecordCount++;
+      }
+
+      //
+      // CODE
+      //
+      NewRecord->Type          = TempRecord.Type;
+      NewRecord->PhysicalStart = ImageRecordCodeSection->CodeSegmentBase;
+      NewRecord->VirtualStart  = 0;
+      NewRecord->NumberOfPages = EfiSizeToPages (ImageRecordCodeSection->CodeSegmentSize);
+      NewRecord->Attribute     = (TempRecord.Attribute & (~EFI_MEMORY_XP)) | EFI_MEMORY_RO;
+      if (NewRecord->NumberOfPages != 0) {
+        NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);
+        NewRecordCount++;
+      }
+
+      TempRecord.PhysicalStart = ImageRecordCodeSection->CodeSegmentBase + EfiPagesToSize (EfiSizeToPages (ImageRecordCodeSection->CodeSegmentSize));
+      TempRecord.NumberOfPages = EfiSizeToPages (PhysicalEnd - TempRecord.PhysicalStart);
+      if (TempRecord.NumberOfPages == 0) {
+        break;
+      }
+    }
+  }
+
+  ImageEnd = ImageRecord->ImageBase + ImageRecord->ImageSize;
+
+  //
+  // Final DATA
+  //
+  if (TempRecord.PhysicalStart < ImageEnd) {
+    NewRecord->Type          = TempRecord.Type;
+    NewRecord->PhysicalStart = TempRecord.PhysicalStart;
+    NewRecord->VirtualStart  = 0;
+    NewRecord->NumberOfPages = EfiSizeToPages (ImageEnd - TempRecord.PhysicalStart);
+    NewRecord->Attribute     = TempRecord.Attribute | EFI_MEMORY_XP;
+    NewRecordCount++;
+  }
+
+  return NewRecordCount;
+}
+
+/**
+  Return the max number of new splitted entries, according to one old entry,
+  based upon PE code section and data section.
+
+  @param[in]  OldRecord         A pointer to one old memory map entry.
+  @param[in]  ImageRecordList   A list of IMAGE_PROPERTIES_RECORD entries used when searching
+                                for an image record contained by the memory range described in
+                                the existing EFI memory map descriptor OldRecord
+
+  @retval  0 no entry need to be splitted.
+  @return  the max number of new splitted entries
+**/
+STATIC
+UINTN
+GetMaxSplitRecordCount (
+  IN EFI_MEMORY_DESCRIPTOR  *OldRecord,
+  IN LIST_ENTRY             *ImageRecordList
+  )
+{
+  IMAGE_PROPERTIES_RECORD  *ImageRecord;
+  UINTN                    SplitRecordCount;
+  UINT64                   PhysicalStart;
+  UINT64                   PhysicalEnd;
+
+  SplitRecordCount = 0;
+  PhysicalStart    = OldRecord->PhysicalStart;
+  PhysicalEnd      = OldRecord->PhysicalStart + EfiPagesToSize (OldRecord->NumberOfPages);
+
+  do {
+    ImageRecord = GetImageRecordByAddress (PhysicalStart, PhysicalEnd - PhysicalStart, ImageRecordList);
+    if (ImageRecord == NULL) {
+      break;
+    }
+
+    SplitRecordCount += (2 * ImageRecord->CodeSegmentCount + 1);
+    PhysicalStart     = ImageRecord->ImageBase + ImageRecord->ImageSize;
+  } while ((ImageRecord != NULL) && (PhysicalStart < PhysicalEnd));
+
+  if (SplitRecordCount != 0) {
+    SplitRecordCount--;
+  }
+
+  return SplitRecordCount;
+}
+
+/**
+  Split the memory map to new entries, according to one old entry,
+  based upon PE code section and data section.
+
+  @param[in]        OldRecord             A pointer to one old memory map entry.
+  @param[in, out]   NewRecord             A pointer to several new memory map entries.
+                                          The caller gurantee the buffer size be 1 +
+                                          (SplitRecordCount * DescriptorSize) calculated
+                                          below.
+  @param[in]        MaxSplitRecordCount   The max number of splitted entries
+  @param[in]        DescriptorSize        Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
+  @param[in]        ImageRecordList       A list of IMAGE_PROPERTIES_RECORD entries used when searching
+                                          for an image record contained by the memory range described in
+                                          the existing EFI memory map descriptor OldRecord
+
+  @retval  0 no entry is splitted.
+  @return  the real number of splitted record.
+**/
+STATIC
+UINTN
+SplitRecord (
+  IN EFI_MEMORY_DESCRIPTOR      *OldRecord,
+  IN OUT EFI_MEMORY_DESCRIPTOR  *NewRecord,
+  IN UINTN                      MaxSplitRecordCount,
+  IN UINTN                      DescriptorSize,
+  IN LIST_ENTRY                 *ImageRecordList
+  )
+{
+  EFI_MEMORY_DESCRIPTOR    TempRecord;
+  IMAGE_PROPERTIES_RECORD  *ImageRecord;
+  IMAGE_PROPERTIES_RECORD  *NewImageRecord;
+  UINT64                   PhysicalStart;
+  UINT64                   PhysicalEnd;
+  UINTN                    NewRecordCount;
+  UINTN                    TotalNewRecordCount;
+  BOOLEAN                  IsLastRecordData;
+
+  if (MaxSplitRecordCount == 0) {
+    CopyMem (NewRecord, OldRecord, DescriptorSize);
+    return 0;
+  }
+
+  TotalNewRecordCount = 0;
+
+  //
+  // Override previous record
+  //
+  CopyMem (&TempRecord, OldRecord, sizeof (EFI_MEMORY_DESCRIPTOR));
+  PhysicalStart = TempRecord.PhysicalStart;
+  PhysicalEnd   = TempRecord.PhysicalStart + EfiPagesToSize (TempRecord.NumberOfPages);
+
+  ImageRecord = NULL;
+  do {
+    NewImageRecord = GetImageRecordByAddress (PhysicalStart, PhysicalEnd - PhysicalStart, ImageRecordList);
+    if (NewImageRecord == NULL) {
+      //
+      // No more image covered by this range, stop
+      //
+      if ((PhysicalEnd > PhysicalStart) && (ImageRecord != NULL)) {
+        //
+        // If this is still address in this record, need record.
+        //
+        NewRecord        = PREVIOUS_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);
+        IsLastRecordData = FALSE;
+        if ((NewRecord->Attribute & EFI_MEMORY_XP) != 0) {
+          IsLastRecordData = TRUE;
+        }
+
+        if (IsLastRecordData) {
+          //
+          // Last record is DATA, just merge it.
+          //
+          NewRecord->NumberOfPages = EfiSizeToPages (PhysicalEnd - NewRecord->PhysicalStart);
+        } else {
+          //
+          // Last record is CODE, create a new DATA entry.
+          //
+          NewRecord                = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);
+          NewRecord->Type          = TempRecord.Type;
+          NewRecord->PhysicalStart = TempRecord.PhysicalStart;
+          NewRecord->VirtualStart  = 0;
+          NewRecord->NumberOfPages = TempRecord.NumberOfPages;
+          NewRecord->Attribute     = TempRecord.Attribute | EFI_MEMORY_XP;
+          TotalNewRecordCount++;
+        }
+      }
+
+      break;
+    }
+
+    ImageRecord = NewImageRecord;
+
+    //
+    // Set new record
+    //
+    NewRecordCount       = SetNewRecord (ImageRecord, NewRecord, &TempRecord, DescriptorSize);
+    TotalNewRecordCount += NewRecordCount;
+    NewRecord            = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)NewRecord + NewRecordCount * DescriptorSize);
+
+    //
+    // Update PhysicalStart, in order to exclude the image buffer already splitted.
+    //
+    PhysicalStart            = ImageRecord->ImageBase + ImageRecord->ImageSize;
+    TempRecord.PhysicalStart = PhysicalStart;
+    TempRecord.NumberOfPages = EfiSizeToPages (PhysicalEnd - PhysicalStart);
+  } while ((ImageRecord != NULL) && (PhysicalStart < PhysicalEnd));
+
+  //
+  // The logic in function SplitTable() ensures that TotalNewRecordCount will not be zero if the
+  // code reaches here.
+  //
+  ASSERT (TotalNewRecordCount != 0);
+  return TotalNewRecordCount - 1;
+}
+
+/**
+  Split the original memory map, and add more entries to describe PE code section and data section.
+  This function will set EfiRuntimeServicesData to be EFI_MEMORY_XP.
+  This function will merge entries with same attributes finally.
+
+  NOTE: It assumes PE code/data section are page aligned.
+  NOTE: It assumes enough entry is prepared for new memory map.
+
+  Split table:
+   +---------------+
+   | Record X      |
+   +---------------+
+   | Record RtCode |
+   +---------------+
+   | Record Y      |
+   +---------------+
+   ==>
+   +---------------+
+   | Record X      |
+   +---------------+ ----
+   | Record RtData |     |
+   +---------------+     |
+   | Record RtCode |     |-> PE/COFF1
+   +---------------+     |
+   | Record RtData |     |
+   +---------------+ ----
+   | Record RtData |     |
+   +---------------+     |
+   | Record RtCode |     |-> PE/COFF2
+   +---------------+     |
+   | Record RtData |     |
+   +---------------+ ----
+   | Record Y      |
+   +---------------+
+
+  @param[in, out] MemoryMapSize                   IN:   The size, in bytes, of the old memory map before the split.
+                                                  OUT:  The size, in bytes, of the used descriptors of the split
+                                                        memory map
+  @param[in, out] MemoryMap                       IN:   A pointer to the buffer containing the current memory map.
+                                                        This buffer must have enough space to accomodate the "worst case"
+                                                        scenario where every image in ImageRecordList needs a new descriptor
+                                                        to describe its code and data sections.
+                                                  OUT:  A pointer to the updated memory map with separated image section
+                                                        descriptors.
+  @param[in]      DescriptorSize                  The size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
+  @param[in]      ImageRecordList                 A list of IMAGE_PROPERTIES_RECORD entries used when searching
+                                                  for an image record contained by the memory range described in
+                                                  EFI memory map descriptors.
+  @param[in]      NumberOfAdditionalDescriptors   The number of unused descriptors at the end of the input MemoryMap.
+**/
+VOID
+EFIAPI
+SplitTable (
+  IN OUT UINTN                  *MemoryMapSize,
+  IN OUT EFI_MEMORY_DESCRIPTOR  *MemoryMap,
+  IN     UINTN                  DescriptorSize,
+  IN     LIST_ENTRY             *ImageRecordList,
+  IN     UINTN                  NumberOfAdditionalDescriptors
+  )
+{
+  INTN   IndexOld;
+  INTN   IndexNew;
+  UINTN  MaxSplitRecordCount;
+  UINTN  RealSplitRecordCount;
+  UINTN  TotalSplitRecordCount;
+
+  TotalSplitRecordCount = 0;
+  //
+  // Let old record point to end of valid MemoryMap buffer.
+  //
+  IndexOld = ((*MemoryMapSize) / DescriptorSize) - 1;
+  //
+  // Let new record point to end of full MemoryMap buffer.
+  //
+  IndexNew = ((*MemoryMapSize) / DescriptorSize) - 1 + NumberOfAdditionalDescriptors;
+  for ( ; IndexOld >= 0; IndexOld--) {
+    MaxSplitRecordCount = GetMaxSplitRecordCount ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + IndexOld * DescriptorSize), ImageRecordList);
+    //
+    // Split this MemoryMap record
+    //
+    IndexNew            -= MaxSplitRecordCount;
+    RealSplitRecordCount = SplitRecord (
+                             (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + IndexOld * DescriptorSize),
+                             (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + IndexNew * DescriptorSize),
+                             MaxSplitRecordCount,
+                             DescriptorSize,
+                             ImageRecordList
+                             );
+    //
+    // Adjust IndexNew according to real split.
+    //
+    CopyMem (
+      ((UINT8 *)MemoryMap + (IndexNew + MaxSplitRecordCount - RealSplitRecordCount) * DescriptorSize),
+      ((UINT8 *)MemoryMap + IndexNew * DescriptorSize),
+      RealSplitRecordCount * DescriptorSize
+      );
+    IndexNew               = IndexNew + MaxSplitRecordCount - RealSplitRecordCount;
+    TotalSplitRecordCount += RealSplitRecordCount;
+    IndexNew--;
+  }
+
+  //
+  // Move all records to the beginning.
+  //
+  CopyMem (
+    MemoryMap,
+    (UINT8 *)MemoryMap + (NumberOfAdditionalDescriptors - TotalSplitRecordCount) * DescriptorSize,
+    (*MemoryMapSize) + TotalSplitRecordCount * DescriptorSize
+    );
+
+  *MemoryMapSize = (*MemoryMapSize) + DescriptorSize * TotalSplitRecordCount;
+
+  //
+  // Sort from low to high (Just in case)
+  //
+  SortMemoryMap (MemoryMap, *MemoryMapSize, DescriptorSize);
+
+  return;
+}
+
+/**
+  Find image record according to image base and size.
+
+  @param[in]  ImageBase        Base of PE image
+  @param[in]  ImageSize        Size of PE image
+  @param[in]  ImageRecordList  A list of IMAGE_PROPERTIES_RECORD entries
+
+  @return image record
+**/
+IMAGE_PROPERTIES_RECORD *
+EFIAPI
+FindImageRecord (
+  IN EFI_PHYSICAL_ADDRESS  ImageBase,
+  IN UINT64                ImageSize,
+  IN LIST_ENTRY            *ImageRecordList
+  )
+{
+  IMAGE_PROPERTIES_RECORD  *ImageRecord;
+  LIST_ENTRY               *ImageRecordLink;
+
+  for (ImageRecordLink = ImageRecordList->ForwardLink;
+       ImageRecordLink != ImageRecordList;
+       ImageRecordLink = ImageRecordLink->ForwardLink)
+  {
+    ImageRecord = CR (
+                    ImageRecordLink,
+                    IMAGE_PROPERTIES_RECORD,
+                    Link,
+                    IMAGE_PROPERTIES_RECORD_SIGNATURE
+                    );
+
+    if ((ImageBase == ImageRecord->ImageBase) &&
+        (ImageSize == ImageRecord->ImageSize))
+    {
+      return ImageRecord;
+    }
+  }
+
+  return NULL;
+}
diff --git a/MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h b/MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h
new file mode 100644
index 000000000000..64bbf572d596
--- /dev/null
+++ b/MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h
@@ -0,0 +1,151 @@
+/** @file
+
+  Provides definitions and functionality for manipulating Image Properties Records.
+
+  Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef IMAGE_PROPERTIES_RECORD_SUPPORT_LIB_H_
+#define IMAGE_PROPERTIES_RECORD_SUPPORT_LIB_H_
+
+#define IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE  SIGNATURE_32 ('I','P','R','C')
+
+typedef struct {
+  UINT32                  Signature;
+  LIST_ENTRY              Link;
+  EFI_PHYSICAL_ADDRESS    CodeSegmentBase;
+  UINT64                  CodeSegmentSize;
+} IMAGE_PROPERTIES_RECORD_CODE_SECTION;
+
+#define IMAGE_PROPERTIES_RECORD_SIGNATURE  SIGNATURE_32 ('I','P','R','D')
+
+typedef struct {
+  UINT32                  Signature;
+  LIST_ENTRY              Link;
+  EFI_PHYSICAL_ADDRESS    ImageBase;
+  UINT64                  ImageSize;
+  UINTN                   CodeSegmentCount;
+  LIST_ENTRY              CodeSegmentList;
+} IMAGE_PROPERTIES_RECORD;
+
+/**
+  Split the original memory map, and add more entries to describe PE code section and data section.
+  This function will set EfiRuntimeServicesData to be EFI_MEMORY_XP.
+  This function will merge entries with same attributes finally.
+
+  NOTE: It assumes PE code/data section are page aligned.
+  NOTE: It assumes enough entry is prepared for new memory map.
+
+  Split table:
+   +---------------+
+   | Record X      |
+   +---------------+
+   | Record RtCode |
+   +---------------+
+   | Record Y      |
+   +---------------+
+   ==>
+   +---------------+
+   | Record X      |
+   +---------------+ ----
+   | Record RtData |     |
+   +---------------+     |
+   | Record RtCode |     |-> PE/COFF1
+   +---------------+     |
+   | Record RtData |     |
+   +---------------+ ----
+   | Record RtData |     |
+   +---------------+     |
+   | Record RtCode |     |-> PE/COFF2
+   +---------------+     |
+   | Record RtData |     |
+   +---------------+ ----
+   | Record Y      |
+   +---------------+
+
+  @param  MemoryMapSize          A pointer to the size, in bytes, of the
+                                 MemoryMap buffer. On input, this is the size of
+                                 old MemoryMap before split. The actual buffer
+                                 size of MemoryMap is MemoryMapSize +
+                                 (AdditionalRecordCount * DescriptorSize) calculated
+                                 below. On output, it is the size of new MemoryMap
+                                 after split.
+  @param  MemoryMap              A pointer to the buffer in which firmware places
+                                 the current memory map.
+  @param  DescriptorSize         Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
+**/
+VOID
+EFIAPI
+SplitTable (
+  IN OUT UINTN                  *MemoryMapSize,
+  IN OUT EFI_MEMORY_DESCRIPTOR  *MemoryMap,
+  IN     UINTN                  DescriptorSize,
+  IN     LIST_ENTRY             *ImageRecordList,
+  IN     UINTN                  NumberOfAdditionalDescriptors
+  );
+
+/**
+  Sort code section in image record, based upon CodeSegmentBase from low to high.
+
+  @param  ImageRecord    image record to be sorted
+**/
+VOID
+EFIAPI
+SortImageRecordCodeSection (
+  IN IMAGE_PROPERTIES_RECORD  *ImageRecord
+  );
+
+/**
+  Check if code section in image record is valid.
+
+  @param  ImageRecord    image record to be checked
+
+  @retval TRUE  image record is valid
+  @retval FALSE image record is invalid
+**/
+BOOLEAN
+EFIAPI
+IsImageRecordCodeSectionValid (
+  IN IMAGE_PROPERTIES_RECORD  *ImageRecord
+  );
+
+/**
+  Sort image record based upon the ImageBase from low to high.
+**/
+VOID
+EFIAPI
+SortImageRecord (
+  IN     LIST_ENTRY  *ImageRecordList
+  );
+
+/**
+  Find image record according to image base and size.
+
+  @param[in]  ImageBase        Base of PE image
+  @param[in]  ImageSize        Size of PE image
+  @param[in]  ImageRecordList  A list of IMAGE_PROPERTIES_RECORD entries
+
+  @return image record
+**/
+IMAGE_PROPERTIES_RECORD *
+EFIAPI
+FindImageRecord (
+  IN EFI_PHYSICAL_ADDRESS  ImageBase,
+  IN UINT64                ImageSize,
+  IN LIST_ENTRY            *ImageRecordList
+  );
+
+/**
+  Dump image record.
+
+  @param[in]  ImageRecordList  A list of IMAGE_PROPERTIES_RECORD entries
+**/
+VOID
+EFIAPI
+DumpImageRecord (
+  IN LIST_ENTRY  *ImageRecordList
+  );
+
+#endif
diff --git a/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf b/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
new file mode 100644
index 000000000000..9062d20eb48b
--- /dev/null
+++ b/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
@@ -0,0 +1,28 @@
+## @file
+#  Provides definitions and functionality for manipulating
+#  Image Properties Records.
+#
+#  Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = ImagePropertiesRecordLib
+  FILE_GUID                      = 5CCA36C1-C430-4A90-8BF7-23D2719D5928
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = ImagePropertiesRecordLib
+
+[Sources.common]
+  ImagePropertiesRecordLib.c
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
index 0ff058b0a9da..80df553b2a5f 100644
--- a/MdeModulePkg/MdeModulePkg.dec
+++ b/MdeModulePkg/MdeModulePkg.dec
@@ -164,6 +164,11 @@ [LibraryClasses]
   #
   VariableFlashInfoLib|Include/Library/VariableFlashInfoLib.h
 
+  ##  @libraryclass   Memory Attribute Table support logic for tracking and reporting
+  #                   runtime images
+  #
+  ImagePropertiesRecordLib|Include/Library/ImagePropertiesRecordLib.h
+
 [Guids]
   ## MdeModule package token space guid
   # Include/Guid/MdeModulePkgTokenSpace.h
diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc
index db3b5af53795..6444111b9214 100644
--- a/MdeModulePkg/MdeModulePkg.dsc
+++ b/MdeModulePkg/MdeModulePkg.dsc
@@ -96,6 +96,7 @@ [LibraryClasses]
   VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
   FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
   NonDiscoverableDeviceRegistrationLib|MdeModulePkg/Library/NonDiscoverableDeviceRegistrationLib/NonDiscoverableDeviceRegistrationLib.inf
+  ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
 
   FmpAuthenticationLib|MdeModulePkg/Library/FmpAuthenticationLibNull/FmpAuthenticationLibNull.inf
   CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
@@ -237,6 +238,7 @@ [Components]
   MdeModulePkg/Library/BaseHobLibNull/BaseHobLibNull.inf
   MdeModulePkg/Library/BaseMemoryAllocationLibNull/BaseMemoryAllocationLibNull.inf
   MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf
+  MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
 
   MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
   MdeModulePkg/Bus/Pci/PciSioSerialDxe/PciSioSerialDxe.inf
-- 
2.41.0.windows.2



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



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

* [edk2-devel] [PATCH v2 2/9] MdeModulePkg: Add ImagePropertiesRecordLib Host-Based Unit Test
  2023-07-20  0:05 [edk2-devel] [PATCH v2 0/9] Add ImagePropertiesRecordLib and Fix MAT Bugs Taylor Beebe
  2023-07-20  0:05 ` [edk2-devel] [PATCH v2 1/9] MdeModulePkg: Add ImagePropertiesRecordLib Taylor Beebe
@ 2023-07-20  0:05 ` Taylor Beebe
  2023-07-20  0:05 ` [edk2-devel] [PATCH v2 3/9] MdeModulePkg: Fix Bugs in MAT Logic Taylor Beebe
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Taylor Beebe @ 2023-07-20  0:05 UTC (permalink / raw)
  To: devel; +Cc: Jian J Wang, Liming Gao, Dandan Bi

Create a host-based unit test for the ImagePropertiesRecordLib
SplitTable() logic. This test has 4 cases which tests different
potential image and memory map layouts. 3/4 of these tests fail
with the logic in its current state to provide proof of the bugs
in the current MAT logic.

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/Library/ImagePropertiesRecordLib/UnitTest/ImagePropertiesRecordLibUnitTestHost.c   | 938 ++++++++++++++++++++
 MdeModulePkg/Library/ImagePropertiesRecordLib/UnitTest/ImagePropertiesRecordLibUnitTestHost.inf |  35 +
 MdeModulePkg/Test/MdeModulePkgHostTest.dsc                                                      |   5 +
 3 files changed, 978 insertions(+)

diff --git a/MdeModulePkg/Library/ImagePropertiesRecordLib/UnitTest/ImagePropertiesRecordLibUnitTestHost.c b/MdeModulePkg/Library/ImagePropertiesRecordLib/UnitTest/ImagePropertiesRecordLibUnitTestHost.c
new file mode 100644
index 000000000000..8b0a55685ce3
--- /dev/null
+++ b/MdeModulePkg/Library/ImagePropertiesRecordLib/UnitTest/ImagePropertiesRecordLibUnitTestHost.c
@@ -0,0 +1,938 @@
+/** @file
+  Unit tests the SplitTable() ImagePropertiesRecordLib Logic
+
+  Copyright (C) Microsoft Corporation.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UnitTestLib.h>
+#include <Library/ImagePropertiesRecordLib.h>
+
+#define UNIT_TEST_APP_NAME     "Image Properties Record Lib Unit Test"
+#define UNIT_TEST_APP_VERSION  "1.0"
+
+#define NEXT_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \
+  ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) + (Size)))
+
+// The starting memory map will contain 6 entries
+#define NUMBER_OF_MEMORY_MAP_DESCRIPTORS  6
+
+// Each memory map descriptor will be the sizeof(EFI_MEMORY_DESCRIPTOR) instead of a nonstandard size
+// to catch pointer math issues
+#define DESCRIPTOR_SIZE  sizeof(EFI_MEMORY_DESCRIPTOR)
+
+// Each memory map descriptor will describe 12 pages
+#define BASE_DESCRIPTOR_NUMBER_OF_PAGES  0x0C
+
+// The size, in bytes, of each memory map descriptor range
+#define BASE_DESCRIPTOR_ENTRY_SIZE  (EFI_PAGES_TO_SIZE(BASE_DESCRIPTOR_NUMBER_OF_PAGES))
+
+// MACRO to get the starting address of a descriptor's described range based on the index of that descriptor
+#define BASE_DESCRIPTOR_START_ADDRESS(DescriptorNumber)  (DescriptorNumber * BASE_DESCRIPTOR_ENTRY_SIZE)
+
+// Virtual start must be zero
+#define BASE_DESCRIPTOR_VIRTUAL_START  0x0
+
+// Size of the default memory map
+#define BASE_MEMORY_MAP_SIZE  (NUMBER_OF_MEMORY_MAP_DESCRIPTORS * DESCRIPTOR_SIZE)
+
+// Number of images in each test case
+#define NUMBER_OF_IMAGES_TO_SPLIT  3
+
+// Maximum number of descriptors required for each image (None->Data->Code->Data->Code->Data->None)
+#define MAX_DESCRIPTORS_PER_IMAGE  7
+
+// Number of unused additional descriptors in the starting memory map buffer which is used by the
+// SplitTable() logic
+#define NUMBER_OF_ADDITIONAL_DESCRIPTORS  (NUMBER_OF_IMAGES_TO_SPLIT * MAX_DESCRIPTORS_PER_IMAGE)
+
+// Size of the memory map with enough space for the starting descriptors and the split descriptors
+#define SPLIT_MEMORY_MAP_SIZE  (BASE_MEMORY_MAP_SIZE + (NUMBER_OF_ADDITIONAL_DESCRIPTORS * DESCRIPTOR_SIZE))
+
+typedef enum {
+  SectionTypeCode,
+  SectionTypeData,
+  SectionTypeNotFound
+} SECTION_TYPE;
+
+typedef struct {
+  EFI_MEMORY_DESCRIPTOR    *MemoryMap;
+  LIST_ENTRY               ImageList;
+} IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT;
+
+EFI_MEMORY_DESCRIPTOR  BaseMemoryMap[] = {
+  {
+    EfiConventionalMemory,             // Type
+    BASE_DESCRIPTOR_START_ADDRESS (0), // PhysicalStart
+    BASE_DESCRIPTOR_VIRTUAL_START,     // VirtualStart
+    BASE_DESCRIPTOR_NUMBER_OF_PAGES,   // Number of Pages
+    0                                  // Attribute
+  },
+  {
+    EfiConventionalMemory,             // Type
+    BASE_DESCRIPTOR_START_ADDRESS (1), // PhysicalStart
+    BASE_DESCRIPTOR_VIRTUAL_START,     // VirtualStart
+    BASE_DESCRIPTOR_NUMBER_OF_PAGES,   // Number of Pages
+    0                                  // Attribute
+  },
+  {
+    EfiConventionalMemory,             // Type
+    BASE_DESCRIPTOR_START_ADDRESS (2), // PhysicalStart
+    BASE_DESCRIPTOR_VIRTUAL_START,     // VirtualStart
+    BASE_DESCRIPTOR_NUMBER_OF_PAGES,   // Number of Pages
+    0                                  // Attribute
+  },
+  {
+    EfiConventionalMemory,             // Type
+    BASE_DESCRIPTOR_START_ADDRESS (3), // PhysicalStart
+    BASE_DESCRIPTOR_VIRTUAL_START,     // VirtualStart
+    BASE_DESCRIPTOR_NUMBER_OF_PAGES,   // Number of Pages
+    0                                  // Attribute
+  },
+  {
+    EfiConventionalMemory,             // Type
+    BASE_DESCRIPTOR_START_ADDRESS (4), // PhysicalStart
+    BASE_DESCRIPTOR_VIRTUAL_START,     // VirtualStart
+    BASE_DESCRIPTOR_NUMBER_OF_PAGES,   // Number of Pages
+    0                                  // Attribute
+  },
+  {
+    EfiConventionalMemory,             // Type
+    BASE_DESCRIPTOR_START_ADDRESS (5), // PhysicalStart
+    BASE_DESCRIPTOR_VIRTUAL_START,     // VirtualStart
+    BASE_DESCRIPTOR_NUMBER_OF_PAGES,   // Number of Pages
+    0                                  // Attribute
+  }
+};
+
+/**
+  Returns a bitmap where one bit is set for each section in the image list. For example, if
+  there are 3 images and each image 3 sections the returned bitmap will be 111111111.
+
+  @param[in]  ImageRecordList   A list of IMAGE_PROPERTIES_RECORD entries
+
+  @retval A bitmap such that the most significant bit is the number of sections
+          in all images and every bit between 0 -> MSB is set
+
+**/
+STATIC
+UINT64
+GetImageSectionBitmap (
+  IN LIST_ENTRY  *ImageRecordList
+  )
+{
+  IMAGE_PROPERTIES_RECORD               *ImageRecord;
+  IMAGE_PROPERTIES_RECORD_CODE_SECTION  *ImageRecordCodeSection;
+  LIST_ENTRY                            *ImageRecordLink;
+  LIST_ENTRY                            *ImageRecordCodeSectionLink;
+  EFI_PHYSICAL_ADDRESS                  SectionBase;
+  UINT64                                ReturnBitmap;
+  UINT64                                Shift;
+
+  if (ImageRecordList == NULL) {
+    return 0;
+  }
+
+  ReturnBitmap = 0;
+  Shift        = 0;
+
+  // Walk through each image record
+  for (ImageRecordLink = ImageRecordList->ForwardLink;
+       ImageRecordLink != ImageRecordList;
+       ImageRecordLink = ImageRecordLink->ForwardLink)
+  {
+    ImageRecord = CR (
+                    ImageRecordLink,
+                    IMAGE_PROPERTIES_RECORD,
+                    Link,
+                    IMAGE_PROPERTIES_RECORD_SIGNATURE
+                    );
+
+    SectionBase = ImageRecord->ImageBase;
+
+    // Walk through each code entry
+    for (ImageRecordCodeSectionLink = ImageRecord->CodeSegmentList.ForwardLink;
+         ImageRecordCodeSectionLink != &ImageRecord->CodeSegmentList;
+         ImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink)
+    {
+      ImageRecordCodeSection = CR (
+                                 ImageRecordCodeSectionLink,
+                                 IMAGE_PROPERTIES_RECORD_CODE_SECTION,
+                                 Link,
+                                 IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
+                                 );
+
+      // Check for data region before the code section base
+      if (SectionBase < ImageRecordCodeSection->CodeSegmentBase) {
+        ReturnBitmap |= LShiftU64 (1, Shift++);
+      }
+
+      // Code section
+      ReturnBitmap |= LShiftU64 (1, Shift++);
+      SectionBase   = ImageRecordCodeSection->CodeSegmentBase + ImageRecordCodeSection->CodeSegmentSize;
+    }
+
+    // Check for data region after the previous code section
+    if (SectionBase < (ImageRecord->ImageBase + ImageRecord->ImageSize)) {
+      ReturnBitmap |= LShiftU64 (1, Shift++);
+    }
+  }
+
+  return ReturnBitmap;
+}
+
+/**
+  Searches the input image list for a section which exactly matches the memory range Buffer -> Buffer + Length.
+
+  @param[in] Buffer           Start Address to check
+  @param[in] Length           Length to check
+  @param[out] Type             The type of the section which corresponds with the memory
+                              range Buffer -> Buffer + Length (Code or Data) or SectionTypeNotFound
+                              if no image section matches the memory range
+  @param[in] ImageRecordList  A list of IMAGE_PROPERTIES_RECORD entries to check against
+                              the memory range Buffer -> Buffer + Length
+
+  @retval A bitmap with a single bit set (1 << Shift) where Shift corresponds with the number of sections inspected
+          in the image list before arriving at the section matching the memory range Buffer -> Buffer + Length
+**/
+STATIC
+UINT64
+MatchDescriptorToImageSection (
+  IN  EFI_PHYSICAL_ADDRESS  Buffer,
+  IN  UINT64                Length,
+  OUT SECTION_TYPE          *Type,
+  IN  LIST_ENTRY            *ImageRecordList
+  )
+{
+  IMAGE_PROPERTIES_RECORD               *ImageRecord;
+  IMAGE_PROPERTIES_RECORD_CODE_SECTION  *ImageRecordCodeSection;
+  LIST_ENTRY                            *ImageRecordLink;
+  LIST_ENTRY                            *ImageRecordCodeSectionLink;
+  EFI_PHYSICAL_ADDRESS                  SectionBase;
+  UINT8                                 Shift;
+
+  Shift = 0;
+
+  if (ImageRecordList == NULL) {
+    return 1;
+  }
+
+  // Walk through each image record
+  for (ImageRecordLink = ImageRecordList->ForwardLink;
+       ImageRecordLink != ImageRecordList;
+       ImageRecordLink = ImageRecordLink->ForwardLink)
+  {
+    ImageRecord = CR (
+                    ImageRecordLink,
+                    IMAGE_PROPERTIES_RECORD,
+                    Link,
+                    IMAGE_PROPERTIES_RECORD_SIGNATURE
+                    );
+
+    SectionBase = ImageRecord->ImageBase;
+
+    // Walk through each code entry
+    for (ImageRecordCodeSectionLink = ImageRecord->CodeSegmentList.ForwardLink;
+         ImageRecordCodeSectionLink != &ImageRecord->CodeSegmentList;
+         ImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink)
+    {
+      ImageRecordCodeSection = CR (
+                                 ImageRecordCodeSectionLink,
+                                 IMAGE_PROPERTIES_RECORD_CODE_SECTION,
+                                 Link,
+                                 IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
+                                 );
+
+      if (SectionBase < ImageRecordCodeSection->CodeSegmentBase) {
+        // Check the data region before the code section base
+        if ((Buffer == SectionBase) &&
+            (Length == ImageRecordCodeSection->CodeSegmentBase - SectionBase))
+        {
+          *Type = SectionTypeData;
+          return LShiftU64 (1, Shift);
+        }
+
+        Shift++;
+      }
+
+      // Check the code region
+      if ((Buffer == ImageRecordCodeSection->CodeSegmentBase) &&
+          (Length == ImageRecordCodeSection->CodeSegmentSize))
+      {
+        *Type = SectionTypeCode;
+        return LShiftU64 (1, Shift);
+      }
+
+      Shift++;
+      SectionBase = ImageRecordCodeSection->CodeSegmentBase + ImageRecordCodeSection->CodeSegmentSize;
+    }
+
+    // Check the data region after the code section
+    if (SectionBase < (ImageRecord->ImageBase + ImageRecord->ImageSize)) {
+      if ((Buffer == SectionBase) &&
+          (Length == (ImageRecord->ImageBase + ImageRecord->ImageSize) - SectionBase))
+      {
+        *Type = SectionTypeData;
+        return LShiftU64 (1, Shift);
+      }
+
+      Shift++;
+    }
+  }
+
+  // No image sections match
+  *Type = SectionTypeNotFound;
+  return 0;
+}
+
+/**
+  Walks through the input memory map and checks that every memory descriptor with an attribute matches
+  an image in ImageRecordList.
+
+  @param[in]        MemoryMapSize                 The size, in bytes, of the memory map
+  @param[in]        MemoryMap                     A pointer to the buffer containing the memory map
+  @param[in]        ImageRecordList               A list of IMAGE_PROPERTIES_RECORD entries
+
+  @retval TRUE if all memory descriptors with attributes match an image section and have the correct attributes
+
+**/
+STATIC
+BOOLEAN
+IsMemoryMapValid (
+  IN UINTN                  MemoryMapSize,
+  IN EFI_MEMORY_DESCRIPTOR  *MemoryMap,
+  IN LIST_ENTRY             *ImageRecordList
+  )
+{
+  UINT64        ImageSectionsBitmap;
+  UINT64        ReturnSectionBitmask;
+  UINT64        NumberOfDescriptors;
+  UINT8         Index;
+  SECTION_TYPE  Type;
+
+  Index               = 0;
+  NumberOfDescriptors = MemoryMapSize / DESCRIPTOR_SIZE;
+
+  UT_ASSERT_EQUAL (MemoryMapSize % DESCRIPTOR_SIZE, 0);
+  UT_ASSERT_NOT_NULL (MemoryMap);
+  UT_ASSERT_NOT_NULL (ImageRecordList);
+
+  // The returned bitmap will have one bit is set for each section in the image list.
+  // If there are 3 images and 3 sections each image, the resulting bitmap will
+  // be 0000000000000000000000000000000000000000000000000000000111111111. Flipping that bitmap
+  // results in 1111111111111111111111111111111111111111111111111111111000000000. The return value
+  // of each iteration through MatchDescriptorToImageSection() is one set bit corrosponding to the number
+  // of sections before finding the section which matched the descriptor memory range which we
+  // OR with ImageSectionsBitmap. If, at the end of the loop, every bit in ImageSectionsBitmap is set,
+  // we must have matched every image in ImageRecordList with a descriptor in the memory map which has
+  // nonzero attributes.
+  ImageSectionsBitmap = ~GetImageSectionBitmap (ImageRecordList);
+
+  // For each descriptor in the memory map
+  for ( ; Index < NumberOfDescriptors; Index++) {
+    if (MemoryMap[Index].Attribute != 0) {
+      ReturnSectionBitmask = MatchDescriptorToImageSection (
+                               MemoryMap[Index].PhysicalStart,
+                               EFI_PAGES_TO_SIZE (MemoryMap[Index].NumberOfPages),
+                               &Type,
+                               ImageRecordList
+                               );
+
+      // Make sure the attributes of the descriptor match the returned section type.
+      // DATA sections should have execution protection and CODE sections should have
+      // write protection.
+      if ((Type == SectionTypeNotFound) ||
+          ((Type == SectionTypeData) && (MemoryMap[Index].Attribute == EFI_MEMORY_RP)) ||
+          ((Type == SectionTypeCode) && (MemoryMap[Index].Attribute == EFI_MEMORY_XP)))
+      {
+        return FALSE;
+      }
+
+      // If the bit associated with image found has already been set, then there must be a duplicate
+      // in the memory map meaning it is invalid.
+      UT_ASSERT_EQUAL (ImageSectionsBitmap & ReturnSectionBitmask, 0);
+
+      ImageSectionsBitmap |= ReturnSectionBitmask;
+    }
+  }
+
+  // If every bit in ImageSectionsBitmap is set, the return value will be TRUE
+  return !(~ImageSectionsBitmap);
+}
+
+/**
+  Separate the image sections in the memory map and run a check to ensure the output is valid.
+
+  @param[in]  Context   Context containing the memory map and image record pointers
+
+  @retval TRUE if the memory map is split correctly
+**/
+STATIC
+BOOLEAN
+SeparateAndCheck (
+  IN IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT  *Context
+  )
+{
+  UINTN  MemoryMapSize;
+
+  MemoryMapSize = BASE_MEMORY_MAP_SIZE;
+
+  // Separate the memory map so each image section has its own descriptor
+  SplitTable (
+    &MemoryMapSize,
+    Context->MemoryMap,
+    DESCRIPTOR_SIZE,
+    &Context->ImageList,
+    NUMBER_OF_ADDITIONAL_DESCRIPTORS
+    );
+
+  // Ensure the updated memory map is valid
+  return IsMemoryMapValid (MemoryMapSize, Context->MemoryMap, &Context->ImageList);
+}
+
+/**
+  Test the case where the image range contains multiple code sections and does not perfectly align with
+  the existing memory descriptor.
+
+  @param[in]  Context   Context containing the memory map and image record pointers
+
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test
+                                        case was successful.
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.
+**/
+UNIT_TEST_STATUS
+EFIAPI
+MaxOutAdditionalDescriptors (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  IMAGE_PROPERTIES_RECORD                    *Image1;
+  IMAGE_PROPERTIES_RECORD                    *Image2;
+  IMAGE_PROPERTIES_RECORD                    *Image3;
+  IMAGE_PROPERTIES_RECORD_CODE_SECTION       *CodeSectionInImage1;
+  IMAGE_PROPERTIES_RECORD_CODE_SECTION       *CodeSectionInImage2;
+  IMAGE_PROPERTIES_RECORD_CODE_SECTION       *CodeSectionInImage3;
+  IMAGE_PROPERTIES_RECORD_CODE_SECTION       *AddCodeSectionInImage1;
+  IMAGE_PROPERTIES_RECORD_CODE_SECTION       *AddCodeSectionInImage2;
+  IMAGE_PROPERTIES_RECORD_CODE_SECTION       *AddCodeSectionInImage3;
+  IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT  *TestContext;
+
+  TestContext = (IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT *)Context;
+
+  Image1 = CR (TestContext->ImageList.ForwardLink, IMAGE_PROPERTIES_RECORD, Link, IMAGE_PROPERTIES_RECORD_SIGNATURE);
+  Image2 = CR (Image1->Link.ForwardLink, IMAGE_PROPERTIES_RECORD, Link, IMAGE_PROPERTIES_RECORD_SIGNATURE);
+  Image3 = CR (Image2->Link.ForwardLink, IMAGE_PROPERTIES_RECORD, Link, IMAGE_PROPERTIES_RECORD_SIGNATURE);
+
+  CodeSectionInImage1 = CR (Image1->CodeSegmentList.ForwardLink, IMAGE_PROPERTIES_RECORD_CODE_SECTION, Link, IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE);
+  CodeSectionInImage2 = CR (Image2->CodeSegmentList.ForwardLink, IMAGE_PROPERTIES_RECORD_CODE_SECTION, Link, IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE);
+  CodeSectionInImage3 = CR (Image3->CodeSegmentList.ForwardLink, IMAGE_PROPERTIES_RECORD_CODE_SECTION, Link, IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE);
+
+  ///////////////
+  // Descriptor 1
+  ///////////////
+  // |         |      |      |      |      |      |             |
+  // | 4K PAGE | DATA | CODE | DATA | CODE | DATA | 4K PAGE * 5 |
+  // |         |      |      |      |      |      |             |
+
+  Image1->ImageBase                    = BASE_DESCRIPTOR_START_ADDRESS (1) + EFI_PAGE_SIZE;
+  Image1->ImageSize                    = BASE_DESCRIPTOR_ENTRY_SIZE - EFI_PAGE_SIZE - EFI_PAGE_SIZE;
+  Image1->CodeSegmentCount             = 2;
+  CodeSectionInImage1->CodeSegmentBase = Image1->ImageBase + EFI_PAGE_SIZE;
+  CodeSectionInImage1->CodeSegmentSize = EFI_PAGE_SIZE;
+  TestContext->MemoryMap[1].Type       = EfiBootServicesCode;
+
+  AddCodeSectionInImage1                  = AllocateZeroPool (sizeof (IMAGE_PROPERTIES_RECORD_CODE_SECTION));
+  AddCodeSectionInImage1->Signature       = IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE;
+  AddCodeSectionInImage1->CodeSegmentBase = CodeSectionInImage1->CodeSegmentBase + CodeSectionInImage1->CodeSegmentSize + EFI_PAGE_SIZE;
+  AddCodeSectionInImage1->CodeSegmentSize = EFI_PAGE_SIZE;
+
+  InsertTailList (&Image1->CodeSegmentList, &AddCodeSectionInImage1->Link);
+
+  ///////////////
+  // Descriptor 2
+  ///////////////
+  // |         |      |      |      |      |      |             |
+  // | 4K PAGE | DATA | CODE | DATA | CODE | DATA | 4K PAGE * 5 |
+  // |         |      |      |      |      |      |             |
+
+  Image2->ImageBase                    = BASE_DESCRIPTOR_START_ADDRESS (2) + EFI_PAGE_SIZE;
+  Image2->ImageSize                    = BASE_DESCRIPTOR_ENTRY_SIZE - EFI_PAGE_SIZE - EFI_PAGE_SIZE;
+  Image2->CodeSegmentCount             = 2;
+  CodeSectionInImage2->CodeSegmentBase = Image2->ImageBase + EFI_PAGE_SIZE;
+  CodeSectionInImage2->CodeSegmentSize = EFI_PAGE_SIZE;
+  TestContext->MemoryMap[2].Type       = EfiLoaderCode;
+
+  AddCodeSectionInImage2                  = AllocateZeroPool (sizeof (IMAGE_PROPERTIES_RECORD_CODE_SECTION));
+  AddCodeSectionInImage2->Signature       = IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE;
+  AddCodeSectionInImage2->CodeSegmentBase = CodeSectionInImage2->CodeSegmentBase + CodeSectionInImage2->CodeSegmentSize + EFI_PAGE_SIZE;
+  AddCodeSectionInImage2->CodeSegmentSize = EFI_PAGE_SIZE;
+
+  InsertTailList (&Image2->CodeSegmentList, &AddCodeSectionInImage2->Link);
+
+  ///////////////
+  // Descriptor 3
+  ///////////////
+  // |         |      |      |      |      |      |             |
+  // | 4K PAGE | DATA | CODE | DATA | CODE | DATA | 4K PAGE * 5 |
+  // |         |      |      |      |      |      |             |
+
+  Image3->ImageBase                    = BASE_DESCRIPTOR_START_ADDRESS (3) + EFI_PAGE_SIZE;
+  Image3->ImageSize                    = BASE_DESCRIPTOR_ENTRY_SIZE - EFI_PAGE_SIZE - EFI_PAGE_SIZE;
+  Image3->CodeSegmentCount             = 2;
+  CodeSectionInImage3->CodeSegmentBase = Image3->ImageBase + EFI_PAGE_SIZE;
+  CodeSectionInImage3->CodeSegmentSize = EFI_PAGE_SIZE;
+  TestContext->MemoryMap[3].Type       = EfiRuntimeServicesCode;
+
+  AddCodeSectionInImage3                  = AllocateZeroPool (sizeof (IMAGE_PROPERTIES_RECORD_CODE_SECTION));
+  AddCodeSectionInImage3->Signature       = IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE;
+  AddCodeSectionInImage3->CodeSegmentBase = CodeSectionInImage3->CodeSegmentBase + CodeSectionInImage3->CodeSegmentSize + EFI_PAGE_SIZE;
+  AddCodeSectionInImage3->CodeSegmentSize = EFI_PAGE_SIZE;
+
+  InsertTailList (&Image3->CodeSegmentList, &AddCodeSectionInImage3->Link);
+
+  UT_ASSERT_TRUE (SeparateAndCheck (TestContext));
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Test the case where multiple image ranges lie within an existing memory descriptor.
+
+  @param[in]  Context   Context containing the memory map and image record pointers
+
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test
+                                        case was successful.
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.
+**/
+UNIT_TEST_STATUS
+EFIAPI
+MultipleImagesInOneDescriptor (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  IMAGE_PROPERTIES_RECORD                    *Image1;
+  IMAGE_PROPERTIES_RECORD                    *Image2;
+  IMAGE_PROPERTIES_RECORD                    *Image3;
+  IMAGE_PROPERTIES_RECORD_CODE_SECTION       *CodeSectionInImage1;
+  IMAGE_PROPERTIES_RECORD_CODE_SECTION       *CodeSectionInImage2;
+  IMAGE_PROPERTIES_RECORD_CODE_SECTION       *CodeSectionInImage3;
+  IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT  *TestContext;
+
+  TestContext = (IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT *)Context;
+
+  Image1 = CR (TestContext->ImageList.ForwardLink, IMAGE_PROPERTIES_RECORD, Link, IMAGE_PROPERTIES_RECORD_SIGNATURE);
+  Image2 = CR (Image1->Link.ForwardLink, IMAGE_PROPERTIES_RECORD, Link, IMAGE_PROPERTIES_RECORD_SIGNATURE);
+  Image3 = CR (Image2->Link.ForwardLink, IMAGE_PROPERTIES_RECORD, Link, IMAGE_PROPERTIES_RECORD_SIGNATURE);
+
+  CodeSectionInImage1 = CR (Image1->CodeSegmentList.ForwardLink, IMAGE_PROPERTIES_RECORD_CODE_SECTION, Link, IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE);
+  CodeSectionInImage2 = CR (Image2->CodeSegmentList.ForwardLink, IMAGE_PROPERTIES_RECORD_CODE_SECTION, Link, IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE);
+  CodeSectionInImage3 = CR (Image3->CodeSegmentList.ForwardLink, IMAGE_PROPERTIES_RECORD_CODE_SECTION, Link, IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE);
+
+  ///////////////
+  // Descriptor 1
+  ///////////////
+  // |         |      |      |      |         |      |      |      |      |      |      |         |
+  // | 4K PAGE | DATA | CODE | DATA | 4K PAGE | DATA | CODE | DATA | DATA | CODE | DATA | 4K PAGE |
+  // |         |      |      |      |         |      |      |      |      |      |      |         |
+
+  Image1->ImageBase                    = BASE_DESCRIPTOR_START_ADDRESS (1) + EFI_PAGE_SIZE;
+  Image1->ImageSize                    = EFI_PAGES_TO_SIZE (3);
+  Image1->CodeSegmentCount             = 1;
+  CodeSectionInImage1->CodeSegmentBase = Image1->ImageBase + EFI_PAGE_SIZE;
+  CodeSectionInImage1->CodeSegmentSize = EFI_PAGE_SIZE;
+  TestContext->MemoryMap[1].Type       = EfiBootServicesCode;
+
+  Image2->ImageBase                    = Image1->ImageBase + Image1->ImageSize + EFI_PAGE_SIZE;
+  Image2->ImageSize                    = EFI_PAGES_TO_SIZE (3);
+  Image2->CodeSegmentCount             = 1;
+  CodeSectionInImage2->CodeSegmentBase = Image2->ImageBase + EFI_PAGE_SIZE;
+  CodeSectionInImage2->CodeSegmentSize = EFI_PAGE_SIZE;
+
+  Image3->ImageBase                    = Image2->ImageBase + Image2->ImageSize;
+  Image3->ImageSize                    = EFI_PAGES_TO_SIZE (3);
+  Image3->CodeSegmentCount             = 1;
+  CodeSectionInImage3->CodeSegmentBase = Image3->ImageBase + EFI_PAGE_SIZE;
+  CodeSectionInImage3->CodeSegmentSize = EFI_PAGE_SIZE;
+
+  UT_ASSERT_TRUE (SeparateAndCheck (TestContext));
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Test the case where all image ranges do not fit perfectly within an existing memory descriptor.
+
+  @param[in]  Context   Context containing the memory map and image record pointers
+
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test
+                                        case was successful.
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.
+**/
+UNIT_TEST_STATUS
+EFIAPI
+ImagesDontFitDescriptors (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  IMAGE_PROPERTIES_RECORD                    *Image1;
+  IMAGE_PROPERTIES_RECORD                    *Image2;
+  IMAGE_PROPERTIES_RECORD                    *Image3;
+  IMAGE_PROPERTIES_RECORD_CODE_SECTION       *CodeSectionInImage1;
+  IMAGE_PROPERTIES_RECORD_CODE_SECTION       *CodeSectionInImage2;
+  IMAGE_PROPERTIES_RECORD_CODE_SECTION       *CodeSectionInImage3;
+  IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT  *TestContext;
+
+  TestContext = (IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT *)Context;
+
+  Image1 = CR (TestContext->ImageList.ForwardLink, IMAGE_PROPERTIES_RECORD, Link, IMAGE_PROPERTIES_RECORD_SIGNATURE);
+  Image2 = CR (Image1->Link.ForwardLink, IMAGE_PROPERTIES_RECORD, Link, IMAGE_PROPERTIES_RECORD_SIGNATURE);
+  Image3 = CR (Image2->Link.ForwardLink, IMAGE_PROPERTIES_RECORD, Link, IMAGE_PROPERTIES_RECORD_SIGNATURE);
+
+  CodeSectionInImage1 = CR (Image1->CodeSegmentList.ForwardLink, IMAGE_PROPERTIES_RECORD_CODE_SECTION, Link, IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE);
+  CodeSectionInImage2 = CR (Image2->CodeSegmentList.ForwardLink, IMAGE_PROPERTIES_RECORD_CODE_SECTION, Link, IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE);
+  CodeSectionInImage3 = CR (Image3->CodeSegmentList.ForwardLink, IMAGE_PROPERTIES_RECORD_CODE_SECTION, Link, IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE);
+
+  ///////////////
+  // Descriptor 1
+  ///////////////
+  // |         |      |          |          |
+  // | 4K PAGE | DATA | CODE * 2 | DATA * 8 |
+  // |         |      |          |          |
+
+  Image1->ImageBase                    = BASE_DESCRIPTOR_START_ADDRESS (1) + EFI_PAGE_SIZE;
+  Image1->ImageSize                    = BASE_DESCRIPTOR_ENTRY_SIZE - EFI_PAGE_SIZE;
+  Image1->CodeSegmentCount             = 1;
+  CodeSectionInImage1->CodeSegmentBase = Image1->ImageBase + EFI_PAGE_SIZE;
+  CodeSectionInImage1->CodeSegmentSize = EFI_PAGES_TO_SIZE (2);
+  TestContext->MemoryMap[1].Type       = EfiBootServicesCode;
+
+  ///////////////
+  // Descriptor 3
+  ///////////////
+  // |      |          |          |         |
+  // | DATA | CODE * 3 | DATA * 7 | 4K PAGE |
+  // |      |          |          |         |
+
+  Image2->ImageBase                    = BASE_DESCRIPTOR_START_ADDRESS (3);
+  Image2->ImageSize                    = BASE_DESCRIPTOR_ENTRY_SIZE - EFI_PAGE_SIZE;
+  Image2->CodeSegmentCount             = 1;
+  CodeSectionInImage2->CodeSegmentBase = Image2->ImageBase + EFI_PAGE_SIZE;
+  CodeSectionInImage2->CodeSegmentSize = EFI_PAGES_TO_SIZE (3);
+  TestContext->MemoryMap[3].Type       = EfiLoaderCode;
+
+  ///////////////
+  // Descriptor 4
+  ///////////////
+  // |         |      |          |          |         |
+  // | 4K PAGE | DATA | CODE * 2 | DATA * 7 | 4K PAGE |
+  // |         |      |          |          |         |
+
+  Image3->ImageBase                    = BASE_DESCRIPTOR_START_ADDRESS (4) + EFI_PAGE_SIZE;
+  Image3->ImageSize                    = BASE_DESCRIPTOR_ENTRY_SIZE - EFI_PAGE_SIZE - EFI_PAGE_SIZE;
+  Image3->CodeSegmentCount             = 1;
+  CodeSectionInImage3->CodeSegmentBase = Image3->ImageBase + EFI_PAGE_SIZE;
+  CodeSectionInImage3->CodeSegmentSize = EFI_PAGES_TO_SIZE (2);
+  TestContext->MemoryMap[4].Type       = EfiRuntimeServicesCode;
+
+  UT_ASSERT_TRUE (SeparateAndCheck (TestContext));
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Test the case where all image ranges fit perfectly within an existing memory descriptor.
+
+  @param[in]  Context   Context containing the memory map and image record pointers
+
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test
+                                        case was successful.
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.
+**/
+UNIT_TEST_STATUS
+EFIAPI
+ImagesFitDescriptors (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  IMAGE_PROPERTIES_RECORD                    *Image1;
+  IMAGE_PROPERTIES_RECORD                    *Image2;
+  IMAGE_PROPERTIES_RECORD                    *Image3;
+  IMAGE_PROPERTIES_RECORD_CODE_SECTION       *CodeSectionInImage1;
+  IMAGE_PROPERTIES_RECORD_CODE_SECTION       *CodeSectionInImage2;
+  IMAGE_PROPERTIES_RECORD_CODE_SECTION       *CodeSectionInImage3;
+  IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT  *TestContext;
+
+  TestContext = (IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT *)Context;
+
+  Image1 = CR (TestContext->ImageList.ForwardLink, IMAGE_PROPERTIES_RECORD, Link, IMAGE_PROPERTIES_RECORD_SIGNATURE);
+  Image2 = CR (Image1->Link.ForwardLink, IMAGE_PROPERTIES_RECORD, Link, IMAGE_PROPERTIES_RECORD_SIGNATURE);
+  Image3 = CR (Image2->Link.ForwardLink, IMAGE_PROPERTIES_RECORD, Link, IMAGE_PROPERTIES_RECORD_SIGNATURE);
+
+  CodeSectionInImage1 = CR (Image1->CodeSegmentList.ForwardLink, IMAGE_PROPERTIES_RECORD_CODE_SECTION, Link, IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE);
+  CodeSectionInImage2 = CR (Image2->CodeSegmentList.ForwardLink, IMAGE_PROPERTIES_RECORD_CODE_SECTION, Link, IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE);
+  CodeSectionInImage3 = CR (Image3->CodeSegmentList.ForwardLink, IMAGE_PROPERTIES_RECORD_CODE_SECTION, Link, IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE);
+
+  ///////////////
+  // Descriptor 1
+  ///////////////
+  // |      |          |          |
+  // | DATA | CODE * 3 | DATA * 8 |
+  // |      |          |          |
+
+  Image1->ImageBase                    = BASE_DESCRIPTOR_START_ADDRESS (1);
+  Image1->ImageSize                    = BASE_DESCRIPTOR_ENTRY_SIZE;
+  Image1->CodeSegmentCount             = 1;
+  CodeSectionInImage1->CodeSegmentBase = Image1->ImageBase + EFI_PAGE_SIZE;
+  CodeSectionInImage1->CodeSegmentSize = EFI_PAGES_TO_SIZE (3);
+  TestContext->MemoryMap[1].Type       = EfiBootServicesCode;
+
+  ///////////////
+  // Descriptor 2
+  ///////////////
+  // |      |          |          |
+  // | DATA | CODE * 4 | DATA * 7 |
+  // |      |          |          |
+
+  Image2->ImageBase                    = BASE_DESCRIPTOR_START_ADDRESS (2);
+  Image2->ImageSize                    = BASE_DESCRIPTOR_ENTRY_SIZE;
+  Image2->CodeSegmentCount             = 1;
+  CodeSectionInImage2->CodeSegmentBase = Image2->ImageBase + EFI_PAGE_SIZE;
+  CodeSectionInImage2->CodeSegmentSize = EFI_PAGES_TO_SIZE (4);
+  TestContext->MemoryMap[2].Type       = EfiLoaderCode;
+
+  ///////////////
+  // Descriptor 3
+  ///////////////
+  // |      |          |          |
+  // | DATA | CODE * 3 | DATA * 8 |
+  // |      |          |          |
+
+  Image3->ImageBase                    = BASE_DESCRIPTOR_START_ADDRESS (3);
+  Image3->ImageSize                    = BASE_DESCRIPTOR_ENTRY_SIZE;
+  Image3->CodeSegmentCount             = 1;
+  CodeSectionInImage3->CodeSegmentBase = Image3->ImageBase + EFI_PAGE_SIZE;
+  CodeSectionInImage3->CodeSegmentSize = EFI_PAGES_TO_SIZE (3);
+  TestContext->MemoryMap[3].Type       = EfiRuntimeServicesCode;
+
+  UT_ASSERT_TRUE (SeparateAndCheck (TestContext));
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Free all allocated memory.
+
+  @param[in]  Context   Context containing the memory map and image record pointers
+**/
+VOID
+EFIAPI
+TestCleanup (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  IMAGE_PROPERTIES_RECORD                    *ImageRecord;
+  IMAGE_PROPERTIES_RECORD_CODE_SECTION       *ImageRecordCodeSection;
+  LIST_ENTRY                                 *ImageRecordLink;
+  LIST_ENTRY                                 *CodeSegmentListHead;
+  IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT  *TestContext;
+
+  TestContext     = (IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT *)Context;
+  ImageRecordLink = &TestContext->ImageList;
+
+  while (!IsListEmpty (ImageRecordLink)) {
+    ImageRecord = CR (
+                    ImageRecordLink->ForwardLink,
+                    IMAGE_PROPERTIES_RECORD,
+                    Link,
+                    IMAGE_PROPERTIES_RECORD_SIGNATURE
+                    );
+
+    CodeSegmentListHead = &ImageRecord->CodeSegmentList;
+    while (!IsListEmpty (CodeSegmentListHead)) {
+      ImageRecordCodeSection = CR (
+                                 CodeSegmentListHead->ForwardLink,
+                                 IMAGE_PROPERTIES_RECORD_CODE_SECTION,
+                                 Link,
+                                 IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
+                                 );
+      RemoveEntryList (&ImageRecordCodeSection->Link);
+      FreePool (ImageRecordCodeSection);
+    }
+
+    RemoveEntryList (&ImageRecord->Link);
+    FreePool (ImageRecord);
+  }
+
+  if (TestContext->MemoryMap != NULL) {
+    FreePool (TestContext->MemoryMap);
+  }
+}
+
+/**
+  Create a generic image list with the proper signatures which will be customized for each test
+  and allocate the default memory map.
+
+  @param[out]  TestContext   Context which will be passed to the test cases
+**/
+STATIC
+VOID
+CreateBaseContextEntry (
+  OUT IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT  *TestContext
+  )
+{
+  IMAGE_PROPERTIES_RECORD               *Image1;
+  IMAGE_PROPERTIES_RECORD               *Image2;
+  IMAGE_PROPERTIES_RECORD               *Image3;
+  IMAGE_PROPERTIES_RECORD_CODE_SECTION  *CodeSectionInImage1;
+  IMAGE_PROPERTIES_RECORD_CODE_SECTION  *CodeSectionInImage2;
+  IMAGE_PROPERTIES_RECORD_CODE_SECTION  *CodeSectionInImage3;
+
+  InitializeListHead (&TestContext->ImageList);
+
+  Image1              = AllocateZeroPool (sizeof (IMAGE_PROPERTIES_RECORD));
+  CodeSectionInImage1 = AllocateZeroPool (sizeof (IMAGE_PROPERTIES_RECORD_CODE_SECTION));
+
+  Image1->Signature              = IMAGE_PROPERTIES_RECORD_SIGNATURE;
+  CodeSectionInImage1->Signature = IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE;
+  InitializeListHead (&Image1->CodeSegmentList);
+
+  InsertTailList (&TestContext->ImageList, &Image1->Link);
+  InsertTailList (&Image1->CodeSegmentList, &CodeSectionInImage1->Link);
+
+  Image2              = AllocateZeroPool (sizeof (IMAGE_PROPERTIES_RECORD));
+  CodeSectionInImage2 = AllocateZeroPool (sizeof (IMAGE_PROPERTIES_RECORD_CODE_SECTION));
+
+  Image2->Signature              = IMAGE_PROPERTIES_RECORD_SIGNATURE;
+  CodeSectionInImage2->Signature = IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE;
+  InitializeListHead (&Image2->CodeSegmentList);
+
+  InsertTailList (&TestContext->ImageList, &Image2->Link);
+  InsertTailList (&Image2->CodeSegmentList, &CodeSectionInImage2->Link);
+
+  Image3              = AllocateZeroPool (sizeof (IMAGE_PROPERTIES_RECORD));
+  CodeSectionInImage3 = AllocateZeroPool (sizeof (IMAGE_PROPERTIES_RECORD_CODE_SECTION));
+
+  Image3->Signature              = IMAGE_PROPERTIES_RECORD_SIGNATURE;
+  CodeSectionInImage3->Signature = IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE;
+  InitializeListHead (&Image3->CodeSegmentList);
+
+  InsertTailList (&TestContext->ImageList, &Image3->Link);
+  InsertTailList (&Image3->CodeSegmentList, &CodeSectionInImage3->Link);
+
+  TestContext->MemoryMap = AllocateZeroPool (SPLIT_MEMORY_MAP_SIZE);
+  CopyMem (TestContext->MemoryMap, &BaseMemoryMap, BASE_MEMORY_MAP_SIZE);
+
+  return;
+}
+
+/**
+  Initialze the unit test framework, suite, and unit tests.
+
+  @retval  EFI_SUCCESS           All test cases were dispatched.
+  @retval  EFI_OUT_OF_RESOURCES  There are not enough resources available to
+                                 initialize the unit tests.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+UnitTestingEntry (
+  VOID
+  )
+{
+  EFI_STATUS                                 Status;
+  UNIT_TEST_FRAMEWORK_HANDLE                 Framework;
+  UNIT_TEST_SUITE_HANDLE                     ImagePropertiesRecordTests;
+  IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT  *Context1;
+  IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT  *Context2;
+  IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT  *Context3;
+  IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT  *Context4;
+
+  DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_APP_NAME, UNIT_TEST_APP_VERSION));
+
+  Framework = NULL;
+
+  Context1 = (IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT *)AllocateZeroPool (sizeof (IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT));
+  Context2 = (IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT *)AllocateZeroPool (sizeof (IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT));
+  Context3 = (IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT *)AllocateZeroPool (sizeof (IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT));
+  Context4 = (IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT *)AllocateZeroPool (sizeof (IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT));
+
+  CreateBaseContextEntry (Context1);
+  CreateBaseContextEntry (Context2);
+  CreateBaseContextEntry (Context3);
+  CreateBaseContextEntry (Context4);
+
+  //
+  // Start setting up the test framework for running the tests.
+  //
+  Status = InitUnitTestFramework (&Framework, UNIT_TEST_APP_NAME, gEfiCallerBaseName, UNIT_TEST_APP_VERSION);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status = %r\n", Status));
+    goto EXIT;
+  }
+
+  //
+  // Populate the Unit Test Suite.
+  //
+  Status = CreateUnitTestSuite (&ImagePropertiesRecordTests, Framework, "Image Properties Record Tests", "ImagePropertiesRecordLib.SplitTable", NULL, NULL);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the Image Properties Record Tests\n"));
+    Status = EFI_OUT_OF_RESOURCES;
+    goto EXIT;
+  }
+
+  //
+  // --------------Suite-----------Description--------------Name----------Function--------Pre---Post-------------------Context-----------
+  //
+  AddTestCase (ImagePropertiesRecordTests, "All images fit perfectly into existing descriptors", "ImagesFitDescriptors", ImagesFitDescriptors, NULL, TestCleanup, Context1);
+  AddTestCase (ImagePropertiesRecordTests, "All images don't fit perfectly into existing descriptors", "ImagesDontFitDescriptors", ImagesDontFitDescriptors, NULL, TestCleanup, Context2);
+  AddTestCase (ImagePropertiesRecordTests, "All Images are contined In single descriptor", "MultipleImagesInOneDescriptor", MultipleImagesInOneDescriptor, NULL, TestCleanup, Context3);
+  AddTestCase (ImagePropertiesRecordTests, "Multiple code sections each image", "MaxOutAdditionalDescriptors", MaxOutAdditionalDescriptors, NULL, TestCleanup, Context4);
+
+  //
+  // Execute the tests.
+  //
+  Status = RunAllTestSuites (Framework);
+
+EXIT:
+  if (Framework) {
+    FreeUnitTestFramework (Framework);
+  }
+
+  return Status;
+}
+
+///
+/// Avoid ECC error for function name that starts with lower case letter
+///
+#define ImagePropertiesRecordLibUnitTestMain  main
+
+/**
+  Standard POSIX C entry point for host based unit test execution.
+
+  @param[in] Argc  Number of arguments
+  @param[in] Argv  Array of pointers to arguments
+
+  @retval 0      Success
+  @retval other  Error
+**/
+INT32
+ImagePropertiesRecordLibUnitTestMain (
+  IN INT32  Argc,
+  IN CHAR8  *Argv[]
+  )
+{
+  return UnitTestingEntry ();
+}
diff --git a/MdeModulePkg/Library/ImagePropertiesRecordLib/UnitTest/ImagePropertiesRecordLibUnitTestHost.inf b/MdeModulePkg/Library/ImagePropertiesRecordLib/UnitTest/ImagePropertiesRecordLibUnitTestHost.inf
new file mode 100644
index 000000000000..cbc64a14bde7
--- /dev/null
+++ b/MdeModulePkg/Library/ImagePropertiesRecordLib/UnitTest/ImagePropertiesRecordLibUnitTestHost.inf
@@ -0,0 +1,35 @@
+## @file
+# Unit tests the SplitTable() ImagePropertiesRecordLib Logic
+#
+# Copyright (C) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010006
+  BASE_NAME                      = ImagePropertiesRecordLibUnitTestHost
+  FILE_GUID                      = 45B39FAA-E25D-4724-A6F4-93C0C8588A80
+  MODULE_TYPE                    = HOST_APPLICATION
+  VERSION_STRING                 = 1.0
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
+#
+
+[Sources]
+  ImagePropertiesRecordLibUnitTestHost.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  MemoryAllocationLib
+  UnitTestLib
+  ImagePropertiesRecordLib
diff --git a/MdeModulePkg/Test/MdeModulePkgHostTest.dsc b/MdeModulePkg/Test/MdeModulePkgHostTest.dsc
index 8fb982a2703d..2b8cbb867a73 100644
--- a/MdeModulePkg/Test/MdeModulePkgHostTest.dsc
+++ b/MdeModulePkg/Test/MdeModulePkgHostTest.dsc
@@ -54,6 +54,11 @@ [Components]
       DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
   }
 
+  MdeModulePkg/Library/ImagePropertiesRecordLib/UnitTest/ImagePropertiesRecordLibUnitTestHost.inf {
+    <LibraryClasses>
+      ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
+  }
+
   #
   # Build HOST_APPLICATION Libraries
   #
-- 
2.41.0.windows.2



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



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

* [edk2-devel] [PATCH v2 3/9] MdeModulePkg: Fix Bugs in MAT Logic
  2023-07-20  0:05 [edk2-devel] [PATCH v2 0/9] Add ImagePropertiesRecordLib and Fix MAT Bugs Taylor Beebe
  2023-07-20  0:05 ` [edk2-devel] [PATCH v2 1/9] MdeModulePkg: Add ImagePropertiesRecordLib Taylor Beebe
  2023-07-20  0:05 ` [edk2-devel] [PATCH v2 2/9] MdeModulePkg: Add ImagePropertiesRecordLib Host-Based Unit Test Taylor Beebe
@ 2023-07-20  0:05 ` Taylor Beebe
  2023-07-20  0:05 ` [edk2-devel] [PATCH v2 4/9] ArmVirtPkg: Add ImagePropertiesRecordLib Instance Taylor Beebe
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Taylor Beebe @ 2023-07-20  0:05 UTC (permalink / raw)
  To: devel; +Cc: Jian J Wang, Liming Gao, Dandan Bi

Fix the bugs in ImagePropertiesRecordLib (which is a copy of the
current UEFI MAT logic) before switching the UEFI and SMM MAT logic
to use the new library.

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/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c | 98 ++++++++++----------
 1 file changed, 48 insertions(+), 50 deletions(-)

diff --git a/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c b/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c
index 46f4f401a4d5..a787e376b551 100644
--- a/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c
+++ b/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c
@@ -519,7 +519,7 @@ GetMaxSplitRecordCount (
       break;
     }
 
-    SplitRecordCount += (2 * ImageRecord->CodeSegmentCount + 1);
+    SplitRecordCount += (2 * ImageRecord->CodeSegmentCount + 3);
     PhysicalStart     = ImageRecord->ImageBase + ImageRecord->ImageSize;
   } while ((ImageRecord != NULL) && (PhysicalStart < PhysicalEnd));
 
@@ -565,7 +565,6 @@ SplitRecord (
   UINT64                   PhysicalEnd;
   UINTN                    NewRecordCount;
   UINTN                    TotalNewRecordCount;
-  BOOLEAN                  IsLastRecordData;
 
   if (MaxSplitRecordCount == 0) {
     CopyMem (NewRecord, OldRecord, DescriptorSize);
@@ -586,35 +585,16 @@ SplitRecord (
     NewImageRecord = GetImageRecordByAddress (PhysicalStart, PhysicalEnd - PhysicalStart, ImageRecordList);
     if (NewImageRecord == NULL) {
       //
-      // No more image covered by this range, stop
+      // No more images cover this range, check if we've reached the end of the old descriptor. If not,
+      // add the remaining range to the new descriptor list.
       //
-      if ((PhysicalEnd > PhysicalStart) && (ImageRecord != NULL)) {
-        //
-        // If this is still address in this record, need record.
-        //
-        NewRecord        = PREVIOUS_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);
-        IsLastRecordData = FALSE;
-        if ((NewRecord->Attribute & EFI_MEMORY_XP) != 0) {
-          IsLastRecordData = TRUE;
-        }
-
-        if (IsLastRecordData) {
-          //
-          // Last record is DATA, just merge it.
-          //
-          NewRecord->NumberOfPages = EfiSizeToPages (PhysicalEnd - NewRecord->PhysicalStart);
-        } else {
-          //
-          // Last record is CODE, create a new DATA entry.
-          //
-          NewRecord                = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);
-          NewRecord->Type          = TempRecord.Type;
-          NewRecord->PhysicalStart = TempRecord.PhysicalStart;
-          NewRecord->VirtualStart  = 0;
-          NewRecord->NumberOfPages = TempRecord.NumberOfPages;
-          NewRecord->Attribute     = TempRecord.Attribute | EFI_MEMORY_XP;
-          TotalNewRecordCount++;
-        }
+      if (PhysicalEnd > PhysicalStart) {
+        NewRecord->Type          = TempRecord.Type;
+        NewRecord->PhysicalStart = PhysicalStart;
+        NewRecord->VirtualStart  = 0;
+        NewRecord->NumberOfPages = EfiSizeToPages (PhysicalEnd - PhysicalStart);
+        NewRecord->Attribute     = TempRecord.Attribute;
+        TotalNewRecordCount++;
       }
 
       break;
@@ -622,6 +602,24 @@ SplitRecord (
 
     ImageRecord = NewImageRecord;
 
+    //
+    // Update PhysicalStart to exclude the portion before the image buffer
+    //
+    if (TempRecord.PhysicalStart < ImageRecord->ImageBase) {
+      NewRecord->Type          = TempRecord.Type;
+      NewRecord->PhysicalStart = TempRecord.PhysicalStart;
+      NewRecord->VirtualStart  = 0;
+      NewRecord->NumberOfPages = EfiSizeToPages (ImageRecord->ImageBase - TempRecord.PhysicalStart);
+      NewRecord->Attribute     = TempRecord.Attribute;
+      TotalNewRecordCount++;
+
+      PhysicalStart            = ImageRecord->ImageBase;
+      TempRecord.PhysicalStart = PhysicalStart;
+      TempRecord.NumberOfPages = EfiSizeToPages (PhysicalEnd - PhysicalStart);
+
+      NewRecord = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)NewRecord + DescriptorSize);
+    }
+
     //
     // Set new record
     //
@@ -707,11 +705,12 @@ SplitTable (
 {
   INTN   IndexOld;
   INTN   IndexNew;
+  INTN   IndexNewStarting;
   UINTN  MaxSplitRecordCount;
   UINTN  RealSplitRecordCount;
-  UINTN  TotalSplitRecordCount;
+  UINTN  TotalSkippedRecords;
 
-  TotalSplitRecordCount = 0;
+  TotalSkippedRecords = 0;
   //
   // Let old record point to end of valid MemoryMap buffer.
   //
@@ -719,7 +718,8 @@ SplitTable (
   //
   // Let new record point to end of full MemoryMap buffer.
   //
-  IndexNew = ((*MemoryMapSize) / DescriptorSize) - 1 + NumberOfAdditionalDescriptors;
+  IndexNew         = ((*MemoryMapSize) / DescriptorSize) - 1 + NumberOfAdditionalDescriptors;
+  IndexNewStarting = IndexNew;
   for ( ; IndexOld >= 0; IndexOld--) {
     MaxSplitRecordCount = GetMaxSplitRecordCount ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + IndexOld * DescriptorSize), ImageRecordList);
     //
@@ -733,16 +733,14 @@ SplitTable (
                              DescriptorSize,
                              ImageRecordList
                              );
-    //
-    // Adjust IndexNew according to real split.
-    //
-    CopyMem (
-      ((UINT8 *)MemoryMap + (IndexNew + MaxSplitRecordCount - RealSplitRecordCount) * DescriptorSize),
-      ((UINT8 *)MemoryMap + IndexNew * DescriptorSize),
-      RealSplitRecordCount * DescriptorSize
-      );
-    IndexNew               = IndexNew + MaxSplitRecordCount - RealSplitRecordCount;
-    TotalSplitRecordCount += RealSplitRecordCount;
+
+    // If we didn't utilize all the extra allocated descriptor slots, set the physical address of the unused slots
+    // to MAX_ADDRESS so they are moved to the bottom of the list when sorting.
+    for ( ; RealSplitRecordCount < MaxSplitRecordCount; RealSplitRecordCount++) {
+      ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + ((IndexNew + RealSplitRecordCount + 1) * DescriptorSize)))->PhysicalStart = MAX_ADDRESS;
+      TotalSkippedRecords++;
+    }
+
     IndexNew--;
   }
 
@@ -751,16 +749,16 @@ SplitTable (
   //
   CopyMem (
     MemoryMap,
-    (UINT8 *)MemoryMap + (NumberOfAdditionalDescriptors - TotalSplitRecordCount) * DescriptorSize,
-    (*MemoryMapSize) + TotalSplitRecordCount * DescriptorSize
+    (UINT8 *)MemoryMap + ((IndexNew + 1) * DescriptorSize),
+    (IndexNewStarting - IndexNew) * DescriptorSize
     );
 
-  *MemoryMapSize = (*MemoryMapSize) + DescriptorSize * TotalSplitRecordCount;
+  //
+  // Sort from low to high to filter out the MAX_ADDRESS records.
+  //
+  SortMemoryMap (MemoryMap, (IndexNewStarting - IndexNew) * DescriptorSize, DescriptorSize);
 
-  //
-  // Sort from low to high (Just in case)
-  //
-  SortMemoryMap (MemoryMap, *MemoryMapSize, DescriptorSize);
+  *MemoryMapSize = (IndexNewStarting - IndexNew - TotalSkippedRecords) * DescriptorSize;
 
   return;
 }
-- 
2.41.0.windows.2



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



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

* [edk2-devel] [PATCH v2 4/9] ArmVirtPkg: Add ImagePropertiesRecordLib Instance
  2023-07-20  0:05 [edk2-devel] [PATCH v2 0/9] Add ImagePropertiesRecordLib and Fix MAT Bugs Taylor Beebe
                   ` (2 preceding siblings ...)
  2023-07-20  0:05 ` [edk2-devel] [PATCH v2 3/9] MdeModulePkg: Fix Bugs in MAT Logic Taylor Beebe
@ 2023-07-20  0:05 ` Taylor Beebe
  2023-07-20  0:05 ` [edk2-devel] [PATCH v2 5/9] EmulatorPkg: " Taylor Beebe
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Taylor Beebe @ 2023-07-20  0:05 UTC (permalink / raw)
  To: devel; +Cc: Ard Biesheuvel, Leif Lindholm, Sami Mujawar, Gerd Hoffmann

Add an instance of ImagePropertiesRecordLib which will be used by the
DXE Core.

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 | 1 +
 1 file changed, 1 insertion(+)

diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc
index 2443e8351c99..b299028b9f51 100644
--- a/ArmVirtPkg/ArmVirt.dsc.inc
+++ b/ArmVirtPkg/ArmVirt.dsc.inc
@@ -52,6 +52,7 @@ [LibraryClasses.common]
   IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicArmVirt.inf
   UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
   CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
+  ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
 
   UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
   HobLib|ArmVirtPkg/Library/ArmVirtDxeHobLib/ArmVirtDxeHobLib.inf
-- 
2.41.0.windows.2



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



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

* [edk2-devel] [PATCH v2 5/9] EmulatorPkg: Add ImagePropertiesRecordLib Instance
  2023-07-20  0:05 [edk2-devel] [PATCH v2 0/9] Add ImagePropertiesRecordLib and Fix MAT Bugs Taylor Beebe
                   ` (3 preceding siblings ...)
  2023-07-20  0:05 ` [edk2-devel] [PATCH v2 4/9] ArmVirtPkg: Add ImagePropertiesRecordLib Instance Taylor Beebe
@ 2023-07-20  0:05 ` Taylor Beebe
  2023-07-20  0:05 ` [edk2-devel] [PATCH v2 6/9] OvmfPkg: " Taylor Beebe
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Taylor Beebe @ 2023-07-20  0:05 UTC (permalink / raw)
  To: devel; +Cc: Andrew Fish, Ray Ni

Add an instance of ImagePropertiesRecordLib which will be used by the
DXE Core.

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

diff --git a/EmulatorPkg/EmulatorPkg.dsc b/EmulatorPkg/EmulatorPkg.dsc
index b44435d7e6ee..e18eeca884a5 100644
--- a/EmulatorPkg/EmulatorPkg.dsc
+++ b/EmulatorPkg/EmulatorPkg.dsc
@@ -126,6 +126,7 @@ [LibraryClasses]
   SortLib|MdeModulePkg/Library/BaseSortLib/BaseSortLib.inf
   ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
   FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
+  ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
 
 !if $(SECURE_BOOT_ENABLE) == TRUE
   RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf
-- 
2.41.0.windows.2



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



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

* [edk2-devel] [PATCH v2 6/9] OvmfPkg: Add ImagePropertiesRecordLib Instance
  2023-07-20  0:05 [edk2-devel] [PATCH v2 0/9] Add ImagePropertiesRecordLib and Fix MAT Bugs Taylor Beebe
                   ` (4 preceding siblings ...)
  2023-07-20  0:05 ` [edk2-devel] [PATCH v2 5/9] EmulatorPkg: " Taylor Beebe
@ 2023-07-20  0:05 ` Taylor Beebe
  2023-07-20  0:05 ` [edk2-devel] [PATCH v2 7/9] UefiPayloadPkg: " Taylor Beebe
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Taylor Beebe @ 2023-07-20  0:05 UTC (permalink / raw)
  To: devel; +Cc: Ard Biesheuvel, Jiewen Yao, Jordan Justen, Gerd Hoffmann

Add an instance of ImagePropertiesRecordLib which will be used by the
DXE Core.

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        | 1 +
 OvmfPkg/Bhyve/BhyveX64.dsc          | 1 +
 OvmfPkg/CloudHv/CloudHvX64.dsc      | 1 +
 OvmfPkg/IntelTdx/IntelTdxX64.dsc    | 1 +
 OvmfPkg/Microvm/MicrovmX64.dsc      | 1 +
 OvmfPkg/OvmfPkgIa32.dsc             | 1 +
 OvmfPkg/OvmfPkgIa32X64.dsc          | 1 +
 OvmfPkg/OvmfPkgX64.dsc              | 1 +
 OvmfPkg/OvmfXen.dsc                 | 1 +
 OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc | 1 +
 10 files changed, 10 insertions(+)

diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc
index 2c6ed7c9745f..e8c954a97956 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.dsc
+++ b/OvmfPkg/AmdSev/AmdSevX64.dsc
@@ -171,6 +171,7 @@ [LibraryClasses]
   MemEncryptTdxLib|OvmfPkg/Library/BaseMemEncryptTdxLib/BaseMemEncryptTdxLib.inf
   PeiHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/PeiHardwareInfoLib.inf
   DxeHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/DxeHardwareInfoLib.inf
+  ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
 
 !if $(SOURCE_DEBUG_ENABLE) == TRUE
   PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf
diff --git a/OvmfPkg/Bhyve/BhyveX64.dsc b/OvmfPkg/Bhyve/BhyveX64.dsc
index 7fa40998ae80..606e84ae1710 100644
--- a/OvmfPkg/Bhyve/BhyveX64.dsc
+++ b/OvmfPkg/Bhyve/BhyveX64.dsc
@@ -173,6 +173,7 @@ [LibraryClasses]
   MemEncryptTdxLib|OvmfPkg/Library/BaseMemEncryptTdxLib/BaseMemEncryptTdxLib.inf
   PeiHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/PeiHardwareInfoLib.inf
   DxeHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/DxeHardwareInfoLib.inf
+  ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
 
   CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
   FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
diff --git a/OvmfPkg/CloudHv/CloudHvX64.dsc b/OvmfPkg/CloudHv/CloudHvX64.dsc
index e000deed9e4d..91816a10996f 100644
--- a/OvmfPkg/CloudHv/CloudHvX64.dsc
+++ b/OvmfPkg/CloudHv/CloudHvX64.dsc
@@ -182,6 +182,7 @@ [LibraryClasses]
   MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf
   PeiHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/PeiHardwareInfoLib.inf
   DxeHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/DxeHardwareInfoLib.inf
+  ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
 !if $(SMM_REQUIRE) == FALSE
   LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf
 !endif
diff --git a/OvmfPkg/IntelTdx/IntelTdxX64.dsc b/OvmfPkg/IntelTdx/IntelTdxX64.dsc
index 193657ff2d61..bee98e798717 100644
--- a/OvmfPkg/IntelTdx/IntelTdxX64.dsc
+++ b/OvmfPkg/IntelTdx/IntelTdxX64.dsc
@@ -171,6 +171,7 @@ [LibraryClasses]
   MemEncryptTdxLib|OvmfPkg/Library/BaseMemEncryptTdxLib/BaseMemEncryptTdxLib.inf
   PeiHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/PeiHardwareInfoLib.inf
   DxeHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/DxeHardwareInfoLib.inf
+  ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
 
   LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf
   CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
diff --git a/OvmfPkg/Microvm/MicrovmX64.dsc b/OvmfPkg/Microvm/MicrovmX64.dsc
index 2f7585639374..38e0af6ae101 100644
--- a/OvmfPkg/Microvm/MicrovmX64.dsc
+++ b/OvmfPkg/Microvm/MicrovmX64.dsc
@@ -185,6 +185,7 @@ [LibraryClasses]
   MemEncryptTdxLib|OvmfPkg/Library/BaseMemEncryptTdxLib/BaseMemEncryptTdxLib.inf
   PeiHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/PeiHardwareInfoLib.inf
   DxeHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/DxeHardwareInfoLib.inf
+  ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
 
 !if $(SOURCE_DEBUG_ENABLE) == TRUE
   PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf
diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index ed36935770f3..84807b3ffee9 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -187,6 +187,7 @@ [LibraryClasses]
   MemEncryptTdxLib|OvmfPkg/Library/BaseMemEncryptTdxLib/BaseMemEncryptTdxLibNull.inf
   PeiHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/PeiHardwareInfoLib.inf
   DxeHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/DxeHardwareInfoLib.inf
+  ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
 !if $(SMM_REQUIRE) == FALSE
   LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf
 !endif
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index 919315e4cb33..dc80edca1671 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -192,6 +192,7 @@ [LibraryClasses]
   MemEncryptTdxLib|OvmfPkg/Library/BaseMemEncryptTdxLib/BaseMemEncryptTdxLibNull.inf
   PeiHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/PeiHardwareInfoLib.inf
   DxeHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/DxeHardwareInfoLib.inf
+  ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
 !if $(SMM_REQUIRE) == FALSE
   LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf
 !endif
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index 823de0d0f9e0..82a97ca6d3df 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -204,6 +204,7 @@ [LibraryClasses]
   MemEncryptTdxLib|OvmfPkg/Library/BaseMemEncryptTdxLib/BaseMemEncryptTdxLib.inf
   PeiHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/PeiHardwareInfoLib.inf
   DxeHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/DxeHardwareInfoLib.inf
+  ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
 
 !if $(SMM_REQUIRE) == FALSE
   LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf
diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc
index 210578c1d74d..17b622f34bf2 100644
--- a/OvmfPkg/OvmfXen.dsc
+++ b/OvmfPkg/OvmfXen.dsc
@@ -176,6 +176,7 @@ [LibraryClasses]
   MemEncryptTdxLib|OvmfPkg/Library/BaseMemEncryptTdxLib/BaseMemEncryptTdxLib.inf
   PeiHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/PeiHardwareInfoLib.inf
   DxeHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/DxeHardwareInfoLib.inf
+  ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
 
 !if $(SOURCE_DEBUG_ENABLE) == TRUE
   PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf
diff --git a/OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc b/OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc
index 34b2037824f1..f8b9479345d7 100644
--- a/OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc
+++ b/OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc
@@ -101,6 +101,7 @@ [LibraryClasses.common]
   PciHostBridgeUtilityLib|OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.inf
   PeiHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/PeiHardwareInfoLib.inf
   PlatformHookLib|MdeModulePkg/Library/BasePlatformHookLibNull/BasePlatformHookLibNull.inf
+  ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
 
 !if $(TPM2_ENABLE) == TRUE
   Tpm2CommandLib|SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf
-- 
2.41.0.windows.2



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



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

* [edk2-devel] [PATCH v2 7/9] UefiPayloadPkg: Add ImagePropertiesRecordLib Instance
  2023-07-20  0:05 [edk2-devel] [PATCH v2 0/9] Add ImagePropertiesRecordLib and Fix MAT Bugs Taylor Beebe
                   ` (5 preceding siblings ...)
  2023-07-20  0:05 ` [edk2-devel] [PATCH v2 6/9] OvmfPkg: " Taylor Beebe
@ 2023-07-20  0:05 ` Taylor Beebe
  2023-07-20  0:05 ` [edk2-devel] [PATCH v2 8/9] UefiCpuPkg: Use Attribute From SMM MemoryAttributesTable if Nonzero Taylor Beebe
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Taylor Beebe @ 2023-07-20  0:05 UTC (permalink / raw)
  To: devel; +Cc: Guo Dong, Sean Rhodes, James Lu, Gua Guo

Add an instance of ImagePropertiesRecordLib which will be used by the
DXE Core.

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>
---
 UefiPayloadPkg/UefiPayloadPkg.dsc | 1 +
 1 file changed, 1 insertion(+)

diff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc b/UefiPayloadPkg/UefiPayloadPkg.dsc
index 47812048ddcf..8d237b23339a 100644
--- a/UefiPayloadPkg/UefiPayloadPkg.dsc
+++ b/UefiPayloadPkg/UefiPayloadPkg.dsc
@@ -277,6 +277,7 @@ [LibraryClasses]
   #
   DebugPrintErrorLevelLib|UefiPayloadPkg/Library/DebugPrintErrorLevelLibHob/DebugPrintErrorLevelLibHob.inf
   PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
+  ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
 !if $(SOURCE_DEBUG_ENABLE) == TRUE
   PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf
   DebugCommunicationLib|SourceLevelDebugPkg/Library/DebugCommunicationLibSerialPort/DebugCommunicationLibSerialPort.inf
-- 
2.41.0.windows.2



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



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

* [edk2-devel] [PATCH v2 8/9] UefiCpuPkg: Use Attribute From SMM MemoryAttributesTable if Nonzero
  2023-07-20  0:05 [edk2-devel] [PATCH v2 0/9] Add ImagePropertiesRecordLib and Fix MAT Bugs Taylor Beebe
                   ` (6 preceding siblings ...)
  2023-07-20  0:05 ` [edk2-devel] [PATCH v2 7/9] UefiPayloadPkg: " Taylor Beebe
@ 2023-07-20  0:05 ` Taylor Beebe
  2023-07-20  0:05 ` [edk2-devel] [PATCH v2 9/9] MdeModulePkg: Update UEFI and SMM MAT Logic To Use ImagePropertiesRecordLib Taylor Beebe
  2023-07-20  5:19 ` [edk2-devel] [PATCH v2 0/9] Add ImagePropertiesRecordLib and Fix MAT Bugs Ni, Ray
  9 siblings, 0 replies; 13+ messages in thread
From: Taylor Beebe @ 2023-07-20  0:05 UTC (permalink / raw)
  To: devel; +Cc: Eric Dong, Ray Ni, Rahul Kumar, Gerd Hoffmann

The function EnforceMemoryMapAttribute() in the SMM MAT logic will
ensure that the CODE and DATA memory types have the desired attributes.
The consumer of the SMM MAT should only override the Attributes field
in the MAT if it is nonzero. This also allows the UEFI and SMM MAT
logic to use ImagePropertiesRecordLib instead of carrying two copies
of the image properties record manipulation.

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/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c
index 6f498666157e..d302a9b0cbcf 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c
@@ -1062,14 +1062,17 @@ SetMemMapAttributes (
   MemoryMap = MemoryMapStart;
   for (Index = 0; Index < MemoryMapEntryCount; Index++) {
     DEBUG ((DEBUG_VERBOSE, "SetAttribute: Memory Entry - 0x%lx, 0x%x\n", MemoryMap->PhysicalStart, MemoryMap->NumberOfPages));
-    if (MemoryMap->Type == EfiRuntimeServicesCode) {
-      MemoryAttribute = EFI_MEMORY_RO;
-    } else {
-      ASSERT ((MemoryMap->Type == EfiRuntimeServicesData) || (MemoryMap->Type == EfiConventionalMemory));
-      //
-      // Set other type memory as NX.
-      //
-      MemoryAttribute = EFI_MEMORY_XP;
+    MemoryAttribute = MemoryMap->Attribute & EFI_MEMORY_ACCESS_MASK;
+    if (MemoryAttribute == 0) {
+      if (MemoryMap->Type == EfiRuntimeServicesCode) {
+        MemoryAttribute = EFI_MEMORY_RO;
+      } else {
+        ASSERT ((MemoryMap->Type == EfiRuntimeServicesData) || (MemoryMap->Type == EfiConventionalMemory));
+        //
+        // Set other type memory as NX.
+        //
+        MemoryAttribute = EFI_MEMORY_XP;
+      }
     }
 
     //
-- 
2.41.0.windows.2



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



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

* [edk2-devel] [PATCH v2 9/9] MdeModulePkg: Update UEFI and SMM MAT Logic To Use ImagePropertiesRecordLib
  2023-07-20  0:05 [edk2-devel] [PATCH v2 0/9] Add ImagePropertiesRecordLib and Fix MAT Bugs Taylor Beebe
                   ` (7 preceding siblings ...)
  2023-07-20  0:05 ` [edk2-devel] [PATCH v2 8/9] UefiCpuPkg: Use Attribute From SMM MemoryAttributesTable if Nonzero Taylor Beebe
@ 2023-07-20  0:05 ` Taylor Beebe
  2023-07-20  5:19 ` [edk2-devel] [PATCH v2 0/9] Add ImagePropertiesRecordLib and Fix MAT Bugs Ni, Ray
  9 siblings, 0 replies; 13+ messages in thread
From: Taylor Beebe @ 2023-07-20  0:05 UTC (permalink / raw)
  To: devel; +Cc: Jian J Wang, Liming Gao, Dandan Bi

With the new ImagePropertiesRecordLib, UEFI and SMM no longer need
to carry duplicate image properties record logic in their respective
MAT implementations.

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/Misc/MemoryAttributesTable.c  | 786 +-------------------
 MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c       |  24 +-
 MdeModulePkg/Core/PiSmmCore/MemoryAttributesTable.c | 785 +------------------
 MdeModulePkg/Core/Dxe/DxeMain.h                     |  20 -
 MdeModulePkg/Core/Dxe/DxeMain.inf                   |   1 +
 MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf           |   1 +
 6 files changed, 46 insertions(+), 1571 deletions(-)

diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c b/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c
index fd127ee167e1..53aedf7d671e 100644
--- a/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c
+++ b/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c
@@ -14,6 +14,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include <Library/DxeServicesTableLib.h>
 #include <Library/DebugLib.h>
 #include <Library/UefiLib.h>
+#include <Library/ImagePropertiesRecordLib.h>
 
 #include <Guid/EventGroup.h>
 
@@ -333,45 +334,6 @@ CoreInitializeMemoryAttributesTable (
 // Below functions are for MemoryMap
 //
 
-/**
-  Converts a number of EFI_PAGEs to a size in bytes.
-
-  NOTE: Do not use EFI_PAGES_TO_SIZE because it handles UINTN only.
-
-  @param  Pages     The number of EFI_PAGES.
-
-  @return  The number of bytes associated with the number of EFI_PAGEs specified
-           by Pages.
-**/
-STATIC
-UINT64
-EfiPagesToSize (
-  IN UINT64  Pages
-  )
-{
-  return LShiftU64 (Pages, EFI_PAGE_SHIFT);
-}
-
-/**
-  Converts a size, in bytes, to a number of EFI_PAGESs.
-
-  NOTE: Do not use EFI_SIZE_TO_PAGES because it handles UINTN only.
-
-  @param  Size      A size in bytes.
-
-  @return  The number of EFI_PAGESs associated with the number of bytes specified
-           by Size.
-
-**/
-STATIC
-UINT64
-EfiSizeToPages (
-  IN UINT64  Size
-  )
-{
-  return RShiftU64 (Size, EFI_PAGE_SHIFT) + ((((UINTN)Size) & EFI_PAGE_MASK) ? 1 : 0);
-}
-
 /**
   Acquire memory lock on mMemoryAttributesTableLock.
 **/
@@ -396,48 +358,6 @@ CoreReleasemMemoryAttributesTableLock (
   CoreReleaseLock (&mMemoryAttributesTableLock);
 }
 
-/**
-  Sort memory map entries based upon PhysicalStart, from low to high.
-
-  @param  MemoryMap              A pointer to the buffer in which firmware places
-                                 the current memory map.
-  @param  MemoryMapSize          Size, in bytes, of the MemoryMap buffer.
-  @param  DescriptorSize         Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
-**/
-STATIC
-VOID
-SortMemoryMap (
-  IN OUT EFI_MEMORY_DESCRIPTOR  *MemoryMap,
-  IN UINTN                      MemoryMapSize,
-  IN UINTN                      DescriptorSize
-  )
-{
-  EFI_MEMORY_DESCRIPTOR  *MemoryMapEntry;
-  EFI_MEMORY_DESCRIPTOR  *NextMemoryMapEntry;
-  EFI_MEMORY_DESCRIPTOR  *MemoryMapEnd;
-  EFI_MEMORY_DESCRIPTOR  TempMemoryMap;
-
-  MemoryMapEntry     = MemoryMap;
-  NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
-  MemoryMapEnd       = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + MemoryMapSize);
-  while (MemoryMapEntry < MemoryMapEnd) {
-    while (NextMemoryMapEntry < MemoryMapEnd) {
-      if (MemoryMapEntry->PhysicalStart > NextMemoryMapEntry->PhysicalStart) {
-        CopyMem (&TempMemoryMap, MemoryMapEntry, sizeof (EFI_MEMORY_DESCRIPTOR));
-        CopyMem (MemoryMapEntry, NextMemoryMapEntry, sizeof (EFI_MEMORY_DESCRIPTOR));
-        CopyMem (NextMemoryMapEntry, &TempMemoryMap, sizeof (EFI_MEMORY_DESCRIPTOR));
-      }
-
-      NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize);
-    }
-
-    MemoryMapEntry     = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
-    NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
-  }
-
-  return;
-}
-
 /**
   Merge continous memory map entries whose have same attributes.
 
@@ -471,7 +391,7 @@ MergeMemoryMap (
 
     do {
       MergeGuardPages (NewMemoryMapEntry, NextMemoryMapEntry->PhysicalStart);
-      MemoryBlockLength = (UINT64)(EfiPagesToSize (NewMemoryMapEntry->NumberOfPages));
+      MemoryBlockLength = LShiftU64 (NewMemoryMapEntry->NumberOfPages, EFI_PAGE_SHIFT);
       if (((UINTN)NextMemoryMapEntry < (UINTN)MemoryMapEnd) &&
           (NewMemoryMapEntry->Type == NextMemoryMapEntry->Type) &&
           (NewMemoryMapEntry->Attribute == NextMemoryMapEntry->Attribute) &&
@@ -538,426 +458,6 @@ EnforceMemoryMapAttribute (
   return;
 }
 
-/**
-  Return the first image record, whose [ImageBase, ImageSize] covered by [Buffer, Length].
-
-  @param Buffer  Start Address
-  @param Length  Address length
-
-  @return first image record covered by [buffer, length]
-**/
-STATIC
-IMAGE_PROPERTIES_RECORD *
-GetImageRecordByAddress (
-  IN EFI_PHYSICAL_ADDRESS  Buffer,
-  IN UINT64                Length
-  )
-{
-  IMAGE_PROPERTIES_RECORD  *ImageRecord;
-  LIST_ENTRY               *ImageRecordLink;
-  LIST_ENTRY               *ImageRecordList;
-
-  ImageRecordList = &mImagePropertiesPrivateData.ImageRecordList;
-
-  for (ImageRecordLink = ImageRecordList->ForwardLink;
-       ImageRecordLink != ImageRecordList;
-       ImageRecordLink = ImageRecordLink->ForwardLink)
-  {
-    ImageRecord = CR (
-                    ImageRecordLink,
-                    IMAGE_PROPERTIES_RECORD,
-                    Link,
-                    IMAGE_PROPERTIES_RECORD_SIGNATURE
-                    );
-
-    if ((Buffer <= ImageRecord->ImageBase) &&
-        (Buffer + Length >= ImageRecord->ImageBase + ImageRecord->ImageSize))
-    {
-      return ImageRecord;
-    }
-  }
-
-  return NULL;
-}
-
-/**
-  Set the memory map to new entries, according to one old entry,
-  based upon PE code section and data section in image record
-
-  @param  ImageRecord            An image record whose [ImageBase, ImageSize] covered
-                                 by old memory map entry.
-  @param  NewRecord              A pointer to several new memory map entries.
-                                 The caller gurantee the buffer size be 1 +
-                                 (SplitRecordCount * DescriptorSize) calculated
-                                 below.
-  @param  OldRecord              A pointer to one old memory map entry.
-  @param  DescriptorSize         Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
-**/
-STATIC
-UINTN
-SetNewRecord (
-  IN IMAGE_PROPERTIES_RECORD    *ImageRecord,
-  IN OUT EFI_MEMORY_DESCRIPTOR  *NewRecord,
-  IN EFI_MEMORY_DESCRIPTOR      *OldRecord,
-  IN UINTN                      DescriptorSize
-  )
-{
-  EFI_MEMORY_DESCRIPTOR                 TempRecord;
-  IMAGE_PROPERTIES_RECORD_CODE_SECTION  *ImageRecordCodeSection;
-  LIST_ENTRY                            *ImageRecordCodeSectionLink;
-  LIST_ENTRY                            *ImageRecordCodeSectionEndLink;
-  LIST_ENTRY                            *ImageRecordCodeSectionList;
-  UINTN                                 NewRecordCount;
-  UINT64                                PhysicalEnd;
-  UINT64                                ImageEnd;
-
-  CopyMem (&TempRecord, OldRecord, sizeof (EFI_MEMORY_DESCRIPTOR));
-  PhysicalEnd    = TempRecord.PhysicalStart + EfiPagesToSize (TempRecord.NumberOfPages);
-  NewRecordCount = 0;
-
-  ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList;
-
-  ImageRecordCodeSectionLink    = ImageRecordCodeSectionList->ForwardLink;
-  ImageRecordCodeSectionEndLink = ImageRecordCodeSectionList;
-  while (ImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) {
-    ImageRecordCodeSection = CR (
-                               ImageRecordCodeSectionLink,
-                               IMAGE_PROPERTIES_RECORD_CODE_SECTION,
-                               Link,
-                               IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
-                               );
-    ImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;
-
-    if (TempRecord.PhysicalStart <= ImageRecordCodeSection->CodeSegmentBase) {
-      //
-      // DATA
-      //
-      NewRecord->Type          = TempRecord.Type;
-      NewRecord->PhysicalStart = TempRecord.PhysicalStart;
-      NewRecord->VirtualStart  = 0;
-      NewRecord->NumberOfPages = EfiSizeToPages (ImageRecordCodeSection->CodeSegmentBase - NewRecord->PhysicalStart);
-      NewRecord->Attribute     = TempRecord.Attribute | EFI_MEMORY_XP;
-      if (NewRecord->NumberOfPages != 0) {
-        NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);
-        NewRecordCount++;
-      }
-
-      //
-      // CODE
-      //
-      NewRecord->Type          = TempRecord.Type;
-      NewRecord->PhysicalStart = ImageRecordCodeSection->CodeSegmentBase;
-      NewRecord->VirtualStart  = 0;
-      NewRecord->NumberOfPages = EfiSizeToPages (ImageRecordCodeSection->CodeSegmentSize);
-      NewRecord->Attribute     = (TempRecord.Attribute & (~EFI_MEMORY_XP)) | EFI_MEMORY_RO;
-      if (NewRecord->NumberOfPages != 0) {
-        NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);
-        NewRecordCount++;
-      }
-
-      TempRecord.PhysicalStart = ImageRecordCodeSection->CodeSegmentBase + EfiPagesToSize (EfiSizeToPages (ImageRecordCodeSection->CodeSegmentSize));
-      TempRecord.NumberOfPages = EfiSizeToPages (PhysicalEnd - TempRecord.PhysicalStart);
-      if (TempRecord.NumberOfPages == 0) {
-        break;
-      }
-    }
-  }
-
-  ImageEnd = ImageRecord->ImageBase + ImageRecord->ImageSize;
-
-  //
-  // Final DATA
-  //
-  if (TempRecord.PhysicalStart < ImageEnd) {
-    NewRecord->Type          = TempRecord.Type;
-    NewRecord->PhysicalStart = TempRecord.PhysicalStart;
-    NewRecord->VirtualStart  = 0;
-    NewRecord->NumberOfPages = EfiSizeToPages (ImageEnd - TempRecord.PhysicalStart);
-    NewRecord->Attribute     = TempRecord.Attribute | EFI_MEMORY_XP;
-    NewRecordCount++;
-  }
-
-  return NewRecordCount;
-}
-
-/**
-  Return the max number of new splitted entries, according to one old entry,
-  based upon PE code section and data section.
-
-  @param  OldRecord              A pointer to one old memory map entry.
-
-  @retval  0 no entry need to be splitted.
-  @return  the max number of new splitted entries
-**/
-STATIC
-UINTN
-GetMaxSplitRecordCount (
-  IN EFI_MEMORY_DESCRIPTOR  *OldRecord
-  )
-{
-  IMAGE_PROPERTIES_RECORD  *ImageRecord;
-  UINTN                    SplitRecordCount;
-  UINT64                   PhysicalStart;
-  UINT64                   PhysicalEnd;
-
-  SplitRecordCount = 0;
-  PhysicalStart    = OldRecord->PhysicalStart;
-  PhysicalEnd      = OldRecord->PhysicalStart + EfiPagesToSize (OldRecord->NumberOfPages);
-
-  do {
-    ImageRecord = GetImageRecordByAddress (PhysicalStart, PhysicalEnd - PhysicalStart);
-    if (ImageRecord == NULL) {
-      break;
-    }
-
-    SplitRecordCount += (2 * ImageRecord->CodeSegmentCount + 1);
-    PhysicalStart     = ImageRecord->ImageBase + ImageRecord->ImageSize;
-  } while ((ImageRecord != NULL) && (PhysicalStart < PhysicalEnd));
-
-  if (SplitRecordCount != 0) {
-    SplitRecordCount--;
-  }
-
-  return SplitRecordCount;
-}
-
-/**
-  Split the memory map to new entries, according to one old entry,
-  based upon PE code section and data section.
-
-  @param  OldRecord              A pointer to one old memory map entry.
-  @param  NewRecord              A pointer to several new memory map entries.
-                                 The caller gurantee the buffer size be 1 +
-                                 (SplitRecordCount * DescriptorSize) calculated
-                                 below.
-  @param  MaxSplitRecordCount    The max number of splitted entries
-  @param  DescriptorSize         Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
-
-  @retval  0 no entry is splitted.
-  @return  the real number of splitted record.
-**/
-STATIC
-UINTN
-SplitRecord (
-  IN EFI_MEMORY_DESCRIPTOR      *OldRecord,
-  IN OUT EFI_MEMORY_DESCRIPTOR  *NewRecord,
-  IN UINTN                      MaxSplitRecordCount,
-  IN UINTN                      DescriptorSize
-  )
-{
-  EFI_MEMORY_DESCRIPTOR    TempRecord;
-  IMAGE_PROPERTIES_RECORD  *ImageRecord;
-  IMAGE_PROPERTIES_RECORD  *NewImageRecord;
-  UINT64                   PhysicalStart;
-  UINT64                   PhysicalEnd;
-  UINTN                    NewRecordCount;
-  UINTN                    TotalNewRecordCount;
-  BOOLEAN                  IsLastRecordData;
-
-  if (MaxSplitRecordCount == 0) {
-    CopyMem (NewRecord, OldRecord, DescriptorSize);
-    return 0;
-  }
-
-  TotalNewRecordCount = 0;
-
-  //
-  // Override previous record
-  //
-  CopyMem (&TempRecord, OldRecord, sizeof (EFI_MEMORY_DESCRIPTOR));
-  PhysicalStart = TempRecord.PhysicalStart;
-  PhysicalEnd   = TempRecord.PhysicalStart + EfiPagesToSize (TempRecord.NumberOfPages);
-
-  ImageRecord = NULL;
-  do {
-    NewImageRecord = GetImageRecordByAddress (PhysicalStart, PhysicalEnd - PhysicalStart);
-    if (NewImageRecord == NULL) {
-      //
-      // No more image covered by this range, stop
-      //
-      if ((PhysicalEnd > PhysicalStart) && (ImageRecord != NULL)) {
-        //
-        // If this is still address in this record, need record.
-        //
-        NewRecord        = PREVIOUS_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);
-        IsLastRecordData = FALSE;
-        if ((NewRecord->Attribute & EFI_MEMORY_XP) != 0) {
-          IsLastRecordData = TRUE;
-        }
-
-        if (IsLastRecordData) {
-          //
-          // Last record is DATA, just merge it.
-          //
-          NewRecord->NumberOfPages = EfiSizeToPages (PhysicalEnd - NewRecord->PhysicalStart);
-        } else {
-          //
-          // Last record is CODE, create a new DATA entry.
-          //
-          NewRecord                = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);
-          NewRecord->Type          = TempRecord.Type;
-          NewRecord->PhysicalStart = TempRecord.PhysicalStart;
-          NewRecord->VirtualStart  = 0;
-          NewRecord->NumberOfPages = TempRecord.NumberOfPages;
-          NewRecord->Attribute     = TempRecord.Attribute | EFI_MEMORY_XP;
-          TotalNewRecordCount++;
-        }
-      }
-
-      break;
-    }
-
-    ImageRecord = NewImageRecord;
-
-    //
-    // Set new record
-    //
-    NewRecordCount       = SetNewRecord (ImageRecord, NewRecord, &TempRecord, DescriptorSize);
-    TotalNewRecordCount += NewRecordCount;
-    NewRecord            = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)NewRecord + NewRecordCount * DescriptorSize);
-
-    //
-    // Update PhysicalStart, in order to exclude the image buffer already splitted.
-    //
-    PhysicalStart            = ImageRecord->ImageBase + ImageRecord->ImageSize;
-    TempRecord.PhysicalStart = PhysicalStart;
-    TempRecord.NumberOfPages = EfiSizeToPages (PhysicalEnd - PhysicalStart);
-  } while ((ImageRecord != NULL) && (PhysicalStart < PhysicalEnd));
-
-  //
-  // The logic in function SplitTable() ensures that TotalNewRecordCount will not be zero if the
-  // code reaches here.
-  //
-  ASSERT (TotalNewRecordCount != 0);
-  return TotalNewRecordCount - 1;
-}
-
-/**
-  Split the original memory map, and add more entries to describe PE code section and data section.
-  This function will set EfiRuntimeServicesData to be EFI_MEMORY_XP.
-  This function will merge entries with same attributes finally.
-
-  NOTE: It assumes PE code/data section are page aligned.
-  NOTE: It assumes enough entry is prepared for new memory map.
-
-  Split table:
-   +---------------+
-   | Record X      |
-   +---------------+
-   | Record RtCode |
-   +---------------+
-   | Record Y      |
-   +---------------+
-   ==>
-   +---------------+
-   | Record X      |
-   +---------------+ ----
-   | Record RtData |     |
-   +---------------+     |
-   | Record RtCode |     |-> PE/COFF1
-   +---------------+     |
-   | Record RtData |     |
-   +---------------+ ----
-   | Record RtData |     |
-   +---------------+     |
-   | Record RtCode |     |-> PE/COFF2
-   +---------------+     |
-   | Record RtData |     |
-   +---------------+ ----
-   | Record Y      |
-   +---------------+
-
-  @param  MemoryMapSize          A pointer to the size, in bytes, of the
-                                 MemoryMap buffer. On input, this is the size of
-                                 old MemoryMap before split. The actual buffer
-                                 size of MemoryMap is MemoryMapSize +
-                                 (AdditionalRecordCount * DescriptorSize) calculated
-                                 below. On output, it is the size of new MemoryMap
-                                 after split.
-  @param  MemoryMap              A pointer to the buffer in which firmware places
-                                 the current memory map.
-  @param  DescriptorSize         Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
-**/
-STATIC
-VOID
-SplitTable (
-  IN OUT UINTN                  *MemoryMapSize,
-  IN OUT EFI_MEMORY_DESCRIPTOR  *MemoryMap,
-  IN UINTN                      DescriptorSize
-  )
-{
-  INTN   IndexOld;
-  INTN   IndexNew;
-  UINTN  MaxSplitRecordCount;
-  UINTN  RealSplitRecordCount;
-  UINTN  TotalSplitRecordCount;
-  UINTN  AdditionalRecordCount;
-
-  AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 1) * mImagePropertiesPrivateData.ImageRecordCount;
-
-  TotalSplitRecordCount = 0;
-  //
-  // Let old record point to end of valid MemoryMap buffer.
-  //
-  IndexOld = ((*MemoryMapSize) / DescriptorSize) - 1;
-  //
-  // Let new record point to end of full MemoryMap buffer.
-  //
-  IndexNew = ((*MemoryMapSize) / DescriptorSize) - 1 + AdditionalRecordCount;
-  for ( ; IndexOld >= 0; IndexOld--) {
-    MaxSplitRecordCount = GetMaxSplitRecordCount ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + IndexOld * DescriptorSize));
-    //
-    // Split this MemoryMap record
-    //
-    IndexNew            -= MaxSplitRecordCount;
-    RealSplitRecordCount = SplitRecord (
-                             (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + IndexOld * DescriptorSize),
-                             (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + IndexNew * DescriptorSize),
-                             MaxSplitRecordCount,
-                             DescriptorSize
-                             );
-    //
-    // Adjust IndexNew according to real split.
-    //
-    CopyMem (
-      ((UINT8 *)MemoryMap + (IndexNew + MaxSplitRecordCount - RealSplitRecordCount) * DescriptorSize),
-      ((UINT8 *)MemoryMap + IndexNew * DescriptorSize),
-      RealSplitRecordCount * DescriptorSize
-      );
-    IndexNew               = IndexNew + MaxSplitRecordCount - RealSplitRecordCount;
-    TotalSplitRecordCount += RealSplitRecordCount;
-    IndexNew--;
-  }
-
-  //
-  // Move all records to the beginning.
-  //
-  CopyMem (
-    MemoryMap,
-    (UINT8 *)MemoryMap + (AdditionalRecordCount - TotalSplitRecordCount) * DescriptorSize,
-    (*MemoryMapSize) + TotalSplitRecordCount * DescriptorSize
-    );
-
-  *MemoryMapSize = (*MemoryMapSize) + DescriptorSize * TotalSplitRecordCount;
-
-  //
-  // Sort from low to high (Just in case)
-  //
-  SortMemoryMap (MemoryMap, *MemoryMapSize, DescriptorSize);
-
-  //
-  // Set RuntimeData to XP
-  //
-  EnforceMemoryMapAttribute (MemoryMap, *MemoryMapSize, DescriptorSize);
-
-  //
-  // Merge same type to save entry size
-  //
-  MergeMemoryMap (MemoryMap, MemoryMapSize, DescriptorSize);
-
-  return;
-}
-
 /**
   This function for GetMemoryMap() with properties table capability.
 
@@ -1017,7 +517,7 @@ CoreGetMemoryMapWithSeparatedImageSection (
 
   CoreAcquiremMemoryAttributesTableLock ();
 
-  AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 1) * mImagePropertiesPrivateData.ImageRecordCount;
+  AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 3) * mImagePropertiesPrivateData.ImageRecordCount;
 
   OldMemoryMapSize = *MemoryMapSize;
   Status           = CoreGetMemoryMap (MemoryMapSize, MemoryMap, MapKey, DescriptorSize, DescriptorVersion);
@@ -1035,7 +535,23 @@ CoreGetMemoryMapWithSeparatedImageSection (
       //
       // Split PE code/data
       //
-      SplitTable (MemoryMapSize, MemoryMap, *DescriptorSize);
+      SplitTable (
+        MemoryMapSize,
+        MemoryMap,
+        *DescriptorSize,
+        &mImagePropertiesPrivateData.ImageRecordList,
+        AdditionalRecordCount
+        );
+
+      //
+      // Set RuntimeData to XP
+      //
+      EnforceMemoryMapAttribute (MemoryMap, *MemoryMapSize, *DescriptorSize);
+
+      //
+      // Merge same type to save entry size
+      //
+      MergeMemoryMap (MemoryMap, MemoryMapSize, *DescriptorSize);
     }
   }
 
@@ -1066,218 +582,6 @@ SetMemoryAttributesTableSectionAlignment (
   }
 }
 
-/**
-  Swap two code sections in image record.
-
-  @param  FirstImageRecordCodeSection    first code section in image record
-  @param  SecondImageRecordCodeSection   second code section in image record
-**/
-STATIC
-VOID
-SwapImageRecordCodeSection (
-  IN IMAGE_PROPERTIES_RECORD_CODE_SECTION  *FirstImageRecordCodeSection,
-  IN IMAGE_PROPERTIES_RECORD_CODE_SECTION  *SecondImageRecordCodeSection
-  )
-{
-  IMAGE_PROPERTIES_RECORD_CODE_SECTION  TempImageRecordCodeSection;
-
-  TempImageRecordCodeSection.CodeSegmentBase = FirstImageRecordCodeSection->CodeSegmentBase;
-  TempImageRecordCodeSection.CodeSegmentSize = FirstImageRecordCodeSection->CodeSegmentSize;
-
-  FirstImageRecordCodeSection->CodeSegmentBase = SecondImageRecordCodeSection->CodeSegmentBase;
-  FirstImageRecordCodeSection->CodeSegmentSize = SecondImageRecordCodeSection->CodeSegmentSize;
-
-  SecondImageRecordCodeSection->CodeSegmentBase = TempImageRecordCodeSection.CodeSegmentBase;
-  SecondImageRecordCodeSection->CodeSegmentSize = TempImageRecordCodeSection.CodeSegmentSize;
-}
-
-/**
-  Sort code section in image record, based upon CodeSegmentBase from low to high.
-
-  @param  ImageRecord    image record to be sorted
-**/
-VOID
-SortImageRecordCodeSection (
-  IN IMAGE_PROPERTIES_RECORD  *ImageRecord
-  )
-{
-  IMAGE_PROPERTIES_RECORD_CODE_SECTION  *ImageRecordCodeSection;
-  IMAGE_PROPERTIES_RECORD_CODE_SECTION  *NextImageRecordCodeSection;
-  LIST_ENTRY                            *ImageRecordCodeSectionLink;
-  LIST_ENTRY                            *NextImageRecordCodeSectionLink;
-  LIST_ENTRY                            *ImageRecordCodeSectionEndLink;
-  LIST_ENTRY                            *ImageRecordCodeSectionList;
-
-  ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList;
-
-  ImageRecordCodeSectionLink     = ImageRecordCodeSectionList->ForwardLink;
-  NextImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;
-  ImageRecordCodeSectionEndLink  = ImageRecordCodeSectionList;
-  while (ImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) {
-    ImageRecordCodeSection = CR (
-                               ImageRecordCodeSectionLink,
-                               IMAGE_PROPERTIES_RECORD_CODE_SECTION,
-                               Link,
-                               IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
-                               );
-    while (NextImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) {
-      NextImageRecordCodeSection = CR (
-                                     NextImageRecordCodeSectionLink,
-                                     IMAGE_PROPERTIES_RECORD_CODE_SECTION,
-                                     Link,
-                                     IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
-                                     );
-      if (ImageRecordCodeSection->CodeSegmentBase > NextImageRecordCodeSection->CodeSegmentBase) {
-        SwapImageRecordCodeSection (ImageRecordCodeSection, NextImageRecordCodeSection);
-      }
-
-      NextImageRecordCodeSectionLink = NextImageRecordCodeSectionLink->ForwardLink;
-    }
-
-    ImageRecordCodeSectionLink     = ImageRecordCodeSectionLink->ForwardLink;
-    NextImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;
-  }
-}
-
-/**
-  Check if code section in image record is valid.
-
-  @param  ImageRecord    image record to be checked
-
-  @retval TRUE  image record is valid
-  @retval FALSE image record is invalid
-**/
-BOOLEAN
-IsImageRecordCodeSectionValid (
-  IN IMAGE_PROPERTIES_RECORD  *ImageRecord
-  )
-{
-  IMAGE_PROPERTIES_RECORD_CODE_SECTION  *ImageRecordCodeSection;
-  IMAGE_PROPERTIES_RECORD_CODE_SECTION  *LastImageRecordCodeSection;
-  LIST_ENTRY                            *ImageRecordCodeSectionLink;
-  LIST_ENTRY                            *ImageRecordCodeSectionEndLink;
-  LIST_ENTRY                            *ImageRecordCodeSectionList;
-
-  DEBUG ((DEBUG_VERBOSE, "ImageCode SegmentCount - 0x%x\n", ImageRecord->CodeSegmentCount));
-
-  ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList;
-
-  ImageRecordCodeSectionLink    = ImageRecordCodeSectionList->ForwardLink;
-  ImageRecordCodeSectionEndLink = ImageRecordCodeSectionList;
-  LastImageRecordCodeSection    = NULL;
-  while (ImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) {
-    ImageRecordCodeSection = CR (
-                               ImageRecordCodeSectionLink,
-                               IMAGE_PROPERTIES_RECORD_CODE_SECTION,
-                               Link,
-                               IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
-                               );
-    if (ImageRecordCodeSection->CodeSegmentSize == 0) {
-      return FALSE;
-    }
-
-    if (ImageRecordCodeSection->CodeSegmentBase < ImageRecord->ImageBase) {
-      return FALSE;
-    }
-
-    if (ImageRecordCodeSection->CodeSegmentBase >= MAX_ADDRESS - ImageRecordCodeSection->CodeSegmentSize) {
-      return FALSE;
-    }
-
-    if ((ImageRecordCodeSection->CodeSegmentBase + ImageRecordCodeSection->CodeSegmentSize) > (ImageRecord->ImageBase + ImageRecord->ImageSize)) {
-      return FALSE;
-    }
-
-    if (LastImageRecordCodeSection != NULL) {
-      if ((LastImageRecordCodeSection->CodeSegmentBase + LastImageRecordCodeSection->CodeSegmentSize) > ImageRecordCodeSection->CodeSegmentBase) {
-        return FALSE;
-      }
-    }
-
-    LastImageRecordCodeSection = ImageRecordCodeSection;
-    ImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;
-  }
-
-  return TRUE;
-}
-
-/**
-  Swap two image records.
-
-  @param  FirstImageRecord   first image record.
-  @param  SecondImageRecord  second image record.
-**/
-STATIC
-VOID
-SwapImageRecord (
-  IN IMAGE_PROPERTIES_RECORD  *FirstImageRecord,
-  IN IMAGE_PROPERTIES_RECORD  *SecondImageRecord
-  )
-{
-  IMAGE_PROPERTIES_RECORD  TempImageRecord;
-
-  TempImageRecord.ImageBase        = FirstImageRecord->ImageBase;
-  TempImageRecord.ImageSize        = FirstImageRecord->ImageSize;
-  TempImageRecord.CodeSegmentCount = FirstImageRecord->CodeSegmentCount;
-
-  FirstImageRecord->ImageBase        = SecondImageRecord->ImageBase;
-  FirstImageRecord->ImageSize        = SecondImageRecord->ImageSize;
-  FirstImageRecord->CodeSegmentCount = SecondImageRecord->CodeSegmentCount;
-
-  SecondImageRecord->ImageBase        = TempImageRecord.ImageBase;
-  SecondImageRecord->ImageSize        = TempImageRecord.ImageSize;
-  SecondImageRecord->CodeSegmentCount = TempImageRecord.CodeSegmentCount;
-
-  SwapListEntries (&FirstImageRecord->CodeSegmentList, &SecondImageRecord->CodeSegmentList);
-}
-
-/**
-  Sort image record based upon the ImageBase from low to high.
-**/
-STATIC
-VOID
-SortImageRecord (
-  VOID
-  )
-{
-  IMAGE_PROPERTIES_RECORD  *ImageRecord;
-  IMAGE_PROPERTIES_RECORD  *NextImageRecord;
-  LIST_ENTRY               *ImageRecordLink;
-  LIST_ENTRY               *NextImageRecordLink;
-  LIST_ENTRY               *ImageRecordEndLink;
-  LIST_ENTRY               *ImageRecordList;
-
-  ImageRecordList = &mImagePropertiesPrivateData.ImageRecordList;
-
-  ImageRecordLink     = ImageRecordList->ForwardLink;
-  NextImageRecordLink = ImageRecordLink->ForwardLink;
-  ImageRecordEndLink  = ImageRecordList;
-  while (ImageRecordLink != ImageRecordEndLink) {
-    ImageRecord = CR (
-                    ImageRecordLink,
-                    IMAGE_PROPERTIES_RECORD,
-                    Link,
-                    IMAGE_PROPERTIES_RECORD_SIGNATURE
-                    );
-    while (NextImageRecordLink != ImageRecordEndLink) {
-      NextImageRecord = CR (
-                          NextImageRecordLink,
-                          IMAGE_PROPERTIES_RECORD,
-                          Link,
-                          IMAGE_PROPERTIES_RECORD_SIGNATURE
-                          );
-      if (ImageRecord->ImageBase > NextImageRecord->ImageBase) {
-        SwapImageRecord (ImageRecord, NextImageRecord);
-      }
-
-      NextImageRecordLink = NextImageRecordLink->ForwardLink;
-    }
-
-    ImageRecordLink     = ImageRecordLink->ForwardLink;
-    NextImageRecordLink = ImageRecordLink->ForwardLink;
-  }
-}
-
 /**
   Insert image record.
 
@@ -1456,54 +760,12 @@ InsertImageRecord (
     mImagePropertiesPrivateData.CodeSegmentCountMax = ImageRecord->CodeSegmentCount;
   }
 
-  SortImageRecord ();
+  SortImageRecord (&mImagePropertiesPrivateData.ImageRecordList);
 
 Finish:
   return;
 }
 
-/**
-  Find image record according to image base and size.
-
-  @param  ImageBase    Base of PE image
-  @param  ImageSize    Size of PE image
-
-  @return image record
-**/
-STATIC
-IMAGE_PROPERTIES_RECORD *
-FindImageRecord (
-  IN EFI_PHYSICAL_ADDRESS  ImageBase,
-  IN UINT64                ImageSize
-  )
-{
-  IMAGE_PROPERTIES_RECORD  *ImageRecord;
-  LIST_ENTRY               *ImageRecordLink;
-  LIST_ENTRY               *ImageRecordList;
-
-  ImageRecordList = &mImagePropertiesPrivateData.ImageRecordList;
-
-  for (ImageRecordLink = ImageRecordList->ForwardLink;
-       ImageRecordLink != ImageRecordList;
-       ImageRecordLink = ImageRecordLink->ForwardLink)
-  {
-    ImageRecord = CR (
-                    ImageRecordLink,
-                    IMAGE_PROPERTIES_RECORD,
-                    Link,
-                    IMAGE_PROPERTIES_RECORD_SIGNATURE
-                    );
-
-    if ((ImageBase == ImageRecord->ImageBase) &&
-        (ImageSize == ImageRecord->ImageSize))
-    {
-      return ImageRecord;
-    }
-  }
-
-  return NULL;
-}
-
 /**
   Remove Image record.
 
@@ -1526,7 +788,11 @@ RemoveImageRecord (
     return;
   }
 
-  ImageRecord = FindImageRecord ((EFI_PHYSICAL_ADDRESS)(UINTN)RuntimeImage->ImageBase, RuntimeImage->ImageSize);
+  ImageRecord = FindImageRecord (
+                  (EFI_PHYSICAL_ADDRESS)(UINTN)RuntimeImage->ImageBase,
+                  RuntimeImage->ImageSize,
+                  &mImagePropertiesPrivateData.ImageRecordList
+                  );
   if (ImageRecord == NULL) {
     DEBUG ((DEBUG_ERROR, "!!!!!!!! ImageRecord not found !!!!!!!!\n"));
     return;
diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c
index 7cc829b17402..977239d08afc 100644
--- a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c
+++ b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c
@@ -32,6 +32,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include <Library/DxeServicesTableLib.h>
 #include <Library/DebugLib.h>
 #include <Library/UefiLib.h>
+#include <Library/ImagePropertiesRecordLib.h>
 
 #include <Guid/EventGroup.h>
 #include <Guid/MemoryAttributesTable.h>
@@ -66,29 +67,6 @@ extern LIST_ENTRY  mGcdMemorySpaceMap;
 
 STATIC LIST_ENTRY  mProtectedImageRecordList;
 
-/**
-  Sort code section in image record, based upon CodeSegmentBase from low to high.
-
-  @param  ImageRecord    image record to be sorted
-**/
-VOID
-SortImageRecordCodeSection (
-  IN IMAGE_PROPERTIES_RECORD  *ImageRecord
-  );
-
-/**
-  Check if code section in image record is valid.
-
-  @param  ImageRecord    image record to be checked
-
-  @retval TRUE  image record is valid
-  @retval FALSE image record is invalid
-**/
-BOOLEAN
-IsImageRecordCodeSectionValid (
-  IN IMAGE_PROPERTIES_RECORD  *ImageRecord
-  );
-
 /**
   Get the image type.
 
diff --git a/MdeModulePkg/Core/PiSmmCore/MemoryAttributesTable.c b/MdeModulePkg/Core/PiSmmCore/MemoryAttributesTable.c
index 394fdae50741..2e4aaddef4e5 100644
--- a/MdeModulePkg/Core/PiSmmCore/MemoryAttributesTable.c
+++ b/MdeModulePkg/Core/PiSmmCore/MemoryAttributesTable.c
@@ -14,6 +14,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include <Library/SmmServicesTableLib.h>
 #include <Library/DebugLib.h>
 #include <Library/PcdLib.h>
+#include <Library/ImagePropertiesRecordLib.h>
 
 #include <Library/PeCoffLib.h>
 #include <Library/PeCoffGetEntryPointLib.h>
@@ -25,26 +26,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #define PREVIOUS_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \
   ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) - (Size)))
 
-#define IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE  SIGNATURE_32 ('I','P','R','C')
-
-typedef struct {
-  UINT32                  Signature;
-  LIST_ENTRY              Link;
-  EFI_PHYSICAL_ADDRESS    CodeSegmentBase;
-  UINT64                  CodeSegmentSize;
-} IMAGE_PROPERTIES_RECORD_CODE_SECTION;
-
-#define IMAGE_PROPERTIES_RECORD_SIGNATURE  SIGNATURE_32 ('I','P','R','D')
-
-typedef struct {
-  UINT32                  Signature;
-  LIST_ENTRY              Link;
-  EFI_PHYSICAL_ADDRESS    ImageBase;
-  UINT64                  ImageSize;
-  UINTN                   CodeSegmentCount;
-  LIST_ENTRY              CodeSegmentList;
-} IMAGE_PROPERTIES_RECORD;
-
 #define IMAGE_PROPERTIES_PRIVATE_DATA_SIGNATURE  SIGNATURE_32 ('I','P','P','D')
 
 typedef struct {
@@ -69,87 +50,6 @@ UINT64  mMemoryProtectionAttribute = EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTEC
 // Below functions are for MemoryMap
 //
 
-/**
-  Converts a number of EFI_PAGEs to a size in bytes.
-
-  NOTE: Do not use EFI_PAGES_TO_SIZE because it handles UINTN only.
-
-  @param[in]  Pages     The number of EFI_PAGES.
-
-  @return  The number of bytes associated with the number of EFI_PAGEs specified
-           by Pages.
-**/
-STATIC
-UINT64
-EfiPagesToSize (
-  IN UINT64  Pages
-  )
-{
-  return LShiftU64 (Pages, EFI_PAGE_SHIFT);
-}
-
-/**
-  Converts a size, in bytes, to a number of EFI_PAGESs.
-
-  NOTE: Do not use EFI_SIZE_TO_PAGES because it handles UINTN only.
-
-  @param[in]  Size      A size in bytes.
-
-  @return  The number of EFI_PAGESs associated with the number of bytes specified
-           by Size.
-
-**/
-STATIC
-UINT64
-EfiSizeToPages (
-  IN UINT64  Size
-  )
-{
-  return RShiftU64 (Size, EFI_PAGE_SHIFT) + ((((UINTN)Size) & EFI_PAGE_MASK) ? 1 : 0);
-}
-
-/**
-  Sort memory map entries based upon PhysicalStart, from low to high.
-
-  @param[in,out]  MemoryMap         A pointer to the buffer in which firmware places
-                                    the current memory map.
-  @param[in]      MemoryMapSize     Size, in bytes, of the MemoryMap buffer.
-  @param[in]      DescriptorSize    Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
-**/
-STATIC
-VOID
-SortMemoryMap (
-  IN OUT EFI_MEMORY_DESCRIPTOR  *MemoryMap,
-  IN UINTN                      MemoryMapSize,
-  IN UINTN                      DescriptorSize
-  )
-{
-  EFI_MEMORY_DESCRIPTOR  *MemoryMapEntry;
-  EFI_MEMORY_DESCRIPTOR  *NextMemoryMapEntry;
-  EFI_MEMORY_DESCRIPTOR  *MemoryMapEnd;
-  EFI_MEMORY_DESCRIPTOR  TempMemoryMap;
-
-  MemoryMapEntry     = MemoryMap;
-  NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
-  MemoryMapEnd       = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + MemoryMapSize);
-  while (MemoryMapEntry < MemoryMapEnd) {
-    while (NextMemoryMapEntry < MemoryMapEnd) {
-      if (MemoryMapEntry->PhysicalStart > NextMemoryMapEntry->PhysicalStart) {
-        CopyMem (&TempMemoryMap, MemoryMapEntry, sizeof (EFI_MEMORY_DESCRIPTOR));
-        CopyMem (MemoryMapEntry, NextMemoryMapEntry, sizeof (EFI_MEMORY_DESCRIPTOR));
-        CopyMem (NextMemoryMapEntry, &TempMemoryMap, sizeof (EFI_MEMORY_DESCRIPTOR));
-      }
-
-      NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize);
-    }
-
-    MemoryMapEntry     = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
-    NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
-  }
-
-  return;
-}
-
 /**
   Merge continuous memory map entries whose have same attributes.
 
@@ -183,7 +83,7 @@ MergeMemoryMap (
     NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
 
     do {
-      MemoryBlockLength = (UINT64)(EfiPagesToSize (MemoryMapEntry->NumberOfPages));
+      MemoryBlockLength = LShiftU64 (MemoryMapEntry->NumberOfPages, EFI_PAGE_SHIFT);
       if (((UINTN)NextMemoryMapEntry < (UINTN)MemoryMapEnd) &&
           (MemoryMapEntry->Type == NextMemoryMapEntry->Type) &&
           (MemoryMapEntry->Attribute == NextMemoryMapEntry->Attribute) &&
@@ -254,423 +154,6 @@ EnforceMemoryMapAttribute (
   return;
 }
 
-/**
-  Return the first image record, whose [ImageBase, ImageSize] covered by [Buffer, Length].
-
-  @param[in] Buffer  Start Address
-  @param[in] Length  Address length
-
-  @return first image record covered by [buffer, length]
-**/
-STATIC
-IMAGE_PROPERTIES_RECORD *
-GetImageRecordByAddress (
-  IN EFI_PHYSICAL_ADDRESS  Buffer,
-  IN UINT64                Length
-  )
-{
-  IMAGE_PROPERTIES_RECORD  *ImageRecord;
-  LIST_ENTRY               *ImageRecordLink;
-  LIST_ENTRY               *ImageRecordList;
-
-  ImageRecordList = &mImagePropertiesPrivateData.ImageRecordList;
-
-  for (ImageRecordLink = ImageRecordList->ForwardLink;
-       ImageRecordLink != ImageRecordList;
-       ImageRecordLink = ImageRecordLink->ForwardLink)
-  {
-    ImageRecord = CR (
-                    ImageRecordLink,
-                    IMAGE_PROPERTIES_RECORD,
-                    Link,
-                    IMAGE_PROPERTIES_RECORD_SIGNATURE
-                    );
-
-    if ((Buffer <= ImageRecord->ImageBase) &&
-        (Buffer + Length >= ImageRecord->ImageBase + ImageRecord->ImageSize))
-    {
-      return ImageRecord;
-    }
-  }
-
-  return NULL;
-}
-
-/**
-  Set the memory map to new entries, according to one old entry,
-  based upon PE code section and data section in image record
-
-  @param[in]       ImageRecord            An image record whose [ImageBase, ImageSize] covered
-                                          by old memory map entry.
-  @param[in, out]  NewRecord              A pointer to several new memory map entries.
-                                          The caller guarantee the buffer size be 1 +
-                                          (SplitRecordCount * DescriptorSize) calculated
-                                          below.
-  @param[in]       OldRecord              A pointer to one old memory map entry.
-  @param[in]       DescriptorSize         Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
-**/
-STATIC
-UINTN
-SetNewRecord (
-  IN IMAGE_PROPERTIES_RECORD    *ImageRecord,
-  IN OUT EFI_MEMORY_DESCRIPTOR  *NewRecord,
-  IN EFI_MEMORY_DESCRIPTOR      *OldRecord,
-  IN UINTN                      DescriptorSize
-  )
-{
-  EFI_MEMORY_DESCRIPTOR                 TempRecord;
-  IMAGE_PROPERTIES_RECORD_CODE_SECTION  *ImageRecordCodeSection;
-  LIST_ENTRY                            *ImageRecordCodeSectionLink;
-  LIST_ENTRY                            *ImageRecordCodeSectionEndLink;
-  LIST_ENTRY                            *ImageRecordCodeSectionList;
-  UINTN                                 NewRecordCount;
-  UINT64                                PhysicalEnd;
-  UINT64                                ImageEnd;
-
-  CopyMem (&TempRecord, OldRecord, sizeof (EFI_MEMORY_DESCRIPTOR));
-  PhysicalEnd    = TempRecord.PhysicalStart + EfiPagesToSize (TempRecord.NumberOfPages);
-  NewRecordCount = 0;
-
-  //
-  // Always create a new entry for non-PE image record
-  //
-  if (ImageRecord->ImageBase > TempRecord.PhysicalStart) {
-    NewRecord->Type          = TempRecord.Type;
-    NewRecord->PhysicalStart = TempRecord.PhysicalStart;
-    NewRecord->VirtualStart  = 0;
-    NewRecord->NumberOfPages = EfiSizeToPages (ImageRecord->ImageBase - TempRecord.PhysicalStart);
-    NewRecord->Attribute     = TempRecord.Attribute;
-    NewRecord                = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);
-    NewRecordCount++;
-    TempRecord.PhysicalStart = ImageRecord->ImageBase;
-    TempRecord.NumberOfPages = EfiSizeToPages (PhysicalEnd - TempRecord.PhysicalStart);
-  }
-
-  ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList;
-
-  ImageRecordCodeSectionLink    = ImageRecordCodeSectionList->ForwardLink;
-  ImageRecordCodeSectionEndLink = ImageRecordCodeSectionList;
-  while (ImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) {
-    ImageRecordCodeSection = CR (
-                               ImageRecordCodeSectionLink,
-                               IMAGE_PROPERTIES_RECORD_CODE_SECTION,
-                               Link,
-                               IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
-                               );
-    ImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;
-
-    if (TempRecord.PhysicalStart <= ImageRecordCodeSection->CodeSegmentBase) {
-      //
-      // DATA
-      //
-      NewRecord->Type          = EfiRuntimeServicesData;
-      NewRecord->PhysicalStart = TempRecord.PhysicalStart;
-      NewRecord->VirtualStart  = 0;
-      NewRecord->NumberOfPages = EfiSizeToPages (ImageRecordCodeSection->CodeSegmentBase - NewRecord->PhysicalStart);
-      NewRecord->Attribute     = TempRecord.Attribute | EFI_MEMORY_XP;
-      if (NewRecord->NumberOfPages != 0) {
-        NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);
-        NewRecordCount++;
-      }
-
-      //
-      // CODE
-      //
-      NewRecord->Type          = EfiRuntimeServicesCode;
-      NewRecord->PhysicalStart = ImageRecordCodeSection->CodeSegmentBase;
-      NewRecord->VirtualStart  = 0;
-      NewRecord->NumberOfPages = EfiSizeToPages (ImageRecordCodeSection->CodeSegmentSize);
-      NewRecord->Attribute     = (TempRecord.Attribute & (~EFI_MEMORY_XP)) | EFI_MEMORY_RO;
-      if (NewRecord->NumberOfPages != 0) {
-        NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);
-        NewRecordCount++;
-      }
-
-      TempRecord.PhysicalStart = ImageRecordCodeSection->CodeSegmentBase + EfiPagesToSize (EfiSizeToPages (ImageRecordCodeSection->CodeSegmentSize));
-      TempRecord.NumberOfPages = EfiSizeToPages (PhysicalEnd - TempRecord.PhysicalStart);
-      if (TempRecord.NumberOfPages == 0) {
-        break;
-      }
-    }
-  }
-
-  ImageEnd = ImageRecord->ImageBase + ImageRecord->ImageSize;
-
-  //
-  // Final DATA
-  //
-  if (TempRecord.PhysicalStart < ImageEnd) {
-    NewRecord->Type          = EfiRuntimeServicesData;
-    NewRecord->PhysicalStart = TempRecord.PhysicalStart;
-    NewRecord->VirtualStart  = 0;
-    NewRecord->NumberOfPages = EfiSizeToPages (ImageEnd - TempRecord.PhysicalStart);
-    NewRecord->Attribute     = TempRecord.Attribute | EFI_MEMORY_XP;
-    NewRecordCount++;
-  }
-
-  return NewRecordCount;
-}
-
-/**
-  Return the max number of new splitted entries, according to one old entry,
-  based upon PE code section and data section.
-
-  @param[in]  OldRecord              A pointer to one old memory map entry.
-
-  @retval  0 no entry need to be splitted.
-  @return  the max number of new splitted entries
-**/
-STATIC
-UINTN
-GetMaxSplitRecordCount (
-  IN EFI_MEMORY_DESCRIPTOR  *OldRecord
-  )
-{
-  IMAGE_PROPERTIES_RECORD  *ImageRecord;
-  UINTN                    SplitRecordCount;
-  UINT64                   PhysicalStart;
-  UINT64                   PhysicalEnd;
-
-  SplitRecordCount = 0;
-  PhysicalStart    = OldRecord->PhysicalStart;
-  PhysicalEnd      = OldRecord->PhysicalStart + EfiPagesToSize (OldRecord->NumberOfPages);
-
-  do {
-    ImageRecord = GetImageRecordByAddress (PhysicalStart, PhysicalEnd - PhysicalStart);
-    if (ImageRecord == NULL) {
-      break;
-    }
-
-    SplitRecordCount += (2 * ImageRecord->CodeSegmentCount + 2);
-    PhysicalStart     = ImageRecord->ImageBase + ImageRecord->ImageSize;
-  } while ((ImageRecord != NULL) && (PhysicalStart < PhysicalEnd));
-
-  return SplitRecordCount;
-}
-
-/**
-  Split the memory map to new entries, according to one old entry,
-  based upon PE code section and data section.
-
-  @param[in]       OldRecord              A pointer to one old memory map entry.
-  @param[in, out]  NewRecord              A pointer to several new memory map entries.
-                                          The caller guarantee the buffer size be 1 +
-                                          (SplitRecordCount * DescriptorSize) calculated
-                                          below.
-  @param[in]       MaxSplitRecordCount    The max number of splitted entries
-  @param[in]       DescriptorSize         Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
-
-  @retval  0 no entry is splitted.
-  @return  the real number of splitted record.
-**/
-STATIC
-UINTN
-SplitRecord (
-  IN EFI_MEMORY_DESCRIPTOR      *OldRecord,
-  IN OUT EFI_MEMORY_DESCRIPTOR  *NewRecord,
-  IN UINTN                      MaxSplitRecordCount,
-  IN UINTN                      DescriptorSize
-  )
-{
-  EFI_MEMORY_DESCRIPTOR    TempRecord;
-  IMAGE_PROPERTIES_RECORD  *ImageRecord;
-  IMAGE_PROPERTIES_RECORD  *NewImageRecord;
-  UINT64                   PhysicalStart;
-  UINT64                   PhysicalEnd;
-  UINTN                    NewRecordCount;
-  UINTN                    TotalNewRecordCount;
-
-  if (MaxSplitRecordCount == 0) {
-    CopyMem (NewRecord, OldRecord, DescriptorSize);
-    return 0;
-  }
-
-  TotalNewRecordCount = 0;
-
-  //
-  // Override previous record
-  //
-  CopyMem (&TempRecord, OldRecord, sizeof (EFI_MEMORY_DESCRIPTOR));
-  PhysicalStart = TempRecord.PhysicalStart;
-  PhysicalEnd   = TempRecord.PhysicalStart + EfiPagesToSize (TempRecord.NumberOfPages);
-
-  ImageRecord = NULL;
-  do {
-    NewImageRecord = GetImageRecordByAddress (PhysicalStart, PhysicalEnd - PhysicalStart);
-    if (NewImageRecord == NULL) {
-      //
-      // No more image covered by this range, stop
-      //
-      if (PhysicalEnd > PhysicalStart) {
-        //
-        // Always create a new entry for non-PE image record
-        //
-        NewRecord->Type          = TempRecord.Type;
-        NewRecord->PhysicalStart = TempRecord.PhysicalStart;
-        NewRecord->VirtualStart  = 0;
-        NewRecord->NumberOfPages = TempRecord.NumberOfPages;
-        NewRecord->Attribute     = TempRecord.Attribute;
-        TotalNewRecordCount++;
-      }
-
-      break;
-    }
-
-    ImageRecord = NewImageRecord;
-
-    //
-    // Set new record
-    //
-    NewRecordCount       = SetNewRecord (ImageRecord, NewRecord, &TempRecord, DescriptorSize);
-    TotalNewRecordCount += NewRecordCount;
-    NewRecord            = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)NewRecord + NewRecordCount * DescriptorSize);
-
-    //
-    // Update PhysicalStart, in order to exclude the image buffer already splitted.
-    //
-    PhysicalStart            = ImageRecord->ImageBase + ImageRecord->ImageSize;
-    TempRecord.PhysicalStart = PhysicalStart;
-    TempRecord.NumberOfPages = EfiSizeToPages (PhysicalEnd - PhysicalStart);
-  } while ((ImageRecord != NULL) && (PhysicalStart < PhysicalEnd));
-
-  return TotalNewRecordCount - 1;
-}
-
-/**
-  Split the original memory map, and add more entries to describe PE code section and data section.
-  This function will set EfiRuntimeServicesData to be EFI_MEMORY_XP.
-  This function will merge entries with same attributes finally.
-
-  NOTE: It assumes PE code/data section are page aligned.
-  NOTE: It assumes enough entry is prepared for new memory map.
-
-  Split table:
-   +---------------+
-   | Record X      |
-   +---------------+
-   | Record RtCode |
-   +---------------+
-   | Record Y      |
-   +---------------+
-   ==>
-   +---------------+
-   | Record X      |
-   +---------------+
-   | Record RtCode |
-   +---------------+ ----
-   | Record RtData |     |
-   +---------------+     |
-   | Record RtCode |     |-> PE/COFF1
-   +---------------+     |
-   | Record RtData |     |
-   +---------------+ ----
-   | Record RtCode |
-   +---------------+ ----
-   | Record RtData |     |
-   +---------------+     |
-   | Record RtCode |     |-> PE/COFF2
-   +---------------+     |
-   | Record RtData |     |
-   +---------------+ ----
-   | Record RtCode |
-   +---------------+
-   | Record Y      |
-   +---------------+
-
-  @param[in, out]  MemoryMapSize          A pointer to the size, in bytes, of the
-                                          MemoryMap buffer. On input, this is the size of
-                                          old MemoryMap before split. The actual buffer
-                                          size of MemoryMap is MemoryMapSize +
-                                          (AdditionalRecordCount * DescriptorSize) calculated
-                                          below. On output, it is the size of new MemoryMap
-                                          after split.
-  @param[in, out]  MemoryMap              A pointer to the buffer in which firmware places
-                                          the current memory map.
-  @param[in]       DescriptorSize         Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
-**/
-STATIC
-VOID
-SplitTable (
-  IN OUT UINTN                  *MemoryMapSize,
-  IN OUT EFI_MEMORY_DESCRIPTOR  *MemoryMap,
-  IN UINTN                      DescriptorSize
-  )
-{
-  INTN   IndexOld;
-  INTN   IndexNew;
-  UINTN  MaxSplitRecordCount;
-  UINTN  RealSplitRecordCount;
-  UINTN  TotalSplitRecordCount;
-  UINTN  AdditionalRecordCount;
-
-  AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 2) * mImagePropertiesPrivateData.ImageRecordCount;
-
-  TotalSplitRecordCount = 0;
-  //
-  // Let old record point to end of valid MemoryMap buffer.
-  //
-  IndexOld = ((*MemoryMapSize) / DescriptorSize) - 1;
-  //
-  // Let new record point to end of full MemoryMap buffer.
-  //
-  IndexNew = ((*MemoryMapSize) / DescriptorSize) - 1 + AdditionalRecordCount;
-  for ( ; IndexOld >= 0; IndexOld--) {
-    MaxSplitRecordCount = GetMaxSplitRecordCount ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + IndexOld * DescriptorSize));
-    //
-    // Split this MemoryMap record
-    //
-    IndexNew            -= MaxSplitRecordCount;
-    RealSplitRecordCount = SplitRecord (
-                             (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + IndexOld * DescriptorSize),
-                             (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + IndexNew * DescriptorSize),
-                             MaxSplitRecordCount,
-                             DescriptorSize
-                             );
-    //
-    // Adjust IndexNew according to real split.
-    //
-    if (MaxSplitRecordCount != RealSplitRecordCount) {
-      CopyMem (
-        ((UINT8 *)MemoryMap + (IndexNew + MaxSplitRecordCount - RealSplitRecordCount) * DescriptorSize),
-        ((UINT8 *)MemoryMap + IndexNew * DescriptorSize),
-        (RealSplitRecordCount + 1) * DescriptorSize
-        );
-    }
-
-    IndexNew               = IndexNew + MaxSplitRecordCount - RealSplitRecordCount;
-    TotalSplitRecordCount += RealSplitRecordCount;
-    IndexNew--;
-  }
-
-  //
-  // Move all records to the beginning.
-  //
-  CopyMem (
-    MemoryMap,
-    (UINT8 *)MemoryMap + (AdditionalRecordCount - TotalSplitRecordCount) * DescriptorSize,
-    (*MemoryMapSize) + TotalSplitRecordCount * DescriptorSize
-    );
-
-  *MemoryMapSize = (*MemoryMapSize) + DescriptorSize * TotalSplitRecordCount;
-
-  //
-  // Sort from low to high (Just in case)
-  //
-  SortMemoryMap (MemoryMap, *MemoryMapSize, DescriptorSize);
-
-  //
-  // Set RuntimeData to XP
-  //
-  EnforceMemoryMapAttribute (MemoryMap, *MemoryMapSize, DescriptorSize);
-
-  //
-  // Merge same type to save entry size
-  //
-  MergeMemoryMap (MemoryMap, MemoryMapSize, DescriptorSize);
-
-  return;
-}
-
 /**
   This function for GetMemoryMap() with memory attributes table.
 
@@ -729,7 +212,7 @@ SmmCoreGetMemoryMapMemoryAttributesTable (
     return EFI_INVALID_PARAMETER;
   }
 
-  AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 2) * mImagePropertiesPrivateData.ImageRecordCount;
+  AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 3) * mImagePropertiesPrivateData.ImageRecordCount;
 
   OldMemoryMapSize = *MemoryMapSize;
   Status           = SmmCoreGetMemoryMap (MemoryMapSize, MemoryMap, MapKey, DescriptorSize, DescriptorVersion);
@@ -747,7 +230,17 @@ SmmCoreGetMemoryMapMemoryAttributesTable (
       // Split PE code/data
       //
       ASSERT (MemoryMap != NULL);
-      SplitTable (MemoryMapSize, MemoryMap, *DescriptorSize);
+      SplitTable (MemoryMapSize, MemoryMap, *DescriptorSize, &mImagePropertiesPrivateData.ImageRecordList, AdditionalRecordCount);
+
+      //
+      // Set RuntimeData to XP
+      //
+      EnforceMemoryMapAttribute (MemoryMap, *MemoryMapSize, *DescriptorSize);
+
+      //
+      // Merge same type to save entry size
+      //
+      MergeMemoryMap (MemoryMap, MemoryMapSize, *DescriptorSize);
     }
   }
 
@@ -777,250 +270,6 @@ SetMemoryAttributesTableSectionAlignment (
   }
 }
 
-/**
-  Swap two code sections in image record.
-
-  @param[in]  FirstImageRecordCodeSection    first code section in image record
-  @param[in]  SecondImageRecordCodeSection   second code section in image record
-**/
-STATIC
-VOID
-SwapImageRecordCodeSection (
-  IN IMAGE_PROPERTIES_RECORD_CODE_SECTION  *FirstImageRecordCodeSection,
-  IN IMAGE_PROPERTIES_RECORD_CODE_SECTION  *SecondImageRecordCodeSection
-  )
-{
-  IMAGE_PROPERTIES_RECORD_CODE_SECTION  TempImageRecordCodeSection;
-
-  TempImageRecordCodeSection.CodeSegmentBase = FirstImageRecordCodeSection->CodeSegmentBase;
-  TempImageRecordCodeSection.CodeSegmentSize = FirstImageRecordCodeSection->CodeSegmentSize;
-
-  FirstImageRecordCodeSection->CodeSegmentBase = SecondImageRecordCodeSection->CodeSegmentBase;
-  FirstImageRecordCodeSection->CodeSegmentSize = SecondImageRecordCodeSection->CodeSegmentSize;
-
-  SecondImageRecordCodeSection->CodeSegmentBase = TempImageRecordCodeSection.CodeSegmentBase;
-  SecondImageRecordCodeSection->CodeSegmentSize = TempImageRecordCodeSection.CodeSegmentSize;
-}
-
-/**
-  Sort code section in image record, based upon CodeSegmentBase from low to high.
-
-  @param[in]  ImageRecord    image record to be sorted
-**/
-STATIC
-VOID
-SortImageRecordCodeSection (
-  IN IMAGE_PROPERTIES_RECORD  *ImageRecord
-  )
-{
-  IMAGE_PROPERTIES_RECORD_CODE_SECTION  *ImageRecordCodeSection;
-  IMAGE_PROPERTIES_RECORD_CODE_SECTION  *NextImageRecordCodeSection;
-  LIST_ENTRY                            *ImageRecordCodeSectionLink;
-  LIST_ENTRY                            *NextImageRecordCodeSectionLink;
-  LIST_ENTRY                            *ImageRecordCodeSectionEndLink;
-  LIST_ENTRY                            *ImageRecordCodeSectionList;
-
-  ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList;
-
-  ImageRecordCodeSectionLink     = ImageRecordCodeSectionList->ForwardLink;
-  NextImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;
-  ImageRecordCodeSectionEndLink  = ImageRecordCodeSectionList;
-  while (ImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) {
-    ImageRecordCodeSection = CR (
-                               ImageRecordCodeSectionLink,
-                               IMAGE_PROPERTIES_RECORD_CODE_SECTION,
-                               Link,
-                               IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
-                               );
-    while (NextImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) {
-      NextImageRecordCodeSection = CR (
-                                     NextImageRecordCodeSectionLink,
-                                     IMAGE_PROPERTIES_RECORD_CODE_SECTION,
-                                     Link,
-                                     IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
-                                     );
-      if (ImageRecordCodeSection->CodeSegmentBase > NextImageRecordCodeSection->CodeSegmentBase) {
-        SwapImageRecordCodeSection (ImageRecordCodeSection, NextImageRecordCodeSection);
-      }
-
-      NextImageRecordCodeSectionLink = NextImageRecordCodeSectionLink->ForwardLink;
-    }
-
-    ImageRecordCodeSectionLink     = ImageRecordCodeSectionLink->ForwardLink;
-    NextImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;
-  }
-}
-
-/**
-  Check if code section in image record is valid.
-
-  @param[in]  ImageRecord    image record to be checked
-
-  @retval TRUE  image record is valid
-  @retval FALSE image record is invalid
-**/
-STATIC
-BOOLEAN
-IsImageRecordCodeSectionValid (
-  IN IMAGE_PROPERTIES_RECORD  *ImageRecord
-  )
-{
-  IMAGE_PROPERTIES_RECORD_CODE_SECTION  *ImageRecordCodeSection;
-  IMAGE_PROPERTIES_RECORD_CODE_SECTION  *LastImageRecordCodeSection;
-  LIST_ENTRY                            *ImageRecordCodeSectionLink;
-  LIST_ENTRY                            *ImageRecordCodeSectionEndLink;
-  LIST_ENTRY                            *ImageRecordCodeSectionList;
-
-  DEBUG ((DEBUG_VERBOSE, "SMM ImageCode SegmentCount - 0x%x\n", ImageRecord->CodeSegmentCount));
-
-  ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList;
-
-  ImageRecordCodeSectionLink    = ImageRecordCodeSectionList->ForwardLink;
-  ImageRecordCodeSectionEndLink = ImageRecordCodeSectionList;
-  LastImageRecordCodeSection    = NULL;
-  while (ImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) {
-    ImageRecordCodeSection = CR (
-                               ImageRecordCodeSectionLink,
-                               IMAGE_PROPERTIES_RECORD_CODE_SECTION,
-                               Link,
-                               IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
-                               );
-    if (ImageRecordCodeSection->CodeSegmentSize == 0) {
-      return FALSE;
-    }
-
-    if (ImageRecordCodeSection->CodeSegmentBase < ImageRecord->ImageBase) {
-      return FALSE;
-    }
-
-    if (ImageRecordCodeSection->CodeSegmentBase >= MAX_ADDRESS - ImageRecordCodeSection->CodeSegmentSize) {
-      return FALSE;
-    }
-
-    if ((ImageRecordCodeSection->CodeSegmentBase + ImageRecordCodeSection->CodeSegmentSize) > (ImageRecord->ImageBase + ImageRecord->ImageSize)) {
-      return FALSE;
-    }
-
-    if (LastImageRecordCodeSection != NULL) {
-      if ((LastImageRecordCodeSection->CodeSegmentBase + LastImageRecordCodeSection->CodeSegmentSize) > ImageRecordCodeSection->CodeSegmentBase) {
-        return FALSE;
-      }
-    }
-
-    LastImageRecordCodeSection = ImageRecordCodeSection;
-    ImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;
-  }
-
-  return TRUE;
-}
-
-/**
-  Swap two image records.
-
-  @param[in]  FirstImageRecord   first image record.
-  @param[in]  SecondImageRecord  second image record.
-**/
-STATIC
-VOID
-SwapImageRecord (
-  IN IMAGE_PROPERTIES_RECORD  *FirstImageRecord,
-  IN IMAGE_PROPERTIES_RECORD  *SecondImageRecord
-  )
-{
-  IMAGE_PROPERTIES_RECORD  TempImageRecord;
-
-  TempImageRecord.ImageBase        = FirstImageRecord->ImageBase;
-  TempImageRecord.ImageSize        = FirstImageRecord->ImageSize;
-  TempImageRecord.CodeSegmentCount = FirstImageRecord->CodeSegmentCount;
-
-  FirstImageRecord->ImageBase        = SecondImageRecord->ImageBase;
-  FirstImageRecord->ImageSize        = SecondImageRecord->ImageSize;
-  FirstImageRecord->CodeSegmentCount = SecondImageRecord->CodeSegmentCount;
-
-  SecondImageRecord->ImageBase        = TempImageRecord.ImageBase;
-  SecondImageRecord->ImageSize        = TempImageRecord.ImageSize;
-  SecondImageRecord->CodeSegmentCount = TempImageRecord.CodeSegmentCount;
-
-  SwapListEntries (&FirstImageRecord->CodeSegmentList, &SecondImageRecord->CodeSegmentList);
-}
-
-/**
-  Sort image record based upon the ImageBase from low to high.
-**/
-STATIC
-VOID
-SortImageRecord (
-  VOID
-  )
-{
-  IMAGE_PROPERTIES_RECORD  *ImageRecord;
-  IMAGE_PROPERTIES_RECORD  *NextImageRecord;
-  LIST_ENTRY               *ImageRecordLink;
-  LIST_ENTRY               *NextImageRecordLink;
-  LIST_ENTRY               *ImageRecordEndLink;
-  LIST_ENTRY               *ImageRecordList;
-
-  ImageRecordList = &mImagePropertiesPrivateData.ImageRecordList;
-
-  ImageRecordLink     = ImageRecordList->ForwardLink;
-  NextImageRecordLink = ImageRecordLink->ForwardLink;
-  ImageRecordEndLink  = ImageRecordList;
-  while (ImageRecordLink != ImageRecordEndLink) {
-    ImageRecord = CR (
-                    ImageRecordLink,
-                    IMAGE_PROPERTIES_RECORD,
-                    Link,
-                    IMAGE_PROPERTIES_RECORD_SIGNATURE
-                    );
-    while (NextImageRecordLink != ImageRecordEndLink) {
-      NextImageRecord = CR (
-                          NextImageRecordLink,
-                          IMAGE_PROPERTIES_RECORD,
-                          Link,
-                          IMAGE_PROPERTIES_RECORD_SIGNATURE
-                          );
-      if (ImageRecord->ImageBase > NextImageRecord->ImageBase) {
-        SwapImageRecord (ImageRecord, NextImageRecord);
-      }
-
-      NextImageRecordLink = NextImageRecordLink->ForwardLink;
-    }
-
-    ImageRecordLink     = ImageRecordLink->ForwardLink;
-    NextImageRecordLink = ImageRecordLink->ForwardLink;
-  }
-}
-
-/**
-  Dump image record.
-**/
-STATIC
-VOID
-DumpImageRecord (
-  VOID
-  )
-{
-  IMAGE_PROPERTIES_RECORD  *ImageRecord;
-  LIST_ENTRY               *ImageRecordLink;
-  LIST_ENTRY               *ImageRecordList;
-  UINTN                    Index;
-
-  ImageRecordList = &mImagePropertiesPrivateData.ImageRecordList;
-
-  for (ImageRecordLink = ImageRecordList->ForwardLink, Index = 0;
-       ImageRecordLink != ImageRecordList;
-       ImageRecordLink = ImageRecordLink->ForwardLink, Index++)
-  {
-    ImageRecord = CR (
-                    ImageRecordLink,
-                    IMAGE_PROPERTIES_RECORD,
-                    Link,
-                    IMAGE_PROPERTIES_RECORD_SIGNATURE
-                    );
-    DEBUG ((DEBUG_VERBOSE, "SMM  Image[%d]: 0x%016lx - 0x%016lx\n", Index, ImageRecord->ImageBase, ImageRecord->ImageSize));
-  }
-}
-
 /**
   Insert image record.
 
@@ -1059,7 +308,7 @@ SmmInsertImageRecord (
   // Step 1: record whole region
   //
   ImageRecord->ImageBase = DriverEntry->ImageBuffer;
-  ImageRecord->ImageSize = EfiPagesToSize (DriverEntry->NumberOfPage);
+  ImageRecord->ImageSize = LShiftU64 (DriverEntry->NumberOfPage, EFI_PAGE_SHIFT);
 
   ImageAddress = (VOID *)(UINTN)DriverEntry->ImageBuffer;
 
@@ -1193,7 +442,7 @@ SmmInsertImageRecord (
     mImagePropertiesPrivateData.CodeSegmentCountMax = ImageRecord->CodeSegmentCount;
   }
 
-  SortImageRecord ();
+  SortImageRecord (&mImagePropertiesPrivateData.ImageRecordList);
 
 Finish:
   return;
@@ -1361,7 +610,7 @@ SmmInstallMemoryAttributesTable (
 
   DEBUG ((DEBUG_VERBOSE, "SMM Total Image Count - 0x%x\n", mImagePropertiesPrivateData.ImageRecordCount));
   DEBUG ((DEBUG_VERBOSE, "SMM Dump ImageRecord:\n"));
-  DumpImageRecord ();
+  DumpImageRecord (&mImagePropertiesPrivateData.ImageRecordList);
 
   PublishMemoryAttributesTable ();
 
diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h
index 43daa037be44..86a7be2f5188 100644
--- a/MdeModulePkg/Core/Dxe/DxeMain.h
+++ b/MdeModulePkg/Core/Dxe/DxeMain.h
@@ -228,26 +228,6 @@ typedef struct {
 #define LOADED_IMAGE_PRIVATE_DATA_FROM_THIS(a) \
           CR(a, LOADED_IMAGE_PRIVATE_DATA, Info, LOADED_IMAGE_PRIVATE_DATA_SIGNATURE)
 
-#define IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE  SIGNATURE_32 ('I','P','R','C')
-
-typedef struct {
-  UINT32                  Signature;
-  LIST_ENTRY              Link;
-  EFI_PHYSICAL_ADDRESS    CodeSegmentBase;
-  UINT64                  CodeSegmentSize;
-} IMAGE_PROPERTIES_RECORD_CODE_SECTION;
-
-#define IMAGE_PROPERTIES_RECORD_SIGNATURE  SIGNATURE_32 ('I','P','R','D')
-
-typedef struct {
-  UINT32                  Signature;
-  LIST_ENTRY              Link;
-  EFI_PHYSICAL_ADDRESS    ImageBase;
-  UINT64                  ImageSize;
-  UINTN                   CodeSegmentCount;
-  LIST_ENTRY              CodeSegmentList;
-} IMAGE_PROPERTIES_RECORD;
-
 //
 // DXE Core Global Variables
 //
diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf
index 35d5bf0dee6f..c0aa37d118c5 100644
--- a/MdeModulePkg/Core/Dxe/DxeMain.inf
+++ b/MdeModulePkg/Core/Dxe/DxeMain.inf
@@ -94,6 +94,7 @@ [LibraryClasses]
   DebugAgentLib
   CpuExceptionHandlerLib
   PcdLib
+  ImagePropertiesRecordLib
 
 [Guids]
   gEfiEventMemoryMapChangeGuid                  ## PRODUCES             ## Event
diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf
index 3df44b38f13c..75a5934f0c1d 100644
--- a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf
+++ b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf
@@ -61,6 +61,7 @@ [LibraryClasses]
   HobLib
   SmmMemLib
   SafeIntLib
+  ImagePropertiesRecordLib
 
 [Protocols]
   gEfiDxeSmmReadyToLockProtocolGuid             ## UNDEFINED # SmiHandlerRegister
-- 
2.41.0.windows.2



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



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

* Re: [edk2-devel] [PATCH v2 0/9] Add ImagePropertiesRecordLib and Fix MAT Bugs
  2023-07-20  0:05 [edk2-devel] [PATCH v2 0/9] Add ImagePropertiesRecordLib and Fix MAT Bugs Taylor Beebe
                   ` (8 preceding siblings ...)
  2023-07-20  0:05 ` [edk2-devel] [PATCH v2 9/9] MdeModulePkg: Update UEFI and SMM MAT Logic To Use ImagePropertiesRecordLib Taylor Beebe
@ 2023-07-20  5:19 ` Ni, Ray
  2023-07-20 18:40   ` Taylor Beebe
  9 siblings, 1 reply; 13+ messages in thread
From: Ni, Ray @ 2023-07-20  5:19 UTC (permalink / raw)
  To: Taylor Beebe, devel@edk2.groups.io
  Cc: Andrew Fish, Ard Biesheuvel, Bi, Dandan, Dong, Eric,
	Gerd Hoffmann, Dong, Guo, Guo, Gua, Lu, James, Wang, Jian J,
	Yao, Jiewen, Justen, Jordan L, Leif Lindholm, Gao, Liming,
	Kumar, Rahul R, Sami Mujawar, Rhodes, Sean

Taylor,
Thank you for your effort for removing the duplicated logic in Dxe/Smm Core and fixing the bugs.

Two general comments:
#1. Can you refactor your patch series in a way that the new lib code is like a "git move" instead of "git add"? For example, you could add an empty lib first and update all DSC to depend on the new lib. Then move the lib code from DxeCore to the lib folder. So that when reviewing the code changes, they are relative smaller.

#2. I see that you directly move the code to lib and update consumer to call the lib APIs. Do you think it's feasible to refine the code further such that the responsibilities of DxeCore and the lib can be clearer and with that the lib APIs can be more meaningful?

I provided thoughts for #1 but haven't thought about #2 specifically.

Thanks,
Ray

> -----Original Message-----
> From: Taylor Beebe <t@taylorbeebe.com>
> Sent: Thursday, July 20, 2023 8:06 AM
> To: devel@edk2.groups.io
> Cc: Andrew Fish <afish@apple.com>; Ard Biesheuvel
> <ardb+tianocore@kernel.org>; Bi, Dandan <dandan.bi@intel.com>; Dong, Eric
> <eric.dong@intel.com>; Gerd Hoffmann <kraxel@redhat.com>; Dong, Guo
> <guo.dong@intel.com>; Guo, Gua <gua.guo@intel.com>; Lu, James
> <james.lu@intel.com>; Wang, Jian J <jian.j.wang@intel.com>; Yao, Jiewen
> <jiewen.yao@intel.com>; Justen, Jordan L <jordan.l.justen@intel.com>; Leif
> Lindholm <quic_llindhol@quicinc.com>; Gao, Liming
> <gaoliming@byosoft.com.cn>; Kumar, Rahul R <rahul.r.kumar@intel.com>; Ni,
> Ray <ray.ni@intel.com>; Sami Mujawar <sami.mujawar@arm.com>; Rhodes,
> Sean <sean@starlabs.systems>
> Subject: [PATCH v2 0/9] Add ImagePropertiesRecordLib and Fix MAT Bugs
> 
> v2:
> - A one-line change in patch 3 was moved to patch 9 for correctness.
> 
> Reference: https://github.com/tianocore/edk2/pull/4590
> Bugzilla: https://bugzilla.tianocore.org/show_bug.cgi?id=4492
> 
> The UEFI and SMM MAT logic contains duplicate logic for manipulating image
> properties records which is used to track runtime images.
> This patch series adds a new library, ImagePropertiesRecordLib,
> which consolidates this logic and fixes the bugs which currently exist in
> the MAT logic.
> 
> The first patch adds the ImagePropertiesRecordLib implementation which
> is a copy of the UEFI MAT logic with minor modifications to remove the
> reliance on globabl variables and make the code unit testable.
> 
> The second patch adds a unit test for the ImagePropertiesRecordLib. The
> logic tests various potential layouts of the EFI memory map and runtime
> images. 3/4 of these tests will fail which demonstrates the MAT logic
> bugs.
> 
> The third patch fixes the logic in the ImagePropertiesRecordLib so
> that all of the unit tests pass and the MAT logic can be fixed by
> using the library.
> 
> The remaining patches add library instances to DSC files and remove
> the image properties record logic from the SMM and UEFI MAT logic.
> 
> Cc: Andrew Fish <afish@apple.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Dandan Bi <dandan.bi@intel.com>
> Cc: Eric Dong <eric.dong@intel.com>
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Cc: Guo Dong <guo.dong@intel.com>
> Cc: Gua Guo <gua.guo@intel.com>
> Cc: James Lu <james.lu@intel.com>
> Cc: Jian J Wang <jian.j.wang@intel.com>
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Leif Lindholm <quic_llindhol@quicinc.com>
> Cc: Liming Gao <gaoliming@byosoft.com.cn>
> Cc: Rahul Kumar <rahul1.kumar@intel.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Sami Mujawar <sami.mujawar@arm.com>
> Cc: Sean Rhodes <sean@starlabs.systems>
> Taylor Beebe (9):
>   MdeModulePkg: Add ImagePropertiesRecordLib
>   MdeModulePkg: Add ImagePropertiesRecordLib Host-Based Unit Test
>   MdeModulePkg: Fix Bugs in MAT Logic
>   ArmVirtPkg: Add ImagePropertiesRecordLib Instance
>   EmulatorPkg: Add ImagePropertiesRecordLib Instance
>   OvmfPkg: Add ImagePropertiesRecordLib Instance
>   UefiPayloadPkg: Add ImagePropertiesRecordLib Instance
>   UefiCpuPkg: Use Attribute From SMM MemoryAttributesTable if Nonzero
>   MdeModulePkg: Update UEFI and SMM MAT Logic To Use
>     ImagePropertiesRecordLib
> 
>  MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c
> | 786 +---------------
>  MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c
> |  24 +-
>  MdeModulePkg/Core/PiSmmCore/MemoryAttributesTable.c
> | 785 +---------------
> 
> MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLi
> b.c                        | 805 +++++++++++++++++
> 
> MdeModulePkg/Library/ImagePropertiesRecordLib/UnitTest/ImageProperties
> RecordLibUnitTestHost.c   | 938 ++++++++++++++++++++
>  UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c
> |  19 +-
>  ArmVirtPkg/ArmVirt.dsc.inc                                                                      |   1 +
>  EmulatorPkg/EmulatorPkg.dsc                                                                     |   1 +
>  MdeModulePkg/Core/Dxe/DxeMain.h                                                                 |  20 -
>  MdeModulePkg/Core/Dxe/DxeMain.inf                                                               |   1 +
>  MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf
> |   1 +
>  MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h
> | 151 ++++
> 
> MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLi
> b.inf                      |  28 +
> 
> MdeModulePkg/Library/ImagePropertiesRecordLib/UnitTest/ImageProperties
> RecordLibUnitTestHost.inf |  35 +
>  MdeModulePkg/MdeModulePkg.dec                                                                   |   5 +
>  MdeModulePkg/MdeModulePkg.dsc                                                                   |   2 +
>  MdeModulePkg/Test/MdeModulePkgHostTest.dsc
> |   5 +
>  OvmfPkg/AmdSev/AmdSevX64.dsc                                                                    |   1 +
>  OvmfPkg/Bhyve/BhyveX64.dsc                                                                      |   1 +
>  OvmfPkg/CloudHv/CloudHvX64.dsc                                                                  |   1 +
>  OvmfPkg/IntelTdx/IntelTdxX64.dsc                                                                |   1 +
>  OvmfPkg/Microvm/MicrovmX64.dsc                                                                  |   1 +
>  OvmfPkg/OvmfPkgIa32.dsc                                                                         |   1 +
>  OvmfPkg/OvmfPkgIa32X64.dsc                                                                      |   1 +
>  OvmfPkg/OvmfPkgX64.dsc                                                                          |   1 +
>  OvmfPkg/OvmfXen.dsc                                                                             |   1 +
>  OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc                                                             |   1 +
>  UefiPayloadPkg/UefiPayloadPkg.dsc                                                               |   1 +
>  28 files changed, 2039 insertions(+), 1579 deletions(-)
>  create mode 100644
> MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLi
> b.c
>  create mode 100644
> MdeModulePkg/Library/ImagePropertiesRecordLib/UnitTest/ImageProperties
> RecordLibUnitTestHost.c
>  create mode 100644
> MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h
>  create mode 100644
> MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLi
> b.inf
>  create mode 100644
> MdeModulePkg/Library/ImagePropertiesRecordLib/UnitTest/ImageProperties
> RecordLibUnitTestHost.inf
> 
> --
> 2.41.0.windows.2



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

* Re: [edk2-devel] [PATCH v2 0/9] Add ImagePropertiesRecordLib and Fix MAT Bugs
  2023-07-20  5:19 ` [edk2-devel] [PATCH v2 0/9] Add ImagePropertiesRecordLib and Fix MAT Bugs Ni, Ray
@ 2023-07-20 18:40   ` Taylor Beebe
  2023-07-21  3:34     ` Ni, Ray
  0 siblings, 1 reply; 13+ messages in thread
From: Taylor Beebe @ 2023-07-20 18:40 UTC (permalink / raw)
  To: devel, ray.ni
  Cc: Andrew Fish, Ard Biesheuvel, Bi, Dandan, Dong, Eric,
	Gerd Hoffmann, Dong, Guo, Guo, Gua, Lu, James, Wang, Jian J,
	Yao, Jiewen, Justen, Jordan L, Leif Lindholm, Gao, Liming,
	Kumar, Rahul R, Sami Mujawar, Rhodes, Sean



On 7/19/23 10:19 PM, Ni, Ray wrote:
> Taylor,
> Thank you for your effort for removing the duplicated logic in Dxe/Smm Core and fixing the bugs.
> 
> Two general comments:
> #1. Can you refactor your patch series in a way that the new lib code is like a "git move" instead of "git add"? For example, you could add an empty lib first and update all DSC to depend on the new lib. Then move the lib code from DxeCore to the lib folder. So that when reviewing the code changes, they are relative smaller.
> 

There are enough differences between the DXE and SMM MAT logic that the
"git move" you suggest won't resolve as cleanly as you hope without
first creating separate library instances then walking them on to a
common implementation. Is there another way I can make this more
digestible?

The MAT logic is very dense, but the most complex part is the 
SplitTable() routine. The host-based unit test should prove that the
expected input/output of the SplitTable() function is correct in this
update.

> #2. I see that you directly move the code to lib and update consumer to call the lib APIs. Do you think it's feasible to refine the code further such that the responsibilities of DxeCore and the lib can be clearer and with that the lib APIs can be more meaningful?
> 

Yes, the currently exposed functions can be renamed and have more
descriptive function headers. I can also round out missing functionality
to attempt to further reduce the code footprint in the
MemoryAttributesTable.c files.

For example:

RemoveImagePropertiesRecord()
InsertImagePropertiesRecord()
DeleteImagePropertiesRecord()
CreateImagePropertiesRecord()


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



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

* Re: [edk2-devel] [PATCH v2 0/9] Add ImagePropertiesRecordLib and Fix MAT Bugs
  2023-07-20 18:40   ` Taylor Beebe
@ 2023-07-21  3:34     ` Ni, Ray
  0 siblings, 0 replies; 13+ messages in thread
From: Ni, Ray @ 2023-07-21  3:34 UTC (permalink / raw)
  To: devel@edk2.groups.io, t@taylorbeebe.com
  Cc: Andrew Fish, Ard Biesheuvel, Bi, Dandan, Dong, Eric,
	Gerd Hoffmann, Dong, Guo, Guo, Gua, Lu, James, Wang, Jian J,
	Yao, Jiewen, Justen, Jordan L, Leif Lindholm, Gao, Liming,
	Kumar, Rahul R, Sami Mujawar, Rhodes, Sean



> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Taylor Beebe
> Sent: Friday, July 21, 2023 2:40 AM
> To: devel@edk2.groups.io; Ni, Ray <ray.ni@intel.com>
> Cc: Andrew Fish <afish@apple.com>; Ard Biesheuvel
> <ardb+tianocore@kernel.org>; Bi, Dandan <dandan.bi@intel.com>; Dong, Eric
> <eric.dong@intel.com>; Gerd Hoffmann <kraxel@redhat.com>; Dong, Guo
> <guo.dong@intel.com>; Guo, Gua <gua.guo@intel.com>; Lu, James
> <james.lu@intel.com>; Wang, Jian J <jian.j.wang@intel.com>; Yao, Jiewen
> <jiewen.yao@intel.com>; Justen, Jordan L <jordan.l.justen@intel.com>; Leif
> Lindholm <quic_llindhol@quicinc.com>; Gao, Liming
> <gaoliming@byosoft.com.cn>; Kumar, Rahul R <rahul.r.kumar@intel.com>; Sami
> Mujawar <sami.mujawar@arm.com>; Rhodes, Sean <sean@starlabs.systems>
> Subject: Re: [edk2-devel] [PATCH v2 0/9] Add ImagePropertiesRecordLib and Fix
> MAT Bugs
> 
> 
> 
> On 7/19/23 10:19 PM, Ni, Ray wrote:
> > Taylor,
> > Thank you for your effort for removing the duplicated logic in Dxe/Smm Core
> and fixing the bugs.
> >
> > Two general comments:
> > #1. Can you refactor your patch series in a way that the new lib code is like a
> "git move" instead of "git add"? For example, you could add an empty lib first and
> update all DSC to depend on the new lib. Then move the lib code from DxeCore to
> the lib folder. So that when reviewing the code changes, they are relative smaller.
> >
> 
> There are enough differences between the DXE and SMM MAT logic that the
> "git move" you suggest won't resolve as cleanly as you hope without
> first creating separate library instances then walking them on to a
> common implementation. Is there another way I can make this more
> digestible?

Even there are lots of differences between DXE and SMM logic, can you start with DXE
implementation first by moving it to a separate lib?
Then you could gradually modify the lib to make it suitable for SMM.


> 
> The MAT logic is very dense, but the most complex part is the
> SplitTable() routine. The host-based unit test should prove that the
> expected input/output of the SplitTable() function is correct in this
> update.
> 
> > #2. I see that you directly move the code to lib and update consumer to call the
> lib APIs. Do you think it's feasible to refine the code further such that the
> responsibilities of DxeCore and the lib can be clearer and with that the lib APIs
> can be more meaningful?
> >
> 
> Yes, the currently exposed functions can be renamed and have more
> descriptive function headers. I can also round out missing functionality
> to attempt to further reduce the code footprint in the
> MemoryAttributesTable.c files.
> 
> For example:
> 
> RemoveImagePropertiesRecord()
> InsertImagePropertiesRecord()
> DeleteImagePropertiesRecord()
> CreateImagePropertiesRecord()


Thanks!


> 
> 
> 
> 



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

end of thread, other threads:[~2023-07-21  3:35 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-07-20  0:05 [edk2-devel] [PATCH v2 0/9] Add ImagePropertiesRecordLib and Fix MAT Bugs Taylor Beebe
2023-07-20  0:05 ` [edk2-devel] [PATCH v2 1/9] MdeModulePkg: Add ImagePropertiesRecordLib Taylor Beebe
2023-07-20  0:05 ` [edk2-devel] [PATCH v2 2/9] MdeModulePkg: Add ImagePropertiesRecordLib Host-Based Unit Test Taylor Beebe
2023-07-20  0:05 ` [edk2-devel] [PATCH v2 3/9] MdeModulePkg: Fix Bugs in MAT Logic Taylor Beebe
2023-07-20  0:05 ` [edk2-devel] [PATCH v2 4/9] ArmVirtPkg: Add ImagePropertiesRecordLib Instance Taylor Beebe
2023-07-20  0:05 ` [edk2-devel] [PATCH v2 5/9] EmulatorPkg: " Taylor Beebe
2023-07-20  0:05 ` [edk2-devel] [PATCH v2 6/9] OvmfPkg: " Taylor Beebe
2023-07-20  0:05 ` [edk2-devel] [PATCH v2 7/9] UefiPayloadPkg: " Taylor Beebe
2023-07-20  0:05 ` [edk2-devel] [PATCH v2 8/9] UefiCpuPkg: Use Attribute From SMM MemoryAttributesTable if Nonzero Taylor Beebe
2023-07-20  0:05 ` [edk2-devel] [PATCH v2 9/9] MdeModulePkg: Update UEFI and SMM MAT Logic To Use ImagePropertiesRecordLib Taylor Beebe
2023-07-20  5:19 ` [edk2-devel] [PATCH v2 0/9] Add ImagePropertiesRecordLib and Fix MAT Bugs Ni, Ray
2023-07-20 18:40   ` Taylor Beebe
2023-07-21  3:34     ` Ni, Ray

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