UefiCpuPkg/PiSmmCpu: Always set RW+P bit for page table by default
So that we can use write-protection for code later. This is REPOST. It includes the bug fix from "Paolo Bonzini" <pbonzini@redhat.com>: Title: fix generation of 32-bit PAE page tables "Bits 1 and 2 are reserved in 32-bit PAE Page Directory Pointer Table Entries (PDPTEs); see Table 4-8 in the SDM. With VMX extended page tables, the processor notices and fails the VM entry as soon as CR0.PG is set to 1." And thanks "Laszlo Ersek" <lersek@redhat.com> to validate the fix. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: "Yao, Jiewen" <jiewen.yao@intel.com> Signed-off-by: "Paolo Bonzini" <pbonzini@redhat.com> Reviewed-by: Michael Kinney <michael.d.kinney@intel.com> Tested-by: Laszlo Ersek <lersek@redhat.com> Cc: "Fan, Jeff" <jeff.fan@intel.com> Cc: "Kinney, Michael D" <michael.d.kinney@intel.com> Cc: "Laszlo Ersek" <lersek@redhat.com> Cc: "Paolo Bonzini" <pbonzini@redhat.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@19067 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
@@ -45,13 +45,13 @@ InitSmmS3Cr3 (
|
||||
//
|
||||
// Generate PAE page table for the first 4GB memory space
|
||||
//
|
||||
Pages = Gen4GPageTable (1);
|
||||
Pages = Gen4GPageTable (1, FALSE);
|
||||
|
||||
//
|
||||
// Fill Page-Table-Level4 (PML4) entry
|
||||
//
|
||||
PTEntry = (UINT64*)(UINTN)(Pages - EFI_PAGES_TO_SIZE (1));
|
||||
*PTEntry = Pages + IA32_PG_P;
|
||||
*PTEntry = Pages | PAGE_ATTRIBUTE_BITS;
|
||||
ZeroMem (PTEntry + 1, EFI_PAGE_SIZE - sizeof (*PTEntry));
|
||||
|
||||
//
|
||||
@@ -117,7 +117,7 @@ AcquirePage (
|
||||
//
|
||||
// Link & Record the current uplink
|
||||
//
|
||||
*Uplink = Address | IA32_PG_P | IA32_PG_RW;
|
||||
*Uplink = Address | PAGE_ATTRIBUTE_BITS;
|
||||
mPFPageUplink[mPFPageIndex] = Uplink;
|
||||
|
||||
mPFPageIndex = (mPFPageIndex + 1) % MAX_PF_PAGE_COUNT;
|
||||
@@ -242,9 +242,9 @@ RestorePageTableAbove4G (
|
||||
// PTE
|
||||
PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & PHYSICAL_ADDRESS_MASK);
|
||||
for (Index = 0; Index < 512; Index++) {
|
||||
PageTable[Index] = Address | IA32_PG_RW | IA32_PG_P;
|
||||
PageTable[Index] = Address | PAGE_ATTRIBUTE_BITS;
|
||||
if (!IsAddressValid (Address, &Nx)) {
|
||||
PageTable[Index] = PageTable[Index] & (INTN)(INT32)(~(IA32_PG_RW | IA32_PG_P));
|
||||
PageTable[Index] = PageTable[Index] & (INTN)(INT32)(~PAGE_ATTRIBUTE_BITS);
|
||||
}
|
||||
if (Nx && mXdSupported) {
|
||||
PageTable[Index] = PageTable[Index] | IA32_PG_NX;
|
||||
@@ -262,7 +262,7 @@ RestorePageTableAbove4G (
|
||||
//
|
||||
// Patch to remove present flag and rw flag.
|
||||
//
|
||||
PageTable[PTIndex] = PageTable[PTIndex] & (INTN)(INT32)(~(IA32_PG_RW | IA32_PG_P));
|
||||
PageTable[PTIndex] = PageTable[PTIndex] & (INTN)(INT32)(~PAGE_ATTRIBUTE_BITS);
|
||||
}
|
||||
//
|
||||
// Set XD bit to 1
|
||||
@@ -289,7 +289,7 @@ RestorePageTableAbove4G (
|
||||
//
|
||||
// Add present flag or clear XD flag to make page fault handler succeed.
|
||||
//
|
||||
PageTable[PTIndex] |= (UINT64)(IA32_PG_RW | IA32_PG_P);
|
||||
PageTable[PTIndex] |= (UINT64)(PAGE_ATTRIBUTE_BITS);
|
||||
if ((ErrorCode & IA32_PF_EC_ID) != 0) {
|
||||
//
|
||||
// If page fault is caused by instruction fetch, clear XD bit in the entry.
|
||||
|
Reference in New Issue
Block a user