* [PATCH V2 0/6] Enable Multi-core based lazy-accept for TDVF
@ 2022-12-20 8:42 Min Xu
2022-12-20 8:42 ` [PATCH V2 1/6] OvmfPkg/TdxMailboxLib: Delete global variables Min Xu
` (6 more replies)
0 siblings, 7 replies; 8+ messages in thread
From: Min Xu @ 2022-12-20 8:42 UTC (permalink / raw)
To: devel
Cc: Min Xu, Erdem Aktas, Gerd Hoffmann, James Bottomley, Jiewen Yao,
Tom Lendacky
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4172
TDVF once accepts memory only by BSP. To improve the boot performance
this patch-set introduce the multi-core accpet memory. Multi-core means
BSP and APs work together to accept memory.
TDVF leverages mailbox to wake up APs. It is not enabled in MpInitLib
(Which requires SIPI). So multi-core accept memory cannot leverages
MpInitLib to coordinate BSP and APs to work together.
So TDVF split the accept memory into 2 phases.
- AcceptMemoryForAPsStack:
BSP accepts a small piece of memory which is then used by APs to setup
stack. We assign a 16KB stack for each AP. So a td-guest with 256 vCPU
requires 255*16KB = 4080KB.
- AcceptMemory:
After above small piece of memory is accepted, BSP commands APs to
accept memory by sending AcceptPages command in td-mailbox. Together
with the command and accpet-function, the APsStack address is send
as well. APs then set the stack and jump to accept-function to accept
memory.
Patch 1-3:
TdxMailboxLib is refactored to help multi-core lazy accept.
Patch 4-5:
Refactor APs' logical to support accpet page.
Patch 6:
Implement multi-core accept in TDVF.
Code: https://github.com/mxu9/edk2/tree/Multi-Core-Lazy-Accept.v2
v2 changes:
- Fix an override error when vCPU number is larger than 64.
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
Min M Xu (6):
OvmfPkg/TdxMailboxLib: Delete global variables
OvmfPkg/TdxMailboxLib: Add NULL instance of TdxMailboxLib
OvmfPkg: Add TdxMailboxLibNull in some platform dsc
OvmfPkg/Sec: Move TDX APs related nasm code to IntelTdxAPs.nasm
OvmfPkg: Enable APs to accept memory for TDVF
OvmfPkg/PlatformInitLib: Implement multi-core accept memory for TDVF
OvmfPkg/AmdSev/AmdSevX64.dsc | 1 +
OvmfPkg/CloudHv/CloudHvX64.dsc | 1 +
OvmfPkg/Include/TdxCommondefs.inc | 4 +-
OvmfPkg/IntelTdx/Sec/X64/IntelTdxAPs.nasm | 119 +++++
OvmfPkg/IntelTdx/Sec/X64/SecEntry.nasm | 58 +--
OvmfPkg/Library/PlatformInitLib/IntelTdx.c | 411 +++++++++++++++---
.../PlatformInitLib/PlatformInitLib.inf | 1 +
OvmfPkg/Library/TdxMailboxLib/TdxMailbox.c | 22 +-
.../Library/TdxMailboxLib/TdxMailboxLib.inf | 7 +-
.../TdxMailboxLib/TdxMailboxLibNull.inf | 34 ++
OvmfPkg/Microvm/MicrovmX64.dsc | 1 +
OvmfPkg/OvmfPkgIa32.dsc | 1 +
OvmfPkg/OvmfPkgIa32X64.dsc | 2 +-
OvmfPkg/Sec/X64/SecEntry.nasm | 58 +--
14 files changed, 545 insertions(+), 175 deletions(-)
create mode 100644 OvmfPkg/IntelTdx/Sec/X64/IntelTdxAPs.nasm
create mode 100644 OvmfPkg/Library/TdxMailboxLib/TdxMailboxLibNull.inf
--
2.29.2.windows.2
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH V2 1/6] OvmfPkg/TdxMailboxLib: Delete global variables
2022-12-20 8:42 [PATCH V2 0/6] Enable Multi-core based lazy-accept for TDVF Min Xu
@ 2022-12-20 8:42 ` Min Xu
2022-12-20 8:42 ` [PATCH V2 2/6] OvmfPkg/TdxMailboxLib: Add NULL instance of TdxMailboxLib Min Xu
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Min Xu @ 2022-12-20 8:42 UTC (permalink / raw)
To: devel
Cc: Min M Xu, Erdem Aktas, Gerd Hoffmann, James Bottomley, Jiewen Yao,
Tom Lendacky
From: Min M Xu <min.m.xu@intel.com>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4172
TdxMailboxLib once was designed to be used in DXE phase. But now it is
going to be used in SEC/PEI phase (in the following patches). Global
variables are not allowed. The library is refactored after those global
variables are deleted.
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
---
OvmfPkg/Library/TdxMailboxLib/TdxMailbox.c | 22 ++++++++++------------
1 file changed, 10 insertions(+), 12 deletions(-)
diff --git a/OvmfPkg/Library/TdxMailboxLib/TdxMailbox.c b/OvmfPkg/Library/TdxMailboxLib/TdxMailbox.c
index 74cb55611fe3..c580a2885603 100644
--- a/OvmfPkg/Library/TdxMailboxLib/TdxMailbox.c
+++ b/OvmfPkg/Library/TdxMailboxLib/TdxMailbox.c
@@ -13,14 +13,10 @@
#include <Library/UefiCpuLib.h>
#include <Library/SynchronizationLib.h>
#include <Uefi/UefiBaseType.h>
-#include <Library/TdxLib.h>
#include <IndustryStandard/IntelTdx.h>
#include <IndustryStandard/Tdx.h>
#include <Library/TdxMailboxLib.h>
-volatile VOID *mMailBox = NULL;
-UINT32 mNumOfCpus = 0;
-
/**
This function will be called by BSP to get the CPU number.
@@ -32,11 +28,17 @@ GetCpusNum (
VOID
)
{
- if (mNumOfCpus == 0) {
- mNumOfCpus = TdVCpuNum ();
+ UINT64 Status;
+ TD_RETURN_DATA TdReturnData;
+
+ Status = TdCall (TDCALL_TDINFO, 0, 0, 0, &TdReturnData);
+ if (Status == TDX_EXIT_REASON_SUCCESS) {
+ return TdReturnData.TdInfo.NumVcpus;
+ } else {
+ DEBUG ((DEBUG_ERROR, "Failed call TDCALL_TDINFO. %llx\n", Status));
}
- return mNumOfCpus;
+ return 0;
}
/**
@@ -48,11 +50,7 @@ GetTdxMailBox (
VOID
)
{
- if (mMailBox == NULL) {
- mMailBox = (VOID *)(UINTN)PcdGet32 (PcdOvmfSecGhcbBackupBase);
- }
-
- return mMailBox;
+ return (VOID *)(UINTN)PcdGet32 (PcdOvmfSecGhcbBackupBase);
}
/**
--
2.29.2.windows.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH V2 2/6] OvmfPkg/TdxMailboxLib: Add NULL instance of TdxMailboxLib
2022-12-20 8:42 [PATCH V2 0/6] Enable Multi-core based lazy-accept for TDVF Min Xu
2022-12-20 8:42 ` [PATCH V2 1/6] OvmfPkg/TdxMailboxLib: Delete global variables Min Xu
@ 2022-12-20 8:42 ` Min Xu
2022-12-20 8:42 ` [PATCH V2 3/6] OvmfPkg: Add TdxMailboxLibNull in some platform dsc Min Xu
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Min Xu @ 2022-12-20 8:42 UTC (permalink / raw)
To: devel
Cc: Min M Xu, Erdem Aktas, Gerd Hoffmann, James Bottomley, Jiewen Yao,
Tom Lendacky
From: Min M Xu <min.m.xu@intel.com>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4172
TdxMailboxLib is designed only for TDX guest which arch is X64. This
patch set the VALID_ARCHITECTURES of TdxMailboxLib as X64.
Because in the following patches TdxMailboxLib will be included in
PlatformInitLib. While PlatformInitLib is imported by some X64 platforms
(for example AmdSevX64.dsc). So we need a NULL instance of TdxMailboxLib
which VALID_ARCHITECTURES is X64 as well. Based on this consideration
we design TdxMailboxLibNull.
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
---
.../Library/TdxMailboxLib/TdxMailboxLib.inf | 7 ++--
.../TdxMailboxLib/TdxMailboxLibNull.inf | 34 +++++++++++++++++++
2 files changed, 36 insertions(+), 5 deletions(-)
create mode 100644 OvmfPkg/Library/TdxMailboxLib/TdxMailboxLibNull.inf
diff --git a/OvmfPkg/Library/TdxMailboxLib/TdxMailboxLib.inf b/OvmfPkg/Library/TdxMailboxLib/TdxMailboxLib.inf
index 3cf3690a16c7..e504bda0dd90 100644
--- a/OvmfPkg/Library/TdxMailboxLib/TdxMailboxLib.inf
+++ b/OvmfPkg/Library/TdxMailboxLib/TdxMailboxLib.inf
@@ -1,6 +1,6 @@
#/** @file
#
-# TBD
+# TdxMailbox Library
#
# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2008, Apple Inc. All rights reserved.<BR>
@@ -19,12 +19,9 @@
LIBRARY_CLASS = TdxMailboxLib
#
-# VALID_ARCHITECTURES = X64 IA32
+# VALID_ARCHITECTURES = X64
#
-[Sources.IA32]
- TdxMailboxNull.c
-
[Sources.X64]
TdxMailbox.c
diff --git a/OvmfPkg/Library/TdxMailboxLib/TdxMailboxLibNull.inf b/OvmfPkg/Library/TdxMailboxLib/TdxMailboxLibNull.inf
new file mode 100644
index 000000000000..8380d9f4f6d8
--- /dev/null
+++ b/OvmfPkg/Library/TdxMailboxLib/TdxMailboxLibNull.inf
@@ -0,0 +1,34 @@
+#/** @file
+#
+# Null instance of TdxMailboxLib
+#
+# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2008, Apple Inc. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = TdxMailboxLibNull
+ FILE_GUID = 002a1265-a1a0-47cd-bc69-4342b147f57d
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = TdxMailboxLib
+
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ TdxMailboxNull.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
--
2.29.2.windows.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH V2 3/6] OvmfPkg: Add TdxMailboxLibNull in some platform dsc
2022-12-20 8:42 [PATCH V2 0/6] Enable Multi-core based lazy-accept for TDVF Min Xu
2022-12-20 8:42 ` [PATCH V2 1/6] OvmfPkg/TdxMailboxLib: Delete global variables Min Xu
2022-12-20 8:42 ` [PATCH V2 2/6] OvmfPkg/TdxMailboxLib: Add NULL instance of TdxMailboxLib Min Xu
@ 2022-12-20 8:42 ` Min Xu
2022-12-20 8:42 ` [PATCH V2 4/6] OvmfPkg/Sec: Move TDX APs related nasm code to IntelTdxAPs.nasm Min Xu
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Min Xu @ 2022-12-20 8:42 UTC (permalink / raw)
To: devel
Cc: Min M Xu, Erdem Aktas, Gerd Hoffmann, James Bottomley, Jiewen Yao,
Tom Lendacky
From: Min M Xu <min.m.xu@intel.com>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4172
In the following patches TdxMailboxLib will be included in
PlatformInitLib. While PlatformInitLib is imported by some IA32/X64
platforms (for example AmdSevX64.dsc). So TdxMailboxLibNull is added in
those platforms which don't support TDX feature.
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
---
OvmfPkg/AmdSev/AmdSevX64.dsc | 1 +
OvmfPkg/CloudHv/CloudHvX64.dsc | 1 +
OvmfPkg/Microvm/MicrovmX64.dsc | 1 +
OvmfPkg/OvmfPkgIa32.dsc | 1 +
OvmfPkg/OvmfPkgIa32X64.dsc | 2 +-
5 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc
index d51c913a0890..ece4cfa89a86 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.dsc
+++ b/OvmfPkg/AmdSev/AmdSevX64.dsc
@@ -206,6 +206,7 @@
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
CcExitLib|OvmfPkg/Library/CcExitLib/CcExitLib.inf
TdxLib|MdePkg/Library/TdxLib/TdxLib.inf
+ TdxMailboxLib|OvmfPkg/Library/TdxMailboxLib/TdxMailboxLibNull.inf
[LibraryClasses.common.SEC]
TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
diff --git a/OvmfPkg/CloudHv/CloudHvX64.dsc b/OvmfPkg/CloudHv/CloudHvX64.dsc
index 4fe7cb5f1b68..6d76e524167e 100644
--- a/OvmfPkg/CloudHv/CloudHvX64.dsc
+++ b/OvmfPkg/CloudHv/CloudHvX64.dsc
@@ -253,6 +253,7 @@
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
CcExitLib|OvmfPkg/Library/CcExitLib/CcExitLib.inf
TdxLib|MdePkg/Library/TdxLib/TdxLib.inf
+ TdxMailboxLib|OvmfPkg/Library/TdxMailboxLib/TdxMailboxLibNull.inf
[LibraryClasses.common.SEC]
TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
diff --git a/OvmfPkg/Microvm/MicrovmX64.dsc b/OvmfPkg/Microvm/MicrovmX64.dsc
index bcca3afbf666..47df222cf6e7 100644
--- a/OvmfPkg/Microvm/MicrovmX64.dsc
+++ b/OvmfPkg/Microvm/MicrovmX64.dsc
@@ -255,6 +255,7 @@
FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf
VirtioMmioDeviceLib|OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceLib.inf
TdxLib|MdePkg/Library/TdxLib/TdxLib.inf
+ TdxMailboxLib|OvmfPkg/Library/TdxMailboxLib/TdxMailboxLibNull.inf
[LibraryClasses.common.SEC]
QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSecLib.inf
diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index dcf46d207d3d..f617aa60ca43 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -257,6 +257,7 @@
[LibraryClasses.common]
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
CcExitLib|UefiCpuPkg/Library/CcExitLibNull/CcExitLibNull.inf
+ TdxMailboxLib|OvmfPkg/Library/TdxMailboxLib/TdxMailboxLibNull.inf
[LibraryClasses.common.SEC]
TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index bc0036eda0d3..49c71cd00f35 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -262,7 +262,7 @@
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
CcExitLib|UefiCpuPkg/Library/CcExitLibNull/CcExitLibNull.inf
TdxLib|MdePkg/Library/TdxLib/TdxLib.inf
- TdxMailboxLib|OvmfPkg/Library/TdxMailboxLib/TdxMailboxLib.inf
+ TdxMailboxLib|OvmfPkg/Library/TdxMailboxLib/TdxMailboxLibNull.inf
[LibraryClasses.common.SEC]
TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
--
2.29.2.windows.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH V2 4/6] OvmfPkg/Sec: Move TDX APs related nasm code to IntelTdxAPs.nasm
2022-12-20 8:42 [PATCH V2 0/6] Enable Multi-core based lazy-accept for TDVF Min Xu
` (2 preceding siblings ...)
2022-12-20 8:42 ` [PATCH V2 3/6] OvmfPkg: Add TdxMailboxLibNull in some platform dsc Min Xu
@ 2022-12-20 8:42 ` Min Xu
2022-12-20 8:42 ` [PATCH V2 5/6] OvmfPkg: Enable APs to accept memory for TDVF Min Xu
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Min Xu @ 2022-12-20 8:42 UTC (permalink / raw)
To: devel
Cc: Min M Xu, Erdem Aktas, Gerd Hoffmann, James Bottomley, Jiewen Yao,
Tom Lendacky
From: Min M Xu <min.m.xu@intel.com>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4172
This patch moves the TDX APs nasm code from SecEntry.nasm to
IntelTdxAPs.nasm. IntelTdxX64 and OvmfPkgX64 use the same nasm so that
it can be easier to be managed. In the following patch there will be
AcceptMemory related changes in IntelTdxAPs.nasm.
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
---
OvmfPkg/IntelTdx/Sec/X64/IntelTdxAPs.nasm | 58 +++++++++++++++++++++++
OvmfPkg/IntelTdx/Sec/X64/SecEntry.nasm | 58 ++---------------------
OvmfPkg/Sec/X64/SecEntry.nasm | 58 ++---------------------
3 files changed, 68 insertions(+), 106 deletions(-)
create mode 100644 OvmfPkg/IntelTdx/Sec/X64/IntelTdxAPs.nasm
diff --git a/OvmfPkg/IntelTdx/Sec/X64/IntelTdxAPs.nasm b/OvmfPkg/IntelTdx/Sec/X64/IntelTdxAPs.nasm
new file mode 100644
index 000000000000..034ac0ee9421
--- /dev/null
+++ b/OvmfPkg/IntelTdx/Sec/X64/IntelTdxAPs.nasm
@@ -0,0 +1,58 @@
+;------------------------------------------------------------------------------
+; @file
+; Intel TDX APs
+;
+; Copyright (c) 2021 - 2022, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;------------------------------------------------------------------------------
+
+%include "TdxCommondefs.inc"
+
+ ;
+ ; Note: BSP never gets here. APs will be unblocked by DXE
+ ;
+ ; R8 [31:0] NUM_VCPUS
+ ; [63:32] MAX_VCPUS
+ ; R9 [31:0] VCPU_INDEX
+ ;
+ParkAp:
+
+do_wait_loop:
+ ;
+ ; register itself in [rsp + CpuArrivalOffset]
+ ;
+ mov rax, 1
+ lock xadd dword [rsp + CpuArrivalOffset], eax
+ inc eax
+
+.check_arrival_cnt:
+ cmp eax, r8d
+ je .check_command
+ mov eax, dword[rsp + CpuArrivalOffset]
+ jmp .check_arrival_cnt
+
+.check_command:
+ mov eax, dword[rsp + CommandOffset]
+ cmp eax, MpProtectedModeWakeupCommandNoop
+ je .check_command
+
+ cmp eax, MpProtectedModeWakeupCommandWakeup
+ je .do_wakeup
+
+ ; Don't support this command, so ignore
+ jmp .check_command
+
+.do_wakeup:
+ ;
+ ; BSP sets these variables before unblocking APs
+ ; RAX: WakeupVectorOffset
+ ; RBX: Relocated mailbox address
+ ; RBP: vCpuId
+ ;
+ mov rax, 0
+ mov eax, dword[rsp + WakeupVectorOffset]
+ mov rbx, [rsp + WakeupArgsRelocatedMailBox]
+ nop
+ jmp rax
+ jmp $
diff --git a/OvmfPkg/IntelTdx/Sec/X64/SecEntry.nasm b/OvmfPkg/IntelTdx/Sec/X64/SecEntry.nasm
index 4528fec309a0..5a38c4213916 100644
--- a/OvmfPkg/IntelTdx/Sec/X64/SecEntry.nasm
+++ b/OvmfPkg/IntelTdx/Sec/X64/SecEntry.nasm
@@ -10,7 +10,6 @@
;------------------------------------------------------------------------------
#include <Base.h>
-%include "TdxCommondefs.inc"
DEFAULT REL
SECTION .text
@@ -49,6 +48,7 @@ ASM_PFX(_ModuleEntryPoint):
cmp byte[eax], VM_GUEST_TYPE_TDX
jne InitStack
+ %define TDCALL_TDINFO 1
mov rax, TDCALL_TDINFO
tdcall
@@ -62,7 +62,9 @@ ASM_PFX(_ModuleEntryPoint):
mov rax, r9
and rax, 0xffff
test rax, rax
- jne ParkAp
+ jz InitStack
+ mov rsp, FixedPcdGet32 (PcdOvmfSecGhcbBackupBase)
+ jmp ParkAp
InitStack:
@@ -98,54 +100,4 @@ InitStack:
sub rsp, 0x20
call ASM_PFX(SecCoreStartupWithStack)
- ;
- ; Note: BSP never gets here. APs will be unblocked by DXE
- ;
- ; R8 [31:0] NUM_VCPUS
- ; [63:32] MAX_VCPUS
- ; R9 [31:0] VCPU_INDEX
- ;
-ParkAp:
-
- mov rbp, r9
-
-.do_wait_loop:
- mov rsp, FixedPcdGet32 (PcdOvmfSecGhcbBackupBase)
-
- ;
- ; register itself in [rsp + CpuArrivalOffset]
- ;
- mov rax, 1
- lock xadd dword [rsp + CpuArrivalOffset], eax
- inc eax
-
-.check_arrival_cnt:
- cmp eax, r8d
- je .check_command
- mov eax, dword[rsp + CpuArrivalOffset]
- jmp .check_arrival_cnt
-
-.check_command:
- mov eax, dword[rsp + CommandOffset]
- cmp eax, MpProtectedModeWakeupCommandNoop
- je .check_command
-
- cmp eax, MpProtectedModeWakeupCommandWakeup
- je .do_wakeup
-
- ; Don't support this command, so ignore
- jmp .check_command
-
-.do_wakeup:
- ;
- ; BSP sets these variables before unblocking APs
- ; RAX: WakeupVectorOffset
- ; RBX: Relocated mailbox address
- ; RBP: vCpuId
- ;
- mov rax, 0
- mov eax, dword[rsp + WakeupVectorOffset]
- mov rbx, [rsp + WakeupArgsRelocatedMailBox]
- nop
- jmp rax
- jmp $
+%include "IntelTdxAPs.nasm"
diff --git a/OvmfPkg/Sec/X64/SecEntry.nasm b/OvmfPkg/Sec/X64/SecEntry.nasm
index 4528fec309a0..0f82051720da 100644
--- a/OvmfPkg/Sec/X64/SecEntry.nasm
+++ b/OvmfPkg/Sec/X64/SecEntry.nasm
@@ -10,7 +10,6 @@
;------------------------------------------------------------------------------
#include <Base.h>
-%include "TdxCommondefs.inc"
DEFAULT REL
SECTION .text
@@ -49,6 +48,7 @@ ASM_PFX(_ModuleEntryPoint):
cmp byte[eax], VM_GUEST_TYPE_TDX
jne InitStack
+ %define TDCALL_TDINFO 1
mov rax, TDCALL_TDINFO
tdcall
@@ -62,7 +62,9 @@ ASM_PFX(_ModuleEntryPoint):
mov rax, r9
and rax, 0xffff
test rax, rax
- jne ParkAp
+ jz InitStack
+ mov rsp, FixedPcdGet32 (PcdOvmfSecGhcbBackupBase)
+ jmp ParkAp
InitStack:
@@ -98,54 +100,4 @@ InitStack:
sub rsp, 0x20
call ASM_PFX(SecCoreStartupWithStack)
- ;
- ; Note: BSP never gets here. APs will be unblocked by DXE
- ;
- ; R8 [31:0] NUM_VCPUS
- ; [63:32] MAX_VCPUS
- ; R9 [31:0] VCPU_INDEX
- ;
-ParkAp:
-
- mov rbp, r9
-
-.do_wait_loop:
- mov rsp, FixedPcdGet32 (PcdOvmfSecGhcbBackupBase)
-
- ;
- ; register itself in [rsp + CpuArrivalOffset]
- ;
- mov rax, 1
- lock xadd dword [rsp + CpuArrivalOffset], eax
- inc eax
-
-.check_arrival_cnt:
- cmp eax, r8d
- je .check_command
- mov eax, dword[rsp + CpuArrivalOffset]
- jmp .check_arrival_cnt
-
-.check_command:
- mov eax, dword[rsp + CommandOffset]
- cmp eax, MpProtectedModeWakeupCommandNoop
- je .check_command
-
- cmp eax, MpProtectedModeWakeupCommandWakeup
- je .do_wakeup
-
- ; Don't support this command, so ignore
- jmp .check_command
-
-.do_wakeup:
- ;
- ; BSP sets these variables before unblocking APs
- ; RAX: WakeupVectorOffset
- ; RBX: Relocated mailbox address
- ; RBP: vCpuId
- ;
- mov rax, 0
- mov eax, dword[rsp + WakeupVectorOffset]
- mov rbx, [rsp + WakeupArgsRelocatedMailBox]
- nop
- jmp rax
- jmp $
+%include "../../IntelTdx/Sec/X64/IntelTdxAPs.nasm"
--
2.29.2.windows.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH V2 5/6] OvmfPkg: Enable APs to accept memory for TDVF
2022-12-20 8:42 [PATCH V2 0/6] Enable Multi-core based lazy-accept for TDVF Min Xu
` (3 preceding siblings ...)
2022-12-20 8:42 ` [PATCH V2 4/6] OvmfPkg/Sec: Move TDX APs related nasm code to IntelTdxAPs.nasm Min Xu
@ 2022-12-20 8:42 ` Min Xu
2022-12-20 8:42 ` [PATCH V2 6/6] OvmfPkg/PlatformInitLib: Implement multi-core " Min Xu
2022-12-21 8:07 ` [PATCH V2 0/6] Enable Multi-core based lazy-accept " Yao, Jiewen
6 siblings, 0 replies; 8+ messages in thread
From: Min Xu @ 2022-12-20 8:42 UTC (permalink / raw)
To: devel
Cc: Min M Xu, Erdem Aktas, Gerd Hoffmann, James Bottomley, Jiewen Yao,
Tom Lendacky
From: Min M Xu <min.m.xu@intel.com>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4172
TDVF APs once did nothing but spin around to wait for the Wakeup command.
This patch enables APs to handle the AcceptPages command. Once APs find
the AcceptPages command, it set its stack and jump to the function of
ApAcceptMemoryResourceRange (which will be introduced in the following
patch).
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
---
OvmfPkg/Include/TdxCommondefs.inc | 4 +-
OvmfPkg/IntelTdx/Sec/X64/IntelTdxAPs.nasm | 61 +++++++++++++++++++++++
2 files changed, 63 insertions(+), 2 deletions(-)
diff --git a/OvmfPkg/Include/TdxCommondefs.inc b/OvmfPkg/Include/TdxCommondefs.inc
index 970eac96592a..a29d2fad4233 100644
--- a/OvmfPkg/Include/TdxCommondefs.inc
+++ b/OvmfPkg/Include/TdxCommondefs.inc
@@ -15,8 +15,8 @@ FirmwareArgsOffset equ 800h
WakeupArgsRelocatedMailBox equ 800h
AcceptPageArgsPhysicalStart equ 800h
AcceptPageArgsPhysicalEnd equ 808h
-AcceptPageArgsChunkSize equ 810h
-AcceptPageArgsPageSize equ 818h
+AcceptPageArgsTopStackAddress equ 810h
+AcceptPageArgsApStackSize equ 818h
CpuArrivalOffset equ 900h
CpusExitingOffset equ 0a00h
TalliesOffset equ 0a08h
diff --git a/OvmfPkg/IntelTdx/Sec/X64/IntelTdxAPs.nasm b/OvmfPkg/IntelTdx/Sec/X64/IntelTdxAPs.nasm
index 034ac0ee9421..4a984ecc1058 100644
--- a/OvmfPkg/IntelTdx/Sec/X64/IntelTdxAPs.nasm
+++ b/OvmfPkg/IntelTdx/Sec/X64/IntelTdxAPs.nasm
@@ -40,9 +40,70 @@ do_wait_loop:
cmp eax, MpProtectedModeWakeupCommandWakeup
je .do_wakeup
+ cmp eax, MpProtectedModeWakeupCommandAcceptPages
+ je .do_accept_pages
+
; Don't support this command, so ignore
jmp .check_command
+.do_accept_pages:
+ ;
+ ; Read the top stack address from arguments
+ mov rsi, [rsp + AcceptPageArgsTopStackAddress]
+
+ ;
+ ; Calculate the top stack address of the AP.
+ ; ApStackAddr = BaseStackAddr + (vCpuIndex) * ApStackSize
+ xor rdx, rdx
+ xor rbx, rbx
+ xor rax, rax
+ mov eax, [rsp + AcceptPageArgsApStackSize]
+ mov ebx, r9d ; vCpuIndex
+ mul ebx
+ add rsi, rax ; now rsi is ApStackAddr
+
+.start_accept_pages:
+ ;
+ ; Read the function address which will be called
+ mov rax, [rsp + WakeupVectorOffset]
+
+ ;
+ ; vCPU index as the first argument
+ mov ecx, r9d
+ mov rdx, [rsp + AcceptPageArgsPhysicalStart]
+ mov r8, [rsp + AcceptPageArgsPhysicalEnd]
+
+ ; save the Mailbox address to rbx
+ mov rbx, rsp
+
+ ;
+ ; set AP Stack
+ mov rsp, rsi
+ nop
+
+ ; save rax (the Mailbox address)
+ push rbx
+
+ call rax
+
+ ; recove rsp
+ pop rbx
+ mov rsp, rbx
+ ;
+ ; recover r8, r9
+ mov rax, 1
+ tdcall
+
+ mov eax, 0FFFFFFFFh
+ lock xadd dword [rsp + CpusExitingOffset], eax
+ dec eax
+
+.check_exiting_cnt:
+ cmp eax, 0
+ je do_wait_loop
+ mov eax, dword[rsp + CpusExitingOffset]
+ jmp .check_exiting_cnt
+
.do_wakeup:
;
; BSP sets these variables before unblocking APs
--
2.29.2.windows.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH V2 6/6] OvmfPkg/PlatformInitLib: Implement multi-core accept memory for TDVF
2022-12-20 8:42 [PATCH V2 0/6] Enable Multi-core based lazy-accept for TDVF Min Xu
` (4 preceding siblings ...)
2022-12-20 8:42 ` [PATCH V2 5/6] OvmfPkg: Enable APs to accept memory for TDVF Min Xu
@ 2022-12-20 8:42 ` Min Xu
2022-12-21 8:07 ` [PATCH V2 0/6] Enable Multi-core based lazy-accept " Yao, Jiewen
6 siblings, 0 replies; 8+ messages in thread
From: Min Xu @ 2022-12-20 8:42 UTC (permalink / raw)
To: devel
Cc: Min M Xu, Erdem Aktas, Gerd Hoffmann, James Bottomley, Jiewen Yao,
Tom Lendacky
From: Min M Xu <min.m.xu@intel.com>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4172
TDVF once accepts memory only by BSP. To improve the boot performance
this patch introduce the multi-core accpet memory. Multi-core means
BSP and APs work together to accept memory.
TDVF leverages mailbox to wake up APs. It is not enabled in MpInitLib
(Which requires SIPI). So multi-core accept memory cannot leverages
MpInitLib to coordinate BSP and APs to work together.
So TDVF split the accept memory into 2 phases.
- AcceptMemoryForAPsStack:
BSP accepts a small piece of memory which is then used by APs to setup
stack. We assign a 16KB stack for each AP. So a td-guest with 256 vCPU
requires 255*16KB = 4080KB.
- AcceptMemory:
After above small piece of memory is accepted, BSP commands APs to
accept memory by sending AcceptPages command in td-mailbox. Together
with the command and accpet-function, the APsStack address is send
as well. APs then set the stack and jump to accept-function to accept
memory.
AcceptMemoryForAPsStack accepts as small memory as possible and then jump
to AcceptMemory. It fully takes advantage of BSP/APs to work together.
After accept memory is done, the memory region for APsStack is not used
anymore. It can be used as other private memory. Because accept-memory
is in the very beginning of boot process and it will not impact other
phases.
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
---
OvmfPkg/Library/PlatformInitLib/IntelTdx.c | 411 +++++++++++++++---
.../PlatformInitLib/PlatformInitLib.inf | 1 +
2 files changed, 363 insertions(+), 49 deletions(-)
diff --git a/OvmfPkg/Library/PlatformInitLib/IntelTdx.c b/OvmfPkg/Library/PlatformInitLib/IntelTdx.c
index 55ca3ecaa13d..6cb63139cba0 100644
--- a/OvmfPkg/Library/PlatformInitLib/IntelTdx.c
+++ b/OvmfPkg/Library/PlatformInitLib/IntelTdx.c
@@ -20,6 +20,7 @@
#include <Library/QemuFwCfgLib.h>
#include <Library/PeiServicesLib.h>
#include <Library/TdxLib.h>
+#include <Library/TdxMailboxLib.h>
#include <Library/SynchronizationLib.h>
#include <Pi/PrePiHob.h>
#include <WorkArea.h>
@@ -28,6 +29,10 @@
#define ALIGNED_2MB_MASK 0x1fffff
#define MEGABYTE_SHIFT 20
+#define ACCEPT_CHUNK_SIZE SIZE_32MB
+#define AP_STACK_SIZE SIZE_16KB
+#define APS_STACK_SIZE(CpusNum) (ALIGN_VALUE(CpusNum*AP_STACK_SIZE, SIZE_2MB))
+
/**
This function will be called to accept pages. Only BSP accepts pages.
@@ -81,8 +86,6 @@ BspAcceptMemoryResourceRange (
return EFI_SUCCESS;
}
- DEBUG ((DEBUG_INFO, "TdAccept: 0x%llx - 0x%llx\n", PhysicalAddress, TotalLength));
-
if (ALIGN_VALUE (PhysicalAddress, SIZE_2MB) != PhysicalAddress) {
StartAddress1 = PhysicalAddress;
Length1 = ALIGN_VALUE (PhysicalAddress, SIZE_2MB) - PhysicalAddress;
@@ -106,11 +109,6 @@ BspAcceptMemoryResourceRange (
Length3 = TotalLength;
}
- DEBUG ((DEBUG_INFO, " Part1: 0x%llx - 0x%llx\n", StartAddress1, Length1));
- DEBUG ((DEBUG_INFO, " Part2: 0x%llx - 0x%llx\n", StartAddress2, Length2));
- DEBUG ((DEBUG_INFO, " Part3: 0x%llx - 0x%llx\n", StartAddress3, Length3));
- DEBUG ((DEBUG_INFO, " Page : 0x%x\n", AcceptPageSize));
-
Status = EFI_SUCCESS;
if (Length1 > 0) {
Pages = Length1 / SIZE_4KB;
@@ -140,6 +138,342 @@ BspAcceptMemoryResourceRange (
return Status;
}
+/**
+ * This function is called by BSP and APs to accept memory.
+ * Note:
+ * The input PhysicalStart/PhysicalEnd indicates the whole memory region
+ * to be accepted. BSP or AP only accepts one piece in the whole memory region.
+ *
+ * @param CpuIndex vCPU index
+ * @param CpusNum Total vCPU number of a Tdx guest
+ * @param PhysicalStart Start address of a memory region which is to be accepted
+ * @param PhysicalEnd End address of a memory region which is to be accepted
+ *
+ * @retval EFI_SUCCESS Successfully accept the memory
+ * @retval Other Other errors as indicated
+ */
+STATIC
+EFI_STATUS
+EFIAPI
+BspApAcceptMemoryResourceRange (
+ UINT32 CpuIndex,
+ UINT32 CpusNum,
+ EFI_PHYSICAL_ADDRESS PhysicalStart,
+ EFI_PHYSICAL_ADDRESS PhysicalEnd
+ )
+{
+ UINT64 Status;
+ UINT64 Pages;
+ UINT64 Stride;
+ UINT64 AcceptPageSize;
+ EFI_PHYSICAL_ADDRESS PhysicalAddress;
+
+ AcceptPageSize = (UINT64)(UINTN)FixedPcdGet32 (PcdTdxAcceptPageSize);
+
+ Status = EFI_SUCCESS;
+ Stride = (UINTN)CpusNum * ACCEPT_CHUNK_SIZE;
+ PhysicalAddress = PhysicalStart + ACCEPT_CHUNK_SIZE * (UINTN)CpuIndex;
+
+ while (!EFI_ERROR (Status) && PhysicalAddress < PhysicalEnd) {
+ Pages = MIN (ACCEPT_CHUNK_SIZE, PhysicalEnd - PhysicalAddress) / AcceptPageSize;
+ Status = TdAcceptPages (PhysicalAddress, Pages, (UINT32)(UINTN)AcceptPageSize);
+ ASSERT (!EFI_ERROR (Status));
+ PhysicalAddress += Stride;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ * This function is called by APs to accept memory.
+ *
+ * @param CpuIndex vCPU index of an AP
+ * @param PhysicalStart Start address of a memory region which is to be accepted
+ * @param PhysicalEnd End address of a memory region which is to be accepted
+ *
+ * @retval EFI_SUCCESS Successfully accept the memory
+ * @retval Others Other errors as indicated
+ */
+STATIC
+EFI_STATUS
+EFIAPI
+ApAcceptMemoryResourceRange (
+ UINT32 CpuIndex,
+ EFI_PHYSICAL_ADDRESS PhysicalStart,
+ EFI_PHYSICAL_ADDRESS PhysicalEnd
+ )
+{
+ UINT64 Status;
+ TD_RETURN_DATA TdReturnData;
+
+ Status = TdCall (TDCALL_TDINFO, 0, 0, 0, &TdReturnData);
+ if (Status != TDX_EXIT_REASON_SUCCESS) {
+ ASSERT (FALSE);
+ return EFI_ABORTED;
+ }
+
+ if ((CpuIndex == 0) || (CpuIndex >= TdReturnData.TdInfo.NumVcpus)) {
+ ASSERT (FALSE);
+ return EFI_ABORTED;
+ }
+
+ return BspApAcceptMemoryResourceRange (CpuIndex, TdReturnData.TdInfo.NumVcpus, PhysicalStart, PhysicalEnd);
+}
+
+/**
+ * This function is called by BSP. It coordinates BSP/APs to accept memory together.
+ *
+ * @param PhysicalStart Start address of a memory region which is to be accepted
+ * @param PhysicalEnd End address of a memory region which is to be accepted
+ * @param APsStackAddress APs stack address
+ * @param CpusNum Total vCPU number of the Tdx guest
+ *
+ * @retval EFI_SUCCESS Successfully accept the memory
+ * @retval Others Other errors as indicated
+ */
+EFI_STATUS
+EFIAPI
+MpAcceptMemoryResourceRange (
+ IN EFI_PHYSICAL_ADDRESS PhysicalStart,
+ IN EFI_PHYSICAL_ADDRESS PhysicalEnd,
+ IN OUT EFI_PHYSICAL_ADDRESS APsStackAddress,
+ IN UINT32 CpusNum
+ )
+{
+ UINT64 Length;
+ EFI_STATUS Status;
+
+ Length = PhysicalEnd - PhysicalStart;
+
+ DEBUG ((DEBUG_INFO, "MpAccept : 0x%llx - 0x%llx (0x%llx)\n", PhysicalStart, PhysicalEnd, Length));
+
+ if (Length == 0) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // The start address is not 2M aligned. BSP first accept the part which is not 2M aligned.
+ //
+ if (ALIGN_VALUE (PhysicalStart, SIZE_2MB) != PhysicalStart) {
+ Length = MIN (ALIGN_VALUE (PhysicalStart, SIZE_2MB) - PhysicalStart, Length);
+ Status = BspAcceptMemoryResourceRange (PhysicalStart, PhysicalStart + Length);
+ ASSERT (Status == EFI_SUCCESS);
+
+ PhysicalStart += Length;
+ Length = PhysicalEnd - PhysicalStart;
+ }
+
+ if (Length == 0) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // BSP will accept the memory by itself if the memory is not big enough compared with a chunk.
+ //
+ if (Length <= ACCEPT_CHUNK_SIZE) {
+ return BspAcceptMemoryResourceRange (PhysicalStart, PhysicalEnd);
+ }
+
+ //
+ // Now APs are asked to accept the memory together.
+ //
+ MpSerializeStart ();
+
+ MpSendWakeupCommand (
+ MpProtectedModeWakeupCommandAcceptPages,
+ (UINT64)(UINTN)ApAcceptMemoryResourceRange,
+ PhysicalStart,
+ PhysicalEnd,
+ APsStackAddress,
+ AP_STACK_SIZE
+ );
+
+ //
+ // Now BSP does its job.
+ //
+ BspApAcceptMemoryResourceRange (0, CpusNum, PhysicalStart, PhysicalEnd);
+
+ MpSerializeEnd ();
+
+ return EFI_SUCCESS;
+}
+
+/**
+ BSP accept a small piece of memory which will be used as APs stack.
+
+ @param[in] VmmHobList The Hoblist pass the firmware
+ @param[in] APsStackSize APs stack size
+ @param[out] PhysicalAddressEnd The physical end address of accepted memory in phase-1
+
+ @retval EFI_SUCCESS Process the HobList successfully
+ @retval Others Other errors as indicated
+**/
+EFI_STATUS
+EFIAPI
+AcceptMemoryForAPsStack (
+ IN CONST VOID *VmmHobList,
+ IN UINT32 APsStackSize,
+ OUT EFI_PHYSICAL_ADDRESS *PhysicalAddressEnd
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_HOB_POINTERS Hob;
+ EFI_PHYSICAL_ADDRESS PhysicalEnd;
+ EFI_PHYSICAL_ADDRESS PhysicalStart;
+ UINT64 ResourceLength;
+ BOOLEAN MemoryRegionFound;
+
+ ASSERT (VmmHobList != NULL);
+
+ Status = EFI_SUCCESS;
+ Hob.Raw = (UINT8 *)VmmHobList;
+ MemoryRegionFound = FALSE;
+
+ DEBUG ((DEBUG_INFO, "AcceptMemoryForAPsStack with APsStackSize=0x%x\n", APsStackSize));
+
+ //
+ // Parse the HOB list until end of list or matching type is found.
+ //
+ while (!END_OF_HOB_LIST (Hob) && !MemoryRegionFound) {
+ if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
+ DEBUG ((DEBUG_INFO, "\nResourceType: 0x%x\n", Hob.ResourceDescriptor->ResourceType));
+
+ if (Hob.ResourceDescriptor->ResourceType == BZ3937_EFI_RESOURCE_MEMORY_UNACCEPTED) {
+ ResourceLength = Hob.ResourceDescriptor->ResourceLength;
+ PhysicalStart = Hob.ResourceDescriptor->PhysicalStart;
+ PhysicalEnd = PhysicalStart + ResourceLength;
+
+ DEBUG ((DEBUG_INFO, "ResourceAttribute: 0x%x\n", Hob.ResourceDescriptor->ResourceAttribute));
+ DEBUG ((DEBUG_INFO, "PhysicalStart: 0x%llx\n", PhysicalStart));
+ DEBUG ((DEBUG_INFO, "ResourceLength: 0x%llx\n", ResourceLength));
+ DEBUG ((DEBUG_INFO, "Owner: %g\n\n", &Hob.ResourceDescriptor->Owner));
+
+ if (ResourceLength >= APsStackSize) {
+ MemoryRegionFound = TRUE;
+ if (ResourceLength > ACCEPT_CHUNK_SIZE) {
+ PhysicalEnd = Hob.ResourceDescriptor->PhysicalStart + APsStackSize;
+ }
+ }
+
+ Status = BspAcceptMemoryResourceRange (
+ Hob.ResourceDescriptor->PhysicalStart,
+ PhysicalEnd
+ );
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+ }
+ }
+
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ }
+
+ ASSERT (MemoryRegionFound);
+ *PhysicalAddressEnd = PhysicalEnd;
+
+ return Status;
+}
+
+/**
+ BSP and APs work togeter to accept memory which is under the address of 4G.
+
+ @param[in] VmmHobList The Hoblist pass the firmware
+ @param[in] CpusNum Number of vCPUs
+ @param[in] APsStackStartAddres Start address of APs stack
+ @param[in] PhysicalAddressStart Start physical address which to be accepted
+
+ @retval EFI_SUCCESS Process the HobList successfully
+ @retval Others Other errors as indicated
+**/
+EFI_STATUS
+EFIAPI
+AcceptMemory (
+ IN CONST VOID *VmmHobList,
+ IN UINT32 CpusNum,
+ IN EFI_PHYSICAL_ADDRESS APsStackStartAddress,
+ IN EFI_PHYSICAL_ADDRESS PhysicalAddressStart
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_HOB_POINTERS Hob;
+ EFI_PHYSICAL_ADDRESS PhysicalStart;
+ EFI_PHYSICAL_ADDRESS PhysicalEnd;
+ EFI_PHYSICAL_ADDRESS AcceptMemoryEndAddress;
+
+ Status = EFI_SUCCESS;
+ AcceptMemoryEndAddress = BASE_4GB;
+
+ ASSERT (VmmHobList != NULL);
+ Hob.Raw = (UINT8 *)VmmHobList;
+
+ DEBUG ((DEBUG_INFO, "AcceptMemory under address of 4G\n"));
+
+ //
+ // Parse the HOB list until end of list or matching type is found.
+ //
+ while (!END_OF_HOB_LIST (Hob)) {
+ if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
+ if (Hob.ResourceDescriptor->ResourceType == BZ3937_EFI_RESOURCE_MEMORY_UNACCEPTED) {
+ PhysicalStart = Hob.ResourceDescriptor->PhysicalStart;
+ PhysicalEnd = PhysicalStart + Hob.ResourceDescriptor->ResourceLength;
+
+ if (PhysicalEnd <= PhysicalAddressStart) {
+ // this memory region has been accepted. Skipped it.
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ continue;
+ }
+
+ if (PhysicalStart >= AcceptMemoryEndAddress) {
+ // this memory region is not to be accepted. And we're done.
+ break;
+ }
+
+ if (PhysicalStart >= PhysicalAddressStart) {
+ // this memory region has not been acceted.
+ } else if ((PhysicalStart < PhysicalAddressStart) && (PhysicalEnd > PhysicalAddressStart)) {
+ // part of the memory region has been accepted.
+ PhysicalStart = PhysicalAddressStart;
+ }
+
+ // then compare the PhysicalEnd with AcceptMemoryEndAddress
+ if (PhysicalEnd >= AcceptMemoryEndAddress) {
+ PhysicalEnd = AcceptMemoryEndAddress;
+ }
+
+ DEBUG ((DEBUG_INFO, "ResourceAttribute: 0x%x\n", Hob.ResourceDescriptor->ResourceAttribute));
+ DEBUG ((DEBUG_INFO, "PhysicalStart: 0x%llx\n", Hob.ResourceDescriptor->PhysicalStart));
+ DEBUG ((DEBUG_INFO, "ResourceLength: 0x%llx\n", Hob.ResourceDescriptor->ResourceLength));
+ DEBUG ((DEBUG_INFO, "Owner: %g\n\n", &Hob.ResourceDescriptor->Owner));
+
+ // Now we're ready to accept memory [PhysicalStart, PhysicalEnd)
+ if (CpusNum == 1) {
+ Status = BspAcceptMemoryResourceRange (PhysicalStart, PhysicalEnd);
+ } else {
+ Status = MpAcceptMemoryResourceRange (
+ PhysicalStart,
+ PhysicalEnd,
+ APsStackStartAddress,
+ CpusNum
+ );
+ }
+
+ if (EFI_ERROR (Status)) {
+ ASSERT (FALSE);
+ break;
+ }
+
+ if (PhysicalEnd == AcceptMemoryEndAddress) {
+ break;
+ }
+ }
+ }
+
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ }
+
+ return Status;
+}
+
/**
Check the value whether in the valid list.
@@ -375,55 +709,34 @@ ProcessHobList (
)
{
EFI_STATUS Status;
- EFI_PEI_HOB_POINTERS Hob;
+ UINT32 CpusNum;
EFI_PHYSICAL_ADDRESS PhysicalEnd;
- UINT64 ResourceLength;
- UINT64 AccumulateAcceptedMemory;
+ EFI_PHYSICAL_ADDRESS APsStackStartAddress;
- Status = EFI_SUCCESS;
- ASSERT (VmmHobList != NULL);
- Hob.Raw = (UINT8 *)VmmHobList;
-
- AccumulateAcceptedMemory = 0;
+ CpusNum = GetCpusNum ();
//
- // Parse the HOB list until end of list or matching type is found.
+ // If there are mutli-vCPU in a TDX guest, accept memory is split into 2 phases.
+ // Phase-1 accepts a small piece of memory by BSP. This piece of memory
+ // is used to setup AP's stack.
+ // After that phase-2 accepts a big piece of memory by BSP/APs.
//
- while (!END_OF_HOB_LIST (Hob)) {
- if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
- DEBUG ((DEBUG_INFO, "\nResourceType: 0x%x\n", Hob.ResourceDescriptor->ResourceType));
-
- if (Hob.ResourceDescriptor->ResourceType == BZ3937_EFI_RESOURCE_MEMORY_UNACCEPTED) {
- DEBUG ((DEBUG_INFO, "ResourceAttribute: 0x%x\n", Hob.ResourceDescriptor->ResourceAttribute));
- DEBUG ((DEBUG_INFO, "PhysicalStart: 0x%llx\n", Hob.ResourceDescriptor->PhysicalStart));
- DEBUG ((DEBUG_INFO, "ResourceLength: 0x%llx\n", Hob.ResourceDescriptor->ResourceLength));
- DEBUG ((DEBUG_INFO, "Owner: %g\n\n", &Hob.ResourceDescriptor->Owner));
-
- PhysicalEnd = Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength;
- ResourceLength = Hob.ResourceDescriptor->ResourceLength;
-
- if (Hob.ResourceDescriptor->PhysicalStart >= BASE_4GB) {
- //
- // In current stage, we only accept the memory under 4G
- //
- break;
- }
-
- Status = BspAcceptMemoryResourceRange (
- Hob.ResourceDescriptor->PhysicalStart,
- PhysicalEnd
- );
- if (EFI_ERROR (Status)) {
- break;
- }
-
- AccumulateAcceptedMemory += ResourceLength;
- }
- }
-
- Hob.Raw = GET_NEXT_HOB (Hob);
+ // TDVF supports 4K and 2M accept-page-size. The memory which can be accpeted
+ // in 2M accept-page-size must be 2M aligned and multiple 2M. So we align
+ // APsStackSize to 2M size aligned.
+ //
+ if (CpusNum > 1) {
+ Status = AcceptMemoryForAPsStack (VmmHobList, APS_STACK_SIZE (CpusNum), &PhysicalEnd);
+ ASSERT (Status == EFI_SUCCESS);
+ APsStackStartAddress = PhysicalEnd - APS_STACK_SIZE (CpusNum);
+ } else {
+ PhysicalEnd = 0;
+ APsStackStartAddress = 0;
}
+ Status = AcceptMemory (VmmHobList, CpusNum, APsStackStartAddress, PhysicalEnd);
+ ASSERT (Status == EFI_SUCCESS);
+
return Status;
}
diff --git a/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf b/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
index 86a82ad3e084..140216979a54 100644
--- a/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
+++ b/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
@@ -52,6 +52,7 @@
PcdLib
PciLib
PeiHardwareInfoLib
+ TdxMailboxLib
[LibraryClasses.X64]
TdxLib
--
2.29.2.windows.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH V2 0/6] Enable Multi-core based lazy-accept for TDVF
2022-12-20 8:42 [PATCH V2 0/6] Enable Multi-core based lazy-accept for TDVF Min Xu
` (5 preceding siblings ...)
2022-12-20 8:42 ` [PATCH V2 6/6] OvmfPkg/PlatformInitLib: Implement multi-core " Min Xu
@ 2022-12-21 8:07 ` Yao, Jiewen
6 siblings, 0 replies; 8+ messages in thread
From: Yao, Jiewen @ 2022-12-21 8:07 UTC (permalink / raw)
To: Xu, Min M, devel@edk2.groups.io
Cc: Aktas, Erdem, Gerd Hoffmann, James Bottomley, Tom Lendacky
Reviewed-by: Jiewen Yao <Jiewen.yao@intel.com>
Merged https://github.com/tianocore/edk2/pull/3813
> -----Original Message-----
> From: Xu, Min M <min.m.xu@intel.com>
> Sent: Tuesday, December 20, 2022 4:43 PM
> To: devel@edk2.groups.io
> Cc: Xu, Min M <min.m.xu@intel.com>; Aktas, Erdem
> <erdemaktas@google.com>; Gerd Hoffmann <kraxel@redhat.com>; James
> Bottomley <jejb@linux.ibm.com>; Yao, Jiewen <jiewen.yao@intel.com>; Tom
> Lendacky <thomas.lendacky@amd.com>
> Subject: [PATCH V2 0/6] Enable Multi-core based lazy-accept for TDVF
>
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4172
>
> TDVF once accepts memory only by BSP. To improve the boot performance
> this patch-set introduce the multi-core accpet memory. Multi-core means
> BSP and APs work together to accept memory.
>
> TDVF leverages mailbox to wake up APs. It is not enabled in MpInitLib
> (Which requires SIPI). So multi-core accept memory cannot leverages
> MpInitLib to coordinate BSP and APs to work together.
>
> So TDVF split the accept memory into 2 phases.
> - AcceptMemoryForAPsStack:
> BSP accepts a small piece of memory which is then used by APs to setup
> stack. We assign a 16KB stack for each AP. So a td-guest with 256 vCPU
> requires 255*16KB = 4080KB.
> - AcceptMemory:
> After above small piece of memory is accepted, BSP commands APs to
> accept memory by sending AcceptPages command in td-mailbox. Together
> with the command and accpet-function, the APsStack address is send
> as well. APs then set the stack and jump to accept-function to accept
> memory.
>
> Patch 1-3:
> TdxMailboxLib is refactored to help multi-core lazy accept.
> Patch 4-5:
> Refactor APs' logical to support accpet page.
> Patch 6:
> Implement multi-core accept in TDVF.
>
> Code: https://github.com/mxu9/edk2/tree/Multi-Core-Lazy-Accept.v2
>
> v2 changes:
> - Fix an override error when vCPU number is larger than 64.
>
> Cc: Erdem Aktas <erdemaktas@google.com>
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Cc: James Bottomley <jejb@linux.ibm.com>
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Tom Lendacky <thomas.lendacky@amd.com>
> Signed-off-by: Min Xu <min.m.xu@intel.com>
>
> Min M Xu (6):
> OvmfPkg/TdxMailboxLib: Delete global variables
> OvmfPkg/TdxMailboxLib: Add NULL instance of TdxMailboxLib
> OvmfPkg: Add TdxMailboxLibNull in some platform dsc
> OvmfPkg/Sec: Move TDX APs related nasm code to IntelTdxAPs.nasm
> OvmfPkg: Enable APs to accept memory for TDVF
> OvmfPkg/PlatformInitLib: Implement multi-core accept memory for TDVF
>
> OvmfPkg/AmdSev/AmdSevX64.dsc | 1 +
> OvmfPkg/CloudHv/CloudHvX64.dsc | 1 +
> OvmfPkg/Include/TdxCommondefs.inc | 4 +-
> OvmfPkg/IntelTdx/Sec/X64/IntelTdxAPs.nasm | 119 +++++
> OvmfPkg/IntelTdx/Sec/X64/SecEntry.nasm | 58 +--
> OvmfPkg/Library/PlatformInitLib/IntelTdx.c | 411 +++++++++++++++---
> .../PlatformInitLib/PlatformInitLib.inf | 1 +
> OvmfPkg/Library/TdxMailboxLib/TdxMailbox.c | 22 +-
> .../Library/TdxMailboxLib/TdxMailboxLib.inf | 7 +-
> .../TdxMailboxLib/TdxMailboxLibNull.inf | 34 ++
> OvmfPkg/Microvm/MicrovmX64.dsc | 1 +
> OvmfPkg/OvmfPkgIa32.dsc | 1 +
> OvmfPkg/OvmfPkgIa32X64.dsc | 2 +-
> OvmfPkg/Sec/X64/SecEntry.nasm | 58 +--
> 14 files changed, 545 insertions(+), 175 deletions(-)
> create mode 100644 OvmfPkg/IntelTdx/Sec/X64/IntelTdxAPs.nasm
> create mode 100644 OvmfPkg/Library/TdxMailboxLib/TdxMailboxLibNull.inf
>
> --
> 2.29.2.windows.2
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2022-12-21 8:08 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-12-20 8:42 [PATCH V2 0/6] Enable Multi-core based lazy-accept for TDVF Min Xu
2022-12-20 8:42 ` [PATCH V2 1/6] OvmfPkg/TdxMailboxLib: Delete global variables Min Xu
2022-12-20 8:42 ` [PATCH V2 2/6] OvmfPkg/TdxMailboxLib: Add NULL instance of TdxMailboxLib Min Xu
2022-12-20 8:42 ` [PATCH V2 3/6] OvmfPkg: Add TdxMailboxLibNull in some platform dsc Min Xu
2022-12-20 8:42 ` [PATCH V2 4/6] OvmfPkg/Sec: Move TDX APs related nasm code to IntelTdxAPs.nasm Min Xu
2022-12-20 8:42 ` [PATCH V2 5/6] OvmfPkg: Enable APs to accept memory for TDVF Min Xu
2022-12-20 8:42 ` [PATCH V2 6/6] OvmfPkg/PlatformInitLib: Implement multi-core " Min Xu
2022-12-21 8:07 ` [PATCH V2 0/6] Enable Multi-core based lazy-accept " Yao, Jiewen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox