Re: [edk2-devel] [PATCH 10/18] UefiCpuPkg:Relocate AP to new safe buffer in PeiMpLib
On Tue, May 14, 2024 at 05:17:51AM GMT, Ni, Ray wrote: > Gerd, > I agree that the logic might be duplicated in multi places. > > But even CPU supports 1G paging, caller can decide whether to use 1G paging > or 2M paging, or 4K paging. > Using a single API to encapsulate the entire logic may not seem flexible. Sure, I don't want take away that flexibility. A caller might also prepare page tables for a paging mode not matching the current CPU paging mode (i.e. 32-bit PEI preparing page tables for 64-bit DXE). > Maybe, a lib API to detect 1G paging capability can be added to CpuLib. Yep, that is exactly what I think would be useful. Add a PAGING_MODE PageTableBestMode(VOID); function with this code to CpuPageTableLib, so callers have the option to use PagingMode = PageTableBestMode(); instead of duplicating the code block. take care, Gerd -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#118881): https://edk2.groups.io/g/devel/message/118881 Mute This Topic: https://groups.io/mt/106018135/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-
Re: [edk2-devel] [PATCH 10/18] UefiCpuPkg:Relocate AP to new safe buffer in PeiMpLib
Gerd, I agree that the logic might be duplicated in multi places. But even CPU supports 1G paging, caller can decide whether to use 1G paging or 2M paging, or 4K paging. Using a single API to encapsulate the entire logic may not seem flexible. Maybe, a lib API to detect 1G paging capability can be added to CpuLib. Thanks, Ray From: Gerd Hoffmann Sent: Monday, May 13, 2024 19:07 To: Tan, Dun Cc: devel@edk2.groups.io ; Ni, Ray ; Laszlo Ersek ; Kumar, Rahul R ; Wu, Jiaxin Subject: Re: [PATCH 10/18] UefiCpuPkg:Relocate AP to new safe buffer in PeiMpLib Hi, > + if (sizeof (UINTN) == sizeof (UINT64)) { > +// > +// Check Page5Level Support or not. > +// > +Cr4.UintN = AsmReadCr4 (); > +Page5LevelSupport = (Cr4.Bits.LA57 ? TRUE : FALSE); > + > +// > +// Check Page1G Support or not. > +// > +Page1GSupport = FALSE; > +AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL); > +if (RegEax >= CPUID_EXTENDED_CPU_SIG) { > + AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &RegEdx.Uint32); > + if (RegEdx.Bits.Page1GB != 0) { > +Page1GSupport = TRUE; > + } > +} > + > +// > +// Decide Paging Mode according Page5LevelSupport & Page1GSupport. > +// > +if (Page5LevelSupport) { > + PagingMode = Page1GSupport ? Paging5Level1GB : Paging5Level; > +} else { > + PagingMode = Page1GSupport ? Paging4Level1GB : Paging4Level; > +} > + } else { > +PagingMode = PagingPae; > + } I'm wondering whenever CpuPageTableLib should get a function for this? I suspect there a multiple places in edk2 which will need this functionality ... take care, Gerd -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#118880): https://edk2.groups.io/g/devel/message/118880 Mute This Topic: https://groups.io/mt/106018135/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-
Re: [edk2-devel] [PATCH 10/18] UefiCpuPkg:Relocate AP to new safe buffer in PeiMpLib
Hi, > + if (sizeof (UINTN) == sizeof (UINT64)) { > +// > +// Check Page5Level Support or not. > +// > +Cr4.UintN = AsmReadCr4 (); > +Page5LevelSupport = (Cr4.Bits.LA57 ? TRUE : FALSE); > + > +// > +// Check Page1G Support or not. > +// > +Page1GSupport = FALSE; > +AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL); > +if (RegEax >= CPUID_EXTENDED_CPU_SIG) { > + AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &RegEdx.Uint32); > + if (RegEdx.Bits.Page1GB != 0) { > +Page1GSupport = TRUE; > + } > +} > + > +// > +// Decide Paging Mode according Page5LevelSupport & Page1GSupport. > +// > +if (Page5LevelSupport) { > + PagingMode = Page1GSupport ? Paging5Level1GB : Paging5Level; > +} else { > + PagingMode = Page1GSupport ? Paging4Level1GB : Paging4Level; > +} > + } else { > +PagingMode = PagingPae; > + } I'm wondering whenever CpuPageTableLib should get a function for this? I suspect there a multiple places in edk2 which will need this functionality ... take care, Gerd -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#118862): https://edk2.groups.io/g/devel/message/118862 Mute This Topic: https://groups.io/mt/106018135/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-
Re: [edk2-devel] [PATCH 10/18] UefiCpuPkg:Relocate AP to new safe buffer in PeiMpLib
Reviewed-by: Ray Ni Thanks, Ray From: Tan, Dun Sent: Friday, May 10, 2024 18:08 To: devel@edk2.groups.io Cc: Ni, Ray ; Laszlo Ersek ; Kumar, Rahul R ; Gerd Hoffmann ; Wu, Jiaxin Subject: [PATCH 10/18] UefiCpuPkg:Relocate AP to new safe buffer in PeiMpLib In this commit, change PeiMpLib to install callback of gEdkiiEndOfS3ResumeGuid to relocate AP to new safe buffer. The gEdkiiEndOfS3ResumeGuid is installed in S3Resume.c before jmping to OS waking vector. Previously, code in CpuS3.c of PiSmmCpuDxe driver will prepare the new safe buffer for AP and place AP in hlt loop state. With this code change, we can remove the Machine Instructions of mApHltLoopCode in PiSmmCpuDxe. Also we can reuse the related code in DxeMpLib for PeiMpLib. Signed-off-by: Dun Tan Cc: Ray Ni Cc: Laszlo Ersek Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Jiaxin Wu --- UefiCpuPkg/Library/MpInitLib/MpLib.h | 3 +++ UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf | 4 UefiCpuPkg/Library/MpInitLib/PeiMpLib.c | 152 3 files changed, 159 insertions(+) diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h index 11e0d2661f..3efd913395 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.h +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -68,6 +69,8 @@ // #define DEFAULT_MAX_MICROCODE_PATCH_NUM 8 +#define PAGING_4K_ADDRESS_MASK_64 0x000FF000ull + // // Data structure for microcode patch information // diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf index e31e34b6f9..8736690348 100644 --- a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf +++ b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf @@ -25,10 +25,12 @@ [Sources.IA32] Ia32/AmdSev.c Ia32/MpFuncs.nasm + Ia32/CreatePageTable.c [Sources.X64] X64/AmdSev.c X64/MpFuncs.nasm + X64/CreatePageTable.c [Sources.IA32, Sources.X64] AmdSev.c @@ -64,6 +66,7 @@ LocalApicLib MicrocodeLib MtrrLib + CpuPageTableLib [Pcd] gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase ## CONSUMES @@ -87,6 +90,7 @@ gEdkiiS3SmmInitDoneGuid gEdkiiMicrocodePatchHobGuid gGhcbApicIdsGuid ## SOMETIMES_CONSUMES + gEdkiiEndOfS3ResumeGuid [Guids.LoongArch64] gProcessorResourceHobGuid ## SOMETIMES_CONSUMES ## HOB diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c b/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c index 4d3acb491f..deb5fc3aac 100644 --- a/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c @@ -9,6 +9,7 @@ #include "MpLib.h" #include #include +#include #include STATIC UINT64 mSevEsPeiWakeupBuffer = BASE_1MB; @@ -449,6 +450,47 @@ BuildMicrocodeCacheHob ( return; } +/** + S3 SMM Init Done notification function. + + @param PeiServices Indirect reference to the PEI Services Table. + @param NotifyDesc Address of the notification descriptor data structure. + @param InvokePpiAddress of the PPI that was invoked. + + @retval EFI_SUCCESS The function completes successfully. + +**/ +EFI_STATUS +EFIAPI +NotifyOnEndOfS3Resume ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, + IN VOID *InvokePpi + ) +{ + CPU_MP_DATA *CpuMpData; + + CpuMpData = GetCpuMpData (); + mNumberToFinish = CpuMpData->CpuCount - 1; + WakeUpAP (CpuMpData, TRUE, 0, RelocateApLoop, NULL, TRUE); + while (mNumberToFinish > 0) { +CpuPause (); + } + + DEBUG ((DEBUG_INFO, "%a() done!\n", __func__)); + + return EFI_SUCCESS; +} + +// +// Global function +// +EFI_PEI_NOTIFY_DESCRIPTOR mEndOfS3ResumeNotifyDesc = { + EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, + &gEdkiiEndOfS3ResumeGuid, + NotifyOnEndOfS3Resume +}; + /** Initialize global data for MP support. @@ -463,12 +505,16 @@ InitMpGlobalData ( BuildMicrocodeCacheHob (CpuMpData); SaveCpuMpData (CpuMpData); + PrepareApLoopCode (CpuMpData); /// /// Install Notify /// Status = PeiServicesNotifyPpi (&mS3SmmInitDoneNotifyDesc); ASSERT_EFI_ERROR (Status); + + Status = PeiServicesNotifyPpi (&mEndOfS3ResumeNotifyDesc); + ASSERT_EFI_ERROR (Status); } /** @@ -815,3 +861,109 @@ PlatformShadowMicrocode ( return EFI_SUCCESS; } + +/** + Allocate buffer for ApLoopCode. + + @param[in] PagesNumber of pages to allocate. + @param[in, out] Address Pointer to the allocated buffer. +**/ +VOID +AllocateApLoopCodeBuffer ( + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *Address + ) +{ + EFI_STATUS Status; + + Status = PeiServicesAllocatePages (EfiACPIMemoryNVS,
[edk2-devel] [PATCH 10/18] UefiCpuPkg:Relocate AP to new safe buffer in PeiMpLib
In this commit, change PeiMpLib to install callback of gEdkiiEndOfS3ResumeGuid to relocate AP to new safe buffer. The gEdkiiEndOfS3ResumeGuid is installed in S3Resume.c before jmping to OS waking vector. Previously, code in CpuS3.c of PiSmmCpuDxe driver will prepare the new safe buffer for AP and place AP in hlt loop state. With this code change, we can remove the Machine Instructions of mApHltLoopCode in PiSmmCpuDxe. Also we can reuse the related code in DxeMpLib for PeiMpLib. Signed-off-by: Dun Tan Cc: Ray Ni Cc: Laszlo Ersek Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Jiaxin Wu --- UefiCpuPkg/Library/MpInitLib/MpLib.h | 3 +++ UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf | 4 UefiCpuPkg/Library/MpInitLib/PeiMpLib.c | 152 3 files changed, 159 insertions(+) diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h index 11e0d2661f..3efd913395 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.h +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -68,6 +69,8 @@ // #define DEFAULT_MAX_MICROCODE_PATCH_NUM 8 +#define PAGING_4K_ADDRESS_MASK_64 0x000FF000ull + // // Data structure for microcode patch information // diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf index e31e34b6f9..8736690348 100644 --- a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf +++ b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf @@ -25,10 +25,12 @@ [Sources.IA32] Ia32/AmdSev.c Ia32/MpFuncs.nasm + Ia32/CreatePageTable.c [Sources.X64] X64/AmdSev.c X64/MpFuncs.nasm + X64/CreatePageTable.c [Sources.IA32, Sources.X64] AmdSev.c @@ -64,6 +66,7 @@ LocalApicLib MicrocodeLib MtrrLib + CpuPageTableLib [Pcd] gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase ## CONSUMES @@ -87,6 +90,7 @@ gEdkiiS3SmmInitDoneGuid gEdkiiMicrocodePatchHobGuid gGhcbApicIdsGuid ## SOMETIMES_CONSUMES + gEdkiiEndOfS3ResumeGuid [Guids.LoongArch64] gProcessorResourceHobGuid ## SOMETIMES_CONSUMES ## HOB diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c b/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c index 4d3acb491f..deb5fc3aac 100644 --- a/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c @@ -9,6 +9,7 @@ #include "MpLib.h" #include #include +#include #include STATIC UINT64 mSevEsPeiWakeupBuffer = BASE_1MB; @@ -449,6 +450,47 @@ BuildMicrocodeCacheHob ( return; } +/** + S3 SMM Init Done notification function. + + @param PeiServices Indirect reference to the PEI Services Table. + @param NotifyDesc Address of the notification descriptor data structure. + @param InvokePpiAddress of the PPI that was invoked. + + @retval EFI_SUCCESS The function completes successfully. + +**/ +EFI_STATUS +EFIAPI +NotifyOnEndOfS3Resume ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, + IN VOID *InvokePpi + ) +{ + CPU_MP_DATA *CpuMpData; + + CpuMpData = GetCpuMpData (); + mNumberToFinish = CpuMpData->CpuCount - 1; + WakeUpAP (CpuMpData, TRUE, 0, RelocateApLoop, NULL, TRUE); + while (mNumberToFinish > 0) { +CpuPause (); + } + + DEBUG ((DEBUG_INFO, "%a() done!\n", __func__)); + + return EFI_SUCCESS; +} + +// +// Global function +// +EFI_PEI_NOTIFY_DESCRIPTOR mEndOfS3ResumeNotifyDesc = { + EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, + &gEdkiiEndOfS3ResumeGuid, + NotifyOnEndOfS3Resume +}; + /** Initialize global data for MP support. @@ -463,12 +505,16 @@ InitMpGlobalData ( BuildMicrocodeCacheHob (CpuMpData); SaveCpuMpData (CpuMpData); + PrepareApLoopCode (CpuMpData); /// /// Install Notify /// Status = PeiServicesNotifyPpi (&mS3SmmInitDoneNotifyDesc); ASSERT_EFI_ERROR (Status); + + Status = PeiServicesNotifyPpi (&mEndOfS3ResumeNotifyDesc); + ASSERT_EFI_ERROR (Status); } /** @@ -815,3 +861,109 @@ PlatformShadowMicrocode ( return EFI_SUCCESS; } + +/** + Allocate buffer for ApLoopCode. + + @param[in] PagesNumber of pages to allocate. + @param[in, out] Address Pointer to the allocated buffer. +**/ +VOID +AllocateApLoopCodeBuffer ( + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *Address + ) +{ + EFI_STATUS Status; + + Status = PeiServicesAllocatePages (EfiACPIMemoryNVS, Pages, Address); + if (EFI_ERROR (Status)) { +*Address = 0; + } +} + +/** + 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 attrib