* [PATCH 1/5] UefiCpuPkg: Duplicate RelocateApLoop for Amd x64 processors.
2023-02-07 13:49 [PATCH 0/5] Put APs in 64 bit mode before handoff to OS Yuanhao Xie
@ 2023-02-07 13:49 ` Yuanhao Xie
2023-02-07 13:49 ` [PATCH 2/5] UefiCpuPkg: Contiguous memory allocation and code clean-up Yuanhao Xie
` (3 subsequent siblings)
4 siblings, 0 replies; 17+ messages in thread
From: Yuanhao Xie @ 2023-02-07 13:49 UTC (permalink / raw)
To: devel; +Cc: Guo Dong, Ray Ni, Sean Rhodes, James Lu, Gua Guo
The duplicated variant is to ensure 64-bit Amd processors can follow the
logic of current existing design to avoid crash may caused by the
untested modification.
Cc: Guo Dong <guo.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Sean Rhodes <sean@starlabs.systems>
Cc: James Lu <james.lu@intel.com>
Cc: Gua Guo <gua.guo@intel.com>
Signed-off-by: Yuanhao Xie <yuanhao.xie@intel.com>
---
UefiCpuPkg/Library/MpInitLib/DxeMpLib.c | 70 +++++---
UefiCpuPkg/Library/MpInitLib/MpEqu.inc | 20 ++-
UefiCpuPkg/Library/MpInitLib/MpLib.h | 28 +++
UefiCpuPkg/Library/MpInitLib/X64/AmdSev.nasm | 169 ++++++++++++++++++
UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm | 3 +
5 files changed, 256 insertions(+), 34 deletions(-)
diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
index a84e9e33ba..fd94652e5b 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
@@ -1,7 +1,7 @@
/** @file
MP initialize support functions for DXE phase.
- Copyright (c) 2016 - 2020, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2016 - 2022, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -378,32 +378,44 @@ RelocateApLoop (
IN OUT VOID *Buffer
)
{
- CPU_MP_DATA *CpuMpData;
- BOOLEAN MwaitSupport;
- ASM_RELOCATE_AP_LOOP AsmRelocateApLoopFunc;
- UINTN ProcessorNumber;
- UINTN StackStart;
+ CPU_MP_DATA *CpuMpData;
+ BOOLEAN MwaitSupport;
+ ASM_RELOCATE_AP_LOOP AsmRelocateApLoopFunc;
+ ASM_RELOCATE_AP_LOOP_AMD64 AsmRelocateApLoopFuncAmd64;
+ UINTN ProcessorNumber;
+ UINTN StackStart;
MpInitLibWhoAmI (&ProcessorNumber);
CpuMpData = GetCpuMpData ();
MwaitSupport = IsMwaitSupport ();
- if (CpuMpData->UseSevEsAPMethod) {
- StackStart = CpuMpData->SevEsAPResetStackStart;
+ if (StandardSignatureIsAuthenticAMD () && (sizeof (UINTN) == sizeof (UINT64))) {
+ StackStart = CpuMpData->UseSevEsAPMethod ? CpuMpData->SevEsAPResetStackStart : mReservedTopOfApStack;
+ AsmRelocateApLoopFuncAmd64 = (ASM_RELOCATE_AP_LOOP)(UINTN)mReservedApLoopFunc;
+ AsmRelocateApLoopFuncAmd64 (
+ MwaitSupport,
+ CpuMpData->ApTargetCState,
+ CpuMpData->PmCodeSegment,
+ StackStart - ProcessorNumber * AP_SAFE_STACK_SIZE,
+ (UINTN)&mNumberToFinish,
+ CpuMpData->Pm16CodeSegment,
+ CpuMpData->SevEsAPBuffer,
+ CpuMpData->WakeupBuffer
+ );
} else {
- StackStart = mReservedTopOfApStack;
+ StackStart = mReservedTopOfApStack;
+ AsmRelocateApLoopFunc = (ASM_RELOCATE_AP_LOOP)(UINTN)mReservedApLoopFunc;
+ AsmRelocateApLoopFunc (
+ MwaitSupport,
+ CpuMpData->ApTargetCState,
+ CpuMpData->PmCodeSegment,
+ StackStart - ProcessorNumber * AP_SAFE_STACK_SIZE,
+ (UINTN)&mNumberToFinish,
+ CpuMpData->Pm16CodeSegment,
+ CpuMpData->SevEsAPBuffer,
+ CpuMpData->WakeupBuffer
+ );
}
- AsmRelocateApLoopFunc = (ASM_RELOCATE_AP_LOOP)(UINTN)mReservedApLoopFunc;
- AsmRelocateApLoopFunc (
- MwaitSupport,
- CpuMpData->ApTargetCState,
- CpuMpData->PmCodeSegment,
- StackStart - ProcessorNumber * AP_SAFE_STACK_SIZE,
- (UINTN)&mNumberToFinish,
- CpuMpData->Pm16CodeSegment,
- CpuMpData->SevEsAPBuffer,
- CpuMpData->WakeupBuffer
- );
//
// It should never reach here
//
@@ -582,11 +594,19 @@ InitMpGlobalData (
mReservedTopOfApStack = (UINTN)Address + ApSafeBufferSize;
ASSERT ((mReservedTopOfApStack & (UINTN)(CPU_STACK_ALIGNMENT - 1)) == 0);
- CopyMem (
- mReservedApLoopFunc,
- CpuMpData->AddressMap.RelocateApLoopFuncAddress,
- CpuMpData->AddressMap.RelocateApLoopFuncSize
- );
+ if (StandardSignatureIsAuthenticAMD () && (sizeof (UINTN) == sizeof (UINT64))) {
+ CopyMem (
+ mReservedApLoopFunc,
+ CpuMpData->AddressMap.RelocateApLoopFuncAddress,
+ CpuMpData->AddressMap.RelocateApLoopFuncSize
+ );
+ } else {
+ CopyMem (
+ mReservedApLoopFunc,
+ CpuMpData->AddressMap.RelocateApLoopFuncAddressAmd64,
+ CpuMpData->AddressMap.RelocateApLoopFuncSizeAmd64
+ );
+ }
Status = gBS->CreateEvent (
EVT_TIMER | EVT_NOTIFY_SIGNAL,
diff --git a/UefiCpuPkg/Library/MpInitLib/MpEqu.inc b/UefiCpuPkg/Library/MpInitLib/MpEqu.inc
index ebadcc6fb3..4d0933d352 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpEqu.inc
+++ b/UefiCpuPkg/Library/MpInitLib/MpEqu.inc
@@ -21,15 +21,17 @@ CPU_SWITCH_STATE_LOADED equ 2
; Equivalent NASM structure of MP_ASSEMBLY_ADDRESS_MAP
;
struc MP_ASSEMBLY_ADDRESS_MAP
- .RendezvousFunnelAddress CTYPE_UINTN 1
- .ModeEntryOffset CTYPE_UINTN 1
- .RendezvousFunnelSize CTYPE_UINTN 1
- .RelocateApLoopFuncAddress CTYPE_UINTN 1
- .RelocateApLoopFuncSize CTYPE_UINTN 1
- .ModeTransitionOffset CTYPE_UINTN 1
- .SwitchToRealNoNxOffset CTYPE_UINTN 1
- .SwitchToRealPM16ModeOffset CTYPE_UINTN 1
- .SwitchToRealPM16ModeSize CTYPE_UINTN 1
+ .RendezvousFunnelAddress CTYPE_UINTN 1
+ .ModeEntryOffset CTYPE_UINTN 1
+ .RendezvousFunnelSize CTYPE_UINTN 1
+ .RelocateApLoopFuncAddress CTYPE_UINTN 1
+ .RelocateApLoopFuncSize CTYPE_UINTN 1
+ .RelocateApLoopFuncAddressAmd64 CTYPE_UINTN 1
+ .RelocateApLoopFuncSizeAmd64 CTYPE_UINTN 1
+ .ModeTransitionOffset CTYPE_UINTN 1
+ .SwitchToRealNoNxOffset CTYPE_UINTN 1
+ .SwitchToRealPM16ModeOffset CTYPE_UINTN 1
+ .SwitchToRealPM16ModeSize CTYPE_UINTN 1
endstruc
;
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index f5086e497e..4f6146e30d 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -179,6 +179,8 @@ typedef struct {
UINTN RendezvousFunnelSize;
UINT8 *RelocateApLoopFuncAddress;
UINTN RelocateApLoopFuncSize;
+ UINT8 *RelocateApLoopFuncAddressAmd64;
+ UINTN RelocateApLoopFuncSizeAmd64;
UINTN ModeTransitionOffset;
UINTN SwitchToRealNoNxOffset;
UINTN SwitchToRealPM16ModeOffset;
@@ -373,6 +375,32 @@ typedef
IN UINTN WakeupBuffer
);
+/**
+ Assembly code to place AP into safe loop mode for Amd X64 processors.
+ Place AP into targeted C-State if MONITOR is supported, otherwise
+ place AP into hlt state.
+ Place AP in protected mode if the current is long mode. Due to AP maybe
+ wakeup by some hardware event. It could avoid accessing page table that
+ may not available during booting to OS.
+
+ @param[in] MwaitSupport TRUE indicates MONITOR is supported.
+ FALSE indicates MONITOR is not supported.
+ @param[in] ApTargetCState Target C-State value.
+ @param[in] PmCodeSegment Protected mode code segment value.
+**/
+typedef
+ VOID
+(EFIAPI *ASM_RELOCATE_AP_LOOP_AMD64)(
+ IN BOOLEAN MwaitSupport,
+ IN UINTN ApTargetCState,
+ IN UINTN PmCodeSegment,
+ IN UINTN TopOfApStack,
+ IN UINTN NumberToFinish,
+ IN UINTN Pm16CodeSegment,
+ IN UINTN SevEsAPJumpTable,
+ IN UINTN WakeupBuffer
+ );
+
/**
Assembly code to get starting address and size of the rendezvous entry for APs.
Information for fixing a jump instruction in the code is also returned.
diff --git a/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.nasm b/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.nasm
index 7c2469f9c5..b3021bc6ea 100644
--- a/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.nasm
+++ b/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.nasm
@@ -346,3 +346,172 @@ PM16Mode:
iret
SwitchToRealProcEnd:
+;-------------------------------------------------------------------------------------
+; AsmRelocateApLoopAmd64 (MwaitSupport, ApTargetCState, PmCodeSegment, TopOfApStack, CountTofinish, Pm16CodeSegment, SevEsAPJumpTable, WakeupBuffer);
+;-------------------------------------------------------------------------------------
+
+AsmRelocateApLoopStartAmd64:
+BITS 64
+ cmp qword [rsp + 56], 0 ; SevEsAPJumpTable
+ je NoSevEsAmd64
+
+ ;
+ ; Perform some SEV-ES related setup before leaving 64-bit mode
+ ;
+ push rcx
+ push rdx
+
+ ;
+ ; Get the RDX reset value using CPUID
+ ;
+ mov rax, 1
+ cpuid
+ mov rsi, rax ; Save off the reset value for RDX
+
+ ;
+ ; Prepare the GHCB for the AP_HLT_LOOP VMGEXIT call
+ ; - Must be done while in 64-bit long mode so that writes to
+ ; the GHCB memory will be unencrypted.
+ ; - No NAE events can be generated once this is set otherwise
+ ; the AP_RESET_HOLD SW_EXITCODE will be overwritten.
+ ;
+ mov rcx, 0xc0010130
+ rdmsr ; Retrieve current GHCB address
+ shl rdx, 32
+ or rdx, rax
+
+ mov rdi, rdx
+ xor rax, rax
+ mov rcx, 0x800
+ shr rcx, 3
+ rep stosq ; Clear the GHCB
+
+ mov rax, 0x80000004 ; VMGEXIT AP_RESET_HOLD
+ mov [rdx + 0x390], rax
+ mov rax, 114 ; Set SwExitCode valid bit
+ bts [rdx + 0x3f0], rax
+ inc rax ; Set SwExitInfo1 valid bit
+ bts [rdx + 0x3f0], rax
+ inc rax ; Set SwExitInfo2 valid bit
+ bts [rdx + 0x3f0], rax
+
+ pop rdx
+ pop rcx
+
+NoSevEsAmd64:
+ cli ; Disable interrupt before switching to 32-bit mode
+ mov rax, [rsp + 40] ; CountTofinish
+ lock dec dword [rax] ; (*CountTofinish)--
+
+ mov r10, [rsp + 48] ; Pm16CodeSegment
+ mov rax, [rsp + 56] ; SevEsAPJumpTable
+ mov rbx, [rsp + 64] ; WakeupBuffer
+ mov rsp, r9 ; TopOfApStack
+
+ push rax ; Save SevEsAPJumpTable
+ push rbx ; Save WakeupBuffer
+ push r10 ; Save Pm16CodeSegment
+ push rcx ; Save MwaitSupport
+ push rdx ; Save ApTargetCState
+
+ lea rax, [PmEntryAmd64] ; rax <- The start address of transition code
+
+ push r8
+ push rax
+
+ ;
+ ; Clear R8 - R15, for reset, before going into 32-bit mode
+ ;
+ xor r8, r8
+ xor r9, r9
+ xor r10, r10
+ xor r11, r11
+ xor r12, r12
+ xor r13, r13
+ xor r14, r14
+ xor r15, r15
+
+ ;
+ ; Far return into 32-bit mode
+ ;
+o64 retf
+
+BITS 32
+PmEntryAmd64:
+ mov eax, cr0
+ btr eax, 31 ; Clear CR0.PG
+ mov cr0, eax ; Disable paging and caches
+
+ mov ecx, 0xc0000080
+ rdmsr
+ and ah, ~ 1 ; Clear LME
+ wrmsr
+ mov eax, cr4
+ and al, ~ (1 << 5) ; Clear PAE
+ mov cr4, eax
+
+ pop edx
+ add esp, 4
+ pop ecx,
+ add esp, 4
+
+MwaitCheckAmd64:
+ cmp cl, 1 ; Check mwait-monitor support
+ jnz HltLoopAmd64
+ mov ebx, edx ; Save C-State to ebx
+MwaitLoopAmd64:
+ cli
+ mov eax, esp ; Set Monitor Address
+ xor ecx, ecx ; ecx = 0
+ xor edx, edx ; edx = 0
+ monitor
+ mov eax, ebx ; Mwait Cx, Target C-State per eax[7:4]
+ shl eax, 4
+ mwait
+ jmp MwaitLoopAmd64
+
+HltLoopAmd64:
+ pop edx ; PM16CodeSegment
+ add esp, 4
+ pop ebx ; WakeupBuffer
+ add esp, 4
+ pop eax ; SevEsAPJumpTable
+ add esp, 4
+ cmp eax, 0 ; Check for SEV-ES
+ je DoHltAmd64
+
+ cli
+ ;
+ ; SEV-ES is enabled, use VMGEXIT (GHCB information already
+ ; set by caller)
+ ;
+BITS 64
+ rep vmmcall
+BITS 32
+
+ ;
+ ; Back from VMGEXIT AP_HLT_LOOP
+ ; Push the FLAGS/CS/IP values to use
+ ;
+ push word 0x0002 ; EFLAGS
+ xor ecx, ecx
+ mov cx, [eax + 2] ; CS
+ push cx
+ mov cx, [eax] ; IP
+ push cx
+ push word 0x0000 ; For alignment, will be discarded
+
+ push edx
+ push ebx
+
+ mov edx, esi ; Restore RDX reset value
+
+ retf
+
+DoHltAmd64:
+ cli
+ hlt
+ jmp DoHltAmd64
+
+BITS 64
+AsmRelocateApLoopEndAmd64:
diff --git a/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm b/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
index 5d71995bf8..cd40099ae4 100644
--- a/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
+++ b/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
@@ -459,6 +459,9 @@ ASM_PFX(AsmGetAddressMap):
lea rax, [AsmRelocateApLoopStart]
mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.RelocateApLoopFuncAddress], rax
mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.RelocateApLoopFuncSize], AsmRelocateApLoopEnd - AsmRelocateApLoopStart
+ lea rax, [AsmRelocateApLoopStartAmd64]
+ mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.RelocateApLoopFuncAddressAmd64], rax
+ mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.RelocateApLoopFuncSizeAmd64], AsmRelocateApLoopEndAmd64 - AsmRelocateApLoopStartAmd64
mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.ModeTransitionOffset], Flat32Start - RendezvousFunnelProcStart
mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealNoNxOffset], SwitchToRealProcStart - Flat32Start
mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealPM16ModeOffset], PM16Mode - RendezvousFunnelProcStart
--
2.36.1.windows.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 2/5] UefiCpuPkg: Contiguous memory allocation and code clean-up.
2023-02-07 13:49 [PATCH 0/5] Put APs in 64 bit mode before handoff to OS Yuanhao Xie
2023-02-07 13:49 ` [PATCH 1/5] UefiCpuPkg: Duplicate RelocateApLoop for Amd x64 processors Yuanhao Xie
@ 2023-02-07 13:49 ` Yuanhao Xie
2023-02-07 16:40 ` [edk2-devel] " Marvin Häuser
2023-02-08 11:09 ` Gerd Hoffmann
2023-02-07 13:49 ` [PATCH 3/5] OvmfPkg: Add CpuPageTableLib required by MpInitLib Yuanhao Xie
` (2 subsequent siblings)
4 siblings, 2 replies; 17+ messages in thread
From: Yuanhao Xie @ 2023-02-07 13:49 UTC (permalink / raw)
To: devel; +Cc: Guo Dong, Ray Ni, Sean Rhodes, James Lu, Gua Guo
Contiguous memory allocation and
This patch includes the code refactoring to eliminate the duplication,
non-descriptive variable, etc.
The memory is calculated taking into account the size difference of
RelocateApLoopFunc under different cases.
Allocate the memory for stacks and AP loop at contiguous address.
Cc: Guo Dong <guo.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Sean Rhodes <sean@starlabs.systems>
Cc: James Lu <james.lu@intel.com>
Cc: Gua Guo <gua.guo@intel.com>
Signed-off-by: Yuanhao Xie <yuanhao.xie@intel.com>
---
UefiCpuPkg/Library/MpInitLib/DxeMpLib.c | 157 ++++++++++++------------
UefiCpuPkg/Library/MpInitLib/MpLib.h | 9 ++
2 files changed, 85 insertions(+), 81 deletions(-)
diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
index fd94652e5b..7b51c5c7f7 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
@@ -20,14 +20,14 @@
#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;
-VOID *mReservedApLoopFunc = NULL;
-UINTN mReservedTopOfApStack;
-volatile UINT32 mNumberToFinish = 0;
+CPU_MP_DATA *mCpuMpData = NULL;
+EFI_EVENT mCheckAllApsEvent = NULL;
+EFI_EVENT mMpInitExitBootServicesEvent = NULL;
+EFI_EVENT mLegacyBootEvent = NULL;
+volatile BOOLEAN mStopCheckAllApsStatus = TRUE;
+UINTN mReservedTopOfApStack;
+volatile UINT32 mNumberToFinish = 0;
+RELOCATE_AP_LOOP_ENTRY mReservedApLoop;
//
// Begin wakeup buffer allocation below 0x88000
@@ -380,8 +380,6 @@ RelocateApLoop (
{
CPU_MP_DATA *CpuMpData;
BOOLEAN MwaitSupport;
- ASM_RELOCATE_AP_LOOP AsmRelocateApLoopFunc;
- ASM_RELOCATE_AP_LOOP_AMD64 AsmRelocateApLoopFuncAmd64;
UINTN ProcessorNumber;
UINTN StackStart;
@@ -390,30 +388,28 @@ RelocateApLoop (
MwaitSupport = IsMwaitSupport ();
if (StandardSignatureIsAuthenticAMD () && (sizeof (UINTN) == sizeof (UINT64))) {
StackStart = CpuMpData->UseSevEsAPMethod ? CpuMpData->SevEsAPResetStackStart : mReservedTopOfApStack;
- AsmRelocateApLoopFuncAmd64 = (ASM_RELOCATE_AP_LOOP)(UINTN)mReservedApLoopFunc;
- AsmRelocateApLoopFuncAmd64 (
- MwaitSupport,
- CpuMpData->ApTargetCState,
- CpuMpData->PmCodeSegment,
- StackStart - ProcessorNumber * AP_SAFE_STACK_SIZE,
- (UINTN)&mNumberToFinish,
- CpuMpData->Pm16CodeSegment,
- CpuMpData->SevEsAPBuffer,
- CpuMpData->WakeupBuffer
- );
+ mReservedApLoop.Amd64Entry (
+ MwaitSupport,
+ CpuMpData->ApTargetCState,
+ CpuMpData->PmCodeSegment,
+ StackStart - ProcessorNumber * AP_SAFE_STACK_SIZE,
+ (UINTN)&mNumberToFinish,
+ CpuMpData->Pm16CodeSegment,
+ CpuMpData->SevEsAPBuffer,
+ CpuMpData->WakeupBuffer
+ );
} else {
- StackStart = mReservedTopOfApStack;
- AsmRelocateApLoopFunc = (ASM_RELOCATE_AP_LOOP)(UINTN)mReservedApLoopFunc;
- AsmRelocateApLoopFunc (
- MwaitSupport,
- CpuMpData->ApTargetCState,
- CpuMpData->PmCodeSegment,
- StackStart - ProcessorNumber * AP_SAFE_STACK_SIZE,
- (UINTN)&mNumberToFinish,
- CpuMpData->Pm16CodeSegment,
- CpuMpData->SevEsAPBuffer,
- CpuMpData->WakeupBuffer
- );
+ StackStart = mReservedTopOfApStack;
+ mReservedApLoop.GenericEntry (
+ MwaitSupport,
+ CpuMpData->ApTargetCState,
+ CpuMpData->PmCodeSegment,
+ StackStart - ProcessorNumber * AP_SAFE_STACK_SIZE,
+ (UINTN)&mNumberToFinish,
+ CpuMpData->Pm16CodeSegment,
+ CpuMpData->SevEsAPBuffer,
+ CpuMpData->WakeupBuffer
+ );
}
//
@@ -477,12 +473,15 @@ InitMpGlobalData (
)
{
EFI_STATUS Status;
- EFI_PHYSICAL_ADDRESS Address;
- UINTN ApSafeBufferSize;
+ MP_ASSEMBLY_ADDRESS_MAP *AddressMap;
+ UINTN AllocSize;
UINTN Index;
EFI_GCD_MEMORY_SPACE_DESCRIPTOR MemDesc;
UINTN StackBase;
CPU_INFO_IN_HOB *CpuInfoInHob;
+ EFI_PHYSICAL_ADDRESS Address;
+ UINT8 *ApLoopFuncData;
+ UINTN ApLoopFuncSize;
SaveCpuMpData (CpuMpData);
@@ -537,6 +536,21 @@ InitMpGlobalData (
}
}
+ AddressMap = &CpuMpData->AddressMap;
+ if (StandardSignatureIsAuthenticAMD () && (sizeof (UINTN) == sizeof (UINT64))) {
+ //
+ // 64-bit AMD Processor
+ //
+ ApLoopFuncData = AddressMap->RelocateApLoopFuncAddressAmd64;
+ ApLoopFuncSize = AddressMap->RelocateApLoopFuncSizeAmd64;
+ } else {
+ //
+ // Intel Processor (32-bit or 64-bit), or 32-bit AMD Processor
+ //
+ ApLoopFuncData = AddressMap->RelocateApLoopFuncAddress;
+ ApLoopFuncSize = AddressMap->RelocateApLoopFuncSize;
+ }
+
//
// Avoid APs access invalid buffer data which allocated by BootServices,
// so we will allocate reserved data for AP loop code. We also need to
@@ -545,26 +559,32 @@ InitMpGlobalData (
// Allocating it in advance since memory services are not available in
// Exit Boot Services callback function.
//
- ApSafeBufferSize = EFI_PAGES_TO_SIZE (
- EFI_SIZE_TO_PAGES (
- CpuMpData->AddressMap.RelocateApLoopFuncSize
- )
- );
+ // +------------+
+ // | Ap Loop |
+ // +------------+
+ // | Stack * N |
+ // +------------+ (low address)
+ //
Address = BASE_4GB - 1;
- Status = gBS->AllocatePages (
- AllocateMaxAddress,
- EfiReservedMemoryType,
- EFI_SIZE_TO_PAGES (ApSafeBufferSize),
- &Address
- );
+ STATIC_ASSERT ((AP_SAFE_STACK_SIZE & (CPU_STACK_ALIGNMENT - 1)) == 0, "AP_SAFE_STACK_SIZE is not aligned with CPU_STACK_ALIGNMENT");
+ AllocSize = EFI_PAGES_TO_SIZE (
+ EFI_SIZE_TO_PAGES (
+ CpuMpData->CpuCount * AP_SAFE_STACK_SIZE + ApLoopFuncSize
+ )
+ );
+ Status = gBS->AllocatePages (
+ AllocateMaxAddress,
+ EfiReservedMemoryType,
+ EFI_SIZE_TO_PAGES (AllocSize),
+ &Address
+ );
ASSERT_EFI_ERROR (Status);
-
- mReservedApLoopFunc = (VOID *)(UINTN)Address;
- ASSERT (mReservedApLoopFunc != NULL);
-
+ // If a memory range has the EFI_MEMORY_XP attribute, OS loader
+ // may set the IA32_EFER.NXE (No-eXecution Enable) bit in IA32_EFER MSR,
+ // then set the XD (eXecution Disable) bit in the CPU PAE page table.
//
- // Make sure that the buffer memory is executable if NX protection is enabled
- // for EfiReservedMemoryType.
+ // Here is to make sure that the memory is executable if NX protection is
+ // enabled for EfiReservedMemoryType.
//
// TODO: Check EFI_MEMORY_XP bit set or not once it's available in DXE GCD
// service.
@@ -573,40 +593,15 @@ InitMpGlobalData (
if (!EFI_ERROR (Status)) {
gDS->SetMemorySpaceAttributes (
Address,
- ApSafeBufferSize,
+ ApLoopFuncSize,
MemDesc.Attributes & (~EFI_MEMORY_XP)
);
}
- ApSafeBufferSize = EFI_PAGES_TO_SIZE (
- EFI_SIZE_TO_PAGES (
- CpuMpData->CpuCount * AP_SAFE_STACK_SIZE
- )
- );
- Address = BASE_4GB - 1;
- Status = gBS->AllocatePages (
- AllocateMaxAddress,
- EfiReservedMemoryType,
- EFI_SIZE_TO_PAGES (ApSafeBufferSize),
- &Address
- );
- ASSERT_EFI_ERROR (Status);
-
- mReservedTopOfApStack = (UINTN)Address + ApSafeBufferSize;
+ mReservedTopOfApStack = ((UINTN)Address + CpuMpData->CpuCount * AP_SAFE_STACK_SIZE);
ASSERT ((mReservedTopOfApStack & (UINTN)(CPU_STACK_ALIGNMENT - 1)) == 0);
- if (StandardSignatureIsAuthenticAMD () && (sizeof (UINTN) == sizeof (UINT64))) {
- CopyMem (
- mReservedApLoopFunc,
- CpuMpData->AddressMap.RelocateApLoopFuncAddress,
- CpuMpData->AddressMap.RelocateApLoopFuncSize
- );
- } else {
- CopyMem (
- mReservedApLoopFunc,
- CpuMpData->AddressMap.RelocateApLoopFuncAddressAmd64,
- CpuMpData->AddressMap.RelocateApLoopFuncSizeAmd64
- );
- }
+ mReservedApLoop.Data = (VOID *)mReservedTopOfApStack;
+ CopyMem (mReservedApLoop.Data, ApLoopFuncData, ApLoopFuncSize);
Status = gBS->CreateEvent (
EVT_TIMER | EVT_NOTIFY_SIGNAL,
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index 4f6146e30d..f1b9063e78 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -401,6 +401,15 @@ typedef
IN UINTN WakeupBuffer
);
+//
+// Union holds the relocate APs loop entries for different cases
+//
+typedef union {
+ VOID *Data;
+ ASM_RELOCATE_AP_LOOP_AMD64 Amd64Entry; // 64-bit AMD Processor
+ ASM_RELOCATE_AP_LOOP GenericEntry; // Intel Processor (32-bit or 64-bit), or 32-bit AMD Processor
+} RELOCATE_AP_LOOP_ENTRY;
+
/**
Assembly code to get starting address and size of the rendezvous entry for APs.
Information for fixing a jump instruction in the code is also returned.
--
2.36.1.windows.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [edk2-devel] [PATCH 2/5] UefiCpuPkg: Contiguous memory allocation and code clean-up.
2023-02-07 13:49 ` [PATCH 2/5] UefiCpuPkg: Contiguous memory allocation and code clean-up Yuanhao Xie
@ 2023-02-07 16:40 ` Marvin Häuser
2023-02-07 16:43 ` Marvin Häuser
2023-02-08 10:36 ` Yuanhao Xie
2023-02-08 11:09 ` Gerd Hoffmann
1 sibling, 2 replies; 17+ messages in thread
From: Marvin Häuser @ 2023-02-07 16:40 UTC (permalink / raw)
To: Yuanhao Xie, devel
[-- Attachment #1: Type: text/plain, Size: 951 bytes --]
Hi Yuanhao,
1) The code comments and copy code suggest that the stacks are located low and the function is located high (good). However, the SetMemorySpaceAttributes() call un-XP's Address, which is the low address. So, do I misunderstand the changes, or are you un-XP'ing the first stack (and keep the function XP'd)?
2) The same SetMemorySpaceAttributes() call, you now pass ApLoopFuncSize over ApSafeBufferSize. The latter was explicitly page-aligned, while the former is not. How is it guaranteed it is indeed aligned? If it is not, I don't think this is supported, at least universally.
3) Similar to 2), the stack size is much smaller than the page size, no? How do you guarantee the function is on a page boundary for memory protection?
4) A proper W^X flow should be to wait with un-XP till the CopyMem() for the function code has returned. Right before that, the copied code should be marked read-only.
Best regards,
Marvin
[-- Attachment #2: Type: text/html, Size: 1268 bytes --]
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [edk2-devel] [PATCH 2/5] UefiCpuPkg: Contiguous memory allocation and code clean-up.
2023-02-07 16:40 ` [edk2-devel] " Marvin Häuser
@ 2023-02-07 16:43 ` Marvin Häuser
2023-02-08 10:36 ` Yuanhao Xie
1 sibling, 0 replies; 17+ messages in thread
From: Marvin Häuser @ 2023-02-07 16:43 UTC (permalink / raw)
To: Yuanhao Xie, edk2-devel-groups-io
Cc: guo.dong, ray.ni, sean, james.lu, gua.guo, Gerd Hoffmann
[-- Attachment #1: Type: text/plain, Size: 1227 bytes --]
CC Gerd (sorry the original quote is missing, groups.io <http://groups.io/> is terrible)
I thought he was to be CC'd on all UefiCpuPkg patches?
Best regards,
Marvin
> On 7. Feb 2023, at 17:40, Marvin Häuser <mhaeuser@posteo.de> wrote:
>
> Hi Yuanhao,
>
> 1) The code comments and copy code suggest that the stacks are located low and the function is located high (good). However, the SetMemorySpaceAttributes() call un-XP's Address, which is the low address. So, do I misunderstand the changes, or are you un-XP'ing the first stack (and keep the function XP'd)?
>
> 2) The same SetMemorySpaceAttributes() call, you now pass ApLoopFuncSize over ApSafeBufferSize. The latter was explicitly page-aligned, while the former is not. How is it guaranteed it is indeed aligned? If it is not, I don't think this is supported, at least universally.
>
> 3) Similar to 2), the stack size is much smaller than the page size, no? How do you guarantee the function is on a page boundary for memory protection?
>
> 4) A proper W^X flow should be to wait with un-XP till the CopyMem() for the function code has returned. Right before that, the copied code should be marked read-only.
>
> Best regards,
> Marvin
[-- Attachment #2: Type: text/html, Size: 1878 bytes --]
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [edk2-devel] [PATCH 2/5] UefiCpuPkg: Contiguous memory allocation and code clean-up.
2023-02-07 16:40 ` [edk2-devel] " Marvin Häuser
2023-02-07 16:43 ` Marvin Häuser
@ 2023-02-08 10:36 ` Yuanhao Xie
1 sibling, 0 replies; 17+ messages in thread
From: Yuanhao Xie @ 2023-02-08 10:36 UTC (permalink / raw)
To: Marvin Häuser; +Cc: devel@edk2.groups.io
[-- Attachment #1: Type: text/plain, Size: 1494 bytes --]
Hi Marvin,
Thanks for the feedbacks.
The corrected implementation is in patch 5.
The stacks are located high and the function is located low. With padding, it ensures page alignment.
I'll resend the patch to make sure the changes are included in patch 2.
Best Regards,
Yuanhao
From: Marvin Häuser <mhaeuser@posteo.de>
Sent: Wednesday, February 8, 2023 12:41 AM
To: Xie, Yuanhao <yuanhao.xie@intel.com>; devel@edk2.groups.io
Subject: Re: [edk2-devel] [PATCH 2/5] UefiCpuPkg: Contiguous memory allocation and code clean-up.
Hi Yuanhao,
1) The code comments and copy code suggest that the stacks are located low and the function is located high (good). However, the SetMemorySpaceAttributes() call un-XP's Address, which is the low address. So, do I misunderstand the changes, or are you un-XP'ing the first stack (and keep the function XP'd)?
2) The same SetMemorySpaceAttributes() call, you now pass ApLoopFuncSize over ApSafeBufferSize. The latter was explicitly page-aligned, while the former is not. How is it guaranteed it is indeed aligned? If it is not, I don't think this is supported, at least universally.
3) Similar to 2), the stack size is much smaller than the page size, no? How do you guarantee the function is on a page boundary for memory protection?
4) A proper W^X flow should be to wait with un-XP till the CopyMem() for the function code has returned. Right before that, the copied code should be marked read-only.
Best regards,
Marvin
[-- Attachment #2: Type: text/html, Size: 3778 bytes --]
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [edk2-devel] [PATCH 2/5] UefiCpuPkg: Contiguous memory allocation and code clean-up.
2023-02-07 13:49 ` [PATCH 2/5] UefiCpuPkg: Contiguous memory allocation and code clean-up Yuanhao Xie
2023-02-07 16:40 ` [edk2-devel] " Marvin Häuser
@ 2023-02-08 11:09 ` Gerd Hoffmann
2023-02-10 9:12 ` Yuanhao Xie
1 sibling, 1 reply; 17+ messages in thread
From: Gerd Hoffmann @ 2023-02-08 11:09 UTC (permalink / raw)
To: devel, yuanhao.xie; +Cc: Guo Dong, Ray Ni, Sean Rhodes, James Lu, Gua Guo
> + AllocSize = EFI_PAGES_TO_SIZE (
> + EFI_SIZE_TO_PAGES (
> + CpuMpData->CpuCount * AP_SAFE_STACK_SIZE + ApLoopFuncSize
> + )
> + );
> + Status = gBS->AllocatePages (
> + AllocateMaxAddress,
> + EfiReservedMemoryType,
> + EFI_SIZE_TO_PAGES (AllocSize),
> + &Address
> + );
Hmm? You convert size to pages, pages to size, size to pages again.
Also you don't want stack and code being on the same page, so I guess
the logic you actually need is this:
StackPages = EFI_SIZE_TO_PAGES(CpuMpData->CpuCount * AP_SAFE_STACK_SIZE);
FuncPages = EFI_SIZE_TO_PAGES(ApLoopFuncSize)
gBS->AllocatePages(..., StackPages + FuncPages, ...);
> +//
> +// Union holds the relocate APs loop entries for different cases
> +//
> +typedef union {
> + VOID *Data;
> + ASM_RELOCATE_AP_LOOP_AMD64 Amd64Entry; // 64-bit AMD Processor
> + ASM_RELOCATE_AP_LOOP GenericEntry; // Intel Processor (32-bit or 64-bit), or 32-bit AMD Processor
> +} RELOCATE_AP_LOOP_ENTRY;
I'm sure I've mentioned this before. The special case you have to
handle is not running on a AMD Processor, but AmdSev being active
(i.e. UseSevEsAPMethod == True). Otherwise it should be just standard
Ia32 and X64, there should be no need to check whenever you are running
on a AMD processor.
take care,
Gerd
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [edk2-devel] [PATCH 2/5] UefiCpuPkg: Contiguous memory allocation and code clean-up.
2023-02-08 11:09 ` Gerd Hoffmann
@ 2023-02-10 9:12 ` Yuanhao Xie
2023-02-10 11:09 ` Gerd Hoffmann
0 siblings, 1 reply; 17+ messages in thread
From: Yuanhao Xie @ 2023-02-10 9:12 UTC (permalink / raw)
To: Gerd Hoffmann
Cc: Dong, Guo, Ni, Ray, Rhodes, Sean, Lu, James, Guo, Gua,
devel@edk2.groups.io
Hi Gerd,
1) You convert size to pages, pages to size, size to pages again.
Agree. I will update it.
2) Also you don't want stack and code being on the same page
Patch 5 ensures that stack and code are in different pages and also ensure alignment. I will update it patch2 as well in v2.
3) The special case you have to handle is not running on a AMD Processor, but AmdSev being active (i.e. UseSevEsAPMethod == True). Otherwise it should be just standard
Ia32 and X64, there should be no need to check whenever you are running on a AMD processor.
I understand your point, but for both cases (check AmdSev, standard Ia32 and X64), AMD related code will be changed. We would like to keep the original implementation as much as possible.
Best regards,
Yuanhao
-----Original Message-----
From: Gerd Hoffmann <kraxel@redhat.com>
Sent: Wednesday, February 8, 2023 7:10 PM
To: devel@edk2.groups.io; Xie, Yuanhao <yuanhao.xie@intel.com>
Cc: Dong, Guo <guo.dong@intel.com>; Ni, Ray <ray.ni@intel.com>; Rhodes, Sean <sean@starlabs.systems>; Lu, James <james.lu@intel.com>; Guo, Gua <gua.guo@intel.com>
Subject: Re: [edk2-devel] [PATCH 2/5] UefiCpuPkg: Contiguous memory allocation and code clean-up.
> + AllocSize = EFI_PAGES_TO_SIZE (
> + EFI_SIZE_TO_PAGES (
> + CpuMpData->CpuCount * AP_SAFE_STACK_SIZE + ApLoopFuncSize
> + )
> + );
> + Status = gBS->AllocatePages (
> + AllocateMaxAddress,
> + EfiReservedMemoryType,
> + EFI_SIZE_TO_PAGES (AllocSize),
> + &Address
> + );
Hmm? You convert size to pages, pages to size, size to pages again.
Also you don't want stack and code being on the same page, so I guess the logic you actually need is this:
StackPages = EFI_SIZE_TO_PAGES(CpuMpData->CpuCount * AP_SAFE_STACK_SIZE); FuncPages = EFI_SIZE_TO_PAGES(ApLoopFuncSize)
gBS->AllocatePages(..., StackPages + FuncPages, ...);
> +//
> +// Union holds the relocate APs loop entries for different cases //
> +typedef union {
> + VOID *Data;
> + ASM_RELOCATE_AP_LOOP_AMD64 Amd64Entry; // 64-bit AMD Processor
> + ASM_RELOCATE_AP_LOOP GenericEntry; // Intel Processor (32-bit or 64-bit), or 32-bit AMD Processor
> +} RELOCATE_AP_LOOP_ENTRY;
I'm sure I've mentioned this before. The special case you have to handle is not running on a AMD Processor, but AmdSev being active (i.e. UseSevEsAPMethod == True). Otherwise it should be just standard
Ia32 and X64, there should be no need to check whenever you are running on a AMD processor.
take care,
Gerd
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [edk2-devel] [PATCH 2/5] UefiCpuPkg: Contiguous memory allocation and code clean-up.
2023-02-10 9:12 ` Yuanhao Xie
@ 2023-02-10 11:09 ` Gerd Hoffmann
2023-02-10 12:52 ` Ni, Ray
0 siblings, 1 reply; 17+ messages in thread
From: Gerd Hoffmann @ 2023-02-10 11:09 UTC (permalink / raw)
To: devel, yuanhao.xie; +Cc: Dong, Guo, Ni, Ray, Rhodes, Sean, Lu, James, Guo, Gua
Hi,
> 3) The special case you have to handle is not running on a AMD
> Processor, but AmdSev being active (i.e. UseSevEsAPMethod == True).
> Otherwise it should be just standard Ia32 and X64, there should be no
> need to check whenever you are running on a AMD processor.
>
> I understand your point, but for both cases (check AmdSev, standard
> Ia32 and X64), AMD related code will be changed. We would like to keep
> the original implementation as much as possible.
Well, the original implementation never checks for an AMD Processor, it
only checks whenever SEV-ES is active (and sets UseSevEsAPMethod in that
case). So why you are adding that check?
take care,
Gerd
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [edk2-devel] [PATCH 2/5] UefiCpuPkg: Contiguous memory allocation and code clean-up.
2023-02-10 11:09 ` Gerd Hoffmann
@ 2023-02-10 12:52 ` Ni, Ray
0 siblings, 0 replies; 17+ messages in thread
From: Ni, Ray @ 2023-02-10 12:52 UTC (permalink / raw)
To: devel@edk2.groups.io, kraxel@redhat.com, Xie, Yuanhao
Cc: Dong, Guo, Rhodes, Sean, Lu, James, Guo, Gua, Tom Lendacky
>
> Hi,
>
> > 3) The special case you have to handle is not running on a AMD
> > Processor, but AmdSev being active (i.e. UseSevEsAPMethod == True).
> > Otherwise it should be just standard Ia32 and X64, there should be no
> > need to check whenever you are running on a AMD processor.
> >
> > I understand your point, but for both cases (check AmdSev, standard
> > Ia32 and X64), AMD related code will be changed. We would like to keep
> > the original implementation as much as possible.
>
> Well, the original implementation never checks for an AMD Processor, it
> only checks whenever SEV-ES is active (and sets UseSevEsAPMethod in that
> case). So why you are adding that check?
Gerd,
I understand that the patch tries to keep AMD flow as the original to avoid
breaking in AMD environment, no matter with or without SEV-ES.
Yuanhao,
I suggest you work with Tom later in a separate patch to put AMD64 non-SEV CPU
in 64bit paging mode as well, if Tom can help to test.
Thanks,
Ray
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 3/5] OvmfPkg: Add CpuPageTableLib required by MpInitLib.
2023-02-07 13:49 [PATCH 0/5] Put APs in 64 bit mode before handoff to OS Yuanhao Xie
2023-02-07 13:49 ` [PATCH 1/5] UefiCpuPkg: Duplicate RelocateApLoop for Amd x64 processors Yuanhao Xie
2023-02-07 13:49 ` [PATCH 2/5] UefiCpuPkg: Contiguous memory allocation and code clean-up Yuanhao Xie
@ 2023-02-07 13:49 ` Yuanhao Xie
2023-02-08 10:53 ` Gerd Hoffmann
2023-02-07 13:49 ` [PATCH 4/5] UefiPayloadPkg: " Yuanhao Xie
2023-02-07 13:49 ` [PATCH 5/5] UefiCpuPkg: Put APs in 64 bit mode before handoff to OS Yuanhao Xie
4 siblings, 1 reply; 17+ messages in thread
From: Yuanhao Xie @ 2023-02-07 13:49 UTC (permalink / raw)
To: devel; +Cc: Ard Biesheuvel, Jiewen Yao, Jordan Justen, Gerd Hoffmann
Add CpuPageTableLib required by MpInitLib in OvmfPkg.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Yuanhao Xie <yuanhao.xie@intel.com>
---
OvmfPkg/AmdSev/AmdSevX64.dsc | 3 ++-
OvmfPkg/CloudHv/CloudHvX64.dsc | 1 +
OvmfPkg/IntelTdx/IntelTdxX64.dsc | 4 +++-
OvmfPkg/Microvm/MicrovmX64.dsc | 1 +
OvmfPkg/OvmfPkgIa32X64.dsc | 1 +
OvmfPkg/OvmfPkgX64.dsc | 2 ++
OvmfPkg/OvmfXen.dsc | 3 ++-
7 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc
index 36100f5fdc..1cafe0d5b3 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.dsc
+++ b/OvmfPkg/AmdSev/AmdSevX64.dsc
@@ -3,7 +3,7 @@
# virtual machine remote attestation and secret injection
#
# Copyright (c) 2020 James Bottomley, IBM Corporation.
-# Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2006 - 2022, Intel Corporation. All rights reserved.<BR>
# (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -353,6 +353,7 @@
DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
!endif
PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
+ CpuPageTableLib|UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableLib.inf
MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
NestedInterruptTplLib|OvmfPkg/Library/NestedInterruptTplLib/NestedInterruptTplLib.inf
QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf
diff --git a/OvmfPkg/CloudHv/CloudHvX64.dsc b/OvmfPkg/CloudHv/CloudHvX64.dsc
index 7326417eab..36fb9bf2a2 100644
--- a/OvmfPkg/CloudHv/CloudHvX64.dsc
+++ b/OvmfPkg/CloudHv/CloudHvX64.dsc
@@ -404,6 +404,7 @@
DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
!endif
PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
+ CpuPageTableLib|UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableLib.inf
MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
NestedInterruptTplLib|OvmfPkg/Library/NestedInterruptTplLib/NestedInterruptTplLib.inf
QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf
diff --git a/OvmfPkg/IntelTdx/IntelTdxX64.dsc b/OvmfPkg/IntelTdx/IntelTdxX64.dsc
index 81511e3556..0a9b7f54d3 100644
--- a/OvmfPkg/IntelTdx/IntelTdxX64.dsc
+++ b/OvmfPkg/IntelTdx/IntelTdxX64.dsc
@@ -1,7 +1,7 @@
## @file
# EFI/Framework Open Virtual Machine Firmware (OVMF) platform
#
-# Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2006 - 2022, Intel Corporation. All rights reserved.<BR>
# (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
# Copyright (c) Microsoft Corporation.
#
@@ -313,6 +313,7 @@
CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxDxeLib.inf
PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
+ CpuPageTableLib|UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableLib.inf
MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
NestedInterruptTplLib|OvmfPkg/Library/NestedInterruptTplLib/NestedInterruptTplLib.inf
QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf
@@ -582,6 +583,7 @@
# Directly use DxeMpInitLib. It depends on DxeMpInitLibMpDepLib which
# checks the Protocol of gEfiMpInitLibMpDepProtocolGuid.
#
+ CpuPageTableLib|UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableLib.inf
MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
NULL|OvmfPkg/Library/MpInitLibDepLib/DxeMpInitLibMpDepLib.inf
}
diff --git a/OvmfPkg/Microvm/MicrovmX64.dsc b/OvmfPkg/Microvm/MicrovmX64.dsc
index 2d53b5c295..b7fad2607f 100644
--- a/OvmfPkg/Microvm/MicrovmX64.dsc
+++ b/OvmfPkg/Microvm/MicrovmX64.dsc
@@ -403,6 +403,7 @@
PciLib|MdePkg/Library/BasePciLibPciExpress/BasePciLibPciExpress.inf
PciPcdProducerLib|OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf
PciExpressLib|OvmfPkg/Library/BaseCachingPciExpressLib/BaseCachingPciExpressLib.inf
+ CpuPageTableLib|UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableLib.inf
MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
NestedInterruptTplLib|OvmfPkg/Library/NestedInterruptTplLib/NestedInterruptTplLib.inf
QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index a9d422bd91..f21b78299f 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -414,6 +414,7 @@
DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
!endif
PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
+ CpuPageTableLib|UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableLib.inf
MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
NestedInterruptTplLib|OvmfPkg/Library/NestedInterruptTplLib/NestedInterruptTplLib.inf
QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index 3f970a79a0..055bc72e57 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -434,6 +434,7 @@
DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
!endif
PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
+ CpuPageTableLib|UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableLib.inf
MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
NestedInterruptTplLib|OvmfPkg/Library/NestedInterruptTplLib/NestedInterruptTplLib.inf
QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf
@@ -818,6 +819,7 @@
# Directly use DxeMpInitLib. It depends on DxeMpInitLibMpDepLib which
# checks the Protocol of gEfiMpInitLibMpDepProtocolGuid.
#
+ CpuPageTableLib|UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableLib.inf
MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
NULL|OvmfPkg/Library/MpInitLibDepLib/DxeMpInitLibMpDepLib.inf
}
diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc
index c328987e84..bfa08c08e3 100644
--- a/OvmfPkg/OvmfXen.dsc
+++ b/OvmfPkg/OvmfXen.dsc
@@ -1,7 +1,7 @@
## @file
# EFI/Framework Open Virtual Machine Firmware (OVMF) platform
#
-# Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2006 - 2022, Intel Corporation. All rights reserved.<BR>
# (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
# Copyright (c) 2019, Citrix Systems, Inc.
# Copyright (c) Microsoft Corporation.
@@ -339,6 +339,7 @@
DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
!endif
PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
+ CpuPageTableLib|UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableLib.inf
MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
NestedInterruptTplLib|OvmfPkg/Library/NestedInterruptTplLib/NestedInterruptTplLib.inf
QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf
--
2.36.1.windows.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH 3/5] OvmfPkg: Add CpuPageTableLib required by MpInitLib.
2023-02-07 13:49 ` [PATCH 3/5] OvmfPkg: Add CpuPageTableLib required by MpInitLib Yuanhao Xie
@ 2023-02-08 10:53 ` Gerd Hoffmann
2023-02-09 16:30 ` [edk2-devel] " Ard Biesheuvel
0 siblings, 1 reply; 17+ messages in thread
From: Gerd Hoffmann @ 2023-02-08 10:53 UTC (permalink / raw)
To: Yuanhao Xie; +Cc: devel, Ard Biesheuvel, Jiewen Yao, Jordan Justen
On Tue, Feb 07, 2023 at 09:49:37PM +0800, Yuanhao Xie wrote:
> Add CpuPageTableLib required by MpInitLib in OvmfPkg.
>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Signed-off-by: Yuanhao Xie <yuanhao.xie@intel.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [edk2-devel] [PATCH 3/5] OvmfPkg: Add CpuPageTableLib required by MpInitLib.
2023-02-08 10:53 ` Gerd Hoffmann
@ 2023-02-09 16:30 ` Ard Biesheuvel
0 siblings, 0 replies; 17+ messages in thread
From: Ard Biesheuvel @ 2023-02-09 16:30 UTC (permalink / raw)
To: devel, kraxel; +Cc: Yuanhao Xie, Jiewen Yao, Jordan Justen
On Wed, 8 Feb 2023 at 11:53, Gerd Hoffmann <kraxel@redhat.com> wrote:
>
> On Tue, Feb 07, 2023 at 09:49:37PM +0800, Yuanhao Xie wrote:
> > Add CpuPageTableLib required by MpInitLib in OvmfPkg.
> >
> > Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> > Cc: Jiewen Yao <jiewen.yao@intel.com>
> > Cc: Jordan Justen <jordan.l.justen@intel.com>
> > Cc: Gerd Hoffmann <kraxel@redhat.com>
> > Signed-off-by: Yuanhao Xie <yuanhao.xie@intel.com>
>
> Acked-by: Gerd Hoffmann <kraxel@redhat.com>
>
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 4/5] UefiPayloadPkg: Add CpuPageTableLib required by MpInitLib
2023-02-07 13:49 [PATCH 0/5] Put APs in 64 bit mode before handoff to OS Yuanhao Xie
` (2 preceding siblings ...)
2023-02-07 13:49 ` [PATCH 3/5] OvmfPkg: Add CpuPageTableLib required by MpInitLib Yuanhao Xie
@ 2023-02-07 13:49 ` Yuanhao Xie
2023-02-08 5:38 ` Guo, Gua
2023-02-08 17:02 ` Guo Dong
2023-02-07 13:49 ` [PATCH 5/5] UefiCpuPkg: Put APs in 64 bit mode before handoff to OS Yuanhao Xie
4 siblings, 2 replies; 17+ messages in thread
From: Yuanhao Xie @ 2023-02-07 13:49 UTC (permalink / raw)
To: devel; +Cc: Guo Dong, Ray Ni, Sean Rhodes, James Lu, Gua Guo
Add CpuPageTableLib required by MpInitLib in UefiPayloadPkg.
Cc: Guo Dong <guo.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Sean Rhodes <sean@starlabs.systems>
Cc: James Lu <james.lu@intel.com>
Cc: Gua Guo <gua.guo@intel.com>
Signed-off-by: Yuanhao Xie <yuanhao.xie@intel.com>
---
UefiPayloadPkg/UefiPayloadPkg.dsc | 1 +
1 file changed, 1 insertion(+)
diff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc b/UefiPayloadPkg/UefiPayloadPkg.dsc
index 2dbd875f37..a1a3c74290 100644
--- a/UefiPayloadPkg/UefiPayloadPkg.dsc
+++ b/UefiPayloadPkg/UefiPayloadPkg.dsc
@@ -340,6 +340,7 @@
DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
!endif
CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
+ CpuPageTableLib|UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableLib.inf
MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
!if $(PERFORMANCE_MEASUREMENT_ENABLE)
PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
--
2.36.1.windows.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH 4/5] UefiPayloadPkg: Add CpuPageTableLib required by MpInitLib
2023-02-07 13:49 ` [PATCH 4/5] UefiPayloadPkg: " Yuanhao Xie
@ 2023-02-08 5:38 ` Guo, Gua
2023-02-08 17:02 ` Guo Dong
1 sibling, 0 replies; 17+ messages in thread
From: Guo, Gua @ 2023-02-08 5:38 UTC (permalink / raw)
To: Xie, Yuanhao, devel@edk2.groups.io
Cc: Dong, Guo, Ni, Ray, Rhodes, Sean, Lu, James
Reviewed-by: Gua Guo <gua.guo@intel.com>
-----Original Message-----
From: Xie, Yuanhao <yuanhao.xie@intel.com>
Sent: Tuesday, February 7, 2023 9:50 PM
To: devel@edk2.groups.io
Cc: Dong, Guo <guo.dong@intel.com>; Ni, Ray <ray.ni@intel.com>; Rhodes, Sean <sean@starlabs.systems>; Lu, James <james.lu@intel.com>; Guo, Gua <gua.guo@intel.com>
Subject: [PATCH 4/5] UefiPayloadPkg: Add CpuPageTableLib required by MpInitLib
Add CpuPageTableLib required by MpInitLib in UefiPayloadPkg.
Cc: Guo Dong <guo.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Sean Rhodes <sean@starlabs.systems>
Cc: James Lu <james.lu@intel.com>
Cc: Gua Guo <gua.guo@intel.com>
Signed-off-by: Yuanhao Xie <yuanhao.xie@intel.com>
---
UefiPayloadPkg/UefiPayloadPkg.dsc | 1 +
1 file changed, 1 insertion(+)
diff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc b/UefiPayloadPkg/UefiPayloadPkg.dsc
index 2dbd875f37..a1a3c74290 100644
--- a/UefiPayloadPkg/UefiPayloadPkg.dsc
+++ b/UefiPayloadPkg/UefiPayloadPkg.dsc
@@ -340,6 +340,7 @@
DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
!endif
CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
+ CpuPageTableLib|UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableLib.inf
MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
!if $(PERFORMANCE_MEASUREMENT_ENABLE)
PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
--
2.36.1.windows.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH 4/5] UefiPayloadPkg: Add CpuPageTableLib required by MpInitLib
2023-02-07 13:49 ` [PATCH 4/5] UefiPayloadPkg: " Yuanhao Xie
2023-02-08 5:38 ` Guo, Gua
@ 2023-02-08 17:02 ` Guo Dong
1 sibling, 0 replies; 17+ messages in thread
From: Guo Dong @ 2023-02-08 17:02 UTC (permalink / raw)
To: Xie, Yuanhao, devel@edk2.groups.io
Cc: Ni, Ray, Rhodes, Sean, Lu, James, Guo, Gua
Reviewed-by: Guo Dong <guo.dong@intel.com>
-----Original Message-----
From: Xie, Yuanhao <yuanhao.xie@intel.com>
Sent: Tuesday, February 7, 2023 6:50 AM
To: devel@edk2.groups.io
Cc: Dong, Guo <guo.dong@intel.com>; Ni, Ray <ray.ni@intel.com>; Rhodes, Sean <sean@starlabs.systems>; Lu, James <james.lu@intel.com>; Guo, Gua <gua.guo@intel.com>
Subject: [PATCH 4/5] UefiPayloadPkg: Add CpuPageTableLib required by MpInitLib
Add CpuPageTableLib required by MpInitLib in UefiPayloadPkg.
Cc: Guo Dong <guo.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Sean Rhodes <sean@starlabs.systems>
Cc: James Lu <james.lu@intel.com>
Cc: Gua Guo <gua.guo@intel.com>
Signed-off-by: Yuanhao Xie <yuanhao.xie@intel.com>
---
UefiPayloadPkg/UefiPayloadPkg.dsc | 1 +
1 file changed, 1 insertion(+)
diff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc b/UefiPayloadPkg/UefiPayloadPkg.dsc
index 2dbd875f37..a1a3c74290 100644
--- a/UefiPayloadPkg/UefiPayloadPkg.dsc
+++ b/UefiPayloadPkg/UefiPayloadPkg.dsc
@@ -340,6 +340,7 @@
DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
!endif
CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
+ CpuPageTableLib|UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableLib.inf
MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
!if $(PERFORMANCE_MEASUREMENT_ENABLE)
PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
--
2.36.1.windows.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 5/5] UefiCpuPkg: Put APs in 64 bit mode before handoff to OS.
2023-02-07 13:49 [PATCH 0/5] Put APs in 64 bit mode before handoff to OS Yuanhao Xie
` (3 preceding siblings ...)
2023-02-07 13:49 ` [PATCH 4/5] UefiPayloadPkg: " Yuanhao Xie
@ 2023-02-07 13:49 ` Yuanhao Xie
4 siblings, 0 replies; 17+ messages in thread
From: Yuanhao Xie @ 2023-02-07 13:49 UTC (permalink / raw)
To: devel; +Cc: Guo Dong, Ray Ni, Sean Rhodes, James Lu, Gua Guo
Only keep 4GB limitation of memory allocation for the case APs
still need to be transferred to 32-bit mode before OS.
Remove the unused arguments of AsmRelocateApLoopStart, updated the
stack offset.
Create PageTable for the allocated reserved memory.
Cc: Guo Dong <guo.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Sean Rhodes <sean@starlabs.systems>
Cc: James Lu <james.lu@intel.com>
Cc: Gua Guo <gua.guo@intel.com>
Signed-off-by: Yuanhao Xie <yuanhao.xie@intel.com>
---
UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf | 7 +-
UefiCpuPkg/Library/MpInitLib/DxeMpLib.c | 61 +++---
.../Library/MpInitLib/Ia32/CreatePageTable.c | 23 +++
.../Library/MpInitLib/Ia32/MpFuncs.nasm | 9 +-
UefiCpuPkg/Library/MpInitLib/MpLib.h | 18 +-
.../Library/MpInitLib/X64/CreatePageTable.c | 82 +++++++++
UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm | 173 +++---------------
UefiCpuPkg/UefiCpuPkg.dsc | 1 +
8 files changed, 193 insertions(+), 181 deletions(-)
create mode 100644 UefiCpuPkg/Library/MpInitLib/Ia32/CreatePageTable.c
create mode 100644 UefiCpuPkg/Library/MpInitLib/X64/CreatePageTable.c
diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
index cd07de3a3c..5507472379 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
@@ -1,7 +1,7 @@
## @file
# MP Initialize Library instance for DXE driver.
#
-# Copyright (c) 2016 - 2021, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2016 - 2022, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
@@ -24,10 +24,12 @@
[Sources.IA32]
Ia32/AmdSev.c
Ia32/MpFuncs.nasm
+ Ia32/CreatePageTable.c
[Sources.X64]
X64/AmdSev.c
X64/MpFuncs.nasm
+ X64/CreatePageTable.c
[Sources.common]
AmdSev.c
@@ -57,6 +59,9 @@
CcExitLib
MicrocodeLib
+[LibraryClasses.X64]
+ CpuPageTableLib
+
[Protocols]
gEfiTimerArchProtocolGuid ## SOMETIMES_CONSUMES
diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
index 7b51c5c7f7..92b6df7f68 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
@@ -28,6 +28,7 @@ volatile BOOLEAN mStopCheckAllApsStatus = TRUE;
UINTN mReservedTopOfApStack;
volatile UINT32 mNumberToFinish = 0;
RELOCATE_AP_LOOP_ENTRY mReservedApLoop;
+UINTN mApPageTable;
//
// Begin wakeup buffer allocation below 0x88000
@@ -378,10 +379,10 @@ RelocateApLoop (
IN OUT VOID *Buffer
)
{
- CPU_MP_DATA *CpuMpData;
- BOOLEAN MwaitSupport;
- UINTN ProcessorNumber;
- UINTN StackStart;
+ CPU_MP_DATA *CpuMpData;
+ BOOLEAN MwaitSupport;
+ UINTN ProcessorNumber;
+ UINTN StackStart;
MpInitLibWhoAmI (&ProcessorNumber);
CpuMpData = GetCpuMpData ();
@@ -403,12 +404,9 @@ RelocateApLoop (
mReservedApLoop.GenericEntry (
MwaitSupport,
CpuMpData->ApTargetCState,
- CpuMpData->PmCodeSegment,
StackStart - ProcessorNumber * AP_SAFE_STACK_SIZE,
(UINTN)&mNumberToFinish,
- CpuMpData->Pm16CodeSegment,
- CpuMpData->SevEsAPBuffer,
- CpuMpData->WakeupBuffer
+ mApPageTable
);
}
@@ -480,7 +478,7 @@ InitMpGlobalData (
UINTN StackBase;
CPU_INFO_IN_HOB *CpuInfoInHob;
EFI_PHYSICAL_ADDRESS Address;
- UINT8 *ApLoopFuncData;
+ UINT8 *ApLoopFunc;
UINTN ApLoopFuncSize;
SaveCpuMpData (CpuMpData);
@@ -541,13 +539,15 @@ InitMpGlobalData (
//
// 64-bit AMD Processor
//
- ApLoopFuncData = AddressMap->RelocateApLoopFuncAddressAmd64;
+ Address = BASE_4GB - 1;
+ ApLoopFunc = AddressMap->RelocateApLoopFuncAddressAmd64;
ApLoopFuncSize = AddressMap->RelocateApLoopFuncSizeAmd64;
} else {
//
// Intel Processor (32-bit or 64-bit), or 32-bit AMD Processor
//
- ApLoopFuncData = AddressMap->RelocateApLoopFuncAddress;
+ Address = MAX_ADDRESS;
+ ApLoopFunc = AddressMap->RelocateApLoopFuncAddress;
ApLoopFuncSize = AddressMap->RelocateApLoopFuncSize;
}
@@ -559,17 +559,17 @@ InitMpGlobalData (
// Allocating it in advance since memory services are not available in
// Exit Boot Services callback function.
//
+ // +------------+ (TopOfApStack)
+ // | Stack * N |
// +------------+
- // | Ap Loop |
+ // | Padding |
// +------------+
- // | Stack * N |
- // +------------+ (low address)
+ // | Ap Loop |
+ // +------------+ (low address )
//
- Address = BASE_4GB - 1;
- STATIC_ASSERT ((AP_SAFE_STACK_SIZE & (CPU_STACK_ALIGNMENT - 1)) == 0, "AP_SAFE_STACK_SIZE is not aligned with CPU_STACK_ALIGNMENT");
AllocSize = EFI_PAGES_TO_SIZE (
EFI_SIZE_TO_PAGES (
- CpuMpData->CpuCount * AP_SAFE_STACK_SIZE + ApLoopFuncSize
+ CpuMpData->CpuCount * AP_SAFE_STACK_SIZE + ALIGN_VALUE (ApLoopFuncSize, EFI_PAGE_SIZE)
)
);
Status = gBS->AllocatePages (
@@ -591,17 +591,28 @@ InitMpGlobalData (
//
Status = gDS->GetMemorySpaceDescriptor (Address, &MemDesc);
if (!EFI_ERROR (Status)) {
- gDS->SetMemorySpaceAttributes (
- Address,
- ApLoopFuncSize,
- MemDesc.Attributes & (~EFI_MEMORY_XP)
- );
+ Status = gDS->SetMemorySpaceAttributes (
+ Address,
+ ALIGN_VALUE (ApLoopFuncSize, EFI_PAGE_SIZE),
+ MemDesc.Attributes & (~EFI_MEMORY_XP)
+ );
+ ASSERT_EFI_ERROR (Status);
}
- mReservedTopOfApStack = ((UINTN)Address + CpuMpData->CpuCount * AP_SAFE_STACK_SIZE);
+ mReservedTopOfApStack = (UINTN)Address + AllocSize;
ASSERT ((mReservedTopOfApStack & (UINTN)(CPU_STACK_ALIGNMENT - 1)) == 0);
- mReservedApLoop.Data = (VOID *)mReservedTopOfApStack;
- CopyMem (mReservedApLoop.Data, ApLoopFuncData, ApLoopFuncSize);
+ mReservedApLoop.Data = (VOID *)(UINTN)Address;
+ CopyMem (mReservedApLoop.Data, ApLoopFunc, ApLoopFuncSize);
+
+ if (!StandardSignatureIsAuthenticAMD () && (sizeof (UINTN) == sizeof (UINT64))) {
+ //
+ // 64-bit Intel Processor
+ //
+ mApPageTable = CreatePageTable (
+ (UINTN)Address,
+ AllocSize
+ );
+ }
Status = gBS->CreateEvent (
EVT_TIMER | EVT_NOTIFY_SIGNAL,
diff --git a/UefiCpuPkg/Library/MpInitLib/Ia32/CreatePageTable.c b/UefiCpuPkg/Library/MpInitLib/Ia32/CreatePageTable.c
new file mode 100644
index 0000000000..76328c38f1
--- /dev/null
+++ b/UefiCpuPkg/Library/MpInitLib/Ia32/CreatePageTable.c
@@ -0,0 +1,23 @@
+/** @file
+ Function to create page talbe.
+ Only create page table for x64, and leave the CreatePageTable empty for Ia32.
+ Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+
+/**
+ Only create page table for x64, and leave the CreatePageTable empty for Ia32.
+ @param[in] LinearAddress The start of the linear address range.
+ @param[in] Length The length of the linear address range.
+ @return The page table to be created.
+**/
+UINTN
+CreatePageTable (
+ IN UINTN Address,
+ IN UINTN Length
+ )
+{
+ return 0;
+}
diff --git a/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm b/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm
index bfcdbd31c1..5cffa632ab 100644
--- a/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm
+++ b/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm
@@ -219,20 +219,17 @@ SwitchToRealProcEnd:
RendezvousFunnelProcEnd:
;-------------------------------------------------------------------------------------
-; AsmRelocateApLoop (MwaitSupport, ApTargetCState, PmCodeSegment, TopOfApStack, CountTofinish, Pm16CodeSegment, SevEsAPJumpTable, WakeupBuffer);
-;
-; The last three parameters (Pm16CodeSegment, SevEsAPJumpTable and WakeupBuffer) are
-; specific to SEV-ES support and are not applicable on IA32.
+; AsmRelocateApLoop (MwaitSupport, ApTargetCState, TopOfApStack, CountTofinish, Cr3);
;-------------------------------------------------------------------------------------
AsmRelocateApLoopStart:
mov eax, esp
- mov esp, [eax + 16] ; TopOfApStack
+ mov esp, [eax + 12] ; TopOfApStack
push dword [eax] ; push return address for stack trace
push ebp
mov ebp, esp
mov ebx, [eax + 8] ; ApTargetCState
mov ecx, [eax + 4] ; MwaitSupport
- mov eax, [eax + 20] ; CountTofinish
+ mov eax, [eax + 16] ; CountTofinish
lock dec dword [eax] ; (*CountTofinish)--
cmp cl, 1 ; Check mwait-monitor support
jnz HltLoop
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index f1b9063e78..b0acf82ab1 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -313,6 +313,7 @@ typedef struct {
#define AP_SAFE_STACK_SIZE 128
#define AP_RESET_STACK_SIZE AP_SAFE_STACK_SIZE
+STATIC_ASSERT ((AP_SAFE_STACK_SIZE & (CPU_STACK_ALIGNMENT - 1)) == 0, "AP_SAFE_STACK_SIZE is not aligned with CPU_STACK_ALIGNMENT");
#pragma pack(1)
@@ -367,12 +368,9 @@ typedef
(EFIAPI *ASM_RELOCATE_AP_LOOP)(
IN BOOLEAN MwaitSupport,
IN UINTN ApTargetCState,
- IN UINTN PmCodeSegment,
IN UINTN TopOfApStack,
IN UINTN NumberToFinish,
- IN UINTN Pm16CodeSegment,
- IN UINTN SevEsAPJumpTable,
- IN UINTN WakeupBuffer
+ IN UINTN Cr3
);
/**
@@ -501,6 +499,18 @@ GetSevEsAPMemory (
VOID
);
+/**
+ Create 1:1 mapping page table in reserved memory to map the specified address range.
+ @param[in] LinearAddress The start of the linear address range.
+ @param[in] Length The length of the linear address range.
+ @return The page table to be created.
+**/
+UINTN
+CreatePageTable (
+ IN UINTN Address,
+ IN UINTN Length
+ );
+
/**
This function will be called by BSP to wakeup AP.
diff --git a/UefiCpuPkg/Library/MpInitLib/X64/CreatePageTable.c b/UefiCpuPkg/Library/MpInitLib/X64/CreatePageTable.c
new file mode 100644
index 0000000000..1341477e52
--- /dev/null
+++ b/UefiCpuPkg/Library/MpInitLib/X64/CreatePageTable.c
@@ -0,0 +1,82 @@
+/** @file
+ Function to create page talbe.
+ Only create page table for x64, and leave the CreatePageTable empty for Ia32.
+ Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Library/CpuPageTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Base.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+
+/**
+ Create 1:1 mapping page table in reserved memory to map the specified address range.
+ @param[in] LinearAddress The start of the linear address range.
+ @param[in] Length The length of the linear address range.
+ @return The page table to be created.
+**/
+UINTN
+CreatePageTable (
+ IN UINTN Address,
+ IN UINTN Length
+ )
+{
+ EFI_STATUS Status;
+ VOID *PageTableBuffer;
+ UINTN PageTableBufferSize;
+ UINTN PageTable;
+ PAGING_MODE PagingMode;
+ IA32_CR4 Cr4;
+
+ IA32_MAP_ATTRIBUTE MapAttribute;
+ IA32_MAP_ATTRIBUTE MapMask;
+
+ MapAttribute.Uint64 = Address;
+ MapAttribute.Bits.Present = 1;
+ MapAttribute.Bits.ReadWrite = 1;
+
+ MapMask.Bits.PageTableBaseAddress = 1;
+ MapMask.Bits.Present = 1;
+ MapMask.Bits.ReadWrite = 1;
+
+ PageTable = 0;
+ PageTableBufferSize = 0;
+
+ Cr4.UintN = AsmReadCr4 ();
+
+ if (Cr4.Bits.LA57 == 1) {
+ PagingMode = Paging5Level;
+ } else {
+ PagingMode = Paging4Level;
+ }
+
+ Status = PageTableMap (
+ &PageTable,
+ PagingMode,
+ NULL,
+ &PageTableBufferSize,
+ Address,
+ Length,
+ &MapAttribute,
+ &MapMask
+ );
+ ASSERT (Status == EFI_BUFFER_TOO_SMALL);
+ DEBUG ((DEBUG_INFO, "AP Page Table Buffer Size = %x\n", PageTableBufferSize));
+
+ PageTableBuffer = AllocateReservedPages (EFI_SIZE_TO_PAGES (PageTableBufferSize));
+ ASSERT (PageTableBuffer != NULL);
+ Status = PageTableMap (
+ &PageTable,
+ PagingMode,
+ PageTableBuffer,
+ &PageTableBufferSize,
+ Address,
+ Length,
+ &MapAttribute,
+ &MapMask
+ );
+ ASSERT_EFI_ERROR (Status);
+ return PageTable;
+}
diff --git a/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm b/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
index cd40099ae4..4ba6a62e4a 100644
--- a/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
+++ b/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
@@ -279,172 +279,55 @@ CProcedureInvoke:
RendezvousFunnelProcEnd:
;-------------------------------------------------------------------------------------
-; AsmRelocateApLoop (MwaitSupport, ApTargetCState, PmCodeSegment, TopOfApStack, CountTofinish, Pm16CodeSegment, SevEsAPJumpTable, WakeupBuffer);
+; AsmRelocateApLoop (MwaitSupport, ApTargetCState, TopOfApStack, CountTofinish, Cr3);
+; This function is called during the finalizaiton of Mp initialization before booting
+; to OS, and aim to put Aps either in Mwait or HLT.
;-------------------------------------------------------------------------------------
-AsmRelocateApLoopStart:
-BITS 64
- cmp qword [rsp + 56], 0 ; SevEsAPJumpTable
- je NoSevEs
-
- ;
- ; Perform some SEV-ES related setup before leaving 64-bit mode
- ;
- push rcx
- push rdx
-
- ;
- ; Get the RDX reset value using CPUID
- ;
- mov rax, 1
- cpuid
- mov rsi, rax ; Save off the reset value for RDX
-
- ;
- ; Prepare the GHCB for the AP_HLT_LOOP VMGEXIT call
- ; - Must be done while in 64-bit long mode so that writes to
- ; the GHCB memory will be unencrypted.
- ; - No NAE events can be generated once this is set otherwise
- ; the AP_RESET_HOLD SW_EXITCODE will be overwritten.
- ;
- mov rcx, 0xc0010130
- rdmsr ; Retrieve current GHCB address
- shl rdx, 32
- or rdx, rax
-
- mov rdi, rdx
- xor rax, rax
- mov rcx, 0x800
- shr rcx, 3
- rep stosq ; Clear the GHCB
-
- mov rax, 0x80000004 ; VMGEXIT AP_RESET_HOLD
- mov [rdx + 0x390], rax
- mov rax, 114 ; Set SwExitCode valid bit
- bts [rdx + 0x3f0], rax
- inc rax ; Set SwExitInfo1 valid bit
- bts [rdx + 0x3f0], rax
- inc rax ; Set SwExitInfo2 valid bit
- bts [rdx + 0x3f0], rax
+; +----------------+
+; | Cr3 | rsp+40
+; +----------------+
+; | CountTofinish | r9
+; +----------------+
+; | TopOfApStack | r8
+; +----------------+
+; | ApTargetCState | rdx
+; +----------------+
+; | MwaitSupport | rcx
+; +----------------+
+; | the return |
+; +----------------+ low address
- pop rdx
- pop rcx
-
-NoSevEs:
- cli ; Disable interrupt before switching to 32-bit mode
- mov rax, [rsp + 40] ; CountTofinish
+AsmRelocateApLoopStart:
+ mov rax, r9 ; CountTofinish
lock dec dword [rax] ; (*CountTofinish)--
- mov r10, [rsp + 48] ; Pm16CodeSegment
- mov rax, [rsp + 56] ; SevEsAPJumpTable
- mov rbx, [rsp + 64] ; WakeupBuffer
- mov rsp, r9 ; TopOfApStack
-
- push rax ; Save SevEsAPJumpTable
- push rbx ; Save WakeupBuffer
- push r10 ; Save Pm16CodeSegment
- push rcx ; Save MwaitSupport
- push rdx ; Save ApTargetCState
-
- lea rax, [PmEntry] ; rax <- The start address of transition code
-
- push r8
- push rax
-
- ;
- ; Clear R8 - R15, for reset, before going into 32-bit mode
- ;
- xor r8, r8
- xor r9, r9
- xor r10, r10
- xor r11, r11
- xor r12, r12
- xor r13, r13
- xor r14, r14
- xor r15, r15
-
- ;
- ; Far return into 32-bit mode
- ;
- retfq
-
-BITS 32
-PmEntry:
- mov eax, cr0
- btr eax, 31 ; Clear CR0.PG
- mov cr0, eax ; Disable paging and caches
-
- mov ecx, 0xc0000080
- rdmsr
- and ah, ~ 1 ; Clear LME
- wrmsr
- mov eax, cr4
- and al, ~ (1 << 5) ; Clear PAE
- mov cr4, eax
-
- pop edx
- add esp, 4
- pop ecx,
- add esp, 4
+ mov rax, [rsp + 40] ; Cr3
+ ; Do not push on old stack, since old stack is not mapped
+ ; in the page table pointed by cr3
+ mov cr3, rax
+ mov rsp, r8 ; TopOfApStack
MwaitCheck:
cmp cl, 1 ; Check mwait-monitor support
jnz HltLoop
- mov ebx, edx ; Save C-State to ebx
+ mov rbx, rdx ; Save C-State to ebx
+
MwaitLoop:
cli
- mov eax, esp ; Set Monitor Address
+ mov rax, rsp ; Set Monitor Address
xor ecx, ecx ; ecx = 0
xor edx, edx ; edx = 0
monitor
- mov eax, ebx ; Mwait Cx, Target C-State per eax[7:4]
+ mov rax, rbx ; Mwait Cx, Target C-State per eax[7:4]
shl eax, 4
mwait
jmp MwaitLoop
HltLoop:
- pop edx ; PM16CodeSegment
- add esp, 4
- pop ebx ; WakeupBuffer
- add esp, 4
- pop eax ; SevEsAPJumpTable
- add esp, 4
- cmp eax, 0 ; Check for SEV-ES
- je DoHlt
-
- cli
- ;
- ; SEV-ES is enabled, use VMGEXIT (GHCB information already
- ; set by caller)
- ;
-BITS 64
- rep vmmcall
-BITS 32
-
- ;
- ; Back from VMGEXIT AP_HLT_LOOP
- ; Push the FLAGS/CS/IP values to use
- ;
- push word 0x0002 ; EFLAGS
- xor ecx, ecx
- mov cx, [eax + 2] ; CS
- push cx
- mov cx, [eax] ; IP
- push cx
- push word 0x0000 ; For alignment, will be discarded
-
- push edx
- push ebx
-
- mov edx, esi ; Restore RDX reset value
-
- retf
-
-DoHlt:
cli
hlt
- jmp DoHlt
+ jmp HltLoop
-BITS 64
AsmRelocateApLoopEnd:
;-------------------------------------------------------------------------------------
diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc
index f9a46089d2..781acedfc5 100644
--- a/UefiCpuPkg/UefiCpuPkg.dsc
+++ b/UefiCpuPkg/UefiCpuPkg.dsc
@@ -94,6 +94,7 @@
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
+ CpuPageTableLib|UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableLib.inf
MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
RegisterCpuFeaturesLib|UefiCpuPkg/Library/RegisterCpuFeaturesLib/DxeRegisterCpuFeaturesLib.inf
CpuCacheInfoLib|UefiCpuPkg/Library/CpuCacheInfoLib/DxeCpuCacheInfoLib.inf
--
2.36.1.windows.1
^ permalink raw reply related [flat|nested] 17+ messages in thread