diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index 49327a9b09..a8058f2afb 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -150,7 +150,6 @@ gUefiImageLoaderImageContextGuid ## CONSUMES ## HOB gEfiGlobalVariableGuid ## SOMETIMES_CONSUMES ## SysCall gEarlyPL011BaseAddressGuid ## CONSUMES - gEfiHobPageTableInfoGuid ## CONSUMES ## HOB [Ppis] gEfiVectorHandoffInfoPpiGuid ## UNDEFINED # HOB @@ -223,9 +222,14 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdEnableUserSpace ## CONSUMES gEfiMdePkgTokenSpaceGuid.PcdDebugRaisePropertyMask ## CONSUMES gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio ## CONSUMES + +[Pcd.IA32,Pcd.X64] + gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable ## SOMETIMES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdUse5LevelPageTable ## SOMETIMES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask ## CONSUMES gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase ## CONSUMES gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaSize ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio ## CONSUMES # [Hob] # RESOURCE_DESCRIPTOR ## CONSUMES diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c index c3bcc33919..51f89dcde9 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c @@ -8,6 +8,7 @@ #include "DxeMain.h" #include +#include #include VOID @@ -17,30 +18,144 @@ MakeUserPageTableTemplate ( OUT UINTN *UserPageTableTemplateSize ) { - EFI_HOB_GUID_TYPE *GuidHob; - EFI_PAGE_TABLE_INFO *PageTableInfo; - UINTN BigPageAddress; - EFI_PHYSICAL_ADDRESS PageAddress; - UINTN IndexOfPml5Entries; - UINTN IndexOfPml4Entries; - UINTN IndexOfPdpEntries; - UINTN IndexOfPageDirectoryEntries; - PAGE_MAP_AND_DIRECTORY_POINTER *PageMapLevel5Entry; - PAGE_MAP_AND_DIRECTORY_POINTER *PageMapLevel4Entry; - PAGE_MAP_AND_DIRECTORY_POINTER *PageMap; - PAGE_MAP_AND_DIRECTORY_POINTER *PageDirectoryPointerEntry; - PAGE_TABLE_ENTRY *PageDirectoryEntry; - PAGE_TABLE_1G_ENTRY *PageDirectory1GEntry; + UINT32 RegEax; + CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_ECX EcxFlags; + UINT32 RegEdx; + UINT8 PhysicalAddressBits; + UINT32 NumberOfPml5EntriesNeeded; + UINT32 NumberOfPml4EntriesNeeded; + UINT32 NumberOfPdpEntriesNeeded; + VOID *Hob; + BOOLEAN Page5LevelEnabled; + BOOLEAN Page1GSupport; + UINT64 AddressEncMask; + IA32_CR4 Cr4; + UINTN TotalPagesNum; + UINTN BigPageAddress; + EFI_PHYSICAL_ADDRESS PageAddress; + UINTN IndexOfPml5Entries; + UINTN IndexOfPml4Entries; + UINTN IndexOfPdpEntries; + UINTN IndexOfPageDirectoryEntries; + PAGE_MAP_AND_DIRECTORY_POINTER *PageMapLevel5Entry; + PAGE_MAP_AND_DIRECTORY_POINTER *PageMapLevel4Entry; + PAGE_MAP_AND_DIRECTORY_POINTER *PageMap; + PAGE_MAP_AND_DIRECTORY_POINTER *PageDirectoryPointerEntry; + PAGE_TABLE_ENTRY *PageDirectoryEntry; + PAGE_TABLE_1G_ENTRY *PageDirectory1GEntry; - GuidHob = GetFirstGuidHob (&gEfiHobPageTableInfoGuid); - if (GuidHob == NULL) { - DEBUG ((DEBUG_ERROR, "Core: Could not retrieve PageTableInfo HOB.\n")); - CpuDeadLoop (); + // + // Set PageMapLevel5Entry to suppress incorrect compiler/analyzer warnings + // + PageMapLevel5Entry = NULL; + + // + // Make sure AddressEncMask is contained to smallest supported address field + // + AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & PAGING_1G_ADDRESS_MASK_64; + + Page1GSupport = FALSE; + if (PcdGetBool (PcdUse1GPageTable)) { + AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL); + if (RegEax >= 0x80000001) { + AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx); + if ((RegEdx & BIT26) != 0) { + Page1GSupport = TRUE; + } + } } - PageTableInfo = (EFI_PAGE_TABLE_INFO *)(GET_GUID_HOB_DATA (GuidHob)); + // + // Get physical address bits supported. + // + Hob = GetFirstHob (EFI_HOB_TYPE_CPU); + if (Hob != NULL) { + PhysicalAddressBits = ((EFI_HOB_CPU *)Hob)->SizeOfMemorySpace; + } else { + AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL); + if (RegEax >= 0x80000008) { + AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL); + PhysicalAddressBits = (UINT8)RegEax; + } else { + PhysicalAddressBits = 36; + } + } - BigPageAddress = (UINTN)AllocateAlignedPages (PageTableInfo->TotalPagesNum, PAGE_TABLE_POOL_ALIGNMENT); + if (sizeof (UINTN) == sizeof (UINT64)) { + // + // If cpu has already run in 64bit long mode PEI, Page table Level in DXE must align with previous level. + // + Cr4.UintN = AsmReadCr4 (); + Page5LevelEnabled = (Cr4.Bits.LA57 != 0); + if (Page5LevelEnabled) { + ASSERT (PcdGetBool (PcdUse5LevelPageTable)); + } + } else { + // + // If cpu runs in 32bit protected mode PEI, Page table Level in DXE is decided by PCD and feature capability. + // + Page5LevelEnabled = FALSE; + if (PcdGetBool (PcdUse5LevelPageTable)) { + AsmCpuidEx ( + CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, + CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_SUB_LEAF_INFO, + NULL, + NULL, + &EcxFlags.Uint32, + NULL + ); + if (EcxFlags.Bits.FiveLevelPage != 0) { + Page5LevelEnabled = TRUE; + } + } + } + + // + // IA-32e paging translates 48-bit linear addresses to 52-bit physical addresses + // when 5-Level Paging is disabled, + // due to either unsupported by HW, or disabled by PCD. + // + ASSERT (PhysicalAddressBits <= 52); + if (!Page5LevelEnabled && (PhysicalAddressBits > 48)) { + PhysicalAddressBits = 48; + } + + // + // Calculate the table entries needed. + // + NumberOfPml5EntriesNeeded = 1; + if (PhysicalAddressBits > 48) { + NumberOfPml5EntriesNeeded = (UINT32)LShiftU64 (1, PhysicalAddressBits - 48); + PhysicalAddressBits = 48; + } + + NumberOfPml4EntriesNeeded = 1; + if (PhysicalAddressBits > 39) { + NumberOfPml4EntriesNeeded = (UINT32)LShiftU64 (1, PhysicalAddressBits - 39); + PhysicalAddressBits = 39; + } + + NumberOfPdpEntriesNeeded = 1; + ASSERT (PhysicalAddressBits > 30); + NumberOfPdpEntriesNeeded = (UINT32)LShiftU64 (1, PhysicalAddressBits - 30); + + // + // Pre-allocate big pages to avoid later allocations. + // + if (!Page1GSupport) { + TotalPagesNum = ((NumberOfPdpEntriesNeeded + 1) * NumberOfPml4EntriesNeeded + 1) * NumberOfPml5EntriesNeeded + 1; + } else { + TotalPagesNum = (NumberOfPml4EntriesNeeded + 1) * NumberOfPml5EntriesNeeded + 1; + } + + // + // Substract the one page occupied by PML5 entries if 5-Level Paging is disabled. + // + if (!Page5LevelEnabled) { + TotalPagesNum--; + } + + BigPageAddress = (UINTN)AllocateAlignedPages (TotalPagesNum, PAGE_TABLE_POOL_ALIGNMENT); if (BigPageAddress == 0) { DEBUG ((DEBUG_ERROR, "Core: Could not allocate buffer for User page table.\n")); CpuDeadLoop (); @@ -50,7 +165,7 @@ MakeUserPageTableTemplate ( // By architecture only one PageMapLevel4 exists - so lets allocate storage for it. // PageMap = (VOID *)BigPageAddress; - if (PageTableInfo->Page5LevelEnabled) { + if (Page5LevelEnabled) { // // By architecture only one PageMapLevel5 exists - so lets allocate storage for it. // @@ -61,7 +176,7 @@ MakeUserPageTableTemplate ( PageAddress = 0; for ( IndexOfPml5Entries = 0 - ; IndexOfPml5Entries < PageTableInfo->NumberOfPml5EntriesNeeded + ; IndexOfPml5Entries < NumberOfPml5EntriesNeeded ; IndexOfPml5Entries++) { // @@ -72,11 +187,11 @@ MakeUserPageTableTemplate ( PageMapLevel4Entry = (VOID *)BigPageAddress; BigPageAddress += SIZE_4KB; - if (PageTableInfo->Page5LevelEnabled) { + if (Page5LevelEnabled) { // // Make a PML5 Entry // - PageMapLevel5Entry->Uint64 = (UINT64)(UINTN)PageMapLevel4Entry | PageTableInfo->AddressEncMask; + PageMapLevel5Entry->Uint64 = (UINT64)(UINTN)PageMapLevel4Entry | AddressEncMask; PageMapLevel5Entry->Bits.ReadWrite = 1; PageMapLevel5Entry->Bits.UserSupervisor = 1; PageMapLevel5Entry->Bits.Present = 1; @@ -84,7 +199,7 @@ MakeUserPageTableTemplate ( } for ( IndexOfPml4Entries = 0 - ; IndexOfPml4Entries < (PageTableInfo->NumberOfPml5EntriesNeeded == 1 ? PageTableInfo->NumberOfPml4EntriesNeeded : 512) + ; IndexOfPml4Entries < (NumberOfPml5EntriesNeeded == 1 ? NumberOfPml4EntriesNeeded : 512) ; IndexOfPml4Entries++, PageMapLevel4Entry++) { // @@ -97,26 +212,26 @@ MakeUserPageTableTemplate ( // // Make a PML4 Entry // - PageMapLevel4Entry->Uint64 = (UINT64)(UINTN)PageDirectoryPointerEntry | PageTableInfo->AddressEncMask; + PageMapLevel4Entry->Uint64 = (UINT64)(UINTN)PageDirectoryPointerEntry | AddressEncMask; PageMapLevel4Entry->Bits.ReadWrite = 1; PageMapLevel4Entry->Bits.UserSupervisor = 1; PageMapLevel4Entry->Bits.Present = 1; - if (PageTableInfo->Page1GSupport) { + if (Page1GSupport) { PageDirectory1GEntry = (VOID *)PageDirectoryPointerEntry; for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectory1GEntry++, PageAddress += SIZE_1GB) { // // Fill in the Page Directory entries // - PageDirectory1GEntry->Uint64 = (UINT64)PageAddress | PageTableInfo->AddressEncMask; + PageDirectory1GEntry->Uint64 = (UINT64)PageAddress | AddressEncMask; PageDirectory1GEntry->Bits.ReadWrite = 1; PageDirectory1GEntry->Bits.Present = 0; PageDirectory1GEntry->Bits.MustBe1 = 1; } } else { for ( IndexOfPdpEntries = 0 - ; IndexOfPdpEntries < (PageTableInfo->NumberOfPml4EntriesNeeded == 1 ? PageTableInfo->NumberOfPdpEntriesNeeded : 512) + ; IndexOfPdpEntries < (NumberOfPml4EntriesNeeded == 1 ? NumberOfPdpEntriesNeeded : 512) ; IndexOfPdpEntries++, PageDirectoryPointerEntry++) { // @@ -129,7 +244,7 @@ MakeUserPageTableTemplate ( // // Fill in a Page Directory Pointer Entries // - PageDirectoryPointerEntry->Uint64 = (UINT64)(UINTN)PageDirectoryEntry | PageTableInfo->AddressEncMask; + PageDirectoryPointerEntry->Uint64 = (UINT64)(UINTN)PageDirectoryEntry | AddressEncMask; PageDirectoryPointerEntry->Bits.ReadWrite = 1; PageDirectoryPointerEntry->Bits.UserSupervisor = 1; PageDirectoryPointerEntry->Bits.Present = 1; @@ -138,7 +253,7 @@ MakeUserPageTableTemplate ( // // Fill in the Page Directory entries // - PageDirectoryEntry->Uint64 = (UINT64)PageAddress | PageTableInfo->AddressEncMask; + PageDirectoryEntry->Uint64 = (UINT64)PageAddress | AddressEncMask; PageDirectoryEntry->Bits.ReadWrite = 1; PageDirectoryEntry->Bits.Present = 0; PageDirectoryEntry->Bits.MustBe1 = 1; @@ -158,7 +273,7 @@ MakeUserPageTableTemplate ( ZeroMem (PageMapLevel4Entry, (512 - IndexOfPml4Entries) * sizeof (PAGE_MAP_AND_DIRECTORY_POINTER)); } - if (PageTableInfo->Page5LevelEnabled) { + if (Page5LevelEnabled) { // // For the PML5 entries we are not using fill in a null entry. // @@ -166,7 +281,7 @@ MakeUserPageTableTemplate ( } *UserPageTableTemplate = (VOID *)PageMap; - *UserPageTableTemplateSize = ALIGN_VALUE (EFI_PAGES_TO_SIZE (PageTableInfo->TotalPagesNum), PAGE_TABLE_POOL_ALIGNMENT); + *UserPageTableTemplateSize = ALIGN_VALUE (EFI_PAGES_TO_SIZE (TotalPagesNum), PAGE_TABLE_POOL_ALIGNMENT); SetUefiImageMemoryAttributes ((UINT64)PageMap, *UserPageTableTemplateSize, EFI_MEMORY_XP); } diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf index 8a4d0eeab4..e231e7bd6f 100644 --- a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf +++ b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf @@ -90,7 +90,6 @@ ## SOMETIMES_PRODUCES ## HOB gEfiMemoryTypeInformationGuid gUefiImageLoaderImageContextGuid - gEfiHobPageTableInfoGuid [FeaturePcd.IA32] gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode ## CONSUMES diff --git a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c index c35e6353d5..d014c95348 100644 --- a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c +++ b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c @@ -705,7 +705,6 @@ CreateIdentityMappingPageTables ( PAGE_TABLE_1G_ENTRY *PageDirectory1GEntry; UINT64 AddressEncMask; IA32_CR4 Cr4; - EFI_PAGE_TABLE_INFO PageTableInfo; // // Set PageMapLevel5Entry to suppress incorrect compiler/analyzer warnings @@ -829,16 +828,6 @@ CreateIdentityMappingPageTables ( (UINT64)TotalPagesNum )); - PageTableInfo.NumberOfPml5EntriesNeeded = NumberOfPml5EntriesNeeded; - PageTableInfo.NumberOfPml4EntriesNeeded = NumberOfPml4EntriesNeeded; - PageTableInfo.NumberOfPdpEntriesNeeded = NumberOfPdpEntriesNeeded; - PageTableInfo.TotalPagesNum = TotalPagesNum; - PageTableInfo.Page5LevelEnabled = Page5LevelEnabled; - PageTableInfo.Page1GSupport = Page1GSupport; - PageTableInfo.AddressEncMask = AddressEncMask; - - BuildGuidDataHob (&gEfiHobPageTableInfoGuid, &PageTableInfo, sizeof (EFI_PAGE_TABLE_INFO)); - BigPageAddress = (UINTN)AllocatePageTableMemory (TotalPagesNum); ASSERT (BigPageAddress != 0); diff --git a/MdePkg/Include/Guid/MemoryAllocationHob.h b/MdePkg/Include/Guid/MemoryAllocationHob.h index 9ebbd13992..e4c57bf1ac 100644 --- a/MdePkg/Include/Guid/MemoryAllocationHob.h +++ b/MdePkg/Include/Guid/MemoryAllocationHob.h @@ -21,12 +21,8 @@ #define EFI_HOB_MEMORY_ALLOC_MODULE_GUID \ {0xf8e21975, 0x899, 0x4f58, {0xa4, 0xbe, 0x55, 0x25, 0xa9, 0xc6, 0xd7, 0x7a} } -#define EFI_HOB_PAGE_TABLE_INFO_GUID \ - {0xac992fe9, 0xb0cc, 0x45df, {0xae, 0xcf, 0x51, 0x5a, 0xd2, 0xc4, 0xe8, 0xb3} } - extern EFI_GUID gEfiHobMemoryAllocBspStoreGuid; extern EFI_GUID gEfiHobMemoryAllocStackGuid; extern EFI_GUID gEfiHobMemoryAllocModuleGuid; -extern EFI_GUID gEfiHobPageTableInfoGuid; #endif diff --git a/MdePkg/Include/Library/MemoryAllocationLib.h b/MdePkg/Include/Library/MemoryAllocationLib.h index da7ac36b2f..59d4b29c44 100644 --- a/MdePkg/Include/Library/MemoryAllocationLib.h +++ b/MdePkg/Include/Library/MemoryAllocationLib.h @@ -14,16 +14,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #ifndef __MEMORY_ALLOCATION_LIB_H__ #define __MEMORY_ALLOCATION_LIB_H__ -typedef struct { - UINT32 NumberOfPml5EntriesNeeded; - UINT32 NumberOfPml4EntriesNeeded; - UINT32 NumberOfPdpEntriesNeeded; - UINTN TotalPagesNum; - BOOLEAN Page5LevelEnabled; - BOOLEAN Page1GSupport; - UINT64 AddressEncMask; -} EFI_PAGE_TABLE_INFO; - /** Allocates one or more 4KB pages of type EfiBootServicesData. diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index fc0ef3deef..84f416b466 100644 --- a/MdePkg/MdePkg.dec +++ b/MdePkg/MdePkg.dec @@ -781,9 +781,6 @@ ## Include/Guid/MemoryAllocationHob.h gEfiHobMemoryAllocBspStoreGuid = { 0x564B33CD, 0xC92A, 0x4593, { 0x90, 0xBF, 0x24, 0x73, 0xE4, 0x3C, 0x63, 0x22 }} - ## Include/Guid/MemoryAllocationHob.h - gEfiHobPageTableInfoGuid = { 0xAC992FE9, 0xB0CC, 0x45DF, { 0xAE, 0xCF, 0x51, 0x5A, 0xD2, 0xC4, 0xE8, 0xB3 }} - ## Include/Guid/EventLegacyBios.h gEfiEventLegacyBootGuid = { 0x2A571201, 0x4966, 0x47F6, { 0x8B, 0x86, 0xF3, 0x1E, 0x41, 0xF3, 0x2F, 0x10 }}