UefiCpuPkg: Use GenSmmPageTable() to create Smm S3 page table

Use GenSmmPageTable() to create both IA32 and X64 Smm S3
page table.

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>
Cc: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
Dun Tan 2023-05-15 16:10:43 +08:00 committed by Ray Ni
parent 701b5797b2
commit b4dde1ae6a
3 changed files with 6 additions and 148 deletions

View File

@ -18,7 +18,7 @@ InitSmmS3Cr3 (
VOID
)
{
mSmmS3ResumeState->SmmS3Cr3 = Gen4GPageTable (TRUE);
mSmmS3ResumeState->SmmS3Cr3 = GenSmmPageTable (PagingPae, mPhysicalAddressBits);
return;
}

View File

@ -1014,136 +1014,6 @@ APHandler (
ReleaseSemaphore (mSmmMpSyncData->CpuData[BspIndex].Run);
}
/**
Create 4G PageTable in SMRAM.
@param[in] Is32BitPageTable Whether the page table is 32-bit PAE
@return PageTable Address
**/
UINT32
Gen4GPageTable (
IN BOOLEAN Is32BitPageTable
)
{
VOID *PageTable;
UINTN Index;
UINT64 *Pte;
UINTN PagesNeeded;
UINTN Low2MBoundary;
UINTN High2MBoundary;
UINTN Pages;
UINTN GuardPage;
UINT64 *Pdpte;
UINTN PageIndex;
UINTN PageAddress;
Low2MBoundary = 0;
High2MBoundary = 0;
PagesNeeded = 0;
if (FeaturePcdGet (PcdCpuSmmStackGuard)) {
//
// Add one more page for known good stack, then find the lower 2MB aligned address.
//
Low2MBoundary = (mSmmStackArrayBase + EFI_PAGE_SIZE) & ~(SIZE_2MB-1);
//
// Add two more pages for known good stack and stack guard page,
// then find the lower 2MB aligned address.
//
High2MBoundary = (mSmmStackArrayEnd - mSmmStackSize - mSmmShadowStackSize + EFI_PAGE_SIZE * 2) & ~(SIZE_2MB-1);
PagesNeeded = ((High2MBoundary - Low2MBoundary) / SIZE_2MB) + 1;
}
//
// Allocate the page table
//
PageTable = AllocatePageTableMemory (5 + PagesNeeded);
ASSERT (PageTable != NULL);
PageTable = (VOID *)((UINTN)PageTable);
Pte = (UINT64 *)PageTable;
//
// Zero out all page table entries first
//
ZeroMem (Pte, EFI_PAGES_TO_SIZE (1));
//
// Set Page Directory Pointers
//
for (Index = 0; Index < 4; Index++) {
Pte[Index] = ((UINTN)PageTable + EFI_PAGE_SIZE * (Index + 1)) | mAddressEncMask |
(Is32BitPageTable ? IA32_PAE_PDPTE_ATTRIBUTE_BITS : PAGE_ATTRIBUTE_BITS);
}
Pte += EFI_PAGE_SIZE / sizeof (*Pte);
//
// Fill in Page Directory Entries
//
for (Index = 0; Index < EFI_PAGE_SIZE * 4 / sizeof (*Pte); Index++) {
Pte[Index] = (Index << 21) | mAddressEncMask | IA32_PG_PS | PAGE_ATTRIBUTE_BITS;
}
Pdpte = (UINT64 *)PageTable;
if (FeaturePcdGet (PcdCpuSmmStackGuard)) {
Pages = (UINTN)PageTable + EFI_PAGES_TO_SIZE (5);
GuardPage = mSmmStackArrayBase + EFI_PAGE_SIZE;
for (PageIndex = Low2MBoundary; PageIndex <= High2MBoundary; PageIndex += SIZE_2MB) {
Pte = (UINT64 *)(UINTN)(Pdpte[BitFieldRead32 ((UINT32)PageIndex, 30, 31)] & ~mAddressEncMask & ~(EFI_PAGE_SIZE - 1));
Pte[BitFieldRead32 ((UINT32)PageIndex, 21, 29)] = (UINT64)Pages | mAddressEncMask | PAGE_ATTRIBUTE_BITS;
//
// Fill in Page Table Entries
//
Pte = (UINT64 *)Pages;
PageAddress = PageIndex;
for (Index = 0; Index < EFI_PAGE_SIZE / sizeof (*Pte); Index++) {
if (PageAddress == GuardPage) {
//
// Mark the guard page as non-present
//
Pte[Index] = PageAddress | mAddressEncMask;
GuardPage += (mSmmStackSize + mSmmShadowStackSize);
if (GuardPage > mSmmStackArrayEnd) {
GuardPage = 0;
}
} else {
Pte[Index] = PageAddress | mAddressEncMask | PAGE_ATTRIBUTE_BITS;
}
PageAddress += EFI_PAGE_SIZE;
}
Pages += EFI_PAGE_SIZE;
}
}
if ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & BIT1) != 0) {
Pte = (UINT64 *)(UINTN)(Pdpte[0] & ~mAddressEncMask & ~(EFI_PAGE_SIZE - 1));
if ((Pte[0] & IA32_PG_PS) == 0) {
// 4K-page entries are already mapped. Just hide the first one anyway.
Pte = (UINT64 *)(UINTN)(Pte[0] & ~mAddressEncMask & ~(EFI_PAGE_SIZE - 1));
Pte[0] &= ~(UINT64)IA32_PG_P; // Hide page 0
} else {
// Create 4K-page entries
Pages = (UINTN)AllocatePageTableMemory (1);
ASSERT (Pages != 0);
Pte[0] = (UINT64)(Pages | mAddressEncMask | PAGE_ATTRIBUTE_BITS);
Pte = (UINT64 *)Pages;
PageAddress = 0;
Pte[0] = PageAddress | mAddressEncMask; // Hide page 0 but present left
for (Index = 1; Index < EFI_PAGE_SIZE / sizeof (*Pte); Index++) {
PageAddress += EFI_PAGE_SIZE;
Pte[Index] = PageAddress | mAddressEncMask | PAGE_ATTRIBUTE_BITS;
}
}
}
return (UINT32)(UINTN)PageTable;
}
/**
Checks whether the input token is the current used token.

View File

@ -35,26 +35,14 @@ InitSmmS3Cr3 (
VOID
)
{
EFI_PHYSICAL_ADDRESS Pages;
UINT64 *PTEntry;
//
// Generate PAE page table for the first 4GB memory space
//
Pages = Gen4GPageTable (FALSE);
//
// Fill Page-Table-Level4 (PML4) entry
//
PTEntry = (UINT64 *)AllocatePageTableMemory (1);
ASSERT (PTEntry != NULL);
*PTEntry = Pages | mAddressEncMask | PAGE_ATTRIBUTE_BITS;
ZeroMem (PTEntry + 1, EFI_PAGE_SIZE - sizeof (*PTEntry));
//
// Generate level4 page table for the first 4GB memory space
// Return the address of PML4 (to set CR3)
//
mSmmS3ResumeState->SmmS3Cr3 = (UINT32)(UINTN)PTEntry;
//
// The SmmS3Cr3 is only used by S3Resume PEIM to switch CPU from 32bit to 64bit
//
mSmmS3ResumeState->SmmS3Cr3 = (UINT32)GenSmmPageTable (Paging4Level, 32);
return;
}