public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH V6 00/12] Enable Tdx measurement in OvmfPkgX64
@ 2023-02-03  3:31 Min Xu
  2023-02-03  3:31 ` [PATCH V6 01/12] OvmfPkg: Add Tdx measurement data structure in WorkArea Min Xu
                   ` (11 more replies)
  0 siblings, 12 replies; 14+ messages in thread
From: Min Xu @ 2023-02-03  3:31 UTC (permalink / raw)
  To: devel
  Cc: Min Xu, Erdem Aktas, James Bottomley, Jiewen Yao, Gerd Hoffmann,
	Tom Lendacky, Michael Roth

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4243

Tdx measurement (RTMR based measurement) is enabled in OvmfPkg/IntelTdx.
This patch-set enables the feature in OvmfPkgX64 as well.

Patch #1:
  Introduce TDX_MEASUREMETNS_DATA in SEC_TDX_WORK_AREA. That is because
  the RTMR measurement of TdHob and Configuration FV (CFV) are executed
  in very early stage of boot process. At that time the memory service is
  not ready and the measurement values have to be stored in OvmfWorkArea.

Patch #2:
  Introduce TdxHelperLibNull which is the NULL instance of TdxHelperLib.

Patch #3:
  Introduce SecTdxHelperLib which is the instance of TdxHelperLib for SEC
  Phase. This patch adds the stubs of TdxHelperLib functions. The actual
  implementation are in the following patches.

Patch #4:
  Re-use the data struct of PLATFORM_FIRMWARE_BLOB2_STRUCT for
  FV_HANDOFF_TABLE_POINTERS2.
  
Patch #5-7:
  These 3 patches move the functions ( which were implemented in
  PeilessStartupLib and PlatformInitLib ) to TdxHelperLib. So that they
  can be called in both OvmfPkgX64 and IntelTdxX64.

Patch #8:
  Do tdx measurement in SecMain in IntelTdxX64 and delete the duplicated
  code in PeilessStartupLib.

Patch #9-12:
  These 4 patches are the changes for OvmfPkgX64 to enable Tdx
  measurement.

Code: https://github.com/mxu9/edk2/tree/TdxMeasurementInOvmfX64.v6

v6 changes:
 - Merge patch 8 and 9 (i.e. move instead of add + delete).
 - Rename TDX_MEASUREMENT_ENABLE to CC_MEASUREMENT_ENABLE so that
   the name is more accurate.

v5 changes:
 - Re-organize the patches. Its purpose is not only to simplify review, but also
   to simplify testing. https://edk2.groups.io/g/devel/message/99209

v4 changes:
 - To make the code reviewable, the implementation of
   TdxHelperBuildGuidHobForTdxMeasurement is split into 4 patches (5-8).
 - Call Sha384HashAll instead of the 3 Sha384XXX functions so that we
   need to allocate memory in SEC phase.

v3 changes:
 - Use the definition of PLATFORM_FIRMWARE_BLOB2_STRUCT in
   Library/TcgEventLogRecordLib.h.
 - Rename TDX_ENABLE as TDX_MEASUREMENT_ENABLE because this flag is
   introduced for Tdx-measurement.
 - Split the patch of SecTdxHelperLib into 2 separate patches (#3/#9).
   Patch#3 implements TdxHelperMeasureTdHob and TdxHelperMeasureCfvImage.
   Patch#9 implements TdxHelperProcessTdHob. This is to make the patches
   more reviewable. The duplicated codes of TdxHelperProcessTdHob are
   deleted in Patch#9 as well.
 - The implementation of TdxHelperBuildGuidHobForTdxMeasurement and update
   of PeilessStartupLib are in one patch (#5). Because the implmentation
   of TdxHelperBuildGuidHobForTdxMeasurement was once in PeilessStartupLib.

v2 changes:
 - Split the patch of TdxHelperLib into 4 separate patches. So that it is
   more reviewable.
 - Add commit message in Patch#1 to emphasize that the tdx-measurement in
   OvmfPkgX64 is supported in SEC phase.

Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Michael Roth <michael.roth@amd.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>

Min M Xu (12):
  OvmfPkg: Add Tdx measurement data structure in WorkArea
  OvmfPkg/IntelTdx: Add TdxHelperLibNull
  OvmfPkg/IntelTdx: Add SecTdxHelperLib
  OvmfPkg/PeilessStartupLib: Update the define of
    FV_HANDOFF_TABLE_POINTERS2
  OvmfPkg: Refactor MeasureHobList
  OvmfPkg: Refactor MeaureFvImage
  OvmfPkg: Refactor ProcessHobList
  OvmfPkg/IntelTdx: Measure TdHob and Configuration FV in SecMain
  OvmfPkg/IntelTdx: Add PeiTdxHelperLib
  OvmfPkg/OvmfPkgX64: Measure TdHob and Configuration FV in SecMain
  OvmfPkg/PlatformPei: Build GuidHob for Tdx measurement
  OvmfPkg: Support Tdx measurement in OvmfPkgX64

 OvmfPkg/AmdSev/AmdSevX64.dsc                  |   5 +-
 OvmfPkg/CloudHv/CloudHvX64.dsc                |   5 +-
 OvmfPkg/Include/Dsc/OvmfTpmLibs.dsc.inc       |  10 +-
 .../Include/Dsc/OvmfTpmSecurityStub.dsc.inc   |   8 +
 OvmfPkg/Include/Library/PlatformInitLib.h     |  17 -
 OvmfPkg/Include/Library/TdxHelperLib.h        |  70 ++
 OvmfPkg/Include/WorkArea.h                    |  25 +-
 OvmfPkg/IntelTdx/IntelTdxX64.dsc              |   4 +-
 OvmfPkg/IntelTdx/Sec/SecMain.c                |  17 +-
 OvmfPkg/IntelTdx/TdxHelperLib/PeiTdxHelper.c  |  91 +++
 .../IntelTdx/TdxHelperLib/PeiTdxHelperLib.inf |  48 ++
 .../TdxHelperLib/SecTdxHelper.c}              | 304 +++----
 .../IntelTdx/TdxHelperLib/SecTdxHelperLib.inf |  53 ++
 .../TdxHelperLib/TdxHelperLibNull.inf         |  32 +
 OvmfPkg/IntelTdx/TdxHelperLib/TdxHelperNull.c |  79 ++
 .../IntelTdx/TdxHelperLib/TdxMeasurementHob.c | 259 ++++++
 OvmfPkg/Library/PeilessStartupLib/IntelTdx.c  | 196 -----
 .../PeilessStartupLib/PeilessStartup.c        |  16 +-
 .../PeilessStartupInternal.h                  |  36 -
 .../PeilessStartupLib/PeilessStartupLib.inf   |   6 -
 OvmfPkg/Library/PlatformInitLib/IntelTdx.c    | 768 ------------------
 .../Library/PlatformInitLib/IntelTdxNull.c    |  20 -
 .../PlatformInitLib/PlatformInitLib.inf       |   1 -
 OvmfPkg/Microvm/MicrovmX64.dsc                |   5 +-
 OvmfPkg/OvmfPkg.dec                           |   4 +
 OvmfPkg/OvmfPkgX64.dsc                        |  20 +-
 OvmfPkg/OvmfPkgX64.fdf                        |   7 +
 OvmfPkg/PlatformPei/IntelTdx.c                |   3 +
 OvmfPkg/Sec/SecMain.c                         |  17 +-
 29 files changed, 915 insertions(+), 1211 deletions(-)
 create mode 100644 OvmfPkg/Include/Library/TdxHelperLib.h
 create mode 100644 OvmfPkg/IntelTdx/TdxHelperLib/PeiTdxHelper.c
 create mode 100644 OvmfPkg/IntelTdx/TdxHelperLib/PeiTdxHelperLib.inf
 copy OvmfPkg/{Library/PlatformInitLib/IntelTdx.c => IntelTdx/TdxHelperLib/SecTdxHelper.c} (80%)
 create mode 100644 OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelperLib.inf
 create mode 100644 OvmfPkg/IntelTdx/TdxHelperLib/TdxHelperLibNull.inf
 create mode 100644 OvmfPkg/IntelTdx/TdxHelperLib/TdxHelperNull.c
 create mode 100644 OvmfPkg/IntelTdx/TdxHelperLib/TdxMeasurementHob.c
 delete mode 100644 OvmfPkg/Library/PeilessStartupLib/IntelTdx.c

-- 
2.29.2.windows.2


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH V6 01/12] OvmfPkg: Add Tdx measurement data structure in WorkArea
  2023-02-03  3:31 [PATCH V6 00/12] Enable Tdx measurement in OvmfPkgX64 Min Xu
@ 2023-02-03  3:31 ` Min Xu
  2023-02-03  3:31 ` [PATCH V6 02/12] OvmfPkg/IntelTdx: Add TdxHelperLibNull Min Xu
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Min Xu @ 2023-02-03  3:31 UTC (permalink / raw)
  To: devel
  Cc: Min M Xu, Erdem Aktas, James Bottomley, Jiewen Yao, Gerd Hoffmann,
	Tom Lendacky, Michael Roth

From: Min M Xu <min.m.xu@intel.com>

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4243

>From the perspective of security any external input should be measured
and extended to some registers (TPM PCRs or TDX RTMR registers).

There are below 2 external input in a Td guest:
 - TdHob
 - Configuration FV (CFV)

TdHob contains the resource information passed from VMM, such as
unaccepted memory region. CFV contains the configurations, such as
secure boot variables.

TdHob and CFV should be measured and extended to RTMRs before they're
consumed. TdHob is consumed in the very early stage of boot process.
At that moment the memory service is not ready. Cfv is consumed in
PlatformPei to initialize the EmuVariableNvStore. To make the
implementation simple and clean, these 2 external input are measured
and extended to RTMRs in SEC phase. That is to say the tdx measurement
is only supported in SEC phase.

After the measurement the hash values are stored in WorkArea. Then after
the Hob service is available, these 2 measurement values are retrieved
and GuidHobs for these 2 tdx measurements are generated.

This patch defines the structure of TDX_MEASUREMENTS_DATA in
SEC_TDX_WORK_AREA to store above 2 tdx measurements. It can be extended
to store more tdx measurements if needed in the future.

Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Michael Roth <michael.roth@amd.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
---
 OvmfPkg/Include/WorkArea.h | 25 ++++++++++++++++++++++---
 1 file changed, 22 insertions(+), 3 deletions(-)

diff --git a/OvmfPkg/Include/WorkArea.h b/OvmfPkg/Include/WorkArea.h
index 6c3702b716f0..b1c7045ce18c 100644
--- a/OvmfPkg/Include/WorkArea.h
+++ b/OvmfPkg/Include/WorkArea.h
@@ -11,6 +11,7 @@
 #define __OVMF_WORK_AREA_H__
 
 #include <ConfidentialComputingGuestAttr.h>
+#include <IndustryStandard/Tpm20.h>
 
 //
 // Confidential computing work area header definition. Any change
@@ -64,13 +65,27 @@ typedef struct _SEV_WORK_AREA {
   SEC_SEV_ES_WORK_AREA                       SevEsWorkArea;
 } SEV_WORK_AREA;
 
+//
+// Start of TDX Specific WorkArea definition
+//
+
+#define TDX_MEASUREMENT_TDHOB_BITMASK   0x1
+#define TDX_MEASUREMENT_CFVIMG_BITMASK  0x2
+
+typedef struct _TDX_MEASUREMENTS_DATA {
+  UINT32    MeasurementsBitmap;
+  UINT8     TdHobHashValue[SHA384_DIGEST_SIZE];
+  UINT8     CfvImgHashValue[SHA384_DIGEST_SIZE];
+} TDX_MEASUREMENTS_DATA;
+
 //
 // The TDX work area definition
 //
 typedef struct _SEC_TDX_WORK_AREA {
-  UINT32    PageTableReady;
-  UINT32    Gpaw;
-  UINT64    HobList;
+  UINT32                   PageTableReady;
+  UINT32                   Gpaw;
+  UINT64                   HobList;
+  TDX_MEASUREMENTS_DATA    TdxMeasurementsData;
 } SEC_TDX_WORK_AREA;
 
 typedef struct _TDX_WORK_AREA {
@@ -78,6 +93,10 @@ typedef struct _TDX_WORK_AREA {
   SEC_TDX_WORK_AREA                          SecTdxWorkArea;
 } TDX_WORK_AREA;
 
+//
+// End of TDX Specific WorkArea definition
+//
+
 typedef union {
   CONFIDENTIAL_COMPUTING_WORK_AREA_HEADER    Header;
   SEV_WORK_AREA                              SevWorkArea;
-- 
2.29.2.windows.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH V6 02/12] OvmfPkg/IntelTdx: Add TdxHelperLibNull
  2023-02-03  3:31 [PATCH V6 00/12] Enable Tdx measurement in OvmfPkgX64 Min Xu
  2023-02-03  3:31 ` [PATCH V6 01/12] OvmfPkg: Add Tdx measurement data structure in WorkArea Min Xu
@ 2023-02-03  3:31 ` Min Xu
  2023-02-03  3:31 ` [PATCH V6 03/12] OvmfPkg/IntelTdx: Add SecTdxHelperLib Min Xu
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Min Xu @ 2023-02-03  3:31 UTC (permalink / raw)
  To: devel
  Cc: Min M Xu, Erdem Aktas, James Bottomley, Jiewen Yao, Gerd Hoffmann,
	Tom Lendacky, Michael Roth

From: Min M Xu <min.m.xu@intel.com>

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4243

TdxHelperLib provides below helper functions for a td-guest.
 - TdxHelperProcessTdHob
 - TdxHelperMeasureTdHob
 - TdxHelperMeasureCfvImage
 - TdxHelperBuildGuidHobForTdxMeasurement

TdxHelperLibNull is the NULL instance of TdxHelperLib.

Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Michael Roth <michael.roth@amd.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
---
 OvmfPkg/Include/Library/TdxHelperLib.h        | 70 ++++++++++++++++
 .../TdxHelperLib/TdxHelperLibNull.inf         | 32 ++++++++
 OvmfPkg/IntelTdx/TdxHelperLib/TdxHelperNull.c | 79 +++++++++++++++++++
 OvmfPkg/OvmfPkg.dec                           |  4 +
 4 files changed, 185 insertions(+)
 create mode 100644 OvmfPkg/Include/Library/TdxHelperLib.h
 create mode 100644 OvmfPkg/IntelTdx/TdxHelperLib/TdxHelperLibNull.inf
 create mode 100644 OvmfPkg/IntelTdx/TdxHelperLib/TdxHelperNull.c

diff --git a/OvmfPkg/Include/Library/TdxHelperLib.h b/OvmfPkg/Include/Library/TdxHelperLib.h
new file mode 100644
index 000000000000..199aade42f8e
--- /dev/null
+++ b/OvmfPkg/Include/Library/TdxHelperLib.h
@@ -0,0 +1,70 @@
+/** @file
+  TdxHelperLib header file
+
+  Copyright (c) 2021 - 2023, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef TDX_HELPER_LIB_H
+#define TDX_HELPER_LIB_H
+
+#include <PiPei.h>
+
+/**
+  In Tdx guest, some information need to be passed from host VMM to guest
+  firmware. For example, the memory resource, etc. These information are
+  prepared by host VMM and put in TdHob which is described in TdxMetadata.
+  TDVF processes the TdHob to accept memories.
+
+  @retval   EFI_SUCCESS   Successfully process the TdHob
+  @retval   Others        Other error as indicated
+**/
+EFI_STATUS
+EFIAPI
+TdxHelperProcessTdHob (
+  VOID
+  );
+
+/**
+  In Tdx guest, TdHob is passed from host VMM to guest firmware and it contains
+  the information of the memory resource. From the security perspective before
+  it is consumed, it should be measured and extended.
+ *
+ * @retval EFI_SUCCESS Successfully measure the TdHob
+ * @retval Others      Other error as indicated
+ */
+EFI_STATUS
+EFIAPI
+TdxHelperMeasureTdHob (
+  VOID
+  );
+
+/**
+ * In Tdx guest, Configuration FV (CFV) is treated as external input because it
+ * may contain the data provided by VMM. From the sucurity perspective Cfv image
+ * should be measured before it is consumed.
+ *
+ * @retval EFI_SUCCESS Successfully measure the CFV image
+ * @retval Others      Other error as indicated
+ */
+EFI_STATUS
+EFIAPI
+TdxHelperMeasureCfvImage (
+  VOID
+  );
+
+/**
+  Build the GuidHob for tdx measurements which were done in SEC phase.
+  The measurement values are stored in WorkArea.
+
+  @retval EFI_SUCCESS  The GuidHob is built successfully
+  @retval Others       Other errors as indicated
+**/
+EFI_STATUS
+EFIAPI
+TdxHelperBuildGuidHobForTdxMeasurement (
+  VOID
+  );
+
+#endif
diff --git a/OvmfPkg/IntelTdx/TdxHelperLib/TdxHelperLibNull.inf b/OvmfPkg/IntelTdx/TdxHelperLib/TdxHelperLibNull.inf
new file mode 100644
index 000000000000..27d07b3886cf
--- /dev/null
+++ b/OvmfPkg/IntelTdx/TdxHelperLib/TdxHelperLibNull.inf
@@ -0,0 +1,32 @@
+## @file
+#  TdxHelperLib NULL instance
+#
+#  Copyright (c) 2021 - 2023, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = TdxHelperLibNull
+  FILE_GUID                      = 853603b2-53ea-463d-93e6-35d09a79e358
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = TdxHelperLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = X64
+#
+
+[Sources]
+  TdxHelperNull.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+  BaseLib
diff --git a/OvmfPkg/IntelTdx/TdxHelperLib/TdxHelperNull.c b/OvmfPkg/IntelTdx/TdxHelperLib/TdxHelperNull.c
new file mode 100644
index 000000000000..a2125190d6aa
--- /dev/null
+++ b/OvmfPkg/IntelTdx/TdxHelperLib/TdxHelperNull.c
@@ -0,0 +1,79 @@
+/** @file
+  NULL instance of TdxHelperLib
+
+  Copyright (c) 2022 - 2023, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Base.h>
+#include <PiPei.h>
+
+/**
+  In Tdx guest, some information need to be passed from host VMM to guest
+  firmware. For example, the memory resource, etc. These information are
+  prepared by host VMM and put in TdHob which is described in TdxMetadata.
+  TDVF processes the TdHob to accept memories.
+
+  @retval   EFI_SUCCESS   Successfully process the TdHob
+  @retval   Others        Other error as indicated
+**/
+EFI_STATUS
+EFIAPI
+TdxHelperProcessTdHob (
+  VOID
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  In Tdx guest, TdHob is passed from host VMM to guest firmware and it contains
+  the information of the memory resource. From the security perspective before
+  it is consumed, it should be measured and extended.
+ *
+ * @retval EFI_SUCCESS Successfully measure the TdHob
+ * @retval Others      Other error as indicated
+ */
+EFI_STATUS
+EFIAPI
+TdxHelperMeasureTdHob (
+  VOID
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+ * In Tdx guest, Configuration FV (CFV) is treated as external input because it
+ * may contain the data provided by VMM. From the sucurity perspective Cfv image
+ * should be measured before it is consumed.
+ *
+ * @retval EFI_SUCCESS Successfully measure the CFV image
+ * @retval Others      Other error as indicated
+ */
+EFI_STATUS
+EFIAPI
+TdxHelperMeasureCfvImage (
+  VOID
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Build the GuidHob for tdx measurements which were done in SEC phase.
+  The measurement values are stored in WorkArea.
+
+  @retval EFI_SUCCESS  The GuidHob is built successfully
+  @retval Others       Other errors as indicated
+**/
+EFI_STATUS
+EFIAPI
+TdxHelperBuildGuidHobForTdxMeasurement (
+  VOID
+  )
+{
+  return EFI_UNSUPPORTED;
+}
diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index a22eb246c625..be30547474ae 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -98,6 +98,10 @@
   #
   SerializeVariablesLib|Include/Library/SerializeVariablesLib.h
 
+  ##  @libraryclass  TdxHelper
+  #
+  TdxHelperLib|Include/Library/TdxHelperLib.h
+
   ##  @libraryclass  Declares utility functions for virtio device drivers.
   VirtioLib|Include/Library/VirtioLib.h
 
-- 
2.29.2.windows.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH V6 03/12] OvmfPkg/IntelTdx: Add SecTdxHelperLib
  2023-02-03  3:31 [PATCH V6 00/12] Enable Tdx measurement in OvmfPkgX64 Min Xu
  2023-02-03  3:31 ` [PATCH V6 01/12] OvmfPkg: Add Tdx measurement data structure in WorkArea Min Xu
  2023-02-03  3:31 ` [PATCH V6 02/12] OvmfPkg/IntelTdx: Add TdxHelperLibNull Min Xu
@ 2023-02-03  3:31 ` Min Xu
  2023-02-03  3:31 ` [PATCH V6 04/12] OvmfPkg/PeilessStartupLib: Update the define of FV_HANDOFF_TABLE_POINTERS2 Min Xu
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Min Xu @ 2023-02-03  3:31 UTC (permalink / raw)
  To: devel
  Cc: Min M Xu, Erdem Aktas, James Bottomley, Jiewen Yao, Gerd Hoffmann,
	Tom Lendacky, Michael Roth

From: Min M Xu <min.m.xu@intel.com>

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4243

TdxHelperLib provides below helper functions for a td-guest.
 - TdxHelperProcessTdHob
 - TdxHelperMeasureTdHob
 - TdxHelperMeasureCfvImage
 - TdxHelperBuildGuidHobForTdxMeasurement

SecTdxHelperLib is the SEC instance of TdxHelperLib. It implements 4
functions for tdx in SEC phase:
 - TdxHelperProcessTdHob consumes TdHob to accept un-accepted memories.
   Before the TdHob is consumed, it is first validated.

 - TdxHelperMeasureTdHob measure/extend TdHob and store the measurement
   value in workarea.

 - TdxHelperMeasureCfvImage measure/extend the Configuration FV image and
   store the measurement value in workarea.

 - TdxHelperBuildGuidHobForTdxMeasurement builds GuidHob for tdx
   measurement.

This patch implements the stubs of the functions. The actual
implementations are in the following patches. Because they are moved from
other files.

Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Michael Roth <michael.roth@amd.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
---
 OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelper.c  | 78 +++++++++++++++++++
 .../IntelTdx/TdxHelperLib/SecTdxHelperLib.inf | 52 +++++++++++++
 2 files changed, 130 insertions(+)
 create mode 100644 OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelper.c
 create mode 100644 OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelperLib.inf

diff --git a/OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelper.c b/OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelper.c
new file mode 100644
index 000000000000..ef958b335940
--- /dev/null
+++ b/OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelper.c
@@ -0,0 +1,78 @@
+/** @file
+  TdxHelper Functions which are used in SEC phase
+
+  Copyright (c) 2022 - 2023, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+
+/**
+  In Tdx guest, some information need to be passed from host VMM to guest
+  firmware. For example, the memory resource, etc. These information are
+  prepared by host VMM and put in TdHob which is described in TdxMetadata.
+  TDVF processes the TdHob to accept memories.
+
+  @retval   EFI_SUCCESS   Successfully process the TdHob
+  @retval   Others        Other error as indicated
+**/
+EFI_STATUS
+EFIAPI
+TdxHelperProcessTdHob (
+  VOID
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  In Tdx guest, TdHob is passed from host VMM to guest firmware and it contains
+  the information of the memory resource. From the security perspective before
+  it is consumed, it should be measured and extended.
+ *
+ * @retval EFI_SUCCESS Successfully measure the TdHob
+ * @retval Others      Other error as indicated
+ */
+EFI_STATUS
+EFIAPI
+TdxHelperMeasureTdHob (
+  VOID
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+ * In Tdx guest, Configuration FV (CFV) is treated as external input because it
+ * may contain the data provided by VMM. From the sucurity perspective Cfv image
+ * should be measured before it is consumed.
+ *
+ * @retval EFI_SUCCESS Successfully measure the CFV image
+ * @retval Others      Other error as indicated
+ */
+EFI_STATUS
+EFIAPI
+TdxHelperMeasureCfvImage (
+  VOID
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Build the GuidHob for tdx measurements which were done in SEC phase.
+  The measurement values are stored in WorkArea.
+
+  @retval EFI_SUCCESS  The GuidHob is built successfully
+  @retval Others       Other errors as indicated
+**/
+EFI_STATUS
+EFIAPI
+TdxHelperBuildGuidHobForTdxMeasurement (
+  VOID
+  )
+{
+  return EFI_UNSUPPORTED;
+}
diff --git a/OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelperLib.inf b/OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelperLib.inf
new file mode 100644
index 000000000000..3c6b96f7759a
--- /dev/null
+++ b/OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelperLib.inf
@@ -0,0 +1,52 @@
+## @file
+#  TdxHelperLib SEC instance
+#
+#  This module provides Tdx helper functions in SEC phase.
+#  Copyright (c) 2021 - 2023, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SecTdxHelperLib
+  FILE_GUID                      = ba69ac6b-0c59-4472-899d-b684590ec1e9
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = TdxHelperLib|SEC
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = X64
+#
+
+[Sources]
+  SecTdxHelper.c
+
+[Packages]
+  CryptoPkg/CryptoPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  OvmfPkg/OvmfPkg.dec
+  SecurityPkg/SecurityPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseCryptLib
+  DebugLib
+  HobLib
+  PcdLib
+  TdxMailboxLib
+  TdxLib
+
+[FixedPcd]
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdTdxAcceptPageSize
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageVariableBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdCfvRawDataSize
+
+[Guids]
+  gCcEventEntryHobGuid
-- 
2.29.2.windows.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH V6 04/12] OvmfPkg/PeilessStartupLib: Update the define of FV_HANDOFF_TABLE_POINTERS2
  2023-02-03  3:31 [PATCH V6 00/12] Enable Tdx measurement in OvmfPkgX64 Min Xu
                   ` (2 preceding siblings ...)
  2023-02-03  3:31 ` [PATCH V6 03/12] OvmfPkg/IntelTdx: Add SecTdxHelperLib Min Xu
@ 2023-02-03  3:31 ` Min Xu
  2023-02-03  3:31 ` [PATCH V6 05/12] OvmfPkg: Refactor MeasureHobList Min Xu
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Min Xu @ 2023-02-03  3:31 UTC (permalink / raw)
  To: devel
  Cc: Min M Xu, Erdem Aktas, James Bottomley, Jiewen Yao, Gerd Hoffmann,
	Tom Lendacky, Michael Roth

From: Min M Xu <min.m.xu@intel.com>

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4243

FV_HANDOFF_TABLE_POINTERS2 once was defined in IntelTdx.c. Its structure
is same as PLATFORM_FIRMWARE_BLOB2_STRUCT which is defined in
Library/TcgEventLogRecordLib.h. So this patch reuse the define of
PLATFORM_FIRMWARE_BLOB2_STRUCT as FV_HANDOFF_TABLE_POINTERS2. Furthermore
FV_HANDOFF_TABLE_POINTERS2 is renamed as CFV_HANDOFF_TABLE_POINTERS2
so that the name is more meaningful.

Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Michael Roth <michael.roth@amd.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
---
 OvmfPkg/Library/PeilessStartupLib/IntelTdx.c | 18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)

diff --git a/OvmfPkg/Library/PeilessStartupLib/IntelTdx.c b/OvmfPkg/Library/PeilessStartupLib/IntelTdx.c
index 216c413caad5..4e8dca3d7712 100644
--- a/OvmfPkg/Library/PeilessStartupLib/IntelTdx.c
+++ b/OvmfPkg/Library/PeilessStartupLib/IntelTdx.c
@@ -11,6 +11,7 @@
 #include <IndustryStandard/UefiTcgPlatform.h>
 #include <Library/HobLib.h>
 #include <Library/PrintLib.h>
+#include <Library/TcgEventLogRecordLib.h>
 #include <Library/TpmMeasurementLib.h>
 
 #include "PeilessStartupInternal.h"
@@ -25,16 +26,11 @@ typedef struct {
   EFI_CONFIGURATION_TABLE    TableEntry[1];
 } TDX_HANDOFF_TABLE_POINTERS2;
 
-#define FV_HANDOFF_TABLE_DESC  "Fv(XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)"
-typedef struct {
-  UINT8                   BlobDescriptionSize;
-  UINT8                   BlobDescription[sizeof (FV_HANDOFF_TABLE_DESC)];
-  EFI_PHYSICAL_ADDRESS    BlobBase;
-  UINT64                  BlobLength;
-} FV_HANDOFF_TABLE_POINTERS2;
-
 #pragma pack()
 
+#define FV_HANDOFF_TABLE_DESC  "Fv(XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)"
+typedef PLATFORM_FIRMWARE_BLOB2_STRUCT CFV_HANDOFF_TABLE_POINTERS2;
+
 /**
   Measure the Hoblist passed from the VMM.
 
@@ -161,9 +157,9 @@ MeasureFvImage (
   IN UINT8                 PcrIndex
   )
 {
-  EFI_STATUS                  Status;
-  FV_HANDOFF_TABLE_POINTERS2  FvBlob2;
-  VOID                        *FvName;
+  EFI_STATUS                   Status;
+  CFV_HANDOFF_TABLE_POINTERS2  FvBlob2;
+  VOID                         *FvName;
 
   //
   // Init the log event for FV measurement
-- 
2.29.2.windows.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH V6 05/12] OvmfPkg: Refactor MeasureHobList
  2023-02-03  3:31 [PATCH V6 00/12] Enable Tdx measurement in OvmfPkgX64 Min Xu
                   ` (3 preceding siblings ...)
  2023-02-03  3:31 ` [PATCH V6 04/12] OvmfPkg/PeilessStartupLib: Update the define of FV_HANDOFF_TABLE_POINTERS2 Min Xu
@ 2023-02-03  3:31 ` Min Xu
  2023-02-03  3:31 ` [PATCH V6 06/12] OvmfPkg: Refactor MeaureFvImage Min Xu
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Min Xu @ 2023-02-03  3:31 UTC (permalink / raw)
  To: devel
  Cc: Min M Xu, Erdem Aktas, James Bottomley, Jiewen Yao, Gerd Hoffmann,
	Tom Lendacky, Michael Roth

From: Min M Xu <min.m.xu@intel.com>

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4243

MeasureHobList once was implemented in PeilessStartupLib and it does
measurement and logging for TdHob in one go, using TpmMeasureAndLogData().
But it doesn't work in SEC.

This patch splits MeasureHobList into 2 functions and implement them in
SecTdxHelperLib.
 - TdxHelperMeasureTdHob
 - TdxHelperBuildGuidHobForTdxMeasurement

TdxHelperMeasureTdHob measures the TdHob and stores the hash value in
WorkArea. TdxHelperBuildGuidHobForTdxMeasurement builds GuidHob for the
measurement based on the hash value in WorkArea.

After these 2 functions are introduced, PeilessStartupLib should also be
updated:
 - Call these 2 functions instead of the MeasureHobList
 - Delete the duplicated codes in PeilessStartupLib

Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Michael Roth <michael.roth@amd.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
---
 OvmfPkg/IntelTdx/IntelTdxX64.dsc              |   1 +
 OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelper.c  | 123 ++++++++++++-
 .../IntelTdx/TdxHelperLib/SecTdxHelperLib.inf |   1 +
 .../IntelTdx/TdxHelperLib/TdxMeasurementHob.c | 173 ++++++++++++++++++
 OvmfPkg/Library/PeilessStartupLib/IntelTdx.c  |  71 -------
 .../PeilessStartupLib/PeilessStartup.c        |  12 +-
 .../PeilessStartupInternal.h                  |  15 --
 7 files changed, 308 insertions(+), 88 deletions(-)
 create mode 100644 OvmfPkg/IntelTdx/TdxHelperLib/TdxMeasurementHob.c

diff --git a/OvmfPkg/IntelTdx/IntelTdxX64.dsc b/OvmfPkg/IntelTdx/IntelTdxX64.dsc
index 0f1e970fbbb3..920f1c6080d4 100644
--- a/OvmfPkg/IntelTdx/IntelTdxX64.dsc
+++ b/OvmfPkg/IntelTdx/IntelTdxX64.dsc
@@ -549,6 +549,7 @@
     <LibraryClasses>
       NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
       TpmMeasurementLib|SecurityPkg/Library/SecTpmMeasurementLib/SecTpmMeasurementLibTdx.inf
+      NULL|OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelperLib.inf
       BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SecCryptLib.inf
       HashLib|SecurityPkg/Library/HashLibTdx/HashLibTdx.inf
       NULL|SecurityPkg/Library/HashInstanceLibSha384/HashInstanceLibSha384.inf
diff --git a/OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelper.c b/OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelper.c
index ef958b335940..6ca6f01aff57 100644
--- a/OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelper.c
+++ b/OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelper.c
@@ -8,6 +8,31 @@
 **/
 
 #include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/BaseCryptLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <IndustryStandard/Tdx.h>
+#include <IndustryStandard/IntelTdx.h>
+#include <IndustryStandard/Tpm20.h>
+#include <Library/TdxLib.h>
+#include <Pi/PrePiHob.h>
+#include <WorkArea.h>
+#include <ConfidentialComputingGuestAttr.h>
+#include <Library/TdxHelperLib.h>
+
+/**
+  Build the GuidHob for tdx measurements which were done in SEC phase.
+  The measurement values are stored in WorkArea.
+
+  @retval EFI_SUCCESS  The GuidHob is built successfully
+  @retval Others       Other errors as indicated
+**/
+EFI_STATUS
+InternalBuildGuidHobForTdxMeasurement (
+  VOID
+  );
 
 /**
   In Tdx guest, some information need to be passed from host VMM to guest
@@ -27,6 +52,58 @@ TdxHelperProcessTdHob (
   return EFI_UNSUPPORTED;
 }
 
+/**
+ * Calculate the sha384 of input Data and extend it to RTMR register.
+ *
+ * @param RtmrIndex       Index of the RTMR register
+ * @param DataToHash      Data to be hashed
+ * @param DataToHashLen   Length of the data
+ * @param Digest          Hash value of the input data
+ * @param DigestLen       Length of the hash value
+ *
+ * @retval EFI_SUCCESS    Successfully hash and extend to RTMR
+ * @retval Others         Other errors as indicated
+ */
+STATIC
+EFI_STATUS
+HashAndExtendToRtmr (
+  IN UINT32  RtmrIndex,
+  IN VOID    *DataToHash,
+  IN UINTN   DataToHashLen,
+  OUT UINT8  *Digest,
+  IN  UINTN  DigestLen
+  )
+{
+  EFI_STATUS  Status;
+
+  if ((DataToHash == NULL) || (DataToHashLen == 0)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((Digest == NULL) || (DigestLen != SHA384_DIGEST_SIZE)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Calculate the sha384 of the data
+  //
+  if (!Sha384HashAll (DataToHash, DataToHashLen, Digest)) {
+    return EFI_ABORTED;
+  }
+
+  //
+  // Extend to RTMR
+  //
+  Status = TdExtendRtmr (
+             (UINT32 *)Digest,
+             SHA384_DIGEST_SIZE,
+             (UINT8)RtmrIndex
+             );
+
+  ASSERT (!EFI_ERROR (Status));
+  return Status;
+}
+
 /**
   In Tdx guest, TdHob is passed from host VMM to guest firmware and it contains
   the information of the memory resource. From the security perspective before
@@ -41,7 +118,47 @@ TdxHelperMeasureTdHob (
   VOID
   )
 {
-  return EFI_UNSUPPORTED;
+  EFI_PEI_HOB_POINTERS  Hob;
+  EFI_STATUS            Status;
+  UINT8                 Digest[SHA384_DIGEST_SIZE];
+  OVMF_WORK_AREA        *WorkArea;
+  VOID                  *TdHob;
+
+  TdHob   = (VOID *)(UINTN)FixedPcdGet32 (PcdOvmfSecGhcbBase);
+  Hob.Raw = (UINT8 *)TdHob;
+
+  //
+  // Walk thru the TdHob list until end of list.
+  //
+  while (!END_OF_HOB_LIST (Hob)) {
+    Hob.Raw = GET_NEXT_HOB (Hob);
+  }
+
+  Status = HashAndExtendToRtmr (
+             0,
+             (UINT8 *)TdHob,
+             (UINTN)((UINT8 *)Hob.Raw - (UINT8 *)TdHob),
+             Digest,
+             SHA384_DIGEST_SIZE
+             );
+
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // This function is called in SEC phase and at that moment the Hob service
+  // is not available. So the TdHob measurement value is stored in workarea.
+  //
+  WorkArea = (OVMF_WORK_AREA *)FixedPcdGet32 (PcdOvmfWorkAreaBase);
+  if (WorkArea == NULL) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  WorkArea->TdxWorkArea.SecTdxWorkArea.TdxMeasurementsData.MeasurementsBitmap |= TDX_MEASUREMENT_TDHOB_BITMASK;
+  CopyMem (WorkArea->TdxWorkArea.SecTdxWorkArea.TdxMeasurementsData.TdHobHashValue, Digest, SHA384_DIGEST_SIZE);
+
+  return EFI_SUCCESS;
 }
 
 /**
@@ -74,5 +191,9 @@ TdxHelperBuildGuidHobForTdxMeasurement (
   VOID
   )
 {
+ #ifdef TDX_PEI_LESS_BOOT
+  return InternalBuildGuidHobForTdxMeasurement ();
+ #else
   return EFI_UNSUPPORTED;
+ #endif
 }
diff --git a/OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelperLib.inf b/OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelperLib.inf
index 3c6b96f7759a..d17b84c01f20 100644
--- a/OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelperLib.inf
+++ b/OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelperLib.inf
@@ -24,6 +24,7 @@
 
 [Sources]
   SecTdxHelper.c
+  TdxMeasurementHob.c
 
 [Packages]
   CryptoPkg/CryptoPkg.dec
diff --git a/OvmfPkg/IntelTdx/TdxHelperLib/TdxMeasurementHob.c b/OvmfPkg/IntelTdx/TdxHelperLib/TdxMeasurementHob.c
new file mode 100644
index 000000000000..6cbc7600adb6
--- /dev/null
+++ b/OvmfPkg/IntelTdx/TdxHelperLib/TdxMeasurementHob.c
@@ -0,0 +1,173 @@
+/** @file
+  Build GuidHob for tdx measurement.
+
+  Copyright (c) 2022 - 2023, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <IndustryStandard/Tpm20.h>
+#include <IndustryStandard/UefiTcgPlatform.h>
+#include <Library/HobLib.h>
+#include <Library/PrintLib.h>
+#include <WorkArea.h>
+
+#pragma pack(1)
+
+#define HANDOFF_TABLE_DESC  "TdxTable"
+typedef struct {
+  UINT8                      TableDescriptionSize;
+  UINT8                      TableDescription[sizeof (HANDOFF_TABLE_DESC)];
+  UINT64                     NumberOfTables;
+  EFI_CONFIGURATION_TABLE    TableEntry[1];
+} TDX_HANDOFF_TABLE_POINTERS2;
+
+#pragma pack()
+
+/**
+ * Build GuidHob for Tdx measurement.
+ *
+ * Tdx measurement includes the measurement of TdHob and CFV. They're measured
+ * and extended to RTMR registers in SEC phase. Because at that moment the Hob
+ * service are not available. So the values of the measurement are saved in
+ * workarea and will be built into GuidHob after the Hob service is ready.
+ *
+ * @param RtmrIndex     RTMR index
+ * @param EventType     Event type
+ * @param EventData     Event data
+ * @param EventSize     Size of event data
+ * @param HashValue     Hash value
+ * @param HashSize      Size of hash
+ *
+ * @retval EFI_SUCCESS  Successfully build the GuidHobs
+ * @retval Others       Other error as indicated
+ */
+STATIC
+EFI_STATUS
+BuildTdxMeasurementGuidHob (
+  UINT32  RtmrIndex,
+  UINT32  EventType,
+  UINT8   *EventData,
+  UINT32  EventSize,
+  UINT8   *HashValue,
+  UINT32  HashSize
+  )
+{
+  VOID                *EventHobData;
+  UINT8               *Ptr;
+  TPML_DIGEST_VALUES  *TdxDigest;
+
+  if (HashSize != SHA384_DIGEST_SIZE) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  #define TDX_DIGEST_VALUE_LEN  (sizeof (UINT32) + sizeof (TPMI_ALG_HASH) + SHA384_DIGEST_SIZE)
+
+  EventHobData = BuildGuidHob (
+                   &gCcEventEntryHobGuid,
+                   sizeof (TCG_PCRINDEX) + sizeof (TCG_EVENTTYPE) +
+                   TDX_DIGEST_VALUE_LEN +
+                   sizeof (UINT32) + EventSize
+                   );
+
+  if (EventHobData == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Ptr = (UINT8 *)EventHobData;
+
+  //
+  // There are 2 types of measurement registers in TDX: MRTD and RTMR[0-3].
+  // According to UEFI Spec 2.10 Section 38.4.1, RTMR[0-3] is mapped to MrIndex[1-4].
+  // So RtmrIndex must be increased by 1 before the event log is created.
+  //
+  RtmrIndex++;
+  CopyMem (Ptr, &RtmrIndex, sizeof (UINT32));
+  Ptr += sizeof (UINT32);
+
+  CopyMem (Ptr, &EventType, sizeof (TCG_EVENTTYPE));
+  Ptr += sizeof (TCG_EVENTTYPE);
+
+  TdxDigest                     = (TPML_DIGEST_VALUES *)Ptr;
+  TdxDigest->count              = 1;
+  TdxDigest->digests[0].hashAlg = TPM_ALG_SHA384;
+  CopyMem (
+    TdxDigest->digests[0].digest.sha384,
+    HashValue,
+    SHA384_DIGEST_SIZE
+    );
+  Ptr += TDX_DIGEST_VALUE_LEN;
+
+  CopyMem (Ptr, &EventSize, sizeof (UINT32));
+  Ptr += sizeof (UINT32);
+
+  CopyMem (Ptr, (VOID *)EventData, EventSize);
+  Ptr += EventSize;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Build the GuidHob for tdx measurements which were done in SEC phase.
+  The measurement values are stored in WorkArea.
+
+  @retval EFI_SUCCESS  The GuidHob is built successfully
+  @retval Others       Other errors as indicated
+**/
+EFI_STATUS
+InternalBuildGuidHobForTdxMeasurement (
+  VOID
+  )
+{
+  EFI_STATUS                   Status;
+  OVMF_WORK_AREA               *WorkArea;
+  VOID                         *TdHobList;
+  TDX_HANDOFF_TABLE_POINTERS2  HandoffTables;
+  UINT8                        *HashValue;
+
+  if (!TdIsEnabled ()) {
+    ASSERT (FALSE);
+    return EFI_UNSUPPORTED;
+  }
+
+  WorkArea = (OVMF_WORK_AREA *)FixedPcdGet32 (PcdOvmfWorkAreaBase);
+  if (WorkArea == NULL) {
+    return EFI_ABORTED;
+  }
+
+  Status = EFI_SUCCESS;
+
+  //
+  // Build the GuidHob for TdHob measurement
+  //
+  TdHobList = (VOID *)(UINTN)FixedPcdGet32 (PcdOvmfSecGhcbBase);
+  if (WorkArea->TdxWorkArea.SecTdxWorkArea.TdxMeasurementsData.MeasurementsBitmap & TDX_MEASUREMENT_TDHOB_BITMASK) {
+    HashValue                          = WorkArea->TdxWorkArea.SecTdxWorkArea.TdxMeasurementsData.TdHobHashValue;
+    HandoffTables.TableDescriptionSize = sizeof (HandoffTables.TableDescription);
+    CopyMem (HandoffTables.TableDescription, HANDOFF_TABLE_DESC, sizeof (HandoffTables.TableDescription));
+    HandoffTables.NumberOfTables = 1;
+    CopyGuid (&(HandoffTables.TableEntry[0].VendorGuid), &gUefiOvmfPkgTokenSpaceGuid);
+    HandoffTables.TableEntry[0].VendorTable = TdHobList;
+
+    Status = BuildTdxMeasurementGuidHob (
+               0,                               // RtmrIndex
+               EV_EFI_HANDOFF_TABLES2,          // EventType
+               (UINT8 *)(UINTN)&HandoffTables,  // EventData
+               sizeof (HandoffTables),          // EventSize
+               HashValue,                       // HashValue
+               SHA384_DIGEST_SIZE               // HashSize
+               );
+  }
+
+  if (EFI_ERROR (Status)) {
+    ASSERT (FALSE);
+    return Status;
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/OvmfPkg/Library/PeilessStartupLib/IntelTdx.c b/OvmfPkg/Library/PeilessStartupLib/IntelTdx.c
index 4e8dca3d7712..ae0ffcc95da5 100644
--- a/OvmfPkg/Library/PeilessStartupLib/IntelTdx.c
+++ b/OvmfPkg/Library/PeilessStartupLib/IntelTdx.c
@@ -16,80 +16,9 @@
 
 #include "PeilessStartupInternal.h"
 
-#pragma pack(1)
-
-#define HANDOFF_TABLE_DESC  "TdxTable"
-typedef struct {
-  UINT8                      TableDescriptionSize;
-  UINT8                      TableDescription[sizeof (HANDOFF_TABLE_DESC)];
-  UINT64                     NumberOfTables;
-  EFI_CONFIGURATION_TABLE    TableEntry[1];
-} TDX_HANDOFF_TABLE_POINTERS2;
-
-#pragma pack()
-
 #define FV_HANDOFF_TABLE_DESC  "Fv(XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)"
 typedef PLATFORM_FIRMWARE_BLOB2_STRUCT CFV_HANDOFF_TABLE_POINTERS2;
 
-/**
-  Measure the Hoblist passed from the VMM.
-
-  @param[in] VmmHobList    The Hoblist pass the firmware
-
-  @retval EFI_SUCCESS           Fv image is measured successfully
-                                or it has been already measured.
-  @retval Others                Other errors as indicated
-**/
-EFI_STATUS
-EFIAPI
-MeasureHobList (
-  IN CONST VOID  *VmmHobList
-  )
-{
-  EFI_PEI_HOB_POINTERS         Hob;
-  TDX_HANDOFF_TABLE_POINTERS2  HandoffTables;
-  EFI_STATUS                   Status;
-
-  if (!TdIsEnabled ()) {
-    ASSERT (FALSE);
-    return EFI_UNSUPPORTED;
-  }
-
-  Hob.Raw = (UINT8 *)VmmHobList;
-
-  //
-  // Parse the HOB list until end of list.
-  //
-  while (!END_OF_HOB_LIST (Hob)) {
-    Hob.Raw = GET_NEXT_HOB (Hob);
-  }
-
-  //
-  // Init the log event for HOB measurement
-  //
-
-  HandoffTables.TableDescriptionSize = sizeof (HandoffTables.TableDescription);
-  CopyMem (HandoffTables.TableDescription, HANDOFF_TABLE_DESC, sizeof (HandoffTables.TableDescription));
-  HandoffTables.NumberOfTables = 1;
-  CopyGuid (&(HandoffTables.TableEntry[0].VendorGuid), &gUefiOvmfPkgTokenSpaceGuid);
-  HandoffTables.TableEntry[0].VendorTable = (VOID *)VmmHobList;
-
-  Status = TpmMeasureAndLogData (
-             1,                                              // PCRIndex
-             EV_EFI_HANDOFF_TABLES2,                         // EventType
-             (VOID *)&HandoffTables,                         // EventData
-             sizeof (HandoffTables),                         // EventSize
-             (UINT8 *)(UINTN)VmmHobList,                     // HashData
-             (UINTN)((UINT8 *)Hob.Raw - (UINT8 *)VmmHobList) // HashDataLen
-             );
-
-  if (EFI_ERROR (Status)) {
-    ASSERT (FALSE);
-  }
-
-  return Status;
-}
-
 /**
   Get the FvName from the FV header.
 
diff --git a/OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c b/OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c
index 928120d183ba..4efbc14d5921 100644
--- a/OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c
+++ b/OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c
@@ -17,6 +17,7 @@
 #include <Library/PrePiLib.h>
 #include <Library/PeilessStartupLib.h>
 #include <Library/PlatformInitLib.h>
+#include <Library/TdxHelperLib.h>
 #include <ConfidentialComputingGuestAttr.h>
 #include <Guid/MemoryTypeInformation.h>
 #include <OvmfPlatforms.h>
@@ -179,7 +180,16 @@ PeilessStartup (
     //
     // Measure HobList
     //
-    Status = MeasureHobList (VmmHobList);
+    Status = TdxHelperMeasureTdHob ();
+    if (EFI_ERROR (Status)) {
+      ASSERT (FALSE);
+      CpuDeadLoop ();
+    }
+
+    //
+    // Build GuidHob for tdx measurement
+    //
+    Status = TdxHelperBuildGuidHobForTdxMeasurement ();
     if (EFI_ERROR (Status)) {
       ASSERT (FALSE);
       CpuDeadLoop ();
diff --git a/OvmfPkg/Library/PeilessStartupLib/PeilessStartupInternal.h b/OvmfPkg/Library/PeilessStartupLib/PeilessStartupInternal.h
index f56bc3578e5e..a2d2c1c9145b 100644
--- a/OvmfPkg/Library/PeilessStartupLib/PeilessStartupInternal.h
+++ b/OvmfPkg/Library/PeilessStartupLib/PeilessStartupInternal.h
@@ -58,21 +58,6 @@ EFIAPI
 ConstructSecHobList (
   );
 
-/**
-  Measure the Hoblist passed from the VMM.
-
-  @param[in] VmmHobList    The Hoblist pass the firmware
-
-  @retval EFI_SUCCESS           Fv image is measured successfully
-                                or it has been already measured.
-  @retval Others                Other errors as indicated
-**/
-EFI_STATUS
-EFIAPI
-MeasureHobList (
-  IN CONST VOID  *VmmHobList
-  );
-
 /**
   Measure FV image.
 
-- 
2.29.2.windows.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH V6 06/12] OvmfPkg: Refactor MeaureFvImage
  2023-02-03  3:31 [PATCH V6 00/12] Enable Tdx measurement in OvmfPkgX64 Min Xu
                   ` (4 preceding siblings ...)
  2023-02-03  3:31 ` [PATCH V6 05/12] OvmfPkg: Refactor MeasureHobList Min Xu
@ 2023-02-03  3:31 ` Min Xu
  2023-02-03  3:31 ` [PATCH V6 07/12] OvmfPkg: Refactor ProcessHobList Min Xu
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Min Xu @ 2023-02-03  3:31 UTC (permalink / raw)
  To: devel
  Cc: Min M Xu, Erdem Aktas, James Bottomley, Jiewen Yao, Gerd Hoffmann,
	Tom Lendacky, Michael Roth

From: Min M Xu <min.m.xu@intel.com>

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4243

MeasureFvImage once was implemented in PeilessStartupLib and it does
measurement and logging for Configuration FV (Cfv) image in one go,
using TpmMeasureAndLogData(). But it doesn't work in SEC.

This patch splits MeasureFvImage into 2 functions and implement them in
SecTdxHelperLib.
 - TdxHelperMeasureCfvImage
 - TdxHelperBuildGuidHobForTdxMeasurement

TdxHelperMeasureCfvImage measures the Cfv image and stores the hash value
in WorkArea. TdxHelperBuildGuidHobForTdxMeasurement builds GuidHob for the
measurement based on the hash value in WorkArea.

After these 2 functions are introduced, PeilessStartupLib should also be
updated:
 - Call these 2 functions instead of the MeasureFvImage
 - Delete the duplicated codes in PeilessStartupLib

Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Michael Roth <michael.roth@amd.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
---
 OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelper.c  |  30 ++++-
 .../IntelTdx/TdxHelperLib/TdxMeasurementHob.c |  86 +++++++++++++
 OvmfPkg/Library/PeilessStartupLib/IntelTdx.c  | 121 ------------------
 .../PeilessStartupLib/PeilessStartup.c        |  20 ++-
 .../PeilessStartupInternal.h                  |  21 ---
 .../PeilessStartupLib/PeilessStartupLib.inf   |   4 -
 6 files changed, 124 insertions(+), 158 deletions(-)
 delete mode 100644 OvmfPkg/Library/PeilessStartupLib/IntelTdx.c

diff --git a/OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelper.c b/OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelper.c
index 6ca6f01aff57..1929093f9110 100644
--- a/OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelper.c
+++ b/OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelper.c
@@ -175,7 +175,35 @@ TdxHelperMeasureCfvImage (
   VOID
   )
 {
-  return EFI_UNSUPPORTED;
+  EFI_STATUS      Status;
+  UINT8           Digest[SHA384_DIGEST_SIZE];
+  OVMF_WORK_AREA  *WorkArea;
+
+  Status = HashAndExtendToRtmr (
+             0,
+             (UINT8 *)(UINTN)PcdGet32 (PcdOvmfFlashNvStorageVariableBase),
+             (UINT64)PcdGet32 (PcdCfvRawDataSize),
+             Digest,
+             SHA384_DIGEST_SIZE
+             );
+
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // This function is called in SEC phase and at that moment the Hob service
+  // is not available. So CfvImage measurement value is stored in workarea.
+  //
+  WorkArea = (OVMF_WORK_AREA *)FixedPcdGet32 (PcdOvmfWorkAreaBase);
+  if (WorkArea == NULL) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  WorkArea->TdxWorkArea.SecTdxWorkArea.TdxMeasurementsData.MeasurementsBitmap |= TDX_MEASUREMENT_CFVIMG_BITMASK;
+  CopyMem (WorkArea->TdxWorkArea.SecTdxWorkArea.TdxMeasurementsData.CfvImgHashValue, Digest, SHA384_DIGEST_SIZE);
+
+  return EFI_SUCCESS;
 }
 
 /**
diff --git a/OvmfPkg/IntelTdx/TdxHelperLib/TdxMeasurementHob.c b/OvmfPkg/IntelTdx/TdxHelperLib/TdxMeasurementHob.c
index 6cbc7600adb6..a4c7095cffab 100644
--- a/OvmfPkg/IntelTdx/TdxHelperLib/TdxMeasurementHob.c
+++ b/OvmfPkg/IntelTdx/TdxHelperLib/TdxMeasurementHob.c
@@ -15,6 +15,7 @@
 #include <IndustryStandard/UefiTcgPlatform.h>
 #include <Library/HobLib.h>
 #include <Library/PrintLib.h>
+#include <Library/TcgEventLogRecordLib.h>
 #include <WorkArea.h>
 
 #pragma pack(1)
@@ -29,6 +30,9 @@ typedef struct {
 
 #pragma pack()
 
+#define FV_HANDOFF_TABLE_DESC  "Fv(XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)"
+typedef PLATFORM_FIRMWARE_BLOB2_STRUCT CFV_HANDOFF_TABLE_POINTERS2;
+
 /**
  * Build GuidHob for Tdx measurement.
  *
@@ -112,6 +116,52 @@ BuildTdxMeasurementGuidHob (
   return EFI_SUCCESS;
 }
 
+/**
+  Get the FvName from the FV header.
+
+  Causion: The FV is untrusted input.
+
+  @param[in]  FvBase            Base address of FV image.
+  @param[in]  FvLength          Length of FV image.
+
+  @return FvName pointer
+  @retval NULL   FvName is NOT found
+**/
+VOID *
+GetFvName (
+  IN EFI_PHYSICAL_ADDRESS  FvBase,
+  IN UINT64                FvLength
+  )
+{
+  EFI_FIRMWARE_VOLUME_HEADER      *FvHeader;
+  EFI_FIRMWARE_VOLUME_EXT_HEADER  *FvExtHeader;
+
+  if (FvBase >= MAX_ADDRESS) {
+    return NULL;
+  }
+
+  if (FvLength >= MAX_ADDRESS - FvBase) {
+    return NULL;
+  }
+
+  if (FvLength < sizeof (EFI_FIRMWARE_VOLUME_HEADER)) {
+    return NULL;
+  }
+
+  FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FvBase;
+  if (FvHeader->ExtHeaderOffset < sizeof (EFI_FIRMWARE_VOLUME_HEADER)) {
+    return NULL;
+  }
+
+  if (FvHeader->ExtHeaderOffset + sizeof (EFI_FIRMWARE_VOLUME_EXT_HEADER) > FvLength) {
+    return NULL;
+  }
+
+  FvExtHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER *)(UINTN)(FvBase + FvHeader->ExtHeaderOffset);
+
+  return &FvExtHeader->FvName;
+}
+
 /**
   Build the GuidHob for tdx measurements which were done in SEC phase.
   The measurement values are stored in WorkArea.
@@ -128,6 +178,10 @@ InternalBuildGuidHobForTdxMeasurement (
   OVMF_WORK_AREA               *WorkArea;
   VOID                         *TdHobList;
   TDX_HANDOFF_TABLE_POINTERS2  HandoffTables;
+  VOID                         *FvName;
+  CFV_HANDOFF_TABLE_POINTERS2  FvBlob2;
+  EFI_PHYSICAL_ADDRESS         FvBase;
+  UINT64                       FvLength;
   UINT8                        *HashValue;
 
   if (!TdIsEnabled ()) {
@@ -169,5 +223,37 @@ InternalBuildGuidHobForTdxMeasurement (
     return Status;
   }
 
+  //
+  // Build the GuidHob for Cfv measurement
+  //
+  if (WorkArea->TdxWorkArea.SecTdxWorkArea.TdxMeasurementsData.MeasurementsBitmap & TDX_MEASUREMENT_CFVIMG_BITMASK) {
+    HashValue                   = WorkArea->TdxWorkArea.SecTdxWorkArea.TdxMeasurementsData.CfvImgHashValue;
+    FvBase                      = (UINT64)PcdGet32 (PcdOvmfFlashNvStorageVariableBase);
+    FvLength                    = (UINT64)PcdGet32 (PcdCfvRawDataSize);
+    FvBlob2.BlobDescriptionSize = sizeof (FvBlob2.BlobDescription);
+    CopyMem (FvBlob2.BlobDescription, FV_HANDOFF_TABLE_DESC, sizeof (FvBlob2.BlobDescription));
+    FvName = GetFvName (FvBase, FvLength);
+    if (FvName != NULL) {
+      AsciiSPrint ((CHAR8 *)FvBlob2.BlobDescription, sizeof (FvBlob2.BlobDescription), "Fv(%g)", FvName);
+    }
+
+    FvBlob2.BlobBase   = FvBase;
+    FvBlob2.BlobLength = FvLength;
+
+    Status = BuildTdxMeasurementGuidHob (
+               0,                              // RtmrIndex
+               EV_EFI_PLATFORM_FIRMWARE_BLOB2, // EventType
+               (VOID *)&FvBlob2,               // EventData
+               sizeof (FvBlob2),               // EventSize
+               HashValue,                      // HashValue
+               SHA384_DIGEST_SIZE              // HashSize
+               );
+  }
+
+  if (EFI_ERROR (Status)) {
+    ASSERT (FALSE);
+    return Status;
+  }
+
   return EFI_SUCCESS;
 }
diff --git a/OvmfPkg/Library/PeilessStartupLib/IntelTdx.c b/OvmfPkg/Library/PeilessStartupLib/IntelTdx.c
deleted file mode 100644
index ae0ffcc95da5..000000000000
--- a/OvmfPkg/Library/PeilessStartupLib/IntelTdx.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/** @file
-  Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
-  SPDX-License-Identifier: BSD-2-Clause-Patent
-**/
-
-#include <PiPei.h>
-#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/DebugLib.h>
-#include <IndustryStandard/Tpm20.h>
-#include <IndustryStandard/UefiTcgPlatform.h>
-#include <Library/HobLib.h>
-#include <Library/PrintLib.h>
-#include <Library/TcgEventLogRecordLib.h>
-#include <Library/TpmMeasurementLib.h>
-
-#include "PeilessStartupInternal.h"
-
-#define FV_HANDOFF_TABLE_DESC  "Fv(XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)"
-typedef PLATFORM_FIRMWARE_BLOB2_STRUCT CFV_HANDOFF_TABLE_POINTERS2;
-
-/**
-  Get the FvName from the FV header.
-
-  Causion: The FV is untrusted input.
-
-  @param[in]  FvBase            Base address of FV image.
-  @param[in]  FvLength          Length of FV image.
-
-  @return FvName pointer
-  @retval NULL   FvName is NOT found
-**/
-VOID *
-GetFvName (
-  IN EFI_PHYSICAL_ADDRESS  FvBase,
-  IN UINT64                FvLength
-  )
-{
-  EFI_FIRMWARE_VOLUME_HEADER      *FvHeader;
-  EFI_FIRMWARE_VOLUME_EXT_HEADER  *FvExtHeader;
-
-  if (FvBase >= MAX_ADDRESS) {
-    return NULL;
-  }
-
-  if (FvLength >= MAX_ADDRESS - FvBase) {
-    return NULL;
-  }
-
-  if (FvLength < sizeof (EFI_FIRMWARE_VOLUME_HEADER)) {
-    return NULL;
-  }
-
-  FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FvBase;
-  if (FvHeader->ExtHeaderOffset < sizeof (EFI_FIRMWARE_VOLUME_HEADER)) {
-    return NULL;
-  }
-
-  if (FvHeader->ExtHeaderOffset + sizeof (EFI_FIRMWARE_VOLUME_EXT_HEADER) > FvLength) {
-    return NULL;
-  }
-
-  FvExtHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER *)(UINTN)(FvBase + FvHeader->ExtHeaderOffset);
-
-  return &FvExtHeader->FvName;
-}
-
-/**
-  Measure FV image.
-
-  @param[in]  FvBase            Base address of FV image.
-  @param[in]  FvLength          Length of FV image.
-  @param[in]  PcrIndex          Index of PCR
-
-  @retval EFI_SUCCESS           Fv image is measured successfully
-                                or it has been already measured.
-  @retval EFI_OUT_OF_RESOURCES  No enough memory to log the new event.
-  @retval EFI_DEVICE_ERROR      The command was unsuccessful.
-
-**/
-EFI_STATUS
-EFIAPI
-MeasureFvImage (
-  IN EFI_PHYSICAL_ADDRESS  FvBase,
-  IN UINT64                FvLength,
-  IN UINT8                 PcrIndex
-  )
-{
-  EFI_STATUS                   Status;
-  CFV_HANDOFF_TABLE_POINTERS2  FvBlob2;
-  VOID                         *FvName;
-
-  //
-  // Init the log event for FV measurement
-  //
-  FvBlob2.BlobDescriptionSize = sizeof (FvBlob2.BlobDescription);
-  CopyMem (FvBlob2.BlobDescription, FV_HANDOFF_TABLE_DESC, sizeof (FvBlob2.BlobDescription));
-  FvName = GetFvName (FvBase, FvLength);
-  if (FvName != NULL) {
-    AsciiSPrint ((CHAR8 *)FvBlob2.BlobDescription, sizeof (FvBlob2.BlobDescription), "Fv(%g)", FvName);
-  }
-
-  FvBlob2.BlobBase   = FvBase;
-  FvBlob2.BlobLength = FvLength;
-
-  Status = TpmMeasureAndLogData (
-             1,                              // PCRIndex
-             EV_EFI_PLATFORM_FIRMWARE_BLOB2, // EventType
-             (VOID *)&FvBlob2,               // EventData
-             sizeof (FvBlob2),               // EventSize
-             (UINT8 *)(UINTN)FvBase,         // HashData
-             (UINTN)(FvLength)               // HashDataLen
-             );
-
-  if (EFI_ERROR (Status)) {
-    DEBUG ((DEBUG_ERROR, "The FV which failed to be measured starts at: 0x%x\n", FvBase));
-    ASSERT (FALSE);
-  }
-
-  return Status;
-}
diff --git a/OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c b/OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c
index 4efbc14d5921..79d3a178a65f 100644
--- a/OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c
+++ b/OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c
@@ -140,13 +140,11 @@ PeilessStartup (
   UINT32                      DxeCodeSize;
   TD_RETURN_DATA              TdReturnData;
   VOID                        *VmmHobList;
-  UINT8                       *CfvBase;
 
   Status      = EFI_SUCCESS;
   BootFv      = NULL;
   VmmHobList  = NULL;
   SecCoreData = (EFI_SEC_PEI_HAND_OFF *)Context;
-  CfvBase     = (UINT8 *)(UINTN)FixedPcdGet32 (PcdCfvBase);
 
   ZeroMem (&PlatformInfoHob, sizeof (PlatformInfoHob));
 
@@ -186,6 +184,15 @@ PeilessStartup (
       CpuDeadLoop ();
     }
 
+    //
+    // Measure Tdx CFV
+    //
+    Status = TdxHelperMeasureCfvImage ();
+    if (EFI_ERROR (Status)) {
+      ASSERT (FALSE);
+      CpuDeadLoop ();
+    }
+
     //
     // Build GuidHob for tdx measurement
     //
@@ -194,15 +201,6 @@ PeilessStartup (
       ASSERT (FALSE);
       CpuDeadLoop ();
     }
-
-    //
-    // Measure Tdx CFV
-    //
-    Status = MeasureFvImage ((EFI_PHYSICAL_ADDRESS)(UINTN)CfvBase, FixedPcdGet32 (PcdCfvRawDataSize), 1);
-    if (EFI_ERROR (Status)) {
-      ASSERT (FALSE);
-      CpuDeadLoop ();
-    }
   }
 
   //
diff --git a/OvmfPkg/Library/PeilessStartupLib/PeilessStartupInternal.h b/OvmfPkg/Library/PeilessStartupLib/PeilessStartupInternal.h
index a2d2c1c9145b..158196271962 100644
--- a/OvmfPkg/Library/PeilessStartupLib/PeilessStartupInternal.h
+++ b/OvmfPkg/Library/PeilessStartupLib/PeilessStartupInternal.h
@@ -58,25 +58,4 @@ EFIAPI
 ConstructSecHobList (
   );
 
-/**
-  Measure FV image.
-
-  @param[in]  FvBase            Base address of FV image.
-  @param[in]  FvLength          Length of FV image.
-  @param[in]  PcrIndex          Index of PCR
-
-  @retval EFI_SUCCESS           Fv image is measured successfully
-                                or it has been already measured.
-  @retval EFI_OUT_OF_RESOURCES  No enough memory to log the new event.
-  @retval EFI_DEVICE_ERROR      The command was unsuccessful.
-
-**/
-EFI_STATUS
-EFIAPI
-MeasureFvImage (
-  IN EFI_PHYSICAL_ADDRESS  FvBase,
-  IN UINT64                FvLength,
-  IN UINT8                 PcrIndex
-  );
-
 #endif
diff --git a/OvmfPkg/Library/PeilessStartupLib/PeilessStartupLib.inf b/OvmfPkg/Library/PeilessStartupLib/PeilessStartupLib.inf
index 5c6eb1597bea..4ced5dda9945 100644
--- a/OvmfPkg/Library/PeilessStartupLib/PeilessStartupLib.inf
+++ b/OvmfPkg/Library/PeilessStartupLib/PeilessStartupLib.inf
@@ -29,7 +29,6 @@
   PeilessStartup.c
   Hob.c
   DxeLoad.c
-  IntelTdx.c
   X64/VirtualMemory.c
 
 [Packages]
@@ -70,9 +69,6 @@
   gEfiNonCcFvGuid
 
 [Pcd]
-  gUefiOvmfPkgTokenSpaceGuid.PcdCfvBase
-  gUefiOvmfPkgTokenSpaceGuid.PcdCfvRawDataOffset
-  gUefiOvmfPkgTokenSpaceGuid.PcdCfvRawDataSize
   gUefiOvmfPkgTokenSpaceGuid.PcdBfvBase
   gUefiOvmfPkgTokenSpaceGuid.PcdBfvRawDataOffset
   gUefiOvmfPkgTokenSpaceGuid.PcdBfvRawDataSize
-- 
2.29.2.windows.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH V6 07/12] OvmfPkg: Refactor ProcessHobList
  2023-02-03  3:31 [PATCH V6 00/12] Enable Tdx measurement in OvmfPkgX64 Min Xu
                   ` (5 preceding siblings ...)
  2023-02-03  3:31 ` [PATCH V6 06/12] OvmfPkg: Refactor MeaureFvImage Min Xu
@ 2023-02-03  3:31 ` Min Xu
  2023-02-03  3:31 ` [PATCH V6 08/12] OvmfPkg/IntelTdx: Measure TdHob and Configuration FV in SecMain Min Xu
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Min Xu @ 2023-02-03  3:31 UTC (permalink / raw)
  To: devel
  Cc: Min M Xu, Erdem Aktas, James Bottomley, Jiewen Yao, Gerd Hoffmann,
	Tom Lendacky, Michael Roth

From: Min M Xu <min.m.xu@intel.com>

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4243

ProcessHobList once was implemented in PlatformInitLib and it walks thru
TdHob list and accept un-accepted memories.

This patch moves the codes to SecTdxHelperLib and rename ProcessHobList
as TdxHelperProcessTdHob

After TdxHelperProcessTdHob is introduced, below changes are applied:
 - Call TdxHelperProcessTdHob instead of ProcessHobList in SecMain.c
   (in both OvmfPkgX64/Sec and IntelTdx/Sec).
 - Delete the duplicated codes in PlatformInitLib

Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Michael Roth <michael.roth@amd.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
---
 OvmfPkg/Include/Library/PlatformInitLib.h     |  17 -
 OvmfPkg/IntelTdx/Sec/SecMain.c                |   4 +-
 OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelper.c  | 754 ++++++++++++++++-
 OvmfPkg/Library/PlatformInitLib/IntelTdx.c    | 768 ------------------
 .../Library/PlatformInitLib/IntelTdxNull.c    |  20 -
 .../PlatformInitLib/PlatformInitLib.inf       |   1 -
 OvmfPkg/OvmfPkgX64.dsc                        |   3 +-
 OvmfPkg/Sec/SecMain.c                         |   4 +-
 8 files changed, 759 insertions(+), 812 deletions(-)

diff --git a/OvmfPkg/Include/Library/PlatformInitLib.h b/OvmfPkg/Include/Library/PlatformInitLib.h
index 051b31191194..57b18b94d9b8 100644
--- a/OvmfPkg/Include/Library/PlatformInitLib.h
+++ b/OvmfPkg/Include/Library/PlatformInitLib.h
@@ -210,23 +210,6 @@ PlatformMaxCpuCountInitialization (
   IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
   );
 
-/**
-  In Tdx guest, some information need to be passed from host VMM to guest
-  firmware. For example, the memory resource, etc. These information are
-  prepared by host VMM and put in HobList which is described in TdxMetadata.
-
-  Information in HobList is treated as external input. From the security
-  perspective before it is consumed, it should be validated.
-
-  @retval   EFI_SUCCESS   Successfully process the hoblist
-  @retval   Others        Other error as indicated
-**/
-EFI_STATUS
-EFIAPI
-ProcessTdxHobList (
-  VOID
-  );
-
 /**
   In Tdx guest, the system memory is passed in TdHob by host VMM. So
   the major task of PlatformTdxPublishRamRegions is to walk thru the
diff --git a/OvmfPkg/IntelTdx/Sec/SecMain.c b/OvmfPkg/IntelTdx/Sec/SecMain.c
index ab01ec9ab19c..41bd5c66ba29 100644
--- a/OvmfPkg/IntelTdx/Sec/SecMain.c
+++ b/OvmfPkg/IntelTdx/Sec/SecMain.c
@@ -24,7 +24,7 @@
 #include <Library/LocalApicLib.h>
 #include <Library/CpuExceptionHandlerLib.h>
 #include <IndustryStandard/Tdx.h>
-#include <Library/PlatformInitLib.h>
+#include <Library/TdxHelperLib.h>
 #include <Library/CcProbeLib.h>
 #include <Library/PeilessStartupLib.h>
 
@@ -67,7 +67,7 @@ SecCoreStartupWithStack (
     // first so that the memory is accepted. Otherwise access to the unaccepted
     // memory will trigger tripple fault.
     //
-    if (ProcessTdxHobList () != EFI_SUCCESS) {
+    if (TdxHelperProcessTdHob () != EFI_SUCCESS) {
       CpuDeadLoop ();
     }
   }
diff --git a/OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelper.c b/OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelper.c
index 1929093f9110..3372cee2f720 100644
--- a/OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelper.c
+++ b/OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelper.c
@@ -17,11 +17,20 @@
 #include <IndustryStandard/IntelTdx.h>
 #include <IndustryStandard/Tpm20.h>
 #include <Library/TdxLib.h>
+#include <Library/TdxMailboxLib.h>
+#include <Library/SynchronizationLib.h>
 #include <Pi/PrePiHob.h>
 #include <WorkArea.h>
 #include <ConfidentialComputingGuestAttr.h>
 #include <Library/TdxHelperLib.h>
 
+#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))
+
 /**
   Build the GuidHob for tdx measurements which were done in SEC phase.
   The measurement values are stored in WorkArea.
@@ -34,6 +43,720 @@ InternalBuildGuidHobForTdxMeasurement (
   VOID
   );
 
+/**
+  This function will be called to accept pages. Only BSP accepts pages.
+
+  TDCALL(ACCEPT_PAGE) supports the accept page size of 4k and 2M. To
+  simplify the implementation, the Memory to be accpeted is splitted
+  into 3 parts:
+  -----------------  <-- StartAddress1 (not 2M aligned)
+  |  part 1       |      Length1 < 2M
+  |---------------|  <-- StartAddress2 (2M aligned)
+  |               |      Length2 = Integer multiples of 2M
+  |  part 2       |
+  |               |
+  |---------------|  <-- StartAddress3
+  |  part 3       |      Length3 < 2M
+  |---------------|
+
+  @param[in] PhysicalAddress   Start physical adress
+  @param[in] PhysicalEnd       End physical address
+
+  @retval    EFI_SUCCESS       Accept memory successfully
+  @retval    Others            Other errors as indicated
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+BspAcceptMemoryResourceRange (
+  IN EFI_PHYSICAL_ADDRESS  PhysicalAddress,
+  IN EFI_PHYSICAL_ADDRESS  PhysicalEnd
+  )
+{
+  EFI_STATUS  Status;
+  UINT32      AcceptPageSize;
+  UINT64      StartAddress1;
+  UINT64      StartAddress2;
+  UINT64      StartAddress3;
+  UINT64      TotalLength;
+  UINT64      Length1;
+  UINT64      Length2;
+  UINT64      Length3;
+  UINT64      Pages;
+
+  AcceptPageSize = FixedPcdGet32 (PcdTdxAcceptPageSize);
+  TotalLength    = PhysicalEnd - PhysicalAddress;
+  StartAddress1  = 0;
+  StartAddress2  = 0;
+  StartAddress3  = 0;
+  Length1        = 0;
+  Length2        = 0;
+  Length3        = 0;
+
+  if (TotalLength == 0) {
+    return EFI_SUCCESS;
+  }
+
+  if (ALIGN_VALUE (PhysicalAddress, SIZE_2MB) != PhysicalAddress) {
+    StartAddress1 = PhysicalAddress;
+    Length1       = ALIGN_VALUE (PhysicalAddress, SIZE_2MB) - PhysicalAddress;
+    if (Length1 >= TotalLength) {
+      Length1 = TotalLength;
+    }
+
+    PhysicalAddress += Length1;
+    TotalLength     -= Length1;
+  }
+
+  if (TotalLength > SIZE_2MB) {
+    StartAddress2    = PhysicalAddress;
+    Length2          = TotalLength & ~(UINT64)ALIGNED_2MB_MASK;
+    PhysicalAddress += Length2;
+    TotalLength     -= Length2;
+  }
+
+  if (TotalLength) {
+    StartAddress3 = PhysicalAddress;
+    Length3       = TotalLength;
+  }
+
+  Status = EFI_SUCCESS;
+  if (Length1 > 0) {
+    Pages  = Length1 / SIZE_4KB;
+    Status = TdAcceptPages (StartAddress1, Pages, SIZE_4KB);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  }
+
+  if (Length2 > 0) {
+    Pages  = Length2 / AcceptPageSize;
+    Status = TdAcceptPages (StartAddress2, Pages, AcceptPageSize);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  }
+
+  if (Length3 > 0) {
+    Pages  = Length3 / SIZE_4KB;
+    Status = TdAcceptPages (StartAddress3, Pages, SIZE_4KB);
+    ASSERT (!EFI_ERROR (Status));
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  }
+
+  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
+ */
+STATIC
+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
+**/
+STATIC
+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
+**/
+STATIC
+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.
+
+  @param[in] Value             A value
+  @param[in] ValidList         A pointer to valid list
+  @param[in] ValidListLength   Length of valid list
+
+  @retval  TRUE   The value is in valid list.
+  @retval  FALSE  The value is not in valid list.
+
+**/
+STATIC
+BOOLEAN
+EFIAPI
+IsInValidList (
+  IN UINT32  Value,
+  IN UINT32  *ValidList,
+  IN UINT32  ValidListLength
+  )
+{
+  UINT32  index;
+
+  if (ValidList == NULL) {
+    return FALSE;
+  }
+
+  for (index = 0; index < ValidListLength; index++) {
+    if (ValidList[index] == Value) {
+      return TRUE;
+    }
+  }
+
+  return FALSE;
+}
+
+/**
+  Check the integrity of VMM Hob List.
+
+  @param[in] VmmHobList   A pointer to Hob List
+
+  @retval  TRUE     The Hob List is valid.
+  @retval  FALSE    The Hob List is invalid.
+
+**/
+STATIC
+BOOLEAN
+EFIAPI
+ValidateHobList (
+  IN CONST VOID  *VmmHobList
+  )
+{
+  EFI_PEI_HOB_POINTERS  Hob;
+  UINT32                EFI_BOOT_MODE_LIST[] = {
+    BOOT_WITH_FULL_CONFIGURATION,
+    BOOT_WITH_MINIMAL_CONFIGURATION,
+    BOOT_ASSUMING_NO_CONFIGURATION_CHANGES,
+    BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS,
+    BOOT_WITH_DEFAULT_SETTINGS,
+    BOOT_ON_S4_RESUME,
+    BOOT_ON_S5_RESUME,
+    BOOT_WITH_MFG_MODE_SETTINGS,
+    BOOT_ON_S2_RESUME,
+    BOOT_ON_S3_RESUME,
+    BOOT_ON_FLASH_UPDATE,
+    BOOT_IN_RECOVERY_MODE
+  };
+
+  UINT32  EFI_RESOURCE_TYPE_LIST[] = {
+    EFI_RESOURCE_SYSTEM_MEMORY,
+    EFI_RESOURCE_MEMORY_MAPPED_IO,
+    EFI_RESOURCE_IO,
+    EFI_RESOURCE_FIRMWARE_DEVICE,
+    EFI_RESOURCE_MEMORY_MAPPED_IO_PORT,
+    EFI_RESOURCE_MEMORY_RESERVED,
+    EFI_RESOURCE_IO_RESERVED,
+    BZ3937_EFI_RESOURCE_MEMORY_UNACCEPTED
+  };
+
+  if (VmmHobList == NULL) {
+    DEBUG ((DEBUG_ERROR, "HOB: HOB data pointer is NULL\n"));
+    return FALSE;
+  }
+
+  Hob.Raw = (UINT8 *)VmmHobList;
+
+  //
+  // Parse the HOB list until end of list or matching type is found.
+  //
+  while (!END_OF_HOB_LIST (Hob)) {
+    if (Hob.Header->Reserved != (UINT32)0) {
+      DEBUG ((DEBUG_ERROR, "HOB: Hob header Reserved filed should be zero\n"));
+      return FALSE;
+    }
+
+    if (Hob.Header->HobLength == 0) {
+      DEBUG ((DEBUG_ERROR, "HOB: Hob header LEANGTH should not be zero\n"));
+      return FALSE;
+    }
+
+    switch (Hob.Header->HobType) {
+      case EFI_HOB_TYPE_HANDOFF:
+        if (Hob.Header->HobLength != sizeof (EFI_HOB_HANDOFF_INFO_TABLE)) {
+          DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_HANDOFF));
+          return FALSE;
+        }
+
+        if (IsInValidList (Hob.HandoffInformationTable->BootMode, EFI_BOOT_MODE_LIST, ARRAY_SIZE (EFI_BOOT_MODE_LIST)) == FALSE) {
+          DEBUG ((DEBUG_ERROR, "HOB: Unknow HandoffInformationTable BootMode type. Type: 0x%08x\n", Hob.HandoffInformationTable->BootMode));
+          return FALSE;
+        }
+
+        if ((Hob.HandoffInformationTable->EfiFreeMemoryTop % 4096) != 0) {
+          DEBUG ((DEBUG_ERROR, "HOB: HandoffInformationTable EfiFreeMemoryTop address must be 4-KB aligned to meet page restrictions of UEFI.\
+                               Address: 0x%016lx\n", Hob.HandoffInformationTable->EfiFreeMemoryTop));
+          return FALSE;
+        }
+
+        break;
+
+      case EFI_HOB_TYPE_RESOURCE_DESCRIPTOR:
+        if (Hob.Header->HobLength != sizeof (EFI_HOB_RESOURCE_DESCRIPTOR)) {
+          DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_RESOURCE_DESCRIPTOR));
+          return FALSE;
+        }
+
+        if (IsInValidList (Hob.ResourceDescriptor->ResourceType, EFI_RESOURCE_TYPE_LIST, ARRAY_SIZE (EFI_RESOURCE_TYPE_LIST)) == FALSE) {
+          DEBUG ((DEBUG_ERROR, "HOB: Unknow ResourceDescriptor ResourceType type. Type: 0x%08x\n", Hob.ResourceDescriptor->ResourceType));
+          return FALSE;
+        }
+
+        if ((Hob.ResourceDescriptor->ResourceAttribute & (~(EFI_RESOURCE_ATTRIBUTE_PRESENT |
+                                                            EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+                                                            EFI_RESOURCE_ATTRIBUTE_TESTED |
+                                                            EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED |
+                                                            EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED |
+                                                            EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED |
+                                                            EFI_RESOURCE_ATTRIBUTE_PERSISTENT |
+                                                            EFI_RESOURCE_ATTRIBUTE_SINGLE_BIT_ECC |
+                                                            EFI_RESOURCE_ATTRIBUTE_MULTIPLE_BIT_ECC |
+                                                            EFI_RESOURCE_ATTRIBUTE_ECC_RESERVED_1 |
+                                                            EFI_RESOURCE_ATTRIBUTE_ECC_RESERVED_2 |
+                                                            EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+                                                            EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
+                                                            EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
+                                                            EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
+                                                            EFI_RESOURCE_ATTRIBUTE_16_BIT_IO |
+                                                            EFI_RESOURCE_ATTRIBUTE_32_BIT_IO |
+                                                            EFI_RESOURCE_ATTRIBUTE_64_BIT_IO |
+                                                            EFI_RESOURCE_ATTRIBUTE_UNCACHED_EXPORTED |
+                                                            EFI_RESOURCE_ATTRIBUTE_READ_PROTECTABLE |
+                                                            EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTABLE |
+                                                            EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTABLE |
+                                                            EFI_RESOURCE_ATTRIBUTE_PERSISTABLE |
+                                                            EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED |
+                                                            EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTABLE |
+                                                            EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE))) != 0)
+        {
+          DEBUG ((DEBUG_ERROR, "HOB: Unknow ResourceDescriptor ResourceAttribute type. Type: 0x%08x\n", Hob.ResourceDescriptor->ResourceAttribute));
+          return FALSE;
+        }
+
+        break;
+
+      // EFI_HOB_GUID_TYPE is variable length data, so skip check
+      case EFI_HOB_TYPE_GUID_EXTENSION:
+        break;
+
+      case EFI_HOB_TYPE_FV:
+        if (Hob.Header->HobLength != sizeof (EFI_HOB_FIRMWARE_VOLUME)) {
+          DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_FV));
+          return FALSE;
+        }
+
+        break;
+
+      case EFI_HOB_TYPE_FV2:
+        if (Hob.Header->HobLength != sizeof (EFI_HOB_FIRMWARE_VOLUME2)) {
+          DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_FV2));
+          return FALSE;
+        }
+
+        break;
+
+      case EFI_HOB_TYPE_FV3:
+        if (Hob.Header->HobLength != sizeof (EFI_HOB_FIRMWARE_VOLUME3)) {
+          DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_FV3));
+          return FALSE;
+        }
+
+        break;
+
+      case EFI_HOB_TYPE_CPU:
+        if (Hob.Header->HobLength != sizeof (EFI_HOB_CPU)) {
+          DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_CPU));
+          return FALSE;
+        }
+
+        for (UINT32 index = 0; index < 6; index++) {
+          if (Hob.Cpu->Reserved[index] != 0) {
+            DEBUG ((DEBUG_ERROR, "HOB: Cpu Reserved field will always be set to zero.\n"));
+            return FALSE;
+          }
+        }
+
+        break;
+
+      default:
+        DEBUG ((DEBUG_ERROR, "HOB: Hob type is not know. Type: 0x%04x\n", Hob.Header->HobType));
+        return FALSE;
+    }
+
+    // Get next HOB
+    Hob.Raw = (UINT8 *)(Hob.Raw + Hob.Header->HobLength);
+  }
+
+  return TRUE;
+}
+
+/**
+  Processing the incoming HobList for the TDX
+
+  Firmware must parse list, and accept the pages of memory before their can be
+  use by the guest.
+
+  @param[in] VmmHobList    The Hoblist pass the firmware
+
+  @retval  EFI_SUCCESS     Process the HobList successfully
+  @retval  Others          Other errors as indicated
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+ProcessHobList (
+  IN CONST VOID  *VmmHobList
+  )
+{
+  EFI_STATUS            Status;
+  UINT32                CpusNum;
+  EFI_PHYSICAL_ADDRESS  PhysicalEnd;
+  EFI_PHYSICAL_ADDRESS  APsStackStartAddress;
+
+  CpusNum = GetCpusNum ();
+
+  //
+  // 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.
+  //
+  // 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;
+}
+
 /**
   In Tdx guest, some information need to be passed from host VMM to guest
   firmware. For example, the memory resource, etc. These information are
@@ -49,7 +772,36 @@ TdxHelperProcessTdHob (
   VOID
   )
 {
-  return EFI_UNSUPPORTED;
+  EFI_STATUS      Status;
+  VOID            *TdHob;
+  TD_RETURN_DATA  TdReturnData;
+
+  TdHob  = (VOID *)(UINTN)FixedPcdGet32 (PcdOvmfSecGhcbBase);
+  Status = TdCall (TDCALL_TDINFO, 0, 0, 0, &TdReturnData);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  DEBUG ((
+    DEBUG_INFO,
+    "Intel Tdx Started with (GPAW: %d, Cpus: %d)\n",
+    TdReturnData.TdInfo.Gpaw,
+    TdReturnData.TdInfo.NumVcpus
+    ));
+
+  //
+  // Validate HobList
+  //
+  if (ValidateHobList (TdHob) == FALSE) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Process Hoblist to accept memory
+  //
+  Status = ProcessHobList (TdHob);
+
+  return Status;
 }
 
 /**
diff --git a/OvmfPkg/Library/PlatformInitLib/IntelTdx.c b/OvmfPkg/Library/PlatformInitLib/IntelTdx.c
index 6cb63139cba0..ada8592ddd5a 100644
--- a/OvmfPkg/Library/PlatformInitLib/IntelTdx.c
+++ b/OvmfPkg/Library/PlatformInitLib/IntelTdx.c
@@ -16,779 +16,11 @@
 #include <Library/MemoryAllocationLib.h>
 #include <IndustryStandard/Tdx.h>
 #include <IndustryStandard/IntelTdx.h>
-#include <IndustryStandard/QemuFwCfg.h>
-#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>
 #include <ConfidentialComputingGuestAttr.h>
 
-#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.
-
-  TDCALL(ACCEPT_PAGE) supports the accept page size of 4k and 2M. To
-  simplify the implementation, the Memory to be accpeted is splitted
-  into 3 parts:
-  -----------------  <-- StartAddress1 (not 2M aligned)
-  |  part 1       |      Length1 < 2M
-  |---------------|  <-- StartAddress2 (2M aligned)
-  |               |      Length2 = Integer multiples of 2M
-  |  part 2       |
-  |               |
-  |---------------|  <-- StartAddress3
-  |  part 3       |      Length3 < 2M
-  |---------------|
-
-  @param[in] PhysicalAddress   Start physical adress
-  @param[in] PhysicalEnd       End physical address
-
-  @retval    EFI_SUCCESS       Accept memory successfully
-  @retval    Others            Other errors as indicated
-**/
-EFI_STATUS
-EFIAPI
-BspAcceptMemoryResourceRange (
-  IN EFI_PHYSICAL_ADDRESS  PhysicalAddress,
-  IN EFI_PHYSICAL_ADDRESS  PhysicalEnd
-  )
-{
-  EFI_STATUS  Status;
-  UINT32      AcceptPageSize;
-  UINT64      StartAddress1;
-  UINT64      StartAddress2;
-  UINT64      StartAddress3;
-  UINT64      TotalLength;
-  UINT64      Length1;
-  UINT64      Length2;
-  UINT64      Length3;
-  UINT64      Pages;
-
-  AcceptPageSize = FixedPcdGet32 (PcdTdxAcceptPageSize);
-  TotalLength    = PhysicalEnd - PhysicalAddress;
-  StartAddress1  = 0;
-  StartAddress2  = 0;
-  StartAddress3  = 0;
-  Length1        = 0;
-  Length2        = 0;
-  Length3        = 0;
-
-  if (TotalLength == 0) {
-    return EFI_SUCCESS;
-  }
-
-  if (ALIGN_VALUE (PhysicalAddress, SIZE_2MB) != PhysicalAddress) {
-    StartAddress1 = PhysicalAddress;
-    Length1       = ALIGN_VALUE (PhysicalAddress, SIZE_2MB) - PhysicalAddress;
-    if (Length1 >= TotalLength) {
-      Length1 = TotalLength;
-    }
-
-    PhysicalAddress += Length1;
-    TotalLength     -= Length1;
-  }
-
-  if (TotalLength > SIZE_2MB) {
-    StartAddress2    = PhysicalAddress;
-    Length2          = TotalLength & ~(UINT64)ALIGNED_2MB_MASK;
-    PhysicalAddress += Length2;
-    TotalLength     -= Length2;
-  }
-
-  if (TotalLength) {
-    StartAddress3 = PhysicalAddress;
-    Length3       = TotalLength;
-  }
-
-  Status = EFI_SUCCESS;
-  if (Length1 > 0) {
-    Pages  = Length1 / SIZE_4KB;
-    Status = TdAcceptPages (StartAddress1, Pages, SIZE_4KB);
-    if (EFI_ERROR (Status)) {
-      return Status;
-    }
-  }
-
-  if (Length2 > 0) {
-    Pages  = Length2 / AcceptPageSize;
-    Status = TdAcceptPages (StartAddress2, Pages, AcceptPageSize);
-    if (EFI_ERROR (Status)) {
-      return Status;
-    }
-  }
-
-  if (Length3 > 0) {
-    Pages  = Length3 / SIZE_4KB;
-    Status = TdAcceptPages (StartAddress3, Pages, SIZE_4KB);
-    ASSERT (!EFI_ERROR (Status));
-    if (EFI_ERROR (Status)) {
-      return Status;
-    }
-  }
-
-  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.
-
-  @param[in] Value             A value
-  @param[in] ValidList         A pointer to valid list
-  @param[in] ValidListLength   Length of valid list
-
-  @retval  TRUE   The value is in valid list.
-  @retval  FALSE  The value is not in valid list.
-
-**/
-BOOLEAN
-EFIAPI
-IsInValidList (
-  IN UINT32  Value,
-  IN UINT32  *ValidList,
-  IN UINT32  ValidListLength
-  )
-{
-  UINT32  index;
-
-  if (ValidList == NULL) {
-    return FALSE;
-  }
-
-  for (index = 0; index < ValidListLength; index++) {
-    if (ValidList[index] == Value) {
-      return TRUE;
-    }
-  }
-
-  return FALSE;
-}
-
-/**
-  Check the integrity of VMM Hob List.
-
-  @param[in] VmmHobList   A pointer to Hob List
-
-  @retval  TRUE     The Hob List is valid.
-  @retval  FALSE    The Hob List is invalid.
-
-**/
-BOOLEAN
-EFIAPI
-ValidateHobList (
-  IN CONST VOID  *VmmHobList
-  )
-{
-  EFI_PEI_HOB_POINTERS  Hob;
-  UINT32                EFI_BOOT_MODE_LIST[] = {
-    BOOT_WITH_FULL_CONFIGURATION,
-    BOOT_WITH_MINIMAL_CONFIGURATION,
-    BOOT_ASSUMING_NO_CONFIGURATION_CHANGES,
-    BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS,
-    BOOT_WITH_DEFAULT_SETTINGS,
-    BOOT_ON_S4_RESUME,
-    BOOT_ON_S5_RESUME,
-    BOOT_WITH_MFG_MODE_SETTINGS,
-    BOOT_ON_S2_RESUME,
-    BOOT_ON_S3_RESUME,
-    BOOT_ON_FLASH_UPDATE,
-    BOOT_IN_RECOVERY_MODE
-  };
-
-  UINT32  EFI_RESOURCE_TYPE_LIST[] = {
-    EFI_RESOURCE_SYSTEM_MEMORY,
-    EFI_RESOURCE_MEMORY_MAPPED_IO,
-    EFI_RESOURCE_IO,
-    EFI_RESOURCE_FIRMWARE_DEVICE,
-    EFI_RESOURCE_MEMORY_MAPPED_IO_PORT,
-    EFI_RESOURCE_MEMORY_RESERVED,
-    EFI_RESOURCE_IO_RESERVED,
-    BZ3937_EFI_RESOURCE_MEMORY_UNACCEPTED
-  };
-
-  if (VmmHobList == NULL) {
-    DEBUG ((DEBUG_ERROR, "HOB: HOB data pointer is NULL\n"));
-    return FALSE;
-  }
-
-  Hob.Raw = (UINT8 *)VmmHobList;
-
-  //
-  // Parse the HOB list until end of list or matching type is found.
-  //
-  while (!END_OF_HOB_LIST (Hob)) {
-    if (Hob.Header->Reserved != (UINT32)0) {
-      DEBUG ((DEBUG_ERROR, "HOB: Hob header Reserved filed should be zero\n"));
-      return FALSE;
-    }
-
-    if (Hob.Header->HobLength == 0) {
-      DEBUG ((DEBUG_ERROR, "HOB: Hob header LEANGTH should not be zero\n"));
-      return FALSE;
-    }
-
-    switch (Hob.Header->HobType) {
-      case EFI_HOB_TYPE_HANDOFF:
-        if (Hob.Header->HobLength != sizeof (EFI_HOB_HANDOFF_INFO_TABLE)) {
-          DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_HANDOFF));
-          return FALSE;
-        }
-
-        if (IsInValidList (Hob.HandoffInformationTable->BootMode, EFI_BOOT_MODE_LIST, ARRAY_SIZE (EFI_BOOT_MODE_LIST)) == FALSE) {
-          DEBUG ((DEBUG_ERROR, "HOB: Unknow HandoffInformationTable BootMode type. Type: 0x%08x\n", Hob.HandoffInformationTable->BootMode));
-          return FALSE;
-        }
-
-        if ((Hob.HandoffInformationTable->EfiFreeMemoryTop % 4096) != 0) {
-          DEBUG ((DEBUG_ERROR, "HOB: HandoffInformationTable EfiFreeMemoryTop address must be 4-KB aligned to meet page restrictions of UEFI.\
-                               Address: 0x%016lx\n", Hob.HandoffInformationTable->EfiFreeMemoryTop));
-          return FALSE;
-        }
-
-        break;
-
-      case EFI_HOB_TYPE_RESOURCE_DESCRIPTOR:
-        if (Hob.Header->HobLength != sizeof (EFI_HOB_RESOURCE_DESCRIPTOR)) {
-          DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_RESOURCE_DESCRIPTOR));
-          return FALSE;
-        }
-
-        if (IsInValidList (Hob.ResourceDescriptor->ResourceType, EFI_RESOURCE_TYPE_LIST, ARRAY_SIZE (EFI_RESOURCE_TYPE_LIST)) == FALSE) {
-          DEBUG ((DEBUG_ERROR, "HOB: Unknow ResourceDescriptor ResourceType type. Type: 0x%08x\n", Hob.ResourceDescriptor->ResourceType));
-          return FALSE;
-        }
-
-        if ((Hob.ResourceDescriptor->ResourceAttribute & (~(EFI_RESOURCE_ATTRIBUTE_PRESENT |
-                                                            EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
-                                                            EFI_RESOURCE_ATTRIBUTE_TESTED |
-                                                            EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED |
-                                                            EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED |
-                                                            EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED |
-                                                            EFI_RESOURCE_ATTRIBUTE_PERSISTENT |
-                                                            EFI_RESOURCE_ATTRIBUTE_SINGLE_BIT_ECC |
-                                                            EFI_RESOURCE_ATTRIBUTE_MULTIPLE_BIT_ECC |
-                                                            EFI_RESOURCE_ATTRIBUTE_ECC_RESERVED_1 |
-                                                            EFI_RESOURCE_ATTRIBUTE_ECC_RESERVED_2 |
-                                                            EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
-                                                            EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
-                                                            EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
-                                                            EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
-                                                            EFI_RESOURCE_ATTRIBUTE_16_BIT_IO |
-                                                            EFI_RESOURCE_ATTRIBUTE_32_BIT_IO |
-                                                            EFI_RESOURCE_ATTRIBUTE_64_BIT_IO |
-                                                            EFI_RESOURCE_ATTRIBUTE_UNCACHED_EXPORTED |
-                                                            EFI_RESOURCE_ATTRIBUTE_READ_PROTECTABLE |
-                                                            EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTABLE |
-                                                            EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTABLE |
-                                                            EFI_RESOURCE_ATTRIBUTE_PERSISTABLE |
-                                                            EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED |
-                                                            EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTABLE |
-                                                            EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE))) != 0)
-        {
-          DEBUG ((DEBUG_ERROR, "HOB: Unknow ResourceDescriptor ResourceAttribute type. Type: 0x%08x\n", Hob.ResourceDescriptor->ResourceAttribute));
-          return FALSE;
-        }
-
-        break;
-
-      // EFI_HOB_GUID_TYPE is variable length data, so skip check
-      case EFI_HOB_TYPE_GUID_EXTENSION:
-        break;
-
-      case EFI_HOB_TYPE_FV:
-        if (Hob.Header->HobLength != sizeof (EFI_HOB_FIRMWARE_VOLUME)) {
-          DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_FV));
-          return FALSE;
-        }
-
-        break;
-
-      case EFI_HOB_TYPE_FV2:
-        if (Hob.Header->HobLength != sizeof (EFI_HOB_FIRMWARE_VOLUME2)) {
-          DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_FV2));
-          return FALSE;
-        }
-
-        break;
-
-      case EFI_HOB_TYPE_FV3:
-        if (Hob.Header->HobLength != sizeof (EFI_HOB_FIRMWARE_VOLUME3)) {
-          DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_FV3));
-          return FALSE;
-        }
-
-        break;
-
-      case EFI_HOB_TYPE_CPU:
-        if (Hob.Header->HobLength != sizeof (EFI_HOB_CPU)) {
-          DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_CPU));
-          return FALSE;
-        }
-
-        for (UINT32 index = 0; index < 6; index++) {
-          if (Hob.Cpu->Reserved[index] != 0) {
-            DEBUG ((DEBUG_ERROR, "HOB: Cpu Reserved field will always be set to zero.\n"));
-            return FALSE;
-          }
-        }
-
-        break;
-
-      default:
-        DEBUG ((DEBUG_ERROR, "HOB: Hob type is not know. Type: 0x%04x\n", Hob.Header->HobType));
-        return FALSE;
-    }
-
-    // Get next HOB
-    Hob.Raw = (UINT8 *)(Hob.Raw + Hob.Header->HobLength);
-  }
-
-  return TRUE;
-}
-
-/**
-  Processing the incoming HobList for the TDX
-
-  Firmware must parse list, and accept the pages of memory before their can be
-  use by the guest.
-
-  @param[in] VmmHobList    The Hoblist pass the firmware
-
-  @retval  EFI_SUCCESS     Process the HobList successfully
-  @retval  Others          Other errors as indicated
-
-**/
-EFI_STATUS
-EFIAPI
-ProcessHobList (
-  IN CONST VOID  *VmmHobList
-  )
-{
-  EFI_STATUS            Status;
-  UINT32                CpusNum;
-  EFI_PHYSICAL_ADDRESS  PhysicalEnd;
-  EFI_PHYSICAL_ADDRESS  APsStackStartAddress;
-
-  CpusNum = GetCpusNum ();
-
-  //
-  // 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.
-  //
-  // 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;
-}
-
-/**
-  In Tdx guest, some information need to be passed from host VMM to guest
-  firmware. For example, the memory resource, etc. These information are
-  prepared by host VMM and put in HobList which is described in TdxMetadata.
-
-  Information in HobList is treated as external input. From the security
-  perspective before it is consumed, it should be validated.
-
-  @retval   EFI_SUCCESS   Successfully process the hoblist
-  @retval   Others        Other error as indicated
-**/
-EFI_STATUS
-EFIAPI
-ProcessTdxHobList (
-  VOID
-  )
-{
-  EFI_STATUS      Status;
-  VOID            *TdHob;
-  TD_RETURN_DATA  TdReturnData;
-
-  TdHob  = (VOID *)(UINTN)FixedPcdGet32 (PcdOvmfSecGhcbBase);
-  Status = TdCall (TDCALL_TDINFO, 0, 0, 0, &TdReturnData);
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-
-  DEBUG ((
-    DEBUG_INFO,
-    "Intel Tdx Started with (GPAW: %d, Cpus: %d)\n",
-    TdReturnData.TdInfo.Gpaw,
-    TdReturnData.TdInfo.NumVcpus
-    ));
-
-  //
-  // Validate HobList
-  //
-  if (ValidateHobList (TdHob) == FALSE) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  //
-  // Process Hoblist to accept memory
-  //
-  Status = ProcessHobList (TdHob);
-
-  return Status;
-}
-
 /**
  * Build ResourceDescriptorHob for the unaccepted memory region.
  * This memory region may be splitted into 2 parts because of lazy accept.
diff --git a/OvmfPkg/Library/PlatformInitLib/IntelTdxNull.c b/OvmfPkg/Library/PlatformInitLib/IntelTdxNull.c
index 3ebe582af8de..7a7c2fb1f6f5 100644
--- a/OvmfPkg/Library/PlatformInitLib/IntelTdxNull.c
+++ b/OvmfPkg/Library/PlatformInitLib/IntelTdxNull.c
@@ -9,26 +9,6 @@
 
 #include <PiPei.h>
 
-/**
-  In Tdx guest, some information need to be passed from host VMM to guest
-  firmware. For example, the memory resource, etc. These information are
-  prepared by host VMM and put in HobList which is described in TdxMetadata.
-
-  Information in HobList is treated as external input. From the security
-  perspective before it is consumed, it should be validated.
-
-  @retval   EFI_SUCCESS   Successfully process the hoblist
-  @retval   Others        Other error as indicated
-**/
-EFI_STATUS
-EFIAPI
-ProcessTdxHobList (
-  VOID
-  )
-{
-  return EFI_UNSUPPORTED;
-}
-
 /**
   In Tdx guest, the system memory is passed in TdHob by host VMM. So
   the major task of PlatformTdxPublishRamRegions is to walk thru the
diff --git a/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf b/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
index 140216979a54..86a82ad3e084 100644
--- a/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
+++ b/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
@@ -52,7 +52,6 @@
   PcdLib
   PciLib
   PeiHardwareInfoLib
-  TdxMailboxLib
 
 [LibraryClasses.X64]
   TdxLib
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index 3f970a79a08a..d87013a4422c 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -724,7 +724,8 @@
   OvmfPkg/Sec/SecMain.inf {
     <LibraryClasses>
       NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
-      NULL|OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
+      NULL|OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelperLib.inf
+      BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SecCryptLib.inf
   }
 
   #
diff --git a/OvmfPkg/Sec/SecMain.c b/OvmfPkg/Sec/SecMain.c
index 1167d22a68cc..a27dc9406b70 100644
--- a/OvmfPkg/Sec/SecMain.c
+++ b/OvmfPkg/Sec/SecMain.c
@@ -29,7 +29,7 @@
 #include <Library/CpuExceptionHandlerLib.h>
 #include <Ppi/TemporaryRamSupport.h>
 #include <Ppi/MpInitLibDep.h>
-#include <Library/PlatformInitLib.h>
+#include <Library/TdxHelperLib.h>
 #include <Library/CcProbeLib.h>
 #include "AmdSev.h"
 
@@ -765,7 +765,7 @@ SecCoreStartupWithStack (
     // first so that the memory is accepted. Otherwise access to the unaccepted
     // memory will trigger tripple fault.
     //
-    if (ProcessTdxHobList () != EFI_SUCCESS) {
+    if (TdxHelperProcessTdHob () != EFI_SUCCESS) {
       CpuDeadLoop ();
     }
   }
-- 
2.29.2.windows.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH V6 08/12] OvmfPkg/IntelTdx: Measure TdHob and Configuration FV in SecMain
  2023-02-03  3:31 [PATCH V6 00/12] Enable Tdx measurement in OvmfPkgX64 Min Xu
                   ` (6 preceding siblings ...)
  2023-02-03  3:31 ` [PATCH V6 07/12] OvmfPkg: Refactor ProcessHobList Min Xu
@ 2023-02-03  3:31 ` Min Xu
  2023-02-03  8:51   ` Gerd Hoffmann
  2023-02-03  3:31 ` [PATCH V6 09/12] OvmfPkg/IntelTdx: Add PeiTdxHelperLib Min Xu
                   ` (3 subsequent siblings)
  11 siblings, 1 reply; 14+ messages in thread
From: Min Xu @ 2023-02-03  3:31 UTC (permalink / raw)
  To: devel
  Cc: Min M Xu, Erdem Aktas, James Bottomley, Jiewen Yao, Gerd Hoffmann,
	Tom Lendacky, Michael Roth

From: Min M Xu <min.m.xu@intel.com>

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4243

TdHob and Configuration FV (Cfv) are external inputs from VMM. From the
security perspective, they should be measured before they're consumed.
This patch measures TdHob and Cfv and stores the measurement values in
WorkArea.

After TdHob and Configuration FV (Cfv) are measured in SecMain, the
same measurements in PeilessStartupLib are deleted.

Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Michael Roth <michael.roth@amd.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
---
 OvmfPkg/IntelTdx/IntelTdxX64.dsc              |  3 ---
 OvmfPkg/IntelTdx/Sec/SecMain.c                | 13 ++++++++++++
 .../PeilessStartupLib/PeilessStartup.c        | 20 +------------------
 .../PeilessStartupLib/PeilessStartupLib.inf   |  2 --
 4 files changed, 14 insertions(+), 24 deletions(-)

diff --git a/OvmfPkg/IntelTdx/IntelTdxX64.dsc b/OvmfPkg/IntelTdx/IntelTdxX64.dsc
index 920f1c6080d4..41de2e942817 100644
--- a/OvmfPkg/IntelTdx/IntelTdxX64.dsc
+++ b/OvmfPkg/IntelTdx/IntelTdxX64.dsc
@@ -548,11 +548,8 @@
   OvmfPkg/IntelTdx/Sec/SecMain.inf {
     <LibraryClasses>
       NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
-      TpmMeasurementLib|SecurityPkg/Library/SecTpmMeasurementLib/SecTpmMeasurementLibTdx.inf
       NULL|OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelperLib.inf
       BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SecCryptLib.inf
-      HashLib|SecurityPkg/Library/HashLibTdx/HashLibTdx.inf
-      NULL|SecurityPkg/Library/HashInstanceLibSha384/HashInstanceLibSha384.inf
   }
 
   #
diff --git a/OvmfPkg/IntelTdx/Sec/SecMain.c b/OvmfPkg/IntelTdx/Sec/SecMain.c
index 41bd5c66ba29..ccb217b709a0 100644
--- a/OvmfPkg/IntelTdx/Sec/SecMain.c
+++ b/OvmfPkg/IntelTdx/Sec/SecMain.c
@@ -62,6 +62,19 @@ SecCoreStartupWithStack (
   volatile UINT8        *Table;
 
   if (CcProbe () == CcGuestTypeIntelTdx) {
+    //
+    // From the security perspective all the external input should be measured before
+    // it is consumed. TdHob and Configuration FV (Cfv) image are passed from VMM
+    // and should be measured here.
+    //
+    if (EFI_ERROR (TdxHelperMeasureTdHob ())) {
+      CpuDeadLoop ();
+    }
+
+    if (EFI_ERROR (TdxHelperMeasureCfvImage ())) {
+      CpuDeadLoop ();
+    }
+
     //
     // For Td guests, the memory map info is in TdHobLib. It should be processed
     // first so that the memory is accepted. Otherwise access to the unaccepted
diff --git a/OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c b/OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c
index 79d3a178a65f..164aa2d61911 100644
--- a/OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c
+++ b/OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c
@@ -176,25 +176,7 @@ PeilessStartup (
 
   if (TdIsEnabled ()) {
     //
-    // Measure HobList
-    //
-    Status = TdxHelperMeasureTdHob ();
-    if (EFI_ERROR (Status)) {
-      ASSERT (FALSE);
-      CpuDeadLoop ();
-    }
-
-    //
-    // Measure Tdx CFV
-    //
-    Status = TdxHelperMeasureCfvImage ();
-    if (EFI_ERROR (Status)) {
-      ASSERT (FALSE);
-      CpuDeadLoop ();
-    }
-
-    //
-    // Build GuidHob for tdx measurement
+    // Build GuidHob for the tdx measurements which were done in SEC phase.
     //
     Status = TdxHelperBuildGuidHobForTdxMeasurement ();
     if (EFI_ERROR (Status)) {
diff --git a/OvmfPkg/Library/PeilessStartupLib/PeilessStartupLib.inf b/OvmfPkg/Library/PeilessStartupLib/PeilessStartupLib.inf
index 4ced5dda9945..e77ad7bc921e 100644
--- a/OvmfPkg/Library/PeilessStartupLib/PeilessStartupLib.inf
+++ b/OvmfPkg/Library/PeilessStartupLib/PeilessStartupLib.inf
@@ -56,8 +56,6 @@
   PrePiLib
   QemuFwCfgLib
   PlatformInitLib
-  HashLib
-  TpmMeasurementLib
 
 [Guids]
   gEfiHobMemoryAllocModuleGuid
-- 
2.29.2.windows.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH V6 09/12] OvmfPkg/IntelTdx: Add PeiTdxHelperLib
  2023-02-03  3:31 [PATCH V6 00/12] Enable Tdx measurement in OvmfPkgX64 Min Xu
                   ` (7 preceding siblings ...)
  2023-02-03  3:31 ` [PATCH V6 08/12] OvmfPkg/IntelTdx: Measure TdHob and Configuration FV in SecMain Min Xu
@ 2023-02-03  3:31 ` Min Xu
  2023-02-03  3:31 ` [PATCH V6 10/12] OvmfPkg/OvmfPkgX64: Measure TdHob and Configuration FV in SecMain Min Xu
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Min Xu @ 2023-02-03  3:31 UTC (permalink / raw)
  To: devel
  Cc: Min M Xu, Erdem Aktas, James Bottomley, Jiewen Yao, Gerd Hoffmann,
	Tom Lendacky, Michael Roth

From: Min M Xu <min.m.xu@intel.com>

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4243

TdxHelperLib provides below helper functions for a td-guest.
 - TdxHelperProcessTdHob
 - TdxHelperMeasureTdHob
 - TdxHelperMeasureCfvImage
 - TdxHelperBuildGuidHobForTdxMeasurement

PeiTdxHelperLib is the PEI instance of TdxHelperLib. It implements 1
function for tdx in PEI phase. Other functions are not supported in
PEI phase.
  - TdxHelperBuildGuidHobForTdxMeasurement builds GuidHob for tdx
    measurement in PEI phase.

Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Michael Roth <michael.roth@amd.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
---
 OvmfPkg/IntelTdx/TdxHelperLib/PeiTdxHelper.c  | 91 +++++++++++++++++++
 .../IntelTdx/TdxHelperLib/PeiTdxHelperLib.inf | 48 ++++++++++
 2 files changed, 139 insertions(+)
 create mode 100644 OvmfPkg/IntelTdx/TdxHelperLib/PeiTdxHelper.c
 create mode 100644 OvmfPkg/IntelTdx/TdxHelperLib/PeiTdxHelperLib.inf

diff --git a/OvmfPkg/IntelTdx/TdxHelperLib/PeiTdxHelper.c b/OvmfPkg/IntelTdx/TdxHelperLib/PeiTdxHelper.c
new file mode 100644
index 000000000000..91ab53ed14ad
--- /dev/null
+++ b/OvmfPkg/IntelTdx/TdxHelperLib/PeiTdxHelper.c
@@ -0,0 +1,91 @@
+/** @file
+  TdxHelper Functions which are used in PEI phase
+
+  Copyright (c) 2022 - 2023, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Base.h>
+#include <PiPei.h>
+
+/**
+  Build the GuidHob for tdx measurements which were done in SEC phase.
+  The measurement values are stored in WorkArea.
+
+  @retval EFI_SUCCESS  The GuidHob is built successfully
+  @retval Others       Other errors as indicated
+**/
+EFI_STATUS
+InternalBuildGuidHobForTdxMeasurement (
+  VOID
+  );
+
+/**
+  In Tdx guest, some information need to be passed from host VMM to guest
+  firmware. For example, the memory resource, etc. These information are
+  prepared by host VMM and put in TdHob which is described in TdxMetadata.
+  TDVF processes the TdHob to accept memories.
+
+  @retval   EFI_SUCCESS   Successfully process the TdHob
+  @retval   Others        Other error as indicated
+**/
+EFI_STATUS
+EFIAPI
+TdxHelperProcessTdHob (
+  VOID
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  In Tdx guest, TdHob is passed from host VMM to guest firmware and it contains
+  the information of the memory resource. From the security perspective before
+  it is consumed, it should be measured and extended.
+ *
+ * @retval EFI_SUCCESS Successfully measure the TdHob
+ * @retval Others      Other error as indicated
+ */
+EFI_STATUS
+EFIAPI
+TdxHelperMeasureTdHob (
+  VOID
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+ * In Tdx guest, Configuration FV (CFV) is treated as external input because it
+ * may contain the data provided by VMM. From the sucurity perspective Cfv image
+ * should be measured before it is consumed.
+ *
+ * @retval EFI_SUCCESS Successfully measure the CFV image
+ * @retval Others      Other error as indicated
+ */
+EFI_STATUS
+EFIAPI
+TdxHelperMeasureCfvImage (
+  VOID
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Build the GuidHob for tdx measurements which were done in SEC phase.
+  The measurement values are stored in WorkArea.
+
+  @retval EFI_SUCCESS  The GuidHob is built successfully
+  @retval Others       Other errors as indicated
+**/
+EFI_STATUS
+EFIAPI
+TdxHelperBuildGuidHobForTdxMeasurement (
+  VOID
+  )
+{
+  return InternalBuildGuidHobForTdxMeasurement ();
+}
diff --git a/OvmfPkg/IntelTdx/TdxHelperLib/PeiTdxHelperLib.inf b/OvmfPkg/IntelTdx/TdxHelperLib/PeiTdxHelperLib.inf
new file mode 100644
index 000000000000..ad3b6c1da62b
--- /dev/null
+++ b/OvmfPkg/IntelTdx/TdxHelperLib/PeiTdxHelperLib.inf
@@ -0,0 +1,48 @@
+## @file
+#  TdxHelperLib PEI instance
+#
+#  This module provides Tdx helper functions in PEI phase.
+#  Copyright (c) 2021 - 2023, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PeiTdxHelperLib
+  FILE_GUID                      = 4d22289d-3bde-4501-a737-7719f3215065
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = TdxHelperLib|PEIM
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = X64
+#
+
+[Sources]
+  PeiTdxHelper.c
+  TdxMeasurementHob.c
+
+[Packages]
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  OvmfPkg/OvmfPkg.dec
+  SecurityPkg/SecurityPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  HobLib
+  PcdLib
+
+[FixedPcd]
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageVariableBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdCfvRawDataSize
+
+[Guids]
+  gCcEventEntryHobGuid
-- 
2.29.2.windows.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH V6 10/12] OvmfPkg/OvmfPkgX64: Measure TdHob and Configuration FV in SecMain
  2023-02-03  3:31 [PATCH V6 00/12] Enable Tdx measurement in OvmfPkgX64 Min Xu
                   ` (8 preceding siblings ...)
  2023-02-03  3:31 ` [PATCH V6 09/12] OvmfPkg/IntelTdx: Add PeiTdxHelperLib Min Xu
@ 2023-02-03  3:31 ` Min Xu
  2023-02-03  3:31 ` [PATCH V6 11/12] OvmfPkg/PlatformPei: Build GuidHob for Tdx measurement Min Xu
  2023-02-03  3:31 ` [PATCH V6 12/12] OvmfPkg: Support Tdx measurement in OvmfPkgX64 Min Xu
  11 siblings, 0 replies; 14+ messages in thread
From: Min Xu @ 2023-02-03  3:31 UTC (permalink / raw)
  To: devel
  Cc: Min M Xu, Erdem Aktas, James Bottomley, Jiewen Yao, Gerd Hoffmann,
	Tom Lendacky, Michael Roth

From: Min M Xu <min.m.xu@intel.com>

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4243

TdHob and Configuration FV (Cfv) are external inputs from VMM. From the
security perspective, they should be measured before they're consumed.
This patch measures TdHob and Cfv and stores the measurement values in
WorkArea.

Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Michael Roth <michael.roth@amd.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
---
 OvmfPkg/Sec/SecMain.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/OvmfPkg/Sec/SecMain.c b/OvmfPkg/Sec/SecMain.c
index a27dc9406b70..4bb3b641701e 100644
--- a/OvmfPkg/Sec/SecMain.c
+++ b/OvmfPkg/Sec/SecMain.c
@@ -760,6 +760,19 @@ SecCoreStartupWithStack (
 
  #if defined (TDX_GUEST_SUPPORTED)
   if (CcProbe () == CcGuestTypeIntelTdx) {
+    //
+    // From the security perspective all the external input should be measured before
+    // it is consumed. TdHob and Configuration FV (Cfv) image are passed from VMM
+    // and should be measured here.
+    //
+    if (EFI_ERROR (TdxHelperMeasureTdHob ())) {
+      CpuDeadLoop ();
+    }
+
+    if (EFI_ERROR (TdxHelperMeasureCfvImage ())) {
+      CpuDeadLoop ();
+    }
+
     //
     // For Td guests, the memory map info is in TdHobLib. It should be processed
     // first so that the memory is accepted. Otherwise access to the unaccepted
-- 
2.29.2.windows.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH V6 11/12] OvmfPkg/PlatformPei: Build GuidHob for Tdx measurement
  2023-02-03  3:31 [PATCH V6 00/12] Enable Tdx measurement in OvmfPkgX64 Min Xu
                   ` (9 preceding siblings ...)
  2023-02-03  3:31 ` [PATCH V6 10/12] OvmfPkg/OvmfPkgX64: Measure TdHob and Configuration FV in SecMain Min Xu
@ 2023-02-03  3:31 ` Min Xu
  2023-02-03  3:31 ` [PATCH V6 12/12] OvmfPkg: Support Tdx measurement in OvmfPkgX64 Min Xu
  11 siblings, 0 replies; 14+ messages in thread
From: Min Xu @ 2023-02-03  3:31 UTC (permalink / raw)
  To: devel
  Cc: Min M Xu, Erdem Aktas, James Bottomley, Jiewen Yao, Gerd Hoffmann,
	Tom Lendacky, Michael Roth

From: Min M Xu <min.m.xu@intel.com>

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4243

TdxHelperBuildGuidHobForTdxMeasurement is called in PlatformPei to build
GuidHob for Tdx measurement.

Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Michael Roth <michael.roth@amd.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
---
 OvmfPkg/AmdSev/AmdSevX64.dsc   | 5 ++++-
 OvmfPkg/CloudHv/CloudHvX64.dsc | 5 ++++-
 OvmfPkg/Microvm/MicrovmX64.dsc | 5 ++++-
 OvmfPkg/OvmfPkgX64.dsc         | 5 ++++-
 OvmfPkg/PlatformPei/IntelTdx.c | 3 +++
 5 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc
index 36100f5fdc11..1cebd6b4bcc2 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.dsc
+++ b/OvmfPkg/AmdSev/AmdSevX64.dsc
@@ -570,7 +570,10 @@
   }
   MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
 
-  OvmfPkg/PlatformPei/PlatformPei.inf
+  OvmfPkg/PlatformPei/PlatformPei.inf {
+    <LibraryClasses>
+      NULL|OvmfPkg/IntelTdx/TdxHelperLib/TdxHelperLibNull.inf
+  }
   UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
   UefiCpuPkg/CpuMpPei/CpuMpPei.inf
   OvmfPkg/AmdSev/SecretPei/SecretPei.inf
diff --git a/OvmfPkg/CloudHv/CloudHvX64.dsc b/OvmfPkg/CloudHv/CloudHvX64.dsc
index 7326417eab62..fc5e73158a71 100644
--- a/OvmfPkg/CloudHv/CloudHvX64.dsc
+++ b/OvmfPkg/CloudHv/CloudHvX64.dsc
@@ -678,7 +678,10 @@
   }
   MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
 
-  OvmfPkg/PlatformPei/PlatformPei.inf
+  OvmfPkg/PlatformPei/PlatformPei.inf {
+    <LibraryClasses>
+      NULL|OvmfPkg/IntelTdx/TdxHelperLib/TdxHelperLibNull.inf
+  }
   UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf {
     <LibraryClasses>
 !if $(SMM_REQUIRE) == TRUE
diff --git a/OvmfPkg/Microvm/MicrovmX64.dsc b/OvmfPkg/Microvm/MicrovmX64.dsc
index 2d53b5c2950d..1161e1f39bf2 100644
--- a/OvmfPkg/Microvm/MicrovmX64.dsc
+++ b/OvmfPkg/Microvm/MicrovmX64.dsc
@@ -679,7 +679,10 @@
   }
   MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
 
-  OvmfPkg/PlatformPei/PlatformPei.inf
+  OvmfPkg/PlatformPei/PlatformPei.inf {
+    <LibraryClasses>
+      NULL|OvmfPkg/IntelTdx/TdxHelperLib/TdxHelperLibNull.inf
+  }
   UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
   UefiCpuPkg/CpuMpPei/CpuMpPei.inf
 
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index d87013a4422c..a13299c18cfd 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -746,7 +746,10 @@
   }
   MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
 
-  OvmfPkg/PlatformPei/PlatformPei.inf
+  OvmfPkg/PlatformPei/PlatformPei.inf {
+    <LibraryClasses>
+      NULL|OvmfPkg/IntelTdx/TdxHelperLib/PeiTdxHelperLib.inf
+  }
   UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf {
     <LibraryClasses>
 !if $(SMM_REQUIRE) == TRUE
diff --git a/OvmfPkg/PlatformPei/IntelTdx.c b/OvmfPkg/PlatformPei/IntelTdx.c
index 3c1ddbfafd80..3d625cabd844 100644
--- a/OvmfPkg/PlatformPei/IntelTdx.c
+++ b/OvmfPkg/PlatformPei/IntelTdx.c
@@ -18,6 +18,7 @@
 #include <Library/QemuFwCfgLib.h>
 #include <Library/PeiServicesLib.h>
 #include <Library/TdxLib.h>
+#include <Library/TdxHelperLib.h>
 #include <Library/PlatformInitLib.h>
 #include <WorkArea.h>
 #include <ConfidentialComputingGuestAttr.h>
@@ -39,6 +40,8 @@ IntelTdxInitialize (
     return;
   }
 
+  TdxHelperBuildGuidHobForTdxMeasurement ();
+
   PcdStatus = PcdSet64S (PcdConfidentialComputingGuestAttr, CCAttrIntelTdx);
   ASSERT_RETURN_ERROR (PcdStatus);
 
-- 
2.29.2.windows.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH V6 12/12] OvmfPkg: Support Tdx measurement in OvmfPkgX64
  2023-02-03  3:31 [PATCH V6 00/12] Enable Tdx measurement in OvmfPkgX64 Min Xu
                   ` (10 preceding siblings ...)
  2023-02-03  3:31 ` [PATCH V6 11/12] OvmfPkg/PlatformPei: Build GuidHob for Tdx measurement Min Xu
@ 2023-02-03  3:31 ` Min Xu
  11 siblings, 0 replies; 14+ messages in thread
From: Min Xu @ 2023-02-03  3:31 UTC (permalink / raw)
  To: devel
  Cc: Min M Xu, Erdem Aktas, James Bottomley, Jiewen Yao, Gerd Hoffmann,
	Tom Lendacky, Michael Roth

From: Min M Xu <min.m.xu@intel.com>

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4243

This patch enables Tdx measurement in OvmfPkgX64 with below changes:
1) CC_MEASUREMENT_ENABLE is introduced in OvmfPkgX64.dsc. This flag
   indicates if Intel TDX measurement is enabled in OvmfPkgX64. Its
   default value is FALSE.
2) Include TdTcg2Dxe in OvmfPkgX64 so that CC_MEASUREMENT_PROTOCOL
   is installed in a Td-guest. TdTcg2Dxe is controlled by
   TDX_MEASUREMENT_ENABLE because it is only valid when Intel TDX
   measurement is enabled.
3) OvmfTpmLibs.dsc.inc and OvmfTpmSecurityStub.dsc.inc are updated
   because DxeTpm2MeasureBootLib.inf and DxeTpmMeasurementLib.inf
   should be included to support CC_MEASUREMENT_PROTOCOL.

Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Michael Roth <michael.roth@amd.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
---
 OvmfPkg/Include/Dsc/OvmfTpmLibs.dsc.inc         | 10 +++++++++-
 OvmfPkg/Include/Dsc/OvmfTpmSecurityStub.dsc.inc |  8 ++++++++
 OvmfPkg/OvmfPkgX64.dsc                          | 12 ++++++++++++
 OvmfPkg/OvmfPkgX64.fdf                          |  7 +++++++
 4 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/OvmfPkg/Include/Dsc/OvmfTpmLibs.dsc.inc b/OvmfPkg/Include/Dsc/OvmfTpmLibs.dsc.inc
index cd1a899d68f7..b97244695b52 100644
--- a/OvmfPkg/Include/Dsc/OvmfTpmLibs.dsc.inc
+++ b/OvmfPkg/Include/Dsc/OvmfTpmLibs.dsc.inc
@@ -10,9 +10,17 @@
   Tpm2CommandLib|SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf
   Tcg2PhysicalPresenceLib|OvmfPkg/Library/Tcg2PhysicalPresenceLibQemu/DxeTcg2PhysicalPresenceLib.inf
   Tcg2PpVendorLib|SecurityPkg/Library/Tcg2PpVendorLibNull/Tcg2PpVendorLibNull.inf
-  TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
 !else
   Tcg2PhysicalPresenceLib|OvmfPkg/Library/Tcg2PhysicalPresenceLibNull/DxeTcg2PhysicalPresenceLib.inf
+!endif
+
+!if $(TPM2_ENABLE) == TRUE || $(CC_MEASUREMENT_ENABLE) == TRUE
+  #
+  # DxeTpmMeasurementLib supports measurement functions for both TPM and Confidential Computing.
+  # It should be controlled by TPM2_ENABLE and CC_MEASUREMENT_ENABLE.
+  #
+  TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
+!else
   TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
 !endif
 
diff --git a/OvmfPkg/Include/Dsc/OvmfTpmSecurityStub.dsc.inc b/OvmfPkg/Include/Dsc/OvmfTpmSecurityStub.dsc.inc
index e9ab2fca7bc7..89455feca4d9 100644
--- a/OvmfPkg/Include/Dsc/OvmfTpmSecurityStub.dsc.inc
+++ b/OvmfPkg/Include/Dsc/OvmfTpmSecurityStub.dsc.inc
@@ -6,5 +6,13 @@
 !if $(TPM1_ENABLE) == TRUE
       NULL|SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.inf
 !endif
+!endif
+
+!if $(TPM2_ENABLE) == TRUE || $(CC_MEASUREMENT_ENABLE) == TRUE
+      #
+      # DxeTpm2MeasureBootLib provides security service of TPM2 measure boot and
+      # Confidential Computing (CC) measure boot. It should be controlled by
+      # TPM2_ENABLE and CC_MEASUREMENT_ENABLE
+      #
       NULL|SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf
 !endif
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index a13299c18cfd..8f9355f5447c 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -32,6 +32,7 @@
   DEFINE SECURE_BOOT_ENABLE      = FALSE
   DEFINE SMM_REQUIRE             = FALSE
   DEFINE SOURCE_DEBUG_ENABLE     = FALSE
+  DEFINE CC_MEASUREMENT_ENABLE   = FALSE
 
 !include OvmfPkg/Include/Dsc/OvmfTpmDefines.dsc.inc
 
@@ -1104,6 +1105,17 @@
   }
 !endif
 
+  #
+  # Cc Measurement Protocol for Td guest
+  #
+!if $(CC_MEASUREMENT_ENABLE) == TRUE
+  SecurityPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.inf {
+    <LibraryClasses>
+      HashLib|SecurityPkg/Library/HashLibTdx/HashLibTdx.inf
+      NULL|SecurityPkg/Library/HashInstanceLibSha384/HashInstanceLibSha384.inf
+  }
+!endif
+
   #
   # TPM support
   #
diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
index 8c02dfe11e37..16666ba24440 100644
--- a/OvmfPkg/OvmfPkgX64.fdf
+++ b/OvmfPkg/OvmfPkgX64.fdf
@@ -402,6 +402,13 @@ INF  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
 INF  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
 !endif
 
+#
+# EFI_CC_MEASUREMENT_PROTOCOL
+#
+!if $(CC_MEASUREMENT_ENABLE) == TRUE
+INF SecurityPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.inf
+!endif
+
 #
 # TPM support
 #
-- 
2.29.2.windows.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH V6 08/12] OvmfPkg/IntelTdx: Measure TdHob and Configuration FV in SecMain
  2023-02-03  3:31 ` [PATCH V6 08/12] OvmfPkg/IntelTdx: Measure TdHob and Configuration FV in SecMain Min Xu
@ 2023-02-03  8:51   ` Gerd Hoffmann
  0 siblings, 0 replies; 14+ messages in thread
From: Gerd Hoffmann @ 2023-02-03  8:51 UTC (permalink / raw)
  To: Min Xu
  Cc: devel, Erdem Aktas, James Bottomley, Jiewen Yao, Tom Lendacky,
	Michael Roth

On Fri, Feb 03, 2023 at 11:31:43AM +0800, Min Xu wrote:
> From: Min M Xu <min.m.xu@intel.com>
> 
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4243
> 
> TdHob and Configuration FV (Cfv) are external inputs from VMM. From the
> security perspective, they should be measured before they're consumed.
> This patch measures TdHob and Cfv and stores the measurement values in
> WorkArea.
> 
> After TdHob and Configuration FV (Cfv) are measured in SecMain, the
> same measurements in PeilessStartupLib are deleted.
> 
> Cc: Erdem Aktas <erdemaktas@google.com>
> Cc: James Bottomley <jejb@linux.ibm.com>
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Cc: Tom Lendacky <thomas.lendacky@amd.com>
> Cc: Michael Roth <michael.roth@amd.com>
> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
> Signed-off-by: Min Xu <min.m.xu@intel.com>

Acked-by: Gerd Hoffmann <kraxel@redhat.com>


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2023-02-03  8:51 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-02-03  3:31 [PATCH V6 00/12] Enable Tdx measurement in OvmfPkgX64 Min Xu
2023-02-03  3:31 ` [PATCH V6 01/12] OvmfPkg: Add Tdx measurement data structure in WorkArea Min Xu
2023-02-03  3:31 ` [PATCH V6 02/12] OvmfPkg/IntelTdx: Add TdxHelperLibNull Min Xu
2023-02-03  3:31 ` [PATCH V6 03/12] OvmfPkg/IntelTdx: Add SecTdxHelperLib Min Xu
2023-02-03  3:31 ` [PATCH V6 04/12] OvmfPkg/PeilessStartupLib: Update the define of FV_HANDOFF_TABLE_POINTERS2 Min Xu
2023-02-03  3:31 ` [PATCH V6 05/12] OvmfPkg: Refactor MeasureHobList Min Xu
2023-02-03  3:31 ` [PATCH V6 06/12] OvmfPkg: Refactor MeaureFvImage Min Xu
2023-02-03  3:31 ` [PATCH V6 07/12] OvmfPkg: Refactor ProcessHobList Min Xu
2023-02-03  3:31 ` [PATCH V6 08/12] OvmfPkg/IntelTdx: Measure TdHob and Configuration FV in SecMain Min Xu
2023-02-03  8:51   ` Gerd Hoffmann
2023-02-03  3:31 ` [PATCH V6 09/12] OvmfPkg/IntelTdx: Add PeiTdxHelperLib Min Xu
2023-02-03  3:31 ` [PATCH V6 10/12] OvmfPkg/OvmfPkgX64: Measure TdHob and Configuration FV in SecMain Min Xu
2023-02-03  3:31 ` [PATCH V6 11/12] OvmfPkg/PlatformPei: Build GuidHob for Tdx measurement Min Xu
2023-02-03  3:31 ` [PATCH V6 12/12] OvmfPkg: Support Tdx measurement in OvmfPkgX64 Min Xu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox