mirror of https://github.com/acidanthera/audk.git
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:
parent
701b5797b2
commit
b4dde1ae6a
|
@ -18,7 +18,7 @@ InitSmmS3Cr3 (
|
|||
VOID
|
||||
)
|
||||
{
|
||||
mSmmS3ResumeState->SmmS3Cr3 = Gen4GPageTable (TRUE);
|
||||
mSmmS3ResumeState->SmmS3Cr3 = GenSmmPageTable (PagingPae, mPhysicalAddressBits);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue