public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [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