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.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Olivier Martin <olivier.martin@arm.com>



git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16206 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Olivier Martin 2014-10-10 11:25:04 +00:00 committed by oliviermartin
parent 1a70a690ea
commit ebb9235329
1 changed files with 8 additions and 6 deletions

View File

@ -251,6 +251,7 @@ GetBlockEntryListFromAddress (
UINTN RootTableEntryCount; UINTN RootTableEntryCount;
UINT64 *TranslationTable; UINT64 *TranslationTable;
UINT64 *BlockEntry; UINT64 *BlockEntry;
UINT64 *SubTableBlockEntry;
UINT64 BlockEntryAddress; UINT64 BlockEntryAddress;
UINTN BaseAddressAlignment; UINTN BaseAddressAlignment;
UINTN PageLevel; UINTN PageLevel;
@ -382,17 +383,18 @@ GetBlockEntryListFromAddress (
} }
TranslationTable = (UINT64*)((UINTN)TranslationTable & TT_ADDRESS_MASK_DESCRIPTION_TABLE); 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 // Fill the BlockEntry with the new TranslationTable
*BlockEntry = ((UINTN)TranslationTable & TT_ADDRESS_MASK_DESCRIPTION_TABLE) | TableAttributes | TT_TYPE_TABLE_ENTRY; *BlockEntry = ((UINTN)TranslationTable & TT_ADDRESS_MASK_DESCRIPTION_TABLE) | TableAttributes | TT_TYPE_TABLE_ENTRY;
// Update the last block entry with the newly created translation table // Update the last block entry with the newly created translation table
*LastBlockEntry = TT_LAST_BLOCK_ADDRESS(TranslationTable, TT_ENTRY_COUNT); *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 // Block Entry points at the beginning of the Translation Table
BlockEntry = TranslationTable; BlockEntry = TranslationTable;
} }