public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Min Xu" <min.m.xu@intel.com>
To: devel@edk2.groups.io
Cc: Min Xu <min.m.xu@intel.com>,
	Ard Biesheuvel <ardb+tianocore@kernel.org>,
	Jordan Justen <jordan.l.justen@intel.com>,
	Brijesh Singh <brijesh.singh@amd.com>,
	Erdem Aktas <erdemaktas@google.com>,
	James Bottomley <jejb@linux.ibm.com>,
	Jiewen Yao <jiewen.yao@intel.com>,
	Tom Lendacky <thomas.lendacky@amd.com>,
	Gerd Hoffmann <kraxel@redhat.com>
Subject: [PATCH V9 31/47] OvmfPkg: Update PlatformInitLib to process Tdx hoblist
Date: Fri, 18 Mar 2022 08:45:49 +0800	[thread overview]
Message-ID: <0cee079ce056cd4999d44b931b1b4dec279777c3.1647523953.git.min.m.xu@intel.com> (raw)
In-Reply-To: <cover.1647523953.git.min.m.xu@intel.com>

RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3429

When host VMM create the Td guest, the system memory informations are
stored in TdHob, which is a memory region described in Tdx metadata.
The system memory region in TdHob should be accepted before it can be
accessed. So the newly added function (ProcessTdxHobList) is to process
the TdHobList to accept the memory. Because TdHobList is provided by
host VMM which is not trusted, so its content should be checked before
it is consumed by TDVF.

Because ProcessTdxHobList is to be called in SEC phase, so
PlatformInitLib.inf is updated to support SEC.

Note: In this patch it is BSP which accepts the pages. So there maybe
boot performance issue. There are some mitigations to this issue, such
as lazy accept, 2M accept page size, etc. We will re-visit here in the
future.

EFI_RESOURCE_MEMORY_UNACCEPTED is a new ResourceType in
EFI_HOB_RESOURCE_DESCRIPTOR. It is defined for the unaccepted memory
passed from Host VMM. This is proposed in microsoft/mu_basecore#66
files#diff-b20a11152d1ce9249c691be5690b4baf52069efadf2e2546cdd2eb663d80c9
e4R237 according to UEFI-Code-First. The proposal was approved in 2021
in UEFI Mantis, and will be added to the new PI.next specification.

Per the MdePkg reviewer's comments, before this new ResourceType is
added in the PI spec, it should not be in MdePkg. So it is now
defined as an internal implementation and will be moved to
MdePkg/Include/Pi/PiHob.h after it is added in PI spec.
See https://edk2.groups.io/g/devel/message/87641

PcdTdxAcceptPageSize is added for page accepting. Currently TDX supports
4K and 2M accept page size. The default value is 2M.

Tdx guest is only supported in X64. So for IA32 ProcessTdxHobList
just returns EFI_UNSUPPORTED.

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
---
 OvmfPkg/Include/Library/PlatformInitLib.h     |  17 +
 OvmfPkg/Library/PlatformInitLib/IntelTdx.c    | 514 ++++++++++++++++++
 .../Library/PlatformInitLib/IntelTdxNull.c    |  30 +
 .../PlatformInitLib/PlatformInitLib.inf       |  13 +-
 OvmfPkg/OvmfPkg.dec                           |   3 +
 5 files changed, 576 insertions(+), 1 deletion(-)
 create mode 100644 OvmfPkg/Library/PlatformInitLib/IntelTdx.c
 create mode 100644 OvmfPkg/Library/PlatformInitLib/IntelTdxNull.c

diff --git a/OvmfPkg/Include/Library/PlatformInitLib.h b/OvmfPkg/Include/Library/PlatformInitLib.h
index b31f521578c2..6152a43d0da7 100644
--- a/OvmfPkg/Include/Library/PlatformInitLib.h
+++ b/OvmfPkg/Include/Library/PlatformInitLib.h
@@ -203,4 +203,21 @@ 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
+  );
+
 #endif // PLATFORM_INIT_LIB_H_
