From: "Min Xu" <min.m.xu@intel.com>
To: devel@edk2.groups.io
Cc: Min M Xu <min.m.xu@intel.com>,
Erdem Aktas <erdemaktas@google.com>,
James Bottomley <jejb@linux.ibm.com>,
Jiewen Yao <jiewen.yao@intel.com>,
Gerd Hoffmann <kraxel@redhat.com>,
Tom Lendacky <thomas.lendacky@amd.com>,
Michael Roth <michael.roth@amd.com>
Subject: [PATCH V5 07/13] OvmfPkg: Refactor ProcessHobList
Date: Sat, 28 Jan 2023 21:58:36 +0800 [thread overview]
Message-ID: <20230128135842.980-8-min.m.xu@intel.com> (raw)
In-Reply-To: <20230128135842.980-1-min.m.xu@intel.com>
From: Min M Xu <min.m.xu@intel.com>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4243
ProcessHobList once was implemented in PlatformInitLib and it walks thru
TdHob list and accept un-accepted memories.
This patch moves the codes to SecTdxHelperLib and rename ProcessHobList
as TdxHelperProcessTdHob
After TdxHelperProcessTdHob is introduced, below changes are applied:
- Call TdxHelperProcessTdHob instead of ProcessHobList in SecMain.c
(in both OvmfPkgX64/Sec and IntelTdx/Sec).
- Delete the duplicated codes in PlatformInitLib
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Michael Roth <michael.roth@amd.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
---
OvmfPkg/Include/Library/PlatformInitLib.h | 17 -
OvmfPkg/IntelTdx/Sec/SecMain.c | 4 +-
OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelper.c | 754 ++++++++++++++++-
OvmfPkg/Library/PlatformInitLib/IntelTdx.c | 768 ------------------
.../Library/PlatformInitLib/IntelTdxNull.c | 20 -
.../PlatformInitLib/PlatformInitLib.inf | 1 -
OvmfPkg/OvmfPkgX64.dsc | 3 +-
OvmfPkg/Sec/SecMain.c | 4 +-
8 files changed, 759 insertions(+), 812 deletions(-)
diff --git a/OvmfPkg/Include/Library/PlatformInitLib.h b/OvmfPkg/Include/Library/PlatformInitLib.h
index 051b31191194..57b18b94d9b8 100644
--- a/OvmfPkg/Include/Library/PlatformInitLib.h
+++ b/OvmfPkg/Include/Library/PlatformInitLib.h
@@ -210,23 +210,6 @@ PlatformMaxCpuCountInitialization (
IN OUT EFI_HOB_PLATFORM_INFO *PlatformInfoHob
);
-/**
- In Tdx guest, some information need to be passed from host VMM to guest
- firmware. For example, the memory resource, etc. These information are
- prepared by host VMM and put in HobList which is described in TdxMetadata.
-
- Information in HobList is treated as external input. From the security
- perspective before it is consumed, it should be validated.
-
- @retval EFI_SUCCESS Successfully process the hoblist
- @retval Others Other error as indicated
-**/
-EFI_STATUS
-EFIAPI
-ProcessTdxHobList (
- VOID
- );
-
/**
In Tdx guest, the system memory is passed in TdHob by host VMM. So
the major task of PlatformTdxPublishRamRegions is to walk thru the
diff --git a/OvmfPkg/IntelTdx/Sec/SecMain.c b/OvmfPkg/IntelTdx/Sec/SecMain.c
index ab01ec9ab19c..41bd5c66ba29 100644
--- a/OvmfPkg/IntelTdx/Sec/SecMain.c
+++ b/OvmfPkg/IntelTdx/Sec/SecMain.c
@@ -24,7 +24,7 @@
#include <Library/LocalApicLib.h>
#include <Library/CpuExceptionHandlerLib.h>
#include <IndustryStandard/Tdx.h>
-#include <Library/PlatformInitLib.h>
+#include <Library/TdxHelperLib.h>
#include <Library/CcProbeLib.h>
#include <Library/PeilessStartupLib.h>
@@ -67,7 +67,7 @@ SecCoreStartupWithStack (
// first so that the memory is accepted. Otherwise access to the unaccepted
// memory will trigger tripple fault.
//
- if (ProcessTdxHobList () != EFI_SUCCESS) {
+ if (TdxHelperProcessTdHob () != EFI_SUCCESS) {
CpuDeadLoop ();
}
}
diff --git a/OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelper.c b/OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelper.c
index 1929093f9110..3372cee2f720 100644
--- a/OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelper.c
+++ b/OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelper.c
@@ -17,11 +17,20 @@
#include <IndustryStandard/IntelTdx.h>
#include <IndustryStandard/Tpm20.h>
#include <Library/TdxLib.h>
+#include <Library/TdxMailboxLib.h>
+#include <Library/SynchronizationLib.h>
#include <Pi/PrePiHob.h>
#include <WorkArea.h>
#include <ConfidentialComputingGuestAttr.h>
#include <Library/TdxHelperLib.h>
+#define ALIGNED_2MB_MASK 0x1fffff
+#define MEGABYTE_SHIFT 20
+
+#define ACCEPT_CHUNK_SIZE SIZE_32MB
+#define AP_STACK_SIZE SIZE_16KB
+#define APS_STACK_SIZE(CpusNum) (ALIGN_VALUE(CpusNum*AP_STACK_SIZE, SIZE_2MB))
+
/**
Build the GuidHob for tdx measurements which were done in SEC phase.
The measurement values are stored in WorkArea.
@@ -34,6 +43,720 @@ InternalBuildGuidHobForTdxMeasurement (
VOID
);
+/**
+ This function will be called to accept pages. Only BSP accepts pages.
+
+ TDCALL(ACCEPT_PAGE) supports the accept page size of 4k and 2M. To
+ simplify the implementation, the Memory to be accpeted is splitted
+ into 3 parts:
+ ----------------- <-- StartAddress1 (not 2M aligned)
+ | part 1 | Length1 < 2M
+ |---------------| <-- StartAddress2 (2M aligned)
+ | | Length2 = Integer multiples of 2M
+ | part 2 |
+ | |
+ |---------------| <-- StartAddress3
+ | part 3 | Length3 < 2M
+ |---------------|
+
+ @param[in] PhysicalAddress Start physical adress
+ @param[in] PhysicalEnd End physical address
+
+ @retval EFI_SUCCESS Accept memory successfully
+ @retval Others Other errors as indicated
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+BspAcceptMemoryResourceRange (
+ IN EFI_PHYSICAL_ADDRESS PhysicalAddress,
+ IN EFI_PHYSICAL_ADDRESS PhysicalEnd
+ )
+{
+ EFI_STATUS Status;
+ UINT32 AcceptPageSize;
+ UINT64 StartAddress1;
+ UINT64 StartAddress2;
+ UINT64 StartAddress3;
+ UINT64 TotalLength;
+ UINT64 Length1;
+ UINT64 Length2;
+ UINT64 Length3;
+ UINT64 Pages;
+
+ AcceptPageSize = FixedPcdGet32 (PcdTdxAcceptPageSize);
+ TotalLength = PhysicalEnd - PhysicalAddress;
+ StartAddress1 = 0;
+ StartAddress2 = 0;
+ StartAddress3 = 0;
+ Length1 = 0;
+ Length2 = 0;
+ Length3 = 0;
+
+ if (TotalLength == 0) {
+ return EFI_SUCCESS;
+ }
+
+ if (ALIGN_VALUE (PhysicalAddress, SIZE_2MB) != PhysicalAddress) {
+ StartAddress1 = PhysicalAddress;
+ Length1 = ALIGN_VALUE (PhysicalAddress, SIZE_2MB) - PhysicalAddress;
+ if (Length1 >= TotalLength) {
+ Length1 = TotalLength;
+ }
+
+ PhysicalAddress += Length1;
+ TotalLength -= Length1;
+ }
+
+ if (TotalLength > SIZE_2MB) {
+ StartAddress2 = PhysicalAddress;
+ Length2 = TotalLength & ~(UINT64)ALIGNED_2MB_MASK;
+ PhysicalAddress += Length2;
+ TotalLength -= Length2;
+ }
+
+ if (TotalLength) {
+ StartAddress3 = PhysicalAddress;
+ Length3 = TotalLength;
+ }
+
+ Status = EFI_SUCCESS;
+ if (Length1 > 0) {
+ Pages = Length1 / SIZE_4KB;
+ Status = TdAcceptPages (StartAddress1, Pages, SIZE_4KB);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ if (Length2 > 0) {
+ Pages = Length2 / AcceptPageSize;
+ Status = TdAcceptPages (StartAddress2, Pages, AcceptPageSize);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ if (Length3 > 0) {
+ Pages = Length3 / SIZE_4KB;
+ Status = TdAcceptPages (StartAddress3, Pages, SIZE_4KB);
+ ASSERT (!EFI_ERROR (Status));
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ return Status;
+}
+
+/**
+ * This function is called by BSP and APs to accept memory.
+ * Note:
+ * The input PhysicalStart/PhysicalEnd indicates the whole memory region
+ * to be accepted. BSP or AP only accepts one piece in the whole memory region.
+ *
+ * @param CpuIndex vCPU index
+ * @param CpusNum Total vCPU number of a Tdx guest
+ * @param PhysicalStart Start address of a memory region which is to be accepted
+ * @param PhysicalEnd End address of a memory region which is to be accepted
+ *
+ * @retval EFI_SUCCESS Successfully accept the memory
+ * @retval Other Other errors as indicated
+ */
+STATIC
+EFI_STATUS
+EFIAPI
+BspApAcceptMemoryResourceRange (
+ UINT32 CpuIndex,
+ UINT32 CpusNum,
+ EFI_PHYSICAL_ADDRESS PhysicalStart,
+ EFI_PHYSICAL_ADDRESS PhysicalEnd
+ )
+{
+ UINT64 Status;
+ UINT64 Pages;
+ UINT64 Stride;
+ UINT64 AcceptPageSize;
+ EFI_PHYSICAL_ADDRESS PhysicalAddress;
+
+ AcceptPageSize = (UINT64)(UINTN)FixedPcdGet32 (PcdTdxAcceptPageSize);
+
+ Status = EFI_SUCCESS;
+ Stride = (UINTN)CpusNum * ACCEPT_CHUNK_SIZE;
+ PhysicalAddress = PhysicalStart + ACCEPT_CHUNK_SIZE * (UINTN)CpuIndex;
+
+ while (!EFI_ERROR (Status) && PhysicalAddress < PhysicalEnd) {
+ Pages = MIN (ACCEPT_CHUNK_SIZE, PhysicalEnd - PhysicalAddress) / AcceptPageSize;
+ Status = TdAcceptPages (PhysicalAddress, Pages, (UINT32)(UINTN)AcceptPageSize);
+ ASSERT (!EFI_ERROR (Status));
+ PhysicalAddress += Stride;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ * This function is called by APs to accept memory.
+ *
+ * @param CpuIndex vCPU index of an AP
+ * @param PhysicalStart Start address of a memory region which is to be accepted
+ * @param PhysicalEnd End address of a memory region which is to be accepted
+ *
+ * @retval EFI_SUCCESS Successfully accept the memory
+ * @retval Others Other errors as indicated
+ */
+STATIC
+EFI_STATUS
+EFIAPI
+ApAcceptMemoryResourceRange (
+ UINT32 CpuIndex,
+ EFI_PHYSICAL_ADDRESS PhysicalStart,
+ EFI_PHYSICAL_ADDRESS PhysicalEnd
+ )
+{
+ UINT64 Status;
+ TD_RETURN_DATA TdReturnData;
+
+ Status = TdCall (TDCALL_TDINFO, 0, 0, 0, &TdReturnData);
+ if (Status != TDX_EXIT_REASON_SUCCESS) {
+ ASSERT (FALSE);
+ return EFI_ABORTED;
+ }
+
+ if ((CpuIndex == 0) || (CpuIndex >= TdReturnData.TdInfo.NumVcpus)) {
+ ASSERT (FALSE);
+ return EFI_ABORTED;
+ }
+
+ return BspApAcceptMemoryResourceRange (CpuIndex, TdReturnData.TdInfo.NumVcpus, PhysicalStart, PhysicalEnd);
+}
+
+/**
+ * This function is called by BSP. It coordinates BSP/APs to accept memory together.
+ *
+ * @param PhysicalStart Start address of a memory region which is to be accepted
+ * @param PhysicalEnd End address of a memory region which is to be accepted
+ * @param APsStackAddress APs stack address
+ * @param CpusNum Total vCPU number of the Tdx guest
+ *
+ * @retval EFI_SUCCESS Successfully accept the memory
+ * @retval Others Other errors as indicated
+ */
+STATIC
+EFI_STATUS
+EFIAPI
+MpAcceptMemoryResourceRange (
+ IN EFI_PHYSICAL_ADDRESS PhysicalStart,
+ IN EFI_PHYSICAL_ADDRESS PhysicalEnd,
+ IN OUT EFI_PHYSICAL_ADDRESS APsStackAddress,
+ IN UINT32 CpusNum
+ )
+{
+ UINT64 Length;
+ EFI_STATUS Status;
+
+ Length = PhysicalEnd - PhysicalStart;
+
+ DEBUG ((DEBUG_INFO, "MpAccept : 0x%llx - 0x%llx (0x%llx)\n", PhysicalStart, PhysicalEnd, Length));
+
+ if (Length == 0) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // The start address is not 2M aligned. BSP first accept the part which is not 2M aligned.
+ //
+ if (ALIGN_VALUE (PhysicalStart, SIZE_2MB) != PhysicalStart) {
+ Length = MIN (ALIGN_VALUE (PhysicalStart, SIZE_2MB) - PhysicalStart, Length);
+ Status = BspAcceptMemoryResourceRange (PhysicalStart, PhysicalStart + Length);
+ ASSERT (Status == EFI_SUCCESS);
+
+ PhysicalStart += Length;
+ Length = PhysicalEnd - PhysicalStart;
+ }
+
+ if (Length == 0) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // BSP will accept the memory by itself if the memory is not big enough compared with a chunk.
+ //
+ if (Length <= ACCEPT_CHUNK_SIZE) {
+ return BspAcceptMemoryResourceRange (PhysicalStart, PhysicalEnd);
+ }
+
+ //
+ // Now APs are asked to accept the memory together.
+ //
+ MpSerializeStart ();
+
+ MpSendWakeupCommand (
+ MpProtectedModeWakeupCommandAcceptPages,
+ (UINT64)(UINTN)ApAcceptMemoryResourceRange,
+ PhysicalStart,
+ PhysicalEnd,
+ APsStackAddress,
+ AP_STACK_SIZE
+ );
+
+ //
+ // Now BSP does its job.
+ //
+ BspApAcceptMemoryResourceRange (0, CpusNum, PhysicalStart, PhysicalEnd);
+
+ MpSerializeEnd ();
+
+ return EFI_SUCCESS;
+}
+
+/**
+ BSP accept a small piece of memory which will be used as APs stack.
+
+ @param[in] VmmHobList The Hoblist pass the firmware
+ @param[in] APsStackSize APs stack size
+ @param[out] PhysicalAddressEnd The physical end address of accepted memory in phase-1
+
+ @retval EFI_SUCCESS Process the HobList successfully
+ @retval Others Other errors as indicated
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+AcceptMemoryForAPsStack (
+ IN CONST VOID *VmmHobList,
+ IN UINT32 APsStackSize,
+ OUT EFI_PHYSICAL_ADDRESS *PhysicalAddressEnd
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_HOB_POINTERS Hob;
+ EFI_PHYSICAL_ADDRESS PhysicalEnd;
+ EFI_PHYSICAL_ADDRESS PhysicalStart;
+ UINT64 ResourceLength;
+ BOOLEAN MemoryRegionFound;
+
+ ASSERT (VmmHobList != NULL);
+
+ Status = EFI_SUCCESS;
+ Hob.Raw = (UINT8 *)VmmHobList;
+ MemoryRegionFound = FALSE;
+
+ DEBUG ((DEBUG_INFO, "AcceptMemoryForAPsStack with APsStackSize=0x%x\n", APsStackSize));
+
+ //
+ // Parse the HOB list until end of list or matching type is found.
+ //
+ while (!END_OF_HOB_LIST (Hob) && !MemoryRegionFound) {
+ if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
+ DEBUG ((DEBUG_INFO, "\nResourceType: 0x%x\n", Hob.ResourceDescriptor->ResourceType));
+
+ if (Hob.ResourceDescriptor->ResourceType == BZ3937_EFI_RESOURCE_MEMORY_UNACCEPTED) {
+ ResourceLength = Hob.ResourceDescriptor->ResourceLength;
+ PhysicalStart = Hob.ResourceDescriptor->PhysicalStart;
+ PhysicalEnd = PhysicalStart + ResourceLength;
+
+ DEBUG ((DEBUG_INFO, "ResourceAttribute: 0x%x\n", Hob.ResourceDescriptor->ResourceAttribute));
+ DEBUG ((DEBUG_INFO, "PhysicalStart: 0x%llx\n", PhysicalStart));
+ DEBUG ((DEBUG_INFO, "ResourceLength: 0x%llx\n", ResourceLength));
+ DEBUG ((DEBUG_INFO, "Owner: %g\n\n", &Hob.ResourceDescriptor->Owner));
+
+ if (ResourceLength >= APsStackSize) {
+ MemoryRegionFound = TRUE;
+ if (ResourceLength > ACCEPT_CHUNK_SIZE) {
+ PhysicalEnd = Hob.ResourceDescriptor->PhysicalStart + APsStackSize;
+ }
+ }
+
+ Status = BspAcceptMemoryResourceRange (
+ Hob.ResourceDescriptor->PhysicalStart,
+ PhysicalEnd
+ );
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+ }
+ }
+
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ }
+
+ ASSERT (MemoryRegionFound);
+ *PhysicalAddressEnd = PhysicalEnd;
+
+ return Status;
+}
+
+/**
+ BSP and APs work togeter to accept memory which is under the address of 4G.
+
+ @param[in] VmmHobList The Hoblist pass the firmware
+ @param[in] CpusNum Number of vCPUs
+ @param[in] APsStackStartAddres Start address of APs stack
+ @param[in] PhysicalAddressStart Start physical address which to be accepted
+
+ @retval EFI_SUCCESS Process the HobList successfully
+ @retval Others Other errors as indicated
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+AcceptMemory (
+ IN CONST VOID *VmmHobList,
+ IN UINT32 CpusNum,
+ IN EFI_PHYSICAL_ADDRESS APsStackStartAddress,
+ IN EFI_PHYSICAL_ADDRESS PhysicalAddressStart
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_HOB_POINTERS Hob;
+ EFI_PHYSICAL_ADDRESS PhysicalStart;
+ EFI_PHYSICAL_ADDRESS PhysicalEnd;
+ EFI_PHYSICAL_ADDRESS AcceptMemoryEndAddress;
+
+ Status = EFI_SUCCESS;
+ AcceptMemoryEndAddress = BASE_4GB;
+
+ ASSERT (VmmHobList != NULL);
+ Hob.Raw = (UINT8 *)VmmHobList;
+
+ DEBUG ((DEBUG_INFO, "AcceptMemory under address of 4G\n"));
+
+ //
+ // Parse the HOB list until end of list or matching type is found.
+ //
+ while (!END_OF_HOB_LIST (Hob)) {
+ if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
+ if (Hob.ResourceDescriptor->ResourceType == BZ3937_EFI_RESOURCE_MEMORY_UNACCEPTED) {
+ PhysicalStart = Hob.ResourceDescriptor->PhysicalStart;
+ PhysicalEnd = PhysicalStart + Hob.ResourceDescriptor->ResourceLength;
+
+ if (PhysicalEnd <= PhysicalAddressStart) {
+ // this memory region has been accepted. Skipped it.
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ continue;
+ }
+
+ if (PhysicalStart >= AcceptMemoryEndAddress) {
+ // this memory region is not to be accepted. And we're done.
+ break;
+ }
+
+ if (PhysicalStart >= PhysicalAddressStart) {
+ // this memory region has not been acceted.
+ } else if ((PhysicalStart < PhysicalAddressStart) && (PhysicalEnd > PhysicalAddressStart)) {
+ // part of the memory region has been accepted.
+ PhysicalStart = PhysicalAddressStart;
+ }
+
+ // then compare the PhysicalEnd with AcceptMemoryEndAddress
+ if (PhysicalEnd >= AcceptMemoryEndAddress) {
+ PhysicalEnd = AcceptMemoryEndAddress;
+ }
+
+ DEBUG ((DEBUG_INFO, "ResourceAttribute: 0x%x\n", Hob.ResourceDescriptor->ResourceAttribute));
+ DEBUG ((DEBUG_INFO, "PhysicalStart: 0x%llx\n", Hob.ResourceDescriptor->PhysicalStart));
+ DEBUG ((DEBUG_INFO, "ResourceLength: 0x%llx\n", Hob.ResourceDescriptor->ResourceLength));
+ DEBUG ((DEBUG_INFO, "Owner: %g\n\n", &Hob.ResourceDescriptor->Owner));
+
+ // Now we're ready to accept memory [PhysicalStart, PhysicalEnd)
+ if (CpusNum == 1) {
+ Status = BspAcceptMemoryResourceRange (PhysicalStart, PhysicalEnd);
+ } else {
+ Status = MpAcceptMemoryResourceRange (
+ PhysicalStart,
+ PhysicalEnd,
+ APsStackStartAddress,
+ CpusNum
+ );
+ }
+
+ if (EFI_ERROR (Status)) {
+ ASSERT (FALSE);
+ break;
+ }
+
+ if (PhysicalEnd == AcceptMemoryEndAddress) {
+ break;
+ }
+ }
+ }
+
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ }
+
+ return Status;
+}
+
+/**
+ Check the value whether in the valid list.
+
+ @param[in] Value A value
+ @param[in] ValidList A pointer to valid list
+ @param[in] ValidListLength Length of valid list
+
+ @retval TRUE The value is in valid list.
+ @retval FALSE The value is not in valid list.
+
+**/
+STATIC
+BOOLEAN
+EFIAPI
+IsInValidList (
+ IN UINT32 Value,
+ IN UINT32 *ValidList,
+ IN UINT32 ValidListLength
+ )
+{
+ UINT32 index;
+
+ if (ValidList == NULL) {
+ return FALSE;
+ }
+
+ for (index = 0; index < ValidListLength; index++) {
+ if (ValidList[index] == Value) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/**
+ Check the integrity of VMM Hob List.
+
+ @param[in] VmmHobList A pointer to Hob List
+
+ @retval TRUE The Hob List is valid.
+ @retval FALSE The Hob List is invalid.
+
+**/
+STATIC
+BOOLEAN
+EFIAPI
+ValidateHobList (
+ IN CONST VOID *VmmHobList
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+ UINT32 EFI_BOOT_MODE_LIST[] = {
+ BOOT_WITH_FULL_CONFIGURATION,
+ BOOT_WITH_MINIMAL_CONFIGURATION,
+ BOOT_ASSUMING_NO_CONFIGURATION_CHANGES,
+ BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS,
+ BOOT_WITH_DEFAULT_SETTINGS,
+ BOOT_ON_S4_RESUME,
+ BOOT_ON_S5_RESUME,
+ BOOT_WITH_MFG_MODE_SETTINGS,
+ BOOT_ON_S2_RESUME,
+ BOOT_ON_S3_RESUME,
+ BOOT_ON_FLASH_UPDATE,
+ BOOT_IN_RECOVERY_MODE
+ };
+
+ UINT32 EFI_RESOURCE_TYPE_LIST[] = {
+ EFI_RESOURCE_SYSTEM_MEMORY,
+ EFI_RESOURCE_MEMORY_MAPPED_IO,
+ EFI_RESOURCE_IO,
+ EFI_RESOURCE_FIRMWARE_DEVICE,
+ EFI_RESOURCE_MEMORY_MAPPED_IO_PORT,
+ EFI_RESOURCE_MEMORY_RESERVED,
+ EFI_RESOURCE_IO_RESERVED,
+ BZ3937_EFI_RESOURCE_MEMORY_UNACCEPTED
+ };
+
+ if (VmmHobList == NULL) {
+ DEBUG ((DEBUG_ERROR, "HOB: HOB data pointer is NULL\n"));
+ return FALSE;
+ }
+
+ Hob.Raw = (UINT8 *)VmmHobList;
+
+ //
+ // Parse the HOB list until end of list or matching type is found.
+ //
+ while (!END_OF_HOB_LIST (Hob)) {
+ if (Hob.Header->Reserved != (UINT32)0) {
+ DEBUG ((DEBUG_ERROR, "HOB: Hob header Reserved filed should be zero\n"));
+ return FALSE;
+ }
+
+ if (Hob.Header->HobLength == 0) {
+ DEBUG ((DEBUG_ERROR, "HOB: Hob header LEANGTH should not be zero\n"));
+ return FALSE;
+ }
+
+ switch (Hob.Header->HobType) {
+ case EFI_HOB_TYPE_HANDOFF:
+ if (Hob.Header->HobLength != sizeof (EFI_HOB_HANDOFF_INFO_TABLE)) {
+ DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_HANDOFF));
+ return FALSE;
+ }
+
+ if (IsInValidList (Hob.HandoffInformationTable->BootMode, EFI_BOOT_MODE_LIST, ARRAY_SIZE (EFI_BOOT_MODE_LIST)) == FALSE) {
+ DEBUG ((DEBUG_ERROR, "HOB: Unknow HandoffInformationTable BootMode type. Type: 0x%08x\n", Hob.HandoffInformationTable->BootMode));
+ return FALSE;
+ }
+
+ if ((Hob.HandoffInformationTable->EfiFreeMemoryTop % 4096) != 0) {
+ DEBUG ((DEBUG_ERROR, "HOB: HandoffInformationTable EfiFreeMemoryTop address must be 4-KB aligned to meet page restrictions of UEFI.\
+ Address: 0x%016lx\n", Hob.HandoffInformationTable->EfiFreeMemoryTop));
+ return FALSE;
+ }
+
+ break;
+
+ case EFI_HOB_TYPE_RESOURCE_DESCRIPTOR:
+ if (Hob.Header->HobLength != sizeof (EFI_HOB_RESOURCE_DESCRIPTOR)) {
+ DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_RESOURCE_DESCRIPTOR));
+ return FALSE;
+ }
+
+ if (IsInValidList (Hob.ResourceDescriptor->ResourceType, EFI_RESOURCE_TYPE_LIST, ARRAY_SIZE (EFI_RESOURCE_TYPE_LIST)) == FALSE) {
+ DEBUG ((DEBUG_ERROR, "HOB: Unknow ResourceDescriptor ResourceType type. Type: 0x%08x\n", Hob.ResourceDescriptor->ResourceType));
+ return FALSE;
+ }
+
+ if ((Hob.ResourceDescriptor->ResourceAttribute & (~(EFI_RESOURCE_ATTRIBUTE_PRESENT |
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+ EFI_RESOURCE_ATTRIBUTE_TESTED |
+ EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED |
+ EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED |
+ EFI_RESOURCE_ATTRIBUTE_PERSISTENT |
+ EFI_RESOURCE_ATTRIBUTE_SINGLE_BIT_ECC |
+ EFI_RESOURCE_ATTRIBUTE_MULTIPLE_BIT_ECC |
+ EFI_RESOURCE_ATTRIBUTE_ECC_RESERVED_1 |
+ EFI_RESOURCE_ATTRIBUTE_ECC_RESERVED_2 |
+ EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
+ EFI_RESOURCE_ATTRIBUTE_16_BIT_IO |
+ EFI_RESOURCE_ATTRIBUTE_32_BIT_IO |
+ EFI_RESOURCE_ATTRIBUTE_64_BIT_IO |
+ EFI_RESOURCE_ATTRIBUTE_UNCACHED_EXPORTED |
+ EFI_RESOURCE_ATTRIBUTE_READ_PROTECTABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTABLE |
+ EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTABLE |
+ EFI_RESOURCE_ATTRIBUTE_PERSISTABLE |
+ EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED |
+ EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTABLE |
+ EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE))) != 0)
+ {
+ DEBUG ((DEBUG_ERROR, "HOB: Unknow ResourceDescriptor ResourceAttribute type. Type: 0x%08x\n", Hob.ResourceDescriptor->ResourceAttribute));
+ return FALSE;
+ }
+
+ break;
+
+ // EFI_HOB_GUID_TYPE is variable length data, so skip check
+ case EFI_HOB_TYPE_GUID_EXTENSION:
+ break;
+
+ case EFI_HOB_TYPE_FV:
+ if (Hob.Header->HobLength != sizeof (EFI_HOB_FIRMWARE_VOLUME)) {
+ DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_FV));
+ return FALSE;
+ }
+
+ break;
+
+ case EFI_HOB_TYPE_FV2:
+ if (Hob.Header->HobLength != sizeof (EFI_HOB_FIRMWARE_VOLUME2)) {
+ DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_FV2));
+ return FALSE;
+ }
+
+ break;
+
+ case EFI_HOB_TYPE_FV3:
+ if (Hob.Header->HobLength != sizeof (EFI_HOB_FIRMWARE_VOLUME3)) {
+ DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_FV3));
+ return FALSE;
+ }
+
+ break;
+
+ case EFI_HOB_TYPE_CPU:
+ if (Hob.Header->HobLength != sizeof (EFI_HOB_CPU)) {
+ DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_CPU));
+ return FALSE;
+ }
+
+ for (UINT32 index = 0; index < 6; index++) {
+ if (Hob.Cpu->Reserved[index] != 0) {
+ DEBUG ((DEBUG_ERROR, "HOB: Cpu Reserved field will always be set to zero.\n"));
+ return FALSE;
+ }
+ }
+
+ break;
+
+ default:
+ DEBUG ((DEBUG_ERROR, "HOB: Hob type is not know. Type: 0x%04x\n", Hob.Header->HobType));
+ return FALSE;
+ }
+
+ // Get next HOB
+ Hob.Raw = (UINT8 *)(Hob.Raw + Hob.Header->HobLength);
+ }
+
+ return TRUE;
+}
+
+/**
+ Processing the incoming HobList for the TDX
+
+ Firmware must parse list, and accept the pages of memory before their can be
+ use by the guest.
+
+ @param[in] VmmHobList The Hoblist pass the firmware
+
+ @retval EFI_SUCCESS Process the HobList successfully
+ @retval Others Other errors as indicated
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+ProcessHobList (
+ IN CONST VOID *VmmHobList
+ )
+{
+ EFI_STATUS Status;
+ UINT32 CpusNum;
+ EFI_PHYSICAL_ADDRESS PhysicalEnd;
+ EFI_PHYSICAL_ADDRESS APsStackStartAddress;
+
+ CpusNum = GetCpusNum ();
+
+ //
+ // If there are mutli-vCPU in a TDX guest, accept memory is split into 2 phases.
+ // Phase-1 accepts a small piece of memory by BSP. This piece of memory
+ // is used to setup AP's stack.
+ // After that phase-2 accepts a big piece of memory by BSP/APs.
+ //
+ // TDVF supports 4K and 2M accept-page-size. The memory which can be accpeted
+ // in 2M accept-page-size must be 2M aligned and multiple 2M. So we align
+ // APsStackSize to 2M size aligned.
+ //
+ if (CpusNum > 1) {
+ Status = AcceptMemoryForAPsStack (VmmHobList, APS_STACK_SIZE (CpusNum), &PhysicalEnd);
+ ASSERT (Status == EFI_SUCCESS);
+ APsStackStartAddress = PhysicalEnd - APS_STACK_SIZE (CpusNum);
+ } else {
+ PhysicalEnd = 0;
+ APsStackStartAddress = 0;
+ }
+
+ Status = AcceptMemory (VmmHobList, CpusNum, APsStackStartAddress, PhysicalEnd);
+ ASSERT (Status == EFI_SUCCESS);
+
+ return Status;
+}
+
/**
In Tdx guest, some information need to be passed from host VMM to guest
firmware. For example, the memory resource, etc. These information are
@@ -49,7 +772,36 @@ TdxHelperProcessTdHob (
VOID
)
{
- return EFI_UNSUPPORTED;
+ EFI_STATUS Status;
+ VOID *TdHob;
+ TD_RETURN_DATA TdReturnData;
+
+ TdHob = (VOID *)(UINTN)FixedPcdGet32 (PcdOvmfSecGhcbBase);
+ Status = TdCall (TDCALL_TDINFO, 0, 0, 0, &TdReturnData);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ DEBUG ((
+ DEBUG_INFO,
+ "Intel Tdx Started with (GPAW: %d, Cpus: %d)\n",
+ TdReturnData.TdInfo.Gpaw,
+ TdReturnData.TdInfo.NumVcpus
+ ));
+
+ //
+ // Validate HobList
+ //
+ if (ValidateHobList (TdHob) == FALSE) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Process Hoblist to accept memory
+ //
+ Status = ProcessHobList (TdHob);
+
+ return Status;
}
/**
diff --git a/OvmfPkg/Library/PlatformInitLib/IntelTdx.c b/OvmfPkg/Library/PlatformInitLib/IntelTdx.c
index 6cb63139cba0..ada8592ddd5a 100644
--- a/OvmfPkg/Library/PlatformInitLib/IntelTdx.c
+++ b/OvmfPkg/Library/PlatformInitLib/IntelTdx.c
@@ -16,779 +16,11 @@
#include <Library/MemoryAllocationLib.h>
#include <IndustryStandard/Tdx.h>
#include <IndustryStandard/IntelTdx.h>
-#include <IndustryStandard/QemuFwCfg.h>
-#include <Library/QemuFwCfgLib.h>
#include <Library/PeiServicesLib.h>
-#include <Library/TdxLib.h>
-#include <Library/TdxMailboxLib.h>
-#include <Library/SynchronizationLib.h>
#include <Pi/PrePiHob.h>
#include <WorkArea.h>
#include <ConfidentialComputingGuestAttr.h>
-#define ALIGNED_2MB_MASK 0x1fffff
-#define MEGABYTE_SHIFT 20
-
-#define ACCEPT_CHUNK_SIZE SIZE_32MB
-#define AP_STACK_SIZE SIZE_16KB
-#define APS_STACK_SIZE(CpusNum) (ALIGN_VALUE(CpusNum*AP_STACK_SIZE, SIZE_2MB))
-
-/**
- This function will be called to accept pages. Only BSP accepts pages.
-
- TDCALL(ACCEPT_PAGE) supports the accept page size of 4k and 2M. To
- simplify the implementation, the Memory to be accpeted is splitted
- into 3 parts:
- ----------------- <-- StartAddress1 (not 2M aligned)
- | part 1 | Length1 < 2M
- |---------------| <-- StartAddress2 (2M aligned)
- | | Length2 = Integer multiples of 2M
- | part 2 |
- | |
- |---------------| <-- StartAddress3
- | part 3 | Length3 < 2M
- |---------------|
-
- @param[in] PhysicalAddress Start physical adress
- @param[in] PhysicalEnd End physical address
-
- @retval EFI_SUCCESS Accept memory successfully
- @retval Others Other errors as indicated
-**/
-EFI_STATUS
-EFIAPI
-BspAcceptMemoryResourceRange (
- IN EFI_PHYSICAL_ADDRESS PhysicalAddress,
- IN EFI_PHYSICAL_ADDRESS PhysicalEnd
- )
-{
- EFI_STATUS Status;
- UINT32 AcceptPageSize;
- UINT64 StartAddress1;
- UINT64 StartAddress2;
- UINT64 StartAddress3;
- UINT64 TotalLength;
- UINT64 Length1;
- UINT64 Length2;
- UINT64 Length3;
- UINT64 Pages;
-
- AcceptPageSize = FixedPcdGet32 (PcdTdxAcceptPageSize);
- TotalLength = PhysicalEnd - PhysicalAddress;
- StartAddress1 = 0;
- StartAddress2 = 0;
- StartAddress3 = 0;
- Length1 = 0;
- Length2 = 0;
- Length3 = 0;
-
- if (TotalLength == 0) {
- return EFI_SUCCESS;
- }
-
- if (ALIGN_VALUE (PhysicalAddress, SIZE_2MB) != PhysicalAddress) {
- StartAddress1 = PhysicalAddress;
- Length1 = ALIGN_VALUE (PhysicalAddress, SIZE_2MB) - PhysicalAddress;
- if (Length1 >= TotalLength) {
- Length1 = TotalLength;
- }
-
- PhysicalAddress += Length1;
- TotalLength -= Length1;
- }
-
- if (TotalLength > SIZE_2MB) {
- StartAddress2 = PhysicalAddress;
- Length2 = TotalLength & ~(UINT64)ALIGNED_2MB_MASK;
- PhysicalAddress += Length2;
- TotalLength -= Length2;
- }
-
- if (TotalLength) {
- StartAddress3 = PhysicalAddress;
- Length3 = TotalLength;
- }
-
- Status = EFI_SUCCESS;
- if (Length1 > 0) {
- Pages = Length1 / SIZE_4KB;
- Status = TdAcceptPages (StartAddress1, Pages, SIZE_4KB);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- }
-
- if (Length2 > 0) {
- Pages = Length2 / AcceptPageSize;
- Status = TdAcceptPages (StartAddress2, Pages, AcceptPageSize);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- }
-
- if (Length3 > 0) {
- Pages = Length3 / SIZE_4KB;
- Status = TdAcceptPages (StartAddress3, Pages, SIZE_4KB);
- ASSERT (!EFI_ERROR (Status));
- if (EFI_ERROR (Status)) {
- return Status;
- }
- }
-
- return Status;
-}
-
-/**
- * This function is called by BSP and APs to accept memory.
- * Note:
- * The input PhysicalStart/PhysicalEnd indicates the whole memory region
- * to be accepted. BSP or AP only accepts one piece in the whole memory region.
- *
- * @param CpuIndex vCPU index
- * @param CpusNum Total vCPU number of a Tdx guest
- * @param PhysicalStart Start address of a memory region which is to be accepted
- * @param PhysicalEnd End address of a memory region which is to be accepted
- *
- * @retval EFI_SUCCESS Successfully accept the memory
- * @retval Other Other errors as indicated
- */
-STATIC
-EFI_STATUS
-EFIAPI
-BspApAcceptMemoryResourceRange (
- UINT32 CpuIndex,
- UINT32 CpusNum,
- EFI_PHYSICAL_ADDRESS PhysicalStart,
- EFI_PHYSICAL_ADDRESS PhysicalEnd
- )
-{
- UINT64 Status;
- UINT64 Pages;
- UINT64 Stride;
- UINT64 AcceptPageSize;
- EFI_PHYSICAL_ADDRESS PhysicalAddress;
-
- AcceptPageSize = (UINT64)(UINTN)FixedPcdGet32 (PcdTdxAcceptPageSize);
-
- Status = EFI_SUCCESS;
- Stride = (UINTN)CpusNum * ACCEPT_CHUNK_SIZE;
- PhysicalAddress = PhysicalStart + ACCEPT_CHUNK_SIZE * (UINTN)CpuIndex;
-
- while (!EFI_ERROR (Status) && PhysicalAddress < PhysicalEnd) {
- Pages = MIN (ACCEPT_CHUNK_SIZE, PhysicalEnd - PhysicalAddress) / AcceptPageSize;
- Status = TdAcceptPages (PhysicalAddress, Pages, (UINT32)(UINTN)AcceptPageSize);
- ASSERT (!EFI_ERROR (Status));
- PhysicalAddress += Stride;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- * This function is called by APs to accept memory.
- *
- * @param CpuIndex vCPU index of an AP
- * @param PhysicalStart Start address of a memory region which is to be accepted
- * @param PhysicalEnd End address of a memory region which is to be accepted
- *
- * @retval EFI_SUCCESS Successfully accept the memory
- * @retval Others Other errors as indicated
- */
-STATIC
-EFI_STATUS
-EFIAPI
-ApAcceptMemoryResourceRange (
- UINT32 CpuIndex,
- EFI_PHYSICAL_ADDRESS PhysicalStart,
- EFI_PHYSICAL_ADDRESS PhysicalEnd
- )
-{
- UINT64 Status;
- TD_RETURN_DATA TdReturnData;
-
- Status = TdCall (TDCALL_TDINFO, 0, 0, 0, &TdReturnData);
- if (Status != TDX_EXIT_REASON_SUCCESS) {
- ASSERT (FALSE);
- return EFI_ABORTED;
- }
-
- if ((CpuIndex == 0) || (CpuIndex >= TdReturnData.TdInfo.NumVcpus)) {
- ASSERT (FALSE);
- return EFI_ABORTED;
- }
-
- return BspApAcceptMemoryResourceRange (CpuIndex, TdReturnData.TdInfo.NumVcpus, PhysicalStart, PhysicalEnd);
-}
-
-/**
- * This function is called by BSP. It coordinates BSP/APs to accept memory together.
- *
- * @param PhysicalStart Start address of a memory region which is to be accepted
- * @param PhysicalEnd End address of a memory region which is to be accepted
- * @param APsStackAddress APs stack address
- * @param CpusNum Total vCPU number of the Tdx guest
- *
- * @retval EFI_SUCCESS Successfully accept the memory
- * @retval Others Other errors as indicated
- */
-EFI_STATUS
-EFIAPI
-MpAcceptMemoryResourceRange (
- IN EFI_PHYSICAL_ADDRESS PhysicalStart,
- IN EFI_PHYSICAL_ADDRESS PhysicalEnd,
- IN OUT EFI_PHYSICAL_ADDRESS APsStackAddress,
- IN UINT32 CpusNum
- )
-{
- UINT64 Length;
- EFI_STATUS Status;
-
- Length = PhysicalEnd - PhysicalStart;
-
- DEBUG ((DEBUG_INFO, "MpAccept : 0x%llx - 0x%llx (0x%llx)\n", PhysicalStart, PhysicalEnd, Length));
-
- if (Length == 0) {
- return EFI_SUCCESS;
- }
-
- //
- // The start address is not 2M aligned. BSP first accept the part which is not 2M aligned.
- //
- if (ALIGN_VALUE (PhysicalStart, SIZE_2MB) != PhysicalStart) {
- Length = MIN (ALIGN_VALUE (PhysicalStart, SIZE_2MB) - PhysicalStart, Length);
- Status = BspAcceptMemoryResourceRange (PhysicalStart, PhysicalStart + Length);
- ASSERT (Status == EFI_SUCCESS);
-
- PhysicalStart += Length;
- Length = PhysicalEnd - PhysicalStart;
- }
-
- if (Length == 0) {
- return EFI_SUCCESS;
- }
-
- //
- // BSP will accept the memory by itself if the memory is not big enough compared with a chunk.
- //
- if (Length <= ACCEPT_CHUNK_SIZE) {
- return BspAcceptMemoryResourceRange (PhysicalStart, PhysicalEnd);
- }
-
- //
- // Now APs are asked to accept the memory together.
- //
- MpSerializeStart ();
-
- MpSendWakeupCommand (
- MpProtectedModeWakeupCommandAcceptPages,
- (UINT64)(UINTN)ApAcceptMemoryResourceRange,
- PhysicalStart,
- PhysicalEnd,
- APsStackAddress,
- AP_STACK_SIZE
- );
-
- //
- // Now BSP does its job.
- //
- BspApAcceptMemoryResourceRange (0, CpusNum, PhysicalStart, PhysicalEnd);
-
- MpSerializeEnd ();
-
- return EFI_SUCCESS;
-}
-
-/**
- BSP accept a small piece of memory which will be used as APs stack.
-
- @param[in] VmmHobList The Hoblist pass the firmware
- @param[in] APsStackSize APs stack size
- @param[out] PhysicalAddressEnd The physical end address of accepted memory in phase-1
-
- @retval EFI_SUCCESS Process the HobList successfully
- @retval Others Other errors as indicated
-**/
-EFI_STATUS
-EFIAPI
-AcceptMemoryForAPsStack (
- IN CONST VOID *VmmHobList,
- IN UINT32 APsStackSize,
- OUT EFI_PHYSICAL_ADDRESS *PhysicalAddressEnd
- )
-{
- EFI_STATUS Status;
- EFI_PEI_HOB_POINTERS Hob;
- EFI_PHYSICAL_ADDRESS PhysicalEnd;
- EFI_PHYSICAL_ADDRESS PhysicalStart;
- UINT64 ResourceLength;
- BOOLEAN MemoryRegionFound;
-
- ASSERT (VmmHobList != NULL);
-
- Status = EFI_SUCCESS;
- Hob.Raw = (UINT8 *)VmmHobList;
- MemoryRegionFound = FALSE;
-
- DEBUG ((DEBUG_INFO, "AcceptMemoryForAPsStack with APsStackSize=0x%x\n", APsStackSize));
-
- //
- // Parse the HOB list until end of list or matching type is found.
- //
- while (!END_OF_HOB_LIST (Hob) && !MemoryRegionFound) {
- if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
- DEBUG ((DEBUG_INFO, "\nResourceType: 0x%x\n", Hob.ResourceDescriptor->ResourceType));
-
- if (Hob.ResourceDescriptor->ResourceType == BZ3937_EFI_RESOURCE_MEMORY_UNACCEPTED) {
- ResourceLength = Hob.ResourceDescriptor->ResourceLength;
- PhysicalStart = Hob.ResourceDescriptor->PhysicalStart;
- PhysicalEnd = PhysicalStart + ResourceLength;
-
- DEBUG ((DEBUG_INFO, "ResourceAttribute: 0x%x\n", Hob.ResourceDescriptor->ResourceAttribute));
- DEBUG ((DEBUG_INFO, "PhysicalStart: 0x%llx\n", PhysicalStart));
- DEBUG ((DEBUG_INFO, "ResourceLength: 0x%llx\n", ResourceLength));
- DEBUG ((DEBUG_INFO, "Owner: %g\n\n", &Hob.ResourceDescriptor->Owner));
-
- if (ResourceLength >= APsStackSize) {
- MemoryRegionFound = TRUE;
- if (ResourceLength > ACCEPT_CHUNK_SIZE) {
- PhysicalEnd = Hob.ResourceDescriptor->PhysicalStart + APsStackSize;
- }
- }
-
- Status = BspAcceptMemoryResourceRange (
- Hob.ResourceDescriptor->PhysicalStart,
- PhysicalEnd
- );
- if (EFI_ERROR (Status)) {
- break;
- }
- }
- }
-
- Hob.Raw = GET_NEXT_HOB (Hob);
- }
-
- ASSERT (MemoryRegionFound);
- *PhysicalAddressEnd = PhysicalEnd;
-
- return Status;
-}
-
-/**
- BSP and APs work togeter to accept memory which is under the address of 4G.
-
- @param[in] VmmHobList The Hoblist pass the firmware
- @param[in] CpusNum Number of vCPUs
- @param[in] APsStackStartAddres Start address of APs stack
- @param[in] PhysicalAddressStart Start physical address which to be accepted
-
- @retval EFI_SUCCESS Process the HobList successfully
- @retval Others Other errors as indicated
-**/
-EFI_STATUS
-EFIAPI
-AcceptMemory (
- IN CONST VOID *VmmHobList,
- IN UINT32 CpusNum,
- IN EFI_PHYSICAL_ADDRESS APsStackStartAddress,
- IN EFI_PHYSICAL_ADDRESS PhysicalAddressStart
- )
-{
- EFI_STATUS Status;
- EFI_PEI_HOB_POINTERS Hob;
- EFI_PHYSICAL_ADDRESS PhysicalStart;
- EFI_PHYSICAL_ADDRESS PhysicalEnd;
- EFI_PHYSICAL_ADDRESS AcceptMemoryEndAddress;
-
- Status = EFI_SUCCESS;
- AcceptMemoryEndAddress = BASE_4GB;
-
- ASSERT (VmmHobList != NULL);
- Hob.Raw = (UINT8 *)VmmHobList;
-
- DEBUG ((DEBUG_INFO, "AcceptMemory under address of 4G\n"));
-
- //
- // Parse the HOB list until end of list or matching type is found.
- //
- while (!END_OF_HOB_LIST (Hob)) {
- if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
- if (Hob.ResourceDescriptor->ResourceType == BZ3937_EFI_RESOURCE_MEMORY_UNACCEPTED) {
- PhysicalStart = Hob.ResourceDescriptor->PhysicalStart;
- PhysicalEnd = PhysicalStart + Hob.ResourceDescriptor->ResourceLength;
-
- if (PhysicalEnd <= PhysicalAddressStart) {
- // this memory region has been accepted. Skipped it.
- Hob.Raw = GET_NEXT_HOB (Hob);
- continue;
- }
-
- if (PhysicalStart >= AcceptMemoryEndAddress) {
- // this memory region is not to be accepted. And we're done.
- break;
- }
-
- if (PhysicalStart >= PhysicalAddressStart) {
- // this memory region has not been acceted.
- } else if ((PhysicalStart < PhysicalAddressStart) && (PhysicalEnd > PhysicalAddressStart)) {
- // part of the memory region has been accepted.
- PhysicalStart = PhysicalAddressStart;
- }
-
- // then compare the PhysicalEnd with AcceptMemoryEndAddress
- if (PhysicalEnd >= AcceptMemoryEndAddress) {
- PhysicalEnd = AcceptMemoryEndAddress;
- }
-
- DEBUG ((DEBUG_INFO, "ResourceAttribute: 0x%x\n", Hob.ResourceDescriptor->ResourceAttribute));
- DEBUG ((DEBUG_INFO, "PhysicalStart: 0x%llx\n", Hob.ResourceDescriptor->PhysicalStart));
- DEBUG ((DEBUG_INFO, "ResourceLength: 0x%llx\n", Hob.ResourceDescriptor->ResourceLength));
- DEBUG ((DEBUG_INFO, "Owner: %g\n\n", &Hob.ResourceDescriptor->Owner));
-
- // Now we're ready to accept memory [PhysicalStart, PhysicalEnd)
- if (CpusNum == 1) {
- Status = BspAcceptMemoryResourceRange (PhysicalStart, PhysicalEnd);
- } else {
- Status = MpAcceptMemoryResourceRange (
- PhysicalStart,
- PhysicalEnd,
- APsStackStartAddress,
- CpusNum
- );
- }
-
- if (EFI_ERROR (Status)) {
- ASSERT (FALSE);
- break;
- }
-
- if (PhysicalEnd == AcceptMemoryEndAddress) {
- break;
- }
- }
- }
-
- Hob.Raw = GET_NEXT_HOB (Hob);
- }
-
- return Status;
-}
-
-/**
- Check the value whether in the valid list.
-
- @param[in] Value A value
- @param[in] ValidList A pointer to valid list
- @param[in] ValidListLength Length of valid list
-
- @retval TRUE The value is in valid list.
- @retval FALSE The value is not in valid list.
-
-**/
-BOOLEAN
-EFIAPI
-IsInValidList (
- IN UINT32 Value,
- IN UINT32 *ValidList,
- IN UINT32 ValidListLength
- )
-{
- UINT32 index;
-
- if (ValidList == NULL) {
- return FALSE;
- }
-
- for (index = 0; index < ValidListLength; index++) {
- if (ValidList[index] == Value) {
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-/**
- Check the integrity of VMM Hob List.
-
- @param[in] VmmHobList A pointer to Hob List
-
- @retval TRUE The Hob List is valid.
- @retval FALSE The Hob List is invalid.
-
-**/
-BOOLEAN
-EFIAPI
-ValidateHobList (
- IN CONST VOID *VmmHobList
- )
-{
- EFI_PEI_HOB_POINTERS Hob;
- UINT32 EFI_BOOT_MODE_LIST[] = {
- BOOT_WITH_FULL_CONFIGURATION,
- BOOT_WITH_MINIMAL_CONFIGURATION,
- BOOT_ASSUMING_NO_CONFIGURATION_CHANGES,
- BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS,
- BOOT_WITH_DEFAULT_SETTINGS,
- BOOT_ON_S4_RESUME,
- BOOT_ON_S5_RESUME,
- BOOT_WITH_MFG_MODE_SETTINGS,
- BOOT_ON_S2_RESUME,
- BOOT_ON_S3_RESUME,
- BOOT_ON_FLASH_UPDATE,
- BOOT_IN_RECOVERY_MODE
- };
-
- UINT32 EFI_RESOURCE_TYPE_LIST[] = {
- EFI_RESOURCE_SYSTEM_MEMORY,
- EFI_RESOURCE_MEMORY_MAPPED_IO,
- EFI_RESOURCE_IO,
- EFI_RESOURCE_FIRMWARE_DEVICE,
- EFI_RESOURCE_MEMORY_MAPPED_IO_PORT,
- EFI_RESOURCE_MEMORY_RESERVED,
- EFI_RESOURCE_IO_RESERVED,
- BZ3937_EFI_RESOURCE_MEMORY_UNACCEPTED
- };
-
- if (VmmHobList == NULL) {
- DEBUG ((DEBUG_ERROR, "HOB: HOB data pointer is NULL\n"));
- return FALSE;
- }
-
- Hob.Raw = (UINT8 *)VmmHobList;
-
- //
- // Parse the HOB list until end of list or matching type is found.
- //
- while (!END_OF_HOB_LIST (Hob)) {
- if (Hob.Header->Reserved != (UINT32)0) {
- DEBUG ((DEBUG_ERROR, "HOB: Hob header Reserved filed should be zero\n"));
- return FALSE;
- }
-
- if (Hob.Header->HobLength == 0) {
- DEBUG ((DEBUG_ERROR, "HOB: Hob header LEANGTH should not be zero\n"));
- return FALSE;
- }
-
- switch (Hob.Header->HobType) {
- case EFI_HOB_TYPE_HANDOFF:
- if (Hob.Header->HobLength != sizeof (EFI_HOB_HANDOFF_INFO_TABLE)) {
- DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_HANDOFF));
- return FALSE;
- }
-
- if (IsInValidList (Hob.HandoffInformationTable->BootMode, EFI_BOOT_MODE_LIST, ARRAY_SIZE (EFI_BOOT_MODE_LIST)) == FALSE) {
- DEBUG ((DEBUG_ERROR, "HOB: Unknow HandoffInformationTable BootMode type. Type: 0x%08x\n", Hob.HandoffInformationTable->BootMode));
- return FALSE;
- }
-
- if ((Hob.HandoffInformationTable->EfiFreeMemoryTop % 4096) != 0) {
- DEBUG ((DEBUG_ERROR, "HOB: HandoffInformationTable EfiFreeMemoryTop address must be 4-KB aligned to meet page restrictions of UEFI.\
- Address: 0x%016lx\n", Hob.HandoffInformationTable->EfiFreeMemoryTop));
- return FALSE;
- }
-
- break;
-
- case EFI_HOB_TYPE_RESOURCE_DESCRIPTOR:
- if (Hob.Header->HobLength != sizeof (EFI_HOB_RESOURCE_DESCRIPTOR)) {
- DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_RESOURCE_DESCRIPTOR));
- return FALSE;
- }
-
- if (IsInValidList (Hob.ResourceDescriptor->ResourceType, EFI_RESOURCE_TYPE_LIST, ARRAY_SIZE (EFI_RESOURCE_TYPE_LIST)) == FALSE) {
- DEBUG ((DEBUG_ERROR, "HOB: Unknow ResourceDescriptor ResourceType type. Type: 0x%08x\n", Hob.ResourceDescriptor->ResourceType));
- return FALSE;
- }
-
- if ((Hob.ResourceDescriptor->ResourceAttribute & (~(EFI_RESOURCE_ATTRIBUTE_PRESENT |
- EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
- EFI_RESOURCE_ATTRIBUTE_TESTED |
- EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED |
- EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED |
- EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED |
- EFI_RESOURCE_ATTRIBUTE_PERSISTENT |
- EFI_RESOURCE_ATTRIBUTE_SINGLE_BIT_ECC |
- EFI_RESOURCE_ATTRIBUTE_MULTIPLE_BIT_ECC |
- EFI_RESOURCE_ATTRIBUTE_ECC_RESERVED_1 |
- EFI_RESOURCE_ATTRIBUTE_ECC_RESERVED_2 |
- EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
- EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
- EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
- EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
- EFI_RESOURCE_ATTRIBUTE_16_BIT_IO |
- EFI_RESOURCE_ATTRIBUTE_32_BIT_IO |
- EFI_RESOURCE_ATTRIBUTE_64_BIT_IO |
- EFI_RESOURCE_ATTRIBUTE_UNCACHED_EXPORTED |
- EFI_RESOURCE_ATTRIBUTE_READ_PROTECTABLE |
- EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTABLE |
- EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTABLE |
- EFI_RESOURCE_ATTRIBUTE_PERSISTABLE |
- EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED |
- EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTABLE |
- EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE))) != 0)
- {
- DEBUG ((DEBUG_ERROR, "HOB: Unknow ResourceDescriptor ResourceAttribute type. Type: 0x%08x\n", Hob.ResourceDescriptor->ResourceAttribute));
- return FALSE;
- }
-
- break;
-
- // EFI_HOB_GUID_TYPE is variable length data, so skip check
- case EFI_HOB_TYPE_GUID_EXTENSION:
- break;
-
- case EFI_HOB_TYPE_FV:
- if (Hob.Header->HobLength != sizeof (EFI_HOB_FIRMWARE_VOLUME)) {
- DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_FV));
- return FALSE;
- }
-
- break;
-
- case EFI_HOB_TYPE_FV2:
- if (Hob.Header->HobLength != sizeof (EFI_HOB_FIRMWARE_VOLUME2)) {
- DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_FV2));
- return FALSE;
- }
-
- break;
-
- case EFI_HOB_TYPE_FV3:
- if (Hob.Header->HobLength != sizeof (EFI_HOB_FIRMWARE_VOLUME3)) {
- DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_FV3));
- return FALSE;
- }
-
- break;
-
- case EFI_HOB_TYPE_CPU:
- if (Hob.Header->HobLength != sizeof (EFI_HOB_CPU)) {
- DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_CPU));
- return FALSE;
- }
-
- for (UINT32 index = 0; index < 6; index++) {
- if (Hob.Cpu->Reserved[index] != 0) {
- DEBUG ((DEBUG_ERROR, "HOB: Cpu Reserved field will always be set to zero.\n"));
- return FALSE;
- }
- }
-
- break;
-
- default:
- DEBUG ((DEBUG_ERROR, "HOB: Hob type is not know. Type: 0x%04x\n", Hob.Header->HobType));
- return FALSE;
- }
-
- // Get next HOB
- Hob.Raw = (UINT8 *)(Hob.Raw + Hob.Header->HobLength);
- }
-
- return TRUE;
-}
-
-/**
- Processing the incoming HobList for the TDX
-
- Firmware must parse list, and accept the pages of memory before their can be
- use by the guest.
-
- @param[in] VmmHobList The Hoblist pass the firmware
-
- @retval EFI_SUCCESS Process the HobList successfully
- @retval Others Other errors as indicated
-
-**/
-EFI_STATUS
-EFIAPI
-ProcessHobList (
- IN CONST VOID *VmmHobList
- )
-{
- EFI_STATUS Status;
- UINT32 CpusNum;
- EFI_PHYSICAL_ADDRESS PhysicalEnd;
- EFI_PHYSICAL_ADDRESS APsStackStartAddress;
-
- CpusNum = GetCpusNum ();
-
- //
- // If there are mutli-vCPU in a TDX guest, accept memory is split into 2 phases.
- // Phase-1 accepts a small piece of memory by BSP. This piece of memory
- // is used to setup AP's stack.
- // After that phase-2 accepts a big piece of memory by BSP/APs.
- //
- // TDVF supports 4K and 2M accept-page-size. The memory which can be accpeted
- // in 2M accept-page-size must be 2M aligned and multiple 2M. So we align
- // APsStackSize to 2M size aligned.
- //
- if (CpusNum > 1) {
- Status = AcceptMemoryForAPsStack (VmmHobList, APS_STACK_SIZE (CpusNum), &PhysicalEnd);
- ASSERT (Status == EFI_SUCCESS);
- APsStackStartAddress = PhysicalEnd - APS_STACK_SIZE (CpusNum);
- } else {
- PhysicalEnd = 0;
- APsStackStartAddress = 0;
- }
-
- Status = AcceptMemory (VmmHobList, CpusNum, APsStackStartAddress, PhysicalEnd);
- ASSERT (Status == EFI_SUCCESS);
-
- return Status;
-}
-
-/**
- In Tdx guest, some information need to be passed from host VMM to guest
- firmware. For example, the memory resource, etc. These information are
- prepared by host VMM and put in HobList which is described in TdxMetadata.
-
- Information in HobList is treated as external input. From the security
- perspective before it is consumed, it should be validated.
-
- @retval EFI_SUCCESS Successfully process the hoblist
- @retval Others Other error as indicated
-**/
-EFI_STATUS
-EFIAPI
-ProcessTdxHobList (
- VOID
- )
-{
- EFI_STATUS Status;
- VOID *TdHob;
- TD_RETURN_DATA TdReturnData;
-
- TdHob = (VOID *)(UINTN)FixedPcdGet32 (PcdOvmfSecGhcbBase);
- Status = TdCall (TDCALL_TDINFO, 0, 0, 0, &TdReturnData);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- DEBUG ((
- DEBUG_INFO,
- "Intel Tdx Started with (GPAW: %d, Cpus: %d)\n",
- TdReturnData.TdInfo.Gpaw,
- TdReturnData.TdInfo.NumVcpus
- ));
-
- //
- // Validate HobList
- //
- if (ValidateHobList (TdHob) == FALSE) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Process Hoblist to accept memory
- //
- Status = ProcessHobList (TdHob);
-
- return Status;
-}
-
/**
* Build ResourceDescriptorHob for the unaccepted memory region.
* This memory region may be splitted into 2 parts because of lazy accept.
diff --git a/OvmfPkg/Library/PlatformInitLib/IntelTdxNull.c b/OvmfPkg/Library/PlatformInitLib/IntelTdxNull.c
index 3ebe582af8de..7a7c2fb1f6f5 100644
--- a/OvmfPkg/Library/PlatformInitLib/IntelTdxNull.c
+++ b/OvmfPkg/Library/PlatformInitLib/IntelTdxNull.c
@@ -9,26 +9,6 @@
#include <PiPei.h>
-/**
- In Tdx guest, some information need to be passed from host VMM to guest
- firmware. For example, the memory resource, etc. These information are
- prepared by host VMM and put in HobList which is described in TdxMetadata.
-
- Information in HobList is treated as external input. From the security
- perspective before it is consumed, it should be validated.
-
- @retval EFI_SUCCESS Successfully process the hoblist
- @retval Others Other error as indicated
-**/
-EFI_STATUS
-EFIAPI
-ProcessTdxHobList (
- VOID
- )
-{
- return EFI_UNSUPPORTED;
-}
-
/**
In Tdx guest, the system memory is passed in TdHob by host VMM. So
the major task of PlatformTdxPublishRamRegions is to walk thru the
diff --git a/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf b/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
index 140216979a54..86a82ad3e084 100644
--- a/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
+++ b/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
@@ -52,7 +52,6 @@
PcdLib
PciLib
PeiHardwareInfoLib
- TdxMailboxLib
[LibraryClasses.X64]
TdxLib
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index 3f970a79a08a..d87013a4422c 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -724,7 +724,8 @@
OvmfPkg/Sec/SecMain.inf {
<LibraryClasses>
NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
- NULL|OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
+ NULL|OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelperLib.inf
+ BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SecCryptLib.inf
}
#
diff --git a/OvmfPkg/Sec/SecMain.c b/OvmfPkg/Sec/SecMain.c
index 1167d22a68cc..a27dc9406b70 100644
--- a/OvmfPkg/Sec/SecMain.c
+++ b/OvmfPkg/Sec/SecMain.c
@@ -29,7 +29,7 @@
#include <Library/CpuExceptionHandlerLib.h>
#include <Ppi/TemporaryRamSupport.h>
#include <Ppi/MpInitLibDep.h>
-#include <Library/PlatformInitLib.h>
+#include <Library/TdxHelperLib.h>
#include <Library/CcProbeLib.h>
#include "AmdSev.h"
@@ -765,7 +765,7 @@ SecCoreStartupWithStack (
// first so that the memory is accepted. Otherwise access to the unaccepted
// memory will trigger tripple fault.
//
- if (ProcessTdxHobList () != EFI_SUCCESS) {
+ if (TdxHelperProcessTdHob () != EFI_SUCCESS) {
CpuDeadLoop ();
}
}
--
2.29.2.windows.2
next prev parent reply other threads:[~2023-01-28 13:59 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-01-28 13:58 [PATCH V5 00/13] Enable Tdx measurement in OvmfPkgX64 Min Xu
2023-01-28 13:58 ` [PATCH V5 01/13] OvmfPkg: Add Tdx measurement data structure in WorkArea Min Xu
2023-01-28 13:58 ` [PATCH V5 02/13] OvmfPkg/IntelTdx: Add TdxHelperLibNull Min Xu
2023-01-28 13:58 ` [PATCH V5 03/13] OvmfPkg/IntelTdx: Add SecTdxHelperLib Min Xu
2023-02-02 12:54 ` Gerd Hoffmann
2023-01-28 13:58 ` [PATCH V5 04/13] OvmfPkg/PeilessStartupLib: Update the define of FV_HANDOFF_TABLE_POINTERS2 Min Xu
2023-02-02 12:56 ` Gerd Hoffmann
2023-01-28 13:58 ` [PATCH V5 05/13] OvmfPkg: Refactor MeasureHobList Min Xu
2023-02-02 13:09 ` Gerd Hoffmann
2023-01-28 13:58 ` [PATCH V5 06/13] OvmfPkg: Refactor MeaureFvImage Min Xu
2023-02-02 13:09 ` Gerd Hoffmann
2023-01-28 13:58 ` Min Xu [this message]
2023-02-02 13:09 ` [PATCH V5 07/13] OvmfPkg: Refactor ProcessHobList Gerd Hoffmann
2023-01-28 13:58 ` [PATCH V5 08/13] OvmfPkg/IntelTdx: Measure TdHob and Configuration FV in SecMain Min Xu
2023-01-28 13:58 ` [PATCH V5 09/13] OvmfPkg/PeilessStartupLib: Delete the duplicated tdx measurement Min Xu
2023-02-02 13:10 ` Gerd Hoffmann
2023-02-02 23:27 ` Min Xu
2023-01-28 13:58 ` [PATCH V5 10/13] OvmfPkg/IntelTdx: Add PeiTdxHelperLib Min Xu
2023-01-28 13:58 ` [PATCH V5 11/13] OvmfPkg/OvmfPkgX64: Measure TdHob and Configuration FV in SecMain Min Xu
2023-02-02 13:15 ` Gerd Hoffmann
2023-01-28 13:58 ` [PATCH V5 12/13] OvmfPkg/PlatformPei: Build GuidHob for Tdx measurement Min Xu
2023-02-02 13:15 ` Gerd Hoffmann
2023-01-28 13:58 ` [PATCH V5 13/13] OvmfPkg: Support Tdx measurement in OvmfPkgX64 Min Xu
2023-02-02 13:15 ` Gerd Hoffmann
2023-02-03 2:25 ` [PATCH V5 00/13] Enable " Yao, Jiewen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230128135842.980-8-min.m.xu@intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox