From: "duntan" <dun.tan@intel.com>
To: devel@edk2.groups.io
Cc: Ray Ni <ray.ni@intel.com>, Rahul Kumar <rahul1.kumar@intel.com>,
Gerd Hoffmann <kraxel@redhat.com>,
Jiaxin Wu <jiaxin.wu@intel.com>
Subject: [edk2-devel] [Patch V2 11/18] UefiCpuPkg:Move some code in DxeMpLib to common place
Date: Fri, 17 May 2024 17:46:03 +0800 [thread overview]
Message-ID: <20240517094610.533-12-dun.tan@intel.com> (raw)
In-Reply-To: <20240517094610.533-1-dun.tan@intel.com>
Move some code in DxeMpLib.C to common MpLib.c.
The related code is to relocate Ap to new safe buffer
before booting into OS. In next commits, these code
also will be used by PeiMpLib. This commit doesn't
change any code functionality.
Signed-off-by: Dun Tan <dun.tan@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Jiaxin Wu <jiaxin.wu@intel.com>
---
UefiCpuPkg/Library/MpInitLib/DxeMpLib.c | 151 +++++--------------------------------------------------------------------------------------------------------------------------------------------------
UefiCpuPkg/Library/MpInitLib/MpLib.c | 144 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
UefiCpuPkg/Library/MpInitLib/MpLib.h | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++--
3 files changed, 199 insertions(+), 149 deletions(-)
diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
index 5f0a87c024..f9c5c92c22 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
@@ -20,15 +20,11 @@
#define AP_SAFE_STACK_SIZE 128
-CPU_MP_DATA *mCpuMpData = NULL;
-EFI_EVENT mCheckAllApsEvent = NULL;
-EFI_EVENT mMpInitExitBootServicesEvent = NULL;
-EFI_EVENT mLegacyBootEvent = NULL;
-volatile BOOLEAN mStopCheckAllApsStatus = TRUE;
-RELOCATE_AP_LOOP_ENTRY mReservedApLoop;
-UINTN mReservedTopOfApStack;
-volatile UINT32 mNumberToFinish = 0;
-UINTN mApPageTable;
+CPU_MP_DATA *mCpuMpData = NULL;
+EFI_EVENT mCheckAllApsEvent = NULL;
+EFI_EVENT mMpInitExitBootServicesEvent = NULL;
+EFI_EVENT mLegacyBootEvent = NULL;
+volatile BOOLEAN mStopCheckAllApsStatus = TRUE;
//
// Begin wakeup buffer allocation below 0x88000
@@ -368,60 +364,6 @@ GetProtectedModeCS (
return Index * 8;
}
-/**
- Do sync on APs.
-
- @param[in, out] Buffer Pointer to private data buffer.
-**/
-VOID
-EFIAPI
-RelocateApLoop (
- IN OUT VOID *Buffer
- )
-{
- CPU_MP_DATA *CpuMpData;
- BOOLEAN MwaitSupport;
- UINTN ProcessorNumber;
- UINTN StackStart;
-
- MpInitLibWhoAmI (&ProcessorNumber);
- CpuMpData = GetCpuMpData ();
- MwaitSupport = IsMwaitSupport ();
- if (CpuMpData->UseSevEsAPMethod) {
- //
- // 64-bit AMD processors with SEV-ES
- //
- StackStart = CpuMpData->SevEsAPResetStackStart;
- mReservedApLoop.AmdSevEntry (
- MwaitSupport,
- CpuMpData->ApTargetCState,
- CpuMpData->PmCodeSegment,
- StackStart - ProcessorNumber * AP_SAFE_STACK_SIZE,
- (UINTN)&mNumberToFinish,
- CpuMpData->Pm16CodeSegment,
- CpuMpData->SevEsAPBuffer,
- CpuMpData->WakeupBuffer
- );
- } else {
- //
- // Intel processors (32-bit or 64-bit), 32-bit AMD processors, or 64-bit AMD processors without SEV-ES
- //
- StackStart = mReservedTopOfApStack;
- mReservedApLoop.GenericEntry (
- MwaitSupport,
- CpuMpData->ApTargetCState,
- StackStart - ProcessorNumber * AP_SAFE_STACK_SIZE,
- (UINTN)&mNumberToFinish,
- mApPageTable
- );
- }
-
- //
- // It should never reach here
- //
- ASSERT (FALSE);
-}
-
/**
Allocate buffer for ApLoopCode.
@@ -477,89 +419,6 @@ RemoveNxprotection (
}
}
-/**
- Prepare ApLoopCode.
-
- @param[in] CpuMpData Pointer to CpuMpData.
-**/
-VOID
-PrepareApLoopCode (
- IN CPU_MP_DATA *CpuMpData
- )
-{
- EFI_PHYSICAL_ADDRESS Address;
- MP_ASSEMBLY_ADDRESS_MAP *AddressMap;
- UINT8 *ApLoopFunc;
- UINTN ApLoopFuncSize;
- UINTN StackPages;
- UINTN FuncPages;
- IA32_CR0 Cr0;
-
- AddressMap = &CpuMpData->AddressMap;
- if (CpuMpData->UseSevEsAPMethod) {
- //
- // 64-bit AMD processors with SEV-ES
- //
- Address = BASE_4GB - 1;
- ApLoopFunc = AddressMap->RelocateApLoopFuncAddressAmdSev;
- ApLoopFuncSize = AddressMap->RelocateApLoopFuncSizeAmdSev;
- } else {
- //
- // Intel processors (32-bit or 64-bit), 32-bit AMD processors, or 64-bit AMD processors without SEV-ES
- //
- Address = MAX_ADDRESS;
- ApLoopFunc = AddressMap->RelocateApLoopFuncAddressGeneric;
- ApLoopFuncSize = AddressMap->RelocateApLoopFuncSizeGeneric;
- }
-
- //
- // Avoid APs access invalid buffer data which allocated by BootServices,
- // so we will allocate reserved data for AP loop code. We also need to
- // allocate this buffer below 4GB due to APs may be transferred to 32bit
- // protected mode on long mode DXE.
- // Allocating it in advance since memory services are not available in
- // Exit Boot Services callback function.
- //
- // +------------+ (TopOfApStack)
- // | Stack * N |
- // +------------+ (stack base, 4k aligned)
- // | Padding |
- // +------------+
- // | Ap Loop |
- // +------------+ ((low address, 4k-aligned)
- //
-
- StackPages = EFI_SIZE_TO_PAGES (CpuMpData->CpuCount * AP_SAFE_STACK_SIZE);
- FuncPages = EFI_SIZE_TO_PAGES (ApLoopFuncSize);
-
- AllocateApLoopCodeBuffer (StackPages + FuncPages, &Address);
- ASSERT (Address != 0);
-
- Cr0.UintN = AsmReadCr0 ();
- if (Cr0.Bits.PG != 0) {
- //
- // Make sure that the buffer memory is executable if NX protection is enabled
- // for EfiReservedMemoryType.
- //
- RemoveNxprotection (Address, EFI_PAGES_TO_SIZE (FuncPages));
- }
-
- mReservedTopOfApStack = (UINTN)Address + EFI_PAGES_TO_SIZE (StackPages+FuncPages);
- ASSERT ((mReservedTopOfApStack & (UINTN)(CPU_STACK_ALIGNMENT - 1)) == 0);
- mReservedApLoop.Data = (VOID *)(UINTN)Address;
- ASSERT (mReservedApLoop.Data != NULL);
- CopyMem (mReservedApLoop.Data, ApLoopFunc, ApLoopFuncSize);
- if (!CpuMpData->UseSevEsAPMethod) {
- //
- // processors without SEV-ES and paging is enabled
- //
- mApPageTable = CreatePageTable (
- (UINTN)Address,
- EFI_PAGES_TO_SIZE (StackPages+FuncPages)
- );
- }
-}
-
/**
Callback function for ExitBootServices.
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index d724456502..cbd43c776a 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -1,7 +1,7 @@
/** @file
CPU MP Initialize Library common functions.
- Copyright (c) 2016 - 2022, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2016 - 2024, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2020 - 2024, AMD Inc. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -17,6 +17,11 @@ EFI_GUID mCpuInitMpLibHobGuid = CPU_INIT_MP_LIB_HOB_GUID;
EFI_GUID mMpHandOffGuid = MP_HANDOFF_GUID;
EFI_GUID mMpHandOffConfigGuid = MP_HANDOFF_CONFIG_GUID;
+RELOCATE_AP_LOOP_ENTRY mReservedApLoop;
+UINTN mReservedTopOfApStack;
+volatile UINT32 mNumberToFinish = 0;
+UINTN mApPageTable;
+
/**
Save the volatile registers required to be restored following INIT IPI.
@@ -3227,3 +3232,140 @@ ConfidentialComputingGuestHas (
return (CurrentAttr == Attr);
}
+
+/**
+ Do sync on APs.
+
+ @param[in, out] Buffer Pointer to private data buffer.
+**/
+VOID
+EFIAPI
+RelocateApLoop (
+ IN OUT VOID *Buffer
+ )
+{
+ CPU_MP_DATA *CpuMpData;
+ BOOLEAN MwaitSupport;
+ UINTN ProcessorNumber;
+ UINTN StackStart;
+
+ MpInitLibWhoAmI (&ProcessorNumber);
+ CpuMpData = GetCpuMpData ();
+ MwaitSupport = IsMwaitSupport ();
+ if (CpuMpData->UseSevEsAPMethod) {
+ //
+ // 64-bit AMD processors with SEV-ES
+ //
+ StackStart = CpuMpData->SevEsAPResetStackStart;
+ mReservedApLoop.AmdSevEntry (
+ MwaitSupport,
+ CpuMpData->ApTargetCState,
+ CpuMpData->PmCodeSegment,
+ StackStart - ProcessorNumber * AP_SAFE_STACK_SIZE,
+ (UINTN)&mNumberToFinish,
+ CpuMpData->Pm16CodeSegment,
+ CpuMpData->SevEsAPBuffer,
+ CpuMpData->WakeupBuffer
+ );
+ } else {
+ //
+ // Intel processors (32-bit or 64-bit), 32-bit AMD processors, or 64-bit AMD processors without SEV-ES
+ //
+ StackStart = mReservedTopOfApStack;
+ mReservedApLoop.GenericEntry (
+ MwaitSupport,
+ CpuMpData->ApTargetCState,
+ StackStart - ProcessorNumber * AP_SAFE_STACK_SIZE,
+ (UINTN)&mNumberToFinish,
+ mApPageTable
+ );
+ }
+
+ //
+ // It should never reach here
+ //
+ ASSERT (FALSE);
+}
+
+/**
+ Prepare ApLoopCode.
+
+ @param[in] CpuMpData Pointer to CpuMpData.
+**/
+VOID
+PrepareApLoopCode (
+ IN CPU_MP_DATA *CpuMpData
+ )
+{
+ EFI_PHYSICAL_ADDRESS Address;
+ MP_ASSEMBLY_ADDRESS_MAP *AddressMap;
+ UINT8 *ApLoopFunc;
+ UINTN ApLoopFuncSize;
+ UINTN StackPages;
+ UINTN FuncPages;
+ IA32_CR0 Cr0;
+
+ AddressMap = &CpuMpData->AddressMap;
+ if (CpuMpData->UseSevEsAPMethod) {
+ //
+ // 64-bit AMD processors with SEV-ES
+ //
+ Address = BASE_4GB - 1;
+ ApLoopFunc = AddressMap->RelocateApLoopFuncAddressAmdSev;
+ ApLoopFuncSize = AddressMap->RelocateApLoopFuncSizeAmdSev;
+ } else {
+ //
+ // Intel processors (32-bit or 64-bit), 32-bit AMD processors, or 64-bit AMD processors without SEV-ES
+ //
+ Address = MAX_ADDRESS;
+ ApLoopFunc = AddressMap->RelocateApLoopFuncAddressGeneric;
+ ApLoopFuncSize = AddressMap->RelocateApLoopFuncSizeGeneric;
+ }
+
+ //
+ // Avoid APs access invalid buffer data which allocated by BootServices,
+ // so we will allocate reserved data for AP loop code. We also need to
+ // allocate this buffer below 4GB due to APs may be transferred to 32bit
+ // protected mode on long mode DXE.
+ // Allocating it in advance since memory services are not available in
+ // Exit Boot Services callback function.
+ //
+ // +------------+ (TopOfApStack)
+ // | Stack * N |
+ // +------------+ (stack base, 4k aligned)
+ // | Padding |
+ // +------------+
+ // | Ap Loop |
+ // +------------+ ((low address, 4k-aligned)
+ //
+
+ StackPages = EFI_SIZE_TO_PAGES (CpuMpData->CpuCount * AP_SAFE_STACK_SIZE);
+ FuncPages = EFI_SIZE_TO_PAGES (ApLoopFuncSize);
+
+ AllocateApLoopCodeBuffer (StackPages + FuncPages, &Address);
+ ASSERT (Address != 0);
+
+ Cr0.UintN = AsmReadCr0 ();
+ if (Cr0.Bits.PG != 0) {
+ //
+ // Make sure that the buffer memory is executable if NX protection is enabled
+ // for EfiReservedMemoryType.
+ //
+ RemoveNxprotection (Address, EFI_PAGES_TO_SIZE (FuncPages));
+ }
+
+ mReservedTopOfApStack = (UINTN)Address + EFI_PAGES_TO_SIZE (StackPages+FuncPages);
+ ASSERT ((mReservedTopOfApStack & (UINTN)(CPU_STACK_ALIGNMENT - 1)) == 0);
+ mReservedApLoop.Data = (VOID *)(UINTN)Address;
+ ASSERT (mReservedApLoop.Data != NULL);
+ CopyMem (mReservedApLoop.Data, ApLoopFunc, ApLoopFuncSize);
+ if (!CpuMpData->UseSevEsAPMethod) {
+ //
+ // processors without SEV-ES and paging is enabled
+ //
+ mApPageTable = CreatePageTable (
+ (UINTN)Address,
+ EFI_PAGES_TO_SIZE (StackPages+FuncPages)
+ );
+ }
+}
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index 179f8e585b..a4a33bf538 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -1,7 +1,7 @@
/** @file
Common header file for MP Initialize Library.
- Copyright (c) 2016 - 2023, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2016 - 2024, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2020 - 2024, AMD Inc. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -357,7 +357,8 @@ typedef
IN UINTN StackStart
);
-extern EFI_GUID mCpuInitMpLibHobGuid;
+extern EFI_GUID mCpuInitMpLibHobGuid;
+extern volatile UINT32 mNumberToFinish;
/**
Assembly code to place AP into safe loop mode.
@@ -933,4 +934,52 @@ AmdSevUpdateCpuMpData (
IN CPU_MP_DATA *CpuMpData
);
+/**
+ Prepare ApLoopCode.
+
+ @param[in] CpuMpData Pointer to CpuMpData.
+**/
+VOID
+PrepareApLoopCode (
+ IN CPU_MP_DATA *CpuMpData
+ );
+
+/**
+ Do sync on APs.
+
+ @param[in, out] Buffer Pointer to private data buffer.
+**/
+VOID
+EFIAPI
+RelocateApLoop (
+ IN OUT VOID *Buffer
+ );
+
+/**
+ Allocate buffer for ApLoopCode.
+
+ @param[in] Pages Number of pages to allocate.
+ @param[in, out] Address Pointer to the allocated buffer.
+**/
+VOID
+AllocateApLoopCodeBuffer (
+ IN UINTN Pages,
+ IN OUT EFI_PHYSICAL_ADDRESS *Address
+ );
+
+/**
+ Remove Nx protection for the range specific by BaseAddress and Length.
+
+ The PEI implementation uses CpuPageTableLib to change the attribute.
+ The DXE implementation uses gDS to change the attribute.
+
+ @param[in] BaseAddress BaseAddress of the range.
+ @param[in] Length Length of the range.
+**/
+VOID
+RemoveNxprotection (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINTN Length
+ );
+
#endif
--
2.31.1.windows.1
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#119008): https://edk2.groups.io/g/devel/message/119008
Mute This Topic: https://groups.io/mt/106150770/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
next prev parent reply other threads:[~2024-05-17 9:47 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-05-17 9:45 [edk2-devel] [Patch V2 00/18] Remove some S3 related code in CpuS3.c of smm cpu driver duntan
2024-05-17 9:45 ` [edk2-devel] [Patch V2 01/18] MdeModulePkg: Add gEdkiiS3MtrrSettingGuid duntan
2024-05-17 9:45 ` [edk2-devel] [Patch V2 02/18] OvmfPkg: Save MTRR by lockbox in CpuS3DataDxe duntan
2024-05-17 9:45 ` [edk2-devel] [Patch V2 03/18] UefiCpuPkg: Add locbox lib instance in DSC duntan
2024-05-17 9:45 ` [edk2-devel] [Patch V2 04/18] UefiCpuPkg: Save MTRR by lockbox in CpuS3DataDxe duntan
2024-05-17 9:45 ` [edk2-devel] [Patch V2 05/18] UefiCpuPkg: LoadMtrrData for all cpu in S3Resume duntan
2024-05-17 9:45 ` [edk2-devel] [Patch V2 06/18] UefiCpuPkg: Remove code to load mtrr setting duntan
2024-05-17 9:45 ` [edk2-devel] [Patch V2 07/18] UefiCpuPkg:Set PcdCpuFeaturesInitOnS3Resume to TRUE duntan
2024-05-17 9:46 ` [edk2-devel] [Patch V2 08/18] UefiCpuPkg: Remove code to set register table duntan
2024-05-17 9:46 ` [edk2-devel] [Patch V2 09/18] UefiCpuPkg: Disable PG in IA32 ApLoopCode duntan
2024-05-17 9:46 ` [edk2-devel] [Patch V2 10/18] UefiCpuPkg:Abstract some DxeMpLib code to function duntan
2024-05-17 9:46 ` duntan [this message]
2024-05-17 9:46 ` [edk2-devel] [Patch V2 12/18] UefiCpuPkg: Install gEdkiiEndOfS3ResumeGuid in S3Resume duntan
2024-05-17 9:46 ` [edk2-devel] [Patch V2 13/18] UefiCpuPkg:Relocate AP to new safe buffer in PeiMpLib duntan
2024-05-17 9:46 ` [edk2-devel] [Patch V2 14/18] UefiCpuPkg:Remove code to handle APIC setting and Interrupt duntan
2024-05-17 9:46 ` [edk2-devel] [Patch V2 15/18] UefiCpuPkg:Remove code to wakeup AP and relocate ap duntan
2024-05-17 9:46 ` [edk2-devel] [Patch V2 16/18] UefiCpuPkg: Remove unneeded MpService2Ppi assignment duntan
2024-05-17 9:46 ` [edk2-devel] [Patch V2 17/18] MdeModulePkg:Remove MpService2Ppi field in SMM_S3_RESUME_STATE duntan
2024-05-17 9:46 ` [edk2-devel] [Patch V2 18/18] UefiCpuPkg: Remove GetAcpiCpuData() in CpuS3.c duntan
2024-05-20 7:05 ` [edk2-devel] [Patch V2 00/18] Remove some S3 related code in CpuS3.c of smm cpu driver Ni, Ray
2024-05-24 3:18 ` duntan
2024-05-24 3:07 ` Wu, Jiaxin
[not found] ` <17D03DA5161A67E3.17823@groups.io>
2024-05-28 6:35 ` [edk2-devel] [Patch V2 17/18] MdeModulePkg:Remove MpService2Ppi field in SMM_S3_RESUME_STATE duntan
2024-05-28 9:16 ` 回复: " gaoliming via groups.io
2024-05-28 9:34 ` duntan
2024-05-28 9:39 ` 回复: " gaoliming via groups.io
2024-05-28 9:44 ` duntan
2024-05-30 5:00 ` 回复: " gaoliming via groups.io
[not found] ` <17D03D9CBFB2693B.16299@groups.io>
2024-05-28 6:37 ` [edk2-devel] [Patch V2 01/18] MdeModulePkg: Add gEdkiiS3MtrrSettingGuid duntan
2024-05-28 9:14 ` 回复: " gaoliming via groups.io
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=20240517094610.533-12-dun.tan@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