From nobody Sun Feb 8 16:30:46 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+45127+1787277+3901457@groups.io; helo=web01.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+45127+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1565244902; cv=none; d=zoho.com; s=zohoarc; b=YapoLdKJvuwFpOyB9dW5MRSD1Z1mHIgNL7SzztfRIriadOkLDTZKvhJufyFM2vXUesUka+VcTKxNzvdQbBsZKem4+JBcWJwIdTlJOhDvF5mptnyunpIaCyFbl19g5sT/UY/ondR5tIgbPzvPsHYOW3x5YinnDg2Ls9BA5tlKeag= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1565244902; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Id:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To:ARC-Authentication-Results; bh=NcT7JUwlcd+0aPS2eyyvPiiVqy55r+lqCKtQaqUStnM=; b=FQ+LjEc3z9Jbt5Dm+PM1ZngcAowU374KKRHUThak64BSlWFZEYNZ9WJ/1SrfgcNftFOPIPv9kjkCo7FGAIu6RxkwamlNlSSNlA/K4NvrgKidObWqyxBeXehQ8JuNaN8ATQZ49ExlHT6cWFIlL4VrhQmSy+bDgjLajVRBlVznuUU= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+45127+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 1565244902448130.97340745128815; Wed, 7 Aug 2019 23:15:02 -0700 (PDT) Return-Path: X-Received: from mga14.intel.com (mga14.intel.com []) by groups.io with SMTP; Wed, 07 Aug 2019 23:15:01 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 07 Aug 2019 23:15:01 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,360,1559545200"; d="scan'208";a="198921320" X-Received: from ydong10-win10.ccr.corp.intel.com ([10.239.158.133]) by fmsmga004.fm.intel.com with ESMTP; 07 Aug 2019 23:14:59 -0700 From: "Dong, Eric" To: devel@edk2.groups.io Cc: "Ni, Ray" , Laszlo Ersek , Hao A Wu Subject: [edk2-devel] [Patch v5 7/9] MdeModulePkg/DxeIpl: Create 5-level page table for long mode Date: Thu, 8 Aug 2019 14:14:46 +0800 Message-Id: <20190808061448.14684-8-eric.dong@intel.com> In-Reply-To: <20190808061448.14684-1-eric.dong@intel.com> References: <20190808061448.14684-1-eric.dong@intel.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,eric.dong@intel.com Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1565244902; bh=3g8HBnZph+IXKh3rXd7agz+bjiQEDf7UVI+wl3ZoAN4=; h=Cc:Date:From:Reply-To:Subject:To; b=wRpe4ALEZYYfpx2Sqanb/fE6qo8vJa78mo+JYcL4JY31Ju2cBAf/j0eKC5BkDUtpIU4 GhUmNV7xUVuo/b/iawp7A6djtdif1EzAmR8Odms6zsoryVGbJvTXhtdmKc3R2MxAoieXL dxMRqbRhq6MFWY/N+IhVwtlRMjJxp+41o9k= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Type: text/plain; charset="utf-8" From: "Ni, Ray" REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D2008 DxeIpl is responsible to create page table for DXE phase running either in long mode or in 32bit mode with certain protection mechanism enabled (refer to ToBuildPageTable()). The patch updates DxeIpl to create 5-level page table for DXE phase running in long mode when PcdUse5LevelPageTable is TRUE and CPU supports 5-level page table. Signed-off-by: Ray Ni Reviewed-by: Eric Dong Regression-tested-by: Laszlo Ersek Reviewed-by: Hao A Wu Signed-off-by: Eric Dong --- MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf | 1 + .../Core/DxeIplPeim/X64/VirtualMemory.c | 229 ++++++++++++------ 2 files changed, 153 insertions(+), 77 deletions(-) diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf b/MdeModulePkg/Core/Dx= eIplPeim/DxeIpl.inf index abc3217b01..98bc17fc9d 100644 --- a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf +++ b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf @@ -110,6 +110,7 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask ##= CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask ##= CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ##= CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdUse5LevelPageTable ##= SOMETIMES_CONSUMES =20 [Pcd.IA32,Pcd.X64,Pcd.ARM,Pcd.AARCH64] gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack ## SOMETIM= ES_CONSUMES diff --git a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c b/MdeModulePk= g/Core/DxeIplPeim/X64/VirtualMemory.c index edc38e4525..b40b7e0c98 100644 --- a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c +++ b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c @@ -15,13 +15,14 @@ 2) IA-32 Intel(R) Architecture Software Developer's Manual Volume 2:In= struction Set Reference, Intel 3) IA-32 Intel(R) Architecture Software Developer's Manual Volume 3:Sy= stem Programmer's Guide, Intel =20 -Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
Copyright (c) 2017, AMD Incorporated. All rights reserved.
=20 SPDX-License-Identifier: BSD-2-Clause-Patent =20 **/ =20 +#include #include "DxeIpl.h" #include "VirtualMemory.h" =20 @@ -626,14 +627,18 @@ CreateIdentityMappingPageTables ( ) { UINT32 RegEax; + CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_ECX EcxFlags; UINT32 RegEdx; UINT8 PhysicalAddressBits; EFI_PHYSICAL_ADDRESS PageAddress; + UINTN IndexOfPml5Entries; UINTN IndexOfPml4Entries; UINTN IndexOfPdpEntries; UINTN IndexOfPageDirectoryEntrie= s; + 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; @@ -641,9 +646,11 @@ CreateIdentityMappingPageTables ( UINTN TotalPagesNum; UINTN BigPageAddress; VOID *Hob; + BOOLEAN Page5LevelSupport; BOOLEAN Page1GSupport; PAGE_TABLE_1G_ENTRY *PageDirectory1GEntry; UINT64 AddressEncMask; + IA32_CR4 Cr4; =20 // // Make sure AddressEncMask is contained to smallest supported address f= ield @@ -677,33 +684,68 @@ CreateIdentityMappingPageTables ( } } =20 + Page5LevelSupport =3D FALSE; + if (PcdGetBool (PcdUse5LevelPageTable)) { + AsmCpuidEx ( + CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, CPUID_STRUCTURED_EXTENDED_F= EATURE_FLAGS_SUB_LEAF_INFO, NULL, + &EcxFlags.Uint32, NULL, NULL + ); + if (EcxFlags.Bits.FiveLevelPage !=3D 0) { + Page5LevelSupport =3D TRUE; + } + } + + DEBUG ((DEBUG_INFO, "AddressBits=3D%u 5LevelPaging=3D%u 1GPage=3D%u\n", = PhysicalAddressBits, Page5LevelSupport, Page1GSupport)); + // - // IA-32e paging translates 48-bit linear addresses to 52-bit physical a= ddresses. + // IA-32e paging translates 48-bit linear addresses to 52-bit physical a= ddresses + // when 5-Level Paging is disabled, + // due to either unsupported by HW, or disabled by PCD. // ASSERT (PhysicalAddressBits <=3D 52); - if (PhysicalAddressBits > 48) { + if (!Page5LevelSupport && PhysicalAddressBits > 48) { PhysicalAddressBits =3D 48; } =20 // // Calculate the table entries needed. // - if (PhysicalAddressBits <=3D 39 ) { - NumberOfPml4EntriesNeeded =3D 1; - NumberOfPdpEntriesNeeded =3D (UINT32)LShiftU64 (1, (PhysicalAddressBit= s - 30)); - } else { - NumberOfPml4EntriesNeeded =3D (UINT32)LShiftU64 (1, (PhysicalAddressBi= ts - 39)); - NumberOfPdpEntriesNeeded =3D 512; + NumberOfPml5EntriesNeeded =3D 1; + if (PhysicalAddressBits > 48) { + NumberOfPml5EntriesNeeded =3D (UINT32) LShiftU64 (1, PhysicalAddressBi= ts - 48); + PhysicalAddressBits =3D 48; + } + + NumberOfPml4EntriesNeeded =3D 1; + if (PhysicalAddressBits > 39) { + NumberOfPml4EntriesNeeded =3D (UINT32) LShiftU64 (1, PhysicalAddressBi= ts - 39); + PhysicalAddressBits =3D 39; } =20 + NumberOfPdpEntriesNeeded =3D 1; + ASSERT (PhysicalAddressBits > 30); + NumberOfPdpEntriesNeeded =3D (UINT32) LShiftU64 (1, PhysicalAddressBits = - 30); + // // Pre-allocate big pages to avoid later allocations. // if (!Page1GSupport) { - TotalPagesNum =3D (NumberOfPdpEntriesNeeded + 1) * NumberOfPml4Entries= Needed + 1; + TotalPagesNum =3D ((NumberOfPdpEntriesNeeded + 1) * NumberOfPml4Entrie= sNeeded + 1) * NumberOfPml5EntriesNeeded + 1; } else { - TotalPagesNum =3D NumberOfPml4EntriesNeeded + 1; + TotalPagesNum =3D (NumberOfPml4EntriesNeeded + 1) * NumberOfPml5Entrie= sNeeded + 1; + } + + // + // Substract the one page occupied by PML5 entries if 5-Level Paging is = disabled. + // + if (!Page5LevelSupport) { + TotalPagesNum--; } + + DEBUG ((DEBUG_INFO, "Pml5=3D%u Pml4=3D%u Pdp=3D%u TotalPage=3D%Lu\n", + NumberOfPml5EntriesNeeded, NumberOfPml4EntriesNeeded, + NumberOfPdpEntriesNeeded, (UINT64)TotalPagesNum)); + BigPageAddress =3D (UINTN) AllocatePageTableMemory (TotalPagesNum); ASSERT (BigPageAddress !=3D 0); =20 @@ -711,92 +753,125 @@ CreateIdentityMappingPageTables ( // By architecture only one PageMapLevel4 exists - so lets allocate stor= age for it. // PageMap =3D (VOID *) BigPageAddress; - BigPageAddress +=3D SIZE_4KB; - - PageMapLevel4Entry =3D PageMap; - PageAddress =3D 0; - for (IndexOfPml4Entries =3D 0; IndexOfPml4Entries < NumberOfPml4EntriesN= eeded; IndexOfPml4Entries++, PageMapLevel4Entry++) { + if (Page5LevelSupport) { // - // Each PML4 entry points to a page of Page Directory Pointer entires. - // So lets allocate space for them and fill them in in the IndexOfPdpE= ntries loop. + // By architecture only one PageMapLevel5 exists - so lets allocate st= orage for it. // - PageDirectoryPointerEntry =3D (VOID *) BigPageAddress; - BigPageAddress +=3D SIZE_4KB; + PageMapLevel5Entry =3D PageMap; + BigPageAddress +=3D SIZE_4KB; + } + PageAddress =3D 0; =20 + for ( IndexOfPml5Entries =3D 0 + ; IndexOfPml5Entries < NumberOfPml5EntriesNeeded + ; IndexOfPml5Entries++, PageMapLevel5Entry++) { // - // Make a PML4 Entry + // Each PML5 entry points to a page of PML4 entires. + // So lets allocate space for them and fill them in in the IndexOfPml4= Entries loop. + // When 5-Level Paging is disabled, below allocation happens only once. // - PageMapLevel4Entry->Uint64 =3D (UINT64)(UINTN)PageDirectoryPointerEntr= y | AddressEncMask; - PageMapLevel4Entry->Bits.ReadWrite =3D 1; - PageMapLevel4Entry->Bits.Present =3D 1; + PageMapLevel4Entry =3D (VOID *) BigPageAddress; + BigPageAddress +=3D SIZE_4KB; =20 - if (Page1GSupport) { - PageDirectory1GEntry =3D (VOID *) PageDirectoryPointerEntry; + if (Page5LevelSupport) { + // + // Make a PML5 Entry + // + PageMapLevel5Entry->Uint64 =3D (UINT64) (UINTN) PageMapLevel4Entry |= AddressEncMask; + PageMapLevel5Entry->Bits.ReadWrite =3D 1; + PageMapLevel5Entry->Bits.Present =3D 1; + } =20 - for (IndexOfPageDirectoryEntries =3D 0; IndexOfPageDirectoryEntries = < 512; IndexOfPageDirectoryEntries++, PageDirectory1GEntry++, PageAddress += =3D SIZE_1GB) { - if (ToSplitPageTable (PageAddress, SIZE_1GB, StackBase, StackSize)= ) { - Split1GPageTo2M (PageAddress, (UINT64 *) PageDirectory1GEntry, S= tackBase, StackSize); - } else { - // - // Fill in the Page Directory entries - // - PageDirectory1GEntry->Uint64 =3D (UINT64)PageAddress | AddressEn= cMask; - PageDirectory1GEntry->Bits.ReadWrite =3D 1; - PageDirectory1GEntry->Bits.Present =3D 1; - PageDirectory1GEntry->Bits.MustBe1 =3D 1; - } - } - } else { - for (IndexOfPdpEntries =3D 0; IndexOfPdpEntries < NumberOfPdpEntries= Needed; IndexOfPdpEntries++, PageDirectoryPointerEntry++) { - // - // Each Directory Pointer entries points to a page of Page Directo= ry entires. - // So allocate space for them and fill them in in the IndexOfPageD= irectoryEntries loop. - // - PageDirectoryEntry =3D (VOID *) BigPageAddress; - BigPageAddress +=3D SIZE_4KB; + for ( IndexOfPml4Entries =3D 0 + ; IndexOfPml4Entries < (NumberOfPml5EntriesNeeded =3D=3D 1 ? Numbe= rOfPml4EntriesNeeded : 512) + ; IndexOfPml4Entries++, PageMapLevel4Entry++) { + // + // Each PML4 entry points to a page of Page Directory Pointer entire= s. + // So lets allocate space for them and fill them in in the IndexOfPd= pEntries loop. + // + PageDirectoryPointerEntry =3D (VOID *) BigPageAddress; + BigPageAddress +=3D SIZE_4KB; =20 - // - // Fill in a Page Directory Pointer Entries - // - PageDirectoryPointerEntry->Uint64 =3D (UINT64)(UINTN)PageDirectory= Entry | AddressEncMask; - PageDirectoryPointerEntry->Bits.ReadWrite =3D 1; - PageDirectoryPointerEntry->Bits.Present =3D 1; + // + // Make a PML4 Entry + // + PageMapLevel4Entry->Uint64 =3D (UINT64)(UINTN)PageDirectoryPointerEn= try | AddressEncMask; + PageMapLevel4Entry->Bits.ReadWrite =3D 1; + PageMapLevel4Entry->Bits.Present =3D 1; =20 - for (IndexOfPageDirectoryEntries =3D 0; IndexOfPageDirectoryEntrie= s < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PageAddress += =3D SIZE_2MB) { - if (ToSplitPageTable (PageAddress, SIZE_2MB, StackBase, StackSiz= e)) { - // - // Need to split this 2M page that covers NULL or stack range. - // - Split2MPageTo4K (PageAddress, (UINT64 *) PageDirectoryEntry, S= tackBase, StackSize); + if (Page1GSupport) { + PageDirectory1GEntry =3D (VOID *) PageDirectoryPointerEntry; + + for (IndexOfPageDirectoryEntries =3D 0; IndexOfPageDirectoryEntrie= s < 512; IndexOfPageDirectoryEntries++, PageDirectory1GEntry++, PageAddress= +=3D SIZE_1GB) { + if (ToSplitPageTable (PageAddress, SIZE_1GB, StackBase, StackSiz= e)) { + Split1GPageTo2M (PageAddress, (UINT64 *) PageDirectory1GEntry,= StackBase, StackSize); } else { // // Fill in the Page Directory entries // - PageDirectoryEntry->Uint64 =3D (UINT64)PageAddress | AddressEn= cMask; - PageDirectoryEntry->Bits.ReadWrite =3D 1; - PageDirectoryEntry->Bits.Present =3D 1; - PageDirectoryEntry->Bits.MustBe1 =3D 1; + PageDirectory1GEntry->Uint64 =3D (UINT64)PageAddress | Address= EncMask; + PageDirectory1GEntry->Bits.ReadWrite =3D 1; + PageDirectory1GEntry->Bits.Present =3D 1; + PageDirectory1GEntry->Bits.MustBe1 =3D 1; } } - } + } else { + for ( IndexOfPdpEntries =3D 0 + ; IndexOfPdpEntries < (NumberOfPml4EntriesNeeded =3D=3D 1 ? Nu= mberOfPdpEntriesNeeded : 512) + ; IndexOfPdpEntries++, PageDirectoryPointerEntry++) { + // + // Each Directory Pointer entries points to a page of Page Direc= tory entires. + // So allocate space for them and fill them in in the IndexOfPag= eDirectoryEntries loop. + // + PageDirectoryEntry =3D (VOID *) BigPageAddress; + BigPageAddress +=3D SIZE_4KB; =20 - for (; IndexOfPdpEntries < 512; IndexOfPdpEntries++, PageDirectoryPo= interEntry++) { - ZeroMem ( - PageDirectoryPointerEntry, - sizeof(PAGE_MAP_AND_DIRECTORY_POINTER) - ); + // + // Fill in a Page Directory Pointer Entries + // + PageDirectoryPointerEntry->Uint64 =3D (UINT64)(UINTN)PageDirecto= ryEntry | AddressEncMask; + PageDirectoryPointerEntry->Bits.ReadWrite =3D 1; + PageDirectoryPointerEntry->Bits.Present =3D 1; + + for (IndexOfPageDirectoryEntries =3D 0; IndexOfPageDirectoryEntr= ies < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PageAddress= +=3D SIZE_2MB) { + if (ToSplitPageTable (PageAddress, SIZE_2MB, StackBase, StackS= ize)) { + // + // Need to split this 2M page that covers NULL or stack rang= e. + // + Split2MPageTo4K (PageAddress, (UINT64 *) PageDirectoryEntry,= StackBase, StackSize); + } else { + // + // Fill in the Page Directory entries + // + PageDirectoryEntry->Uint64 =3D (UINT64)PageAddress | Address= EncMask; + PageDirectoryEntry->Bits.ReadWrite =3D 1; + PageDirectoryEntry->Bits.Present =3D 1; + PageDirectoryEntry->Bits.MustBe1 =3D 1; + } + } + } + + // + // Fill with null entry for unused PDPTE + // + ZeroMem (PageDirectoryPointerEntry, (512 - IndexOfPdpEntries) * si= zeof(PAGE_MAP_AND_DIRECTORY_POINTER)); } } + + // + // For the PML4 entries we are not using fill in a null entry. + // + ZeroMem (PageMapLevel4Entry, (512 - IndexOfPml4Entries) * sizeof (PAGE= _MAP_AND_DIRECTORY_POINTER)); } =20 - // - // For the PML4 entries we are not using fill in a null entry. - // - for (; IndexOfPml4Entries < 512; IndexOfPml4Entries++, PageMapLevel4Entr= y++) { - ZeroMem ( - PageMapLevel4Entry, - sizeof (PAGE_MAP_AND_DIRECTORY_POINTER) - ); + if (Page5LevelSupport) { + Cr4.UintN =3D AsmReadCr4 (); + Cr4.Bits.LA57 =3D 1; + AsmWriteCr4 (Cr4.UintN); + // + // For the PML5 entries we are not using fill in a null entry. + // + ZeroMem (PageMapLevel5Entry, (512 - IndexOfPml5Entries) * sizeof (PAGE= _MAP_AND_DIRECTORY_POINTER)); } =20 // --=20 2.21.0.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#45127): https://edk2.groups.io/g/devel/message/45127 Mute This Topic: https://groups.io/mt/32796010/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-