From: "Wu, Jiaxin" <jiaxin.wu@intel.com>
To: devel@edk2.groups.io
Cc: Eric Dong <eric.dong@intel.com>, Ray Ni <ray.ni@intel.com>,
Zeng Star <star.zeng@intel.com>,
Gerd Hoffmann <kraxel@redhat.com>,
Rahul Kumar <rahul1.kumar@intel.com>
Subject: [PATCH v3 2/5] UefiCpuPkg/CpuMpPei: Conditionally enable PAE paging in 32bit mode
Date: Mon, 15 May 2023 10:15:58 +0800 [thread overview]
Message-ID: <20230515021601.6244-3-jiaxin.wu@intel.com> (raw)
In-Reply-To: <20230515021601.6244-1-jiaxin.wu@intel.com>
Some security features depend on the page table enabling. So, This
patch is to enable paging if it is not enabled (32bit mode)"
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Zeng Star <star.zeng@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Signed-off-by: Jiaxin Wu <jiaxin.wu@intel.com>
---
UefiCpuPkg/CpuMpPei/CpuMpPei.h | 1 +
UefiCpuPkg/CpuMpPei/CpuMpPei.inf | 1 +
UefiCpuPkg/CpuMpPei/CpuPaging.c | 202 ++++++++++++++-------------------------
3 files changed, 75 insertions(+), 129 deletions(-)
diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.h b/UefiCpuPkg/CpuMpPei/CpuMpPei.h
index 0649c48d14..1b9a94e18f 100644
--- a/UefiCpuPkg/CpuMpPei/CpuMpPei.h
+++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.h
@@ -26,10 +26,11 @@
#include <Library/ReportStatusCodeLib.h>
#include <Library/CpuExceptionHandlerLib.h>
#include <Library/MpInitLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
+#include <Library/CpuPageTableLib.h>
extern EFI_PEI_PPI_DESCRIPTOR mPeiCpuMpPpiDesc;
/**
This service retrieves the number of logical processor in the platform
diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.inf b/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
index 7444bdb968..865be5627e 100644
--- a/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
+++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
@@ -44,10 +44,11 @@
CpuExceptionHandlerLib
MpInitLib
BaseMemoryLib
CpuLib
MemoryAllocationLib
+ CpuPageTableLib
[Guids]
gEdkiiMigratedFvInfoGuid ## SOMETIMES_CONSUMES ## HOB
[Ppis]
diff --git a/UefiCpuPkg/CpuMpPei/CpuPaging.c b/UefiCpuPkg/CpuMpPei/CpuPaging.c
index a471f089c8..976a912741 100644
--- a/UefiCpuPkg/CpuMpPei/CpuPaging.c
+++ b/UefiCpuPkg/CpuMpPei/CpuPaging.c
@@ -115,42 +115,10 @@ AllocatePageTableMemory (
}
return Address;
}
-/**
- Get the address width supported by current processor.
-
- @retval 32 If processor is in 32-bit mode.
- @retval 36-48 If processor is in 64-bit mode.
-
-**/
-UINTN
-GetPhysicalAddressWidth (
- VOID
- )
-{
- UINT32 RegEax;
-
- if (sizeof (UINTN) == 4) {
- return 32;
- }
-
- AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
- if (RegEax >= CPUID_VIR_PHY_ADDRESS_SIZE) {
- AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &RegEax, NULL, NULL, NULL);
- RegEax &= 0xFF;
- if (RegEax > 48) {
- return 48;
- }
-
- return (UINTN)RegEax;
- }
-
- return 36;
-}
-
/**
Get the type of top level page table.
@retval Page512G PML4 paging.
@retval Page1G PAE paging.
@@ -381,120 +349,84 @@ ConvertMemoryPageAttributes (
return RETURN_SUCCESS;
}
/**
- Get maximum size of page memory supported by current processor.
-
- @param[in] TopLevelType The type of top level page entry.
-
- @retval Page1G If processor supports 1G page and PML4.
- @retval Page2M For all other situations.
-
-**/
-PAGE_ATTRIBUTE
-GetMaxMemoryPage (
- IN PAGE_ATTRIBUTE TopLevelType
- )
-{
- UINT32 RegEax;
- UINT32 RegEdx;
-
- if (TopLevelType == Page512G) {
- AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
- if (RegEax >= CPUID_EXTENDED_CPU_SIG) {
- AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &RegEdx);
- if ((RegEdx & BIT26) != 0) {
- return Page1G;
- }
- }
- }
-
- return Page2M;
-}
-
-/**
- Create PML4 or PAE page table.
+ Enable PAE Page Table.
- @return The address of page table.
+ @retval EFI_SUCCESS The PAE Page Table was enabled successfully.
+ @retval EFI_OUT_OF_RESOURCES The PAE Page Table could not be enabled due to lack of available memory.
**/
-UINTN
-CreatePageTable (
+EFI_STATUS
+EnablePaePageTable (
VOID
)
{
- RETURN_STATUS Status;
- UINTN PhysicalAddressBits;
- UINTN NumberOfEntries;
- PAGE_ATTRIBUTE TopLevelPageAttr;
- UINTN PageTable;
- PAGE_ATTRIBUTE MaxMemoryPage;
- UINTN Index;
- UINT64 AddressEncMask;
- UINT64 *PageEntry;
- EFI_PHYSICAL_ADDRESS PhysicalAddress;
+ EFI_STATUS Status;
+
+ UINTN PageTable;
+ VOID *Buffer;
+ UINTN BufferSize;
+ IA32_MAP_ATTRIBUTE MapAttribute;
+ IA32_MAP_ATTRIBUTE MapMask;
+
+ PageTable = 0;
+ Buffer = NULL;
+ BufferSize = 0;
+ MapAttribute.Uint64 = 0;
+ MapMask.Uint64 = MAX_UINT64;
+ MapAttribute.Bits.Present = 1;
+ MapAttribute.Bits.ReadWrite = 1;
- TopLevelPageAttr = (PAGE_ATTRIBUTE)GetPageTableTopLevelType ();
- PhysicalAddressBits = GetPhysicalAddressWidth ();
- NumberOfEntries = (UINTN)1 << (PhysicalAddressBits -
- mPageAttributeTable[TopLevelPageAttr].AddressBitOffset);
-
- PageTable = (UINTN)AllocatePageTableMemory (1);
- if (PageTable == 0) {
- return 0;
+ //
+ // 1:1 map 4GB in 32bit mode
+ //
+ Status = PageTableMap (&PageTable, PagingPae, 0, &BufferSize, 0, SIZE_4GB, &MapAttribute, &MapMask, NULL);
+ ASSERT (Status == EFI_BUFFER_TOO_SMALL);
+ if (Status != EFI_BUFFER_TOO_SMALL) {
+ return Status;
}
- AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask);
- AddressEncMask &= mPageAttributeTable[TopLevelPageAttr].AddressMask;
- MaxMemoryPage = GetMaxMemoryPage (TopLevelPageAttr);
- PageEntry = (UINT64 *)PageTable;
-
- PhysicalAddress = 0;
- for (Index = 0; Index < NumberOfEntries; ++Index) {
- *PageEntry = PhysicalAddress | AddressEncMask | PAGE_ATTRIBUTE_BITS;
+ //
+ // Allocate required Buffer.
+ //
+ Buffer = AllocatePageTableMemory (EFI_SIZE_TO_PAGES (BufferSize));
+ ASSERT (Buffer != NULL);
+ if (Buffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
- //
- // Split the top page table down to the maximum page size supported
- //
- if (MaxMemoryPage < TopLevelPageAttr) {
- Status = SplitPage (PageEntry, TopLevelPageAttr, MaxMemoryPage, TRUE);
- ASSERT_EFI_ERROR (Status);
- }
+ Status = PageTableMap (&PageTable, PagingPae, Buffer, &BufferSize, 0, SIZE_4GB, &MapAttribute, &MapMask, NULL);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status) || (PageTable == 0)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
- if (TopLevelPageAttr == Page1G) {
- //
- // PDPTE[2:1] (PAE Paging) must be 0. SplitPage() might change them to 1.
- //
- *PageEntry &= ~(UINT64)(IA32_PG_RW | IA32_PG_U);
- }
+ //
+ // Write the Pagetable to CR3.
+ //
+ AsmWriteCr3 (PageTable);
- PageEntry += 1;
- PhysicalAddress += mPageAttributeTable[TopLevelPageAttr].Length;
- }
+ //
+ // Enable CR4.PAE
+ //
+ AsmWriteCr4 (AsmReadCr4 () | BIT5);
- return PageTable;
-}
+ //
+ // Enable CR0.PG
+ //
+ AsmWriteCr0 (AsmReadCr0 () | BIT31);
-/**
- Setup page tables and make them work.
+ DEBUG ((
+ DEBUG_INFO,
+ "EnablePaePageTable: Created PageTable = 0x%x, BufferSize = %x\n",
+ PageTable,
+ BufferSize
+ ));
-**/
-VOID
-EnablePaging (
- VOID
- )
-{
- UINTN PageTable;
-
- PageTable = CreatePageTable ();
- ASSERT (PageTable != 0);
- if (PageTable != 0) {
- AsmWriteCr3 (PageTable);
- AsmWriteCr4 (AsmReadCr4 () | BIT5); // CR4.PAE
- AsmWriteCr0 (AsmReadCr0 () | BIT31); // CR0.PG
- }
+ return Status;
}
/**
Get the base address of current AP's stack.
@@ -622,10 +554,11 @@ MemoryDiscoveredPpiNotifyCallback (
{
EFI_STATUS Status;
BOOLEAN InitStackGuard;
EDKII_MIGRATED_FV_INFO *MigratedFvInfo;
EFI_PEI_HOB_POINTERS Hob;
+ IA32_CR0 Cr0;
//
// Paging must be setup first. Otherwise the exception TSS setup during MP
// initialization later will not contain paging information and then fail
// the task switch (for the sake of stack switch).
@@ -635,12 +568,23 @@ MemoryDiscoveredPpiNotifyCallback (
if (IsIa32PaeSupported ()) {
Hob.Raw = GetFirstGuidHob (&gEdkiiMigratedFvInfoGuid);
InitStackGuard = PcdGetBool (PcdCpuStackGuard);
}
- if (InitStackGuard || (Hob.Raw != NULL)) {
- EnablePaging ();
+ //
+ // Some security features depend on the page table enabling. So, here
+ // is to enable paging if it is not enabled (only in 32bit mode).
+ //
+ Cr0.UintN = AsmReadCr0 ();
+ if ((Cr0.Bits.PG == 0) && (InitStackGuard || (Hob.Raw != NULL))) {
+ ASSERT (sizeof (UINTN) == sizeof (UINT32));
+
+ Status = EnablePaePageTable ();
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "MemoryDiscoveredPpiNotifyCallback: Failed to enable PAE page table: %r.\n", Status));
+ CpuDeadLoop ();
+ }
}
Status = InitializeCpuMpWorker ((CONST EFI_PEI_SERVICES **)PeiServices);
ASSERT_EFI_ERROR (Status);
--
2.16.2.windows.1
next prev parent reply other threads:[~2023-05-15 2:16 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-05-15 2:15 [PATCH v3 0/5] Target to enable paging from temporary RAM Done Wu, Jiaxin
2023-05-15 2:15 ` [PATCH v3 1/5] UefiCpuPkg/SecCore: Migrate page table to permanent memory Wu, Jiaxin
2023-05-17 2:25 ` Ni, Ray
2023-05-15 2:15 ` Wu, Jiaxin [this message]
2023-05-15 2:15 ` [PATCH v3 3/5] MdeModulePkg/DxeIpl: Align Page table Level setting with previous level Wu, Jiaxin
2023-05-15 2:16 ` [PATCH v3 4/5] OvmfPkg: Add CpuPageTableLib required by SecCore & CpuMpPei Wu, Jiaxin
2023-05-15 2:16 ` [PATCH v3 5/5] UefiPayloadPkg: " Wu, Jiaxin
2023-05-15 2:22 ` Guo, Gua
2023-05-17 7:00 ` [edk2-devel] [PATCH v3 0/5] Target to enable paging from temporary RAM Done Ni, Ray
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230515021601.6244-3-jiaxin.wu@intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox