summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Martin <olivier.martin@arm.com>2014-10-06 17:18:53 +0100
committerRyan Harkin <ryan.harkin@linaro.org>2014-10-22 16:22:40 +0100
commitaa592e479db328a8703ca8d2eb790ed0051fdbb5 (patch)
tree63c1dd736c98617710ac5876a01d87b92e361087
parentc71b2dcbfbbfbec037f6274b4652a1a663c3b969 (diff)
ArmPkg/ArmLib/AArch64: Initialize the new N+1-level page table before registering it
Prior to this change, when a new page table was created at level N+1, the reference to the table was added to the level N translation table, before being initialized. It means if virtual addresses were in the address range defined by this new table the CPU would crash as the address range was not initialized. Change-Id: Iff02afe0dfd7d296bac803bc07deef8552ed392f
-rw-r--r--ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c b/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c
index f0d2bff1a..f215fe927 100644
--- a/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c
+++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c
@@ -251,6 +251,7 @@ GetBlockEntryListFromAddress (
UINTN RootTableEntryCount;
UINT64 *TranslationTable;
UINT64 *BlockEntry;
+ UINT64 *SubTableBlockEntry;
UINT64 BlockEntryAddress;
UINTN BaseAddressAlignment;
UINTN PageLevel;
@@ -382,17 +383,18 @@ GetBlockEntryListFromAddress (
}
TranslationTable = (UINT64*)((UINTN)TranslationTable & TT_ADDRESS_MASK_DESCRIPTION_TABLE);
+ // Populate the newly created lower level table
+ SubTableBlockEntry = TranslationTable;
+ for (Index = 0; Index < TT_ENTRY_COUNT; Index++) {
+ *SubTableBlockEntry = Attributes | (BlockEntryAddress + (Index << TT_ADDRESS_OFFSET_AT_LEVEL(IndexLevel + 1)));
+ SubTableBlockEntry++;
+ }
+
// Fill the BlockEntry with the new TranslationTable
*BlockEntry = ((UINTN)TranslationTable & TT_ADDRESS_MASK_DESCRIPTION_TABLE) | TableAttributes | TT_TYPE_TABLE_ENTRY;
// Update the last block entry with the newly created translation table
*LastBlockEntry = TT_LAST_BLOCK_ADDRESS(TranslationTable, TT_ENTRY_COUNT);
- // Populate the newly created lower level table
- BlockEntry = TranslationTable;
- for (Index = 0; Index < TT_ENTRY_COUNT; Index++) {
- *BlockEntry = Attributes | (BlockEntryAddress + (Index << TT_ADDRESS_OFFSET_AT_LEVEL(IndexLevel + 1)));
- BlockEntry++;
- }
// Block Entry points at the beginning of the Translation Table
BlockEntry = TranslationTable;
}