From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by mx.groups.io with SMTP id smtpd.web09.17699.1646032885667369347 for ; Sun, 27 Feb 2022 23:21:33 -0800 Authentication-Results: mx.groups.io; dkim=fail reason="unable to parse pub key" header.i=@intel.com header.s=intel header.b=gyCaG3pa; spf=pass (domain: intel.com, ip: 134.134.136.24, mailfrom: min.m.xu@intel.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1646032893; x=1677568893; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=TClTBUDqs5V+2jlVQyWgKto5I4mCr2Wrr2TvawZ86mA=; b=gyCaG3paEooV8ED2FX1c30d7Xkihv3dIpafsjaDs6nX38aHTT9sBzZhi 61nWMcVdaFIAoCCI29RMe0n/OgHB63Yi4LJgFT/IqhFiMJRZneghWgcWx jvhN8EXeeXDBBx9wYWHduWUiAWRKsNEbc8a1SLUke9ygvTiKw3Ul52LrZ 7F5TDkGahwdZBt0EaHheVx29IxZ8UWksRN2efh+V6OqsJ969NImGCXH3Y Ph9blloj/BNq7UcoGzFZHRBAa27wm2VXdL0jb5aD/mpIFjdgyYFEeApeD SpDD0sy+T2f5+a4ewsXVjXZRoPWBn1fLbCmPirkg38b2Q+hjtDfdhfH/y A==; X-IronPort-AV: E=McAfee;i="6200,9189,10271"; a="252552608" X-IronPort-AV: E=Sophos;i="5.90,142,1643702400"; d="scan'208";a="252552608" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Feb 2022 23:21:33 -0800 X-IronPort-AV: E=Sophos;i="5.90,142,1643702400"; d="scan'208";a="534340759" Received: from mxu9-mobl1.ccr.corp.intel.com ([10.238.2.184]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Feb 2022 23:21:30 -0800 From: "Min Xu" To: devel@edk2.groups.io Cc: Min Xu , Michael D Kinney , Liming Gao , Zhiguang Liu , Brijesh Singh , Erdem Aktas , James Bottomley , Jiewen Yao , Tom Lendacky , Gerd Hoffmann Subject: [PATCH V7 03/37] MdePkg: Add TdxLib to wrap Tdx operations Date: Mon, 28 Feb 2022 15:20:35 +0800 Message-Id: X-Mailer: git-send-email 2.29.2.windows.2 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3429 TdxLib is created with functions to perform the related Tdx operation. This includes functions for: - TdAcceptPages : Accept pending private pages and initialize the pages to all-0 using the TD ephemeral private key. - TdExtendRtmr : Extend measurement to one of the RTMR registers. - TdSharedPageMask: Get the Td guest shared page mask which indicates it is a Shared or Private page. - TdMaxVCpuNum : Get the maximum number of virtual CPUs. - TdVCpuNum : Get the number of virtual CPUs. Cc: Michael D Kinney Cc: Liming Gao Cc: Zhiguang Liu Cc: Brijesh Singh Cc: Erdem Aktas Cc: James Bottomley Cc: Jiewen Yao Cc: Tom Lendacky Cc: Gerd Hoffmann Acked-by: Gerd Hoffmann Signed-off-by: Min Xu --- MdePkg/Include/Library/TdxLib.h | 97 +++++++++++++++ MdePkg/Library/TdxLib/AcceptPages.c | 180 ++++++++++++++++++++++++++++ MdePkg/Library/TdxLib/Rtmr.c | 83 +++++++++++++ MdePkg/Library/TdxLib/TdInfo.c | 114 ++++++++++++++++++ MdePkg/Library/TdxLib/TdxLib.inf | 37 ++++++ MdePkg/Library/TdxLib/TdxLibNull.c | 107 +++++++++++++++++ MdePkg/MdePkg.dec | 3 + MdePkg/MdePkg.dsc | 1 + 8 files changed, 622 insertions(+) create mode 100644 MdePkg/Include/Library/TdxLib.h create mode 100644 MdePkg/Library/TdxLib/AcceptPages.c create mode 100644 MdePkg/Library/TdxLib/Rtmr.c create mode 100644 MdePkg/Library/TdxLib/TdInfo.c create mode 100644 MdePkg/Library/TdxLib/TdxLib.inf create mode 100644 MdePkg/Library/TdxLib/TdxLibNull.c diff --git a/MdePkg/Include/Library/TdxLib.h b/MdePkg/Include/Library/TdxLib.h new file mode 100644 index 000000000000..86539460c9f9 --- /dev/null +++ b/MdePkg/Include/Library/TdxLib.h @@ -0,0 +1,97 @@ +/** @file + TdxLib definitions + + Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef TDX_LIB_H_ +#define TDX_LIB_H_ + +#include +#include +#include +#include + +/** + This function accepts a pending private page, and initialize the page to + all-0 using the TD ephemeral private key. + + @param[in] StartAddress Guest physical address of the private page + to accept. [63:52] and [11:0] must be 0. + @param[in] NumberOfPages Number of the pages to be accepted. + @param[in] PageSize GPA page size. Accept 2M/4K page size. + + @return EFI_SUCCESS +**/ +EFI_STATUS +EFIAPI +TdAcceptPages ( + IN UINT64 StartAddress, + IN UINT64 NumberOfPages, + IN UINT32 PageSize + ); + +/** + This function extends one of the RTMR measurement register + in TDCS with the provided extension data in memory. + RTMR extending supports SHA384 which length is 48 bytes. + + @param[in] Data Point to the data to be extended + @param[in] DataLen Length of the data. Must be 48 + @param[in] Index RTMR index + + @return EFI_SUCCESS + @return EFI_INVALID_PARAMETER + @return EFI_DEVICE_ERROR + +**/ +EFI_STATUS +EFIAPI +TdExtendRtmr ( + IN UINT32 *Data, + IN UINT32 DataLen, + IN UINT8 Index + ); + +/** + This function gets the Td guest shared page mask. + + The guest indicates if a page is shared using the Guest Physical Address + (GPA) Shared (S) bit. If the GPA Width(GPAW) is 48, the S-bit is bit-47. + If the GPAW is 52, the S-bit is bit-51. + + @return Shared page bit mask +**/ +UINT64 +EFIAPI +TdSharedPageMask ( + VOID + ); + +/** + This function gets the maximum number of Virtual CPUs that are usable for + Td Guest. + + @return maximum Virtual CPUs number +**/ +UINT32 +EFIAPI +TdMaxVCpuNum ( + VOID + ); + +/** + This function gets the number of Virtual CPUs that are usable for Td + Guest. + + @return Virtual CPUs number +**/ +UINT32 +EFIAPI +TdVCpuNum ( + VOID + ); + +#endif diff --git a/MdePkg/Library/TdxLib/AcceptPages.c b/MdePkg/Library/TdxLib/AcceptPages.c new file mode 100644 index 000000000000..651d47a8d8a1 --- /dev/null +++ b/MdePkg/Library/TdxLib/AcceptPages.c @@ -0,0 +1,180 @@ +/** @file + + Unaccepted memory is a special type of private memory. In Td guest + TDCALL [TDG.MEM.PAGE.ACCEPT] is invoked to accept the unaccepted + memory before use it. + + Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include + +UINT64 mNumberOfDuplicatedAcceptedPages; + +#define TDX_ACCEPTPAGE_MAX_RETRIED 3 + +// PageSize is mapped to PageLevel like below: +// 4KB - 0, 2MB - 1 +UINT32 mTdxAcceptPageLevelMap[2] = { + SIZE_4KB, + SIZE_2MB +}; + +#define INVALID_ACCEPT_PAGELEVEL ARRAY_SIZE(mTdxAcceptPageLevelMap) + +/** + This function gets the PageLevel according to the input page size. + + @param[in] PageSize Page size + + @return UINT32 The mapped page level +**/ +UINT32 +GetGpaPageLevel ( + UINT32 PageSize + ) +{ + UINT32 Index; + + for (Index = 0; Index < ARRAY_SIZE (mTdxAcceptPageLevelMap); Index++) { + if (mTdxAcceptPageLevelMap[Index] == PageSize) { + break; + } + } + + return Index; +} + +/** + This function accept a pending private page, and initialize the page to + all-0 using the TD ephemeral private key. + + Sometimes TDCALL [TDG.MEM.PAGE.ACCEPT] may return + TDX_EXIT_REASON_PAGE_SIZE_MISMATCH. It indicates the input PageLevel is + not workable. In this case we need to try to fallback to a smaller + PageLevel if possible. + + @param[in] StartAddress Guest physical address of the private + page to accept. [63:52] and [11:0] must be 0. + @param[in] NumberOfPages Number of the pages to be accepted. + @param[in] PageSize GPA page size. Only accept 2M/4K size. + + @return EFI_SUCCESS Accept successfully + @return others Indicate other errors +**/ +EFI_STATUS +EFIAPI +TdAcceptPages ( + IN UINT64 StartAddress, + IN UINT64 NumberOfPages, + IN UINT32 PageSize + ) +{ + EFI_STATUS Status; + UINT64 Address; + UINT64 TdxStatus; + UINT64 Index; + UINT32 GpaPageLevel; + UINT32 PageSize2; + UINTN Retried; + + Retried = 0; + + if ((StartAddress & ~0xFFFFFFFFFF000ULL) != 0) { + ASSERT (FALSE); + DEBUG ((DEBUG_ERROR, "Accept page address(0x%llx) is not valid. [63:52] and [11:0] must be 0\n", StartAddress)); + return EFI_INVALID_PARAMETER; + } + + Address = StartAddress; + + GpaPageLevel = GetGpaPageLevel (PageSize); + if (GpaPageLevel == INVALID_ACCEPT_PAGELEVEL) { + ASSERT (FALSE); + DEBUG ((DEBUG_ERROR, "Accept page size must be 4K/2M. Invalid page size - 0x%llx\n", PageSize)); + return EFI_INVALID_PARAMETER; + } + + Status = EFI_SUCCESS; + for (Index = 0; Index < NumberOfPages; Index++) { + Retried = 0; + +DoAcceptPage: + TdxStatus = TdCall (TDCALL_TDACCEPTPAGE, Address | GpaPageLevel, 0, 0, 0); + if (TdxStatus != TDX_EXIT_REASON_SUCCESS) { + if ((TdxStatus & ~0xFFFFULL) == TDX_EXIT_REASON_PAGE_ALREADY_ACCEPTED) { + // + // Already accepted + // + mNumberOfDuplicatedAcceptedPages++; + DEBUG ((DEBUG_WARN, "Page at Address (0x%llx) has already been accepted. - %d\n", Address, mNumberOfDuplicatedAcceptedPages)); + } else if ((TdxStatus & ~0xFFFFULL) == TDX_EXIT_REASON_PAGE_SIZE_MISMATCH) { + // + // GpaPageLevel is mismatch, fall back to a smaller GpaPageLevel if possible + // + DEBUG ((DEBUG_VERBOSE, "Address %llx cannot be accepted in PageLevel of %d\n", Address, GpaPageLevel)); + + if (GpaPageLevel == 0) { + // + // Cannot fall back to smaller page level + // + DEBUG ((DEBUG_ERROR, "AcceptPage cannot fallback from PageLevel %d\n", GpaPageLevel)); + Status = EFI_INVALID_PARAMETER; + break; + } else { + // + // Fall back to a smaller page size + // + PageSize2 = mTdxAcceptPageLevelMap[GpaPageLevel - 1]; + Status = TdAcceptPages (Address, 512, PageSize2); + if (EFI_ERROR (Status)) { + break; + } + } + } else if ((TdxStatus & ~0xFFFFULL) == TDX_EXIT_REASON_OPERAND_BUSY) { + // + // Concurrent TDG.MEM.PAGE.ACCEPT is using the same Secure EPT entry + // So try it again. There is a max retried count. If Retried exceeds the max count, + // report the error and quit. + // + Retried += 1; + if (Retried > TDX_ACCEPTPAGE_MAX_RETRIED) { + DEBUG (( + DEBUG_ERROR, + "Address %llx (%d) failed to be accepted because of OPERAND_BUSY. Retried %d time.\n", + Address, + Index, + Retried + )); + Status = EFI_INVALID_PARAMETER; + break; + } else { + goto DoAcceptPage; + } + } else { + // + // Other errors + // + DEBUG (( + DEBUG_ERROR, + "Address %llx (%d) failed to be accepted. Error = 0x%llx\n", + Address, + Index, + TdxStatus + )); + Status = EFI_INVALID_PARAMETER; + break; + } + } + + Address += PageSize; + } + + return Status; +} diff --git a/MdePkg/Library/TdxLib/Rtmr.c b/MdePkg/Library/TdxLib/Rtmr.c new file mode 100644 index 000000000000..bdc91b3ebe6a --- /dev/null +++ b/MdePkg/Library/TdxLib/Rtmr.c @@ -0,0 +1,83 @@ +/** @file + + Extends one of the RTMR measurement registers in TDCS with the provided + extension data in memory. + + Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include + +#define RTMR_COUNT 4 +#define TD_EXTEND_BUFFER_LEN (64 + 48) + +UINT8 mExtendBuffer[TD_EXTEND_BUFFER_LEN]; + +/** + This function extends one of the RTMR measurement register + in TDCS with the provided extension data in memory. + RTMR extending supports SHA384 which length is 48 bytes. + + @param[in] Data Point to the data to be extended + @param[in] DataLen Length of the data. Must be 48 + @param[in] Index RTMR index + + @return EFI_SUCCESS + @return EFI_INVALID_PARAMETER + @return EFI_DEVICE_ERROR + +**/ +EFI_STATUS +EFIAPI +TdExtendRtmr ( + IN UINT32 *Data, + IN UINT32 DataLen, + IN UINT8 Index + ) +{ + EFI_STATUS Status; + UINT64 TdCallStatus; + UINT8 *ExtendBuffer; + + Status = EFI_SUCCESS; + + ASSERT (Data != NULL); + ASSERT (DataLen == SHA384_DIGEST_SIZE); + ASSERT (Index >= 0 && Index < RTMR_COUNT); + + if ((Data == NULL) || (DataLen != SHA384_DIGEST_SIZE) || (Index >= RTMR_COUNT)) { + return EFI_INVALID_PARAMETER; + } + + // TD.RTMR.EXTEND requires 64B-aligned guest physical address of + // 48B-extension data. We use ALIGN_POINTER(Pointer, 64) to get + // the 64B-aligned guest physical address. + ExtendBuffer = ALIGN_POINTER (mExtendBuffer, 64); + ASSERT (((UINTN)ExtendBuffer & 0x3f) == 0); + + ZeroMem (ExtendBuffer, SHA384_DIGEST_SIZE); + CopyMem (ExtendBuffer, Data, SHA384_DIGEST_SIZE); + + TdCallStatus = TdCall (TDCALL_TDEXTENDRTMR, (UINT64)(UINTN)ExtendBuffer, Index, 0, 0); + + if (TdCallStatus == TDX_EXIT_REASON_SUCCESS) { + Status = EFI_SUCCESS; + } else if (TdCallStatus == TDX_EXIT_REASON_OPERAND_INVALID) { + Status = EFI_INVALID_PARAMETER; + } else { + Status = EFI_DEVICE_ERROR; + } + + if (Status != EFI_SUCCESS) { + DEBUG ((DEBUG_ERROR, "Error returned from TdExtendRtmr call - 0x%lx\n", TdCallStatus)); + } + + return Status; +} diff --git a/MdePkg/Library/TdxLib/TdInfo.c b/MdePkg/Library/TdxLib/TdInfo.c new file mode 100644 index 000000000000..a40a15116f30 --- /dev/null +++ b/MdePkg/Library/TdxLib/TdInfo.c @@ -0,0 +1,114 @@ +/** @file + + Fetch the Tdx info. + + Copyright (c) 2021, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include + +UINT64 mTdSharedPageMask = 0; +UINT32 mTdMaxVCpuNum = 0; +UINT32 mTdVCpuNum = 0; +BOOLEAN mTdDataReturned = FALSE; + +/** + This function call TDCALL_TDINFO to get the TD_RETURN_DATA. + If the TDCALL is successful, populate below variables: + - mTdSharedPageMask + - mTdMaxVCpunum + - mTdVCpuNum + - mTdDataReturned + + @return TRUE The TDCALL is successful and above variables are populated. + @return FALSE The TDCALL is failed. Above variables are not set. +**/ +BOOLEAN +GetTdInfo ( + VOID + ) +{ + UINT64 Status; + TD_RETURN_DATA TdReturnData; + UINT8 Gpaw; + + Status = TdCall (TDCALL_TDINFO, 0, 0, 0, &TdReturnData); + if (Status == TDX_EXIT_REASON_SUCCESS) { + Gpaw = (UINT8)(TdReturnData.TdInfo.Gpaw & 0x3f); + mTdSharedPageMask = 1ULL << (Gpaw - 1); + mTdMaxVCpuNum = TdReturnData.TdInfo.MaxVcpus; + mTdVCpuNum = TdReturnData.TdInfo.NumVcpus; + mTdDataReturned = TRUE; + } else { + DEBUG ((DEBUG_ERROR, "Failed call TDCALL_TDINFO. %llx\n", Status)); + mTdDataReturned = FALSE; + } + + return mTdDataReturned; +} + +/** + This function gets the Td guest shared page mask. + + The guest indicates if a page is shared using the Guest Physical Address + (GPA) Shared (S) bit. If the GPA Width(GPAW) is 48, the S-bit is bit-47. + If the GPAW is 52, the S-bit is bit-51. + + @return Shared page bit mask +**/ +UINT64 +EFIAPI +TdSharedPageMask ( + VOID + ) +{ + if (mTdDataReturned) { + return mTdSharedPageMask; + } + + return GetTdInfo () ? mTdSharedPageMask : 0; +} + +/** + This function gets the maximum number of Virtual CPUs that are usable for + Td Guest. + + @return maximum Virtual CPUs number +**/ +UINT32 +EFIAPI +TdMaxVCpuNum ( + VOID + ) +{ + if (mTdDataReturned) { + return mTdMaxVCpuNum; + } + + return GetTdInfo () ? mTdMaxVCpuNum : 0; +} + +/** + This function gets the number of Virtual CPUs that are usable for Td + Guest. + + @return Virtual CPUs number +**/ +UINT32 +EFIAPI +TdVCpuNum ( + VOID + ) +{ + if (mTdDataReturned) { + return mTdVCpuNum; + } + + return GetTdInfo () ? mTdVCpuNum : 0; +} diff --git a/MdePkg/Library/TdxLib/TdxLib.inf b/MdePkg/Library/TdxLib/TdxLib.inf new file mode 100644 index 000000000000..442e63d079da --- /dev/null +++ b/MdePkg/Library/TdxLib/TdxLib.inf @@ -0,0 +1,37 @@ +## @file +# Tdx library +# +# Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = TdxLib + FILE_GUID = 032A8E0D-0C27-40C0-9CAA-23B731C1B223 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = TdxLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources.IA32] + TdxLibNull.c + +[Sources.X64] + AcceptPages.c + Rtmr.c + TdInfo.c + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib diff --git a/MdePkg/Library/TdxLib/TdxLibNull.c b/MdePkg/Library/TdxLib/TdxLibNull.c new file mode 100644 index 000000000000..83ab929b4a3b --- /dev/null +++ b/MdePkg/Library/TdxLib/TdxLibNull.c @@ -0,0 +1,107 @@ +/** @file + + Null stub of TdxLib + + Copyright (c) 2021, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include + +/** + This function accepts a pending private page, and initialize the page to + all-0 using the TD ephemeral private key. + + @param[in] StartAddress Guest physical address of the private page + to accept. + @param[in] NumberOfPages Number of the pages to be accepted. + @param[in] PageSize GPA page size. Accept 1G/2M/4K page size. + + @return EFI_SUCCESS +**/ +EFI_STATUS +EFIAPI +TdAcceptPages ( + IN UINT64 StartAddress, + IN UINT64 NumberOfPages, + IN UINT32 PageSize + ) +{ + return EFI_UNSUPPORTED; +} + +/** + This function extends one of the RTMR measurement register + in TDCS with the provided extension data in memory. + RTMR extending supports SHA384 which length is 48 bytes. + + @param[in] Data Point to the data to be extended + @param[in] DataLen Length of the data. Must be 48 + @param[in] Index RTMR index + + @return EFI_SUCCESS + @return EFI_INVALID_PARAMETER + @return EFI_DEVICE_ERROR + +**/ +EFI_STATUS +EFIAPI +TdExtendRtmr ( + IN UINT32 *Data, + IN UINT32 DataLen, + IN UINT8 Index + ) +{ + return EFI_UNSUPPORTED; +} + +/** + This function gets the Td guest shared page mask. + + The guest indicates if a page is shared using the Guest Physical Address + (GPA) Shared (S) bit. If the GPA Width(GPAW) is 48, the S-bit is bit-47. + If the GPAW is 52, the S-bit is bit-51. + + @return Shared page bit mask +**/ +UINT64 +EFIAPI +TdSharedPageMask ( + VOID + ) +{ + return 0; +} + +/** + This function gets the maximum number of Virtual CPUs that are usable for + Td Guest. + + @return maximum Virtual CPUs number +**/ +UINT32 +EFIAPI +TdMaxVCpuNum ( + VOID + ) +{ + return 0; +} + +/** + This function gets the number of Virtual CPUs that are usable for Td + Guest. + + @return Virtual CPUs number +**/ +UINT32 +EFIAPI +TdVCpuNum ( + VOID + ) +{ + return 0; +} diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index 59b405928bf8..1934c9840423 100644 --- a/MdePkg/MdePkg.dec +++ b/MdePkg/MdePkg.dec @@ -296,6 +296,9 @@ ## @libraryclass Provides services to log the SMI handler registration. SmiHandlerProfileLib|Include/Library/SmiHandlerProfileLib.h + ## @libraryclass Provides function to support TDX processing. + TdxLib|Include/Library/TdxLib.h + [Guids] # # GUID defined in UEFI2.1/UEFI2.0/EFI1.1 diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc index a94959169b2f..d6a7af412be7 100644 --- a/MdePkg/MdePkg.dsc +++ b/MdePkg/MdePkg.dsc @@ -175,6 +175,7 @@ MdePkg/Library/SmiHandlerProfileLibNull/SmiHandlerProfileLibNull.inf MdePkg/Library/MmServicesTableLib/MmServicesTableLib.inf MdePkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLibNull.inf + MdePkg/Library/TdxLib/TdxLib.inf [Components.EBC] MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf -- 2.29.2.windows.2