[PATCH v3 3/5] MpInitLib: Put SEV logic in separate file


Ni, Ray
 

The patch does several simplifications:
1. Treat SwitchToRealProc as part of RendezvousFunnelProc.
So the common logic in MpLib.c doesn't need to be aware of
SwitchToRealProc.
As a result, SwitchToRealSize/Offset are removed from
MP_ASSEMBLY_ADDRESS_MAP.

2. Move SwitchToRealProc to AmdSev.nasm.
All other assembly code in AmdSev.nasm is called through
OneTimeCall.

Signed-off-by: Ray Ni <ray.ni@...>
Cc: Eric Dong <eric.dong@...>
Cc: Ray Ni <ray.ni@...>
Cc: Rahul Kumar <rahul1.kumar@...>
Cc: Michael Roth <michael.roth@...>
Cc: James Bottomley <jejb@...>
Cc: Min Xu <min.m.xu@...>
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Tom Lendacky <thomas.lendacky@...>
Cc: Jordan Justen <jordan.l.justen@...>
Cc: Ard Biesheuvel <ardb+tianocore@...>
Cc: Erdem Aktas <erdemaktas@...>
Cc: Gerd Hoffmann <kraxel@...>
---
.../Library/MpInitLib/Ia32/MpFuncs.nasm | 5 +-
UefiCpuPkg/Library/MpInitLib/MpEqu.inc | 4 +-
UefiCpuPkg/Library/MpInitLib/MpLib.c | 13 +-
UefiCpuPkg/Library/MpInitLib/MpLib.h | 4 +-
UefiCpuPkg/Library/MpInitLib/X64/AmdSev.nasm | 148 ++++++++++++++++
UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm | 159 +-----------------
6 files changed, 161 insertions(+), 172 deletions(-)

