summaryrefslogtreecommitdiffstats
path: root/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c
diff options
context:
space:
mode:
Diffstat (limited to 'UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c')
-rw-r--r--UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c46
1 files changed, 41 insertions, 5 deletions
diff --git a/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c b/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c
index 76c3719cdf..64383cc522 100644
--- a/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c
+++ b/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c
@@ -274,6 +274,7 @@ IsAttributesAndMaskValidForNonPresentEntry (
Page table entries that map the linear address range are reset to 0 before set to the new attribute
when a new physical base address is set.
@param[in] Mask The mask used for attribute. The corresponding field in Attribute is ignored if that in Mask is 0.
+ @param[out] IsModified TRUE means page table is modified. FALSE means page table is not modified.
@retval RETURN_INVALID_PARAMETER For non-present range, Mask->Bits.Present is 0 but some other attributes are provided.
@retval RETURN_INVALID_PARAMETER For non-present range, Mask->Bits.Present is 1, Attribute->Bits.Present is 1 but some other attributes are not provided.
@@ -292,7 +293,8 @@ PageTableLibMapInLevel (
IN UINT64 Length,
IN UINT64 Offset,
IN IA32_MAP_ATTRIBUTE *Attribute,
- IN IA32_MAP_ATTRIBUTE *Mask
+ IN IA32_MAP_ATTRIBUTE *Mask,
+ OUT BOOLEAN *IsModified
)
{
RETURN_STATUS Status;
@@ -318,6 +320,8 @@ PageTableLibMapInLevel (
IA32_MAP_ATTRIBUTE LocalParentAttribute;
UINT64 PhysicalAddrInEntry;
UINT64 PhysicalAddrInAttr;
+ IA32_PAGING_ENTRY OriginalParentPagingEntry;
+ IA32_PAGING_ENTRY OriginalCurrentPagingEntry;
ASSERT (Level != 0);
ASSERT ((Attribute != NULL) && (Mask != NULL));
@@ -333,6 +337,8 @@ PageTableLibMapInLevel (
LocalParentAttribute.Uint64 = ParentAttribute->Uint64;
ParentAttribute = &LocalParentAttribute;
+ OriginalParentPagingEntry.Uint64 = ParentPagingEntry->Uint64;
+
//
// RegionLength: 256T (1 << 48) 512G (1 << 39), 1G (1 << 30), 2M (1 << 21) or 4K (1 << 12).
//
@@ -568,7 +574,15 @@ PageTableLibMapInLevel (
ASSERT (CreateNew || (Mask->Bits.Nx == 0) || (Attribute->Bits.Nx == 1));
}
+ //
+ // Check if any leaf PagingEntry is modified.
+ //
+ OriginalCurrentPagingEntry.Uint64 = CurrentPagingEntry->Uint64;
PageTableLibSetPle (Level, CurrentPagingEntry, Offset, Attribute, &CurrentMask);
+
+ if (OriginalCurrentPagingEntry.Uint64 != CurrentPagingEntry->Uint64) {
+ *IsModified = TRUE;
+ }
}
} else {
//
@@ -591,7 +605,8 @@ PageTableLibMapInLevel (
Length,
Offset,
Attribute,
- Mask
+ Mask,
+ IsModified
);
if (RETURN_ERROR (Status)) {
return Status;
@@ -603,6 +618,14 @@ PageTableLibMapInLevel (
Index++;
}
+ //
+ // Check if ParentPagingEntry entry is modified here is enough. Except the changes happen in leaf PagingEntry during
+ // the while loop, if there is any other change happens in page table, the ParentPagingEntry must has been modified.
+ //
+ if (OriginalParentPagingEntry.Uint64 != ParentPagingEntry->Uint64) {
+ *IsModified = TRUE;
+ }
+
return RETURN_SUCCESS;
}
@@ -623,6 +646,7 @@ PageTableLibMapInLevel (
Page table entries that map the linear address range are reset to 0 before set to the new attribute
when a new physical base address is set.
@param[in] Mask The mask used for attribute. The corresponding field in Attribute is ignored if that in Mask is 0.
+ @param[out] IsModified TRUE means page table is modified. FALSE means page table is not modified.
@retval RETURN_UNSUPPORTED PagingMode is not supported.
@retval RETURN_INVALID_PARAMETER PageTable, BufferSize, Attribute or Mask is NULL.
@@ -646,7 +670,8 @@ PageTableMap (
IN UINT64 LinearAddress,
IN UINT64 Length,
IN IA32_MAP_ATTRIBUTE *Attribute,
- IN IA32_MAP_ATTRIBUTE *Mask
+ IN IA32_MAP_ATTRIBUTE *Mask,
+ OUT BOOLEAN *IsModified OPTIONAL
)
{
RETURN_STATUS Status;
@@ -656,6 +681,7 @@ PageTableMap (
IA32_PAGE_LEVEL MaxLevel;
IA32_PAGE_LEVEL MaxLeafLevel;
IA32_MAP_ATTRIBUTE ParentAttribute;
+ BOOLEAN LocalIsModified;
if (Length == 0) {
return RETURN_SUCCESS;
@@ -718,6 +744,12 @@ PageTableMap (
TopPagingEntry.Pce.Nx = 0;
}
+ if (IsModified == NULL) {
+ IsModified = &LocalIsModified;
+ }
+
+ *IsModified = FALSE;
+
ParentAttribute.Uint64 = 0;
ParentAttribute.Bits.PageTableBaseAddress = 1;
ParentAttribute.Bits.Present = 1;
@@ -741,8 +773,10 @@ PageTableMap (
Length,
0,
Attribute,
- Mask
+ Mask,
+ IsModified
);
+ ASSERT (*IsModified == FALSE);
if (RETURN_ERROR (Status)) {
return Status;
}
@@ -773,8 +807,10 @@ PageTableMap (
Length,
0,
Attribute,
- Mask
+ Mask,
+ IsModified
);
+
if (!RETURN_ERROR (Status)) {
*PageTable = (UINTN)(TopPagingEntry.Uintn & IA32_PE_BASE_ADDRESS_MASK_40);
}