summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYuanhao Xie <yuanhao.xie@intel.com>2023-01-09 11:37:21 +0800
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2023-01-09 17:53:41 +0000
commitcbcf0cd65ed44e88f3f36edc18a14c59d5372b3b (patch)
treeb08167cce6ae2c6d0db7718769e9baeeab019c01
parentd8d829b89dababf763ab33b8cdd852b2830db3cf (diff)
downloadedk2-cbcf0cd65ed44e88f3f36edc18a14c59d5372b3b.tar.gz
edk2-cbcf0cd65ed44e88f3f36edc18a14c59d5372b3b.tar.bz2
edk2-cbcf0cd65ed44e88f3f36edc18a14c59d5372b3b.zip
Revert "UefiCpuPkg: Has APs in 64 bit long-mode before booting to OS."
This reverts commit 73ccde8f6d04a246377cabaed2875e69d4b6b719 since it results in a hang of the IA32 processor and needs further clean-up. Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=4234 Cc: Eric Dong <eric.dong@intel.com> Cc: Ray Ni <ray.ni@intel.com> Cc: Rahul Kumar <rahul1.kumar@intel.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Laszlo Ersek <lersek@redhat.com> Signed-off-by: Yuanhao Xie <yuanhao.xie@intel.com>
-rw-r--r--UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf7
-rw-r--r--UefiCpuPkg/Library/MpInitLib/DxeMpLib.c84
-rw-r--r--UefiCpuPkg/Library/MpInitLib/Ia32/CreatePageTable.c27
-rw-r--r--UefiCpuPkg/Library/MpInitLib/MpLib.h19
-rw-r--r--UefiCpuPkg/Library/MpInitLib/X64/CreatePageTable.c75
-rw-r--r--UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm171
-rw-r--r--UefiCpuPkg/UefiCpuPkg.dsc1
7 files changed, 200 insertions, 184 deletions
diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
index 8c8b81d933..cd07de3a3c 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 - 2022, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2016 - 2021, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
@@ -24,11 +24,9 @@
[Sources.IA32]
Ia32/AmdSev.c
Ia32/MpFuncs.nasm
- Ia32/CreatePageTable.c
[Sources.X64]
X64/AmdSev.c
- X64/CreatePageTable.c
X64/MpFuncs.nasm
[Sources.common]
@@ -59,9 +57,6 @@
CcExitLib
MicrocodeLib
-[LibraryClasses.X64]
- CpuPageTableLib
-
[Protocols]
gEfiTimerArchProtocolGuid ## SOMETIMES_CONSUMES
diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
index beab06a5b1..445e0853d2 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
@@ -28,7 +28,6 @@ volatile BOOLEAN mStopCheckAllApsStatus = TRUE;
VOID *mReservedApLoopFunc = NULL;
UINTN mReservedTopOfApStack;
volatile UINT32 mNumberToFinish = 0;
-UINTN mApPageTable;
//
// Begin wakeup buffer allocation below 0x88000
@@ -408,9 +407,12 @@ RelocateApLoop (
AsmRelocateApLoopFunc (
MwaitSupport,
CpuMpData->ApTargetCState,
+ CpuMpData->PmCodeSegment,
StackStart - ProcessorNumber * AP_SAFE_STACK_SIZE,
(UINTN)&mNumberToFinish,
- mApPageTable
+ CpuMpData->Pm16CodeSegment,
+ CpuMpData->SevEsAPBuffer,
+ CpuMpData->WakeupBuffer
);
}
@@ -475,6 +477,7 @@ InitMpGlobalData (
)
{
EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS Address;
UINTN ApSafeBufferSize;
UINTN Index;
EFI_GCD_MEMORY_SPACE_DESCRIPTOR MemDesc;
@@ -542,45 +545,60 @@ InitMpGlobalData (
// Allocating it in advance since memory services are not available in
// Exit Boot Services callback function.
//
- // +------------+
- // | Ap Loop |
- // +------------+
- // | Stack * N |
- // +------------+ (low address)
- //
ApSafeBufferSize = EFI_PAGES_TO_SIZE (
EFI_SIZE_TO_PAGES (
- CpuMpData->CpuCount * AP_SAFE_STACK_SIZE
- + CpuMpData->AddressMap.RelocateApLoopFuncSize
+ CpuMpData->AddressMap.RelocateApLoopFuncSize
)
);
+ Address = BASE_4GB - 1;
+ Status = gBS->AllocatePages (
+ AllocateMaxAddress,
+ EfiReservedMemoryType,
+ EFI_SIZE_TO_PAGES (ApSafeBufferSize),
+ &Address
+ );
+ ASSERT_EFI_ERROR (Status);
- mReservedTopOfApStack = (UINTN)AllocateReservedPages (EFI_SIZE_TO_PAGES (ApSafeBufferSize));
- ASSERT (mReservedTopOfApStack != 0);
- ASSERT ((mReservedTopOfApStack & (UINTN)(CPU_STACK_ALIGNMENT - 1)) == 0);
- ASSERT ((AP_SAFE_STACK_SIZE & (CPU_STACK_ALIGNMENT - 1)) == 0);
-
- mReservedApLoopFunc = (VOID *)(mReservedTopOfApStack + CpuMpData->CpuCount * AP_SAFE_STACK_SIZE);
- if (StandardSignatureIsAuthenticAMD ()) {
- CopyMem (
- mReservedApLoopFunc,
- CpuMpData->AddressMap.RelocateApLoopFuncAddressAmd,
- CpuMpData->AddressMap.RelocateApLoopFuncSizeAmd
- );
- } else {
- CopyMem (
- mReservedApLoopFunc,
- CpuMpData->AddressMap.RelocateApLoopFuncAddress,
- CpuMpData->AddressMap.RelocateApLoopFuncSize
- );
+ mReservedApLoopFunc = (VOID *)(UINTN)Address;
+ ASSERT (mReservedApLoopFunc != NULL);
- mApPageTable = CreatePageTable (
- mReservedTopOfApStack,
- ApSafeBufferSize
- );
+ //
+ // Make sure that the buffer 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.
+ //
+ Status = gDS->GetMemorySpaceDescriptor (Address, &MemDesc);
+ if (!EFI_ERROR (Status)) {
+ gDS->SetMemorySpaceAttributes (
+ Address,
+ ApSafeBufferSize,
+ MemDesc.Attributes & (~EFI_MEMORY_XP)
+ );
}
- mReservedTopOfApStack += CpuMpData->CpuCount * AP_SAFE_STACK_SIZE;
+ 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;
+ ASSERT ((mReservedTopOfApStack & (UINTN)(CPU_STACK_ALIGNMENT - 1)) == 0);
+ CopyMem (
+ mReservedApLoopFunc,
+ CpuMpData->AddressMap.RelocateApLoopFuncAddress,
+ CpuMpData->AddressMap.RelocateApLoopFuncSize
+ );
Status = gBS->CreateEvent (
EVT_TIMER | EVT_NOTIFY_SIGNAL,
diff --git a/UefiCpuPkg/Library/MpInitLib/Ia32/CreatePageTable.c b/UefiCpuPkg/Library/MpInitLib/Ia32/CreatePageTable.c
deleted file mode 100644
index 525885b77d..0000000000
--- a/UefiCpuPkg/Library/MpInitLib/Ia32/CreatePageTable.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/** @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/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index 13d515c2df..1102003a93 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -392,9 +392,12 @@ typedef
(EFIAPI *ASM_RELOCATE_AP_LOOP)(
IN BOOLEAN MwaitSupport,
IN UINTN ApTargetCState,
+ IN UINTN PmCodeSegment,
IN UINTN TopOfApStack,
IN UINTN NumberToFinish,
- IN UINTN Cr3
+ IN UINTN Pm16CodeSegment,
+ IN UINTN SevEsAPJumpTable,
+ IN UINTN WakeupBuffer
);
/**
@@ -510,20 +513,6 @@ WakeUpAP (
);
/**
- 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
- );
-
-/**
Initialize global data for MP support.
@param[in] CpuMpData The pointer to CPU MP Data structure.
diff --git a/UefiCpuPkg/Library/MpInitLib/X64/CreatePageTable.c b/UefiCpuPkg/Library/MpInitLib/X64/CreatePageTable.c
deleted file mode 100644
index 548ef3f2c8..0000000000
--- a/UefiCpuPkg/Library/MpInitLib/X64/CreatePageTable.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/** @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>
-
-/**
- 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;
-
- 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;
-
- Status = PageTableMap (
- &PageTable,
- Paging4Level,
- 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,
- Paging4Level,
- 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 8ae287dd8d..39c3e8606a 100644
--- a/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
+++ b/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
@@ -279,42 +279,120 @@ CProcedureInvoke:
RendezvousFunnelProcEnd:
;-------------------------------------------------------------------------------------
-; 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.
+; AsmRelocateApLoop (MwaitSupport, ApTargetCState, PmCodeSegment, TopOfApStack, CountTofinish, Pm16CodeSegment, SevEsAPJumpTable, WakeupBuffer);
;-------------------------------------------------------------------------------------
-; +----------------+
-; | Cr3 | rsp+40
-; +----------------+
-; | CountTofinish | r9
-; +----------------+
-; | TopOfApStack | r8
-; +----------------+
-; | ApTargetCState | rdx
-; +----------------+
-; | MwaitSupport | rcx
-; +----------------+
-; | the return |
-; +----------------+ low address
-
AsmRelocateApLoopStart:
- mov rax, r9 ; CountTofinish
+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
+
+ pop rdx
+ pop rcx
+
+NoSevEs:
+ cli ; Disable interrupt before switching to 32-bit mode
+ mov rax, [rsp + 40] ; CountTofinish
lock dec dword [rax] ; (*CountTofinish)--
- 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
+ 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
MwaitCheck:
cmp cl, 1 ; Check mwait-monitor support
jnz HltLoop
- mov rbx, rdx ; Save C-State to ebx
-
+ mov ebx, edx ; Save C-State to ebx
MwaitLoop:
cli
- mov rax, rsp ; Set Monitor Address
+ mov eax, esp ; Set Monitor Address
xor ecx, ecx ; ecx = 0
xor edx, edx ; edx = 0
monitor
@@ -324,10 +402,49 @@ MwaitLoop:
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 HltLoop
+ jmp DoHlt
+BITS 64
AsmRelocateApLoopEnd:
;-------------------------------------------------------------------------------------
diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc
index 781acedfc5..f9a46089d2 100644
--- a/UefiCpuPkg/UefiCpuPkg.dsc
+++ b/UefiCpuPkg/UefiCpuPkg.dsc
@@ -94,7 +94,6 @@
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