* [PATCH V2 00/10] Enable Tdx measurement in OvmfPkgX64
@ 2023-01-19 3:28 Min Xu
2023-01-19 3:28 ` [PATCH V2 01/10] OvmfPkg: Add Tdx measurement data structure in WorkArea Min Xu
` (9 more replies)
0 siblings, 10 replies; 26+ messages in thread
From: Min Xu @ 2023-01-19 3:28 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 - 5:
Introduce TdxHelperLib which provides helper functions for td-guest.
Patch #6/7:
These 2 patches are the changes for OvmfPkg/IntelTdx because of the
introduction of TdxHelperLib.
Patch #8/9:
These 2 patches are the changes for OvmfPkg/OvmfPkgX64 to enable Tdx
measurement.
Patch #10:
ProcessTdxHobList is moved to TdxHelperLib and is renamed as
TdxHelperProcessTdHob(). So the duplicated codes are deleted in this
patch.
Code: https://github.com/mxu9/edk2/tree/TdxMeasurementInOvmfX64.v2
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 (10):
OvmfPkg: Add Tdx measurement data structure in WorkArea
OvmfPkg/IntelTdx: Add TdxHelperLibNull
OvmfPkg/IntelTdx: Add SecTdxHelperLib
OvmfPkg/IntelTdx: Implement other helper functions in SecTdxHelperLib
OvmfPkg/IntelTdx: Add PeiTdxHelperLib
OvmfPkg/PeilessStartupLib: Build GuidHob for Tdx measurements
OvmfPkg/IntelTdx: Update tdx measurement in SEC phase
OvmfPkg: Enable Tdx measurement in OvmfPkgX64
OvmfPkg/PlatformPei: Build GuidHob for Tdx measurement
OvmfPkg/PlatformInitLib: Delete the ProcessTdxHobList()
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} | 312 +++----
.../IntelTdx/TdxHelperLib/SecTdxHelperLib.inf | 53 ++
.../TdxHelperLib/TdxHelperLibNull.inf | 32 +
OvmfPkg/IntelTdx/TdxHelperLib/TdxHelperNull.c | 79 ++
.../IntelTdx/TdxHelperLib/TdxMeasurementHob.c | 266 ++++++
OvmfPkg/Library/PeilessStartupLib/IntelTdx.c | 196 -----
.../PeilessStartupLib/PeilessStartup.c | 16 +-
.../PeilessStartupInternal.h | 36 -
.../PeilessStartupLib/PeilessStartupLib.inf | 3 -
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, 931 insertions(+), 1207 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} (79%)
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] 26+ messages in thread
* [PATCH V2 01/10] OvmfPkg: Add Tdx measurement data structure in WorkArea
2023-01-19 3:28 [PATCH V2 00/10] Enable Tdx measurement in OvmfPkgX64 Min Xu
@ 2023-01-19 3:28 ` Min Xu
2023-01-19 9:33 ` Gerd Hoffmann
2023-01-19 3:28 ` [PATCH V2 02/10] OvmfPkg/IntelTdx: Add TdxHelperLibNull Min Xu
` (8 subsequent siblings)
9 siblings, 1 reply; 26+ messages in thread
From: Min Xu @ 2023-01-19 3:28 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>
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] 26+ messages in thread
* [PATCH V2 02/10] OvmfPkg/IntelTdx: Add TdxHelperLibNull
2023-01-19 3:28 [PATCH V2 00/10] Enable Tdx measurement in OvmfPkgX64 Min Xu
2023-01-19 3:28 ` [PATCH V2 01/10] OvmfPkg: Add Tdx measurement data structure in WorkArea Min Xu
@ 2023-01-19 3:28 ` Min Xu
2023-01-19 9:33 ` Gerd Hoffmann
2023-01-19 3:28 ` [PATCH V2 03/10] OvmfPkg/IntelTdx: Add SecTdxHelperLib Min Xu
` (7 subsequent siblings)
9 siblings, 1 reply; 26+ messages in thread
From: Min Xu @ 2023-01-19 3:28 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>
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 e07546f4a701..7b91580f8e3a 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] 26+ messages in thread
* [PATCH V2 03/10] OvmfPkg/IntelTdx: Add SecTdxHelperLib
2023-01-19 3:28 [PATCH V2 00/10] Enable Tdx measurement in OvmfPkgX64 Min Xu
2023-01-19 3:28 ` [PATCH V2 01/10] OvmfPkg: Add Tdx measurement data structure in WorkArea Min Xu
2023-01-19 3:28 ` [PATCH V2 02/10] OvmfPkg/IntelTdx: Add TdxHelperLibNull Min Xu
@ 2023-01-19 3:28 ` Min Xu
2023-01-19 9:33 ` Gerd Hoffmann
2023-01-19 3:28 ` [PATCH V2 04/10] OvmfPkg/IntelTdx: Implement other helper functions in SecTdxHelperLib Min Xu
` (6 subsequent siblings)
9 siblings, 1 reply; 26+ messages in thread
From: Min Xu @ 2023-01-19 3:28 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.
In this patch only TdxHelperProcessTdHob is implemented. Other 3 functions
are to be implemented in the following patch. This is because the code of
TdxHelperProcessTdHob is copied from PlatformInitLib/IntelTdx.c.
TdxHelperProcessTdHob is corresponding to ProcessTdxHobList. To make the
patch reviewable, we sperate the SecTdxHelperLib into several patches. The
duplicated code in PlatformInitLib/IntelTdx.c will be deleted later. This
is to prevent the build from broken.
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>
---
OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelper.c | 845 ++++++++++++++++++
.../IntelTdx/TdxHelperLib/SecTdxHelperLib.inf | 52 ++
2 files changed, 897 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..4fb2d2a8acad
--- /dev/null
+++ b/OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelper.c
@@ -0,0 +1,845 @@
+/** @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 <Base.h>
+#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 <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))
+
+/**
+ 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
+ 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
+ )
+{
+ 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;
+}
+
+/**
+ 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] 26+ messages in thread
* [PATCH V2 04/10] OvmfPkg/IntelTdx: Implement other helper functions in SecTdxHelperLib
2023-01-19 3:28 [PATCH V2 00/10] Enable Tdx measurement in OvmfPkgX64 Min Xu
` (2 preceding siblings ...)
2023-01-19 3:28 ` [PATCH V2 03/10] OvmfPkg/IntelTdx: Add SecTdxHelperLib Min Xu
@ 2023-01-19 3:28 ` Min Xu
2023-01-19 9:54 ` Gerd Hoffmann
2023-01-19 3:28 ` [PATCH V2 05/10] OvmfPkg/IntelTdx: Add PeiTdxHelperLib Min Xu
` (5 subsequent siblings)
9 siblings, 1 reply; 26+ messages in thread
From: Min Xu @ 2023-01-19 3:28 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
This patch implements below helper functions in SecTdxHelperLib:
- 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 is only valid in PEI-LESS
startup mode. It builds GuidHob for tdx measurement 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>
---
OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelper.c | 150 +++++++++-
.../IntelTdx/TdxHelperLib/SecTdxHelperLib.inf | 1 +
.../IntelTdx/TdxHelperLib/TdxMeasurementHob.c | 266 ++++++++++++++++++
3 files changed, 414 insertions(+), 3 deletions(-)
create mode 100644 OvmfPkg/IntelTdx/TdxHelperLib/TdxMeasurementHob.c
diff --git a/OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelper.c b/OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelper.c
index 4fb2d2a8acad..82242d37d1ed 100644
--- a/OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelper.c
+++ b/OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelper.c
@@ -32,6 +32,18 @@
#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.
+
+ @retval EFI_SUCCESS The GuidHob is built successfully
+ @retval Others Other errors as indicated
+**/
+EFI_STATUS
+InternalBuildGuidHobForTdxMeasurement (
+ VOID
+ );
+
/**
This function will be called to accept pages. Only BSP accepts pages.
@@ -793,6 +805,67 @@ TdxHelperProcessTdHob (
return Status;
}
+//
+// SHA512_CTX is defined in <openssl/sha.h> and its size is 216 bytes.
+// It can be built successfully with GCC5 compiler but failed with VS2019.
+// The error code showed in VS2019 is that "openssl/sha.h" cannot be found.
+// To overcome this error SHA512_CTX_SIZE is defined.
+//
+#define SHA512_CTX_SIZ 216
+
+/**
+ * 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;
+ UINT8 Sha384Ctx[SHA512_CTX_SIZ];
+
+ 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
+ //
+ Sha384Init (Sha384Ctx);
+ Sha384Update (Sha384Ctx, DataToHash, DataToHashLen);
+ Sha384Final (Sha384Ctx, Digest);
+
+ //
+ // 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
@@ -807,7 +880,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;
}
/**
@@ -824,10 +937,37 @@ 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;
}
-/**
/**
Build the GuidHob for tdx measurements which were done in SEC phase.
The measurement values are stored in WorkArea.
@@ -841,5 +981,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..906d4df485b8
--- /dev/null
+++ b/OvmfPkg/IntelTdx/TdxHelperLib/TdxMeasurementHob.c
@@ -0,0 +1,266 @@
+/** @file
+ Build GuidHob for tdx measurement.
+
+ Copyright (c) 2022 - 2023, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Base.h>
+#include <PiPei.h>
+#include <IndustryStandard/UefiTcgPlatform.h>
+#include <IndustryStandard/Tpm20.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PrintLib.h>
+#include <Library/TpmMeasurementLib.h>
+#include <Pi/PrePiHob.h>
+#include <WorkArea.h>
+#include <ConfidentialComputingGuestAttr.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;
+
+#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()
+
+/**
+ * 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;
+}
+
+/**
+ 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
+**/
+STATIC
+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.
+
+ @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;
+ VOID *FvName;
+ FV_HANDOFF_TABLE_POINTERS2 FvBlob2;
+ EFI_PHYSICAL_ADDRESS FvBase;
+ UINT64 FvLength;
+ 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;
+ }
+
+ //
+ // 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;
+}
--
2.29.2.windows.2
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH V2 05/10] OvmfPkg/IntelTdx: Add PeiTdxHelperLib
2023-01-19 3:28 [PATCH V2 00/10] Enable Tdx measurement in OvmfPkgX64 Min Xu
` (3 preceding siblings ...)
2023-01-19 3:28 ` [PATCH V2 04/10] OvmfPkg/IntelTdx: Implement other helper functions in SecTdxHelperLib Min Xu
@ 2023-01-19 3:28 ` Min Xu
2023-01-19 9:54 ` Gerd Hoffmann
2023-01-19 3:28 ` [PATCH V2 06/10] OvmfPkg/PeilessStartupLib: Build GuidHob for Tdx measurements Min Xu
` (4 subsequent siblings)
9 siblings, 1 reply; 26+ messages in thread
From: Min Xu @ 2023-01-19 3:28 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>
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] 26+ messages in thread
* [PATCH V2 06/10] OvmfPkg/PeilessStartupLib: Build GuidHob for Tdx measurements
2023-01-19 3:28 [PATCH V2 00/10] Enable Tdx measurement in OvmfPkgX64 Min Xu
` (4 preceding siblings ...)
2023-01-19 3:28 ` [PATCH V2 05/10] OvmfPkg/IntelTdx: Add PeiTdxHelperLib Min Xu
@ 2023-01-19 3:28 ` Min Xu
2023-01-19 9:57 ` Gerd Hoffmann
2023-01-19 3:28 ` [PATCH V2 07/10] OvmfPkg/IntelTdx: Update tdx measurement in SEC phase Min Xu
` (3 subsequent siblings)
9 siblings, 1 reply; 26+ messages in thread
From: Min Xu @ 2023-01-19 3:28 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
With the introduction of TdxHelperBuildGuidHobForTdxMeasurement in
TdxHelperLib PeilessStartup should also be updated. It should call
TdxHelperBuildGuidHobForTdxMeasurement to build the GuidHob for Tdx
measurement.
The deprecated codes are deleted as well in this patch.
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>
---
OvmfPkg/Library/PeilessStartupLib/IntelTdx.c | 196 ------------------
.../PeilessStartupLib/PeilessStartup.c | 16 +-
.../PeilessStartupInternal.h | 36 ----
.../PeilessStartupLib/PeilessStartupLib.inf | 3 -
4 files changed, 3 insertions(+), 248 deletions(-)
delete mode 100644 OvmfPkg/Library/PeilessStartupLib/IntelTdx.c
diff --git a/OvmfPkg/Library/PeilessStartupLib/IntelTdx.c b/OvmfPkg/Library/PeilessStartupLib/IntelTdx.c
deleted file mode 100644
index 216c413caad5..000000000000
--- a/OvmfPkg/Library/PeilessStartupLib/IntelTdx.c
+++ /dev/null
@@ -1,196 +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/TpmMeasurementLib.h>
-
-#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;
-
-#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()
-
-/**
- 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.
-
- 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;
- FV_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 928120d183ba..164aa2d61911 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>
@@ -139,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));
@@ -177,18 +176,9 @@ PeilessStartup (
if (TdIsEnabled ()) {
//
- // Measure HobList
+ // Build GuidHob for the tdx measurements which were done in SEC phase.
//
- Status = MeasureHobList (VmmHobList);
- if (EFI_ERROR (Status)) {
- ASSERT (FALSE);
- CpuDeadLoop ();
- }
-
- //
- // Measure Tdx CFV
- //
- Status = MeasureFvImage ((EFI_PHYSICAL_ADDRESS)(UINTN)CfvBase, FixedPcdGet32 (PcdCfvRawDataSize), 1);
+ Status = TdxHelperBuildGuidHobForTdxMeasurement ();
if (EFI_ERROR (Status)) {
ASSERT (FALSE);
CpuDeadLoop ();
diff --git a/OvmfPkg/Library/PeilessStartupLib/PeilessStartupInternal.h b/OvmfPkg/Library/PeilessStartupLib/PeilessStartupInternal.h
index 09cac3e26c67..23e9e0be53f1 100644
--- a/OvmfPkg/Library/PeilessStartupLib/PeilessStartupInternal.h
+++ b/OvmfPkg/Library/PeilessStartupLib/PeilessStartupInternal.h
@@ -52,40 +52,4 @@ 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.
-
- @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 def50b4b019e..9971a8cee356 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]
@@ -57,8 +56,6 @@
PrePiLib
QemuFwCfgLib
PlatformInitLib
- HashLib
- TpmMeasurementLib
[Guids]
gEfiHobMemoryAllocModuleGuid
--
2.29.2.windows.2
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH V2 07/10] OvmfPkg/IntelTdx: Update tdx measurement in SEC phase
2023-01-19 3:28 [PATCH V2 00/10] Enable Tdx measurement in OvmfPkgX64 Min Xu
` (5 preceding siblings ...)
2023-01-19 3:28 ` [PATCH V2 06/10] OvmfPkg/PeilessStartupLib: Build GuidHob for Tdx measurements Min Xu
@ 2023-01-19 3:28 ` Min Xu
2023-01-19 9:57 ` Gerd Hoffmann
2023-01-19 3:28 ` [PATCH V2 08/10] OvmfPkg: Enable Tdx measurement in OvmfPkgX64 Min Xu
` (2 subsequent siblings)
9 siblings, 1 reply; 26+ messages in thread
From: Min Xu @ 2023-01-19 3:28 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
After TdxHelperLib is instroduced, the SecMain.c in IntelTdx is updated
with the new functions provided by 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>
Signed-off-by: Min Xu <min.m.xu@intel.com>
---
OvmfPkg/IntelTdx/IntelTdxX64.dsc | 4 +---
OvmfPkg/IntelTdx/Sec/SecMain.c | 17 +++++++++++++++--
2 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/OvmfPkg/IntelTdx/IntelTdxX64.dsc b/OvmfPkg/IntelTdx/IntelTdxX64.dsc
index 81511e3556a6..d8232f27dae9 100644
--- a/OvmfPkg/IntelTdx/IntelTdxX64.dsc
+++ b/OvmfPkg/IntelTdx/IntelTdxX64.dsc
@@ -541,10 +541,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 ab01ec9ab19c..ccb217b709a0 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>
@@ -62,12 +62,25 @@ 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
// 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] 26+ messages in thread
* [PATCH V2 08/10] OvmfPkg: Enable Tdx measurement in OvmfPkgX64
2023-01-19 3:28 [PATCH V2 00/10] Enable Tdx measurement in OvmfPkgX64 Min Xu
` (6 preceding siblings ...)
2023-01-19 3:28 ` [PATCH V2 07/10] OvmfPkg/IntelTdx: Update tdx measurement in SEC phase Min Xu
@ 2023-01-19 3:28 ` Min Xu
2023-01-19 3:28 ` [PATCH V2 09/10] OvmfPkg/PlatformPei: Build GuidHob for Tdx measurement Min Xu
2023-01-19 3:28 ` [PATCH V2 10/10] OvmfPkg/PlatformInitLib: Delete the ProcessTdxHobList() Min Xu
9 siblings, 0 replies; 26+ messages in thread
From: Min Xu @ 2023-01-19 3:28 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) TDX_ENABLE is introduced in OvmfPkgX64.dsc. This flag indicates
if Intel TDX is enabled in OvmfPkgX64. Its default value is FALSE.
2) Update SecMain.c with the functions provided by TdxHelperLib
3) Include TdTcg2Dxe in OvmfPkgX64 so that CC_MEASUREMENT_PROTOCOL
is installed in a Td-guest. TdTcg2Dxe is controlled by TDX_ENABLE
because it is only valid when Intel TDX 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>
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 | 15 ++++++++++++++-
OvmfPkg/OvmfPkgX64.fdf | 7 +++++++
OvmfPkg/Sec/SecMain.c | 17 +++++++++++++++--
5 files changed, 53 insertions(+), 4 deletions(-)
diff --git a/OvmfPkg/Include/Dsc/OvmfTpmLibs.dsc.inc b/OvmfPkg/Include/Dsc/OvmfTpmLibs.dsc.inc
index cd1a899d68f7..df228dc5e2ca 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 || $(TDX_ENABLE) == TRUE
+ #
+ # DxeTpmMeasurementLib supports measurement functions for both TPM and Confidential Computing.
+ # It should be controlled by TPM2_ENABLE and TDX_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..a08e29720f5d 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 || $(TDX_ENABLE) == TRUE
+ #
+ # DxeTpm2MeasureBootLib provides security service of TPM2 measure boot and
+ # Confidential Computing (CC) measure boot. It should be controlled by
+ # TPM2_ENABLE and TDX_ENABLE
+ #
NULL|SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf
!endif
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index 3f970a79a08a..0bf16a4815b3 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 TDX_ENABLE = FALSE
!include OvmfPkg/Include/Dsc/OvmfTpmDefines.dsc.inc
@@ -724,7 +725,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
}
#
@@ -1100,6 +1102,17 @@
}
!endif
+ #
+ # Cc Measurement Protocol for Td guest
+ #
+!if $(TDX_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..0df986f7ebec 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 $(TDX_ENABLE) == TRUE
+INF SecurityPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.inf
+!endif
+
#
# TPM support
#
diff --git a/OvmfPkg/Sec/SecMain.c b/OvmfPkg/Sec/SecMain.c
index 1167d22a68cc..4bb3b641701e 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"
@@ -760,12 +760,25 @@ 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
// 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] 26+ messages in thread
* [PATCH V2 09/10] OvmfPkg/PlatformPei: Build GuidHob for Tdx measurement
2023-01-19 3:28 [PATCH V2 00/10] Enable Tdx measurement in OvmfPkgX64 Min Xu
` (7 preceding siblings ...)
2023-01-19 3:28 ` [PATCH V2 08/10] OvmfPkg: Enable Tdx measurement in OvmfPkgX64 Min Xu
@ 2023-01-19 3:28 ` Min Xu
2023-01-19 9:58 ` Gerd Hoffmann
2023-01-19 3:28 ` [PATCH V2 10/10] OvmfPkg/PlatformInitLib: Delete the ProcessTdxHobList() Min Xu
9 siblings, 1 reply; 26+ messages in thread
From: Min Xu @ 2023-01-19 3:28 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>
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 0bf16a4815b3..3eade00a6eb4 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -747,7 +747,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] 26+ messages in thread
* [PATCH V2 10/10] OvmfPkg/PlatformInitLib: Delete the ProcessTdxHobList()
2023-01-19 3:28 [PATCH V2 00/10] Enable Tdx measurement in OvmfPkgX64 Min Xu
` (8 preceding siblings ...)
2023-01-19 3:28 ` [PATCH V2 09/10] OvmfPkg/PlatformPei: Build GuidHob for Tdx measurement Min Xu
@ 2023-01-19 3:28 ` Min Xu
9 siblings, 0 replies; 26+ messages in thread
From: Min Xu @ 2023-01-19 3:28 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
ProcessTdxHobList is moved to TdxHelperLib and is renamed as
TdxHelperProcessTdHob(). So the duplicated codes are deleted
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>
Signed-off-by: Min Xu <min.m.xu@intel.com>
---
OvmfPkg/Include/Library/PlatformInitLib.h | 17 -
OvmfPkg/Library/PlatformInitLib/IntelTdx.c | 768 ------------------
.../Library/PlatformInitLib/IntelTdxNull.c | 20 -
.../PlatformInitLib/PlatformInitLib.inf | 1 -
4 files changed, 806 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/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
--
2.29.2.windows.2
^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH V2 03/10] OvmfPkg/IntelTdx: Add SecTdxHelperLib
2023-01-19 3:28 ` [PATCH V2 03/10] OvmfPkg/IntelTdx: Add SecTdxHelperLib Min Xu
@ 2023-01-19 9:33 ` Gerd Hoffmann
0 siblings, 0 replies; 26+ messages in thread
From: Gerd Hoffmann @ 2023-01-19 9:33 UTC (permalink / raw)
To: Min Xu
Cc: devel, Erdem Aktas, James Bottomley, Jiewen Yao, Tom Lendacky,
Michael Roth
Hi,
> TdxHelperLib provides below helper functions for a td-guest.
> - TdxHelperProcessTdHob
This is moved over from PlatformInitLib.
> - TdxHelperMeasureTdHob
> - TdxHelperMeasureCfvImage
> - TdxHelperBuildGuidHobForTdxMeasurement
This is new.
> In this patch only TdxHelperProcessTdHob is implemented. Other 3 functions
> are to be implemented in the following patch. This is because the code of
> TdxHelperProcessTdHob is copied from PlatformInitLib/IntelTdx.c.
Why copy? You should be able to move the code over in one patch. Maybe
it's easier to do so at the end of the series, i.e. drop this patch and
the last patch moves the code instead of deleting it.
take care,
Gerd
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH V2 01/10] OvmfPkg: Add Tdx measurement data structure in WorkArea
2023-01-19 3:28 ` [PATCH V2 01/10] OvmfPkg: Add Tdx measurement data structure in WorkArea Min Xu
@ 2023-01-19 9:33 ` Gerd Hoffmann
0 siblings, 0 replies; 26+ messages in thread
From: Gerd Hoffmann @ 2023-01-19 9:33 UTC (permalink / raw)
To: Min Xu
Cc: devel, Erdem Aktas, James Bottomley, Jiewen Yao, Tom Lendacky,
Michael Roth
On Thu, Jan 19, 2023 at 11:28:13AM +0800, Min Xu wrote:
> 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.
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH V2 02/10] OvmfPkg/IntelTdx: Add TdxHelperLibNull
2023-01-19 3:28 ` [PATCH V2 02/10] OvmfPkg/IntelTdx: Add TdxHelperLibNull Min Xu
@ 2023-01-19 9:33 ` Gerd Hoffmann
0 siblings, 0 replies; 26+ messages in thread
From: Gerd Hoffmann @ 2023-01-19 9:33 UTC (permalink / raw)
To: Min Xu
Cc: devel, Erdem Aktas, James Bottomley, Jiewen Yao, Tom Lendacky,
Michael Roth
On Thu, Jan 19, 2023 at 11:28:14AM +0800, Min Xu wrote:
> 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>
> Signed-off-by: Min Xu <min.m.xu@intel.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH V2 04/10] OvmfPkg/IntelTdx: Implement other helper functions in SecTdxHelperLib
2023-01-19 3:28 ` [PATCH V2 04/10] OvmfPkg/IntelTdx: Implement other helper functions in SecTdxHelperLib Min Xu
@ 2023-01-19 9:54 ` Gerd Hoffmann
2023-01-19 23:44 ` Min Xu
2023-01-20 7:40 ` Min Xu
0 siblings, 2 replies; 26+ messages in thread
From: Gerd Hoffmann @ 2023-01-19 9:54 UTC (permalink / raw)
To: Min Xu
Cc: devel, Erdem Aktas, James Bottomley, Jiewen Yao, Tom Lendacky,
Michael Roth
> @@ -807,7 +880,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);
> + }
Hmm? Isn't there just a single TdHob? Why do you need to walk the list
here?
> +#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;
> +
> +#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()
Why do you need this? For standard event types we should have those
structs already defined somewhere in edk2 I think ...
take care,
Gerd
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH V2 05/10] OvmfPkg/IntelTdx: Add PeiTdxHelperLib
2023-01-19 3:28 ` [PATCH V2 05/10] OvmfPkg/IntelTdx: Add PeiTdxHelperLib Min Xu
@ 2023-01-19 9:54 ` Gerd Hoffmann
0 siblings, 0 replies; 26+ messages in thread
From: Gerd Hoffmann @ 2023-01-19 9:54 UTC (permalink / raw)
To: Min Xu
Cc: devel, Erdem Aktas, James Bottomley, Jiewen Yao, Tom Lendacky,
Michael Roth
On Thu, Jan 19, 2023 at 11:28:17AM +0800, Min Xu wrote:
> 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>
> Signed-off-by: Min Xu <min.m.xu@intel.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH V2 06/10] OvmfPkg/PeilessStartupLib: Build GuidHob for Tdx measurements
2023-01-19 3:28 ` [PATCH V2 06/10] OvmfPkg/PeilessStartupLib: Build GuidHob for Tdx measurements Min Xu
@ 2023-01-19 9:57 ` Gerd Hoffmann
0 siblings, 0 replies; 26+ messages in thread
From: Gerd Hoffmann @ 2023-01-19 9:57 UTC (permalink / raw)
To: Min Xu
Cc: devel, Erdem Aktas, James Bottomley, Jiewen Yao, Tom Lendacky,
Michael Roth
On Thu, Jan 19, 2023 at 11:28:18AM +0800, Min Xu wrote:
> From: Min M Xu <min.m.xu@intel.com>
>
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4243
>
> With the introduction of TdxHelperBuildGuidHobForTdxMeasurement in
> TdxHelperLib PeilessStartup should also be updated. It should call
> TdxHelperBuildGuidHobForTdxMeasurement to build the GuidHob for Tdx
> measurement.
>
> The deprecated codes are deleted as well in this patch.
This should likewise be a move instead of adding the code first and
delete it elsewhere later.
take care,
Gerd
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH V2 07/10] OvmfPkg/IntelTdx: Update tdx measurement in SEC phase
2023-01-19 3:28 ` [PATCH V2 07/10] OvmfPkg/IntelTdx: Update tdx measurement in SEC phase Min Xu
@ 2023-01-19 9:57 ` Gerd Hoffmann
0 siblings, 0 replies; 26+ messages in thread
From: Gerd Hoffmann @ 2023-01-19 9:57 UTC (permalink / raw)
To: Min Xu
Cc: devel, Erdem Aktas, James Bottomley, Jiewen Yao, Tom Lendacky,
Michael Roth
On Thu, Jan 19, 2023 at 11:28:19AM +0800, Min Xu wrote:
> From: Min M Xu <min.m.xu@intel.com>
>
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4243
>
> After TdxHelperLib is instroduced, the SecMain.c in IntelTdx is updated
> with the new functions provided by 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>
> Signed-off-by: Min Xu <min.m.xu@intel.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH V2 09/10] OvmfPkg/PlatformPei: Build GuidHob for Tdx measurement
2023-01-19 3:28 ` [PATCH V2 09/10] OvmfPkg/PlatformPei: Build GuidHob for Tdx measurement Min Xu
@ 2023-01-19 9:58 ` Gerd Hoffmann
0 siblings, 0 replies; 26+ messages in thread
From: Gerd Hoffmann @ 2023-01-19 9:58 UTC (permalink / raw)
To: Min Xu
Cc: devel, Erdem Aktas, James Bottomley, Jiewen Yao, Tom Lendacky,
Michael Roth
On Thu, Jan 19, 2023 at 11:28:21AM +0800, Min Xu wrote:
> 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>
> Signed-off-by: Min Xu <min.m.xu@intel.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH V2 04/10] OvmfPkg/IntelTdx: Implement other helper functions in SecTdxHelperLib
2023-01-19 9:54 ` Gerd Hoffmann
@ 2023-01-19 23:44 ` Min Xu
2023-01-20 7:40 ` Min Xu
1 sibling, 0 replies; 26+ messages in thread
From: Min Xu @ 2023-01-19 23:44 UTC (permalink / raw)
To: Gerd Hoffmann
Cc: devel@edk2.groups.io, Aktas, Erdem, James Bottomley, Yao, Jiewen,
Tom Lendacky, Michael Roth
On January 19, 2023 5:54 PM, Gerd Hoffmann wrote:
> > @@ -807,7 +880,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);
> > + }
>
> Hmm? Isn't there just a single TdHob? Why do you need to walk the list here?
No, TdHob is a HobList and it contains several Hobs, including the ResourceDescriptorHobs which describe the memory regions. So we have to walk thru the hob list to find out its length.
>
> > +#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;
> > +
> > +#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()
>
> Why do you need this? For standard event types we should have those
> structs already defined somewhere in edk2 I think ...
These structs are defined in SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c. Let me think can they be moved to a common header file. Thanks for reminder.
Thanks
Min
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH V2 04/10] OvmfPkg/IntelTdx: Implement other helper functions in SecTdxHelperLib
2023-01-19 9:54 ` Gerd Hoffmann
2023-01-19 23:44 ` Min Xu
@ 2023-01-20 7:40 ` Min Xu
2023-01-20 8:10 ` Yao, Jiewen
1 sibling, 1 reply; 26+ messages in thread
From: Min Xu @ 2023-01-20 7:40 UTC (permalink / raw)
To: Gerd Hoffmann, Yao, Jiewen
Cc: devel@edk2.groups.io, Aktas, Erdem, James Bottomley, Tom Lendacky,
Michael Roth
On January 19, 2023 5:54 PM, Gerd Hoffmann wrote:
>
> > +#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;
> > +
> > +#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()
>
> Why do you need this? For standard event types we should have those
> structs already defined somewhere in edk2 I think ...
>
FV_HANDOFF_TABLE_POINTERS2 is related to standard event type (EV_EFI_PLATFORM_FIRMWARE_BLOB2).
According to comment (https://github.com/tianocore/edk2/blob/master/MdePkg/Include/IndustryStandard/UefiTcgPlatform.h#L145-L156) we can see this event type uses the structure of UEFI_PLATFORM_FIRMWARE_BLOB2. It is not a data struct with fixed size. Instead its size depends on BlobDescriptionSize.
Tcg2Pei measures the FV image with the event type (EV_EFI_PLATFORM_FIRMWARE_BLOB2) and data struct (FV_HANDOFF_TABLE_POINTERS2).
Tdx measurement does the same measurement to the Configuration FV image.
@Yao, Jiewen Can we define FV_HANDOFF_TABLE_POINTERS2 and FV_HANDOFF_TABLE_POINTERS2 in MdePkg/Include/IndustryStandard/UefiTcgPlatform.h?
Thanks
Min
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH V2 04/10] OvmfPkg/IntelTdx: Implement other helper functions in SecTdxHelperLib
2023-01-20 7:40 ` Min Xu
@ 2023-01-20 8:10 ` Yao, Jiewen
2023-01-20 10:18 ` Gerd Hoffmann
0 siblings, 1 reply; 26+ messages in thread
From: Yao, Jiewen @ 2023-01-20 8:10 UTC (permalink / raw)
To: Xu, Min M, Gerd Hoffmann
Cc: devel@edk2.groups.io, Aktas, Erdem, James Bottomley, Tom Lendacky,
Michael Roth
> Can we define FV_HANDOFF_TABLE_POINTERS2 and FV_HANDOFF_TABLE_POINTERS2 in MdePkg/Include/IndustryStandard/UefiTcgPlatform.h?
[Jiewen] No. We cannot move to MdePkg.
TCG defines the field to be variable length. Something like below:
typedef struct {
UINT8 TableDescriptionSize;
UINT8 TableDescription[TableDescriptionSize];
UINT64 NumberOfTables;
EFI_CONFIGURATION_TABLE TableEntry[NumberOfTables];
} HANDOFF_TABLE_POINTERS2;
typedef struct {
UINT8 BlobDescriptionSize;
UINT8 BlobDescription[BlobDescriptionSize];
EFI_PHYSICAL_ADDRESS BlobBase;
UINT64 BlobLength;
} HANDOFF_TABLE_POINTERS2;
The implementation can choose its own length as they wish.
Thank you
Yao, Jiewen
> -----Original Message-----
> From: Xu, Min M <min.m.xu@intel.com>
> Sent: Friday, January 20, 2023 3:40 PM
> To: Gerd Hoffmann <kraxel@redhat.com>; Yao, Jiewen
> <jiewen.yao@intel.com>
> Cc: devel@edk2.groups.io; Aktas, Erdem <erdemaktas@google.com>; James
> Bottomley <jejb@linux.ibm.com>; Tom Lendacky
> <thomas.lendacky@amd.com>; Michael Roth <michael.roth@amd.com>
> Subject: RE: [PATCH V2 04/10] OvmfPkg/IntelTdx: Implement other helper
> functions in SecTdxHelperLib
>
> On January 19, 2023 5:54 PM, Gerd Hoffmann wrote:
> >
> > > +#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;
> > > +
> > > +#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()
> >
> > Why do you need this? For standard event types we should have those
> > structs already defined somewhere in edk2 I think ...
> >
> FV_HANDOFF_TABLE_POINTERS2 is related to standard event type
> (EV_EFI_PLATFORM_FIRMWARE_BLOB2).
> According to comment
> (https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Industry
> Standard/UefiTcgPlatform.h#L145-L156) we can see this event type uses the
> structure of UEFI_PLATFORM_FIRMWARE_BLOB2. It is not a data struct with
> fixed size. Instead its size depends on BlobDescriptionSize.
> Tcg2Pei measures the FV image with the event type
> (EV_EFI_PLATFORM_FIRMWARE_BLOB2) and data struct
> (FV_HANDOFF_TABLE_POINTERS2).
> Tdx measurement does the same measurement to the Configuration FV
> image.
> @Yao, Jiewen Can we define FV_HANDOFF_TABLE_POINTERS2 and
> FV_HANDOFF_TABLE_POINTERS2 in
> MdePkg/Include/IndustryStandard/UefiTcgPlatform.h?
>
> Thanks
> Min
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH V2 04/10] OvmfPkg/IntelTdx: Implement other helper functions in SecTdxHelperLib
2023-01-20 8:10 ` Yao, Jiewen
@ 2023-01-20 10:18 ` Gerd Hoffmann
2023-01-20 11:42 ` Min Xu
0 siblings, 1 reply; 26+ messages in thread
From: Gerd Hoffmann @ 2023-01-20 10:18 UTC (permalink / raw)
To: Yao, Jiewen
Cc: Xu, Min M, devel@edk2.groups.io, Aktas, Erdem, James Bottomley,
Tom Lendacky, Michael Roth
On Fri, Jan 20, 2023 at 08:10:45AM +0000, Yao, Jiewen wrote:
> > Can we define FV_HANDOFF_TABLE_POINTERS2 and FV_HANDOFF_TABLE_POINTERS2 in MdePkg/Include/IndustryStandard/UefiTcgPlatform.h?
>
> [Jiewen] No. We cannot move to MdePkg.
> TCG defines the field to be variable length. Something like below:
>
> typedef struct {
> UINT8 TableDescriptionSize;
> UINT8 TableDescription[TableDescriptionSize];
> UINT64 NumberOfTables;
> EFI_CONFIGURATION_TABLE TableEntry[NumberOfTables];
> } HANDOFF_TABLE_POINTERS2;
>
> typedef struct {
> UINT8 BlobDescriptionSize;
> UINT8 BlobDescription[BlobDescriptionSize];
> EFI_PHYSICAL_ADDRESS BlobBase;
> UINT64 BlobLength;
> } HANDOFF_TABLE_POINTERS2;
>
> The implementation can choose its own length as they wish.
Why doesn't follow TDX standard TCG practices here?
take care,
Gerd
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH V2 04/10] OvmfPkg/IntelTdx: Implement other helper functions in SecTdxHelperLib
2023-01-20 10:18 ` Gerd Hoffmann
@ 2023-01-20 11:42 ` Min Xu
2023-01-20 13:50 ` Gerd Hoffmann
0 siblings, 1 reply; 26+ messages in thread
From: Min Xu @ 2023-01-20 11:42 UTC (permalink / raw)
To: Gerd Hoffmann, Yao, Jiewen
Cc: devel@edk2.groups.io, Aktas, Erdem, James Bottomley, Tom Lendacky,
Michael Roth
On January 20, 2023 6:18 PM, Gerd Hoffmann wrote:
> On Fri, Jan 20, 2023 at 08:10:45AM +0000, Yao, Jiewen wrote:
> > > Can we define FV_HANDOFF_TABLE_POINTERS2 and
> FV_HANDOFF_TABLE_POINTERS2 in
> MdePkg/Include/IndustryStandard/UefiTcgPlatform.h?
> >
> > [Jiewen] No. We cannot move to MdePkg.
> > TCG defines the field to be variable length. Something like below:
> >
> > typedef struct {
> > UINT8 TableDescriptionSize;
> > UINT8 TableDescription[TableDescriptionSize];
> > UINT64 NumberOfTables;
> > EFI_CONFIGURATION_TABLE TableEntry[NumberOfTables];
> > } HANDOFF_TABLE_POINTERS2;
> >
> > typedef struct {
> > UINT8 BlobDescriptionSize;
> > UINT8 BlobDescription[BlobDescriptionSize];
> > EFI_PHYSICAL_ADDRESS BlobBase;
> > UINT64 BlobLength;
> > } HANDOFF_TABLE_POINTERS2;
> >
> > The implementation can choose its own length as they wish.
>
> Why doesn't follow TDX standard TCG practices here?
>
As Jiewen mentioned TCG defines the field to be variable length. The implementation can choose its own length. Below are some examples.
Tcg2Pei defines its FV_HANDOFF_TABLE_POINTERS2. (https://github.com/tianocore/edk2/blob/master/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c#L126-L136)
SmbiosMeasurementDxe defines its SMBIOS_HANDOFF_TABLE_POINTERS2 (https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Universal/SmbiosMeasurementDxe/SmbiosMeasurementDxe.c#L113-L123)
TcgEventLogRecordLib defines the PLATFORM_FIRMWARE_BLOB2_STRUCT and HANDOFF_TABLE_POINTERS2_STRUCT. https://github.com/tianocore/edk2/blob/master/SecurityPkg/Include/Library/TcgEventLogRecordLib.h#L14-L32
I think TDX follow the same practice above to define its own TDX_HANDOFF_TABLE_POINTERS2 and FV_HANDOFF_TABLE_POINTERS2. (FV_HANDOFF_TABLE_POINTERS2 happens to be same as the one in Tcg2Pei.) To make the definition more clear, TDX can define the name as CFV_HANDOFF_TABLE_POINTERS2.
@Gerd, Hoffmann what's your thought?
Thanks
Min
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH V2 04/10] OvmfPkg/IntelTdx: Implement other helper functions in SecTdxHelperLib
2023-01-20 11:42 ` Min Xu
@ 2023-01-20 13:50 ` Gerd Hoffmann
2023-01-21 0:02 ` Min Xu
0 siblings, 1 reply; 26+ messages in thread
From: Gerd Hoffmann @ 2023-01-20 13:50 UTC (permalink / raw)
To: Xu, Min M
Cc: Yao, Jiewen, devel@edk2.groups.io, Aktas, Erdem, James Bottomley,
Tom Lendacky, Michael Roth
> > > [Jiewen] No. We cannot move to MdePkg.
> > > TCG defines the field to be variable length. Something like below:
> > >
> > > typedef struct {
> > > UINT8 TableDescriptionSize;
> > > UINT8 TableDescription[TableDescriptionSize];
> > > UINT64 NumberOfTables;
> > > EFI_CONFIGURATION_TABLE TableEntry[NumberOfTables];
> > > } HANDOFF_TABLE_POINTERS2;
> > >
> > > typedef struct {
> > > UINT8 BlobDescriptionSize;
> > > UINT8 BlobDescription[BlobDescriptionSize];
> > > EFI_PHYSICAL_ADDRESS BlobBase;
> > > UINT64 BlobLength;
> > > } HANDOFF_TABLE_POINTERS2;
> > >
> > > The implementation can choose its own length as they wish.
> >
> > Why doesn't follow TDX standard TCG practices here?
> >
> As Jiewen mentioned TCG defines the field to be variable length. The implementation can choose its own length. Below are some examples.
> Tcg2Pei defines its FV_HANDOFF_TABLE_POINTERS2. (https://github.com/tianocore/edk2/blob/master/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c#L126-L136)
> SmbiosMeasurementDxe defines its SMBIOS_HANDOFF_TABLE_POINTERS2 (https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Universal/SmbiosMeasurementDxe/SmbiosMeasurementDxe.c#L113-L123)
> TcgEventLogRecordLib defines the PLATFORM_FIRMWARE_BLOB2_STRUCT and HANDOFF_TABLE_POINTERS2_STRUCT. https://github.com/tianocore/edk2/blob/master/SecurityPkg/Include/Library/TcgEventLogRecordLib.h#L14-L32
> I think TDX follow the same practice above to define its own
> TDX_HANDOFF_TABLE_POINTERS2 and FV_HANDOFF_TABLE_POINTERS2.
> (FV_HANDOFF_TABLE_POINTERS2 happens to be same as the one in Tcg2Pei.)
Ok, that makes sense. The TdHob is tdx-specific, measuring a firmware
volume is not. I'm still wondering why the structs for standard events
(like the firmware volume) are not in some shared header file ...
take care,
Gerd
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH V2 04/10] OvmfPkg/IntelTdx: Implement other helper functions in SecTdxHelperLib
2023-01-20 13:50 ` Gerd Hoffmann
@ 2023-01-21 0:02 ` Min Xu
0 siblings, 0 replies; 26+ messages in thread
From: Min Xu @ 2023-01-21 0:02 UTC (permalink / raw)
To: Gerd Hoffmann
Cc: Yao, Jiewen, devel@edk2.groups.io, Aktas, Erdem, James Bottomley,
Tom Lendacky, Michael Roth
On January 20, 2023 9:51 PM, Gerd Hoffmann wrote:
>
> > > > [Jiewen] No. We cannot move to MdePkg.
> > > > TCG defines the field to be variable length. Something like below:
> > > >
> > > > typedef struct {
> > > > UINT8 TableDescriptionSize;
> > > > UINT8 TableDescription[TableDescriptionSize];
> > > > UINT64 NumberOfTables;
> > > > EFI_CONFIGURATION_TABLE TableEntry[NumberOfTables];
> > > > } HANDOFF_TABLE_POINTERS2;
> > > >
> > > > typedef struct {
> > > > UINT8 BlobDescriptionSize;
> > > > UINT8 BlobDescription[BlobDescriptionSize];
> > > > EFI_PHYSICAL_ADDRESS BlobBase;
> > > > UINT64 BlobLength;
> > > > } HANDOFF_TABLE_POINTERS2;
> > > >
> > > > The implementation can choose its own length as they wish.
> > >
> > > Why doesn't follow TDX standard TCG practices here?
> > >
> > As Jiewen mentioned TCG defines the field to be variable length. The
> implementation can choose its own length. Below are some examples.
> > Tcg2Pei defines its FV_HANDOFF_TABLE_POINTERS2.
> > (https://github.com/tianocore/edk2/blob/master/SecurityPkg/Tcg/Tcg2Pei
> > /Tcg2Pei.c#L126-L136) SmbiosMeasurementDxe defines its
> > SMBIOS_HANDOFF_TABLE_POINTERS2
> >
> (https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Universal/
> > SmbiosMeasurementDxe/SmbiosMeasurementDxe.c#L113-L123)
> > TcgEventLogRecordLib defines the PLATFORM_FIRMWARE_BLOB2_STRUCT
> and
> > HANDOFF_TABLE_POINTERS2_STRUCT.
> > https://github.com/tianocore/edk2/blob/master/SecurityPkg/Include/Libr
> > ary/TcgEventLogRecordLib.h#L14-L32
>
> > I think TDX follow the same practice above to define its own
> > TDX_HANDOFF_TABLE_POINTERS2 and FV_HANDOFF_TABLE_POINTERS2.
> > (FV_HANDOFF_TABLE_POINTERS2 happens to be same as the one in
> Tcg2Pei.)
>
> Ok, that makes sense. The TdHob is tdx-specific, measuring a firmware
> volume is not. I'm still wondering why the structs for standard events (like
> the firmware volume) are not in some shared header file ...
>
Hi, Gerd
Actually I tried to find some common header file to define the events (the firmware volume). But it seems there is no such header file. Let me check the code again and see if there is such header file.
Thanks
Min
^ permalink raw reply [flat|nested] 26+ messages in thread
end of thread, other threads:[~2023-01-21 0:02 UTC | newest]
Thread overview: 26+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-01-19 3:28 [PATCH V2 00/10] Enable Tdx measurement in OvmfPkgX64 Min Xu
2023-01-19 3:28 ` [PATCH V2 01/10] OvmfPkg: Add Tdx measurement data structure in WorkArea Min Xu
2023-01-19 9:33 ` Gerd Hoffmann
2023-01-19 3:28 ` [PATCH V2 02/10] OvmfPkg/IntelTdx: Add TdxHelperLibNull Min Xu
2023-01-19 9:33 ` Gerd Hoffmann
2023-01-19 3:28 ` [PATCH V2 03/10] OvmfPkg/IntelTdx: Add SecTdxHelperLib Min Xu
2023-01-19 9:33 ` Gerd Hoffmann
2023-01-19 3:28 ` [PATCH V2 04/10] OvmfPkg/IntelTdx: Implement other helper functions in SecTdxHelperLib Min Xu
2023-01-19 9:54 ` Gerd Hoffmann
2023-01-19 23:44 ` Min Xu
2023-01-20 7:40 ` Min Xu
2023-01-20 8:10 ` Yao, Jiewen
2023-01-20 10:18 ` Gerd Hoffmann
2023-01-20 11:42 ` Min Xu
2023-01-20 13:50 ` Gerd Hoffmann
2023-01-21 0:02 ` Min Xu
2023-01-19 3:28 ` [PATCH V2 05/10] OvmfPkg/IntelTdx: Add PeiTdxHelperLib Min Xu
2023-01-19 9:54 ` Gerd Hoffmann
2023-01-19 3:28 ` [PATCH V2 06/10] OvmfPkg/PeilessStartupLib: Build GuidHob for Tdx measurements Min Xu
2023-01-19 9:57 ` Gerd Hoffmann
2023-01-19 3:28 ` [PATCH V2 07/10] OvmfPkg/IntelTdx: Update tdx measurement in SEC phase Min Xu
2023-01-19 9:57 ` Gerd Hoffmann
2023-01-19 3:28 ` [PATCH V2 08/10] OvmfPkg: Enable Tdx measurement in OvmfPkgX64 Min Xu
2023-01-19 3:28 ` [PATCH V2 09/10] OvmfPkg/PlatformPei: Build GuidHob for Tdx measurement Min Xu
2023-01-19 9:58 ` Gerd Hoffmann
2023-01-19 3:28 ` [PATCH V2 10/10] OvmfPkg/PlatformInitLib: Delete the ProcessTdxHobList() Min Xu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox