From 5ab77c6630317f0ab2da1892e6d36a4b83e06a2f Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Thu, 8 Oct 2015 18:52:06 +0000 Subject: [PATCH] ArmPkg/AArch64Mmu: move page table traversal code to separate function Move the page table traversal and splitting logic to a separate function UpdateRegionMapping() and refactor it slightly so we can reuse it later to implement non-executable regions, for the stack. This primarly involves adding a value/mask pair to the function prototype that allows us to flip arbitrary bits on each block entry as the page tables are traversed. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel Reviewed-by: Leif Lindholm git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18586 6f19259b-4bc3-4df7-8a09-765794883524 --- ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c | 50 ++++++++++++++-------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c b/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c index d82c82c202..60f5cf188d 100644 --- a/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c +++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c @@ -408,35 +408,30 @@ GetBlockEntryListFromAddress ( STATIC RETURN_STATUS -FillTranslationTable ( - IN UINT64 *RootTable, - IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryRegion +UpdateRegionMapping ( + IN UINT64 *RootTable, + IN UINT64 RegionStart, + IN UINT64 RegionLength, + IN UINT64 Attributes, + IN UINT64 BlockEntryMask ) { - UINT64 Attributes; UINT32 Type; - UINT64 RegionStart; - UINT64 RemainingRegionLength; - UINT64 *BlockEntry; - UINT64 *LastBlockEntry; + UINT64 *BlockEntry; + UINT64 *LastBlockEntry; UINT64 BlockEntrySize; UINTN TableLevel; // Ensure the Length is aligned on 4KB boundary - if ((MemoryRegion->Length == 0) || ((MemoryRegion->Length & (SIZE_4KB - 1)) != 0)) { + if ((RegionLength == 0) || ((RegionLength & (SIZE_4KB - 1)) != 0)) { ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); return RETURN_INVALID_PARAMETER; } - // Variable initialization - Attributes = ArmMemoryAttributeToPageAttribute (MemoryRegion->Attributes) | TT_AF; - RemainingRegionLength = MemoryRegion->Length; - RegionStart = MemoryRegion->VirtualBase; - do { // Get the first Block Entry that matches the Virtual Address and also the information on the Table Descriptor // such as the the size of the Block Entry and the address of the last BlockEntry of the Table Descriptor - BlockEntrySize = RemainingRegionLength; + BlockEntrySize = RegionLength; BlockEntry = GetBlockEntryListFromAddress (RootTable, RegionStart, &TableLevel, &BlockEntrySize, &LastBlockEntry); if (BlockEntry == NULL) { // GetBlockEntryListFromAddress() return NULL when it fails to allocate new pages from the Translation Tables @@ -451,11 +446,12 @@ FillTranslationTable ( do { // Fill the Block Entry with attribute and output block address - *BlockEntry = (RegionStart & TT_ADDRESS_MASK_BLOCK_ENTRY) | Attributes | Type; + *BlockEntry &= BlockEntryMask; + *BlockEntry |= (RegionStart & TT_ADDRESS_MASK_BLOCK_ENTRY) | Attributes | Type; // Go to the next BlockEntry RegionStart += BlockEntrySize; - RemainingRegionLength -= BlockEntrySize; + RegionLength -= BlockEntrySize; BlockEntry++; // Break the inner loop when next block is a table @@ -464,12 +460,28 @@ FillTranslationTable ( (*BlockEntry & TT_TYPE_MASK) == TT_TYPE_TABLE_ENTRY) { break; } - } while ((RemainingRegionLength >= BlockEntrySize) && (BlockEntry <= LastBlockEntry)); - } while (RemainingRegionLength != 0); + } while ((RegionLength >= BlockEntrySize) && (BlockEntry <= LastBlockEntry)); + } while (RegionLength != 0); return RETURN_SUCCESS; } +STATIC +RETURN_STATUS +FillTranslationTable ( + IN UINT64 *RootTable, + IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryRegion + ) +{ + return UpdateRegionMapping ( + RootTable, + MemoryRegion->VirtualBase, + MemoryRegion->Length, + ArmMemoryAttributeToPageAttribute (MemoryRegion->Attributes) | TT_AF, + 0 + ); +} + RETURN_STATUS SetMemoryAttributes ( IN EFI_PHYSICAL_ADDRESS BaseAddress, -- 2.39.5