[edk2-devel] [PATCH V3 14/29] UefiCpuPkg: Enable Tdx support in MpInitLib

Min Xu posted 29 patches 4 years, 3 months ago
There is a newer version of this series
[edk2-devel] [PATCH V3 14/29] UefiCpuPkg: Enable Tdx support in MpInitLib
Posted by Min Xu 4 years, 3 months ago
RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3429

In TDVF BSP and APs are simplified. BSP is the vCPU-0, while the others
are treated as APs.

So MP intialization is rather simple. The processor info is retrieved by
TDCALL, ApWorker is not supported, BSP is always the working processor,
while the APs are just in a wait-for-precedure state.

Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
---
 UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf |   5 +
 UefiCpuPkg/Library/MpInitLib/DxeMpLib.c       |  15 ++-
 UefiCpuPkg/Library/MpInitLib/MpIntelTdx.h     | 107 +++++++++++++++
 UefiCpuPkg/Library/MpInitLib/MpLib.c          |  27 ++++
 UefiCpuPkg/Library/MpInitLib/MpLibTdx.c       | 126 ++++++++++++++++++
 UefiCpuPkg/Library/MpInitLib/MpLibTdxNull.c   | 117 ++++++++++++++++
 UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf |   5 +
 .../Library/MpInitLib/X64/IntelTdcall.nasm    | 120 +++++++++++++++++
 8 files changed, 521 insertions(+), 1 deletion(-)
 create mode 100644 UefiCpuPkg/Library/MpInitLib/MpIntelTdx.h
 create mode 100644 UefiCpuPkg/Library/MpInitLib/MpLibTdx.c
 create mode 100644 UefiCpuPkg/Library/MpInitLib/MpLibTdxNull.c
 create mode 100644 UefiCpuPkg/Library/MpInitLib/X64/IntelTdcall.nasm

diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
index d34419c2a524..d78b6c179501 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
@@ -22,10 +22,13 @@
 #
 
 [Sources.IA32]
+  MpLibTdxNull.c
   Ia32/MpFuncs.nasm
 
 [Sources.X64]
+  MpLibTdx.c
   X64/MpFuncs.nasm
+  X64/IntelTdcall.nasm
 
 [Sources.common]
   MpEqu.inc
@@ -33,6 +36,7 @@
   MpLib.c
   MpLib.h
   Microcode.c
+  MpIntelTdx.h
 
 [Packages]
   MdePkg/MdePkg.dec
@@ -76,3 +80,4 @@
   gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase                       ## SOMETIMES_CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard                      ## CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase                           ## CONSUMES
+  gEfiMdePkgTokenSpaceGuid.PcdConfidentialComputingGuestAttr           ## CONSUMES
diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
index 93fc63bf93e3..718c6adb9d2a 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
@@ -7,6 +7,7 @@
 **/
 
 #include "MpLib.h"
+#include "MpIntelTdx.h"
 
 #include <Library/UefiLib.h>
 #include <Library/UefiBootServicesTableLib.h>
@@ -15,8 +16,8 @@
 #include <Library/VmgExitLib.h>
 #include <Register/Amd/Fam17Msr.h>
 #include <Register/Amd/Ghcb.h>
-
 #include <Protocol/Timer.h>
+#include <ConfidentialComputingGuestAttr.h>
 
 #define  AP_SAFE_STACK_SIZE    128
 
@@ -801,6 +802,10 @@ MpInitLibStartupThisAP (
 {
   EFI_STATUS              Status;
 
+  if (CC_GUEST_IS_TDX (PcdGet64 (PcdConfidentialComputingGuestAttr))) {
+    return EFI_UNSUPPORTED;
+  }
+
   //
   // temporarily stop checkAllApsStatus for avoid resource dead-lock.
   //
@@ -857,6 +862,10 @@ MpInitLibSwitchBSP (
   EFI_TIMER_ARCH_PROTOCOL      *Timer;
   UINT64                       TimerPeriod;
 
+  if (CC_GUEST_IS_TDX (PcdGet64 (PcdConfidentialComputingGuestAttr))) {
+    return EFI_UNSUPPORTED;
+  }
+
   TimerPeriod = 0;
   //
   // Locate Timer Arch Protocol
@@ -930,6 +939,10 @@ MpInitLibEnableDisableAP (
   EFI_STATUS     Status;
   BOOLEAN        TempStopCheckState;
 
+  if (CC_GUEST_IS_TDX (PcdGet64 (PcdConfidentialComputingGuestAttr))) {
+    return EFI_UNSUPPORTED;
+  }
+
   TempStopCheckState = FALSE;
   //
   // temporarily stop checkAllAPsStatus for initialize parameters.
diff --git a/UefiCpuPkg/Library/MpInitLib/MpIntelTdx.h b/UefiCpuPkg/Library/MpInitLib/MpIntelTdx.h
new file mode 100644
index 000000000000..59bd739eed22
--- /dev/null
+++ b/UefiCpuPkg/Library/MpInitLib/MpIntelTdx.h
@@ -0,0 +1,107 @@
+/** @file
+  Intel Tdx header file.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef MP_INTEL_TDX_H_
+#define MP_INTEL_TDX_H_
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Uefi/UefiBaseType.h>
+#include <Protocol/MpService.h>
+
+/**
+  Gets detailed MP-related information on the requested processor at the
+  instant this call is made. This service may only be called from the BSP.
+
+  @param[in]  ProcessorNumber       The handle number of processor.
+  @param[out] ProcessorInfoBuffer   A pointer to the buffer where information for
+                                    the requested processor is deposited.
+  @param[out]  HealthData            Return processor health data.
+
+  @retval EFI_SUCCESS             Processor information was returned.
+  @retval EFI_DEVICE_ERROR        The calling processor is an AP.
+  @retval EFI_INVALID_PARAMETER   ProcessorInfoBuffer is NULL.
+  @retval EFI_NOT_FOUND           The processor with the handle specified by
+                                  ProcessorNumber does not exist in the platform.
+  @retval EFI_NOT_READY           MP Initialize Library is not initialized.
+
+**/
+EFI_STATUS
+EFIAPI
+TdxMpInitLibGetProcessorInfo (
+  IN  UINTN                      ProcessorNumber,
+  OUT EFI_PROCESSOR_INFORMATION  *ProcessorInfoBuffer,
+  OUT EFI_HEALTH_FLAGS           *HealthData  OPTIONAL
+  );
+
+/**
+  Retrieves the number of logical processor in the platform and the number of
+  those logical processors that are enabled on this boot. This service may only
+  be called from the BSP.
+
+  @param[out] NumberOfProcessors          Pointer to the total number of logical
+                                          processors in the system, including the BSP
+                                          and disabled APs.
+  @param[out] NumberOfEnabledProcessors   Pointer to the number of enabled logical
+                                          processors that exist in system, including
+                                          the BSP.
+
+  @retval EFI_SUCCESS             The number of logical processors and enabled
+                                  logical processors was retrieved.
+  @retval EFI_DEVICE_ERROR        The calling processor is an AP.
+  @retval EFI_INVALID_PARAMETER   NumberOfProcessors is NULL and NumberOfEnabledProcessors
+                                  is NULL.
+  @retval EFI_NOT_READY           MP Initialize Library is not initialized.
+
+**/
+EFI_STATUS
+EFIAPI
+TdxMpInitLibGetNumberOfProcessors (
+  OUT UINTN                     *NumberOfProcessors,       OPTIONAL
+  OUT UINTN                     *NumberOfEnabledProcessors OPTIONAL
+  );
+
+/**
+  The TDCALL instruction causes a VM exit to the Intel TDX module.  It is
+  used to call guest-side Intel TDX functions, either local or a TD exit
+  to the host VMM, as selected by Leaf.
+
+  @param[in]      Leaf        Leaf number of TDCALL instruction
+  @param[in]      Arg1        Arg1
+  @param[in]      Arg2        Arg2
+  @param[in]      Arg3        Arg3
+  @param[in,out]  Results  Returned result of the Leaf function
+
+  @return EFI_SUCCESS
+  @return Other           See individual leaf functions
+**/
+EFI_STATUS
+EFIAPI
+MpTdCall (
+  IN UINT64           Leaf,
+  IN UINT64           Arg1,
+  IN UINT64           Arg2,
+  IN UINT64           Arg3,
+  IN OUT VOID         *Results
+  );
+
+/**
+  Whether Intel TDX is enabled.
+
+  @return TRUE    TDX enabled
+  @return FALSE   TDX not enabled
+**/
+BOOLEAN
+EFIAPI
+MpTdxIsEnabled (
+  VOID
+  );
+
+#endif
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index b9a06747edbf..7ccfde0d79f7 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -9,9 +9,11 @@
 **/
 
 #include "MpLib.h"
+#include "MpIntelTdx.h"
 #include <Library/VmgExitLib.h>
 #include <Register/Amd/Fam17Msr.h>
 #include <Register/Amd/Ghcb.h>
+#include <ConfidentialComputingGuestAttr.h>
 
 EFI_GUID mCpuInitMpLibHobGuid = CPU_INIT_MP_LIB_HOB_GUID;
 
@@ -1965,6 +1967,10 @@ MpInitLibInitialize (
   UINTN                    BackupBufferAddr;
   UINTN                    ApIdtBase;
 
+  if (CC_GUEST_IS_TDX (PcdGet64 (PcdConfidentialComputingGuestAttr))) {
+    return EFI_SUCCESS;
+  }
+
   OldCpuMpData = GetCpuMpDataFromGuidedHob ();
   if (OldCpuMpData == NULL) {
     MaxLogicalProcessorNumber = PcdGet32(PcdCpuMaxLogicalProcessorNumber);
@@ -2215,6 +2221,10 @@ MpInitLibGetProcessorInfo (
   CPU_INFO_IN_HOB        *CpuInfoInHob;
   UINTN                  OriginalProcessorNumber;
 
+  if (CC_GUEST_IS_TDX (PcdGet64 (PcdConfidentialComputingGuestAttr))) {
+    return TdxMpInitLibGetProcessorInfo (ProcessorNumber, ProcessorInfoBuffer, HealthData);
+  }
+
   CpuMpData = GetCpuMpData ();
   CpuInfoInHob = (CPU_INFO_IN_HOB *) (UINTN) CpuMpData->CpuInfoInHob;
 
@@ -2446,6 +2456,10 @@ EnableDisableApWorker (
   CPU_MP_DATA               *CpuMpData;
   UINTN                     CallerNumber;
 
+  if (CC_GUEST_IS_TDX (PcdGet64 (PcdConfidentialComputingGuestAttr))) {
+    return EFI_UNSUPPORTED;
+  }
+
   CpuMpData = GetCpuMpData ();
 
   //
@@ -2506,6 +2520,11 @@ MpInitLibWhoAmI (
     return EFI_INVALID_PARAMETER;
   }
 
+  if (CC_GUEST_IS_TDX (PcdGet64 (PcdConfidentialComputingGuestAttr))) {
+    *ProcessorNumber = 0;
+    return EFI_SUCCESS;
+  }
+
   CpuMpData = GetCpuMpData ();
 
   return GetProcessorNumber (CpuMpData, ProcessorNumber);
@@ -2544,6 +2563,10 @@ MpInitLibGetNumberOfProcessors (
   UINTN                   EnabledProcessorNumber;
   UINTN                   Index;
 
+  if (CC_GUEST_IS_TDX (PcdGet64 (PcdConfidentialComputingGuestAttr))) {
+    return TdxMpInitLibGetNumberOfProcessors(NumberOfProcessors, NumberOfEnabledProcessors);
+  }
+
   CpuMpData = GetCpuMpData ();
 
   if ((NumberOfProcessors == NULL) && (NumberOfEnabledProcessors == NULL)) {
@@ -2629,6 +2652,10 @@ StartupAllCPUsWorker (
   BOOLEAN                 HasEnabledAp;
   CPU_STATE               ApState;
 
+  if (CC_GUEST_IS_TDX (PcdGet64 (PcdConfidentialComputingGuestAttr))) {
+    return EFI_SUCCESS;
+  }
+
   CpuMpData = GetCpuMpData ();
 
   if (FailedCpuList != NULL) {
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLibTdx.c b/UefiCpuPkg/Library/MpInitLib/MpLibTdx.c
new file mode 100644
index 000000000000..fb9f6e3ee4b0
--- /dev/null
+++ b/UefiCpuPkg/Library/MpInitLib/MpLibTdx.c
@@ -0,0 +1,126 @@
+/** @file
+  CPU MP Initialize Library common functions.
+
+  Copyright (c) 2016 - 2020, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2020, AMD Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "MpLib.h"
+#include "MpIntelTdx.h"
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <IndustryStandard/Tdx.h>
+
+/**
+  Gets detailed MP-related information on the requested processor at the
+  instant this call is made. This service may only be called from the BSP.
+
+  @param[in]  ProcessorNumber       The handle number of processor.
+  @param[out] ProcessorInfoBuffer   A pointer to the buffer where information for
+                                    the requested processor is deposited.
+  @param[out]  HealthData            Return processor health data.
+
+  @retval EFI_SUCCESS             Processor information was returned.
+  @retval EFI_DEVICE_ERROR        The calling processor is an AP.
+  @retval EFI_INVALID_PARAMETER   ProcessorInfoBuffer is NULL.
+  @retval EFI_NOT_FOUND           The processor with the handle specified by
+                                  ProcessorNumber does not exist in the platform.
+  @retval EFI_NOT_READY           MP Initialize Library is not initialized.
+
+**/
+EFI_STATUS
+EFIAPI
+TdxMpInitLibGetProcessorInfo (
+  IN  UINTN                      ProcessorNumber,
+  OUT EFI_PROCESSOR_INFORMATION  *ProcessorInfoBuffer,
+  OUT EFI_HEALTH_FLAGS           *HealthData  OPTIONAL
+  )
+{
+  EFI_STATUS              Status;
+  TD_RETURN_DATA          TdReturnData;
+
+  if (ProcessorInfoBuffer == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = MpTdCall(TDCALL_TDINFO, 0, 0, 0, &TdReturnData);
+  ASSERT(Status == EFI_SUCCESS);
+
+  if (ProcessorNumber >= TdReturnData.TdInfo.NumVcpus) {
+    return EFI_NOT_FOUND;
+  }
+
+  ProcessorInfoBuffer->ProcessorId = ProcessorNumber;
+  ProcessorInfoBuffer->StatusFlag  = 0;
+  if (ProcessorNumber == 0) {
+    ProcessorInfoBuffer->StatusFlag |= PROCESSOR_AS_BSP_BIT;
+  }
+  ProcessorInfoBuffer->StatusFlag |= PROCESSOR_ENABLED_BIT;
+
+  //
+  // Get processor location information
+  //
+  GetProcessorLocationByApicId (
+    (UINT32)ProcessorNumber,
+    &ProcessorInfoBuffer->Location.Package,
+    &ProcessorInfoBuffer->Location.Core,
+    &ProcessorInfoBuffer->Location.Thread
+    );
+
+  if (HealthData != NULL) {
+    HealthData->Uint32 = 0;
+  }
+
+  return Status;
+}
+
+/**
+  Retrieves the number of logical processor in the platform and the number of
+  those logical processors that are enabled on this boot. This service may only
+  be called from the BSP.
+
+  @param[out] NumberOfProcessors          Pointer to the total number of logical
+                                          processors in the system, including the BSP
+                                          and disabled APs.
+  @param[out] NumberOfEnabledProcessors   Pointer to the number of enabled logical
+                                          processors that exist in system, including
+                                          the BSP.
+
+  @retval EFI_SUCCESS             The number of logical processors and enabled
+                                  logical processors was retrieved.
+  @retval EFI_DEVICE_ERROR        The calling processor is an AP.
+  @retval EFI_INVALID_PARAMETER   NumberOfProcessors is NULL and NumberOfEnabledProcessors
+                                  is NULL.
+  @retval EFI_NOT_READY           MP Initialize Library is not initialized.
+
+**/
+EFI_STATUS
+EFIAPI
+TdxMpInitLibGetNumberOfProcessors (
+  OUT UINTN                     *NumberOfProcessors,       OPTIONAL
+  OUT UINTN                     *NumberOfEnabledProcessors OPTIONAL
+  )
+{
+  EFI_STATUS              Status;
+  TD_RETURN_DATA          TdReturnData;
+
+  if ((NumberOfProcessors == NULL) && (NumberOfEnabledProcessors == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = MpTdCall(TDCALL_TDINFO, 0, 0, 0, &TdReturnData);
+  ASSERT(Status == EFI_SUCCESS);
+
+  if (NumberOfProcessors != NULL) {
+    *NumberOfProcessors = TdReturnData.TdInfo.NumVcpus;
+  }
+  if (NumberOfEnabledProcessors != NULL) {
+    *NumberOfEnabledProcessors = TdReturnData.TdInfo.MaxVcpus;
+  }
+
+  return Status;
+}
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLibTdxNull.c b/UefiCpuPkg/Library/MpInitLib/MpLibTdxNull.c
new file mode 100644
index 000000000000..f9cfedf01240
--- /dev/null
+++ b/UefiCpuPkg/Library/MpInitLib/MpLibTdxNull.c
@@ -0,0 +1,117 @@
+/** @file
+  CPU MP Initialize Library common functions.
+
+  Copyright (c) 2016 - 2020, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2020, AMD Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "MpLib.h"
+#include "MpIntelTdx.h"
+#include <Library/DebugLib.h>
+
+/**
+  Gets detailed MP-related information on the requested processor at the
+  instant this call is made. This service may only be called from the BSP.
+
+  @param[in]  ProcessorNumber       The handle number of processor.
+  @param[out] ProcessorInfoBuffer   A pointer to the buffer where information for
+                                    the requested processor is deposited.
+  @param[out]  HealthData            Return processor health data.
+
+  @retval EFI_SUCCESS             Processor information was returned.
+  @retval EFI_DEVICE_ERROR        The calling processor is an AP.
+  @retval EFI_INVALID_PARAMETER   ProcessorInfoBuffer is NULL.
+  @retval EFI_NOT_FOUND           The processor with the handle specified by
+                                  ProcessorNumber does not exist in the platform.
+  @retval EFI_NOT_READY           MP Initialize Library is not initialized.
+
+**/
+EFI_STATUS
+EFIAPI
+TdxMpInitLibGetProcessorInfo (
+  IN  UINTN                      ProcessorNumber,
+  OUT EFI_PROCESSOR_INFORMATION  *ProcessorInfoBuffer,
+  OUT EFI_HEALTH_FLAGS           *HealthData  OPTIONAL
+  )
+{
+  ASSERT (FALSE);
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Retrieves the number of logical processor in the platform and the number of
+  those logical processors that are enabled on this boot. This service may only
+  be called from the BSP.
+
+  @param[out] NumberOfProcessors          Pointer to the total number of logical
+                                          processors in the system, including the BSP
+                                          and disabled APs.
+  @param[out] NumberOfEnabledProcessors   Pointer to the number of enabled logical
+                                          processors that exist in system, including
+                                          the BSP.
+
+  @retval EFI_SUCCESS             The number of logical processors and enabled
+                                  logical processors was retrieved.
+  @retval EFI_DEVICE_ERROR        The calling processor is an AP.
+  @retval EFI_INVALID_PARAMETER   NumberOfProcessors is NULL and NumberOfEnabledProcessors
+                                  is NULL.
+  @retval EFI_NOT_READY           MP Initialize Library is not initialized.
+
+**/
+EFI_STATUS
+EFIAPI
+TdxMpInitLibGetNumberOfProcessors (
+  OUT UINTN                     *NumberOfProcessors,       OPTIONAL
+  OUT UINTN                     *NumberOfEnabledProcessors OPTIONAL
+  )
+{
+  ASSERT (FALSE);
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Whether Intel TDX is enabled.
+
+  @return TRUE    TDX enabled
+  @return FALSE   TDX not enabled
+**/
+BOOLEAN
+EFIAPI
+MpTdxIsEnabled (
+  VOID
+  )
+{
+  return FALSE;
+}
+
+/**
+  The TDCALL instruction causes a VM exit to the Intel TDX module.  It is
+  used to call guest-side Intel TDX functions, either local or a TD exit
+  to the host VMM, as selected by Leaf.
+  Leaf functions are described at <https://software.intel.com/content/
+  www/us/en/develop/articles/intel-trust-domain-extensions.html>
+
+  @param[in]      Leaf        Leaf number of TDCALL instruction
+  @param[in]      Arg1        Arg1
+  @param[in]      Arg2        Arg2
+  @param[in]      Arg3        Arg3
+  @param[in,out]  Results  Returned result of the Leaf function
+
+  @return EFI_SUCCESS
+  @return Other           See individual leaf functions
+**/
+EFI_STATUS
+EFIAPI
+MpTdCall (
+  IN UINT64           Leaf,
+  IN UINT64           Arg1,
+  IN UINT64           Arg2,
+  IN UINT64           Arg3,
+  IN OUT VOID         *Results
+  )
+{
+  return EFI_UNSUPPORTED;
+}
diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
index 36fcb96b5852..7c1a773f2bef 100644
--- a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
@@ -22,10 +22,13 @@
 #
 
 [Sources.IA32]
+  MpLibTdxNull.c
   Ia32/MpFuncs.nasm
 
 [Sources.X64]
+  MpLibTdx.c
   X64/MpFuncs.nasm
+  X64/IntelTdcall.nasm
 
 [Sources.common]
   MpEqu.inc
@@ -33,6 +36,7 @@
   MpLib.c
   MpLib.h
   Microcode.c
+  MpIntelTdx.h
 
 [Packages]
   MdePkg/MdePkg.dec
@@ -65,6 +69,7 @@
   gUefiCpuPkgTokenSpaceGuid.PcdSevEsIsEnabled                      ## CONSUMES
   gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase                   ## SOMETIMES_CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase                       ## CONSUMES
+  gEfiMdePkgTokenSpaceGuid.PcdConfidentialComputingGuestAttr       ## CONSUMES
 
 [Ppis]
   gEdkiiPeiShadowMicrocodePpiGuid        ## SOMETIMES_CONSUMES
diff --git a/UefiCpuPkg/Library/MpInitLib/X64/IntelTdcall.nasm b/UefiCpuPkg/Library/MpInitLib/X64/IntelTdcall.nasm
new file mode 100644
index 000000000000..5e98557d5590
--- /dev/null
+++ b/UefiCpuPkg/Library/MpInitLib/X64/IntelTdcall.nasm
@@ -0,0 +1,120 @@
+;------------------------------------------------------------------------------
+;*
+;* Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.<BR>
+;* SPDX-License-Identifier: BSD-2-Clause-Patent
+;*
+;*
+;------------------------------------------------------------------------------
+
+DEFAULT REL
+SECTION .text
+
+%macro tdcall 0
+    db 0x66,0x0f,0x01,0xcc
+%endmacro
+
+%macro tdcall_push_regs 0
+    push rbp
+    mov  rbp, rsp
+    push r15
+    push r14
+    push r13
+    push r12
+    push rbx
+    push rsi
+    push rdi
+%endmacro
+
+%macro tdcall_pop_regs 0
+    pop rdi
+    pop rsi
+    pop rbx
+    pop r12
+    pop r13
+    pop r14
+    pop r15
+    pop rbp
+%endmacro
+
+%define number_of_regs_pushed 8
+%define number_of_parameters  4
+
+;
+; Keep these in sync for push_regs/pop_regs, code below
+; uses them to find 5th or greater parameters
+;
+%define first_variable_on_stack_offset \
+  ((number_of_regs_pushed * 8) + (number_of_parameters * 8) + 8)
+%define second_variable_on_stack_offset \
+  ((first_variable_on_stack_offset) + 8)
+
+%macro tdcall_regs_preamble 2
+    mov rax, %1
+
+    mov ecx, %2
+
+    ; R10 = 0 (standard TDVMCALL)
+
+    xor r10d, r10d
+
+    ; Zero out unused (for standard TDVMCALL) registers to avoid leaking
+    ; secrets to the VMM.
+
+    xor ebx, ebx
+    xor esi, esi
+    xor edi, edi
+
+    xor edx, edx
+    xor ebp, ebp
+    xor r8d, r8d
+    xor r9d, r9d
+%endmacro
+
+%macro tdcall_regs_postamble 0
+    xor ebx, ebx
+    xor esi, esi
+    xor edi, edi
+
+    xor ecx, ecx
+    xor edx, edx
+    xor r8d,  r8d
+    xor r9d,  r9d
+    xor r10d, r10d
+    xor r11d, r11d
+%endmacro
+
+;  MpTdCall (
+;    UINT64  Leaf,    // Rcx
+;    UINT64  P1,      // Rdx
+;    UINT64  P2,      // R8
+;    UINT64  P3,      // R9
+;    UINT64  Results, // rsp + 0x28
+;    )
+global ASM_PFX(MpTdCall)
+ASM_PFX(MpTdCall):
+       tdcall_push_regs
+
+       mov rax, rcx
+       mov rcx, rdx
+       mov rdx, r8
+       mov r8, r9
+
+       tdcall
+
+       ; exit if tdcall reports failure.
+       test rax, rax
+       jnz .exit
+
+       ; test if caller wanted results
+       mov r12, [rsp + first_variable_on_stack_offset ]
+       test r12, r12
+       jz .exit
+       mov [r12 + 0 ], rcx
+       mov [r12 + 8 ], rdx
+       mov [r12 + 16], r8
+       mov [r12 + 24], r9
+       mov [r12 + 32], r10
+       mov [r12 + 40], r11
+.exit:
+       tdcall_pop_regs
+       ret
-- 
2.29.2.windows.2



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#82969): https://edk2.groups.io/g/devel/message/82969
Mute This Topic: https://groups.io/mt/86739862/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-


Re: [edk2-devel] [PATCH V3 14/29] UefiCpuPkg: Enable Tdx support in MpInitLib
Posted by Gerd Hoffmann 4 years, 3 months ago
> +++ b/UefiCpuPkg/Library/MpInitLib/X64/IntelTdcall.nasm
> @@ -0,0 +1,120 @@
> +;------------------------------------------------------------------------------
> +;*
> +;* Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.<BR>
> +;* SPDX-License-Identifier: BSD-2-Clause-Patent
> +;*
> +;*
> +;------------------------------------------------------------------------------
> +
> +DEFAULT REL
> +SECTION .text
> +
> +%macro tdcall 0
> +    db 0x66,0x0f,0x01,0xcc
> +%endmacro

Hmm, could you just use TdxLib instead of bringing your own copy of the
assembler code?

take care,
  Gerd



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#83219): https://edk2.groups.io/g/devel/message/83219
Mute This Topic: https://groups.io/mt/86739862/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-


Re: [edk2-devel] [PATCH V3 14/29] UefiCpuPkg: Enable Tdx support in MpInitLib
Posted by Min Xu 4 years, 3 months ago
On November 3, 2021 2:09 PM, Gerd Hoffmann wrote:
> > +++ b/UefiCpuPkg/Library/MpInitLib/X64/IntelTdcall.nasm
> > @@ -0,0 +1,120 @@
> > +;--------------------------------------------------------------------
> > +----------
> > +;*
> > +;* Copyright (c) 2020 - 2021, Intel Corporation. All rights
> > +reserved.<BR>
> > +;* SPDX-License-Identifier: BSD-2-Clause-Patent
> > +;*
> > +;*
> > +;--------------------------------------------------------------------
> > +----------
> > +
> > +DEFAULT REL
> > +SECTION .text
> > +
> > +%macro tdcall 0
> > +    db 0x66,0x0f,0x01,0xcc
> > +%endmacro
> 
> Hmm, could you just use TdxLib instead of bringing your own copy of the
> assembler code?
> 
My initial thought was to include TdxLib in the .dsc as little as possible. For example, DxeMpInitLib is included in OvmfPkg/Microvm/MicrovmX64.dsc. If TdxLib is used by DxeMpInitLib, then it has to be included in MicrovmX64.dsc as well.
So I copy the assemble code in MpInitLib.
But now VmgExitLib is extended to handle #VE exception ( TdxLib must be used ), so TdxLib has to be included in the .dsc where VmgExitLib is included.
I will update the MpInitLib to use TdxLib in the next version.

Thanks
Min



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#83251): https://edk2.groups.io/g/devel/message/83251
Mute This Topic: https://groups.io/mt/86739862/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-


Re: [edk2-devel] [PATCH V3 14/29] UefiCpuPkg: Enable Tdx support in MpInitLib
Posted by Gerd Hoffmann 4 years, 3 months ago
On Wed, Nov 03, 2021 at 12:57:37PM +0000, Xu, Min M wrote:
> On November 3, 2021 2:09 PM, Gerd Hoffmann wrote:
> > > +++ b/UefiCpuPkg/Library/MpInitLib/X64/IntelTdcall.nasm
> > > @@ -0,0 +1,120 @@
> > > +;--------------------------------------------------------------------
> > > +----------
> > > +;*
> > > +;* Copyright (c) 2020 - 2021, Intel Corporation. All rights
> > > +reserved.<BR>
> > > +;* SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +;*
> > > +;*
> > > +;--------------------------------------------------------------------
> > > +----------
> > > +
> > > +DEFAULT REL
> > > +SECTION .text
> > > +
> > > +%macro tdcall 0
> > > +    db 0x66,0x0f,0x01,0xcc
> > > +%endmacro
> > 
> > Hmm, could you just use TdxLib instead of bringing your own copy of the
> > assembler code?

> My initial thought was to include TdxLib in the .dsc as little as
> possible. For example, DxeMpInitLib is included in
> OvmfPkg/Microvm/MicrovmX64.dsc. If TdxLib is used by DxeMpInitLib,
> then it has to be included in MicrovmX64.dsc as well.

Hmm, yes.  Adding a TdxLib dependency has its downsides indeed.

> So I copy the assemble code in MpInitLib.

The problem with copying code is that long-term maintenance becomes
harder.  When a bug is found you have to find and fix all the copies of
that code.  That's why I strongly prefer to avoid code copy&paste.
Sometimes there is no easy way around creating a copy though.

take care,
  Gerd



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#83325): https://edk2.groups.io/g/devel/message/83325
Mute This Topic: https://groups.io/mt/86739862/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-


Re: [edk2-devel] [PATCH V3 14/29] UefiCpuPkg: Enable Tdx support in MpInitLib
Posted by Lendacky, Thomas via groups.io 4 years, 3 months ago
On 11/4/21 3:10 AM, Gerd Hoffmann wrote:
> On Wed, Nov 03, 2021 at 12:57:37PM +0000, Xu, Min M wrote:
>> On November 3, 2021 2:09 PM, Gerd Hoffmann wrote:
>>>> +++ b/UefiCpuPkg/Library/MpInitLib/X64/IntelTdcall.nasm
>>>> @@ -0,0 +1,120 @@
>>>> +;--------------------------------------------------------------------
>>>> +----------
>>>> +;*
>>>> +;* Copyright (c) 2020 - 2021, Intel Corporation. All rights
>>>> +reserved.<BR>
>>>> +;* SPDX-License-Identifier: BSD-2-Clause-Patent
>>>> +;*
>>>> +;*
>>>> +;--------------------------------------------------------------------
>>>> +----------
>>>> +
>>>> +DEFAULT REL
>>>> +SECTION .text
>>>> +
>>>> +%macro tdcall 0
>>>> +    db 0x66,0x0f,0x01,0xcc
>>>> +%endmacro
>>>
>>> Hmm, could you just use TdxLib instead of bringing your own copy of the
>>> assembler code?
> 
>> My initial thought was to include TdxLib in the .dsc as little as
>> possible. For example, DxeMpInitLib is included in
>> OvmfPkg/Microvm/MicrovmX64.dsc. If TdxLib is used by DxeMpInitLib,
>> then it has to be included in MicrovmX64.dsc as well.
> 
> Hmm, yes.  Adding a TdxLib dependency has its downsides indeed.
> 
>> So I copy the assemble code in MpInitLib.
> 
> The problem with copying code is that long-term maintenance becomes
> harder.  When a bug is found you have to find and fix all the copies of
> that code.  That's why I strongly prefer to avoid code copy&paste.
> Sometimes there is no easy way around creating a copy though.

Can't you create something in MdePkg/Library/Baselib and then use it 
everywhere it's needed?

Thanks,
Tom

> 
> take care,
>    Gerd
> 


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#83349): https://edk2.groups.io/g/devel/message/83349
Mute This Topic: https://groups.io/mt/86739862/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-


Re: [edk2-devel] [PATCH V3 14/29] UefiCpuPkg: Enable Tdx support in MpInitLib
Posted by Min Xu 4 years, 3 months ago
On November 4, 2021 11:21 PM, Tom Lendacky wrote:
> On 11/4/21 3:10 AM, Gerd Hoffmann wrote:
> > On Wed, Nov 03, 2021 at 12:57:37PM +0000, Xu, Min M wrote:
> >> On November 3, 2021 2:09 PM, Gerd Hoffmann wrote:
> >>>> +++ b/UefiCpuPkg/Library/MpInitLib/X64/IntelTdcall.nasm
> >>>> @@ -0,0 +1,120 @@
> >>>> +;-----------------------------------------------------------------
> >>>> +---
> >>>> +----------
> >>>> +;*
> >>>> +;* Copyright (c) 2020 - 2021, Intel Corporation. All rights
> >>>> +reserved.<BR>
> >>>> +;* SPDX-License-Identifier: BSD-2-Clause-Patent
> >>>> +;*
> >>>> +;*
> >>>> +;-----------------------------------------------------------------
> >>>> +---
> >>>> +----------
> >>>> +
> >>>> +DEFAULT REL
> >>>> +SECTION .text
> >>>> +
> >>>> +%macro tdcall 0
> >>>> +    db 0x66,0x0f,0x01,0xcc
> >>>> +%endmacro
> >>>
> >>> Hmm, could you just use TdxLib instead of bringing your own copy of
> >>> the assembler code?
> >
> >> My initial thought was to include TdxLib in the .dsc as little as
> >> possible. For example, DxeMpInitLib is included in
> >> OvmfPkg/Microvm/MicrovmX64.dsc. If TdxLib is used by DxeMpInitLib,
> >> then it has to be included in MicrovmX64.dsc as well.
> >
> > Hmm, yes.  Adding a TdxLib dependency has its downsides indeed.
> >
> >> So I copy the assemble code in MpInitLib.
> >
> > The problem with copying code is that long-term maintenance becomes
> > harder.  When a bug is found you have to find and fix all the copies
> > of that code.  That's why I strongly prefer to avoid code copy&paste.
> > Sometimes there is no easy way around creating a copy though.
> 
> Can't you create something in MdePkg/Library/Baselib and then use it
> everywhere it's needed?
> 
Do you mean put the basic Tdx functions in MdePkg/Library/BaseLib? If that is the case, then I would add below basic Tdx functions in BaseLib:
 - TdIsEnabled ()
 - TdCall ()
 - TdVmCall ()

Gerd, what's your thought?

Thanks
Min


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#83357): https://edk2.groups.io/g/devel/message/83357
Mute This Topic: https://groups.io/mt/86739862/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-


Re: [edk2-devel] [PATCH V3 14/29] UefiCpuPkg: Enable Tdx support in MpInitLib
Posted by Gerd Hoffmann 4 years, 3 months ago
> > Can't you create something in MdePkg/Library/Baselib and then use it
> > everywhere it's needed?
> > 
> Do you mean put the basic Tdx functions in MdePkg/Library/BaseLib? If that is the case, then I would add below basic Tdx functions in BaseLib:
>  - TdIsEnabled ()
>  - TdCall ()
>  - TdVmCall ()

That is the cpuid-based check and the asm code for td calls, correct?

> Gerd, what's your thought?

Looks fine to me.

take care,
  Gerd



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#83371): https://edk2.groups.io/g/devel/message/83371
Mute This Topic: https://groups.io/mt/86739862/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-


Re: [edk2-devel] [PATCH V3 14/29] UefiCpuPkg: Enable Tdx support in MpInitLib
Posted by Min Xu 4 years, 3 months ago
On November 5, 2021 2:46 PM, Gerd Hoffmann wrote:
> > > Can't you create something in MdePkg/Library/Baselib and then use it
> > > everywhere it's needed?
> > >
> > Do you mean put the basic Tdx functions in MdePkg/Library/BaseLib? If that is
> the case, then I would add below basic Tdx functions in BaseLib:
> >  - TdIsEnabled ()
> >  - TdCall ()
> >  - TdVmCall ()
> 
> That is the cpuid-based check and the asm code for td calls, correct?
TdIsEnabled() is the cpuid-based check.
TdCall/TdVmCall are the asm code.
> 
> > Gerd, what's your thought?
> 
> Looks fine to me.

Thanks
Min


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#83372): https://edk2.groups.io/g/devel/message/83372
Mute This Topic: https://groups.io/mt/86739862/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-


Re: [edk2-devel] [PATCH V3 14/29] UefiCpuPkg: Enable Tdx support in MpInitLib
Posted by Min Xu 4 years, 3 months ago
On November 5, 2021 2:46 PM, Gerd Hoffmann wrote:
> > > Can't you create something in MdePkg/Library/Baselib and then use it
> > > everywhere it's needed?
> > >
> > Do you mean put the basic Tdx functions in MdePkg/Library/BaseLib? If that is
> the case, then I would add below basic Tdx functions in BaseLib:
> >  - TdIsEnabled ()
> >  - TdCall ()
> >  - TdVmCall ()
> 
> That is the cpuid-based check and the asm code for td calls, correct?
> 
> > Gerd, what's your thought?
> 
> Looks fine to me.
> 
Hi, Liming & Michael
You're the MdePkg maintainers. What's your thoughts about adding these Tdx functions in MdePkg/Library/BaseLib?
  - TdIsEnabled ()  <-- cpuid-based check if it is a TD guest
  - TdCall ()             <-- TD call
  - TdVmCall ()       <-- TD vmcall
https://github.com/mxu9/edk2/blob/tdvf_wave2.v3/MdePkg/Library/TdxLib/X64/Tdcall.nasm
https://github.com/mxu9/edk2/blob/tdvf_wave2.v3/MdePkg/Library/TdxLib/X64/Tdvmcall.nasm

Thanks
Min




-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#83478): https://edk2.groups.io/g/devel/message/83478
Mute This Topic: https://groups.io/mt/86739862/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-