X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=UefiCpuPkg%2FCpuDxe%2FCpuPageTable.c;h=0a02cb3f6b7e1606536126368738d04c5ed74f7a;hb=6ff7c838d09224dd4e4c9b5b93152d8db1b19740;hp=c369b44f128e70a3e49e94adf5b484782fecdfb9;hpb=0acd869796ded1266e69487dff717cd69d6031f9;p=mirror_edk2.git
diff --git a/UefiCpuPkg/CpuDxe/CpuPageTable.c b/UefiCpuPkg/CpuDxe/CpuPageTable.c
index c369b44f12..0a02cb3f6b 100644
--- a/UefiCpuPkg/CpuDxe/CpuPageTable.c
+++ b/UefiCpuPkg/CpuDxe/CpuPageTable.c
@@ -1,7 +1,7 @@
/** @file
Page table management support.
- Copyright (c) 2017, Intel Corporation. All rights reserved.
+ Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.
Copyright (c) 2017, AMD Incorporated. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -15,20 +15,12 @@
#include
#include
#include
-#include
-#include
+#include
+#include
#include "CpuDxe.h"
#include "CpuPageTable.h"
-///
-/// Paging registers
-///
-#define CR0_WP BIT16
-#define CR0_PG BIT31
-#define CR4_PSE BIT4
-#define CR4_PAE BIT5
-
///
/// Page Table Entry
///
@@ -161,6 +153,10 @@ GetCurrentPagingContext (
UINT32 RegEax;
CPUID_EXTENDED_CPU_SIG_EDX RegEdx;
MSR_IA32_EFER_REGISTER MsrEfer;
+ IA32_CR4 Cr4;
+ IA32_CR0 Cr0;
+ UINT32 *Attributes;
+ UINTN *PageTableBase;
//
// Don't retrieve current paging context from processor if in SMM mode.
@@ -172,20 +168,28 @@ GetCurrentPagingContext (
} else {
mPagingContext.MachineType = IMAGE_FILE_MACHINE_I386;
}
- if ((AsmReadCr0 () & CR0_PG) != 0) {
- mPagingContext.ContextData.X64.PageTableBase = (AsmReadCr3 () & PAGING_4K_ADDRESS_MASK_64);
+
+ GetPagingDetails (&mPagingContext.ContextData, &PageTableBase, &Attributes);
+
+ Cr0.UintN = AsmReadCr0 ();
+ Cr4.UintN = AsmReadCr4 ();
+
+ if (Cr0.Bits.PG != 0) {
+ *PageTableBase = (AsmReadCr3 () & PAGING_4K_ADDRESS_MASK_64);
} else {
- mPagingContext.ContextData.X64.PageTableBase = 0;
+ *PageTableBase = 0;
}
-
- if ((AsmReadCr4 () & CR4_PSE) != 0) {
- mPagingContext.ContextData.Ia32.Attributes |= PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_PSE;
+ if (Cr0.Bits.WP != 0) {
+ *Attributes |= PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_WP_ENABLE;
+ }
+ if (Cr4.Bits.PSE != 0) {
+ *Attributes |= PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_PSE;
}
- if ((AsmReadCr4 () & CR4_PAE) != 0) {
- mPagingContext.ContextData.Ia32.Attributes |= PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_PAE;
+ if (Cr4.Bits.PAE != 0) {
+ *Attributes |= PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_PAE;
}
- if ((AsmReadCr0 () & CR0_WP) != 0) {
- mPagingContext.ContextData.Ia32.Attributes |= PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_WP_ENABLE;
+ if (Cr4.Bits.LA57 != 0) {
+ *Attributes |= PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_5_LEVEL;
}
AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
@@ -197,12 +201,12 @@ GetCurrentPagingContext (
MsrEfer.Uint64 = AsmReadMsr64(MSR_CORE_IA32_EFER);
if (MsrEfer.Bits.NXE != 0) {
// XD activated
- mPagingContext.ContextData.Ia32.Attributes |= PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_XD_ACTIVATED;
+ *Attributes |= PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_XD_ACTIVATED;
}
}
if (RegEdx.Bits.Page1GB != 0) {
- mPagingContext.ContextData.Ia32.Attributes |= PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_PAGE_1G_SUPPORT;
+ *Attributes |= PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_PAGE_1G_SUPPORT;
}
}
}
@@ -276,14 +280,17 @@ GetPageTableEntry (
UINTN Index2;
UINTN Index3;
UINTN Index4;
+ UINTN Index5;
UINT64 *L1PageTable;
UINT64 *L2PageTable;
UINT64 *L3PageTable;
UINT64 *L4PageTable;
+ UINT64 *L5PageTable;
UINT64 AddressEncMask;
ASSERT (PagingContext != NULL);
+ Index5 = ((UINTN)RShiftU64 (Address, 48)) & PAGING_PAE_INDEX_MASK;
Index4 = ((UINTN)RShiftU64 (Address, 39)) & PAGING_PAE_INDEX_MASK;
Index3 = ((UINTN)Address >> 30) & PAGING_PAE_INDEX_MASK;
Index2 = ((UINTN)Address >> 21) & PAGING_PAE_INDEX_MASK;
@@ -294,7 +301,17 @@ GetPageTableEntry (
AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & PAGING_1G_ADDRESS_MASK_64;
if (PagingContext->MachineType == IMAGE_FILE_MACHINE_X64) {
- L4PageTable = (UINT64 *)(UINTN)PagingContext->ContextData.X64.PageTableBase;
+ if ((PagingContext->ContextData.X64.Attributes & PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_5_LEVEL) != 0) {
+ L5PageTable = (UINT64 *)(UINTN)PagingContext->ContextData.X64.PageTableBase;
+ if (L5PageTable[Index5] == 0) {
+ *PageAttribute = PageNone;
+ return NULL;
+ }
+
+ L4PageTable = (UINT64 *)(UINTN)(L5PageTable[Index5] & ~AddressEncMask & PAGING_4K_ADDRESS_MASK_64);
+ } else {
+ L4PageTable = (UINT64 *)(UINTN)PagingContext->ContextData.X64.PageTableBase;
+ }
if (L4PageTable[Index4] == 0) {
*PageAttribute = PageNone;
return NULL;
@@ -382,6 +399,7 @@ ConvertPageEntryAttribute (
{
UINT64 CurrentPageEntry;
UINT64 NewPageEntry;
+ UINT32 *PageAttributes;
CurrentPageEntry = *PageEntry;
NewPageEntry = CurrentPageEntry;
@@ -425,7 +443,10 @@ ConvertPageEntryAttribute (
break;
}
}
- if ((PagingContext->ContextData.Ia32.Attributes & PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_XD_ACTIVATED) != 0) {
+
+ GetPagingDetails (&PagingContext->ContextData, NULL, &PageAttributes);
+
+ if ((*PageAttributes & PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_XD_ACTIVATED) != 0) {
if ((Attributes & EFI_MEMORY_XP) != 0) {
switch (PageAction) {
case PageActionAssign:
@@ -581,12 +602,14 @@ IsReadOnlyPageWriteProtected (
VOID
)
{
+ IA32_CR0 Cr0;
//
// To avoid unforseen consequences, don't touch paging settings in SMM mode
// in this driver.
//
if (!IsInSmm ()) {
- return ((AsmReadCr0 () & CR0_WP) != 0);
+ Cr0.UintN = AsmReadCr0 ();
+ return (BOOLEAN) (Cr0.Bits.WP != 0);
}
return FALSE;
}
@@ -599,12 +622,15 @@ DisableReadOnlyPageWriteProtect (
VOID
)
{
+ IA32_CR0 Cr0;
//
// To avoid unforseen consequences, don't touch paging settings in SMM mode
// in this driver.
//
if (!IsInSmm ()) {
- AsmWriteCr0 (AsmReadCr0 () & ~CR0_WP);
+ Cr0.UintN = AsmReadCr0 ();
+ Cr0.Bits.WP = 0;
+ AsmWriteCr0 (Cr0.UintN);
}
}
@@ -616,12 +642,15 @@ EnableReadOnlyPageWriteProtect (
VOID
)
{
+ IA32_CR0 Cr0;
//
// To avoid unforseen consequences, don't touch paging settings in SMM mode
// in this driver.
//
if (!IsInSmm ()) {
- AsmWriteCr0 (AsmReadCr0 () | CR0_WP);
+ Cr0.UintN = AsmReadCr0 ();
+ Cr0.Bits.WP = 1;
+ AsmWriteCr0 (Cr0.UintN);
}
}
@@ -747,7 +776,7 @@ ConvertMemoryPageAttributes (
}
//
- // Below logic is to check 2M/4K page to make sure we donot waist memory.
+ // Below logic is to check 2M/4K page to make sure we do not waste memory.
//
Status = EFI_SUCCESS;
while (Length != 0) {
@@ -809,7 +838,7 @@ Done:
Caller should make sure BaseAddress and Length is at page boundary.
- Caller need guarentee the TPL <= TPL_NOTIFY, if there is split page request.
+ Caller need guarantee the TPL <= TPL_NOTIFY, if there is split page request.
@param[in] PagingContext The paging context. NULL means get page table from current CPU context.
@param[in] BaseAddress The physical address that is the start address of a memory region.
@@ -940,7 +969,7 @@ RefreshGcdMemoryAttributesFromPaging (
);
if (EFI_ERROR (Status)) {
//
- // If we cannot udpate the capabilities, we cannot update its
+ // If we cannot update the capabilities, we cannot update its
// attributes either. So just simply skip current block of memory.
//
DEBUG ((
@@ -1317,15 +1346,18 @@ InitializePageTableLib (
)
{
PAGE_TABLE_LIB_PAGING_CONTEXT CurrentPagingContext;
+ UINT32 *Attributes;
+ UINTN *PageTableBase;
GetCurrentPagingContext (&CurrentPagingContext);
+ GetPagingDetails (&CurrentPagingContext.ContextData, &PageTableBase, &Attributes);
+
//
// Reserve memory of page tables for future uses, if paging is enabled.
//
- if (CurrentPagingContext.ContextData.X64.PageTableBase != 0 &&
- (CurrentPagingContext.ContextData.Ia32.Attributes &
- PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_PAE) != 0) {
+ if ((*PageTableBase != 0) &&
+ (*Attributes & PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_PAE) != 0) {
DisableReadOnlyPageWriteProtect ();
InitializePageTablePool (1);
EnableReadOnlyPageWriteProtect ();
@@ -1340,10 +1372,10 @@ InitializePageTableLib (
ASSERT (mLastPFEntryPointer != NULL);
}
- DEBUG ((DEBUG_INFO, "CurrentPagingContext:\n", CurrentPagingContext.MachineType));
+ DEBUG ((DEBUG_INFO, "CurrentPagingContext:\n"));
DEBUG ((DEBUG_INFO, " MachineType - 0x%x\n", CurrentPagingContext.MachineType));
- DEBUG ((DEBUG_INFO, " PageTableBase - 0x%x\n", CurrentPagingContext.ContextData.X64.PageTableBase));
- DEBUG ((DEBUG_INFO, " Attributes - 0x%x\n", CurrentPagingContext.ContextData.X64.Attributes));
+ DEBUG ((DEBUG_INFO, " PageTableBase - 0x%Lx\n", (UINT64)*PageTableBase));
+ DEBUG ((DEBUG_INFO, " Attributes - 0x%x\n", *Attributes));
return ;
}