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:
@@ -732,12 +732,14 @@ APHandler (
|
||||
Create 4G PageTable in SMRAM.
|
||||
|
||||
@param ExtraPages Additional page numbers besides for 4G memory
|
||||
@param Is32BitPageTable Whether the page table is 32-bit PAE
|
||||
@return PageTable Address
|
||||
|
||||
**/
|
||||
UINT32
|
||||
Gen4GPageTable (
|
||||
IN UINTN ExtraPages
|
||||
IN UINTN ExtraPages,
|
||||
IN BOOLEAN Is32BitPageTable
|
||||
)
|
||||
{
|
||||
VOID *PageTable;
|
||||
@@ -785,7 +787,7 @@ Gen4GPageTable (
|
||||
// Set Page Directory Pointers
|
||||
//
|
||||
for (Index = 0; Index < 4; Index++) {
|
||||
Pte[Index] = (UINTN)PageTable + EFI_PAGE_SIZE * (Index + 1) + IA32_PG_P;
|
||||
Pte[Index] = (UINTN)PageTable + EFI_PAGE_SIZE * (Index + 1) + (Is32BitPageTable ? IA32_PAE_PDPTE_ATTRIBUTE_BITS : PAGE_ATTRIBUTE_BITS);
|
||||
}
|
||||
Pte += EFI_PAGE_SIZE / sizeof (*Pte);
|
||||
|
||||
@@ -793,7 +795,7 @@ Gen4GPageTable (
|
||||
// Fill in Page Directory Entries
|
||||
//
|
||||
for (Index = 0; Index < EFI_PAGE_SIZE * 4 / sizeof (*Pte); Index++) {
|
||||
Pte[Index] = (Index << 21) + IA32_PG_PS + IA32_PG_RW + IA32_PG_P;
|
||||
Pte[Index] = (Index << 21) | IA32_PG_PS | PAGE_ATTRIBUTE_BITS;
|
||||
}
|
||||
|
||||
if (FeaturePcdGet (PcdCpuSmmStackGuard)) {
|
||||
@@ -802,7 +804,7 @@ Gen4GPageTable (
|
||||
Pdpte = (UINT64*)PageTable;
|
||||
for (PageIndex = Low2MBoundary; PageIndex <= High2MBoundary; PageIndex += SIZE_2MB) {
|
||||
Pte = (UINT64*)(UINTN)(Pdpte[BitFieldRead32 ((UINT32)PageIndex, 30, 31)] & ~(EFI_PAGE_SIZE - 1));
|
||||
Pte[BitFieldRead32 ((UINT32)PageIndex, 21, 29)] = (UINT64)Pages + IA32_PG_RW + IA32_PG_P;
|
||||
Pte[BitFieldRead32 ((UINT32)PageIndex, 21, 29)] = (UINT64)Pages | PAGE_ATTRIBUTE_BITS;
|
||||
//
|
||||
// Fill in Page Table Entries
|
||||
//
|
||||
@@ -819,7 +821,7 @@ Gen4GPageTable (
|
||||
GuardPage = 0;
|
||||
}
|
||||
} else {
|
||||
Pte[Index] = PageAddress + IA32_PG_RW + IA32_PG_P;
|
||||
Pte[Index] = PageAddress | PAGE_ATTRIBUTE_BITS;
|
||||
}
|
||||
PageAddress+= EFI_PAGE_SIZE;
|
||||
}
|
||||
@@ -886,7 +888,7 @@ SetCacheability (
|
||||
NewPageTable[Index] |= (UINT64)(Index << EFI_PAGE_SHIFT);
|
||||
}
|
||||
|
||||
PageTable[PTIndex] = ((UINTN)NewPageTableAddress & gPhyMask) | IA32_PG_P;
|
||||
PageTable[PTIndex] = ((UINTN)NewPageTableAddress & gPhyMask) | PAGE_ATTRIBUTE_BITS;
|
||||
}
|
||||
|
||||
ASSERT (PageTable[PTIndex] & IA32_PG_P);
|
||||
|
Reference in New Issue
Block a user