diff --git a/OvmfPkg/Library/PlatformInitLib/IntelTdx.c b/OvmfPkg/Library/PlatformInitLib/IntelTdx.c
new file mode 100644
index 000000000000..e9196b7ffaa7
--- /dev/null
+++ b/OvmfPkg/Library/PlatformInitLib/IntelTdx.c
@@ -0,0 +1,514 @@
+/** @file
+  Initialize Intel TDX support.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/BaseMemoryLib.h>
+#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/SynchronizationLib.h>
+#include <WorkArea.h>
+#include <ConfidentialComputingGuestAttr.h>
+
+#define ALIGNED_2MB_MASK                0x1fffff
+#define EFI_RESOURCE_MEMORY_UNACCEPTED  7
+
+/**
+  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;
+  }
+
+  DEBUG ((DEBUG_INFO, "TdAccept: 0x%llx - 0x%llx\n", PhysicalAddress, TotalLength));
+
+  if (ALIGN_VALUE (PhysicalAddress, SIZE_2MB) != PhysicalAddress) {
+    StartAddress1 = PhysicalAddress;
+    Length1       = ALIGN_VALUE (PhysicalAddress, SIZE_2MB) - PhysicalAddress;
+    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;
+  }
+
+  DEBUG ((DEBUG_INFO, "   Part1: 0x%llx - 0x%llx\n", StartAddress1, Length1));
+  DEBUG ((DEBUG_INFO, "   Part2: 0x%llx - 0x%llx\n", StartAddress2, Length2));
+  DEBUG ((DEBUG_INFO, "   Part3: 0x%llx - 0x%llx\n", StartAddress3, Length3));
+  DEBUG ((DEBUG_INFO, "   Page : 0x%x\n", AcceptPageSize));
+
+  Status = EFI_SUCCESS;
+  if (Length1 > 0) {
+    Pages  = Length1 / SIZE_4KB;
+    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;
+}
+
+/**
+  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,
+    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;
+  EFI_PEI_HOB_POINTERS  Hob;
+  EFI_PHYSICAL_ADDRESS  PhysicalEnd;
+
+  Status = EFI_SUCCESS;
+  ASSERT (VmmHobList != NULL);
+  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->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
+      DEBUG ((DEBUG_INFO, "\nResourceType: 0x%x\n", Hob.ResourceDescriptor->ResourceType));
+
+      if (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_UNACCEPTED) {
+        DEBUG ((DEBUG_INFO, "ResourceAttribute: 0x%x\n", Hob.ResourceDescriptor->ResourceAttribute));
+        DEBUG ((DEBUG_INFO, "PhysicalStart: 0x%llx\n", Hob.ResourceDescriptor->PhysicalStart));
+        DEBUG ((DEBUG_INFO, "ResourceLength: 0x%llx\n", Hob.ResourceDescriptor->ResourceLength));
+        DEBUG ((DEBUG_INFO, "Owner: %g\n\n", &Hob.ResourceDescriptor->Owner));
+
+        PhysicalEnd = Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength;
+
+        Status = BspAcceptMemoryResourceRange (
+                   Hob.ResourceDescriptor->PhysicalStart,
+                   PhysicalEnd
+                   );
+        if (EFI_ERROR (Status)) {
+          break;
+        }
+      }
+    }
+
+    Hob.Raw = GET_NEXT_HOB (Hob);
+  }
+
+  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;
+}
+
+/**
+  Transfer the incoming HobList for the TD to the final HobList for Dxe.
+  The Hobs transferred in this function are ResourceDescriptor hob and
+  MemoryAllocation hob.
+
+  @param[in] VmmHobList    The Hoblist pass the firmware
+
+**/
+VOID
+EFIAPI
+TransferTdxHobList (
+  VOID
+  )
+{
+  EFI_PEI_HOB_POINTERS         Hob;
+  EFI_RESOURCE_TYPE            ResourceType;
+  EFI_RESOURCE_ATTRIBUTE_TYPE  ResourceAttribute;
+
+  //
+  // PcdOvmfSecGhcbBase is used as the TD_HOB in Tdx guest.
+  //
+  Hob.Raw = (UINT8 *)(UINTN)FixedPcdGet32 (PcdOvmfSecGhcbBase);
+  while (!END_OF_HOB_LIST (Hob)) {
+    switch (Hob.Header->HobType) {
+      case EFI_HOB_TYPE_RESOURCE_DESCRIPTOR:
+        ResourceType      = Hob.ResourceDescriptor->ResourceType;
+        ResourceAttribute = Hob.ResourceDescriptor->ResourceAttribute;
+
+        if (ResourceType == EFI_RESOURCE_MEMORY_UNACCEPTED) {
+          ResourceType       = EFI_RESOURCE_SYSTEM_MEMORY;
+          ResourceAttribute |= (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_TESTED);
+        }
+
+        BuildResourceDescriptorHob (
+          ResourceType,
+          ResourceAttribute,
+          Hob.ResourceDescriptor->PhysicalStart,
+          Hob.ResourceDescriptor->ResourceLength
+          );
+        break;
+      case EFI_HOB_TYPE_MEMORY_ALLOCATION:
+        BuildMemoryAllocationHob (
+          Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress,
+          Hob.MemoryAllocation->AllocDescriptor.MemoryLength,
+          Hob.MemoryAllocation->AllocDescriptor.MemoryType
+          );
+        break;
+    }
+
+    Hob.Raw = GET_NEXT_HOB (Hob);
+  }
+}
diff --git a/OvmfPkg/Library/PlatformInitLib/IntelTdxNull.c b/OvmfPkg/Library/PlatformInitLib/IntelTdxNull.c
new file mode 100644
index 000000000000..af90e0866e89
--- /dev/null
+++ b/OvmfPkg/Library/PlatformInitLib/IntelTdxNull.c
@@ -0,0 +1,30 @@
+/** @file
+  Initialize Intel TDX support.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+
+/**
+  In Tdx guest, some information need to be passed from host VMM to guest
+  firmware. For example, the memory resource, etc. These information are
+  prepared by host VMM and put in 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;
+}
diff --git a/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf b/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
index 19a88d363819..d0fab5cc1f4f 100644
--- a/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
+++ b/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
@@ -14,7 +14,7 @@
   FILE_GUID                      = 89f886b0-7109-46e1-9d28-503ad4ab6ee0
   MODULE_TYPE                    = BASE
   VERSION_STRING                 = 1.0
-  LIBRARY_CLASS                  = PlatformInitLib|PEIM
+  LIBRARY_CLASS                  = PlatformInitLib|SEC PEIM
 
 #
 # The following information is for reference only and not required by the build tools.
@@ -27,6 +27,12 @@
   MemDetect.c
   Platform.c
 
+[Sources.IA32]
+  IntelTdxNull.c
+
+[Sources.X64]
+  IntelTdx.c
+
 [Packages]
   EmbeddedPkg/EmbeddedPkg.dec
   MdeModulePkg/MdeModulePkg.dec
@@ -45,6 +51,9 @@
   PcdLib
   PciLib
 
+[LibraryClasses.X64]
+  TdxLib
+
 [FixedPcd]
   gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase
@@ -83,5 +92,7 @@
   gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress
   gUefiOvmfPkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
 
+  gUefiOvmfPkgTokenSpaceGuid.PcdTdxAcceptPageSize
+
 [FeaturePcd]
   gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode
diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index 61635c73c761..f3d06411b51b 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -377,6 +377,9 @@
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecValidatedStart|0|UINT32|0x62
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecValidatedEnd|0|UINT32|0x63
 
+  ## The Tdx accept page size. 0x1000(4k),0x200000(2M)
+  gUefiOvmfPkgTokenSpaceGuid.PcdTdxAcceptPageSize|0x200000|UINT32|0x65
+
 [PcdsDynamic, PcdsDynamicEx]
   gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10
-- 
2.29.2.windows.2


  parent reply	other threads:[~2022-03-18  0:48 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-03-18  0:45 [PATCH V9 00/47] Enable Intel TDX in OvmfPkg (Config-A) Min Xu
2022-03-18  0:45 ` [PATCH V9 01/47] MdePkg: Add Tdx.h Min Xu
2022-03-18  0:45 ` [PATCH V9 02/47] MdePkg: Update Cpuid.h for Tdx Min Xu
2022-03-22  3:02   ` Min Xu
2022-03-23  1:15     ` 回复: " gaoliming
2022-03-22  7:54   ` Gerd Hoffmann
2022-03-23  9:18     ` [edk2-devel] " Ni, Ray
2022-03-18  0:45 ` [PATCH V9 03/47] MdePkg: Introduce basic Tdx functions in BaseLib Min Xu
2022-03-18  0:45 ` [PATCH V9 04/47] MdePkg: Add TdxLib to wrap Tdx operations Min Xu
2022-03-18  0:45 ` [PATCH V9 05/47] UefiCpuPkg: Extend VmgExitLibNull to handle #VE exception Min Xu
2022-03-18  0:45 ` [PATCH V9 06/47] OvmfPkg: Extend VmgExitLib " Min Xu
2022-03-18  0:45 ` [PATCH V9 07/47] UefiCpuPkg/CpuExceptionHandler: Add base support for the " Min Xu
2022-03-18  0:45 ` [PATCH V9 08/47] MdePkg: Add helper functions for Tdx guest in BaseIoLibIntrinsic Min Xu
2022-03-18  0:45 ` [PATCH V9 09/47] MdePkg: Support mmio " Min Xu
2022-03-18  0:45 ` [PATCH V9 10/47] MdePkg: Support IoFifo " Min Xu
2022-03-18  0:45 ` [PATCH V9 11/47] MdePkg: Support IoRead/IoWrite " Min Xu
2022-03-18  0:45 ` [PATCH V9 12/47] UefiCpuPkg: Support TDX in BaseXApicX2ApicLib Min Xu
2022-03-18  0:45 ` [PATCH V9 13/47] MdePkg: Add macro to check SEV / TDX guest Min Xu
2022-03-18  0:45 ` [PATCH V9 14/47] UefiCpuPkg: Enable Tdx support in MpInitLib Min Xu
2022-03-22  3:04   ` Min Xu
2022-03-23  7:19   ` Ni, Ray
2022-03-23 11:30     ` Min Xu
2022-03-18  0:45 ` [PATCH V9 15/47] OvmfPkg: Add IntelTdx.h in OvmfPkg/Include/IndustryStandard Min Xu
2022-03-18  0:45 ` [PATCH V9 16/47] OvmfPkg: Add TdxMailboxLib Min Xu
2022-03-18  0:45 ` [PATCH V9 17/47] OvmfPkg: Create initial version of PlatformInitLib Min Xu
2022-03-18  0:45 ` [PATCH V9 18/47] OvmfPkg/PlatformInitLib: Add hob functions Min Xu
2022-03-18  0:45 ` [PATCH V9 19/47] OvmfPkg/PlatformPei: Move global variables to PlatformInfoHob Min Xu
2022-03-22  8:35   ` Gerd Hoffmann
2022-03-18  0:45 ` [PATCH V9 20/47] OvmfPkg/PlatformPei: Refactor MiscInitialization Min Xu
2022-03-18  0:45 ` [PATCH V9 21/47] OvmfPkg/PlatformPei: Refactor MiscInitialization for CloudHV Min Xu
2022-03-18  0:45 ` [PATCH V9 22/47] OvmfPkg/PlatformPei: Refactor AddressWidthInitialization Min Xu
2022-03-22  8:36   ` Gerd Hoffmann
2022-03-18  0:45 ` [PATCH V9 23/47] OvmfPkg/PlatformPei: Refactor MaxCpuCountInitialization Min Xu
2022-03-22  8:37   ` Gerd Hoffmann
2022-03-18  0:45 ` [PATCH V9 24/47] OvmfPkg/PlatformPei: Refactor QemuUc32BaseInitialization Min Xu
2022-03-18  0:45 ` [PATCH V9 25/47] OvmfPkg/PlatformPei: Refactor InitializeRamRegions Min Xu
2022-03-18  0:45 ` [PATCH V9 27/47] OvmfPkg/PlatformPei: Refactor NoexecDxeInitialization Min Xu
2022-03-18  0:45 ` [PATCH V9 28/47] OvmfPkg/PlatformPei: Refactor MiscInitialization Min Xu
2022-03-18  0:45 ` [PATCH V9 29/47] OvmfPkg/PlatformInitLib: Create MemDetect.c Min Xu
2022-03-18  0:45 ` [PATCH V9 30/47] OvmfPkg/PlatformInitLib: Move functions to Platform.c Min Xu
2022-03-18  0:45 ` Min Xu [this message]
2022-03-18  0:45 ` [PATCH V9 32/47] OvmfPkg/Sec: Declare local variable as volatile in SecCoreStartupWithStack Min Xu
2022-03-18  0:45 ` [PATCH V9 33/47] OvmfPkg: Update Sec to support Tdx Min Xu
2022-03-18  0:45 ` [PATCH V9 34/47] OvmfPkg: Check Tdx in QemuFwCfgPei to avoid DMA operation Min Xu
2022-03-18  0:45 ` [PATCH V9 35/47] MdeModulePkg: Skip setting IA32_ERER.NXE if it has already been set Min Xu
2022-03-18 13:39   ` [edk2-devel] " Ni, Ray
2022-03-18  0:45 ` [PATCH V9 36/47] MdeModulePkg: Add PcdTdxSharedBitMask Min Xu
2022-03-18  0:45 ` [PATCH V9 37/47] UefiCpuPkg: Update AddressEncMask in CpuPageTable Min Xu
2022-03-18  0:45 ` [PATCH V9 38/47] OvmfPkg: Update PlatformInitLib for Tdx guest Min Xu
2022-03-18  0:45 ` [PATCH V9 39/47] OvmfPkg: Update PlatformPei to support " Min Xu
2022-03-18  0:45 ` [PATCH V9 40/47] OvmfPkg: Update AcpiPlatformDxe to alter MADT table Min Xu

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=0cee079ce056cd4999d44b931b1b4dec279777c3.1647523953.git.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