X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdeModulePkg%2FCore%2FDxeIplPeim%2FX64%2FVirtualMemory.c;h=516cf908bc886e8c34ab549694cb9beea1896d16;hp=2389f3eb485b2e5919ac01439ec0b4a8f800a804;hb=HEAD;hpb=46f8a6891606746ca8b1e684ac379ce271306dc0 diff --git a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c index 2389f3eb48..18b121d768 100644 --- a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c +++ b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c @@ -15,7 +15,7 @@ 2) IA-32 Intel(R) Architecture Software Developer's Manual Volume 2:Instruction Set Reference, Intel 3) IA-32 Intel(R) Architecture Software Developer's Manual Volume 3:System Programmer's Guide, Intel -Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2022, Intel Corporation. All rights reserved.
Copyright (c) 2017, AMD Incorporated. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -29,7 +29,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent // // Global variable to keep track current available memory used as page table. // -PAGE_TABLE_POOL *mPageTablePool = NULL; +PAGE_TABLE_POOL *mPageTablePool = NULL; /** Clear legacy memory located at the first 4K-page, if available. @@ -42,39 +42,50 @@ PAGE_TABLE_POOL *mPageTablePool = NULL; **/ VOID ClearFirst4KPage ( - IN VOID *HobStart + IN VOID *HobStart ) { - EFI_PEI_HOB_POINTERS RscHob; - EFI_PEI_HOB_POINTERS MemHob; - BOOLEAN DoClear; + EFI_PEI_HOB_POINTERS RscHob; + EFI_PEI_HOB_POINTERS MemHob; + BOOLEAN DoClear; RscHob.Raw = HobStart; MemHob.Raw = HobStart; - DoClear = FALSE; + DoClear = FALSE; // // Check if page 0 exists and free // - while ((RscHob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, - RscHob.Raw)) != NULL) { - if (RscHob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY && - RscHob.ResourceDescriptor->PhysicalStart == 0) { + while ((RscHob.Raw = GetNextHob ( + EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, + RscHob.Raw + )) != NULL) + { + if ((RscHob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) && + (RscHob.ResourceDescriptor->PhysicalStart == 0)) + { DoClear = TRUE; // // Make sure memory at 0-4095 has not been allocated. // - while ((MemHob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, - MemHob.Raw)) != NULL) { + while ((MemHob.Raw = GetNextHob ( + EFI_HOB_TYPE_MEMORY_ALLOCATION, + MemHob.Raw + )) != NULL) + { if (MemHob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress - < EFI_PAGE_SIZE) { + < EFI_PAGE_SIZE) + { DoClear = FALSE; break; } + MemHob.Raw = GET_NEXT_HOB (MemHob); } + break; } + RscHob.Raw = GET_NEXT_HOB (RscHob); } @@ -113,9 +124,9 @@ IsExecuteDisableBitAvailable ( VOID ) { - UINT32 RegEax; - UINT32 RegEdx; - BOOLEAN Available; + UINT32 RegEax; + UINT32 RegEdx; + BOOLEAN Available; Available = FALSE; AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL); @@ -166,11 +177,13 @@ EnableExecuteDisableBit ( VOID ) { - UINT64 MsrRegisters; + UINT64 MsrRegisters; MsrRegisters = AsmReadMsr64 (0xC0000080); - MsrRegisters |= BIT11; - AsmWriteMsr64 (0xC0000080, MsrRegisters); + if ((MsrRegisters & BIT11) == 0) { + MsrRegisters |= BIT11; + AsmWriteMsr64 (0xC0000080, MsrRegisters); + } } /** @@ -181,24 +194,28 @@ EnableExecuteDisableBit ( @param Size Size of the given physical memory. @param StackBase Base address of stack. @param StackSize Size of stack. + @param GhcbBase Base address of GHCB pages. + @param GhcbSize Size of GHCB area. @retval TRUE Page table should be split. @retval FALSE Page table should not be split. **/ BOOLEAN ToSplitPageTable ( - IN EFI_PHYSICAL_ADDRESS Address, - IN UINTN Size, - IN EFI_PHYSICAL_ADDRESS StackBase, - IN UINTN StackSize + IN EFI_PHYSICAL_ADDRESS Address, + IN UINTN Size, + IN EFI_PHYSICAL_ADDRESS StackBase, + IN UINTN StackSize, + IN EFI_PHYSICAL_ADDRESS GhcbBase, + IN UINTN GhcbSize ) { - if (IsNullDetectionEnabled () && Address == 0) { + if (IsNullDetectionEnabled () && (Address == 0)) { return TRUE; } if (PcdGetBool (PcdCpuStackGuard)) { - if (StackBase >= Address && StackBase < (Address + Size)) { + if ((StackBase >= Address) && (StackBase < (Address + Size))) { return TRUE; } } @@ -209,8 +226,15 @@ ToSplitPageTable ( } } + if (GhcbBase != 0) { + if ((Address < GhcbBase + GhcbSize) && ((Address + Size) > GhcbBase)) { + return TRUE; + } + } + return FALSE; } + /** Initialize a buffer pool for page table use only. @@ -230,18 +254,18 @@ ToSplitPageTable ( **/ BOOLEAN InitializePageTablePool ( - IN UINTN PoolPages + IN UINTN PoolPages ) { - VOID *Buffer; + VOID *Buffer; // // Always reserve at least PAGE_TABLE_POOL_UNIT_PAGES, including one page for // header. // PoolPages += 1; // Add one page for header. - PoolPages = ((PoolPages - 1) / PAGE_TABLE_POOL_UNIT_PAGES + 1) * - PAGE_TABLE_POOL_UNIT_PAGES; + PoolPages = ((PoolPages - 1) / PAGE_TABLE_POOL_UNIT_PAGES + 1) * + PAGE_TABLE_POOL_UNIT_PAGES; Buffer = AllocateAlignedPages (PoolPages, PAGE_TABLE_POOL_ALIGNMENT); if (Buffer == NULL) { DEBUG ((DEBUG_ERROR, "ERROR: Out of aligned pages\r\n")); @@ -252,19 +276,19 @@ InitializePageTablePool ( // Link all pools into a list for easier track later. // if (mPageTablePool == NULL) { - mPageTablePool = Buffer; + mPageTablePool = Buffer; mPageTablePool->NextPool = mPageTablePool; } else { ((PAGE_TABLE_POOL *)Buffer)->NextPool = mPageTablePool->NextPool; - mPageTablePool->NextPool = Buffer; - mPageTablePool = Buffer; + mPageTablePool->NextPool = Buffer; + mPageTablePool = Buffer; } // // Reserve one page for pool header. // - mPageTablePool->FreePages = PoolPages - 1; - mPageTablePool->Offset = EFI_PAGES_TO_SIZE (1); + mPageTablePool->FreePages = PoolPages - 1; + mPageTablePool->Offset = EFI_PAGES_TO_SIZE (1); return TRUE; } @@ -288,10 +312,10 @@ InitializePageTablePool ( **/ VOID * AllocatePageTableMemory ( - IN UINTN Pages + IN UINTN Pages ) { - VOID *Buffer; + VOID *Buffer; if (Pages == 0) { return NULL; @@ -300,8 +324,9 @@ AllocatePageTableMemory ( // // Renew the pool if necessary. // - if (mPageTablePool == NULL || - Pages > mPageTablePool->FreePages) { + if ((mPageTablePool == NULL) || + (Pages > mPageTablePool->FreePages)) + { if (!InitializePageTablePool (Pages)) { return NULL; } @@ -309,8 +334,8 @@ AllocatePageTableMemory ( Buffer = (UINT8 *)mPageTablePool + mPageTablePool->Offset; - mPageTablePool->Offset += EFI_PAGES_TO_SIZE (Pages); - mPageTablePool->FreePages -= Pages; + mPageTablePool->Offset += EFI_PAGES_TO_SIZE (Pages); + mPageTablePool->FreePages -= Pages; return Buffer; } @@ -322,20 +347,24 @@ AllocatePageTableMemory ( @param[in, out] PageEntry2M Pointer to 2M page entry. @param[in] StackBase Stack base address. @param[in] StackSize Stack size. + @param[in] GhcbBase GHCB page area base address. + @param[in] GhcbSize GHCB page area size. **/ VOID Split2MPageTo4K ( - IN EFI_PHYSICAL_ADDRESS PhysicalAddress, - IN OUT UINT64 *PageEntry2M, - IN EFI_PHYSICAL_ADDRESS StackBase, - IN UINTN StackSize + IN EFI_PHYSICAL_ADDRESS PhysicalAddress, + IN OUT UINT64 *PageEntry2M, + IN EFI_PHYSICAL_ADDRESS StackBase, + IN UINTN StackSize, + IN EFI_PHYSICAL_ADDRESS GhcbBase, + IN UINTN GhcbSize ) { - EFI_PHYSICAL_ADDRESS PhysicalAddress4K; - UINTN IndexOfPageTableEntries; - PAGE_TABLE_4K_ENTRY *PageTableEntry; - UINT64 AddressEncMask; + EFI_PHYSICAL_ADDRESS PhysicalAddress4K; + UINTN IndexOfPageTableEntries; + PAGE_TABLE_4K_ENTRY *PageTableEntry; + UINT64 AddressEncMask; // // Make sure AddressEncMask is contained to smallest supported address field @@ -348,26 +377,43 @@ Split2MPageTo4K ( // // Fill in 2M page entry. // - *PageEntry2M = (UINT64) (UINTN) PageTableEntry | AddressEncMask | IA32_PG_P | IA32_PG_RW; + *PageEntry2M = (UINT64)(UINTN)PageTableEntry | AddressEncMask | IA32_PG_P | IA32_PG_RW; PhysicalAddress4K = PhysicalAddress; for (IndexOfPageTableEntries = 0; IndexOfPageTableEntries < 512; IndexOfPageTableEntries++, PageTableEntry++, PhysicalAddress4K += SIZE_4KB) { // // Fill in the Page Table entries // - PageTableEntry->Uint64 = (UINT64) PhysicalAddress4K | AddressEncMask; + PageTableEntry->Uint64 = (UINT64)PhysicalAddress4K; + + // + // The GHCB range consists of two pages per CPU, the GHCB and a + // per-CPU variable page. The GHCB page needs to be mapped as an + // unencrypted page while the per-CPU variable page needs to be + // mapped encrypted. These pages alternate in assignment. + // + if ( (GhcbBase == 0) + || (PhysicalAddress4K < GhcbBase) + || (PhysicalAddress4K >= GhcbBase + GhcbSize) + || (((PhysicalAddress4K - GhcbBase) & SIZE_4KB) != 0)) + { + PageTableEntry->Uint64 |= AddressEncMask; + } + PageTableEntry->Bits.ReadWrite = 1; - if ((IsNullDetectionEnabled () && PhysicalAddress4K == 0) || - (PcdGetBool (PcdCpuStackGuard) && PhysicalAddress4K == StackBase)) { + if ((IsNullDetectionEnabled () && (PhysicalAddress4K == 0)) || + (PcdGetBool (PcdCpuStackGuard) && (PhysicalAddress4K == StackBase))) + { PageTableEntry->Bits.Present = 0; } else { PageTableEntry->Bits.Present = 1; } - if (PcdGetBool (PcdSetNxForStack) - && (PhysicalAddress4K >= StackBase) - && (PhysicalAddress4K < StackBase + StackSize)) { + if ( PcdGetBool (PcdSetNxForStack) + && (PhysicalAddress4K >= StackBase) + && (PhysicalAddress4K < StackBase + StackSize)) + { // // Set Nx bit for stack. // @@ -383,20 +429,24 @@ Split2MPageTo4K ( @param[in, out] PageEntry1G Pointer to 1G page entry. @param[in] StackBase Stack base address. @param[in] StackSize Stack size. + @param[in] GhcbBase GHCB page area base address. + @param[in] GhcbSize GHCB page area size. **/ VOID Split1GPageTo2M ( - IN EFI_PHYSICAL_ADDRESS PhysicalAddress, - IN OUT UINT64 *PageEntry1G, - IN EFI_PHYSICAL_ADDRESS StackBase, - IN UINTN StackSize + IN EFI_PHYSICAL_ADDRESS PhysicalAddress, + IN OUT UINT64 *PageEntry1G, + IN EFI_PHYSICAL_ADDRESS StackBase, + IN UINTN StackSize, + IN EFI_PHYSICAL_ADDRESS GhcbBase, + IN UINTN GhcbSize ) { - EFI_PHYSICAL_ADDRESS PhysicalAddress2M; - UINTN IndexOfPageDirectoryEntries; - PAGE_TABLE_ENTRY *PageDirectoryEntry; - UINT64 AddressEncMask; + EFI_PHYSICAL_ADDRESS PhysicalAddress2M; + UINTN IndexOfPageDirectoryEntries; + PAGE_TABLE_ENTRY *PageDirectoryEntry; + UINT64 AddressEncMask; // // Make sure AddressEncMask is contained to smallest supported address field @@ -409,23 +459,23 @@ Split1GPageTo2M ( // // Fill in 1G page entry. // - *PageEntry1G = (UINT64) (UINTN) PageDirectoryEntry | AddressEncMask | IA32_PG_P | IA32_PG_RW; + *PageEntry1G = (UINT64)(UINTN)PageDirectoryEntry | AddressEncMask | IA32_PG_P | IA32_PG_RW; PhysicalAddress2M = PhysicalAddress; for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PhysicalAddress2M += SIZE_2MB) { - if (ToSplitPageTable (PhysicalAddress2M, SIZE_2MB, StackBase, StackSize)) { + if (ToSplitPageTable (PhysicalAddress2M, SIZE_2MB, StackBase, StackSize, GhcbBase, GhcbSize)) { // // Need to split this 2M page that covers NULL or stack range. // - Split2MPageTo4K (PhysicalAddress2M, (UINT64 *) PageDirectoryEntry, StackBase, StackSize); + Split2MPageTo4K (PhysicalAddress2M, (UINT64 *)PageDirectoryEntry, StackBase, StackSize, GhcbBase, GhcbSize); } else { // // Fill in the Page Directory entries // - PageDirectoryEntry->Uint64 = (UINT64) PhysicalAddress2M | AddressEncMask; + PageDirectoryEntry->Uint64 = (UINT64)PhysicalAddress2M | AddressEncMask; PageDirectoryEntry->Bits.ReadWrite = 1; - PageDirectoryEntry->Bits.Present = 1; - PageDirectoryEntry->Bits.MustBe1 = 1; + PageDirectoryEntry->Bits.Present = 1; + PageDirectoryEntry->Bits.MustBe1 = 1; } } } @@ -440,9 +490,9 @@ Split1GPageTo2M ( **/ VOID SetPageTablePoolReadOnly ( - IN UINTN PageTableBase, - IN EFI_PHYSICAL_ADDRESS Address, - IN BOOLEAN Level4Paging + IN UINTN PageTableBase, + IN EFI_PHYSICAL_ADDRESS Address, + IN BOOLEAN Level4Paging ) { UINTN Index; @@ -482,13 +532,13 @@ SetPageTablePoolReadOnly ( LevelSize[3] = SIZE_1GB; LevelSize[4] = SIZE_512GB; - AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & - PAGING_1G_ADDRESS_MASK_64; - PageTable = (UINT64 *)(UINTN)PageTableBase; - PoolUnitSize = PAGE_TABLE_POOL_UNIT_SIZE; + AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & + PAGING_1G_ADDRESS_MASK_64; + PageTable = (UINT64 *)(UINTN)PageTableBase; + PoolUnitSize = PAGE_TABLE_POOL_UNIT_SIZE; for (Level = (Level4Paging) ? 4 : 3; Level > 0; --Level) { - Index = ((UINTN)RShiftU64 (Address, LevelShift[Level])); + Index = ((UINTN)RShiftU64 (Address, LevelShift[Level])); Index &= PAGING_PAE_INDEX_MASK; PageAttr = PageTable[Index]; @@ -516,14 +566,13 @@ SetPageTablePoolReadOnly ( ASSERT (Index < EFI_PAGE_SIZE/sizeof (UINT64)); PageTable[Index] &= ~(UINT64)IA32_PG_RW; - PoolUnitSize -= LevelSize[Level]; + PoolUnitSize -= LevelSize[Level]; ++Index; } } break; - } else { // // The smaller granularity of page must be needed. @@ -535,18 +584,20 @@ SetPageTablePoolReadOnly ( PhysicalAddress = PageAttr & LevelMask[Level]; for (EntryIndex = 0; - EntryIndex < EFI_PAGE_SIZE/sizeof (UINT64); - ++EntryIndex) { + EntryIndex < EFI_PAGE_SIZE/sizeof (UINT64); + ++EntryIndex) + { NewPageTable[EntryIndex] = PhysicalAddress | AddressEncMask | IA32_PG_P | IA32_PG_RW; if (Level > 2) { NewPageTable[EntryIndex] |= IA32_PG_PS; } + PhysicalAddress += LevelSize[Level - 1]; } PageTable[Index] = (UINT64)(UINTN)NewPageTable | AddressEncMask | - IA32_PG_P | IA32_PG_RW; + IA32_PG_P | IA32_PG_RW; PageTable = NewPageTable; } } @@ -561,31 +612,26 @@ SetPageTablePoolReadOnly ( **/ VOID EnablePageTableProtection ( - IN UINTN PageTableBase, - IN BOOLEAN Level4Paging + IN UINTN PageTableBase, + IN BOOLEAN Level4Paging ) { - PAGE_TABLE_POOL *HeadPool; - PAGE_TABLE_POOL *Pool; - UINT64 PoolSize; - EFI_PHYSICAL_ADDRESS Address; + PAGE_TABLE_POOL *HeadPool; + PAGE_TABLE_POOL *Pool; + UINT64 PoolSize; + EFI_PHYSICAL_ADDRESS Address; if (mPageTablePool == NULL) { return; } // - // Disable write protection, because we need to mark page table to be write - // protected. - // - AsmWriteCr0 (AsmReadCr0() & ~CR0_WP); - - // + // No need to clear CR0.WP since PageTableBase has't been written to CR3 yet. // SetPageTablePoolReadOnly might update mPageTablePool. It's safer to // remember original one in advance. // HeadPool = mPageTablePool; - Pool = HeadPool; + Pool = HeadPool; do { Address = (EFI_PHYSICAL_ADDRESS)(UINTN)Pool; PoolSize = Pool->Offset + EFI_PAGES_TO_SIZE (Pool->FreePages); @@ -596,9 +642,9 @@ EnablePageTableProtection ( // protection to them one by one. // while (PoolSize > 0) { - SetPageTablePoolReadOnly(PageTableBase, Address, Level4Paging); - Address += PAGE_TABLE_POOL_UNIT_SIZE; - PoolSize -= PAGE_TABLE_POOL_UNIT_SIZE; + SetPageTablePoolReadOnly (PageTableBase, Address, Level4Paging); + Address += PAGE_TABLE_POOL_UNIT_SIZE; + PoolSize -= PAGE_TABLE_POOL_UNIT_SIZE; } Pool = Pool->NextPool; @@ -607,7 +653,7 @@ EnablePageTableProtection ( // // Enable write protection, after page table attribute updated. // - AsmWriteCr0 (AsmReadCr0() | CR0_WP); + AsmWriteCr0 (AsmReadCr0 () | CR0_WP); } /** @@ -616,41 +662,50 @@ EnablePageTableProtection ( @param[in] StackBase Stack base address. @param[in] StackSize Stack size. + @param[in] GhcbBase GHCB base address. + @param[in] GhcbSize GHCB size. @return The address of 4 level page map. **/ UINTN CreateIdentityMappingPageTables ( - IN EFI_PHYSICAL_ADDRESS StackBase, - IN UINTN StackSize + IN EFI_PHYSICAL_ADDRESS StackBase, + IN UINTN StackSize, + IN EFI_PHYSICAL_ADDRESS GhcbBase, + IN UINTN GhcbSize ) { - UINT32 RegEax; - CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_ECX EcxFlags; - UINT32 RegEdx; - UINT8 PhysicalAddressBits; - EFI_PHYSICAL_ADDRESS PageAddress; - UINTN IndexOfPml5Entries; - UINTN IndexOfPml4Entries; - UINTN IndexOfPdpEntries; - UINTN IndexOfPageDirectoryEntries; - UINT32 NumberOfPml5EntriesNeeded; - UINT32 NumberOfPml4EntriesNeeded; - UINT32 NumberOfPdpEntriesNeeded; - 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; - UINTN TotalPagesNum; - UINTN BigPageAddress; - VOID *Hob; - BOOLEAN Page5LevelSupport; - BOOLEAN Page1GSupport; - PAGE_TABLE_1G_ENTRY *PageDirectory1GEntry; - UINT64 AddressEncMask; - IA32_CR4 Cr4; + UINT32 RegEax; + CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_ECX EcxFlags; + UINT32 RegEdx; + UINT8 PhysicalAddressBits; + EFI_PHYSICAL_ADDRESS PageAddress; + UINTN IndexOfPml5Entries; + UINTN IndexOfPml4Entries; + UINTN IndexOfPdpEntries; + UINTN IndexOfPageDirectoryEntries; + UINT32 NumberOfPml5EntriesNeeded; + UINT32 NumberOfPml4EntriesNeeded; + UINT32 NumberOfPdpEntriesNeeded; + 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; + UINTN TotalPagesNum; + UINTN BigPageAddress; + VOID *Hob; + BOOLEAN Page5LevelSupport; + BOOLEAN Page1GSupport; + PAGE_TABLE_1G_ENTRY *PageDirectory1GEntry; + UINT64 AddressEncMask; + IA32_CR4 Cr4; + + // + // Set PageMapLevel5Entry to suppress incorrect compiler/analyzer warnings + // + PageMapLevel5Entry = NULL; // // Make sure AddressEncMask is contained to smallest supported address field @@ -658,7 +713,7 @@ CreateIdentityMappingPageTables ( AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & PAGING_1G_ADDRESS_MASK_64; Page1GSupport = FALSE; - if (PcdGetBool(PcdUse1GPageTable)) { + if (PcdGetBool (PcdUse1GPageTable)) { AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL); if (RegEax >= 0x80000001) { AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx); @@ -673,12 +728,12 @@ CreateIdentityMappingPageTables ( // Hob = GetFirstHob (EFI_HOB_TYPE_CPU); if (Hob != NULL) { - PhysicalAddressBits = ((EFI_HOB_CPU *) Hob)->SizeOfMemorySpace; + 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; + PhysicalAddressBits = (UINT8)RegEax; } else { PhysicalAddressBits = 36; } @@ -687,8 +742,12 @@ CreateIdentityMappingPageTables ( Page5LevelSupport = FALSE; if (PcdGetBool (PcdUse5LevelPageTable)) { AsmCpuidEx ( - CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_SUB_LEAF_INFO, NULL, - &EcxFlags.Uint32, NULL, NULL + CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, + CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_SUB_LEAF_INFO, + NULL, + NULL, + &EcxFlags.Uint32, + NULL ); if (EcxFlags.Bits.FiveLevelPage != 0) { Page5LevelSupport = TRUE; @@ -703,7 +762,7 @@ CreateIdentityMappingPageTables ( // due to either unsupported by HW, or disabled by PCD. // ASSERT (PhysicalAddressBits <= 52); - if (!Page5LevelSupport && PhysicalAddressBits > 48) { + if (!Page5LevelSupport && (PhysicalAddressBits > 48)) { PhysicalAddressBits = 48; } @@ -712,19 +771,19 @@ CreateIdentityMappingPageTables ( // NumberOfPml5EntriesNeeded = 1; if (PhysicalAddressBits > 48) { - NumberOfPml5EntriesNeeded = (UINT32) LShiftU64 (1, PhysicalAddressBits - 48); - PhysicalAddressBits = 48; + NumberOfPml5EntriesNeeded = (UINT32)LShiftU64 (1, PhysicalAddressBits - 48); + PhysicalAddressBits = 48; } NumberOfPml4EntriesNeeded = 1; if (PhysicalAddressBits > 39) { - NumberOfPml4EntriesNeeded = (UINT32) LShiftU64 (1, PhysicalAddressBits - 39); - PhysicalAddressBits = 39; + NumberOfPml4EntriesNeeded = (UINT32)LShiftU64 (1, PhysicalAddressBits - 39); + PhysicalAddressBits = 39; } NumberOfPdpEntriesNeeded = 1; ASSERT (PhysicalAddressBits > 30); - NumberOfPdpEntriesNeeded = (UINT32) LShiftU64 (1, PhysicalAddressBits - 30); + NumberOfPdpEntriesNeeded = (UINT32)LShiftU64 (1, PhysicalAddressBits - 30); // // Pre-allocate big pages to avoid later allocations. @@ -742,17 +801,22 @@ CreateIdentityMappingPageTables ( TotalPagesNum--; } - DEBUG ((DEBUG_INFO, "Pml5=%u Pml4=%u Pdp=%u TotalPage=%Lu\n", - NumberOfPml5EntriesNeeded, NumberOfPml4EntriesNeeded, - NumberOfPdpEntriesNeeded, (UINT64)TotalPagesNum)); + DEBUG (( + DEBUG_INFO, + "Pml5=%u Pml4=%u Pdp=%u TotalPage=%Lu\n", + NumberOfPml5EntriesNeeded, + NumberOfPml4EntriesNeeded, + NumberOfPdpEntriesNeeded, + (UINT64)TotalPagesNum + )); - BigPageAddress = (UINTN) AllocatePageTableMemory (TotalPagesNum); + BigPageAddress = (UINTN)AllocatePageTableMemory (TotalPagesNum); ASSERT (BigPageAddress != 0); // // By architecture only one PageMapLevel4 exists - so lets allocate storage for it. // - PageMap = (VOID *) BigPageAddress; + PageMap = (VOID *)BigPageAddress; if (Page5LevelSupport) { // // By architecture only one PageMapLevel5 exists - so lets allocate storage for it. @@ -760,94 +824,98 @@ CreateIdentityMappingPageTables ( PageMapLevel5Entry = PageMap; BigPageAddress += SIZE_4KB; } - PageAddress = 0; + + PageAddress = 0; for ( IndexOfPml5Entries = 0 - ; IndexOfPml5Entries < NumberOfPml5EntriesNeeded - ; IndexOfPml5Entries++) { + ; IndexOfPml5Entries < NumberOfPml5EntriesNeeded + ; IndexOfPml5Entries++) + { // // Each PML5 entry points to a page of PML4 entires. // So lets allocate space for them and fill them in in the IndexOfPml4Entries loop. // When 5-Level Paging is disabled, below allocation happens only once. // - PageMapLevel4Entry = (VOID *) BigPageAddress; + PageMapLevel4Entry = (VOID *)BigPageAddress; BigPageAddress += SIZE_4KB; if (Page5LevelSupport) { // // Make a PML5 Entry // - PageMapLevel5Entry->Uint64 = (UINT64) (UINTN) PageMapLevel4Entry | AddressEncMask; + PageMapLevel5Entry->Uint64 = (UINT64)(UINTN)PageMapLevel4Entry | AddressEncMask; PageMapLevel5Entry->Bits.ReadWrite = 1; PageMapLevel5Entry->Bits.Present = 1; PageMapLevel5Entry++; } for ( IndexOfPml4Entries = 0 - ; IndexOfPml4Entries < (NumberOfPml5EntriesNeeded == 1 ? NumberOfPml4EntriesNeeded : 512) - ; IndexOfPml4Entries++, PageMapLevel4Entry++) { + ; IndexOfPml4Entries < (NumberOfPml5EntriesNeeded == 1 ? NumberOfPml4EntriesNeeded : 512) + ; IndexOfPml4Entries++, PageMapLevel4Entry++) + { // // Each PML4 entry points to a page of Page Directory Pointer entires. // So lets allocate space for them and fill them in in the IndexOfPdpEntries loop. // - PageDirectoryPointerEntry = (VOID *) BigPageAddress; - BigPageAddress += SIZE_4KB; + PageDirectoryPointerEntry = (VOID *)BigPageAddress; + BigPageAddress += SIZE_4KB; // // Make a PML4 Entry // - PageMapLevel4Entry->Uint64 = (UINT64)(UINTN)PageDirectoryPointerEntry | AddressEncMask; + PageMapLevel4Entry->Uint64 = (UINT64)(UINTN)PageDirectoryPointerEntry | AddressEncMask; PageMapLevel4Entry->Bits.ReadWrite = 1; - PageMapLevel4Entry->Bits.Present = 1; + PageMapLevel4Entry->Bits.Present = 1; if (Page1GSupport) { - PageDirectory1GEntry = (VOID *) PageDirectoryPointerEntry; + PageDirectory1GEntry = (VOID *)PageDirectoryPointerEntry; for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectory1GEntry++, PageAddress += SIZE_1GB) { - if (ToSplitPageTable (PageAddress, SIZE_1GB, StackBase, StackSize)) { - Split1GPageTo2M (PageAddress, (UINT64 *) PageDirectory1GEntry, StackBase, StackSize); + if (ToSplitPageTable (PageAddress, SIZE_1GB, StackBase, StackSize, GhcbBase, GhcbSize)) { + Split1GPageTo2M (PageAddress, (UINT64 *)PageDirectory1GEntry, StackBase, StackSize, GhcbBase, GhcbSize); } else { // // Fill in the Page Directory entries // - PageDirectory1GEntry->Uint64 = (UINT64)PageAddress | AddressEncMask; + PageDirectory1GEntry->Uint64 = (UINT64)PageAddress | AddressEncMask; PageDirectory1GEntry->Bits.ReadWrite = 1; - PageDirectory1GEntry->Bits.Present = 1; - PageDirectory1GEntry->Bits.MustBe1 = 1; + PageDirectory1GEntry->Bits.Present = 1; + PageDirectory1GEntry->Bits.MustBe1 = 1; } } } else { for ( IndexOfPdpEntries = 0 - ; IndexOfPdpEntries < (NumberOfPml4EntriesNeeded == 1 ? NumberOfPdpEntriesNeeded : 512) - ; IndexOfPdpEntries++, PageDirectoryPointerEntry++) { + ; IndexOfPdpEntries < (NumberOfPml4EntriesNeeded == 1 ? NumberOfPdpEntriesNeeded : 512) + ; IndexOfPdpEntries++, PageDirectoryPointerEntry++) + { // // Each Directory Pointer entries points to a page of Page Directory entires. // So allocate space for them and fill them in in the IndexOfPageDirectoryEntries loop. // - PageDirectoryEntry = (VOID *) BigPageAddress; - BigPageAddress += SIZE_4KB; + PageDirectoryEntry = (VOID *)BigPageAddress; + BigPageAddress += SIZE_4KB; // // Fill in a Page Directory Pointer Entries // - PageDirectoryPointerEntry->Uint64 = (UINT64)(UINTN)PageDirectoryEntry | AddressEncMask; + PageDirectoryPointerEntry->Uint64 = (UINT64)(UINTN)PageDirectoryEntry | AddressEncMask; PageDirectoryPointerEntry->Bits.ReadWrite = 1; - PageDirectoryPointerEntry->Bits.Present = 1; + PageDirectoryPointerEntry->Bits.Present = 1; for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PageAddress += SIZE_2MB) { - if (ToSplitPageTable (PageAddress, SIZE_2MB, StackBase, StackSize)) { + if (ToSplitPageTable (PageAddress, SIZE_2MB, StackBase, StackSize, GhcbBase, GhcbSize)) { // // Need to split this 2M page that covers NULL or stack range. // - Split2MPageTo4K (PageAddress, (UINT64 *) PageDirectoryEntry, StackBase, StackSize); + Split2MPageTo4K (PageAddress, (UINT64 *)PageDirectoryEntry, StackBase, StackSize, GhcbBase, GhcbSize); } else { // // Fill in the Page Directory entries // - PageDirectoryEntry->Uint64 = (UINT64)PageAddress | AddressEncMask; + PageDirectoryEntry->Uint64 = (UINT64)PageAddress | AddressEncMask; PageDirectoryEntry->Bits.ReadWrite = 1; - PageDirectoryEntry->Bits.Present = 1; - PageDirectoryEntry->Bits.MustBe1 = 1; + PageDirectoryEntry->Bits.Present = 1; + PageDirectoryEntry->Bits.MustBe1 = 1; } } } @@ -855,7 +923,7 @@ CreateIdentityMappingPageTables ( // // Fill with null entry for unused PDPTE // - ZeroMem (PageDirectoryPointerEntry, (512 - IndexOfPdpEntries) * sizeof(PAGE_MAP_AND_DIRECTORY_POINTER)); + ZeroMem (PageDirectoryPointerEntry, (512 - IndexOfPdpEntries) * sizeof (PAGE_MAP_AND_DIRECTORY_POINTER)); } } @@ -866,7 +934,7 @@ CreateIdentityMappingPageTables ( } if (Page5LevelSupport) { - Cr4.UintN = AsmReadCr4 (); + Cr4.UintN = AsmReadCr4 (); Cr4.Bits.LA57 = 1; AsmWriteCr4 (Cr4.UintN); // @@ -890,4 +958,3 @@ CreateIdentityMappingPageTables ( return (UINTN)PageMap; } -