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
|
VOID
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
mSmmS3ResumeState->SmmS3Cr3 = Gen4GPageTable (TRUE);
|
mSmmS3ResumeState->SmmS3Cr3 = GenSmmPageTable (PagingPae, mPhysicalAddressBits);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1014,136 +1014,6 @@ APHandler (
|
||||||
ReleaseSemaphore (mSmmMpSyncData->CpuData[BspIndex].Run);
|
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.
|
Checks whether the input token is the current used token.
|
||||||
|
|
||||||
|
|
|
@ -35,26 +35,14 @@ InitSmmS3Cr3 (
|
||||||
VOID
|
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)
|
// 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue