mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-25 06:34:30 +02:00
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 <ard.biesheuvel@linaro.org> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18586 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
2afeabd1a9
commit
5ab77c6630
@ -408,35 +408,30 @@ GetBlockEntryListFromAddress (
|
|||||||
|
|
||||||
STATIC
|
STATIC
|
||||||
RETURN_STATUS
|
RETURN_STATUS
|
||||||
FillTranslationTable (
|
UpdateRegionMapping (
|
||||||
IN UINT64 *RootTable,
|
IN UINT64 *RootTable,
|
||||||
IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryRegion
|
IN UINT64 RegionStart,
|
||||||
|
IN UINT64 RegionLength,
|
||||||
|
IN UINT64 Attributes,
|
||||||
|
IN UINT64 BlockEntryMask
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINT64 Attributes;
|
|
||||||
UINT32 Type;
|
UINT32 Type;
|
||||||
UINT64 RegionStart;
|
|
||||||
UINT64 RemainingRegionLength;
|
|
||||||
UINT64 *BlockEntry;
|
UINT64 *BlockEntry;
|
||||||
UINT64 *LastBlockEntry;
|
UINT64 *LastBlockEntry;
|
||||||
UINT64 BlockEntrySize;
|
UINT64 BlockEntrySize;
|
||||||
UINTN TableLevel;
|
UINTN TableLevel;
|
||||||
|
|
||||||
// Ensure the Length is aligned on 4KB boundary
|
// 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);
|
ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
|
||||||
return RETURN_INVALID_PARAMETER;
|
return RETURN_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Variable initialization
|
|
||||||
Attributes = ArmMemoryAttributeToPageAttribute (MemoryRegion->Attributes) | TT_AF;
|
|
||||||
RemainingRegionLength = MemoryRegion->Length;
|
|
||||||
RegionStart = MemoryRegion->VirtualBase;
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
// Get the first Block Entry that matches the Virtual Address and also the information on the Table Descriptor
|
// 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
|
// 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);
|
BlockEntry = GetBlockEntryListFromAddress (RootTable, RegionStart, &TableLevel, &BlockEntrySize, &LastBlockEntry);
|
||||||
if (BlockEntry == NULL) {
|
if (BlockEntry == NULL) {
|
||||||
// GetBlockEntryListFromAddress() return NULL when it fails to allocate new pages from the Translation Tables
|
// GetBlockEntryListFromAddress() return NULL when it fails to allocate new pages from the Translation Tables
|
||||||
@ -451,11 +446,12 @@ FillTranslationTable (
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
// Fill the Block Entry with attribute and output block address
|
// 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
|
// Go to the next BlockEntry
|
||||||
RegionStart += BlockEntrySize;
|
RegionStart += BlockEntrySize;
|
||||||
RemainingRegionLength -= BlockEntrySize;
|
RegionLength -= BlockEntrySize;
|
||||||
BlockEntry++;
|
BlockEntry++;
|
||||||
|
|
||||||
// Break the inner loop when next block is a table
|
// Break the inner loop when next block is a table
|
||||||
@ -464,12 +460,28 @@ FillTranslationTable (
|
|||||||
(*BlockEntry & TT_TYPE_MASK) == TT_TYPE_TABLE_ENTRY) {
|
(*BlockEntry & TT_TYPE_MASK) == TT_TYPE_TABLE_ENTRY) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while ((RemainingRegionLength >= BlockEntrySize) && (BlockEntry <= LastBlockEntry));
|
} while ((RegionLength >= BlockEntrySize) && (BlockEntry <= LastBlockEntry));
|
||||||
} while (RemainingRegionLength != 0);
|
} while (RegionLength != 0);
|
||||||
|
|
||||||
return RETURN_SUCCESS;
|
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
|
RETURN_STATUS
|
||||||
SetMemoryAttributes (
|
SetMemoryAttributes (
|
||||||
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user