* [PATCH 0/4] Update CpuDxe MMU Logic to Improve Consistency
@ 2023-06-29 16:17 Taylor Beebe
2023-06-29 16:17 ` [PATCH 1/4] ArmPkg: Apply Uncrustify to Non-Compliant Files Taylor Beebe
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Taylor Beebe @ 2023-06-29 16:17 UTC (permalink / raw)
To: devel; +Cc: Taylor Beebe, Leif Lindholm, Ard Biesheuvel
This patch series:
1. Updates applies uncrustify to noncompliant files
2. Updates GetMemoryRegion() to handle the case where
BaseAddress is an unmapped page, and update some other
return values to be more consistent.
3. Adds some branching paths to what were previously only
ASSERT statements to avoid dereferencing NULL and producing
non-deterministic behavior when ASSERTs are disabled.
4. Adds function headers to the MMU logic documenting the
behavior, parameters, and potetial return values.
Taylor Beebe (4):
ArmPkg: Apply Uncrustify to Non-Compliant Files
ArmPkg: Update GetMemoryRegion() to Handle No mapping
ArmPkg: Fix Unsafe ASSERTs in MMU Logic
ArmPkg: Add Function Headers to MMU Logic
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
ArmPkg/Drivers/CpuDxe/AArch64/Mmu.c | 143 ++++++++++++--
ArmPkg/Drivers/CpuDxe/Arm/Mmu.c | 187 ++++++++++++++----
.../MmCommunicationPei/MmCommunicationPei.c | 6 +-
ArmPkg/Include/IndustryStandard/ArmStdSmc.h | 8 +-
4 files changed, 281 insertions(+), 63 deletions(-)
--
2.41.0.windows.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/4] ArmPkg: Apply Uncrustify to Non-Compliant Files
2023-06-29 16:17 [PATCH 0/4] Update CpuDxe MMU Logic to Improve Consistency Taylor Beebe
@ 2023-06-29 16:17 ` Taylor Beebe
2023-06-29 16:17 ` [PATCH 2/4] ArmPkg: Update GetMemoryRegion() to Handle No mapping Taylor Beebe
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Taylor Beebe @ 2023-06-29 16:17 UTC (permalink / raw)
To: devel; +Cc: Taylor Beebe, Leif Lindholm, Ard Biesheuvel, Taylor Beebe
From: Taylor Beebe <tabeebe@microsoft.com>
This patch applies Uncrustify to the following files:
ArmPkg/Drivers/MmCommunicationPei/MmCommunicationPei.c
ArmPkg/Include/IndustryStandard/ArmStdSmc.h
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Signed-off-by: Taylor Beebe <t@taylorbeebe.com>
---
ArmPkg/Drivers/MmCommunicationPei/MmCommunicationPei.c | 6 +++---
ArmPkg/Include/IndustryStandard/ArmStdSmc.h | 8 ++++----
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/ArmPkg/Drivers/MmCommunicationPei/MmCommunicationPei.c b/ArmPkg/Drivers/MmCommunicationPei/MmCommunicationPei.c
index 5dbe99fc3134..ccb182668d6a 100644
--- a/ArmPkg/Drivers/MmCommunicationPei/MmCommunicationPei.c
+++ b/ArmPkg/Drivers/MmCommunicationPei/MmCommunicationPei.c
@@ -159,8 +159,8 @@ MmCommunicationPeim (
}
CopyMem (CommBuffer, CommunicateHeader, BufferSize);
- *CommSize = BufferSize;
- Status = EFI_SUCCESS;
+ *CommSize = BufferSize;
+ Status = EFI_SUCCESS;
break;
case ARM_SMC_MM_RET_INVALID_PARAMS:
@@ -197,7 +197,7 @@ STATIC CONST EFI_PEI_MM_COMMUNICATION_PPI mPeiMmCommunication = {
STATIC CONST EFI_PEI_PPI_DESCRIPTOR mPeiMmCommunicationPpi = {
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
&gEfiPeiMmCommunicationPpiGuid,
- (VOID*)&mPeiMmCommunication
+ (VOID *)&mPeiMmCommunication
};
/**
diff --git a/ArmPkg/Include/IndustryStandard/ArmStdSmc.h b/ArmPkg/Include/IndustryStandard/ArmStdSmc.h
index 616c650d07c8..f3d78d8e789b 100644
--- a/ArmPkg/Include/IndustryStandard/ArmStdSmc.h
+++ b/ArmPkg/Include/IndustryStandard/ArmStdSmc.h
@@ -248,9 +248,9 @@
* SMC64 SiP Service Calls
*/
-#define SMC_FASTCALL 0x80000000
-#define SMC64_FUNCTION (SMC_FASTCALL | 0x40000000)
-#define SMC_SIP_FUNCTION (SMC64_FUNCTION | 0x02000000)
-#define SMC_SIP_FUNCTION_ID(n) (SMC_SIP_FUNCTION | (n))
+#define SMC_FASTCALL 0x80000000
+#define SMC64_FUNCTION (SMC_FASTCALL | 0x40000000)
+#define SMC_SIP_FUNCTION (SMC64_FUNCTION | 0x02000000)
+#define SMC_SIP_FUNCTION_ID(n) (SMC_SIP_FUNCTION | (n))
#endif // ARM_STD_SMC_H_
--
2.41.0.windows.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/4] ArmPkg: Update GetMemoryRegion() to Handle No mapping
2023-06-29 16:17 [PATCH 0/4] Update CpuDxe MMU Logic to Improve Consistency Taylor Beebe
2023-06-29 16:17 ` [PATCH 1/4] ArmPkg: Apply Uncrustify to Non-Compliant Files Taylor Beebe
@ 2023-06-29 16:17 ` Taylor Beebe
2023-06-29 16:17 ` [PATCH 3/4] ArmPkg: Fix Unsafe ASSERTs in MMU Logic Taylor Beebe
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Taylor Beebe @ 2023-06-29 16:17 UTC (permalink / raw)
To: devel; +Cc: Taylor Beebe, Leif Lindholm, Ard Biesheuvel, Taylor Beebe
From: Taylor Beebe <tabeebe@microsoft.com>
This patch updates the GetMemoryRegion() function to handle the case
where there is no mapping for the requested address.
The original logic for the ARM would hit an ASSERT after
GetMemoryRegionPage() returned EFI_SUCCESS but did not update The
RegionLength parameter.
The original logic for the AARCH64 would never initialize the
RegionLength parameter to zero and return EFI_SUCCESS after
traversing an unknown number of pages.
To fix this, the logic for both architecture has updated to
return EFI_NO_MAPPING if the BaseAddress being checked is unmapped.
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Signed-off-by: Taylor Beebe <t@taylorbeebe.com>
---
ArmPkg/Drivers/CpuDxe/AArch64/Mmu.c | 30 +++++++------
ArmPkg/Drivers/CpuDxe/Arm/Mmu.c | 65 +++++++++++++++++++----------
2 files changed, 60 insertions(+), 35 deletions(-)
diff --git a/ArmPkg/Drivers/CpuDxe/AArch64/Mmu.c b/ArmPkg/Drivers/CpuDxe/AArch64/Mmu.c
index 1d02e41e18d8..0d3bc2809682 100644
--- a/ArmPkg/Drivers/CpuDxe/AArch64/Mmu.c
+++ b/ArmPkg/Drivers/CpuDxe/AArch64/Mmu.c
@@ -380,10 +380,10 @@ GetMemoryRegionRec (
RegionAttributes
);
- // In case of 'Success', it means the end of the block region has been found into the upper
- // level translation table
- if (!EFI_ERROR (Status)) {
- return EFI_SUCCESS;
+ // EFI_SUCCESS: The end of the end of the region was found.
+ // EFI_NO_MAPPING: The translation entry associated with BaseAddress is invalid.
+ if (Status != EFI_NOT_FOUND) {
+ return Status;
}
// Now we processed the table move to the next entry
@@ -395,12 +395,13 @@ GetMemoryRegionRec (
*RegionLength = 0;
*RegionAttributes = *BlockEntry & TT_ATTRIBUTES_MASK;
} else {
- // We have an 'Invalid' entry
- return EFI_UNSUPPORTED;
+ return EFI_NO_MAPPING;
}
while (BlockEntry <= LastBlockEntry) {
- if ((*BlockEntry & TT_ATTRIBUTES_MASK) == *RegionAttributes) {
+ if (((*BlockEntry & TT_TYPE_MASK) == BlockEntryType) &&
+ ((*BlockEntry & TT_ATTRIBUTES_MASK) == *RegionAttributes))
+ {
*RegionLength = *RegionLength + TT_BLOCK_ENTRY_SIZE_AT_LEVEL (TableLevel);
} else {
// In case we have found the end of the region we return success
@@ -412,7 +413,7 @@ GetMemoryRegionRec (
// If we have reached the end of the TranslationTable and we have not found the end of the region then
// we return EFI_NOT_FOUND.
- // The caller will continue to look for the memory region at its level
+ // The caller will continue to look for the memory region at its level.
return EFI_NOT_FOUND;
}
@@ -433,6 +434,11 @@ GetMemoryRegion (
TranslationTable = ArmGetTTBR0BaseAddress ();
+ // Initialize the output parameters. These paramaters are only valid if the
+ // result is EFI_SUCCESS.
+ *RegionLength = 0;
+ *RegionAttributes = 0;
+
T0SZ = ArmGetTCR () & TCR_T0SZ_MASK;
// Get the Table info from T0SZ
GetRootTranslationTableInfo (T0SZ, &TableLevel, &EntryCount);
@@ -447,10 +453,10 @@ GetMemoryRegion (
);
// If the region continues up to the end of the root table then GetMemoryRegionRec()
- // will return EFI_NOT_FOUND
- if (Status == EFI_NOT_FOUND) {
+ // will return EFI_NOT_FOUND. Check if the region length was updated.
+ if ((Status == EFI_NOT_FOUND) && (*RegionLength > 0)) {
return EFI_SUCCESS;
- } else {
- return Status;
}
+
+ return Status;
}
diff --git a/ArmPkg/Drivers/CpuDxe/Arm/Mmu.c b/ArmPkg/Drivers/CpuDxe/Arm/Mmu.c
index afd6aab60204..268c0bf3f9ae 100644
--- a/ArmPkg/Drivers/CpuDxe/Arm/Mmu.c
+++ b/ArmPkg/Drivers/CpuDxe/Arm/Mmu.c
@@ -427,17 +427,20 @@ EfiAttributeToArmAttribute (
EFI_STATUS
GetMemoryRegionPage (
IN UINT32 *PageTable,
- IN OUT UINTN *BaseAddress,
- OUT UINTN *RegionLength,
- OUT UINTN *RegionAttributes
+ IN UINTN *BaseAddress,
+ IN UINTN *RegionAttributes,
+ OUT UINTN *RegionLength
)
{
- UINT32 PageAttributes;
- UINT32 TableIndex;
- UINT32 PageDescriptor;
+ UINT32 PageAttributes;
+ UINT32 TableIndex;
+ UINT32 PageDescriptor;
+ EFI_STATUS Status;
// Convert the section attributes into page attributes
PageAttributes = ConvertSectionAttributesToPageAttributes (*RegionAttributes);
+ Status = EFI_NOT_FOUND;
+ *RegionLength = 0;
// Calculate index into first level translation table for start of modification
TableIndex = ((*BaseAddress) & TT_DESCRIPTOR_PAGE_INDEX_MASK) >> TT_DESCRIPTOR_PAGE_BASE_SHIFT;
@@ -449,23 +452,24 @@ GetMemoryRegionPage (
PageDescriptor = PageTable[TableIndex];
if ((PageDescriptor & TT_DESCRIPTOR_PAGE_TYPE_MASK) == TT_DESCRIPTOR_PAGE_TYPE_FAULT) {
- // Case: End of the boundary of the region
- return EFI_SUCCESS;
+ Status = (*RegionLength > 0) ? EFI_SUCCESS : EFI_NO_MAPPING;
+ break;
} else if ((PageDescriptor & TT_DESCRIPTOR_PAGE_TYPE_PAGE) == TT_DESCRIPTOR_PAGE_TYPE_PAGE) {
- if ((PageDescriptor & TT_DESCRIPTOR_PAGE_ATTRIBUTE_MASK) == PageAttributes) {
- *RegionLength = *RegionLength + TT_DESCRIPTOR_PAGE_SIZE;
- } else {
- // Case: End of the boundary of the region
- return EFI_SUCCESS;
+ if ((PageDescriptor & TT_DESCRIPTOR_PAGE_ATTRIBUTE_MASK) != PageAttributes) {
+ Status = EFI_SUCCESS;
+ break;
}
+
+ *RegionLength += TT_DESCRIPTOR_PAGE_SIZE;
} else {
- // We do not support Large Page yet. We return EFI_SUCCESS that means end of the region.
+ // Large pages are unsupported.
+ Status = EFI_UNSUPPORTED;
ASSERT (0);
- return EFI_SUCCESS;
+ break;
}
}
- return EFI_NOT_FOUND;
+ return Status;
}
EFI_STATUS
@@ -482,6 +486,7 @@ GetMemoryRegion (
UINT32 SectionDescriptor;
ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable;
UINT32 *PageTable;
+ UINTN Length;
// Initialize the arguments
*RegionLength = 0;
@@ -491,7 +496,11 @@ GetMemoryRegion (
// Calculate index into first level translation table for start of modification
TableIndex = TT_DESCRIPTOR_SECTION_BASE_ADDRESS (*BaseAddress) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT;
- ASSERT (TableIndex < TRANSLATION_TABLE_SECTION_COUNT);
+
+ if (TableIndex >= TRANSLATION_TABLE_SECTION_COUNT) {
+ ASSERT (TableIndex < TRANSLATION_TABLE_SECTION_COUNT);
+ return EFI_INVALID_PARAMETER;
+ }
// Get the section at the given index
SectionDescriptor = FirstLevelTable[TableIndex];
@@ -524,6 +533,8 @@ GetMemoryRegion (
TT_DESCRIPTOR_CONVERT_TO_SECTION_AP (PageAttributes);
}
+ Status = EFI_NOT_FOUND;
+
for ( ; TableIndex < TRANSLATION_TABLE_SECTION_COUNT; TableIndex++) {
// Get the section at the given index
SectionDescriptor = FirstLevelTable[TableIndex];
@@ -532,15 +543,18 @@ GetMemoryRegion (
if (TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE (SectionDescriptor)) {
// Extract the page table location from the descriptor
PageTable = (UINT32 *)(SectionDescriptor & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK);
+ Length = 0;
// Scan the page table to find the end of the region.
- Status = GetMemoryRegionPage (PageTable, BaseAddress, RegionLength, RegionAttributes);
- ASSERT (*RegionLength > 0);
+ Status = GetMemoryRegionPage (PageTable, BaseAddress, RegionAttributes, &Length);
+ *RegionLength += Length;
- // If we have found the end of the region (Status == EFI_SUCCESS) then we exit the for-loop
- if (Status == EFI_SUCCESS) {
- break;
+ // Status == EFI_NOT_FOUND implies we have not reached the end of the region.
+ if ((Status == EFI_NOT_FOUND) && (Length > 0)) {
+ continue;
}
+
+ break;
} else if (((SectionDescriptor & TT_DESCRIPTOR_SECTION_TYPE_MASK) == TT_DESCRIPTOR_SECTION_TYPE_SECTION) ||
((SectionDescriptor & TT_DESCRIPTOR_SECTION_TYPE_MASK) == TT_DESCRIPTOR_SECTION_TYPE_SUPERSECTION))
{
@@ -556,5 +570,10 @@ GetMemoryRegion (
}
}
- return EFI_SUCCESS;
+ // Check if the region length was updated.
+ if (*RegionLength > 0) {
+ Status = EFI_SUCCESS;
+ }
+
+ return Status;
}
--
2.41.0.windows.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/4] ArmPkg: Fix Unsafe ASSERTs in MMU Logic
2023-06-29 16:17 [PATCH 0/4] Update CpuDxe MMU Logic to Improve Consistency Taylor Beebe
2023-06-29 16:17 ` [PATCH 1/4] ArmPkg: Apply Uncrustify to Non-Compliant Files Taylor Beebe
2023-06-29 16:17 ` [PATCH 2/4] ArmPkg: Update GetMemoryRegion() to Handle No mapping Taylor Beebe
@ 2023-06-29 16:17 ` Taylor Beebe
2023-06-29 16:17 ` [PATCH 4/4] ArmPkg: Add Function Headers to " Taylor Beebe
2023-07-03 14:17 ` [PATCH 0/4] Update CpuDxe MMU Logic to Improve Consistency Ard Biesheuvel
4 siblings, 0 replies; 6+ messages in thread
From: Taylor Beebe @ 2023-06-29 16:17 UTC (permalink / raw)
To: devel; +Cc: Taylor Beebe, Leif Lindholm, Ard Biesheuvel, Taylor Beebe
From: Taylor Beebe <tabeebe@microsoft.com>
There are ASSERTs present in the MMU logic to ensure various
functions return successfully, but these ASSERTs may be ignored
on release builds causing unsafe behavior. This patch updates
the logic to handle unexpected return values and branch safely.
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Signed-off-by: Taylor Beebe <t@taylorbeebe.com>
---
ArmPkg/Drivers/CpuDxe/AArch64/Mmu.c | 21 ++++++++++++-----
ArmPkg/Drivers/CpuDxe/Arm/Mmu.c | 36 ++++++++++++++++++++++++-----
2 files changed, 45 insertions(+), 12 deletions(-)
diff --git a/ArmPkg/Drivers/CpuDxe/AArch64/Mmu.c b/ArmPkg/Drivers/CpuDxe/AArch64/Mmu.c
index 0d3bc2809682..d9d386dbed6b 100644
--- a/ArmPkg/Drivers/CpuDxe/AArch64/Mmu.c
+++ b/ArmPkg/Drivers/CpuDxe/AArch64/Mmu.c
@@ -148,10 +148,12 @@ GetNextEntryAttribute (
// Get the memory space map from GCD
MemorySpaceMap = NULL;
Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);
- ASSERT_EFI_ERROR (Status);
- // We cannot get more than 3-level page table
- ASSERT (TableLevel <= 3);
+ if (EFI_ERROR (Status) || (TableLevel > 3)) {
+ ASSERT_EFI_ERROR (Status);
+ ASSERT (TableLevel <= 3);
+ return 0;
+ }
// While the top level table might not contain TT_ENTRY_COUNT entries;
// the subsequent ones should be filled up
@@ -243,7 +245,11 @@ SyncCacheConfig (
//
MemorySpaceMap = NULL;
Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);
- ASSERT_EFI_ERROR (Status);
+
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
// The GCD implementation maintains its own copy of the state of memory space attributes. GCD needs
// to know what the initial memory space attributes are. The CPU Arch. Protocol does not provide a
@@ -277,7 +283,7 @@ SyncCacheConfig (
);
// Update GCD with the last region if valid
- if (PageAttribute != INVALID_ENTRY) {
+ if ((PageAttribute != INVALID_ENTRY) && (EndAddressGcdRegion > BaseAddressGcdRegion)) {
SetGcdMemorySpaceAttributes (
MemorySpaceMap,
NumberOfDescriptors,
@@ -430,7 +436,10 @@ GetMemoryRegion (
UINTN EntryCount;
UINTN T0SZ;
- ASSERT ((BaseAddress != NULL) && (RegionLength != NULL) && (RegionAttributes != NULL));
+ if ((BaseAddress == NULL) || (RegionLength == NULL) || (RegionAttributes == NULL)) {
+ ASSERT ((BaseAddress != NULL) && (RegionLength != NULL) && (RegionAttributes != NULL));
+ return EFI_INVALID_PARAMETER;
+ }
TranslationTable = ArmGetTTBR0BaseAddress ();
diff --git a/ArmPkg/Drivers/CpuDxe/Arm/Mmu.c b/ArmPkg/Drivers/CpuDxe/Arm/Mmu.c
index 268c0bf3f9ae..5a2f36d06086 100644
--- a/ArmPkg/Drivers/CpuDxe/Arm/Mmu.c
+++ b/ArmPkg/Drivers/CpuDxe/Arm/Mmu.c
@@ -217,7 +217,10 @@ SyncCacheConfigPage (
} else if (PageAttributes != NextPageAttributes) {
// Convert Section Attributes into GCD Attributes
Status = PageToGcdAttributes (NextPageAttributes, &GcdAttributes);
- ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ GcdAttributes = 0;
+ }
// update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)
SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, *NextRegionBase, *NextRegionLength, GcdAttributes);
@@ -230,7 +233,10 @@ SyncCacheConfigPage (
} else if (NextPageAttributes != 0) {
// Convert Page Attributes into GCD Attributes
Status = PageToGcdAttributes (NextPageAttributes, &GcdAttributes);
- ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ GcdAttributes = 0;
+ }
// update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)
SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, *NextRegionBase, *NextRegionLength, GcdAttributes);
@@ -278,7 +284,12 @@ SyncCacheConfig (
//
MemorySpaceMap = NULL;
Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);
- ASSERT_EFI_ERROR (Status);
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "SyncCacheConfig - GetMemorySpaceMap() failed! Status: %r\n", Status));
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
// The GCD implementation maintains its own copy of the state of memory space attributes. GCD needs
// to know what the initial memory space attributes are. The CPU Arch. Protocol does not provide a
@@ -307,7 +318,12 @@ SyncCacheConfig (
} else if (SectionAttributes != NextSectionAttributes) {
// Convert Section Attributes into GCD Attributes
Status = SectionToGcdAttributes (NextSectionAttributes, &GcdAttributes);
- ASSERT_EFI_ERROR (Status);
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "SyncCacheConfig - SectionToGcdAttributes() failed! Status: %r\n", Status));
+ ASSERT_EFI_ERROR (Status);
+ GcdAttributes = 0;
+ }
// update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)
SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, NextRegionBase, NextRegionLength, GcdAttributes);
@@ -343,7 +359,11 @@ SyncCacheConfig (
if (NextSectionAttributes != 0) {
// Convert Section Attributes into GCD Attributes
Status = SectionToGcdAttributes (NextSectionAttributes, &GcdAttributes);
- ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "SyncCacheConfig - SectionToGcdAttributes() failed! Status: %r\n", Status));
+ ASSERT_EFI_ERROR (Status);
+ GcdAttributes = 0;
+ }
// update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)
SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, NextRegionBase, NextRegionLength, GcdAttributes);
@@ -360,7 +380,11 @@ SyncCacheConfig (
if (NextSectionAttributes != 0) {
// Convert Section Attributes into GCD Attributes
Status = SectionToGcdAttributes (NextSectionAttributes, &GcdAttributes);
- ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "SyncCacheConfig - SectionToGcdAttributes() failed! Status: %r\n", Status));
+ ASSERT_EFI_ERROR (Status);
+ GcdAttributes = 0;
+ }
// update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)
SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, NextRegionBase, NextRegionLength, GcdAttributes);
--
2.41.0.windows.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 4/4] ArmPkg: Add Function Headers to MMU Logic
2023-06-29 16:17 [PATCH 0/4] Update CpuDxe MMU Logic to Improve Consistency Taylor Beebe
` (2 preceding siblings ...)
2023-06-29 16:17 ` [PATCH 3/4] ArmPkg: Fix Unsafe ASSERTs in MMU Logic Taylor Beebe
@ 2023-06-29 16:17 ` Taylor Beebe
2023-07-03 14:17 ` [PATCH 0/4] Update CpuDxe MMU Logic to Improve Consistency Ard Biesheuvel
4 siblings, 0 replies; 6+ messages in thread
From: Taylor Beebe @ 2023-06-29 16:17 UTC (permalink / raw)
To: devel; +Cc: Taylor Beebe, Leif Lindholm, Ard Biesheuvel, Taylor Beebe
From: Taylor Beebe <tabeebe@microsoft.com>
Much of the MMU logic was written without function headers. This patch
adds function headers where absent and updates function headers which
do not match the EDK2 standard.
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Signed-off-by: Taylor Beebe <t@taylorbeebe.com>
---
ArmPkg/Drivers/CpuDxe/AArch64/Mmu.c | 92 ++++++++++++++++++++++++++++-
ArmPkg/Drivers/CpuDxe/Arm/Mmu.c | 86 ++++++++++++++++++++++++---
2 files changed, 169 insertions(+), 9 deletions(-)
diff --git a/ArmPkg/Drivers/CpuDxe/AArch64/Mmu.c b/ArmPkg/Drivers/CpuDxe/AArch64/Mmu.c
index d9d386dbed6b..e14eb47ce4c6 100644
--- a/ArmPkg/Drivers/CpuDxe/AArch64/Mmu.c
+++ b/ArmPkg/Drivers/CpuDxe/AArch64/Mmu.c
@@ -18,6 +18,14 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#define MIN_T0SZ 16
#define BITS_PER_LEVEL 9
+/**
+ Parses T0SZ to determine the level and number of entries at the root
+ of the translation table.
+
+ @param T0SZ The T0SZ value to be parsed.
+ @param RootTableLevel The level of the root table.
+ @param RootTableEntryCount The number of entries in the root table.
+**/
STATIC
VOID
GetRootTranslationTableInfo (
@@ -30,6 +38,13 @@ GetRootTranslationTableInfo (
*RootTableEntryCount = TT_ENTRY_COUNT >> (T0SZ - MIN_T0SZ) % BITS_PER_LEVEL;
}
+/**
+ Converts ARM translation table attributes to GCD attributes.
+
+ @param PageAttributes The translation table attributes to be converted.
+
+ @retval The analogous GCD attributes.
+**/
STATIC
UINT64
PageAttributeToGcdAttribute (
@@ -100,6 +115,14 @@ RegionAttributeToGcdAttribute (
return PageAttributeToGcdAttribute (PageAttributes);
}
+/**
+ Retrieves the attribute of the first page entry in the translation table.
+
+ @param[in] FirstLevelTableAddress The base address of the translation table.
+ @param[in] TableLevel The current level being traversed.
+
+ @retval The attributes of the first page entry found, or INVALID_ENTRY.
+**/
STATIC
UINT64
GetFirstPageAttribute (
@@ -126,6 +149,19 @@ GetFirstPageAttribute (
}
}
+/**
+ This function recursively traverses the translation table heirarchy to
+ synchronise the GCD with the translation table.
+
+ @param[in] TableAddress The address of the table being processed.
+ @param[in] EntryCount The number of entries in the current level of the table.
+ @param[in] TableLevel The current level of the memory table being processed.
+ @param[in] BaseAddress The starting address of the region.
+ @param[in, out] PrevEntryAttribute The attributes of the previous region.
+ @param[in, out] StartGcdRegion The start of the GCD region.
+
+ @retval The address at the end of the last region processed.
+**/
STATIC
UINT64
GetNextEntryAttribute (
@@ -220,6 +256,15 @@ GetNextEntryAttribute (
return BaseAddress + (EntryCount * TT_ADDRESS_AT_LEVEL (TableLevel));
}
+/**
+ Sync the GCD memory space attributes with the translation table.
+
+ @param[in] CpuProtocol The CPU architectural protocol instance.
+
+ @retval EFI_SUCCESS The GCD memory space attributes are synced with
+ the MMU page table.
+ @retval Others The return value of GetMemorySpaceMap().
+**/
EFI_STATUS
SyncCacheConfig (
IN EFI_CPU_ARCH_PROTOCOL *CpuProtocol
@@ -298,6 +343,13 @@ SyncCacheConfig (
return EFI_SUCCESS;
}
+/**
+ Convert EFI memory attributes to ARM translation table attributes.
+
+ @param[in] EfiAttributes EFI memory attributes.
+
+ @retval The analogous translation table attributes.
+**/
UINT64
EfiAttributeToArmAttribute (
IN UINT64 EfiAttributes
@@ -345,8 +397,25 @@ EfiAttributeToArmAttribute (
return ArmAttributes;
}
-// This function will recursively go down the page table to find the first block address linked to 'BaseAddress'.
-// And then the function will identify the size of the region that has the same page table attribute.
+/**
+ This function returns the attributes of the memory region containing the
+ specified address.
+
+ RegionLength and RegionAttributes are only valid if the result is EFI_SUCCESS.
+
+ @param[in] TranslationTable The translation table base address.
+ @param[in] TableLevel The level of the translation table.
+ @param[in] LastBlockEntry The last block address of the table level.
+ @param[in, out] BaseAddress The base address of the memory region.
+ @param[out] RegionLength The length of the memory region.
+ @param[out] RegionAttributes The attributes of the memory region.
+
+ @retval EFI_SUCCESS The attributes of the memory region were
+ returned successfully.
+ @retval EFI_NOT_FOUND The memory region was not found.
+ @retval EFI_NO_MAPPING The translation table entry associated with
+ BaseAddress is invalid.
+**/
EFI_STATUS
GetMemoryRegionRec (
IN UINT64 *TranslationTable,
@@ -423,6 +492,25 @@ GetMemoryRegionRec (
return EFI_NOT_FOUND;
}
+/**
+ Retrieves a memory region from a given base address.
+
+ This function retrieves a memory region starting from a given base address.
+
+ @param[in, out] BaseAddress The base address from which to retrieve
+ the memory region. On successful return, this is
+ updated to the end address of the retrieved region.
+ @param[out] RegionLength The length of the retrieved memory region.
+ @param[out] RegionAttributes The attributes of the retrieved memory region.
+
+ @retval EFI_STATUS Returns EFI_SUCCESS if the memory region is
+ retrieved successfully, or the status of the
+ recursive call to GetMemoryRegionRec.
+ @retval EFI_NOT_FOUND The memory region was not found.
+ @retval EFI_NO_MAPPING The translation table entry associated with
+ BaseAddress is invalid.
+ @retval EFI_INVALID_PARAMETER One of the input parameters was NULL.
+**/
EFI_STATUS
GetMemoryRegion (
IN OUT UINTN *BaseAddress,
diff --git a/ArmPkg/Drivers/CpuDxe/Arm/Mmu.c b/ArmPkg/Drivers/CpuDxe/Arm/Mmu.c
index 5a2f36d06086..8c4de284e160 100644
--- a/ArmPkg/Drivers/CpuDxe/Arm/Mmu.c
+++ b/ArmPkg/Drivers/CpuDxe/Arm/Mmu.c
@@ -17,9 +17,12 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
Convert a set of ARM short descriptor section attributes into a mask
of EFI_MEMORY_xx constants.
- @param SectionAttributes The set of page attributes.
- @param GcdAttributes Pointer to the return value.
+ @param[in] SectionAttributes The set of page attributes.
+ @param[out] GcdAttributes Pointer to the return value.
+ @retval EFI_SUCCESS The attributes were converted successfully.
+ @retval EFI_UNSUPPORTED The section attributes did not have a
+ GCD transation.
**/
STATIC
EFI_STATUS
@@ -87,10 +90,11 @@ SectionToGcdAttributes (
Convert an arch specific set of page attributes into a mask
of EFI_MEMORY_xx constants.
- @param PageAttributes The set of page attributes.
-
- @retval The mask of EFI_MEMORY_xx constants.
+ @param[in] PageAttributes The set of page attributes.
+ @retval EFI_SUCCESS The attributes were converted successfully.
+ @retval EFI_UNSUPPORTED The section attributes did not have a
+ GCD transation.
**/
UINT64
RegionAttributeToGcdAttribute (
@@ -107,9 +111,11 @@ RegionAttributeToGcdAttribute (
Convert a set of ARM short descriptor page attributes into a mask
of EFI_MEMORY_xx constants.
- @param PageAttributes The set of page attributes.
- @param GcdAttributes Pointer to the return value.
+ @param[in] PageAttributes The set of page attributes.
+ @param[out] GcdAttributes Pointer to the return value.
+ @retval EFI_SUCCESS The attributes were converted successfully.
+ @retval EFI_UNSUPPORTED The page attributes did not have a GCD transation.
**/
STATIC
EFI_STATUS
@@ -173,6 +179,23 @@ PageToGcdAttributes (
return EFI_SUCCESS;
}
+/**
+ Synchronizes the GCD with the translation table for a specified page.
+
+ This function synchronizes cache configuration for a given page based on its section index
+ and the first level descriptor. It traverses the second level table entries of the page and
+ updates the GCD attributes accordingly for each entry.
+
+ @param[in] SectionIndex The index of the section where the page resides.
+ @param[in] FirstLevelDescriptor The first translation table level of the page.
+ @param[in] NumberOfDescriptors The number of descriptors in the GCD memory space map.
+ @param[in] MemorySpaceMap The GCD memory space descriptor.
+ @param[in, out] NextRegionBase The next region base address.
+ @param[in, out] NextRegionLength The next region length.
+ @param[in, out] NextSectionAttributes The next section attributes.
+
+ @retval EFI_STATUS Always return success
+**/
EFI_STATUS
SyncCacheConfigPage (
IN UINT32 SectionIndex,
@@ -258,6 +281,14 @@ SyncCacheConfigPage (
return EFI_SUCCESS;
}
+/**
+ Sync the GCD memory space attributes with the translation table.
+
+ @param[in] CpuProtocol The CPU architectural protocol instance.
+
+ @retval EFI_SUCCESS The GCD memory space attributes are synced with the MMU page table.
+ @retval Others The return value of GetMemorySpaceMap().
+**/
EFI_STATUS
SyncCacheConfig (
IN EFI_CPU_ARCH_PROTOCOL *CpuProtocol
@@ -395,6 +426,13 @@ SyncCacheConfig (
return EFI_SUCCESS;
}
+/**
+ Convert EFI memory attributes to ARM translation table attributes.
+
+ @param[in] EfiAttributes EFI memory attributes.
+
+ @retval The analogous translation table attributes.
+**/
UINT64
EfiAttributeToArmAttribute (
IN UINT64 EfiAttributes
@@ -448,6 +486,22 @@ EfiAttributeToArmAttribute (
return ArmAttributes;
}
+/**
+ This function finds the end of a memory region in a translation table. A
+ memory region is defined as a contiguous set of pages with the same attributes.
+
+ @param[in] PageTable The translation table to traverse.
+ @param[in] BaseAddress The address from which to start the search
+ @param[in] RegionAttributes The attributes of the start of the region.
+ @param[out] RegionLength The length of the region found.
+
+ @retval EFI_SUCCESS The region was found.
+ @retval EFI_NOT_FOUND The end of the region was not found.
+ @retval EFI_NO_MAPPING The region specified by BaseAddress is not mapped
+ in the input translation table.
+ @retval EFI_UNSUPPORTED Large pages are not supported.
+**/
+STATIC
EFI_STATUS
GetMemoryRegionPage (
IN UINT32 *PageTable,
@@ -496,6 +550,24 @@ GetMemoryRegionPage (
return Status;
}
+/**
+ Get the memory region that contains the specified address. A memory region is defined
+ as a contiguous set of pages with the same attributes.
+
+ RegionLength and RegionAttributes are only valid if EFI_SUCCESS is returned.
+
+ @param[in, out] BaseAddress On input, the address to search for.
+ On output, the base address of the region found.
+ @param[out] RegionLength The length of the region found.
+ @param[out] RegionAttributes The attributes of the region found.
+
+ @retval EFI_SUCCESS Region found
+ @retval EFI_NOT_FOUND Region not found
+ @retval EFI_UNSUPPORTED Large pages are unsupported
+ @retval EFI_NO_MAPPING The page specified by BaseAddress is unmapped
+ @retval EFI_INVALID_PARAMETER The BaseAddress exceeds the addressable range of
+ the translation table.
+**/
EFI_STATUS
GetMemoryRegion (
IN OUT UINTN *BaseAddress,
--
2.41.0.windows.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 0/4] Update CpuDxe MMU Logic to Improve Consistency
2023-06-29 16:17 [PATCH 0/4] Update CpuDxe MMU Logic to Improve Consistency Taylor Beebe
` (3 preceding siblings ...)
2023-06-29 16:17 ` [PATCH 4/4] ArmPkg: Add Function Headers to " Taylor Beebe
@ 2023-07-03 14:17 ` Ard Biesheuvel
4 siblings, 0 replies; 6+ messages in thread
From: Ard Biesheuvel @ 2023-07-03 14:17 UTC (permalink / raw)
To: Taylor Beebe; +Cc: devel, Leif Lindholm, Ard Biesheuvel
On Thu, 29 Jun 2023 at 18:20, Taylor Beebe <t@taylorbeebe.com> wrote:
>
> This patch series:
>
> 1. Updates applies uncrustify to noncompliant files
> 2. Updates GetMemoryRegion() to handle the case where
> BaseAddress is an unmapped page, and update some other
> return values to be more consistent.
> 3. Adds some branching paths to what were previously only
> ASSERT statements to avoid dereferencing NULL and producing
> non-deterministic behavior when ASSERTs are disabled.
> 4. Adds function headers to the MMU logic documenting the
> behavior, parameters, and potetial return values.
>
> Taylor Beebe (4):
> ArmPkg: Apply Uncrustify to Non-Compliant Files
> ArmPkg: Update GetMemoryRegion() to Handle No mapping
> ArmPkg: Fix Unsafe ASSERTs in MMU Logic
> ArmPkg: Add Function Headers to MMU Logic
>
> Cc: Leif Lindholm <quic_llindhol@quicinc.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
>
Thanks a lot for cleaning this up.
For the series,
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
I've submitted these to be merged,
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2023-07-03 14:17 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-06-29 16:17 [PATCH 0/4] Update CpuDxe MMU Logic to Improve Consistency Taylor Beebe
2023-06-29 16:17 ` [PATCH 1/4] ArmPkg: Apply Uncrustify to Non-Compliant Files Taylor Beebe
2023-06-29 16:17 ` [PATCH 2/4] ArmPkg: Update GetMemoryRegion() to Handle No mapping Taylor Beebe
2023-06-29 16:17 ` [PATCH 3/4] ArmPkg: Fix Unsafe ASSERTs in MMU Logic Taylor Beebe
2023-06-29 16:17 ` [PATCH 4/4] ArmPkg: Add Function Headers to " Taylor Beebe
2023-07-03 14:17 ` [PATCH 0/4] Update CpuDxe MMU Logic to Improve Consistency Ard Biesheuvel
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox