summaryrefslogtreecommitdiffstats
path: root/ArmPkg
diff options
context:
space:
mode:
Diffstat (limited to 'ArmPkg')
-rw-r--r--ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c10
-rw-r--r--ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c11
2 files changed, 21 insertions, 0 deletions
diff --git a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c
index 6d21a2e41d..1ce200c43c 100644
--- a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c
+++ b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c
@@ -252,6 +252,16 @@ UpdateRegionMappingRecursive (
if (!IsTableEntry (*Entry, Level)) {
//
+ // If the region we are trying to map is already covered by a block
+ // entry with the right attributes, don't bother splitting it up.
+ //
+ if (IsBlockEntry (*Entry, Level) &&
+ ((*Entry & TT_ATTRIBUTES_MASK & ~AttributeClearMask) == AttributeSetMask))
+ {
+ continue;
+ }
+
+ //
// No table entry exists yet, so we need to allocate a page table
// for the next level.
//
diff --git a/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c b/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c
index 247cf87bf3..299d38ad07 100644
--- a/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c
+++ b/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c
@@ -170,6 +170,17 @@ UpdatePageEntries (
// Does this descriptor need to be converted from section entry to 4K pages?
if (!TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE (Descriptor)) {
+ //
+ // If the section mapping covers the requested region with the expected
+ // attributes, splitting it is unnecessary, and should be avoided as it
+ // may result in unbounded recursion when using a strict NX policy.
+ //
+ if ((EntryValue & ~TT_DESCRIPTOR_PAGE_TYPE_MASK & EntryMask) ==
+ (ConvertSectionAttributesToPageAttributes (Descriptor) & EntryMask))
+ {
+ continue;
+ }
+
Status = ConvertSectionToPages (FirstLevelIdx << TT_DESCRIPTOR_SECTION_BASE_SHIFT);
if (EFI_ERROR (Status)) {
// Exit for loop