Reviewed-by: Ray Ni <ray...@intel.com> > -----Original Message----- > From: Tan, Dun <dun....@intel.com> > Sent: Thursday, June 8, 2023 10:28 AM > To: devel@edk2.groups.io > Cc: Dong, Eric <eric.d...@intel.com>; Ni, Ray <ray...@intel.com>; Kumar, > Rahul R <rahul.r.ku...@intel.com>; Gerd Hoffmann <kra...@redhat.com> > Subject: [Patch V5 03/14] UefiCpuPkg: Use CpuPageTableLib to convert SMM > paging attribute. > > Simplify the ConvertMemoryPageAttributes API to convert paging > attribute by CpuPageTableLib. In the new API, it calls > PageTableMap() to update the page attributes of a memory range. > With the PageTableMap() API in CpuPageTableLib, we can remove > the complicated page table manipulating code. > > Signed-off-by: Dun Tan <dun....@intel.com> > Cc: Eric Dong <eric.d...@intel.com> > Cc: Ray Ni <ray...@intel.com> > Cc: Rahul Kumar <rahul1.ku...@intel.com> > Cc: Gerd Hoffmann <kra...@redhat.com> > --- > UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c | 3 ++- > UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h | 28 > +++++++++++++--------------- > UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf | 1 + > UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c | 409 > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++++++++++++--------------------------- > ---------------------------------------------------------------------------------------------- > ---------------------------------------------------------------------------------------------- > ---------------------------------------------------------------------------------------------- > UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c | 7 ++++++- > 5 files changed, 122 insertions(+), 326 deletions(-) > > diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c > b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c > index 34bf6e1a25..9c8107080a 100644 > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c > @@ -1,7 +1,7 @@ > /** @file > Page table manipulation functions for IA-32 processors > > -Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR> > +Copyright (c) 2009 - 2023, Intel Corporation. All rights reserved.<BR> > Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR> > > SPDX-License-Identifier: BSD-2-Clause-Patent > @@ -31,6 +31,7 @@ SmmInitPageTable ( > InitializeSpinLock (mPFLock); > > mPhysicalAddressBits = 32; > + mPagingMode = PagingPae; > > if (FeaturePcdGet (PcdCpuSmmProfileEnable) || > HEAP_GUARD_NONSTOP_MODE || > diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h > b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h > index a5c2bdd971..ba341cadc6 100644 > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h > @@ -50,6 +50,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent > #include <Library/SmmCpuFeaturesLib.h> > #include <Library/PeCoffGetEntryPointLib.h> > #include <Library/RegisterCpuFeaturesLib.h> > +#include <Library/CpuPageTableLib.h> > > #include <AcpiCpuData.h> > #include <CpuHotPlugData.h> > @@ -260,6 +261,7 @@ extern UINTN mNumberOfCpus; > extern EFI_SMM_CPU_PROTOCOL mSmmCpu; > extern EFI_MM_MP_PROTOCOL mSmmMp; > extern BOOLEAN m5LevelPagingNeeded; > +extern PAGING_MODE mPagingMode; > > /// > /// The mode of the CPU at the time an SMI occurs > @@ -1008,11 +1010,10 @@ SetPageTableAttributes ( > Length from their current attributes to the attributes specified by > Attributes. > > @param[in] PageTableBase The page table base. > - @param[in] EnablePML5Paging If PML5 paging is enabled. > + @param[in] PagingMode The paging mode. > @param[in] BaseAddress The physical address that is the start > address of > a memory region. > @param[in] Length The size in bytes of the memory region. > @param[in] Attributes The bit mask of attributes to set for the > memory > region. > - @param[out] IsSplitted TRUE means page table splitted. FALSE means > page table not splitted. > > @retval EFI_SUCCESS The attributes were set for the memory > region. > @retval EFI_ACCESS_DENIED The attributes for the memory resource > range specified by > @@ -1030,12 +1031,11 @@ SetPageTableAttributes ( > **/ > EFI_STATUS > SmmSetMemoryAttributesEx ( > - IN UINTN PageTableBase, > - IN BOOLEAN EnablePML5Paging, > - IN EFI_PHYSICAL_ADDRESS BaseAddress, > - IN UINT64 Length, > - IN UINT64 Attributes, > - OUT BOOLEAN *IsSplitted OPTIONAL > + IN UINTN PageTableBase, > + IN PAGING_MODE PagingMode, > + IN PHYSICAL_ADDRESS BaseAddress, > + IN UINT64 Length, > + IN UINT64 Attributes > ); > > /** > @@ -1043,34 +1043,32 @@ SmmSetMemoryAttributesEx ( > Length from their current attributes to the attributes specified by > Attributes. > > @param[in] PageTableBase The page table base. > - @param[in] EnablePML5Paging If PML5 paging is enabled. > + @param[in] PagingMode The paging mode. > @param[in] BaseAddress The physical address that is the start > address of > a memory region. > @param[in] Length The size in bytes of the memory region. > @param[in] Attributes The bit mask of attributes to clear for the > memory > region. > - @param[out] IsSplitted TRUE means page table splitted. FALSE means > page table not splitted. > > @retval EFI_SUCCESS The attributes were cleared for the memory > region. > @retval EFI_ACCESS_DENIED The attributes for the memory resource > range specified by > BaseAddress and Length cannot be modified. > @retval EFI_INVALID_PARAMETER Length is zero. > Attributes specified an illegal combination > of attributes that > - cannot be set together. > + cannot be cleared together. > @retval EFI_OUT_OF_RESOURCES There are not enough system resources > to modify the attributes of > the memory resource range. > @retval EFI_UNSUPPORTED The processor does not support one or more > bytes of the memory > resource range specified by BaseAddress and > Length. > - The bit mask of attributes is not support > for the memory > resource > + The bit mask of attributes is not supported > for the memory > resource > range specified by BaseAddress and Length. > > **/ > EFI_STATUS > SmmClearMemoryAttributesEx ( > IN UINTN PageTableBase, > - IN BOOLEAN EnablePML5Paging, > + IN PAGING_MODE PagingMode, > IN EFI_PHYSICAL_ADDRESS BaseAddress, > IN UINT64 Length, > - IN UINT64 Attributes, > - OUT BOOLEAN *IsSplitted OPTIONAL > + IN UINT64 Attributes > ); > > /** > diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf > b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf > index 158e05e264..38d4e950a4 100644 > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf > @@ -97,6 +97,7 @@ > ReportStatusCodeLib > SmmCpuFeaturesLib > PeCoffGetEntryPointLib > + CpuPageTableLib > > [Protocols] > gEfiSmmAccess2ProtocolGuid ## CONSUMES > diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c > b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c > index 834a756061..12723e5750 100644 > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c > @@ -1,6 +1,6 @@ > /** @file > > -Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.<BR> > +Copyright (c) 2016 - 2023, Intel Corporation. All rights reserved.<BR> > SPDX-License-Identifier: BSD-2-Clause-Patent > > **/ > @@ -26,14 +26,9 @@ UINTN mGcdMemNumberOfDesc = 0; > > EFI_MEMORY_ATTRIBUTES_TABLE *mUefiMemoryAttributesTable = NULL; > > -PAGE_ATTRIBUTE_TABLE mPageAttributeTable[] = { > - { Page4K, SIZE_4KB, PAGING_4K_ADDRESS_MASK_64 }, > - { Page2M, SIZE_2MB, PAGING_2M_ADDRESS_MASK_64 }, > - { Page1G, SIZE_1GB, PAGING_1G_ADDRESS_MASK_64 }, > -}; > - > -BOOLEAN mIsShadowStack = FALSE; > -BOOLEAN m5LevelPagingNeeded = FALSE; > +BOOLEAN mIsShadowStack = FALSE; > +BOOLEAN m5LevelPagingNeeded = FALSE; > +PAGING_MODE mPagingMode = PagingModeMax; > > // > // Global variable to keep track current available memory used as page table. > @@ -185,52 +180,6 @@ AllocatePageTableMemory ( > return Buffer; > } > > -/** > - Return length according to page attributes. > - > - @param[in] PageAttributes The page attribute of the page entry. > - > - @return The length of page entry. > -**/ > -UINTN > -PageAttributeToLength ( > - IN PAGE_ATTRIBUTE PageAttribute > - ) > -{ > - UINTN Index; > - > - for (Index = 0; Index < sizeof (mPageAttributeTable)/sizeof > (mPageAttributeTable[0]); Index++) { > - if (PageAttribute == mPageAttributeTable[Index].Attribute) { > - return (UINTN)mPageAttributeTable[Index].Length; > - } > - } > - > - return 0; > -} > - > -/** > - Return address mask according to page attributes. > - > - @param[in] PageAttributes The page attribute of the page entry. > - > - @return The address mask of page entry. > -**/ > -UINTN > -PageAttributeToMask ( > - IN PAGE_ATTRIBUTE PageAttribute > - ) > -{ > - UINTN Index; > - > - for (Index = 0; Index < sizeof (mPageAttributeTable)/sizeof > (mPageAttributeTable[0]); Index++) { > - if (PageAttribute == mPageAttributeTable[Index].Attribute) { > - return (UINTN)mPageAttributeTable[Index].AddressMask; > - } > - } > - > - return 0; > -} > - > /** > Return page table entry to match the address. > > @@ -353,181 +302,6 @@ GetAttributesFromPageEntry ( > return Attributes; > } > > -/** > - Modify memory attributes of page entry. > - > - @param[in] PageEntry The page entry. > - @param[in] Attributes The bit mask of attributes to modify for the > memory region. > - @param[in] IsSet TRUE means to set attributes. FALSE means to > clear > attributes. > - @param[out] IsModified TRUE means page table modified. FALSE means > page table not modified. > -**/ > -VOID > -ConvertPageEntryAttribute ( > - IN UINT64 *PageEntry, > - IN UINT64 Attributes, > - IN BOOLEAN IsSet, > - OUT BOOLEAN *IsModified > - ) > -{ > - UINT64 CurrentPageEntry; > - UINT64 NewPageEntry; > - > - CurrentPageEntry = *PageEntry; > - NewPageEntry = CurrentPageEntry; > - if ((Attributes & EFI_MEMORY_RP) != 0) { > - if (IsSet) { > - NewPageEntry &= ~(UINT64)IA32_PG_P; > - } else { > - NewPageEntry |= IA32_PG_P; > - } > - } > - > - if ((Attributes & EFI_MEMORY_RO) != 0) { > - if (IsSet) { > - NewPageEntry &= ~(UINT64)IA32_PG_RW; > - if (mIsShadowStack) { > - // Environment setup > - // ReadOnly page need set Dirty bit for shadow stack > - NewPageEntry |= IA32_PG_D; > - // Clear user bit for supervisor shadow stack > - NewPageEntry &= ~(UINT64)IA32_PG_U; > - } else { > - // Runtime update > - // Clear dirty bit for non shadow stack, to protect RO page. > - NewPageEntry &= ~(UINT64)IA32_PG_D; > - } > - } else { > - NewPageEntry |= IA32_PG_RW; > - } > - } > - > - if ((Attributes & EFI_MEMORY_XP) != 0) { > - if (mXdSupported) { > - if (IsSet) { > - NewPageEntry |= IA32_PG_NX; > - } else { > - NewPageEntry &= ~IA32_PG_NX; > - } > - } > - } > - > - *PageEntry = NewPageEntry; > - if (CurrentPageEntry != NewPageEntry) { > - *IsModified = TRUE; > - DEBUG ((DEBUG_VERBOSE, "ConvertPageEntryAttribute 0x%lx", > CurrentPageEntry)); > - DEBUG ((DEBUG_VERBOSE, "->0x%lx\n", NewPageEntry)); > - } else { > - *IsModified = FALSE; > - } > -} > - > -/** > - This function returns if there is need to split page entry. > - > - @param[in] BaseAddress The base address to be checked. > - @param[in] Length The length to be checked. > - @param[in] PageEntry The page entry to be checked. > - @param[in] PageAttribute The page attribute of the page entry. > - > - @retval SplitAttributes on if there is need to split page entry. > -**/ > -PAGE_ATTRIBUTE > -NeedSplitPage ( > - IN PHYSICAL_ADDRESS BaseAddress, > - IN UINT64 Length, > - IN UINT64 *PageEntry, > - IN PAGE_ATTRIBUTE PageAttribute > - ) > -{ > - UINT64 PageEntryLength; > - > - PageEntryLength = PageAttributeToLength (PageAttribute); > - > - if (((BaseAddress & (PageEntryLength - 1)) == 0) && (Length >= > PageEntryLength)) { > - return PageNone; > - } > - > - if (((BaseAddress & PAGING_2M_MASK) != 0) || (Length < SIZE_2MB)) { > - return Page4K; > - } > - > - return Page2M; > -} > - > -/** > - This function splits one page entry to small page entries. > - > - @param[in] PageEntry The page entry to be splitted. > - @param[in] PageAttribute The page attribute of the page entry. > - @param[in] SplitAttribute How to split the page entry. > - > - @retval RETURN_SUCCESS The page entry is splitted. > - @retval RETURN_UNSUPPORTED The page entry does not support to be > splitted. > - @retval RETURN_OUT_OF_RESOURCES No resource to split page entry. > -**/ > -RETURN_STATUS > -SplitPage ( > - IN UINT64 *PageEntry, > - IN PAGE_ATTRIBUTE PageAttribute, > - IN PAGE_ATTRIBUTE SplitAttribute > - ) > -{ > - UINT64 BaseAddress; > - UINT64 *NewPageEntry; > - UINTN Index; > - > - ASSERT (PageAttribute == Page2M || PageAttribute == Page1G); > - > - if (PageAttribute == Page2M) { > - // > - // Split 2M to 4K > - // > - ASSERT (SplitAttribute == Page4K); > - if (SplitAttribute == Page4K) { > - NewPageEntry = AllocatePageTableMemory (1); > - DEBUG ((DEBUG_VERBOSE, "Split - 0x%x\n", NewPageEntry)); > - if (NewPageEntry == NULL) { > - return RETURN_OUT_OF_RESOURCES; > - } > - > - BaseAddress = *PageEntry & PAGING_2M_ADDRESS_MASK_64; > - for (Index = 0; Index < SIZE_4KB / sizeof (UINT64); Index++) { > - NewPageEntry[Index] = (BaseAddress + SIZE_4KB * Index) | > mAddressEncMask | ((*PageEntry) & PAGE_PROGATE_BITS); > - } > - > - (*PageEntry) = (UINT64)(UINTN)NewPageEntry | mAddressEncMask | > PAGE_ATTRIBUTE_BITS; > - return RETURN_SUCCESS; > - } else { > - return RETURN_UNSUPPORTED; > - } > - } else if (PageAttribute == Page1G) { > - // > - // Split 1G to 2M > - // No need support 1G->4K directly, we should use 1G->2M, then 2M->4K > to get more compact page table. > - // > - ASSERT (SplitAttribute == Page2M || SplitAttribute == Page4K); > - if (((SplitAttribute == Page2M) || (SplitAttribute == Page4K))) { > - NewPageEntry = AllocatePageTableMemory (1); > - DEBUG ((DEBUG_VERBOSE, "Split - 0x%x\n", NewPageEntry)); > - if (NewPageEntry == NULL) { > - return RETURN_OUT_OF_RESOURCES; > - } > - > - BaseAddress = *PageEntry & PAGING_1G_ADDRESS_MASK_64; > - for (Index = 0; Index < SIZE_4KB / sizeof (UINT64); Index++) { > - NewPageEntry[Index] = (BaseAddress + SIZE_2MB * Index) | > mAddressEncMask | IA32_PG_PS | ((*PageEntry) & PAGE_PROGATE_BITS); > - } > - > - (*PageEntry) = (UINT64)(UINTN)NewPageEntry | mAddressEncMask | > PAGE_ATTRIBUTE_BITS; > - return RETURN_SUCCESS; > - } else { > - return RETURN_UNSUPPORTED; > - } > - } else { > - return RETURN_UNSUPPORTED; > - } > -} > - > /** > This function modifies the page attributes for the memory region specified > by BaseAddress and > Length from their current attributes to the attributes specified by > Attributes. > @@ -535,12 +309,11 @@ SplitPage ( > Caller should make sure BaseAddress and Length is at page boundary. > > @param[in] PageTableBase The page table base. > - @param[in] EnablePML5Paging If PML5 paging is enabled. > + @param[in] PagingMode The paging mode. > @param[in] BaseAddress The physical address that is the start > address of > a memory region. > @param[in] Length The size in bytes of the memory region. > @param[in] Attributes The bit mask of attributes to modify for the > memory region. > @param[in] IsSet TRUE means to set attributes. FALSE means to > clear > attributes. > - @param[out] IsSplitted TRUE means page table splitted. FALSE means > page table not splitted. > @param[out] IsModified TRUE means page table modified. FALSE means > page table not modified. > > @retval RETURN_SUCCESS The attributes were modified for the > memory region. > @@ -559,28 +332,30 @@ SplitPage ( > RETURN_STATUS > ConvertMemoryPageAttributes ( > IN UINTN PageTableBase, > - IN BOOLEAN EnablePML5Paging, > + IN PAGING_MODE PagingMode, > IN PHYSICAL_ADDRESS BaseAddress, > IN UINT64 Length, > IN UINT64 Attributes, > IN BOOLEAN IsSet, > - OUT BOOLEAN *IsSplitted OPTIONAL, > OUT BOOLEAN *IsModified OPTIONAL > ) > { > - UINT64 *PageEntry; > - PAGE_ATTRIBUTE PageAttribute; > - UINTN PageEntryLength; > - PAGE_ATTRIBUTE SplitAttribute; > RETURN_STATUS Status; > - BOOLEAN IsEntryModified; > + IA32_MAP_ATTRIBUTE PagingAttribute; > + IA32_MAP_ATTRIBUTE PagingAttrMask; > + UINTN PageTableBufferSize; > + VOID *PageTableBuffer; > EFI_PHYSICAL_ADDRESS MaximumSupportMemAddress; > + IA32_MAP_ENTRY *Map; > + UINTN Count; > + UINTN Index; > > ASSERT (Attributes != 0); > ASSERT ((Attributes & ~EFI_MEMORY_ATTRIBUTE_MASK) == 0); > > ASSERT ((BaseAddress & (SIZE_4KB - 1)) == 0); > ASSERT ((Length & (SIZE_4KB - 1)) == 0); > + ASSERT (PageTableBase != 0); > > if (Length == 0) { > return RETURN_INVALID_PARAMETER; > @@ -599,61 +374,89 @@ ConvertMemoryPageAttributes ( > return RETURN_UNSUPPORTED; > } > > - // DEBUG ((DEBUG_ERROR, "ConvertMemoryPageAttributes(%x) - > %016lx, %016lx, %02lx\n", IsSet, BaseAddress, Length, Attributes)); > - > - if (IsSplitted != NULL) { > - *IsSplitted = FALSE; > - } > - > if (IsModified != NULL) { > *IsModified = FALSE; > } > > - // > - // Below logic is to check 2M/4K page to make sure we do not waste > memory. > - // > - while (Length != 0) { > - PageEntry = GetPageTableEntry (PageTableBase, EnablePML5Paging, > BaseAddress, &PageAttribute); > - if (PageEntry == NULL) { > - return RETURN_UNSUPPORTED; > - } > + PagingAttribute.Uint64 = 0; > + PagingAttribute.Uint64 = mAddressEncMask | BaseAddress; > + PagingAttrMask.Uint64 = 0; > > - PageEntryLength = PageAttributeToLength (PageAttribute); > - SplitAttribute = NeedSplitPage (BaseAddress, Length, PageEntry, > PageAttribute); > - if (SplitAttribute == PageNone) { > - ConvertPageEntryAttribute (PageEntry, Attributes, IsSet, > &IsEntryModified); > - if (IsEntryModified) { > - if (IsModified != NULL) { > - *IsModified = TRUE; > - } > + if ((Attributes & EFI_MEMORY_RO) != 0) { > + PagingAttrMask.Bits.ReadWrite = 1; > + if (IsSet) { > + PagingAttribute.Bits.ReadWrite = 0; > + PagingAttrMask.Bits.Dirty = 1; > + if (mIsShadowStack) { > + // Environment setup > + // ReadOnly page need set Dirty bit for shadow stack > + PagingAttribute.Bits.Dirty = 1; > + // Clear user bit for supervisor shadow stack > + PagingAttribute.Bits.UserSupervisor = 0; > + PagingAttrMask.Bits.UserSupervisor = 1; > + } else { > + // Runtime update > + // Clear dirty bit for non shadow stack, to protect RO page. > + PagingAttribute.Bits.Dirty = 0; > } > + } else { > + PagingAttribute.Bits.ReadWrite = 1; > + } > + } > > + if ((Attributes & EFI_MEMORY_XP) != 0) { > + if (mXdSupported) { > + PagingAttribute.Bits.Nx = IsSet ? 1 : 0; > + PagingAttrMask.Bits.Nx = 1; > + } > + } > + > + if ((Attributes & EFI_MEMORY_RP) != 0) { > + if (IsSet) { > + PagingAttribute.Bits.Present = 0; > // > - // Convert success, move to next > + // When map a range to non-present, all attributes except Present > should > not be provided. > // > - BaseAddress += PageEntryLength; > - Length -= PageEntryLength; > + PagingAttrMask.Uint64 = 0; > + PagingAttrMask.Bits.Present = 1; > } else { > - Status = SplitPage (PageEntry, PageAttribute, SplitAttribute); > - if (RETURN_ERROR (Status)) { > - return RETURN_UNSUPPORTED; > - } > - > - if (IsSplitted != NULL) { > - *IsSplitted = TRUE; > - } > - > - if (IsModified != NULL) { > - *IsModified = TRUE; > - } > + // > + // When map range to present range, provide all attributes. > + // > + PagingAttribute.Bits.Present = 1; > + PagingAttrMask.Uint64 = MAX_UINT64; > > // > - // Just split current page > - // Convert success in next around > + // By default memory is Ring 3 accessble. > // > + PagingAttribute.Bits.UserSupervisor = 1; > } > } > > + if (PagingAttrMask.Uint64 == 0) { > + return RETURN_SUCCESS; > + } > + > + PageTableBufferSize = 0; > + Status = PageTableMap (&PageTableBase, PagingMode, NULL, > &PageTableBufferSize, BaseAddress, Length, &PagingAttribute, > &PagingAttrMask, IsModified); > + > + if (Status == RETURN_BUFFER_TOO_SMALL) { > + PageTableBuffer = AllocatePageTableMemory (EFI_SIZE_TO_PAGES > (PageTableBufferSize)); > + ASSERT (PageTableBuffer != NULL); > + Status = PageTableMap (&PageTableBase, PagingMode, PageTableBuffer, > &PageTableBufferSize, BaseAddress, Length, &PagingAttribute, > &PagingAttrMask, IsModified); > + } > + > + if (Status == RETURN_INVALID_PARAMETER) { > + // > + // The only reason that PageTableMap returns > RETURN_INVALID_PARAMETER here is to modify other attributes > + // of a non-present range but remains the non-present range still as non- > present. > + // > + DEBUG ((DEBUG_ERROR, "SMM ConvertMemoryPageAttributes: Only > change EFI_MEMORY_XP/EFI_MEMORY_RO for non-present range in [0x%lx, > 0x%lx] is not permitted\n", BaseAddress, BaseAddress + Length)); > + } > + > + ASSERT_RETURN_ERROR (Status); > + ASSERT (PageTableBufferSize == 0); > + > return RETURN_SUCCESS; > } > > @@ -697,11 +500,10 @@ FlushTlbForAll ( > Length from their current attributes to the attributes specified by > Attributes. > > @param[in] PageTableBase The page table base. > - @param[in] EnablePML5Paging If PML5 paging is enabled. > + @param[in] PagingMode The paging mode. > @param[in] BaseAddress The physical address that is the start > address of > a memory region. > @param[in] Length The size in bytes of the memory region. > @param[in] Attributes The bit mask of attributes to set for the > memory > region. > - @param[out] IsSplitted TRUE means page table splitted. FALSE means > page table not splitted. > > @retval EFI_SUCCESS The attributes were set for the memory > region. > @retval EFI_ACCESS_DENIED The attributes for the memory resource > range specified by > @@ -720,17 +522,16 @@ FlushTlbForAll ( > EFI_STATUS > SmmSetMemoryAttributesEx ( > IN UINTN PageTableBase, > - IN BOOLEAN EnablePML5Paging, > + IN PAGING_MODE PagingMode, > IN EFI_PHYSICAL_ADDRESS BaseAddress, > IN UINT64 Length, > - IN UINT64 Attributes, > - OUT BOOLEAN *IsSplitted OPTIONAL > + IN UINT64 Attributes > ) > { > EFI_STATUS Status; > BOOLEAN IsModified; > > - Status = ConvertMemoryPageAttributes (PageTableBase, EnablePML5Paging, > BaseAddress, Length, Attributes, TRUE, IsSplitted, &IsModified); > + Status = ConvertMemoryPageAttributes (PageTableBase, PagingMode, > BaseAddress, Length, Attributes, TRUE, &IsModified); > if (!EFI_ERROR (Status)) { > if (IsModified) { > // > @@ -748,11 +549,10 @@ SmmSetMemoryAttributesEx ( > Length from their current attributes to the attributes specified by > Attributes. > > @param[in] PageTableBase The page table base. > - @param[in] EnablePML5Paging If PML5 paging is enabled. > + @param[in] PagingMode The paging mode. > @param[in] BaseAddress The physical address that is the start > address of > a memory region. > @param[in] Length The size in bytes of the memory region. > @param[in] Attributes The bit mask of attributes to clear for the > memory > region. > - @param[out] IsSplitted TRUE means page table splitted. FALSE means > page table not splitted. > > @retval EFI_SUCCESS The attributes were cleared for the memory > region. > @retval EFI_ACCESS_DENIED The attributes for the memory resource > range specified by > @@ -771,17 +571,16 @@ SmmSetMemoryAttributesEx ( > EFI_STATUS > SmmClearMemoryAttributesEx ( > IN UINTN PageTableBase, > - IN BOOLEAN EnablePML5Paging, > + IN PAGING_MODE PagingMode, > IN EFI_PHYSICAL_ADDRESS BaseAddress, > IN UINT64 Length, > - IN UINT64 Attributes, > - OUT BOOLEAN *IsSplitted OPTIONAL > + IN UINT64 Attributes > ) > { > EFI_STATUS Status; > BOOLEAN IsModified; > > - Status = ConvertMemoryPageAttributes (PageTableBase, EnablePML5Paging, > BaseAddress, Length, Attributes, FALSE, IsSplitted, &IsModified); > + Status = ConvertMemoryPageAttributes (PageTableBase, PagingMode, > BaseAddress, Length, Attributes, FALSE, &IsModified); > if (!EFI_ERROR (Status)) { > if (IsModified) { > // > @@ -823,14 +622,10 @@ SmmSetMemoryAttributes ( > IN UINT64 Attributes > ) > { > - IA32_CR4 Cr4; > - UINTN PageTableBase; > - BOOLEAN Enable5LevelPaging; > - > - PageTableBase = AsmReadCr3 () & PAGING_4K_ADDRESS_MASK_64; > - Cr4.UintN = AsmReadCr4 (); > - Enable5LevelPaging = (BOOLEAN)(Cr4.Bits.LA57 == 1); > - return SmmSetMemoryAttributesEx (PageTableBase, Enable5LevelPaging, > BaseAddress, Length, Attributes, NULL); > + UINTN PageTableBase; > + > + PageTableBase = AsmReadCr3 () & PAGING_4K_ADDRESS_MASK_64; > + return SmmSetMemoryAttributesEx (PageTableBase, mPagingMode, > BaseAddress, Length, Attributes); > } > > /** > @@ -862,14 +657,10 @@ SmmClearMemoryAttributes ( > IN UINT64 Attributes > ) > { > - IA32_CR4 Cr4; > - UINTN PageTableBase; > - BOOLEAN Enable5LevelPaging; > - > - PageTableBase = AsmReadCr3 () & PAGING_4K_ADDRESS_MASK_64; > - Cr4.UintN = AsmReadCr4 (); > - Enable5LevelPaging = (BOOLEAN)(Cr4.Bits.LA57 == 1); > - return SmmClearMemoryAttributesEx (PageTableBase, Enable5LevelPaging, > BaseAddress, Length, Attributes, NULL); > + UINTN PageTableBase; > + > + PageTableBase = AsmReadCr3 () & PAGING_4K_ADDRESS_MASK_64; > + return SmmClearMemoryAttributesEx (PageTableBase, mPagingMode, > BaseAddress, Length, Attributes); > } > > /** > @@ -891,7 +682,7 @@ SetShadowStack ( > EFI_STATUS Status; > > mIsShadowStack = TRUE; > - Status = SmmSetMemoryAttributesEx (Cr3, m5LevelPagingNeeded, > BaseAddress, Length, EFI_MEMORY_RO, NULL); > + Status = SmmSetMemoryAttributesEx (Cr3, mPagingMode, > BaseAddress, Length, EFI_MEMORY_RO); > mIsShadowStack = FALSE; > > return Status; > @@ -915,7 +706,7 @@ SetNotPresentPage ( > { > EFI_STATUS Status; > > - Status = SmmSetMemoryAttributesEx (Cr3, m5LevelPagingNeeded, > BaseAddress, Length, EFI_MEMORY_RP, NULL); > + Status = SmmSetMemoryAttributesEx (Cr3, mPagingMode, BaseAddress, > Length, EFI_MEMORY_RP); > return Status; > } > > @@ -1799,7 +1590,7 @@ EnablePageTableProtection ( > // > // Set entire pool including header, used-memory and left free-memory as > ReadOnly in SMM page table. > // > - ConvertMemoryPageAttributes (PageTableBase, m5LevelPagingNeeded, > Address, PoolSize, EFI_MEMORY_RO, TRUE, NULL, NULL); > + ConvertMemoryPageAttributes (PageTableBase, mPagingMode, Address, > PoolSize, EFI_MEMORY_RO, TRUE, NULL); > Pool = Pool->NextPool; > } while (Pool != HeadPool); > } > diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c > b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c > index 3deb1ffd67..0bed857cae 100644 > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c > @@ -1,7 +1,7 @@ > /** @file > Page Fault (#PF) handler for X64 processors > > -Copyright (c) 2009 - 2022, Intel Corporation. All rights reserved.<BR> > +Copyright (c) 2009 - 2023, Intel Corporation. All rights reserved.<BR> > Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR> > > SPDX-License-Identifier: BSD-2-Clause-Patent > @@ -354,6 +354,11 @@ SmmInitPageTable ( > m5LevelPagingNeeded = Is5LevelPagingNeeded (); > mPhysicalAddressBits = CalculateMaximumSupportAddress (); > PatchInstructionX86 (gPatch5LevelPagingNeeded, m5LevelPagingNeeded, > 1); > + if (m5LevelPagingNeeded) { > + mPagingMode = m1GPageTableSupport ? Paging5Level1GB : Paging5Level; > + } else { > + mPagingMode = m1GPageTableSupport ? Paging4Level1GB : Paging4Level; > + } > DEBUG ((DEBUG_INFO, "5LevelPaging Needed - %d\n", > m5LevelPagingNeeded)); > DEBUG ((DEBUG_INFO, "1GPageTable Support - %d\n", > m1GPageTableSupport)); > DEBUG ((DEBUG_INFO, "PcdCpuSmmRestrictedMemoryAccess - %d\n", > mCpuSmmRestrictedMemoryAccess)); > -- > 2.31.1.windows.1
-=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#105927): https://edk2.groups.io/g/devel/message/105927 Mute This Topic: https://groups.io/mt/99399227/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/leave/9847357/21656/1706620634/xyzzy [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-