diff --git a/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm b/UefiCpuPkg/Li=
brary/MpInitLib/Ia32/MpFuncs.nasm
index 8981c32722..28301bb8f0 100644
--- a/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm
+++ b/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm
@@ -199,7 +199,6 @@ CProcedureInvoke:
call eax ; Invoke C function=0D
=0D
jmp $ ; Never reach here=0D
-RendezvousFunnelProcEnd:=0D
=0D
;-------------------------------------------------------------------------=
------------=0D
;SwitchToRealProc procedure follows.=0D
@@ -209,6 +208,8 @@ SwitchToRealProcStart:
jmp $ ; Never reach here=0D
SwitchToRealProcEnd:=0D
=0D
+RendezvousFunnelProcEnd:=0D
+=0D
;-------------------------------------------------------------------------=
------------=0D
; AsmRelocateApLoop (MwaitSupport, ApTargetCState, PmCodeSegment, TopOfAp=
Stack, CountTofinish, Pm16CodeSegment, SevEsAPJumpTable, WakeupBuffer);=0D
;=0D
@@ -258,8 +259,6 @@ ASM_PFX(AsmGetAddressMap):
mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.RelocateApLoopFuncAddr=
ess], AsmRelocateApLoopStart=0D
mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.RelocateApLoopFuncSize=
], AsmRelocateApLoopEnd - AsmRelocateApLoopStart=0D
mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.ModeTransitionOffset],=
Flat32Start - RendezvousFunnelProcStart=0D
- mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealSize], Swi=
tchToRealProcEnd - SwitchToRealProcStart=0D
- mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealOffset], S=
witchToRealProcStart - RendezvousFunnelProcStart=0D
mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealNoNxOffset=
], SwitchToRealProcStart - Flat32Start=0D
mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealPM16ModeOf=
fset], 0=0D
mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealPM16ModeSi=
ze], 0=0D
diff --git a/UefiCpuPkg/Library/MpInitLib/MpEqu.inc b/UefiCpuPkg/Library/Mp=
InitLib/MpEqu.inc
index aba53f5720..1cc071cf7b 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpEqu.inc
+++ b/UefiCpuPkg/Library/MpInitLib/MpEqu.inc
@@ -1,5 +1,5 @@
;-------------------------------------------------------------------------=
----- ;=0D
-; Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved.<BR>=0D
+; Copyright (c) 2015 - 2022, Intel Corporation. All rights reserved.<BR>=0D
; SPDX-License-Identifier: BSD-2-Clause-Patent=0D
;=0D
; Module Name:=0D
@@ -27,8 +27,6 @@ struc MP_ASSEMBLY_ADDRESS_MAP
.RelocateApLoopFuncAddress CTYPE_UINTN 1=0D
.RelocateApLoopFuncSize CTYPE_UINTN 1=0D
.ModeTransitionOffset CTYPE_UINTN 1=0D
- .SwitchToRealSize CTYPE_UINTN 1=0D
- .SwitchToRealOffset CTYPE_UINTN 1=0D
.SwitchToRealNoNxOffset CTYPE_UINTN 1=0D
.SwitchToRealPM16ModeOffset CTYPE_UINTN 1=0D
.SwitchToRealPM16ModeSize CTYPE_UINTN 1=0D
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpIn=
itLib/MpLib.c
index d761bdc487..aa0eb9a70b 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -936,8 +936,7 @@ FillExchangeInfoData (
// EfiBootServicesCode to avoid page fault if NX memory protection is en=
abled.=0D
//=0D
if (CpuMpData->WakeupBufferHigh !=3D 0) {=0D
- Size =3D CpuMpData->AddressMap.RendezvousFunnelSize +=0D
- CpuMpData->AddressMap.SwitchToRealSize -=0D
+ Size =3D CpuMpData->AddressMap.RendezvousFunnelSize -=0D
CpuMpData->AddressMap.ModeTransitionOffset;=0D
CopyMem (=0D
(VOID *)CpuMpData->WakeupBufferHigh,=0D
@@ -991,8 +990,7 @@ BackupAndPrepareWakeupBuffer (
CopyMem (=0D
(VOID *)CpuMpData->WakeupBuffer,=0D
(VOID *)CpuMpData->AddressMap.RendezvousFunnelAddress,=0D
- CpuMpData->AddressMap.RendezvousFunnelSize +=0D
- CpuMpData->AddressMap.SwitchToRealSize=0D
+ CpuMpData->AddressMap.RendezvousFunnelSize=0D
);=0D
}=0D
=0D
@@ -1029,7 +1027,6 @@ GetApResetVectorSize (
UINTN Size;=0D
=0D
Size =3D AddressMap->RendezvousFunnelSize +=0D
- AddressMap->SwitchToRealSize +=0D
sizeof (MP_CPU_EXCHANGE_INFO);=0D
=0D
return Size;=0D
@@ -1054,11 +1051,9 @@ AllocateResetVector (
CpuMpData->WakeupBuffer =3D GetWakeupBuffer (ApResetVectorSize);=
=0D
CpuMpData->MpCpuExchangeInfo =3D (MP_CPU_EXCHANGE_INFO *)(UINTN)=0D
(CpuMpData->WakeupBuffer +=0D
- CpuMpData->AddressMap.RendezvousFunnel=
Size +=0D
- CpuMpData->AddressMap.SwitchToRealSize=
);=0D
+ CpuMpData->AddressMap.RendezvousFunnel=
Size);=0D
CpuMpData->WakeupBufferHigh =3D AllocateCodeBuffer (=0D
- CpuMpData->AddressMap.RendezvousFunnel=
Size +=0D
- CpuMpData->AddressMap.SwitchToRealSize=
-=0D
+ CpuMpData->AddressMap.RendezvousFunnel=
Size -=0D
CpuMpData->AddressMap.ModeTransitionOf=
fset=0D
);=0D
//=0D
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpIn=
itLib/MpLib.h
index 59ab960897..974fb76019 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -1,7 +1,7 @@
/** @file=0D
Common header file for MP Initialize Library.=0D
=0D
- Copyright (c) 2016 - 2021, Intel Corporation. All rights reserved.<BR>=0D
+ Copyright (c) 2016 - 2022, Intel Corporation. All rights reserved.<BR>=0D
Copyright (c) 2020, AMD Inc. All rights reserved.<BR>=0D
=0D
SPDX-License-Identifier: BSD-2-Clause-Patent=0D
@@ -181,8 +181,6 @@ typedef struct {
UINT8 *RelocateApLoopFuncAddress;=0D
UINTN RelocateApLoopFuncSize;=0D
UINTN ModeTransitionOffset;=0D
- UINTN SwitchToRealSize;=0D
- UINTN SwitchToRealOffset;=0D
UINTN SwitchToRealNoNxOffset;=0D
UINTN SwitchToRealPM16ModeOffset;=0D
UINTN SwitchToRealPM16ModeSize;=0D
diff --git a/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.nasm b/UefiCpuPkg/Libr=
ary/MpInitLib/X64/AmdSev.nasm
index 8bb1161fa0..7c2469f9c5 100644
--- a/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.nasm
+++ b/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.nasm
@@ -198,3 +198,151 @@ RestoreGhcb:
=0D
SevEsGetApicIdExit:=0D
OneTimeCallRet SevEsGetApicId=0D
+=0D
+=0D
+;-------------------------------------------------------------------------=
------------=0D
+;SwitchToRealProc procedure follows.=0D
+;ALSO THIS PROCEDURE IS EXECUTED BY APs TRANSITIONING TO 16 BIT MODE. HENC=
E THIS PROC=0D
+;IS IN MACHINE CODE.=0D
+; SwitchToRealProc (UINTN BufferStart, UINT16 Code16, UINT16 Code32, UINT=
N StackStart)=0D
+; rcx - Buffer Start=0D
+; rdx - Code16 Selector Offset=0D
+; r8 - Code32 Selector Offset=0D
+; r9 - Stack Start=0D
+;-------------------------------------------------------------------------=
------------=0D
+SwitchToRealProcStart:=0D
+BITS 64=0D
+ cli=0D
+=0D
+ ;=0D
+ ; Get RDX reset value before changing stacks since the=0D
+ ; new stack won't be able to accomodate a #VC exception.=0D
+ ;=0D
+ push rax=0D
+ push rbx=0D
+ push rcx=0D
+ push rdx=0D
+=0D
+ mov rax, 1=0D
+ cpuid=0D
+ mov rsi, rax ; Save off the reset value for =
RDX=0D
+=0D
+ pop rdx=0D
+ pop rcx=0D
+ pop rbx=0D
+ pop rax=0D
+=0D
+ ;=0D
+ ; Establish stack below 1MB=0D
+ ;=0D
+ mov rsp, r9=0D
+=0D
+ ;=0D
+ ; Push ultimate Reset Vector onto the stack=0D
+ ;=0D
+ mov rax, rcx=0D
+ shr rax, 4=0D
+ push word 0x0002 ; RFLAGS=0D
+ push ax ; CS=0D
+ push word 0x0000 ; RIP=0D
+ push word 0x0000 ; For alignment, will be discar=
ded=0D
+=0D
+ ;=0D
+ ; Get address of "16-bit operand size" label=0D
+ ;=0D
+ lea rbx, [PM16Mode]=0D
+=0D
+ ;=0D
+ ; Push addresses used to change to compatibility mode=0D
+ ;=0D
+ lea rax, [CompatMode]=0D
+ push r8=0D
+ push rax=0D
+=0D
+ ;=0D
+ ; Clear R8 - R15, for reset, before going into 32-bit mode=0D
+ ;=0D
+ xor r8, r8=0D
+ xor r9, r9=0D
+ xor r10, r10=0D
+ xor r11, r11=0D
+ xor r12, r12=0D
+ xor r13, r13=0D
+ xor r14, r14=0D
+ xor r15, r15=0D
+=0D
+ ;=0D
+ ; Far return into 32-bit mode=0D
+ ;=0D
+ retfq=0D
+=0D
+BITS 32=0D
+CompatMode:=0D
+ ;=0D
+ ; Set up stack to prepare for exiting protected mode=0D
+ ;=0D
+ push edx ; Code16 CS=0D
+ push ebx ; PM16Mode label address=0D
+=0D
+ ;=0D
+ ; Disable paging=0D
+ ;=0D
+ mov eax, cr0 ; Read CR0=0D
+ btr eax, 31 ; Set PG=3D0=0D
+ mov cr0, eax ; Write CR0=0D
+=0D
+ ;=0D
+ ; Disable long mode=0D
+ ;=0D
+ mov ecx, 0c0000080h ; EFER MSR number=0D
+ rdmsr ; Read EFER=0D
+ btr eax, 8 ; Set LME=3D0=0D
+ wrmsr ; Write EFER=0D
+=0D
+ ;=0D
+ ; Disable PAE=0D
+ ;=0D
+ mov eax, cr4 ; Read CR4=0D
+ btr eax, 5 ; Set PAE=3D0=0D
+ mov cr4, eax ; Write CR4=0D
+=0D
+ mov edx, esi ; Restore RDX reset value=0D
+=0D
+ ;=0D
+ ; Switch to 16-bit operand size=0D
+ ;=0D
+ retf=0D
+=0D
+BITS 16=0D
+ ;=0D
+ ; At entry to this label=0D
+ ; - RDX will have its reset value=0D
+ ; - On the top of the stack=0D
+ ; - Alignment data (two bytes) to be discarded=0D
+ ; - IP for Real Mode (two bytes)=0D
+ ; - CS for Real Mode (two bytes)=0D
+ ;=0D
+ ; This label is also used with AsmRelocateApLoop. During MP finalizati=
on,=0D
+ ; the code from PM16Mode to SwitchToRealProcEnd is copied to the start=
of=0D
+ ; the WakeupBuffer, allowing a parked AP to be booted by an OS.=0D
+ ;=0D
+PM16Mode:=0D
+ mov eax, cr0 ; Read CR0=0D
+ btr eax, 0 ; Set PE=3D0=0D
+ mov cr0, eax ; Write CR0=0D
+=0D
+ pop ax ; Discard alignment data=0D
+=0D
+ ;=0D
+ ; Clear registers (except RDX and RSP) before going into 16-bit mode=0D
+ ;=0D
+ xor eax, eax=0D
+ xor ebx, ebx=0D
+ xor ecx, ecx=0D
+ xor esi, esi=0D
+ xor edi, edi=0D
+ xor ebp, ebp=0D
+=0D
+ iret=0D
+=0D
+SwitchToRealProcEnd:=0D
diff --git a/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm b/UefiCpuPkg/Lib=
rary/MpInitLib/X64/MpFuncs.nasm
index d7e0e1fabd..1daaa72b1e 100644
--- a/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
+++ b/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
@@ -152,11 +152,6 @@ SkipEnable5LevelPaging:
=0D
BITS 64=0D
=0D
-;=0D
-; Required for the AMD SEV helper functions=0D
-;=0D
-%include "AmdSev.nasm"=0D
-=0D
LongModeStart:=0D
mov esi, ebx=0D
lea edi, [esi + MP_CPU_EXCHANGE_INFO_FIELD (InitFlag)]=0D
@@ -265,154 +260,12 @@ CProcedureInvoke:
add rsp, 20h=0D
jmp $ ; Should never reach here=0D
=0D
-RendezvousFunnelProcEnd:=0D
-=0D
-;-------------------------------------------------------------------------=
------------=0D
-;SwitchToRealProc procedure follows.=0D
-;ALSO THIS PROCEDURE IS EXECUTED BY APs TRANSITIONING TO 16 BIT MODE. HENC=
E THIS PROC=0D
-;IS IN MACHINE CODE.=0D
-; SwitchToRealProc (UINTN BufferStart, UINT16 Code16, UINT16 Code32, UINT=
N StackStart)=0D
-; rcx - Buffer Start=0D
-; rdx - Code16 Selector Offset=0D
-; r8 - Code32 Selector Offset=0D
-; r9 - Stack Start=0D
-;-------------------------------------------------------------------------=
------------=0D
-SwitchToRealProcStart:=0D
-BITS 64=0D
- cli=0D
-=0D
- ;=0D
- ; Get RDX reset value before changing stacks since the=0D
- ; new stack won't be able to accomodate a #VC exception.=0D
- ;=0D
- push rax=0D
- push rbx=0D
- push rcx=0D
- push rdx=0D
-=0D
- mov rax, 1=0D
- cpuid=0D
- mov rsi, rax ; Save off the reset value for =
RDX=0D
-=0D
- pop rdx=0D
- pop rcx=0D
- pop rbx=0D
- pop rax=0D
-=0D
- ;=0D
- ; Establish stack below 1MB=0D
- ;=0D
- mov rsp, r9=0D
-=0D
- ;=0D
- ; Push ultimate Reset Vector onto the stack=0D
- ;=0D
- mov rax, rcx=0D
- shr rax, 4=0D
- push word 0x0002 ; RFLAGS=0D
- push ax ; CS=0D
- push word 0x0000 ; RIP=0D
- push word 0x0000 ; For alignment, will be discar=
ded=0D
-=0D
- ;=0D
- ; Get address of "16-bit operand size" label=0D
- ;=0D
- lea rbx, [PM16Mode]=0D
-=0D
- ;=0D
- ; Push addresses used to change to compatibility mode=0D
- ;=0D
- lea rax, [CompatMode]=0D
- push r8=0D
- push rax=0D
-=0D
- ;=0D
- ; Clear R8 - R15, for reset, before going into 32-bit mode=0D
- ;=0D
- xor r8, r8=0D
- xor r9, r9=0D
- xor r10, r10=0D
- xor r11, r11=0D
- xor r12, r12=0D
- xor r13, r13=0D
- xor r14, r14=0D
- xor r15, r15=0D
-=0D
- ;=0D
- ; Far return into 32-bit mode=0D
- ;=0D
- retfq=0D
-=0D
-BITS 32=0D
-CompatMode:=0D
- ;=0D
- ; Set up stack to prepare for exiting protected mode=0D
- ;=0D
- push edx ; Code16 CS=0D
- push ebx ; PM16Mode label address=0D
-=0D
- ;=0D
- ; Disable paging=0D
- ;=0D
- mov eax, cr0 ; Read CR0=0D
- btr eax, 31 ; Set PG=3D0=0D
- mov cr0, eax ; Write CR0=0D
-=0D
- ;=0D
- ; Disable long mode=0D
- ;=0D
- mov ecx, 0c0000080h ; EFER MSR number=0D
- rdmsr ; Read EFER=0D
- btr eax, 8 ; Set LME=3D0=0D
- wrmsr ; Write EFER=0D
-=0D
- ;=0D
- ; Disable PAE=0D
- ;=0D
- mov eax, cr4 ; Read CR4=0D
- btr eax, 5 ; Set PAE=3D0=0D
- mov cr4, eax ; Write CR4=0D
-=0D
- mov edx, esi ; Restore RDX reset value=0D
-=0D
- ;=0D
- ; Switch to 16-bit operand size=0D
- ;=0D
- retf=0D
-=0D
-BITS 16=0D
- ;=0D
- ; At entry to this label=0D
- ; - RDX will have its reset value=0D
- ; - On the top of the stack=0D
- ; - Alignment data (two bytes) to be discarded=0D
- ; - IP for Real Mode (two bytes)=0D
- ; - CS for Real Mode (two bytes)=0D
- ;=0D
- ; This label is also used with AsmRelocateApLoop. During MP finalizati=
on,=0D
- ; the code from PM16Mode to SwitchToRealProcEnd is copied to the start=
of=0D
- ; the WakeupBuffer, allowing a parked AP to be booted by an OS.=0D
- ;=0D
-PM16Mode:=0D
- mov eax, cr0 ; Read CR0=0D
- btr eax, 0 ; Set PE=3D0=0D
- mov cr0, eax ; Write CR0=0D
-=0D
- pop ax ; Discard alignment data=0D
-=0D
- ;=0D
- ; Clear registers (except RDX and RSP) before going into 16-bit mode=0D
- ;=0D
- xor eax, eax=0D
- xor ebx, ebx=0D
- xor ecx, ecx=0D
- xor esi, esi=0D
- xor edi, edi=0D
- xor ebp, ebp=0D
-=0D
- iret=0D
+;=0D
+; Required for the AMD SEV helper functions=0D
+;=0D
+%include "AmdSev.nasm"=0D
=0D
-SwitchToRealProcEnd:=0D
+RendezvousFunnelProcEnd:=0D
=0D
;-------------------------------------------------------------------------=
------------=0D
; AsmRelocateApLoop (MwaitSupport, ApTargetCState, PmCodeSegment, TopOfAp=
Stack, CountTofinish, Pm16CodeSegment, SevEsAPJumpTable, WakeupBuffer);=0D
@@ -596,8 +449,6 @@ ASM_PFX(AsmGetAddressMap):
mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.RelocateApLoopFuncAddr=
ess], rax=0D
mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.RelocateApLoopFuncSize=
], AsmRelocateApLoopEnd - AsmRelocateApLoopStart=0D
mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.ModeTransitionOffset],=
Flat32Start - RendezvousFunnelProcStart=0D
- mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealSize], Swi=
tchToRealProcEnd - SwitchToRealProcStart=0D
- mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealOffset], S=
witchToRealProcStart - RendezvousFunnelProcStart=0D
mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealNoNxOffset=
], SwitchToRealProcStart - Flat32Start=0D
mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealPM16ModeOf=
fset], PM16Mode - RendezvousFunnelProcStart=0D
mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealPM16ModeSi=
ze], SwitchToRealProcEnd - PM16Mode=0D
--=20
2.35.1.windows.2

Join devel@edk2.groups.io to automatically receive all group messages.