summaryrefslogtreecommitdiffstats
path: root/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c
diff options
context:
space:
mode:
authorDun Tan <dun.tan@intel.com>2022-12-09 10:36:37 +0800
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2023-03-27 08:21:58 +0000
commitc8c6cf149d07e2749ce7a17c084ab658af2e9cdd (patch)
tree068d81b9e0d3e8edcd16221281275d95e91461fa /UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c
parent3b2661d247eb58bfad30662da434f73382d3e873 (diff)
downloadedk2-c8c6cf149d07e2749ce7a17c084ab658af2e9cdd.tar.gz
edk2-c8c6cf149d07e2749ce7a17c084ab658af2e9cdd.tar.bz2
edk2-c8c6cf149d07e2749ce7a17c084ab658af2e9cdd.zip
UefiCpuPkg/CpuPageTableLib: Add OUTPUT IsModified parameter.
Add OUTPUT IsModified parameter in PageTableMap() to indicate if page table has been modified. With this parameter, caller can know if need to call FlushTlb when the page table is in CR3. Signed-off-by: Dun Tan <dun.tan@intel.com> Cc: Eric Dong <eric.dong@intel.com> Reviewed-by: Ray Ni <ray.ni@intel.com> Cc: Rahul Kumar <rahul1.kumar@intel.com> Tested-by: Gerd Hoffmann <kraxel@redhat.com> Acked-by: Gerd Hoffmann <kraxel@redhat.com>
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);
}