* [PATCH V2 0/4] Add Intel TDX support in OvmfPkg/ResetVector @ 2021-07-22 5:52 Min Xu 2021-07-22 5:52 ` [PATCH V2 1/4] OvmfPkg: Add Tdx BFV/CFV PCDs and PcdOvmfImageSizeInKb Min Xu ` (3 more replies) 0 siblings, 4 replies; 16+ messages in thread From: Min Xu @ 2021-07-22 5:52 UTC (permalink / raw) To: devel Cc: Min Xu, Ard Biesheuvel, Jordan Justen, Brijesh Singh, Erdem Aktas, James Bottomley, Jiewen Yao, Tom Lendacky, Eric Dong, Ray Ni, Debkumar De REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3429 Intel's Trust Domain Extensions (Intel TDX) refers to an Intel technology that extends Virtual Machines Extensions (VMX) and Multi-Key Total Memory Encryption (MKTME) with a new kind of virutal machines guest called a Trust Domain (TD). A TD is desinged to run in a CPU mode that protects the confidentiality of TD memory contents and the TD's CPU state from other software, including the hosting Virtual-Machine Monitor (VMM), unless explicitly shared by the TD itself. The patch-sets to support Intel TDX in OvmfPkg is split into several waves. This is wave1 which adds Intel TDX support in OvmfPkg/ResetVector. Note: TDX only works in X64. Patch 1 add the PCDs of BFV/CFV. BFV is the code part of the image. CFV is the configuration part. BFV is measured by VMM and CFV is measured by TDVF itself. Patch 2 add TdxMetadata in OvmfPkg/ResetVector. It describes the information about the image so that VMM can do the initialization and measurement based on these information. Patch 3 updates the UefiCpuPkg/Vtf0/Main.asm to add Main32 entrypoint. It is because on reset all the CPUs are in 32-bit protected mode. In the Main32 entry point, Init32 is called to do the 32-bit initializaiton. In UefiCpuPkg/ResetVector/Vtf0/Ia32, Init32.asm is added. It is a null stub of the 32-bit initialization. The actual work is implemented in OvmfPkg. In Patch 4, InitTdx.asm does the tdx initialization, ReloadFlat32 loads the GDT and sets the CR0, then jump to 32-bit protected mode. Init32.asm put above 2 together to complete the 32-bit initializaiton. After that page tables are built and set, then jump to SecEntry. [TDX]: https://software.intel.com/content/dam/develop/external/us/en/ documents/tdx-whitepaper-final9-17.pdf [TDVF]: https://software.intel.com/content/dam/develop/external/us/en/ documents/tdx-virtual-firmware-design-guide-rev-1.pdf Code is at https://github.com/mxu9/edk2/tree/tdvf_wave1.v2 v2 changes: - Move InitTdx.asm and ReloadFlat32.asm from UefiCpuPkg/ResetVector/Vtf0 to OvmfPkg/ResetVector. Init32.asm is created which is a null stub of 32-bit initialization. In Main32 just simply call Init32. It makes the Main.asm in UefiCpuPkg/ResetVector clean and clear. - Init32.asm/InitTdx.asm/ReloadFlat32.asm are created under OvmfPkg/ResetVector/Ia32. - Update some descriptions of the patch-sets. - Update the REF link in cover letter. - Add Ard Biesheuvel in Cc list. v1: https://edk2.groups.io/g/devel/message/77675 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: Eric Dong <eric.dong@intel.com> Cc: Ray Ni <ray.ni@intel.com> CC: Debkumar De <debkumar.de@intel.com> Signed-off-by: Min Xu <min.m.xu@intel.com> Min Xu (4): OvmfPkg: Add Tdx BFV/CFV PCDs and PcdOvmfImageSizeInKb OvmfPkg: Add Tdx metadata UefiCpuPkg/ResetVector: Add Main32 entry point in Main.asm OvmfPkg/ResetVector: Update ResetVector to support Tdx OvmfPkg/OvmfPkg.dec | 13 +++ OvmfPkg/OvmfPkgDefines.fdf.inc | 12 ++- OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm | 38 ++++++++ OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm | 47 ++++++++++ OvmfPkg/ResetVector/Ia32/Init32.asm | 34 +++++++ OvmfPkg/ResetVector/Ia32/InitTdx.asm | 57 ++++++++++++ OvmfPkg/ResetVector/Ia32/PageTables64.asm | 41 +++++++++ OvmfPkg/ResetVector/Ia32/ReloadFlat32.asm | 44 +++++++++ OvmfPkg/ResetVector/ResetVector.inf | 11 ++- OvmfPkg/ResetVector/ResetVector.nasmb | 65 ++++++++++++- OvmfPkg/ResetVector/X64/TdxMetadata.asm | 97 ++++++++++++++++++++ UefiCpuPkg/ResetVector/Vtf0/Ia32/Init32.asm | 13 +++ UefiCpuPkg/ResetVector/Vtf0/Main.asm | 14 +++ UefiCpuPkg/ResetVector/Vtf0/Vtf0.nasmb | 2 +- 14 files changed, 483 insertions(+), 5 deletions(-) create mode 100644 OvmfPkg/ResetVector/Ia32/Init32.asm create mode 100644 OvmfPkg/ResetVector/Ia32/InitTdx.asm create mode 100644 OvmfPkg/ResetVector/Ia32/ReloadFlat32.asm create mode 100644 OvmfPkg/ResetVector/X64/TdxMetadata.asm create mode 100644 UefiCpuPkg/ResetVector/Vtf0/Ia32/Init32.asm -- 2.29.2.windows.2 ^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH V2 1/4] OvmfPkg: Add Tdx BFV/CFV PCDs and PcdOvmfImageSizeInKb 2021-07-22 5:52 [PATCH V2 0/4] Add Intel TDX support in OvmfPkg/ResetVector Min Xu @ 2021-07-22 5:52 ` Min Xu 2021-07-22 5:52 ` [PATCH V2 2/4] OvmfPkg: Add Tdx metadata Min Xu ` (2 subsequent siblings) 3 siblings, 0 replies; 16+ messages in thread From: Min Xu @ 2021-07-22 5:52 UTC (permalink / raw) To: devel Cc: Min Xu, Ard Biesheuvel, Brijesh Singh, Erdem Aktas, James Bottomley, Jiewen Yao, Tom Lendacky RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3429 Tdx Virtual Firmware (TDVF) includes one Firmware Volume (FV) known as the Boot Firmware Volume (BFV). The FV format is defined in the UEFI Platform Initialization (PI) spec. BFV includes all TDVF components required during boot. TDVF also include a configuration firmware volume (CFV) that is separated from the BFV. The reason is because the CFV is measured in RTMR, while the BFV is measured in MRTD. In practice BFV is the code part of Ovmf image. CFV is the vars part of Ovmf image (exclude the SPARE part). PcdOvmfImageSizeInKb is added which is used to calculate the offset of TdxMetadata in ResetVectorVtf0.asm. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> 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> Signed-off-by: Min Xu <min.m.xu@intel.com> --- OvmfPkg/OvmfPkg.dec | 13 +++++++++++++ OvmfPkg/OvmfPkgDefines.fdf.inc | 12 +++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec index 6ae733f6e39f..6d9bb91e9274 100644 --- a/OvmfPkg/OvmfPkg.dec +++ b/OvmfPkg/OvmfPkg.dec @@ -321,6 +321,19 @@ gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretBase|0x0|UINT32|0x42 gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretSize|0x0|UINT32|0x43 + ## The base address and size of the TDX Cfv base and size. + gUefiOvmfPkgTokenSpaceGuid.PcdCfvBase|0|UINT32|0x47 + gUefiOvmfPkgTokenSpaceGuid.PcdCfvRawDataOffset|0|UINT32|0x48 + gUefiOvmfPkgTokenSpaceGuid.PcdCfvRawDataSize|0|UINT32|0x49 + + ## The base address and size of the TDX Bfv base and size. + gUefiOvmfPkgTokenSpaceGuid.PcdBfvBase|0|UINT32|0x4a + gUefiOvmfPkgTokenSpaceGuid.PcdBfvRawDataOffset|0|UINT32|0x4b + gUefiOvmfPkgTokenSpaceGuid.PcdBfvRawDataSize|0|UINT32|0x4c + + ## Size of the Ovmf image in KB + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfImageSizeInKb|0|UINT32|0x4d + [PcdsDynamic, PcdsDynamicEx] gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2 gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10 diff --git a/OvmfPkg/OvmfPkgDefines.fdf.inc b/OvmfPkg/OvmfPkgDefines.fdf.inc index 35fd454b97ab..401e491e4cbe 100644 --- a/OvmfPkg/OvmfPkgDefines.fdf.inc +++ b/OvmfPkg/OvmfPkgDefines.fdf.inc @@ -2,13 +2,14 @@ # FDF include file that defines the main macros and sets the dependent PCDs. # # Copyright (C) 2014, Red Hat, Inc. -# Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR> +# Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.<BR> # # SPDX-License-Identifier: BSD-2-Clause-Patent # ## DEFINE BLOCK_SIZE = 0x1000 +DEFINE VARS_OFFSET = 0 # # A firmware binary built with FD_SIZE_IN_KB=1024, and a firmware binary built @@ -66,6 +67,7 @@ DEFINE SECFV_OFFSET = 0x003CC000 DEFINE SECFV_SIZE = 0x34000 !endif +SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfImageSizeInKb = $(FD_SIZE_IN_KB) SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress = $(FW_BASE_ADDRESS) SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize = $(FW_SIZE) SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareBlockSize = $(BLOCK_SIZE) @@ -82,6 +84,14 @@ SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize = $(BLOCK_SIZ SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageFtwSpareBase = gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageFtwWorkingBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize = $(VARS_SPARE_SIZE) +SET gUefiOvmfPkgTokenSpaceGuid.PcdCfvBase = $(FW_BASE_ADDRESS) +SET gUefiOvmfPkgTokenSpaceGuid.PcdCfvRawDataOffset = $(VARS_OFFSET) +SET gUefiOvmfPkgTokenSpaceGuid.PcdCfvRawDataSize = $(VARS_LIVE_SIZE) + +SET gUefiOvmfPkgTokenSpaceGuid.PcdBfvBase = $(CODE_BASE_ADDRESS) +SET gUefiOvmfPkgTokenSpaceGuid.PcdBfvRawDataOffset = $(VARS_SIZE) +SET gUefiOvmfPkgTokenSpaceGuid.PcdBfvRawDataSize = $(CODE_SIZE) + !if $(SMM_REQUIRE) == TRUE SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64 = gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageVariableBase SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase = gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageFtwWorkingBase -- 2.29.2.windows.2 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH V2 2/4] OvmfPkg: Add Tdx metadata 2021-07-22 5:52 [PATCH V2 0/4] Add Intel TDX support in OvmfPkg/ResetVector Min Xu 2021-07-22 5:52 ` [PATCH V2 1/4] OvmfPkg: Add Tdx BFV/CFV PCDs and PcdOvmfImageSizeInKb Min Xu @ 2021-07-22 5:52 ` Min Xu 2021-07-22 5:52 ` [PATCH V2 3/4] UefiCpuPkg/ResetVector: Add Main32 entry point in Main.asm Min Xu 2021-07-22 5:52 ` [PATCH V2 4/4] OvmfPkg/ResetVector: Update ResetVector to support Tdx Min Xu 3 siblings, 0 replies; 16+ messages in thread From: Min Xu @ 2021-07-22 5:52 UTC (permalink / raw) To: devel Cc: Min Xu, Ard Biesheuvel, Brijesh Singh, Erdem Aktas, James Bottomley, Jiewen Yao, Tom Lendacky RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3429 Tdx Metadata describes the information about the image for VMM use. For example, the base address and length of the TdHob, TdMailbox, etc. Its offset is put in a GUID-ed structure which is appended in the GUID-ed chain from a fixed GPA (0xffffffd0). Below are the items in TdxMetadata: _Bfv: Boot Firmware Volume _Cfv: Configuration Firmware Volume _Stack: Initial stack _Heap: Initial heap _MailBox: TDVF reserves the memory region so each AP can receive the message sent by the guest OS. _TdHob: VMM pass the resource information in TdHob to TDVF. _TdxPageTable: If 5-level page table is supported (GPAW is 52), a top level page directory pointers (1 * 256TB entry) is generated in this page. _OvmfPageTable: Initial page table for standard Ovmf. TDVF indicate above chunk of temporary initialized memory region (_Stack/ _Heap/_MailBox/_TdHob/_TdxPageTables/OvmfPageTable) to support TDVF code finishing the memory initialization. Because the other unaccepted memory cannot be accessed until they're accepted. Since AMD SEV has already defined some SEV specific memory region in MEMFD. SEV and TDX will not run at the same time. So TDX re-use the memory region defined by SEV. - MailBox : PcdOvmfSecGhcbBackupBase|PcdOvmfSecGhcbBackupSize - TdHob : PcdOvmfSecGhcbBase|PcdOvmfSecGhcbSize - TdxPageTable : PcdOvmfSecGhcbPageTableBase|PcdOvmfSecGhcbPageTableSize Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> 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> Signed-off-by: Min Xu <min.m.xu@intel.com> --- OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm | 17 ++++ OvmfPkg/ResetVector/ResetVector.inf | 11 ++- OvmfPkg/ResetVector/ResetVector.nasmb | 47 +++++++++- OvmfPkg/ResetVector/X64/TdxMetadata.asm | 97 ++++++++++++++++++++ 4 files changed, 169 insertions(+), 3 deletions(-) create mode 100644 OvmfPkg/ResetVector/X64/TdxMetadata.asm diff --git a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm index 9c0b5853a46f..ac86ce69ebe8 100644 --- a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm +++ b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm @@ -47,6 +47,23 @@ TIMES (15 - ((guidedStructureEnd - guidedStructureStart + 15) % 16)) DB 0 ; guidedStructureStart: +%ifdef ARCH_X64 +; +; TDX Metadata offset block +; +; If TdxMetadata.asm is included then we need below block which describes +; the offset of TdxMetadata block in Ovmf image +; +; GUID : e47a6535-984a-4798-865e-4685a7bf8ec2 +; +tdxMetadataOffsetStart: + DD (OVMF_IMAGE_SIZE_IN_KB * 1024 - (fourGigabytes - TdxMetadataGuid - 16)) + DD tdxMetadataOffsetEnd - tdxMetadataOffsetStart + DB 0x35, 0x65, 0x7a, 0xe4, 0x4a, 0x98, 0x98, 0x47 + DB 0x86, 0x5e, 0x46, 0x85, 0xa7, 0xbf, 0x8e, 0xc2 +tdxMetadataOffsetEnd: + +%endif ; ; SEV Secret block ; diff --git a/OvmfPkg/ResetVector/ResetVector.inf b/OvmfPkg/ResetVector/ResetVector.inf index dc38f68919cd..fd65c0c9621d 100644 --- a/OvmfPkg/ResetVector/ResetVector.inf +++ b/OvmfPkg/ResetVector/ResetVector.inf @@ -1,7 +1,7 @@ ## @file # Reset Vector # -# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR> +# Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.<BR> # # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -43,6 +43,15 @@ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupBase + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupSize + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfImageSizeInKb + gUefiOvmfPkgTokenSpaceGuid.PcdCfvBase + gUefiOvmfPkgTokenSpaceGuid.PcdCfvRawDataOffset + gUefiOvmfPkgTokenSpaceGuid.PcdCfvRawDataSize + gUefiOvmfPkgTokenSpaceGuid.PcdBfvBase + gUefiOvmfPkgTokenSpaceGuid.PcdBfvRawDataOffset + gUefiOvmfPkgTokenSpaceGuid.PcdBfvRawDataSize [FixedPcd] gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretBase diff --git a/OvmfPkg/ResetVector/ResetVector.nasmb b/OvmfPkg/ResetVector/ResetVector.nasmb index 5fbacaed5f9d..b653fe87abd6 100644 --- a/OvmfPkg/ResetVector/ResetVector.nasmb +++ b/OvmfPkg/ResetVector/ResetVector.nasmb @@ -4,6 +4,7 @@ ; ; Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR> ; Copyright (c) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR> +; Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> ; SPDX-License-Identifier: BSD-2-Clause-Patent ; ;------------------------------------------------------------------------------ @@ -67,6 +68,44 @@ %error "This implementation inherently depends on PcdOvmfSecGhcbBase not straddling a 2MB boundary" %endif + ; + ; TDX meta data + ; + %define TDX_METADATA_SECTION_TYPE_BFV 0 + %define TDX_METADATA_SECTION_TYPE_CFV 1 + %define TDX_METADATA_SECTION_TYPE_TD_HOB 2 + %define TDX_METADATA_SECTION_TYPE_TEMP_MEM 3 + %define TDX_METADATA_VERSION 1 + %define TDX_METADATA_ATTRIBUTES_EXTENDMR 0x00000001 + + %define TDX_BFV_RAW_DATA_OFFSET FixedPcdGet32 (PcdBfvRawDataOffset) + %define TDX_BFV_RAW_DATA_SIZE FixedPcdGet32 (PcdBfvRawDataSize) + %define TDX_BFV_MEMORY_BASE FixedPcdGet32 (PcdBfvBase) + %define TDX_BFV_MEMORY_SIZE FixedPcdGet32 (PcdBfvRawDataSize) + + %define TDX_CFV_RAW_DATA_OFFSET FixedPcdGet32 (PcdCfvRawDataOffset) + %define TDX_CFV_RAW_DATA_SIZE FixedPcdGet32 (PcdCfvRawDataSize) + %define TDX_CFV_MEMORY_BASE FixedPcdGet32 (PcdCfvBase), + %define TDX_CFV_MEMORY_SIZE FixedPcdGet32 (PcdCfvRawDataSize), + + %define TDX_HEAP_MEMORY_BASE FixedPcdGet32 (PcdOvmfSecPeiTempRamBase) + %define TDX_HEAP_MEMORY_SIZE FixedPcdGet32 (PcdOvmfSecPeiTempRamSize) / 2 + + %define TDX_STACK_MEMORY_BASE (TDX_HEAP_MEMORY_BASE + TDX_HEAP_MEMORY_SIZE) + %define TDX_STACK_MEMORY_SIZE FixedPcdGet32 (PcdOvmfSecPeiTempRamSize) / 2 + + %define TDX_HOB_MEMORY_BASE FixedPcdGet32 (PcdOvmfSecGhcbBase) + %define TDX_HOB_MEMORY_SIZE FixedPcdGet32 (PcdOvmfSecGhcbSize) + + %define TDX_MAILBOX_MEMORY_BASE FixedPcdGet32 (PcdOvmfSecGhcbBackupBase) + %define TDX_MAILBOX_MEMORY_SIZE FixedPcdGet32 (PcdOvmfSecGhcbBackupSize) + + %define OVMF_PAGE_TABLE_BASE FixedPcdGet32 (PcdOvmfSecPageTablesBase) + %define OVMF_PAGE_TABLE_SIZE FixedPcdGet32 (PcdOvmfSecPageTablesSize) + + %define TDX_EXTRA_PAGE_TABLE_BASE FixedPcdGet32 (PcdOvmfSecGhcbPageTableBase) + %define TDX_EXTRA_PAGE_TABLE_SIZE FixedPcdGet32 (PcdOvmfSecGhcbPageTableSize) + %define PT_ADDR(Offset) (FixedPcdGet32 (PcdOvmfSecPageTablesBase) + (Offset)) %define GHCB_PT_ADDR (FixedPcdGet32 (PcdOvmfSecGhcbPageTableBase)) @@ -76,8 +115,11 @@ %define SEV_ES_WORK_AREA_RDRAND (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 8) %define SEV_ES_WORK_AREA_ENC_MASK (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 16) %define SEV_ES_VC_TOP_OF_STACK (FixedPcdGet32 (PcdOvmfSecPeiTempRamBase) + FixedPcdGet32 (PcdOvmfSecPeiTempRamSize)) -%include "Ia32/Flat32ToFlat64.asm" -%include "Ia32/PageTables64.asm" + + %include "X64/TdxMetadata.asm" + + %include "Ia32/Flat32ToFlat64.asm" + %include "Ia32/PageTables64.asm" %endif %include "Ia16/Real16ToFlat32.asm" @@ -88,5 +130,6 @@ %define SEV_ES_AP_RESET_IP FixedPcdGet32 (PcdSevEsWorkAreaBase) %define SEV_LAUNCH_SECRET_BASE FixedPcdGet32 (PcdSevLaunchSecretBase) %define SEV_LAUNCH_SECRET_SIZE FixedPcdGet32 (PcdSevLaunchSecretSize) + %define OVMF_IMAGE_SIZE_IN_KB FixedPcdGet32 (PcdOvmfImageSizeInKb) %include "Ia16/ResetVectorVtf0.asm" diff --git a/OvmfPkg/ResetVector/X64/TdxMetadata.asm b/OvmfPkg/ResetVector/X64/TdxMetadata.asm new file mode 100644 index 000000000000..8dba8daa0165 --- /dev/null +++ b/OvmfPkg/ResetVector/X64/TdxMetadata.asm @@ -0,0 +1,97 @@ +;------------------------------------------------------------------------------ +; @file +; Tdx Virtual Firmware metadata +; +; Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> +; SPDX-License-Identifier: BSD-2-Clause-Patent +; +;------------------------------------------------------------------------------ + +BITS 64 + +%define TDX_VIRTUAL_FIRMWARE + +ALIGN 16 +TIMES (15 - ((TdxGuidedStructureEnd - TdxGuidedStructureStart + 15) % 16)) DB 0 + +TdxGuidedStructureStart: + +; +; TDVF meta data +; +TdxMetadataGuid: + DB 0xf3, 0xf9, 0xea, 0xe9, 0x8e, 0x16, 0xd5, 0x44 + DB 0xa8, 0xeb, 0x7f, 0x4d, 0x87, 0x38, 0xf6, 0xae + +_Descriptor: + DB 'T','D','V','F' ; Signature + DD TdxGuidedStructureEnd - _Descriptor ; Length + DD TDX_METADATA_VERSION ; Version + DD (TdxGuidedStructureEnd - _Descriptor - 16)/32 ; Number of sections + +_Bfv: + DD TDX_BFV_RAW_DATA_OFFSET + DD TDX_BFV_RAW_DATA_SIZE + DQ TDX_BFV_MEMORY_BASE + DQ TDX_BFV_MEMORY_SIZE + DD TDX_METADATA_SECTION_TYPE_BFV + DD TDX_METADATA_ATTRIBUTES_EXTENDMR + +_Cfv: + DD TDX_CFV_RAW_DATA_OFFSET + DD TDX_CFV_RAW_DATA_SIZE + DQ TDX_CFV_MEMORY_BASE + DQ TDX_CFV_MEMORY_SIZE + DD TDX_METADATA_SECTION_TYPE_CFV + DD 0 + +_Stack: + DD 0 + DD 0 + DQ TDX_STACK_MEMORY_BASE + DQ TDX_STACK_MEMORY_SIZE + DD TDX_METADATA_SECTION_TYPE_TEMP_MEM + DD 0 + +_Heap: + DD 0 + DD 0 + DQ TDX_HEAP_MEMORY_BASE + DQ TDX_HEAP_MEMORY_SIZE + DD TDX_METADATA_SECTION_TYPE_TEMP_MEM + DD 0 + +_MailBox: + DD 0 + DD 0 + DQ TDX_MAILBOX_MEMORY_BASE + DQ TDX_MAILBOX_MEMORY_SIZE + DD TDX_METADATA_SECTION_TYPE_TEMP_MEM + DD 0 + +_TdHob: + DD 0 + DD 0 + DQ TDX_HOB_MEMORY_BASE + DQ TDX_HOB_MEMORY_SIZE + DD TDX_METADATA_SECTION_TYPE_TD_HOB + DD 0 + +_TdxPageTable: + DD 0 + DD 0 + DQ TDX_EXTRA_PAGE_TABLE_BASE + DQ TDX_EXTRA_PAGE_TABLE_SIZE + DD TDX_METADATA_SECTION_TYPE_TEMP_MEM + DD 0 + +_OvmfPageTable: + DD 0 + DD 0 + DQ OVMF_PAGE_TABLE_BASE + DQ OVMF_PAGE_TABLE_SIZE + DD TDX_METADATA_SECTION_TYPE_TEMP_MEM + DD 0 + +TdxGuidedStructureEnd: +ALIGN 16 -- 2.29.2.windows.2 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH V2 3/4] UefiCpuPkg/ResetVector: Add Main32 entry point in Main.asm 2021-07-22 5:52 [PATCH V2 0/4] Add Intel TDX support in OvmfPkg/ResetVector Min Xu 2021-07-22 5:52 ` [PATCH V2 1/4] OvmfPkg: Add Tdx BFV/CFV PCDs and PcdOvmfImageSizeInKb Min Xu 2021-07-22 5:52 ` [PATCH V2 2/4] OvmfPkg: Add Tdx metadata Min Xu @ 2021-07-22 5:52 ` Min Xu 2021-07-23 2:33 ` Ni, Ray 2021-07-25 6:07 ` Yao, Jiewen 2021-07-22 5:52 ` [PATCH V2 4/4] OvmfPkg/ResetVector: Update ResetVector to support Tdx Min Xu 3 siblings, 2 replies; 16+ messages in thread From: Min Xu @ 2021-07-22 5:52 UTC (permalink / raw) To: devel; +Cc: Min Xu, Eric Dong, Ray Ni, Jiewen Yao RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3429 In Tdx all CPUs "reset" to run on 32-bit protected mode with flat descriptor (paging disabled). Main32 entry point is added in UefiCpuPkg/ResetVector/Vtf0/Main.asm so that Main.asm can support the 32-bit protected mode. Init32.asm is the 32-bit initialization code. It is a null stub in UefiCpuPkg. The actual initialization can be implemented in the platform (OvmfPkg/ResetVector/Ia32/Init32.asm is the example.) Cc: Eric Dong <eric.dong@intel.com> Cc: Ray Ni <ray.ni@intel.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Signed-off-by: Min Xu <min.m.xu@intel.com> --- UefiCpuPkg/ResetVector/Vtf0/Ia32/Init32.asm | 13 +++++++++++++ UefiCpuPkg/ResetVector/Vtf0/Main.asm | 14 ++++++++++++++ UefiCpuPkg/ResetVector/Vtf0/Vtf0.nasmb | 2 +- 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 UefiCpuPkg/ResetVector/Vtf0/Ia32/Init32.asm diff --git a/UefiCpuPkg/ResetVector/Vtf0/Ia32/Init32.asm b/UefiCpuPkg/ResetVector/Vtf0/Ia32/Init32.asm new file mode 100644 index 000000000000..0cdae4a4a84a --- /dev/null +++ b/UefiCpuPkg/ResetVector/Vtf0/Ia32/Init32.asm @@ -0,0 +1,13 @@ +;------------------------------------------------------------------------------ +; @file +; 32-bit initialization code. +; Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> +; SPDX-License-Identifier: BSD-2-Clause-Patent +; +;------------------------------------------------------------------------------ + +BITS 32 + +Init32: + nop + OneTimeCallRet Init32 diff --git a/UefiCpuPkg/ResetVector/Vtf0/Main.asm b/UefiCpuPkg/ResetVector/Vtf0/Main.asm index 19d08482f831..4920c6937e1b 100644 --- a/UefiCpuPkg/ResetVector/Vtf0/Main.asm +++ b/UefiCpuPkg/ResetVector/Vtf0/Main.asm @@ -36,6 +36,20 @@ Main16: BITS 32 +%ifdef ARCH_X64 + + jmp SearchBfv + +; +; Entry point of Main32 +; +Main32: + + OneTimeCall Init32 + +%endif + +SearchBfv: ; ; Search for the Boot Firmware Volume (BFV) ; diff --git a/UefiCpuPkg/ResetVector/Vtf0/Vtf0.nasmb b/UefiCpuPkg/ResetVector/Vtf0/Vtf0.nasmb index 493738c79c1c..6493b9863c48 100644 --- a/UefiCpuPkg/ResetVector/Vtf0/Vtf0.nasmb +++ b/UefiCpuPkg/ResetVector/Vtf0/Vtf0.nasmb @@ -51,7 +51,7 @@ %include "Ia32/SearchForSecEntry.asm" %ifdef ARCH_X64 -%include "Ia32/Flat32ToFlat64.asm" +%include "Ia32/Init32.asm" %include "Ia32/PageTables64.asm" %endif -- 2.29.2.windows.2 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH V2 3/4] UefiCpuPkg/ResetVector: Add Main32 entry point in Main.asm 2021-07-22 5:52 ` [PATCH V2 3/4] UefiCpuPkg/ResetVector: Add Main32 entry point in Main.asm Min Xu @ 2021-07-23 2:33 ` Ni, Ray 2021-07-25 6:07 ` Yao, Jiewen 1 sibling, 0 replies; 16+ messages in thread From: Ni, Ray @ 2021-07-23 2:33 UTC (permalink / raw) To: Xu, Min M, devel@edk2.groups.io; +Cc: Dong, Eric, Yao, Jiewen Reviewed-by: Ray Ni <ray.ni@intel.com> > -----Original Message----- > From: Xu, Min M <min.m.xu@intel.com> > Sent: Thursday, July 22, 2021 1:52 PM > To: devel@edk2.groups.io > Cc: Xu, Min M <min.m.xu@intel.com>; Dong, Eric <eric.dong@intel.com>; Ni, Ray <ray.ni@intel.com>; Yao, Jiewen > <jiewen.yao@intel.com> > Subject: [PATCH V2 3/4] UefiCpuPkg/ResetVector: Add Main32 entry point in Main.asm > > RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3429 > > In Tdx all CPUs "reset" to run on 32-bit protected mode with flat > descriptor (paging disabled). Main32 entry point is added in > UefiCpuPkg/ResetVector/Vtf0/Main.asm so that Main.asm can support > the 32-bit protected mode. > > Init32.asm is the 32-bit initialization code. It is a null stub in > UefiCpuPkg. The actual initialization can be implemented in the platform > (OvmfPkg/ResetVector/Ia32/Init32.asm is the example.) > > Cc: Eric Dong <eric.dong@intel.com> > Cc: Ray Ni <ray.ni@intel.com> > Cc: Jiewen Yao <jiewen.yao@intel.com> > Signed-off-by: Min Xu <min.m.xu@intel.com> > --- > UefiCpuPkg/ResetVector/Vtf0/Ia32/Init32.asm | 13 +++++++++++++ > UefiCpuPkg/ResetVector/Vtf0/Main.asm | 14 ++++++++++++++ > UefiCpuPkg/ResetVector/Vtf0/Vtf0.nasmb | 2 +- > 3 files changed, 28 insertions(+), 1 deletion(-) > create mode 100644 UefiCpuPkg/ResetVector/Vtf0/Ia32/Init32.asm > > diff --git a/UefiCpuPkg/ResetVector/Vtf0/Ia32/Init32.asm b/UefiCpuPkg/ResetVector/Vtf0/Ia32/Init32.asm > new file mode 100644 > index 000000000000..0cdae4a4a84a > --- /dev/null > +++ b/UefiCpuPkg/ResetVector/Vtf0/Ia32/Init32.asm > @@ -0,0 +1,13 @@ > +;------------------------------------------------------------------------------ > +; @file > +; 32-bit initialization code. > +; Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> > +; SPDX-License-Identifier: BSD-2-Clause-Patent > +; > +;------------------------------------------------------------------------------ > + > +BITS 32 > + > +Init32: > + nop > + OneTimeCallRet Init32 > diff --git a/UefiCpuPkg/ResetVector/Vtf0/Main.asm b/UefiCpuPkg/ResetVector/Vtf0/Main.asm > index 19d08482f831..4920c6937e1b 100644 > --- a/UefiCpuPkg/ResetVector/Vtf0/Main.asm > +++ b/UefiCpuPkg/ResetVector/Vtf0/Main.asm > @@ -36,6 +36,20 @@ Main16: > > BITS 32 > > +%ifdef ARCH_X64 > + > + jmp SearchBfv > + > +; > +; Entry point of Main32 > +; > +Main32: > + > + OneTimeCall Init32 > + > +%endif > + > +SearchBfv: > ; > ; Search for the Boot Firmware Volume (BFV) > ; > diff --git a/UefiCpuPkg/ResetVector/Vtf0/Vtf0.nasmb b/UefiCpuPkg/ResetVector/Vtf0/Vtf0.nasmb > index 493738c79c1c..6493b9863c48 100644 > --- a/UefiCpuPkg/ResetVector/Vtf0/Vtf0.nasmb > +++ b/UefiCpuPkg/ResetVector/Vtf0/Vtf0.nasmb > @@ -51,7 +51,7 @@ > %include "Ia32/SearchForSecEntry.asm" > > %ifdef ARCH_X64 > -%include "Ia32/Flat32ToFlat64.asm" > +%include "Ia32/Init32.asm" > %include "Ia32/PageTables64.asm" > %endif > > -- > 2.29.2.windows.2 ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH V2 3/4] UefiCpuPkg/ResetVector: Add Main32 entry point in Main.asm 2021-07-22 5:52 ` [PATCH V2 3/4] UefiCpuPkg/ResetVector: Add Main32 entry point in Main.asm Min Xu 2021-07-23 2:33 ` Ni, Ray @ 2021-07-25 6:07 ` Yao, Jiewen 2021-07-25 7:41 ` Min Xu 1 sibling, 1 reply; 16+ messages in thread From: Yao, Jiewen @ 2021-07-25 6:07 UTC (permalink / raw) To: Xu, Min M, devel@edk2.groups.io; +Cc: Dong, Eric, Ni, Ray Current OvmfPkg Reser vector is a mess (see my previous email). I also compared the ResetVector code in UefiCpuPkg and OvmfPkg. There are already duplication/override. I suggest we just drop UefiCpuPkg change, and focus on improving OvmfPkg. If we need add something in UefiCpuPkg, let's copy the file to OvmfPkg and update there. I really don't want to mess up UefiCpuPkg at this moment. We can make a better architecture to share reset vector in virtual BIOS and physical BIOS later. But at this moment, let's finish the virtual BIOS architecture at first. Thank you Yao Jiewen > -----Original Message----- > From: Xu, Min M <min.m.xu@intel.com> > Sent: Thursday, July 22, 2021 1:52 PM > To: devel@edk2.groups.io > Cc: Xu, Min M <min.m.xu@intel.com>; Dong, Eric <eric.dong@intel.com>; Ni, > Ray <ray.ni@intel.com>; Yao, Jiewen <jiewen.yao@intel.com> > Subject: [PATCH V2 3/4] UefiCpuPkg/ResetVector: Add Main32 entry point in > Main.asm > > RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3429 > > In Tdx all CPUs "reset" to run on 32-bit protected mode with flat > descriptor (paging disabled). Main32 entry point is added in > UefiCpuPkg/ResetVector/Vtf0/Main.asm so that Main.asm can support > the 32-bit protected mode. > > Init32.asm is the 32-bit initialization code. It is a null stub in > UefiCpuPkg. The actual initialization can be implemented in the platform > (OvmfPkg/ResetVector/Ia32/Init32.asm is the example.) > > Cc: Eric Dong <eric.dong@intel.com> > Cc: Ray Ni <ray.ni@intel.com> > Cc: Jiewen Yao <jiewen.yao@intel.com> > Signed-off-by: Min Xu <min.m.xu@intel.com> > --- > UefiCpuPkg/ResetVector/Vtf0/Ia32/Init32.asm | 13 +++++++++++++ > UefiCpuPkg/ResetVector/Vtf0/Main.asm | 14 ++++++++++++++ > UefiCpuPkg/ResetVector/Vtf0/Vtf0.nasmb | 2 +- > 3 files changed, 28 insertions(+), 1 deletion(-) > create mode 100644 UefiCpuPkg/ResetVector/Vtf0/Ia32/Init32.asm > > diff --git a/UefiCpuPkg/ResetVector/Vtf0/Ia32/Init32.asm > b/UefiCpuPkg/ResetVector/Vtf0/Ia32/Init32.asm > new file mode 100644 > index 000000000000..0cdae4a4a84a > --- /dev/null > +++ b/UefiCpuPkg/ResetVector/Vtf0/Ia32/Init32.asm > @@ -0,0 +1,13 @@ > +;------------------------------------------------------------------------------ > +; @file > +; 32-bit initialization code. > +; Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> > +; SPDX-License-Identifier: BSD-2-Clause-Patent > +; > +;------------------------------------------------------------------------------ > + > +BITS 32 > + > +Init32: > + nop > + OneTimeCallRet Init32 > diff --git a/UefiCpuPkg/ResetVector/Vtf0/Main.asm > b/UefiCpuPkg/ResetVector/Vtf0/Main.asm > index 19d08482f831..4920c6937e1b 100644 > --- a/UefiCpuPkg/ResetVector/Vtf0/Main.asm > +++ b/UefiCpuPkg/ResetVector/Vtf0/Main.asm > @@ -36,6 +36,20 @@ Main16: > > BITS 32 > > +%ifdef ARCH_X64 > + > + jmp SearchBfv > + > +; > +; Entry point of Main32 > +; > +Main32: > + > + OneTimeCall Init32 > + > +%endif > + > +SearchBfv: > ; > ; Search for the Boot Firmware Volume (BFV) > ; > diff --git a/UefiCpuPkg/ResetVector/Vtf0/Vtf0.nasmb > b/UefiCpuPkg/ResetVector/Vtf0/Vtf0.nasmb > index 493738c79c1c..6493b9863c48 100644 > --- a/UefiCpuPkg/ResetVector/Vtf0/Vtf0.nasmb > +++ b/UefiCpuPkg/ResetVector/Vtf0/Vtf0.nasmb > @@ -51,7 +51,7 @@ > %include "Ia32/SearchForSecEntry.asm" > > %ifdef ARCH_X64 > -%include "Ia32/Flat32ToFlat64.asm" > +%include "Ia32/Init32.asm" > %include "Ia32/PageTables64.asm" > %endif > > -- > 2.29.2.windows.2 ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH V2 3/4] UefiCpuPkg/ResetVector: Add Main32 entry point in Main.asm 2021-07-25 6:07 ` Yao, Jiewen @ 2021-07-25 7:41 ` Min Xu 2021-07-25 7:43 ` Yao, Jiewen 0 siblings, 1 reply; 16+ messages in thread From: Min Xu @ 2021-07-25 7:41 UTC (permalink / raw) To: Yao, Jiewen, devel@edk2.groups.io; +Cc: Dong, Eric, Ni, Ray On July 25, 2021 2:08 PM, Yao, Jiewen wrote: > Current OvmfPkg Reser vector is a mess (see my previous email). > I also compared the ResetVector code in UefiCpuPkg and OvmfPkg. There > are already duplication/override. > > I suggest we just drop UefiCpuPkg change, and focus on improving OvmfPkg. > If we need add something in UefiCpuPkg, let's copy the file to OvmfPkg and > update there. > Do you mean we create the Main.asm in OvmfPkg/ResetVector/ and update the changes in this Main.asm? > > I really don't want to mess up UefiCpuPkg at this moment. > We can make a better architecture to share reset vector in virtual BIOS and > physical BIOS later. But at this moment, let's finish the virtual BIOS > architecture at first. > > Thank you > Yao Jiewen > > > -----Original Message----- > > From: Xu, Min M <min.m.xu@intel.com> > > Sent: Thursday, July 22, 2021 1:52 PM > > To: devel@edk2.groups.io > > Cc: Xu, Min M <min.m.xu@intel.com>; Dong, Eric <eric.dong@intel.com>; > > Ni, Ray <ray.ni@intel.com>; Yao, Jiewen <jiewen.yao@intel.com> > > Subject: [PATCH V2 3/4] UefiCpuPkg/ResetVector: Add Main32 entry point > > in Main.asm > > > > RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3429 > > > > In Tdx all CPUs "reset" to run on 32-bit protected mode with flat > > descriptor (paging disabled). Main32 entry point is added in > > UefiCpuPkg/ResetVector/Vtf0/Main.asm so that Main.asm can support the > > 32-bit protected mode. > > > > Init32.asm is the 32-bit initialization code. It is a null stub in > > UefiCpuPkg. The actual initialization can be implemented in the > > platform (OvmfPkg/ResetVector/Ia32/Init32.asm is the example.) > > > > Cc: Eric Dong <eric.dong@intel.com> > > Cc: Ray Ni <ray.ni@intel.com> > > Cc: Jiewen Yao <jiewen.yao@intel.com> > > Signed-off-by: Min Xu <min.m.xu@intel.com> > > --- > > UefiCpuPkg/ResetVector/Vtf0/Ia32/Init32.asm | 13 +++++++++++++ > > UefiCpuPkg/ResetVector/Vtf0/Main.asm | 14 ++++++++++++++ > > UefiCpuPkg/ResetVector/Vtf0/Vtf0.nasmb | 2 +- > > 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 > > UefiCpuPkg/ResetVector/Vtf0/Ia32/Init32.asm > > > > diff --git a/UefiCpuPkg/ResetVector/Vtf0/Ia32/Init32.asm > > b/UefiCpuPkg/ResetVector/Vtf0/Ia32/Init32.asm > > new file mode 100644 > > index 000000000000..0cdae4a4a84a > > --- /dev/null > > +++ b/UefiCpuPkg/ResetVector/Vtf0/Ia32/Init32.asm > > @@ -0,0 +1,13 @@ > > +;-------------------------------------------------------------------- > > +---------- > > +; @file > > +; 32-bit initialization code. > > +; Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> ; > > +SPDX-License-Identifier: BSD-2-Clause-Patent ; > > +;-------------------------------------------------------------------- > > +---------- > > + > > +BITS 32 > > + > > +Init32: > > + nop > > + OneTimeCallRet Init32 > > diff --git a/UefiCpuPkg/ResetVector/Vtf0/Main.asm > > b/UefiCpuPkg/ResetVector/Vtf0/Main.asm > > index 19d08482f831..4920c6937e1b 100644 > > --- a/UefiCpuPkg/ResetVector/Vtf0/Main.asm > > +++ b/UefiCpuPkg/ResetVector/Vtf0/Main.asm > > @@ -36,6 +36,20 @@ Main16: > > > > BITS 32 > > > > +%ifdef ARCH_X64 > > + > > + jmp SearchBfv > > + > > +; > > +; Entry point of Main32 > > +; > > +Main32: > > + > > + OneTimeCall Init32 > > + > > +%endif > > + > > +SearchBfv: > > ; > > ; Search for the Boot Firmware Volume (BFV) > > ; > > diff --git a/UefiCpuPkg/ResetVector/Vtf0/Vtf0.nasmb > > b/UefiCpuPkg/ResetVector/Vtf0/Vtf0.nasmb > > index 493738c79c1c..6493b9863c48 100644 > > --- a/UefiCpuPkg/ResetVector/Vtf0/Vtf0.nasmb > > +++ b/UefiCpuPkg/ResetVector/Vtf0/Vtf0.nasmb > > @@ -51,7 +51,7 @@ > > %include "Ia32/SearchForSecEntry.asm" > > > > %ifdef ARCH_X64 > > -%include "Ia32/Flat32ToFlat64.asm" > > +%include "Ia32/Init32.asm" > > %include "Ia32/PageTables64.asm" > > %endif > > > > -- > > 2.29.2.windows.2 ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH V2 3/4] UefiCpuPkg/ResetVector: Add Main32 entry point in Main.asm 2021-07-25 7:41 ` Min Xu @ 2021-07-25 7:43 ` Yao, Jiewen 2021-07-25 7:46 ` Min Xu 0 siblings, 1 reply; 16+ messages in thread From: Yao, Jiewen @ 2021-07-25 7:43 UTC (permalink / raw) To: Xu, Min M, devel@edk2.groups.io; +Cc: Dong, Eric, Ni, Ray Yes, if that can avoid the UefiCpuPkg change. > -----Original Message----- > From: Xu, Min M <min.m.xu@intel.com> > Sent: Sunday, July 25, 2021 3:42 PM > To: Yao, Jiewen <jiewen.yao@intel.com>; devel@edk2.groups.io > Cc: Dong, Eric <eric.dong@intel.com>; Ni, Ray <ray.ni@intel.com> > Subject: RE: [PATCH V2 3/4] UefiCpuPkg/ResetVector: Add Main32 entry point in > Main.asm > > On July 25, 2021 2:08 PM, Yao, Jiewen wrote: > > Current OvmfPkg Reser vector is a mess (see my previous email). > > I also compared the ResetVector code in UefiCpuPkg and OvmfPkg. There > > are already duplication/override. > > > > I suggest we just drop UefiCpuPkg change, and focus on improving OvmfPkg. > > If we need add something in UefiCpuPkg, let's copy the file to OvmfPkg and > > update there. > > > Do you mean we create the Main.asm in OvmfPkg/ResetVector/ and update > the changes in this Main.asm? > > > > I really don't want to mess up UefiCpuPkg at this moment. > > We can make a better architecture to share reset vector in virtual BIOS and > > physical BIOS later. But at this moment, let's finish the virtual BIOS > > architecture at first. > > > > Thank you > > Yao Jiewen > > > > > -----Original Message----- > > > From: Xu, Min M <min.m.xu@intel.com> > > > Sent: Thursday, July 22, 2021 1:52 PM > > > To: devel@edk2.groups.io > > > Cc: Xu, Min M <min.m.xu@intel.com>; Dong, Eric <eric.dong@intel.com>; > > > Ni, Ray <ray.ni@intel.com>; Yao, Jiewen <jiewen.yao@intel.com> > > > Subject: [PATCH V2 3/4] UefiCpuPkg/ResetVector: Add Main32 entry point > > > in Main.asm > > > > > > RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3429 > > > > > > In Tdx all CPUs "reset" to run on 32-bit protected mode with flat > > > descriptor (paging disabled). Main32 entry point is added in > > > UefiCpuPkg/ResetVector/Vtf0/Main.asm so that Main.asm can support the > > > 32-bit protected mode. > > > > > > Init32.asm is the 32-bit initialization code. It is a null stub in > > > UefiCpuPkg. The actual initialization can be implemented in the > > > platform (OvmfPkg/ResetVector/Ia32/Init32.asm is the example.) > > > > > > Cc: Eric Dong <eric.dong@intel.com> > > > Cc: Ray Ni <ray.ni@intel.com> > > > Cc: Jiewen Yao <jiewen.yao@intel.com> > > > Signed-off-by: Min Xu <min.m.xu@intel.com> > > > --- > > > UefiCpuPkg/ResetVector/Vtf0/Ia32/Init32.asm | 13 +++++++++++++ > > > UefiCpuPkg/ResetVector/Vtf0/Main.asm | 14 ++++++++++++++ > > > UefiCpuPkg/ResetVector/Vtf0/Vtf0.nasmb | 2 +- > > > 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 > > > UefiCpuPkg/ResetVector/Vtf0/Ia32/Init32.asm > > > > > > diff --git a/UefiCpuPkg/ResetVector/Vtf0/Ia32/Init32.asm > > > b/UefiCpuPkg/ResetVector/Vtf0/Ia32/Init32.asm > > > new file mode 100644 > > > index 000000000000..0cdae4a4a84a > > > --- /dev/null > > > +++ b/UefiCpuPkg/ResetVector/Vtf0/Ia32/Init32.asm > > > @@ -0,0 +1,13 @@ > > > +;-------------------------------------------------------------------- > > > +---------- > > > +; @file > > > +; 32-bit initialization code. > > > +; Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> ; > > > +SPDX-License-Identifier: BSD-2-Clause-Patent ; > > > +;-------------------------------------------------------------------- > > > +---------- > > > + > > > +BITS 32 > > > + > > > +Init32: > > > + nop > > > + OneTimeCallRet Init32 > > > diff --git a/UefiCpuPkg/ResetVector/Vtf0/Main.asm > > > b/UefiCpuPkg/ResetVector/Vtf0/Main.asm > > > index 19d08482f831..4920c6937e1b 100644 > > > --- a/UefiCpuPkg/ResetVector/Vtf0/Main.asm > > > +++ b/UefiCpuPkg/ResetVector/Vtf0/Main.asm > > > @@ -36,6 +36,20 @@ Main16: > > > > > > BITS 32 > > > > > > +%ifdef ARCH_X64 > > > + > > > + jmp SearchBfv > > > + > > > +; > > > +; Entry point of Main32 > > > +; > > > +Main32: > > > + > > > + OneTimeCall Init32 > > > + > > > +%endif > > > + > > > +SearchBfv: > > > ; > > > ; Search for the Boot Firmware Volume (BFV) > > > ; > > > diff --git a/UefiCpuPkg/ResetVector/Vtf0/Vtf0.nasmb > > > b/UefiCpuPkg/ResetVector/Vtf0/Vtf0.nasmb > > > index 493738c79c1c..6493b9863c48 100644 > > > --- a/UefiCpuPkg/ResetVector/Vtf0/Vtf0.nasmb > > > +++ b/UefiCpuPkg/ResetVector/Vtf0/Vtf0.nasmb > > > @@ -51,7 +51,7 @@ > > > %include "Ia32/SearchForSecEntry.asm" > > > > > > %ifdef ARCH_X64 > > > -%include "Ia32/Flat32ToFlat64.asm" > > > +%include "Ia32/Init32.asm" > > > %include "Ia32/PageTables64.asm" > > > %endif > > > > > > -- > > > 2.29.2.windows.2 ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH V2 3/4] UefiCpuPkg/ResetVector: Add Main32 entry point in Main.asm 2021-07-25 7:43 ` Yao, Jiewen @ 2021-07-25 7:46 ` Min Xu 0 siblings, 0 replies; 16+ messages in thread From: Min Xu @ 2021-07-25 7:46 UTC (permalink / raw) To: Yao, Jiewen, devel@edk2.groups.io; +Cc: Dong, Eric, Ni, Ray I see. I will update it in the next version. Thanks! > -----Original Message----- > From: Yao, Jiewen <jiewen.yao@intel.com> > Sent: Sunday, July 25, 2021 3:44 PM > To: Xu, Min M <min.m.xu@intel.com>; devel@edk2.groups.io > Cc: Dong, Eric <eric.dong@intel.com>; Ni, Ray <ray.ni@intel.com> > Subject: RE: [PATCH V2 3/4] UefiCpuPkg/ResetVector: Add Main32 entry point > in Main.asm > > Yes, if that can avoid the UefiCpuPkg change. > > > -----Original Message----- > > From: Xu, Min M <min.m.xu@intel.com> > > Sent: Sunday, July 25, 2021 3:42 PM > > To: Yao, Jiewen <jiewen.yao@intel.com>; devel@edk2.groups.io > > Cc: Dong, Eric <eric.dong@intel.com>; Ni, Ray <ray.ni@intel.com> > > Subject: RE: [PATCH V2 3/4] UefiCpuPkg/ResetVector: Add Main32 entry > > point in Main.asm > > > > On July 25, 2021 2:08 PM, Yao, Jiewen wrote: > > > Current OvmfPkg Reser vector is a mess (see my previous email). > > > I also compared the ResetVector code in UefiCpuPkg and OvmfPkg. > > > There are already duplication/override. > > > > > > I suggest we just drop UefiCpuPkg change, and focus on improving OvmfPkg. > > > If we need add something in UefiCpuPkg, let's copy the file to > > > OvmfPkg and update there. > > > > > Do you mean we create the Main.asm in OvmfPkg/ResetVector/ and update > > the changes in this Main.asm? > > > > > > I really don't want to mess up UefiCpuPkg at this moment. > > > We can make a better architecture to share reset vector in virtual > > > BIOS and physical BIOS later. But at this moment, let's finish the > > > virtual BIOS architecture at first. > > > > > > Thank you > > > Yao Jiewen > > > > > > > -----Original Message----- > > > > From: Xu, Min M <min.m.xu@intel.com> > > > > Sent: Thursday, July 22, 2021 1:52 PM > > > > To: devel@edk2.groups.io > > > > Cc: Xu, Min M <min.m.xu@intel.com>; Dong, Eric > > > > <eric.dong@intel.com>; Ni, Ray <ray.ni@intel.com>; Yao, Jiewen > > > > <jiewen.yao@intel.com> > > > > Subject: [PATCH V2 3/4] UefiCpuPkg/ResetVector: Add Main32 entry > > > > point in Main.asm > > > > > > > > RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3429 > > > > > > > > In Tdx all CPUs "reset" to run on 32-bit protected mode with flat > > > > descriptor (paging disabled). Main32 entry point is added in > > > > UefiCpuPkg/ResetVector/Vtf0/Main.asm so that Main.asm can support > > > > the 32-bit protected mode. > > > > > > > > Init32.asm is the 32-bit initialization code. It is a null stub in > > > > UefiCpuPkg. The actual initialization can be implemented in the > > > > platform (OvmfPkg/ResetVector/Ia32/Init32.asm is the example.) > > > > > > > > Cc: Eric Dong <eric.dong@intel.com> > > > > Cc: Ray Ni <ray.ni@intel.com> > > > > Cc: Jiewen Yao <jiewen.yao@intel.com> > > > > Signed-off-by: Min Xu <min.m.xu@intel.com> > > > > --- > > > > UefiCpuPkg/ResetVector/Vtf0/Ia32/Init32.asm | 13 +++++++++++++ > > > > UefiCpuPkg/ResetVector/Vtf0/Main.asm | 14 ++++++++++++++ > > > > UefiCpuPkg/ResetVector/Vtf0/Vtf0.nasmb | 2 +- > > > > 3 files changed, 28 insertions(+), 1 deletion(-) create mode > > > > 100644 UefiCpuPkg/ResetVector/Vtf0/Ia32/Init32.asm > > > > > > > > diff --git a/UefiCpuPkg/ResetVector/Vtf0/Ia32/Init32.asm > > > > b/UefiCpuPkg/ResetVector/Vtf0/Ia32/Init32.asm > > > > new file mode 100644 > > > > index 000000000000..0cdae4a4a84a > > > > --- /dev/null > > > > +++ b/UefiCpuPkg/ResetVector/Vtf0/Ia32/Init32.asm > > > > @@ -0,0 +1,13 @@ > > > > +;---------------------------------------------------------------- > > > > +---- > > > > +---------- > > > > +; @file > > > > +; 32-bit initialization code. > > > > +; Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> > > > > +; > > > > +SPDX-License-Identifier: BSD-2-Clause-Patent ; > > > > +;---------------------------------------------------------------- > > > > +---- > > > > +---------- > > > > + > > > > +BITS 32 > > > > + > > > > +Init32: > > > > + nop > > > > + OneTimeCallRet Init32 > > > > diff --git a/UefiCpuPkg/ResetVector/Vtf0/Main.asm > > > > b/UefiCpuPkg/ResetVector/Vtf0/Main.asm > > > > index 19d08482f831..4920c6937e1b 100644 > > > > --- a/UefiCpuPkg/ResetVector/Vtf0/Main.asm > > > > +++ b/UefiCpuPkg/ResetVector/Vtf0/Main.asm > > > > @@ -36,6 +36,20 @@ Main16: > > > > > > > > BITS 32 > > > > > > > > +%ifdef ARCH_X64 > > > > + > > > > + jmp SearchBfv > > > > + > > > > +; > > > > +; Entry point of Main32 > > > > +; > > > > +Main32: > > > > + > > > > + OneTimeCall Init32 > > > > + > > > > +%endif > > > > + > > > > +SearchBfv: > > > > ; > > > > ; Search for the Boot Firmware Volume (BFV) > > > > ; > > > > diff --git a/UefiCpuPkg/ResetVector/Vtf0/Vtf0.nasmb > > > > b/UefiCpuPkg/ResetVector/Vtf0/Vtf0.nasmb > > > > index 493738c79c1c..6493b9863c48 100644 > > > > --- a/UefiCpuPkg/ResetVector/Vtf0/Vtf0.nasmb > > > > +++ b/UefiCpuPkg/ResetVector/Vtf0/Vtf0.nasmb > > > > @@ -51,7 +51,7 @@ > > > > %include "Ia32/SearchForSecEntry.asm" > > > > > > > > %ifdef ARCH_X64 > > > > -%include "Ia32/Flat32ToFlat64.asm" > > > > +%include "Ia32/Init32.asm" > > > > %include "Ia32/PageTables64.asm" > > > > %endif > > > > > > > > -- > > > > 2.29.2.windows.2 ^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH V2 4/4] OvmfPkg/ResetVector: Update ResetVector to support Tdx 2021-07-22 5:52 [PATCH V2 0/4] Add Intel TDX support in OvmfPkg/ResetVector Min Xu ` (2 preceding siblings ...) 2021-07-22 5:52 ` [PATCH V2 3/4] UefiCpuPkg/ResetVector: Add Main32 entry point in Main.asm Min Xu @ 2021-07-22 5:52 ` Min Xu 2021-07-22 17:07 ` Lendacky, Thomas 2021-07-25 6:00 ` Yao, Jiewen 3 siblings, 2 replies; 16+ messages in thread From: Min Xu @ 2021-07-22 5:52 UTC (permalink / raw) To: devel Cc: Min Xu, Ard Biesheuvel, Brijesh Singh, Erdem Aktas, James Bottomley, Jiewen Yao, Tom Lendacky RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3429 In Tdx all CPUs "reset" to run on 32-bit protected mode with flat descriptor (paging disabled). But in Non-Td guest the initial state of CPUs is 16-bit real mode. To resolve this conflict, BITS 16/32 is used in the very beginning of ResetVector. It will check the 32-bit protected mode or 16-bit real mode, then jump to the corresponding entry point. This is done in OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm. ReloadFlat32.asm load the GDT and set the CR0, then jump to Flat-32 mode. InitTdx.asm is called to record the Tdx signature ('TDXG') and other tdx information in a TDX_WORK_AREA which can be used by the other routines in ResetVector. Init32.asm is 32-bit initialization code in OvmfPkg. It puts above ReloadFlat32 and InitTdx together to do the initializaiton for Tdx. After that Tdx jumps to 64-bit long mode by doing following tasks: 1. SetCr3ForPageTables64 For OVMF, some initial page tables is built at: PcdOvmfSecPageTablesBase - (PcdOvmfSecPageTablesBase + 0x6000) This page table supports the 4-level page table. But Tdx support 4-level and 5-level page table based on the CPU GPA width. 48bit is 4-level paging, 52-bit is 5-level paging. If 5-level page table is supported (GPAW is 52), then a top level page directory pointers (1 * 256TB entry) is generated in the TdxPageTable. 2. Set Cr4 Enable PAE. 3. Adjust Cr3 If GPAW is 48, then Cr3 is PT_ADDR (0). If GPAW is 52, then Cr3 is TDX_PT_ADDR (0). Tdx MailBox [0x10, 0x800] is reserved for OS. So we initialize piece of this area ([0x10, 0x20]) to record the Tdx flag ('TDXG') and other Tdx info so that they can be used in the following flow. After all above is successfully done, Tdx jump to SecEntry. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> 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> Signed-off-by: Min Xu <min.m.xu@intel.com> --- OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm | 21 ++++++++ OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm | 47 ++++++++++++++++ OvmfPkg/ResetVector/Ia32/Init32.asm | 34 ++++++++++++ OvmfPkg/ResetVector/Ia32/InitTdx.asm | 57 ++++++++++++++++++++ OvmfPkg/ResetVector/Ia32/PageTables64.asm | 41 ++++++++++++++ OvmfPkg/ResetVector/Ia32/ReloadFlat32.asm | 44 +++++++++++++++ OvmfPkg/ResetVector/ResetVector.nasmb | 18 +++++++ 7 files changed, 262 insertions(+) create mode 100644 OvmfPkg/ResetVector/Ia32/Init32.asm create mode 100644 OvmfPkg/ResetVector/Ia32/InitTdx.asm create mode 100644 OvmfPkg/ResetVector/Ia32/ReloadFlat32.asm diff --git a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm index ac86ce69ebe8..a390ed81d021 100644 --- a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm +++ b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm @@ -155,10 +155,31 @@ resetVector: ; ; This is where the processor will begin execution ; +; In IA32 we follow the standard reset vector flow. While in X64, Td guest +; may be supported. Td guest requires the startup mode to be 32-bit +; protected mode but the legacy VM startup mode is 16-bit real mode. +; To make NASM generate such shared entry code that behaves correctly in +; both 16-bit and 32-bit mode, more BITS directives are added. +; +%ifdef ARCH_IA32 + nop nop jmp EarlyBspInitReal16 +%else + + smsw ax + test al, 1 + jz .Real +BITS 32 + jmp Main32 +BITS 16 +.Real: + jmp EarlyBspInitReal16 + +%endif + ALIGN 16 fourGigabytes: diff --git a/OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm b/OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm index c6d0d898bcd1..2206ca719593 100644 --- a/OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm +++ b/OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm @@ -17,6 +17,9 @@ Transition32FlatTo64Flat: OneTimeCall SetCr3ForPageTables64 + cmp dword[TDX_WORK_AREA], 0x47584454 ; 'TDXG' + jz TdxTransition32FlatTo64Flat + mov eax, cr4 bts eax, 5 ; enable PAE mov cr4, eax @@ -65,10 +68,54 @@ EnablePaging: bts eax, 31 ; set PG mov cr0, eax ; enable paging + jmp _jumpTo64Bit + +; +; Tdx Transition from 32Flat to 64Flat +; +TdxTransition32FlatTo64Flat: + + mov eax, cr4 + bts eax, 5 ; enable PAE + + ; + ; byte[TDX_WORK_AREA_PAGELEVEL5] holds the indicator whether 52bit is supported. + ; if it is the case, need to set LA57 and use 5-level paging + ; + cmp byte[TDX_WORK_AREA_PAGELEVEL5], 0 + jz .set_cr4 + bts eax, 12 +.set_cr4: + mov cr4, eax + mov ebx, cr3 + + ; + ; if la57 is not set, we are ok + ; if using 5-level paging, adjust top-level page directory + ; + bt eax, 12 + jnc .set_cr3 + mov ebx, TDX_PT_ADDR (0) +.set_cr3: + mov cr3, ebx + + mov eax, cr0 + bts eax, 31 ; set PG + mov cr0, eax ; enable paging + +_jumpTo64Bit: jmp LINEAR_CODE64_SEL:ADDR_OF(jumpTo64BitAndLandHere) + BITS 64 jumpTo64BitAndLandHere: + ; + ; For Td guest we are done and jump to the end + ; + mov eax, TDX_WORK_AREA + cmp dword [eax], 0x47584454 ; 'TDXG' + jz GoodCompare + ; ; Check if the second step of the SEV-ES mitigation is to be performed. ; diff --git a/OvmfPkg/ResetVector/Ia32/Init32.asm b/OvmfPkg/ResetVector/Ia32/Init32.asm new file mode 100644 index 000000000000..772adc51e531 --- /dev/null +++ b/OvmfPkg/ResetVector/Ia32/Init32.asm @@ -0,0 +1,34 @@ +;------------------------------------------------------------------------------ +; @file +; 32-bit initialization for Tdx +; +; Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> +; SPDX-License-Identifier: BSD-2-Clause-Patent +; +;------------------------------------------------------------------------------ + +BITS 32 + +; +; Modified: EBP +; +; @param[in] EBX [6:0] CPU supported GPA width +; [7:7] 5 level page table support +; @param[in] ECX [31:0] TDINITVP - Untrusted Configuration +; @param[in] EDX [31:0] VCPUID +; @param[in] ESI [31:0] VCPU_Index +; +Init32: + ; + ; Save EBX in EBP because EBX will be changed in ReloadFlat32 + ; + mov ebp, ebx + + OneTimeCall ReloadFlat32 + + ; + ; Init Tdx + ; + OneTimeCall InitTdx + + OneTimeCallRet Init32 diff --git a/OvmfPkg/ResetVector/Ia32/InitTdx.asm b/OvmfPkg/ResetVector/Ia32/InitTdx.asm new file mode 100644 index 000000000000..de8273da6a0c --- /dev/null +++ b/OvmfPkg/ResetVector/Ia32/InitTdx.asm @@ -0,0 +1,57 @@ +;------------------------------------------------------------------------------ +; @file +; Initialize TDX_WORK_AREA to record the Tdx flag ('TDXG') and other Tdx info +; so that the following codes can use these information. +; +; Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> +; SPDX-License-Identifier: BSD-2-Clause-Patent +; +;------------------------------------------------------------------------------ + +BITS 32 + +; +; Modified: EBP +; +InitTdx: + ; + ; In Td guest, BSP/AP shares the same entry point + ; BSP builds up the page table, while APs shouldn't do the same task. + ; Instead, APs just leverage the page table which is built by BSP. + ; APs will wait until the page table is ready. + ; In Td guest, vCPU 0 is treated as the BSP, the others are APs. + ; ESI indicates the vCPU ID. + ; + cmp esi, 0 + je tdBspEntry + +apWait: + cmp byte[TDX_WORK_AREA_PGTBL_READY], 0 + je apWait + jmp doneTdxInit + +tdBspEntry: + ; + ; It is of Tdx Guest + ; Save the Tdx info in TDX_WORK_AREA so that the following code can use + ; these information. + ; + mov dword [TDX_WORK_AREA], 0x47584454 ; 'TDXG' + + ; + ; EBP[6:0] CPU supported GPA width + ; + and ebp, 0x3f + cmp ebp, 52 + jl NotPageLevel5 + mov byte[TDX_WORK_AREA_PAGELEVEL5], 1 + +NotPageLevel5: + ; + ; ECX[31:0] TDINITVP - Untrusted Configuration + ; + mov DWORD[TDX_WORK_AREA_INITVP], ecx + mov DWORD[TDX_WORK_AREA_INFO], ebp + +doneTdxInit: + OneTimeCallRet InitTdx diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm b/OvmfPkg/ResetVector/Ia32/PageTables64.asm index 5fae8986d9da..508df6cf5967 100644 --- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm +++ b/OvmfPkg/ResetVector/Ia32/PageTables64.asm @@ -218,6 +218,24 @@ SevEsDisabled: ; SetCr3ForPageTables64: + ; + ; Check Td guest + ; + cmp dword[TDX_WORK_AREA], 0x47584454 ; 'TDXG' + jnz CheckSev + + xor edx, edx + + ; + ; In Td guest, BSP builds the page table and set the flag of + ; TDX_WORK_AREA_PGTBL_READY. APs check this flag and then set + ; cr3 directly. + ; + cmp byte[TDX_WORK_AREA_PGTBL_READY], 1 + jz SetCr3 + jmp SevNotActive + +CheckSev: OneTimeCall CheckSevFeatures xor edx, edx test eax, eax @@ -277,6 +295,29 @@ pageTableEntriesLoop: mov [(ecx * 8 + PT_ADDR (0x2000 - 8)) + 4], edx loop pageTableEntriesLoop + ; + ; If it is Td guest, TdxExtraPageTable should be initialized as well + ; + cmp dword[TDX_WORK_AREA], 0x47584454 ; 'TDXG' + jnz IsSevEs + + xor eax, eax + mov ecx, 0x400 +tdClearTdxPageTablesMemoryLoop: + mov dword [ecx * 4 + TDX_PT_ADDR (0) - 4], eax + loop tdClearTdxPageTablesMemoryLoop + + xor edx, edx + ; + ; Top level Page Directory Pointers (1 * 256TB entry) + ; + mov dword[TDX_PT_ADDR (0)], PT_ADDR (0) + PAGE_PDP_ATTR + mov dword[TDX_PT_ADDR (4)], edx + + mov byte[TDX_WORK_AREA_PGTBL_READY], 1 + jmp SetCr3 + +IsSevEs: OneTimeCall IsSevEsEnabled test eax, eax jz SetCr3 diff --git a/OvmfPkg/ResetVector/Ia32/ReloadFlat32.asm b/OvmfPkg/ResetVector/Ia32/ReloadFlat32.asm new file mode 100644 index 000000000000..06d44142625a --- /dev/null +++ b/OvmfPkg/ResetVector/Ia32/ReloadFlat32.asm @@ -0,0 +1,44 @@ +;------------------------------------------------------------------------------ +; @file +; Load the GDT and set the CR0/CR4, then jump to Flat 32 protected mode. +; +; Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> +; SPDX-License-Identifier: BSD-2-Clause-Patent +; +;------------------------------------------------------------------------------ + +%define SEC_DEFAULT_CR0 0x00000023 +%define SEC_DEFAULT_CR4 0x640 + +BITS 32 + +; +; Modified: EAX, EBX, CR0, CR4, DS, ES, FS, GS, SS +; +ReloadFlat32: + + cli + mov ebx, ADDR_OF(gdtr) + lgdt [ebx] + + mov eax, SEC_DEFAULT_CR0 + mov cr0, eax + + jmp LINEAR_CODE_SEL:dword ADDR_OF(jumpToFlat32BitAndLandHere) +BITS 32 +jumpToFlat32BitAndLandHere: + + mov eax, SEC_DEFAULT_CR4 + mov cr4, eax + + debugShowPostCode POSTCODE_32BIT_MODE + + mov ax, LINEAR_SEL + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov ss, ax + + OneTimeCallRet ReloadFlat32 + diff --git a/OvmfPkg/ResetVector/ResetVector.nasmb b/OvmfPkg/ResetVector/ResetVector.nasmb index b653fe87abd6..3ec163613477 100644 --- a/OvmfPkg/ResetVector/ResetVector.nasmb +++ b/OvmfPkg/ResetVector/ResetVector.nasmb @@ -106,6 +106,21 @@ %define TDX_EXTRA_PAGE_TABLE_BASE FixedPcdGet32 (PcdOvmfSecGhcbPageTableBase) %define TDX_EXTRA_PAGE_TABLE_SIZE FixedPcdGet32 (PcdOvmfSecGhcbPageTableSize) + ; + ; TdMailboxBase [0x10, 0x800] is reserved for OS. + ; Td guest initialize piece of this area (TdMailboxBase [0x10,0x20]) to + ; record the Td guest info so that this information can be used in the + ; following ResetVector flow. + ; + %define TD_MAILBOX_WORKAREA_OFFSET 0x10 + %define TDX_WORK_AREA (TDX_MAILBOX_MEMORY_BASE + TD_MAILBOX_WORKAREA_OFFSET) + %define TDX_WORK_AREA_PAGELEVEL5 (TDX_WORK_AREA + 4) + %define TDX_WORK_AREA_PGTBL_READY (TDX_WORK_AREA + 5) + %define TDX_WORK_AREA_INITVP (TDX_WORK_AREA + 8) + %define TDX_WORK_AREA_INFO (TDX_WORK_AREA + 8 + 4) + + %define TDX_PT_ADDR(Offset) (TDX_EXTRA_PAGE_TABLE_BASE + (Offset)) + %define PT_ADDR(Offset) (FixedPcdGet32 (PcdOvmfSecPageTablesBase) + (Offset)) %define GHCB_PT_ADDR (FixedPcdGet32 (PcdOvmfSecGhcbPageTableBase)) @@ -117,6 +132,9 @@ %define SEV_ES_VC_TOP_OF_STACK (FixedPcdGet32 (PcdOvmfSecPeiTempRamBase) + FixedPcdGet32 (PcdOvmfSecPeiTempRamSize)) %include "X64/TdxMetadata.asm" + %include "Ia32/Init32.asm" + %include "Ia32/InitTdx.asm" + %include "Ia32/ReloadFlat32.asm" %include "Ia32/Flat32ToFlat64.asm" %include "Ia32/PageTables64.asm" -- 2.29.2.windows.2 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH V2 4/4] OvmfPkg/ResetVector: Update ResetVector to support Tdx 2021-07-22 5:52 ` [PATCH V2 4/4] OvmfPkg/ResetVector: Update ResetVector to support Tdx Min Xu @ 2021-07-22 17:07 ` Lendacky, Thomas 2021-07-22 22:58 ` Min Xu 2021-07-25 6:00 ` Yao, Jiewen 1 sibling, 1 reply; 16+ messages in thread From: Lendacky, Thomas @ 2021-07-22 17:07 UTC (permalink / raw) To: Min Xu, devel Cc: Ard Biesheuvel, Brijesh Singh, Erdem Aktas, James Bottomley, Jiewen Yao On 7/22/21 12:52 AM, Min Xu wrote: > RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3429 > > In Tdx all CPUs "reset" to run on 32-bit protected mode with flat > descriptor (paging disabled). But in Non-Td guest the initial state of > CPUs is 16-bit real mode. To resolve this conflict, BITS 16/32 is used > in the very beginning of ResetVector. It will check the 32-bit protected > mode or 16-bit real mode, then jump to the corresponding entry point. > This is done in OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm. > > ReloadFlat32.asm load the GDT and set the CR0, then jump to Flat-32 mode. > > InitTdx.asm is called to record the Tdx signature ('TDXG') and other tdx > information in a TDX_WORK_AREA which can be used by the other routines in > ResetVector. > > Init32.asm is 32-bit initialization code in OvmfPkg. It puts above > ReloadFlat32 and InitTdx together to do the initializaiton for Tdx. > > After that Tdx jumps to 64-bit long mode by doing following tasks: > 1. SetCr3ForPageTables64 > For OVMF, some initial page tables is built at: > PcdOvmfSecPageTablesBase - (PcdOvmfSecPageTablesBase + 0x6000) > This page table supports the 4-level page table. > But Tdx support 4-level and 5-level page table based on the CPU GPA width. > 48bit is 4-level paging, 52-bit is 5-level paging. > If 5-level page table is supported (GPAW is 52), then a top level > page directory pointers (1 * 256TB entry) is generated in the > TdxPageTable. > 2. Set Cr4 > Enable PAE. > 3. Adjust Cr3 > If GPAW is 48, then Cr3 is PT_ADDR (0). If GPAW is 52, then Cr3 is > TDX_PT_ADDR (0). > > Tdx MailBox [0x10, 0x800] is reserved for OS. So we initialize piece of this > area ([0x10, 0x20]) to record the Tdx flag ('TDXG') and other Tdx info so that > they can be used in the following flow. > > After all above is successfully done, Tdx jump to SecEntry. > > Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> > 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> > Signed-off-by: Min Xu <min.m.xu@intel.com> > --- > OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm | 21 ++++++++ > OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm | 47 ++++++++++++++++ > OvmfPkg/ResetVector/Ia32/Init32.asm | 34 ++++++++++++ > OvmfPkg/ResetVector/Ia32/InitTdx.asm | 57 ++++++++++++++++++++ > OvmfPkg/ResetVector/Ia32/PageTables64.asm | 41 ++++++++++++++ > OvmfPkg/ResetVector/Ia32/ReloadFlat32.asm | 44 +++++++++++++++ > OvmfPkg/ResetVector/ResetVector.nasmb | 18 +++++++ > 7 files changed, 262 insertions(+) > create mode 100644 OvmfPkg/ResetVector/Ia32/Init32.asm > create mode 100644 OvmfPkg/ResetVector/Ia32/InitTdx.asm > create mode 100644 OvmfPkg/ResetVector/Ia32/ReloadFlat32.asm > > diff --git a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm > index ac86ce69ebe8..a390ed81d021 100644 > --- a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm > +++ b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm > @@ -155,10 +155,31 @@ resetVector: > ; > ; This is where the processor will begin execution > ; > +; In IA32 we follow the standard reset vector flow. While in X64, Td guest > +; may be supported. Td guest requires the startup mode to be 32-bit > +; protected mode but the legacy VM startup mode is 16-bit real mode. > +; To make NASM generate such shared entry code that behaves correctly in > +; both 16-bit and 32-bit mode, more BITS directives are added. > +; > +%ifdef ARCH_IA32 > + > nop > nop > jmp EarlyBspInitReal16 > > +%else > + > + smsw ax > + test al, 1 > + jz .Real > +BITS 32 > + jmp Main32 > +BITS 16 > +.Real: > + jmp EarlyBspInitReal16 > + > +%endif > + > ALIGN 16 > > fourGigabytes: > diff --git a/OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm b/OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm > index c6d0d898bcd1..2206ca719593 100644 > --- a/OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm > +++ b/OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm > @@ -17,6 +17,9 @@ Transition32FlatTo64Flat: > > OneTimeCall SetCr3ForPageTables64 > > + cmp dword[TDX_WORK_AREA], 0x47584454 ; 'TDXG' > + jz TdxTransition32FlatTo64Flat > + Is the memory area guaranteed to be zeroed for legacy guests? Hopefully, this won't trip up a non-TDX guest with a false match (highly unlikely, though). > mov eax, cr4 > bts eax, 5 ; enable PAE > mov cr4, eax > @@ -65,10 +68,54 @@ EnablePaging: > bts eax, 31 ; set PG > mov cr0, eax ; enable paging > > + jmp _jumpTo64Bit > + > +; > +; Tdx Transition from 32Flat to 64Flat > +; > +TdxTransition32FlatTo64Flat: > + > + mov eax, cr4 > + bts eax, 5 ; enable PAE > + > + ; > + ; byte[TDX_WORK_AREA_PAGELEVEL5] holds the indicator whether 52bit is supported. > + ; if it is the case, need to set LA57 and use 5-level paging > + ; > + cmp byte[TDX_WORK_AREA_PAGELEVEL5], 0 > + jz .set_cr4 > + bts eax, 12 > +.set_cr4: > + mov cr4, eax > + mov ebx, cr3 > + > + ; > + ; if la57 is not set, we are ok > + ; if using 5-level paging, adjust top-level page directory > + ; > + bt eax, 12 > + jnc .set_cr3 > + mov ebx, TDX_PT_ADDR (0) > +.set_cr3: > + mov cr3, ebx > + > + mov eax, cr0 > + bts eax, 31 ; set PG > + mov cr0, eax ; enable paging If you clear ebx here... > + > +_jumpTo64Bit: > jmp LINEAR_CODE64_SEL:ADDR_OF(jumpTo64BitAndLandHere) > + > BITS 64 > jumpTo64BitAndLandHere: > > + ; > + ; For Td guest we are done and jump to the end > + ; > + mov eax, TDX_WORK_AREA > + cmp dword [eax], 0x47584454 ; 'TDXG' > + jz GoodCompare > + ... you can remove these instructions. You'll jump to InsnCompare and that check should succeed, right? Thanks, Tom > ; > ; Check if the second step of the SEV-ES mitigation is to be performed. > ; ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH V2 4/4] OvmfPkg/ResetVector: Update ResetVector to support Tdx 2021-07-22 17:07 ` Lendacky, Thomas @ 2021-07-22 22:58 ` Min Xu 2021-07-23 13:35 ` Lendacky, Thomas 0 siblings, 1 reply; 16+ messages in thread From: Min Xu @ 2021-07-22 22:58 UTC (permalink / raw) To: Tom Lendacky, devel@edk2.groups.io Cc: Ard Biesheuvel, Brijesh Singh, Erdem Aktas, James Bottomley, Yao, Jiewen On July 23, 2021 1:08 AM, Tom Lendacky wrote: > On 7/22/21 12:52 AM, Min Xu wrote: > > RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3429 > > > > diff --git a/OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm > > b/OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm > > index c6d0d898bcd1..2206ca719593 100644 > > --- a/OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm > > +++ b/OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm > > @@ -17,6 +17,9 @@ Transition32FlatTo64Flat: > > > > OneTimeCall SetCr3ForPageTables64 > > > > + cmp dword[TDX_WORK_AREA], 0x47584454 ; 'TDXG' > > + jz TdxTransition32FlatTo64Flat > > + > > Is the memory area guaranteed to be zeroed for legacy guests? Hopefully, > this won't trip up a non-TDX guest with a false match (highly unlikely, though). > TDX_WORK_AREA is piece of TdxMailbox which is located in the MEMFD started from PcdOvmfSecGhcbBackupBase. In Td guest, this memory region is initialized to all-0 by host VMM. In legacy guests, I am not sure what's the initialized value it is. So 'TDXG' is checked to guarantee it is Td-guest or not. Since Tdx re-use the memory region (PcdOvmfSecGhcbBackupBase) as the TDX_WORK_AREA, and @Tom Lendacky you should be the original owner of PcdOvmfSecGhcbBackupBase, can this area be cleared in the beginning of ResetVector in legacy guests? Or I should better create a TDX specific work area in MEMFD to guarantee the Td And Non-Td check? > > > > mov eax, cr4 > > bts eax, 5 ; enable PAE > > mov cr4, eax > > @@ -65,10 +68,54 @@ EnablePaging: > > bts eax, 31 ; set PG > > mov cr0, eax ; enable paging > > > > + jmp _jumpTo64Bit > > + > > +; > > +; Tdx Transition from 32Flat to 64Flat ; > > +TdxTransition32FlatTo64Flat: > > + > > + mov eax, cr4 > > + bts eax, 5 ; enable PAE > > + > > + ; > > + ; byte[TDX_WORK_AREA_PAGELEVEL5] holds the indicator whether > 52bit is supported. > > + ; if it is the case, need to set LA57 and use 5-level paging > > + ; > > + cmp byte[TDX_WORK_AREA_PAGELEVEL5], 0 > > + jz .set_cr4 > > + bts eax, 12 > > +.set_cr4: > > + mov cr4, eax > > + mov ebx, cr3 > > + > > + ; > > + ; if la57 is not set, we are ok > > + ; if using 5-level paging, adjust top-level page directory > > + ; > > + bt eax, 12 > > + jnc .set_cr3 > > + mov ebx, TDX_PT_ADDR (0) > > +.set_cr3: > > + mov cr3, ebx > > + > > + mov eax, cr0 > > + bts eax, 31 ; set PG > > + mov cr0, eax ; enable paging > > If you clear ebx here... > > > + > > +_jumpTo64Bit: > > jmp LINEAR_CODE64_SEL:ADDR_OF(jumpTo64BitAndLandHere) > > + > > BITS 64 > > jumpTo64BitAndLandHere: > > > > + ; > > + ; For Td guest we are done and jump to the end > > + ; > > + mov eax, TDX_WORK_AREA > > + cmp dword [eax], 0x47584454 ; 'TDXG' > > + jz GoodCompare > > + > > ... you can remove these instructions. You'll jump to InsnCompare and that > check should succeed, right? > Ah, I see. Thanks for reminder. I will update it in next version. > > Thanks, > Tom > > > ; > > ; Check if the second step of the SEV-ES mitigation is to be performed. > > ; ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH V2 4/4] OvmfPkg/ResetVector: Update ResetVector to support Tdx 2021-07-22 22:58 ` Min Xu @ 2021-07-23 13:35 ` Lendacky, Thomas 2021-07-24 1:54 ` [edk2-devel] " Min Xu 0 siblings, 1 reply; 16+ messages in thread From: Lendacky, Thomas @ 2021-07-23 13:35 UTC (permalink / raw) To: Xu, Min M, devel@edk2.groups.io Cc: Ard Biesheuvel, Brijesh Singh, Erdem Aktas, James Bottomley, Yao, Jiewen On 7/22/21 5:58 PM, Xu, Min M wrote: > On July 23, 2021 1:08 AM, Tom Lendacky wrote: >> On 7/22/21 12:52 AM, Min Xu wrote: >>> RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3429 >>> >>> diff --git a/OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm >>> b/OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm >>> index c6d0d898bcd1..2206ca719593 100644 >>> --- a/OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm >>> +++ b/OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm >>> @@ -17,6 +17,9 @@ Transition32FlatTo64Flat: >>> >>> OneTimeCall SetCr3ForPageTables64 >>> >>> + cmp dword[TDX_WORK_AREA], 0x47584454 ; 'TDXG' >>> + jz TdxTransition32FlatTo64Flat >>> + >> >> Is the memory area guaranteed to be zeroed for legacy guests? Hopefully, >> this won't trip up a non-TDX guest with a false match (highly unlikely, though). >> > TDX_WORK_AREA is piece of TdxMailbox which is located in the MEMFD started > from PcdOvmfSecGhcbBackupBase. In Td guest, this memory region is initialized > to all-0 by host VMM. In legacy guests, I am not sure what's the initialized value > it is. So 'TDXG' is checked to guarantee it is Td-guest or not. > Since Tdx re-use the memory region (PcdOvmfSecGhcbBackupBase) as the > TDX_WORK_AREA, and @Tom Lendacky you should be the original owner of > PcdOvmfSecGhcbBackupBase, can this area be cleared in the beginning of > ResetVector in legacy guests? Or I should better create a TDX specific work > area in MEMFD to guarantee the Td And Non-Td check? I believe PcdOvmfSecGhcbBackupBase can be cleared early. For SEV-ES, it isn't shared with the hypervisor, so clearing it before activating the pagetables can be done (it will be treated as encrypted before paging is enabled and mapped as encrypted after paging is enabled) and for a legacy guest the mapping doesn't matter. It isn't required to be cleared today, so if you do add something, be sure to put a comment in there about why it's being done. No need for a new area. The possibility of random data being there that matches 'TDXG' is extremely low. But better safe than sorry, I guess. Thanks, Tom >> ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [edk2-devel] [PATCH V2 4/4] OvmfPkg/ResetVector: Update ResetVector to support Tdx 2021-07-23 13:35 ` Lendacky, Thomas @ 2021-07-24 1:54 ` Min Xu 0 siblings, 0 replies; 16+ messages in thread From: Min Xu @ 2021-07-24 1:54 UTC (permalink / raw) To: devel@edk2.groups.io, thomas.lendacky@amd.com Cc: Ard Biesheuvel, Brijesh Singh, Erdem Aktas, James Bottomley, Yao, Jiewen On July 23, 2021 9:35 PM, Lendacky, Thomas wrote: > On 7/22/21 5:58 PM, Xu, Min M wrote: > > On July 23, 2021 1:08 AM, Tom Lendacky wrote: > >> On 7/22/21 12:52 AM, Min Xu wrote: > >>> RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3429 > >>> > >>> diff --git a/OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm > >>> b/OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm > >>> index c6d0d898bcd1..2206ca719593 100644 > >>> --- a/OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm > >>> +++ b/OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm > >>> @@ -17,6 +17,9 @@ Transition32FlatTo64Flat: > >>> > >>> OneTimeCall SetCr3ForPageTables64 > >>> > >>> + cmp dword[TDX_WORK_AREA], 0x47584454 ; 'TDXG' > >>> + jz TdxTransition32FlatTo64Flat > >>> + > >> > >> Is the memory area guaranteed to be zeroed for legacy guests? > >> Hopefully, this won't trip up a non-TDX guest with a false match (highly > unlikely, though). > >> > > TDX_WORK_AREA is piece of TdxMailbox which is located in the MEMFD > > started from PcdOvmfSecGhcbBackupBase. In Td guest, this memory region > > is initialized to all-0 by host VMM. In legacy guests, I am not sure > > what's the initialized value it is. So 'TDXG' is checked to guarantee it is Td- > guest or not. > > Since Tdx re-use the memory region (PcdOvmfSecGhcbBackupBase) as the > > TDX_WORK_AREA, and @Tom Lendacky you should be the original owner of > > PcdOvmfSecGhcbBackupBase, can this area be cleared in the beginning of > > ResetVector in legacy guests? Or I should better create a TDX specific > > work area in MEMFD to guarantee the Td And Non-Td check? > > I believe PcdOvmfSecGhcbBackupBase can be cleared early. For SEV-ES, it isn't > shared with the hypervisor, so clearing it before activating the pagetables can > be done (it will be treated as encrypted before paging is enabled and mapped > as encrypted after paging is enabled) and for a legacy guest the mapping > doesn't matter. It isn't required to be cleared today, so if you do add > something, be sure to put a comment in there about why it's being done. No > need for a new area. > > The possibility of random data being there that matches 'TDXG' is extremely > low. But better safe than sorry, I guess. > Thanks Tom. I will update it in the next version. > Thanks! Xu, Min ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH V2 4/4] OvmfPkg/ResetVector: Update ResetVector to support Tdx 2021-07-22 5:52 ` [PATCH V2 4/4] OvmfPkg/ResetVector: Update ResetVector to support Tdx Min Xu 2021-07-22 17:07 ` Lendacky, Thomas @ 2021-07-25 6:00 ` Yao, Jiewen 2021-07-25 7:50 ` Min Xu 1 sibling, 1 reply; 16+ messages in thread From: Yao, Jiewen @ 2021-07-25 6:00 UTC (permalink / raw) To: Xu, Min M, devel@edk2.groups.io Cc: Ard Biesheuvel, Brijesh Singh, Erdem Aktas, James Bottomley, Tom Lendacky Hi Min, Brijesh, James I feel very frustrated when I review the existing OVMF reset vector. A big problem is that this code mixed too many SEV stuff, and we are trying to add more TDX stuff in *one* file, without clear isolation. Take PageTables64.asm as example, here are the symbols. (* means it is newly added.) ================= CheckSevFeatures: GetSevEncBit: SevEncBitLowHlt: SevSaveMask: NoSev: NoSevEsVcHlt: NoSevPass: SevExit: IsSevEsEnabled: SevEsDisabled: SetCr3ForPageTables64: CheckSev: (*) SevNotActive: clearPageTablesMemoryLoop: pageTableEntriesLoop: tdClearTdxPageTablesMemoryLoop: (*) IsSevEs: (*) pageTableEntries4kLoop: clearGhcbMemoryLoop: SetCr3: SevEsIdtNotCpuid: SevEsIdtNoCpuidResponse: SevEsIdtTerminate: SevEsIdtHlt: SevEsIdtVmmComm: NextReg: VmmDone: ================= In order to better maintain the ResetVector, may I propose some refinement: 1) The main function only contains the non-TEE function, where TEE == SEV + TDX. 2) The TEE related code is moved to TEE specific standalone file, such *Sev.asm and *Tdx.Asm. 3) We need handle different cases with different pattern. I hope the patter can be used consistently. As such, the reviewer can easily understand what it is for. 3.1) If TEE function is a hook, then the main function calls TEE function directly. The TEE function need implement a TEE check function (such as IsSev, or IsTdx). For example: ==================== OneTimeCall PreMainFunctionHookSev OneTimeCall PreMainFunctionHookTdx MainFunction: XXXXXX OneTimeCall PostMainFunctionHookSev OneTimeCall PostMainFunctionHookTdx ==================== 3.2) If TEE function is a replacement for non-TEE function. The main function can call TEE replacement function, then check the return status to decide next step. For example: ==================== OneTimeCall MainFunctionSev Jz MainFunctionEnd OneTimeCall MainFunctionTdx Jz MainFunctionEnd MainFunction: XXXXXX MainFunctionEnd: ==================== 4) If we found it is too hard to write code in above patter, we can discuss case by case. > -----Original Message----- > From: Xu, Min M <min.m.xu@intel.com> > Sent: Thursday, July 22, 2021 1:52 PM > To: devel@edk2.groups.io > Cc: Xu, Min M <min.m.xu@intel.com>; Ard Biesheuvel > <ardb+tianocore@kernel.org>; Brijesh Singh <brijesh.singh@amd.com>; Erdem > Aktas <erdemaktas@google.com>; James Bottomley <jejb@linux.ibm.com>; > Yao, Jiewen <jiewen.yao@intel.com>; Tom Lendacky > <thomas.lendacky@amd.com> > Subject: [PATCH V2 4/4] OvmfPkg/ResetVector: Update ResetVector to support > Tdx > > RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3429 > > In Tdx all CPUs "reset" to run on 32-bit protected mode with flat > descriptor (paging disabled). But in Non-Td guest the initial state of > CPUs is 16-bit real mode. To resolve this conflict, BITS 16/32 is used > in the very beginning of ResetVector. It will check the 32-bit protected > mode or 16-bit real mode, then jump to the corresponding entry point. > This is done in OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm. > > ReloadFlat32.asm load the GDT and set the CR0, then jump to Flat-32 mode. > > InitTdx.asm is called to record the Tdx signature ('TDXG') and other tdx > information in a TDX_WORK_AREA which can be used by the other routines in > ResetVector. > > Init32.asm is 32-bit initialization code in OvmfPkg. It puts above > ReloadFlat32 and InitTdx together to do the initializaiton for Tdx. > > After that Tdx jumps to 64-bit long mode by doing following tasks: > 1. SetCr3ForPageTables64 > For OVMF, some initial page tables is built at: > PcdOvmfSecPageTablesBase - (PcdOvmfSecPageTablesBase + 0x6000) > This page table supports the 4-level page table. > But Tdx support 4-level and 5-level page table based on the CPU GPA width. > 48bit is 4-level paging, 52-bit is 5-level paging. > If 5-level page table is supported (GPAW is 52), then a top level > page directory pointers (1 * 256TB entry) is generated in the > TdxPageTable. > 2. Set Cr4 > Enable PAE. > 3. Adjust Cr3 > If GPAW is 48, then Cr3 is PT_ADDR (0). If GPAW is 52, then Cr3 is > TDX_PT_ADDR (0). > > Tdx MailBox [0x10, 0x800] is reserved for OS. So we initialize piece of this > area ([0x10, 0x20]) to record the Tdx flag ('TDXG') and other Tdx info so that > they can be used in the following flow. > > After all above is successfully done, Tdx jump to SecEntry. > > Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> > 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> > Signed-off-by: Min Xu <min.m.xu@intel.com> > --- > OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm | 21 ++++++++ > OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm | 47 ++++++++++++++++ > OvmfPkg/ResetVector/Ia32/Init32.asm | 34 ++++++++++++ > OvmfPkg/ResetVector/Ia32/InitTdx.asm | 57 ++++++++++++++++++++ > OvmfPkg/ResetVector/Ia32/PageTables64.asm | 41 ++++++++++++++ > OvmfPkg/ResetVector/Ia32/ReloadFlat32.asm | 44 +++++++++++++++ > OvmfPkg/ResetVector/ResetVector.nasmb | 18 +++++++ > 7 files changed, 262 insertions(+) > create mode 100644 OvmfPkg/ResetVector/Ia32/Init32.asm > create mode 100644 OvmfPkg/ResetVector/Ia32/InitTdx.asm > create mode 100644 OvmfPkg/ResetVector/Ia32/ReloadFlat32.asm > > diff --git a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm > b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm > index ac86ce69ebe8..a390ed81d021 100644 > --- a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm > +++ b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm > @@ -155,10 +155,31 @@ resetVector: > ; > ; This is where the processor will begin execution > ; > +; In IA32 we follow the standard reset vector flow. While in X64, Td guest > +; may be supported. Td guest requires the startup mode to be 32-bit > +; protected mode but the legacy VM startup mode is 16-bit real mode. > +; To make NASM generate such shared entry code that behaves correctly in > +; both 16-bit and 32-bit mode, more BITS directives are added. > +; > +%ifdef ARCH_IA32 > + > nop > nop > jmp EarlyBspInitReal16 > > +%else > + > + smsw ax > + test al, 1 > + jz .Real > +BITS 32 > + jmp Main32 > +BITS 16 > +.Real: > + jmp EarlyBspInitReal16 > + > +%endif > + > ALIGN 16 > > fourGigabytes: > diff --git a/OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm > b/OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm > index c6d0d898bcd1..2206ca719593 100644 > --- a/OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm > +++ b/OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm > @@ -17,6 +17,9 @@ Transition32FlatTo64Flat: > > OneTimeCall SetCr3ForPageTables64 > > + cmp dword[TDX_WORK_AREA], 0x47584454 ; 'TDXG' > + jz TdxTransition32FlatTo64Flat > + > mov eax, cr4 > bts eax, 5 ; enable PAE > mov cr4, eax > @@ -65,10 +68,54 @@ EnablePaging: > bts eax, 31 ; set PG > mov cr0, eax ; enable paging > > + jmp _jumpTo64Bit > + > +; > +; Tdx Transition from 32Flat to 64Flat > +; > +TdxTransition32FlatTo64Flat: > + > + mov eax, cr4 > + bts eax, 5 ; enable PAE > + > + ; > + ; byte[TDX_WORK_AREA_PAGELEVEL5] holds the indicator whether 52bit is > supported. > + ; if it is the case, need to set LA57 and use 5-level paging > + ; > + cmp byte[TDX_WORK_AREA_PAGELEVEL5], 0 > + jz .set_cr4 > + bts eax, 12 > +.set_cr4: > + mov cr4, eax > + mov ebx, cr3 > + > + ; > + ; if la57 is not set, we are ok > + ; if using 5-level paging, adjust top-level page directory > + ; > + bt eax, 12 > + jnc .set_cr3 > + mov ebx, TDX_PT_ADDR (0) > +.set_cr3: > + mov cr3, ebx > + > + mov eax, cr0 > + bts eax, 31 ; set PG > + mov cr0, eax ; enable paging > + > +_jumpTo64Bit: > jmp LINEAR_CODE64_SEL:ADDR_OF(jumpTo64BitAndLandHere) > + > BITS 64 > jumpTo64BitAndLandHere: > > + ; > + ; For Td guest we are done and jump to the end > + ; > + mov eax, TDX_WORK_AREA > + cmp dword [eax], 0x47584454 ; 'TDXG' > + jz GoodCompare > + > ; > ; Check if the second step of the SEV-ES mitigation is to be performed. > ; > diff --git a/OvmfPkg/ResetVector/Ia32/Init32.asm > b/OvmfPkg/ResetVector/Ia32/Init32.asm > new file mode 100644 > index 000000000000..772adc51e531 > --- /dev/null > +++ b/OvmfPkg/ResetVector/Ia32/Init32.asm > @@ -0,0 +1,34 @@ > +;------------------------------------------------------------------------------ > +; @file > +; 32-bit initialization for Tdx > +; > +; Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> > +; SPDX-License-Identifier: BSD-2-Clause-Patent > +; > +;------------------------------------------------------------------------------ > + > +BITS 32 > + > +; > +; Modified: EBP > +; > +; @param[in] EBX [6:0] CPU supported GPA width > +; [7:7] 5 level page table support > +; @param[in] ECX [31:0] TDINITVP - Untrusted Configuration > +; @param[in] EDX [31:0] VCPUID > +; @param[in] ESI [31:0] VCPU_Index > +; > +Init32: > + ; > + ; Save EBX in EBP because EBX will be changed in ReloadFlat32 > + ; > + mov ebp, ebx > + > + OneTimeCall ReloadFlat32 > + > + ; > + ; Init Tdx > + ; > + OneTimeCall InitTdx > + > + OneTimeCallRet Init32 > diff --git a/OvmfPkg/ResetVector/Ia32/InitTdx.asm > b/OvmfPkg/ResetVector/Ia32/InitTdx.asm > new file mode 100644 > index 000000000000..de8273da6a0c > --- /dev/null > +++ b/OvmfPkg/ResetVector/Ia32/InitTdx.asm > @@ -0,0 +1,57 @@ > +;------------------------------------------------------------------------------ > +; @file > +; Initialize TDX_WORK_AREA to record the Tdx flag ('TDXG') and other Tdx info > +; so that the following codes can use these information. > +; > +; Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> > +; SPDX-License-Identifier: BSD-2-Clause-Patent > +; > +;------------------------------------------------------------------------------ > + > +BITS 32 > + > +; > +; Modified: EBP > +; > +InitTdx: > + ; > + ; In Td guest, BSP/AP shares the same entry point > + ; BSP builds up the page table, while APs shouldn't do the same task. > + ; Instead, APs just leverage the page table which is built by BSP. > + ; APs will wait until the page table is ready. > + ; In Td guest, vCPU 0 is treated as the BSP, the others are APs. > + ; ESI indicates the vCPU ID. > + ; > + cmp esi, 0 > + je tdBspEntry > + > +apWait: > + cmp byte[TDX_WORK_AREA_PGTBL_READY], 0 > + je apWait > + jmp doneTdxInit > + > +tdBspEntry: > + ; > + ; It is of Tdx Guest > + ; Save the Tdx info in TDX_WORK_AREA so that the following code can use > + ; these information. > + ; > + mov dword [TDX_WORK_AREA], 0x47584454 ; 'TDXG' > + > + ; > + ; EBP[6:0] CPU supported GPA width > + ; > + and ebp, 0x3f > + cmp ebp, 52 > + jl NotPageLevel5 > + mov byte[TDX_WORK_AREA_PAGELEVEL5], 1 > + > +NotPageLevel5: > + ; > + ; ECX[31:0] TDINITVP - Untrusted Configuration > + ; > + mov DWORD[TDX_WORK_AREA_INITVP], ecx > + mov DWORD[TDX_WORK_AREA_INFO], ebp > + > +doneTdxInit: > + OneTimeCallRet InitTdx > diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm > b/OvmfPkg/ResetVector/Ia32/PageTables64.asm > index 5fae8986d9da..508df6cf5967 100644 > --- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm > +++ b/OvmfPkg/ResetVector/Ia32/PageTables64.asm > @@ -218,6 +218,24 @@ SevEsDisabled: > ; > SetCr3ForPageTables64: > > + ; > + ; Check Td guest > + ; > + cmp dword[TDX_WORK_AREA], 0x47584454 ; 'TDXG' > + jnz CheckSev > + > + xor edx, edx > + > + ; > + ; In Td guest, BSP builds the page table and set the flag of > + ; TDX_WORK_AREA_PGTBL_READY. APs check this flag and then set > + ; cr3 directly. > + ; > + cmp byte[TDX_WORK_AREA_PGTBL_READY], 1 > + jz SetCr3 > + jmp SevNotActive > + > +CheckSev: > OneTimeCall CheckSevFeatures > xor edx, edx > test eax, eax > @@ -277,6 +295,29 @@ pageTableEntriesLoop: > mov [(ecx * 8 + PT_ADDR (0x2000 - 8)) + 4], edx > loop pageTableEntriesLoop > > + ; > + ; If it is Td guest, TdxExtraPageTable should be initialized as well > + ; > + cmp dword[TDX_WORK_AREA], 0x47584454 ; 'TDXG' > + jnz IsSevEs > + > + xor eax, eax > + mov ecx, 0x400 > +tdClearTdxPageTablesMemoryLoop: > + mov dword [ecx * 4 + TDX_PT_ADDR (0) - 4], eax > + loop tdClearTdxPageTablesMemoryLoop > + > + xor edx, edx > + ; > + ; Top level Page Directory Pointers (1 * 256TB entry) > + ; > + mov dword[TDX_PT_ADDR (0)], PT_ADDR (0) + PAGE_PDP_ATTR > + mov dword[TDX_PT_ADDR (4)], edx > + > + mov byte[TDX_WORK_AREA_PGTBL_READY], 1 > + jmp SetCr3 > + > +IsSevEs: > OneTimeCall IsSevEsEnabled > test eax, eax > jz SetCr3 > diff --git a/OvmfPkg/ResetVector/Ia32/ReloadFlat32.asm > b/OvmfPkg/ResetVector/Ia32/ReloadFlat32.asm > new file mode 100644 > index 000000000000..06d44142625a > --- /dev/null > +++ b/OvmfPkg/ResetVector/Ia32/ReloadFlat32.asm > @@ -0,0 +1,44 @@ > +;------------------------------------------------------------------------------ > +; @file > +; Load the GDT and set the CR0/CR4, then jump to Flat 32 protected mode. > +; > +; Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> > +; SPDX-License-Identifier: BSD-2-Clause-Patent > +; > +;------------------------------------------------------------------------------ > + > +%define SEC_DEFAULT_CR0 0x00000023 > +%define SEC_DEFAULT_CR4 0x640 > + > +BITS 32 > + > +; > +; Modified: EAX, EBX, CR0, CR4, DS, ES, FS, GS, SS > +; > +ReloadFlat32: > + > + cli > + mov ebx, ADDR_OF(gdtr) > + lgdt [ebx] > + > + mov eax, SEC_DEFAULT_CR0 > + mov cr0, eax > + > + jmp LINEAR_CODE_SEL:dword ADDR_OF(jumpToFlat32BitAndLandHere) > +BITS 32 > +jumpToFlat32BitAndLandHere: > + > + mov eax, SEC_DEFAULT_CR4 > + mov cr4, eax > + > + debugShowPostCode POSTCODE_32BIT_MODE > + > + mov ax, LINEAR_SEL > + mov ds, ax > + mov es, ax > + mov fs, ax > + mov gs, ax > + mov ss, ax > + > + OneTimeCallRet ReloadFlat32 > + > diff --git a/OvmfPkg/ResetVector/ResetVector.nasmb > b/OvmfPkg/ResetVector/ResetVector.nasmb > index b653fe87abd6..3ec163613477 100644 > --- a/OvmfPkg/ResetVector/ResetVector.nasmb > +++ b/OvmfPkg/ResetVector/ResetVector.nasmb > @@ -106,6 +106,21 @@ > %define TDX_EXTRA_PAGE_TABLE_BASE FixedPcdGet32 > (PcdOvmfSecGhcbPageTableBase) > %define TDX_EXTRA_PAGE_TABLE_SIZE FixedPcdGet32 > (PcdOvmfSecGhcbPageTableSize) > > + ; > + ; TdMailboxBase [0x10, 0x800] is reserved for OS. > + ; Td guest initialize piece of this area (TdMailboxBase [0x10,0x20]) to > + ; record the Td guest info so that this information can be used in the > + ; following ResetVector flow. > + ; > + %define TD_MAILBOX_WORKAREA_OFFSET 0x10 > + %define TDX_WORK_AREA (TDX_MAILBOX_MEMORY_BASE + > TD_MAILBOX_WORKAREA_OFFSET) > + %define TDX_WORK_AREA_PAGELEVEL5 (TDX_WORK_AREA + 4) > + %define TDX_WORK_AREA_PGTBL_READY (TDX_WORK_AREA + 5) > + %define TDX_WORK_AREA_INITVP (TDX_WORK_AREA + 8) > + %define TDX_WORK_AREA_INFO (TDX_WORK_AREA + 8 + 4) > + > + %define TDX_PT_ADDR(Offset) (TDX_EXTRA_PAGE_TABLE_BASE + (Offset)) > + > %define PT_ADDR(Offset) (FixedPcdGet32 (PcdOvmfSecPageTablesBase) + > (Offset)) > > %define GHCB_PT_ADDR (FixedPcdGet32 (PcdOvmfSecGhcbPageTableBase)) > @@ -117,6 +132,9 @@ > %define SEV_ES_VC_TOP_OF_STACK (FixedPcdGet32 > (PcdOvmfSecPeiTempRamBase) + FixedPcdGet32 (PcdOvmfSecPeiTempRamSize)) > > %include "X64/TdxMetadata.asm" > + %include "Ia32/Init32.asm" > + %include "Ia32/InitTdx.asm" > + %include "Ia32/ReloadFlat32.asm" > > %include "Ia32/Flat32ToFlat64.asm" > %include "Ia32/PageTables64.asm" > -- > 2.29.2.windows.2 ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH V2 4/4] OvmfPkg/ResetVector: Update ResetVector to support Tdx 2021-07-25 6:00 ` Yao, Jiewen @ 2021-07-25 7:50 ` Min Xu 0 siblings, 0 replies; 16+ messages in thread From: Min Xu @ 2021-07-25 7:50 UTC (permalink / raw) To: Yao, Jiewen, devel@edk2.groups.io Cc: Ard Biesheuvel, Brijesh Singh, Erdem Aktas, James Bottomley, Tom Lendacky Agree. I will update the patch set based upon your suggestions. Thanks! Xu, Min > -----Original Message----- > From: Yao, Jiewen <jiewen.yao@intel.com> > Sent: Sunday, July 25, 2021 2:01 PM > To: Xu, Min M <min.m.xu@intel.com>; devel@edk2.groups.io > Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>; Brijesh Singh > <brijesh.singh@amd.com>; Erdem Aktas <erdemaktas@google.com>; James > Bottomley <jejb@linux.ibm.com>; Tom Lendacky > <thomas.lendacky@amd.com> > Subject: RE: [PATCH V2 4/4] OvmfPkg/ResetVector: Update ResetVector to > support Tdx > > Hi Min, Brijesh, James > I feel very frustrated when I review the existing OVMF reset vector. > > A big problem is that this code mixed too many SEV stuff, and we are trying > to add more TDX stuff in *one* file, without clear isolation. > > Take PageTables64.asm as example, here are the symbols. (* means it is > newly added.) ================= > CheckSevFeatures: > GetSevEncBit: > SevEncBitLowHlt: > SevSaveMask: > NoSev: > NoSevEsVcHlt: > NoSevPass: > SevExit: > IsSevEsEnabled: > SevEsDisabled: > SetCr3ForPageTables64: > CheckSev: (*) > SevNotActive: > clearPageTablesMemoryLoop: > pageTableEntriesLoop: > tdClearTdxPageTablesMemoryLoop: (*) > IsSevEs: (*) > pageTableEntries4kLoop: > clearGhcbMemoryLoop: > SetCr3: > SevEsIdtNotCpuid: > SevEsIdtNoCpuidResponse: > SevEsIdtTerminate: > SevEsIdtHlt: > SevEsIdtVmmComm: > NextReg: > VmmDone: > ================= > > In order to better maintain the ResetVector, may I propose some refinement: > 1) The main function only contains the non-TEE function, where TEE == SEV + > TDX. > 2) The TEE related code is moved to TEE specific standalone file, such > *Sev.asm and *Tdx.Asm. > > 3) We need handle different cases with different pattern. > I hope the patter can be used consistently. As such, the reviewer can easily > understand what it is for. > > 3.1) If TEE function is a hook, then the main function calls TEE function > directly. The TEE function need implement a TEE check function (such as > IsSev, or IsTdx). For example: > ==================== > OneTimeCall PreMainFunctionHookSev > OneTimeCall PreMainFunctionHookTdx > MainFunction: > XXXXXX > OneTimeCall PostMainFunctionHookSev > OneTimeCall PostMainFunctionHookTdx > ==================== > 3.2) If TEE function is a replacement for non-TEE function. The main function > can call TEE replacement function, then check the return status to decide > next step. For example: > ==================== > OneTimeCall MainFunctionSev > Jz MainFunctionEnd > OneTimeCall MainFunctionTdx > Jz MainFunctionEnd > MainFunction: > XXXXXX > MainFunctionEnd: > ==================== > > 4) If we found it is too hard to write code in above patter, we can discuss > case by case. > > > > > > -----Original Message----- > > From: Xu, Min M <min.m.xu@intel.com> > > Sent: Thursday, July 22, 2021 1:52 PM > > To: devel@edk2.groups.io > > Cc: Xu, Min M <min.m.xu@intel.com>; Ard Biesheuvel > > <ardb+tianocore@kernel.org>; Brijesh Singh <brijesh.singh@amd.com>; > > Erdem Aktas <erdemaktas@google.com>; James Bottomley > > <jejb@linux.ibm.com>; Yao, Jiewen <jiewen.yao@intel.com>; Tom > Lendacky > > <thomas.lendacky@amd.com> > > Subject: [PATCH V2 4/4] OvmfPkg/ResetVector: Update ResetVector to > > support Tdx > > > > RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3429 > > > > In Tdx all CPUs "reset" to run on 32-bit protected mode with flat > > descriptor (paging disabled). But in Non-Td guest the initial state of > > CPUs is 16-bit real mode. To resolve this conflict, BITS 16/32 is used > > in the very beginning of ResetVector. It will check the 32-bit > > protected mode or 16-bit real mode, then jump to the corresponding entry > point. > > This is done in OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm. > > > > ReloadFlat32.asm load the GDT and set the CR0, then jump to Flat-32 > mode. > > > > InitTdx.asm is called to record the Tdx signature ('TDXG') and other > > tdx information in a TDX_WORK_AREA which can be used by the other > > routines in ResetVector. > > > > Init32.asm is 32-bit initialization code in OvmfPkg. It puts above > > ReloadFlat32 and InitTdx together to do the initializaiton for Tdx. > > > > After that Tdx jumps to 64-bit long mode by doing following tasks: > > 1. SetCr3ForPageTables64 > > For OVMF, some initial page tables is built at: > > PcdOvmfSecPageTablesBase - (PcdOvmfSecPageTablesBase + 0x6000) > > This page table supports the 4-level page table. > > But Tdx support 4-level and 5-level page table based on the CPU GPA > width. > > 48bit is 4-level paging, 52-bit is 5-level paging. > > If 5-level page table is supported (GPAW is 52), then a top level > > page directory pointers (1 * 256TB entry) is generated in the > > TdxPageTable. > > 2. Set Cr4 > > Enable PAE. > > 3. Adjust Cr3 > > If GPAW is 48, then Cr3 is PT_ADDR (0). If GPAW is 52, then Cr3 is > > TDX_PT_ADDR (0). > > > > Tdx MailBox [0x10, 0x800] is reserved for OS. So we initialize piece > > of this area ([0x10, 0x20]) to record the Tdx flag ('TDXG') and other > > Tdx info so that they can be used in the following flow. > > > > After all above is successfully done, Tdx jump to SecEntry. > > > > Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> > > 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> > > Signed-off-by: Min Xu <min.m.xu@intel.com> > > --- > > OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm | 21 ++++++++ > > OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm | 47 ++++++++++++++++ > > OvmfPkg/ResetVector/Ia32/Init32.asm | 34 ++++++++++++ > > OvmfPkg/ResetVector/Ia32/InitTdx.asm | 57 ++++++++++++++++++++ > > OvmfPkg/ResetVector/Ia32/PageTables64.asm | 41 ++++++++++++++ > > OvmfPkg/ResetVector/Ia32/ReloadFlat32.asm | 44 +++++++++++++++ > > OvmfPkg/ResetVector/ResetVector.nasmb | 18 +++++++ > > 7 files changed, 262 insertions(+) > > create mode 100644 OvmfPkg/ResetVector/Ia32/Init32.asm > > create mode 100644 OvmfPkg/ResetVector/Ia32/InitTdx.asm > > create mode 100644 OvmfPkg/ResetVector/Ia32/ReloadFlat32.asm > > > > diff --git a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm > > b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm > > index ac86ce69ebe8..a390ed81d021 100644 > > --- a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm > > +++ b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm > > @@ -155,10 +155,31 @@ resetVector: > > ; > > ; This is where the processor will begin execution ; > > +; In IA32 we follow the standard reset vector flow. While in X64, Td > > +guest ; may be supported. Td guest requires the startup mode to be > > +32-bit ; protected mode but the legacy VM startup mode is 16-bit real > mode. > > +; To make NASM generate such shared entry code that behaves correctly > > +in ; both 16-bit and 32-bit mode, more BITS directives are added. > > +; > > +%ifdef ARCH_IA32 > > + > > nop > > nop > > jmp EarlyBspInitReal16 > > > > +%else > > + > > + smsw ax > > + test al, 1 > > + jz .Real > > +BITS 32 > > + jmp Main32 > > +BITS 16 > > +.Real: > > + jmp EarlyBspInitReal16 > > + > > +%endif > > + > > ALIGN 16 > > > > fourGigabytes: > > diff --git a/OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm > > b/OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm > > index c6d0d898bcd1..2206ca719593 100644 > > --- a/OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm > > +++ b/OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm > > @@ -17,6 +17,9 @@ Transition32FlatTo64Flat: > > > > OneTimeCall SetCr3ForPageTables64 > > > > + cmp dword[TDX_WORK_AREA], 0x47584454 ; 'TDXG' > > + jz TdxTransition32FlatTo64Flat > > + > > mov eax, cr4 > > bts eax, 5 ; enable PAE > > mov cr4, eax > > @@ -65,10 +68,54 @@ EnablePaging: > > bts eax, 31 ; set PG > > mov cr0, eax ; enable paging > > > > + jmp _jumpTo64Bit > > + > > +; > > +; Tdx Transition from 32Flat to 64Flat ; > > +TdxTransition32FlatTo64Flat: > > + > > + mov eax, cr4 > > + bts eax, 5 ; enable PAE > > + > > + ; > > + ; byte[TDX_WORK_AREA_PAGELEVEL5] holds the indicator whether > > + 52bit is > > supported. > > + ; if it is the case, need to set LA57 and use 5-level paging > > + ; > > + cmp byte[TDX_WORK_AREA_PAGELEVEL5], 0 > > + jz .set_cr4 > > + bts eax, 12 > > +.set_cr4: > > + mov cr4, eax > > + mov ebx, cr3 > > + > > + ; > > + ; if la57 is not set, we are ok > > + ; if using 5-level paging, adjust top-level page directory > > + ; > > + bt eax, 12 > > + jnc .set_cr3 > > + mov ebx, TDX_PT_ADDR (0) > > +.set_cr3: > > + mov cr3, ebx > > + > > + mov eax, cr0 > > + bts eax, 31 ; set PG > > + mov cr0, eax ; enable paging > > + > > +_jumpTo64Bit: > > jmp LINEAR_CODE64_SEL:ADDR_OF(jumpTo64BitAndLandHere) > > + > > BITS 64 > > jumpTo64BitAndLandHere: > > > > + ; > > + ; For Td guest we are done and jump to the end > > + ; > > + mov eax, TDX_WORK_AREA > > + cmp dword [eax], 0x47584454 ; 'TDXG' > > + jz GoodCompare > > + > > ; > > ; Check if the second step of the SEV-ES mitigation is to be performed. > > ; > > diff --git a/OvmfPkg/ResetVector/Ia32/Init32.asm > > b/OvmfPkg/ResetVector/Ia32/Init32.asm > > new file mode 100644 > > index 000000000000..772adc51e531 > > --- /dev/null > > +++ b/OvmfPkg/ResetVector/Ia32/Init32.asm > > @@ -0,0 +1,34 @@ > > +;-------------------------------------------------------------------- > > +---------- > > +; @file > > +; 32-bit initialization for Tdx > > +; > > +; Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> ; > > +SPDX-License-Identifier: BSD-2-Clause-Patent ; > > +;-------------------------------------------------------------------- > > +---------- > > + > > +BITS 32 > > + > > +; > > +; Modified: EBP > > +; > > +; @param[in] EBX [6:0] CPU supported GPA width > > +; [7:7] 5 level page table support > > +; @param[in] ECX [31:0] TDINITVP - Untrusted Configuration > > +; @param[in] EDX [31:0] VCPUID > > +; @param[in] ESI [31:0] VCPU_Index > > +; > > +Init32: > > + ; > > + ; Save EBX in EBP because EBX will be changed in ReloadFlat32 > > + ; > > + mov ebp, ebx > > + > > + OneTimeCall ReloadFlat32 > > + > > + ; > > + ; Init Tdx > > + ; > > + OneTimeCall InitTdx > > + > > + OneTimeCallRet Init32 > > diff --git a/OvmfPkg/ResetVector/Ia32/InitTdx.asm > > b/OvmfPkg/ResetVector/Ia32/InitTdx.asm > > new file mode 100644 > > index 000000000000..de8273da6a0c > > --- /dev/null > > +++ b/OvmfPkg/ResetVector/Ia32/InitTdx.asm > > @@ -0,0 +1,57 @@ > > +;-------------------------------------------------------------------- > > +---------- > > +; @file > > +; Initialize TDX_WORK_AREA to record the Tdx flag ('TDXG') and other > Tdx info > > +; so that the following codes can use these information. > > +; > > +; Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> ; > > +SPDX-License-Identifier: BSD-2-Clause-Patent ; > > +;-------------------------------------------------------------------- > > +---------- > > + > > +BITS 32 > > + > > +; > > +; Modified: EBP > > +; > > +InitTdx: > > + ; > > + ; In Td guest, BSP/AP shares the same entry point > > + ; BSP builds up the page table, while APs shouldn't do the same task. > > + ; Instead, APs just leverage the page table which is built by BSP. > > + ; APs will wait until the page table is ready. > > + ; In Td guest, vCPU 0 is treated as the BSP, the others are APs. > > + ; ESI indicates the vCPU ID. > > + ; > > + cmp esi, 0 > > + je tdBspEntry > > + > > +apWait: > > + cmp byte[TDX_WORK_AREA_PGTBL_READY], 0 > > + je apWait > > + jmp doneTdxInit > > + > > +tdBspEntry: > > + ; > > + ; It is of Tdx Guest > > + ; Save the Tdx info in TDX_WORK_AREA so that the following code can > use > > + ; these information. > > + ; > > + mov dword [TDX_WORK_AREA], 0x47584454 ; 'TDXG' > > + > > + ; > > + ; EBP[6:0] CPU supported GPA width > > + ; > > + and ebp, 0x3f > > + cmp ebp, 52 > > + jl NotPageLevel5 > > + mov byte[TDX_WORK_AREA_PAGELEVEL5], 1 > > + > > +NotPageLevel5: > > + ; > > + ; ECX[31:0] TDINITVP - Untrusted Configuration > > + ; > > + mov DWORD[TDX_WORK_AREA_INITVP], ecx > > + mov DWORD[TDX_WORK_AREA_INFO], ebp > > + > > +doneTdxInit: > > + OneTimeCallRet InitTdx > > diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm > > b/OvmfPkg/ResetVector/Ia32/PageTables64.asm > > index 5fae8986d9da..508df6cf5967 100644 > > --- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm > > +++ b/OvmfPkg/ResetVector/Ia32/PageTables64.asm > > @@ -218,6 +218,24 @@ SevEsDisabled: > > ; > > SetCr3ForPageTables64: > > > > + ; > > + ; Check Td guest > > + ; > > + cmp dword[TDX_WORK_AREA], 0x47584454 ; 'TDXG' > > + jnz CheckSev > > + > > + xor edx, edx > > + > > + ; > > + ; In Td guest, BSP builds the page table and set the flag of > > + ; TDX_WORK_AREA_PGTBL_READY. APs check this flag and then set > > + ; cr3 directly. > > + ; > > + cmp byte[TDX_WORK_AREA_PGTBL_READY], 1 > > + jz SetCr3 > > + jmp SevNotActive > > + > > +CheckSev: > > OneTimeCall CheckSevFeatures > > xor edx, edx > > test eax, eax > > @@ -277,6 +295,29 @@ pageTableEntriesLoop: > > mov [(ecx * 8 + PT_ADDR (0x2000 - 8)) + 4], edx > > loop pageTableEntriesLoop > > > > + ; > > + ; If it is Td guest, TdxExtraPageTable should be initialized as well > > + ; > > + cmp dword[TDX_WORK_AREA], 0x47584454 ; 'TDXG' > > + jnz IsSevEs > > + > > + xor eax, eax > > + mov ecx, 0x400 > > +tdClearTdxPageTablesMemoryLoop: > > + mov dword [ecx * 4 + TDX_PT_ADDR (0) - 4], eax > > + loop tdClearTdxPageTablesMemoryLoop > > + > > + xor edx, edx > > + ; > > + ; Top level Page Directory Pointers (1 * 256TB entry) > > + ; > > + mov dword[TDX_PT_ADDR (0)], PT_ADDR (0) + PAGE_PDP_ATTR > > + mov dword[TDX_PT_ADDR (4)], edx > > + > > + mov byte[TDX_WORK_AREA_PGTBL_READY], 1 > > + jmp SetCr3 > > + > > +IsSevEs: > > OneTimeCall IsSevEsEnabled > > test eax, eax > > jz SetCr3 > > diff --git a/OvmfPkg/ResetVector/Ia32/ReloadFlat32.asm > > b/OvmfPkg/ResetVector/Ia32/ReloadFlat32.asm > > new file mode 100644 > > index 000000000000..06d44142625a > > --- /dev/null > > +++ b/OvmfPkg/ResetVector/Ia32/ReloadFlat32.asm > > @@ -0,0 +1,44 @@ > > +;-------------------------------------------------------------------- > > +---------- > > +; @file > > +; Load the GDT and set the CR0/CR4, then jump to Flat 32 protected > mode. > > +; > > +; Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> ; > > +SPDX-License-Identifier: BSD-2-Clause-Patent ; > > +;-------------------------------------------------------------------- > > +---------- > > + > > +%define SEC_DEFAULT_CR0 0x00000023 > > +%define SEC_DEFAULT_CR4 0x640 > > + > > +BITS 32 > > + > > +; > > +; Modified: EAX, EBX, CR0, CR4, DS, ES, FS, GS, SS ; > > +ReloadFlat32: > > + > > + cli > > + mov ebx, ADDR_OF(gdtr) > > + lgdt [ebx] > > + > > + mov eax, SEC_DEFAULT_CR0 > > + mov cr0, eax > > + > > + jmp LINEAR_CODE_SEL:dword > ADDR_OF(jumpToFlat32BitAndLandHere) > > +BITS 32 > > +jumpToFlat32BitAndLandHere: > > + > > + mov eax, SEC_DEFAULT_CR4 > > + mov cr4, eax > > + > > + debugShowPostCode POSTCODE_32BIT_MODE > > + > > + mov ax, LINEAR_SEL > > + mov ds, ax > > + mov es, ax > > + mov fs, ax > > + mov gs, ax > > + mov ss, ax > > + > > + OneTimeCallRet ReloadFlat32 > > + > > diff --git a/OvmfPkg/ResetVector/ResetVector.nasmb > > b/OvmfPkg/ResetVector/ResetVector.nasmb > > index b653fe87abd6..3ec163613477 100644 > > --- a/OvmfPkg/ResetVector/ResetVector.nasmb > > +++ b/OvmfPkg/ResetVector/ResetVector.nasmb > > @@ -106,6 +106,21 @@ > > %define TDX_EXTRA_PAGE_TABLE_BASE FixedPcdGet32 > > (PcdOvmfSecGhcbPageTableBase) > > %define TDX_EXTRA_PAGE_TABLE_SIZE FixedPcdGet32 > > (PcdOvmfSecGhcbPageTableSize) > > > > + ; > > + ; TdMailboxBase [0x10, 0x800] is reserved for OS. > > + ; Td guest initialize piece of this area (TdMailboxBase > > + [0x10,0x20]) to ; record the Td guest info so that this information > > + can be used in the ; following ResetVector flow. > > + ; > > + %define TD_MAILBOX_WORKAREA_OFFSET 0x10 > > + %define TDX_WORK_AREA (TDX_MAILBOX_MEMORY_BASE + > > TD_MAILBOX_WORKAREA_OFFSET) > > + %define TDX_WORK_AREA_PAGELEVEL5 (TDX_WORK_AREA + 4) > > + %define TDX_WORK_AREA_PGTBL_READY (TDX_WORK_AREA + 5) > > + %define TDX_WORK_AREA_INITVP (TDX_WORK_AREA + 8) > > + %define TDX_WORK_AREA_INFO (TDX_WORK_AREA + 8 + 4) > > + > > + %define TDX_PT_ADDR(Offset) (TDX_EXTRA_PAGE_TABLE_BASE + > (Offset)) > > + > > %define PT_ADDR(Offset) (FixedPcdGet32 (PcdOvmfSecPageTablesBase) > + > > (Offset)) > > > > %define GHCB_PT_ADDR (FixedPcdGet32 > (PcdOvmfSecGhcbPageTableBase)) > > @@ -117,6 +132,9 @@ > > %define SEV_ES_VC_TOP_OF_STACK (FixedPcdGet32 > > (PcdOvmfSecPeiTempRamBase) + FixedPcdGet32 > (PcdOvmfSecPeiTempRamSize)) > > > > %include "X64/TdxMetadata.asm" > > + %include "Ia32/Init32.asm" > > + %include "Ia32/InitTdx.asm" > > + %include "Ia32/ReloadFlat32.asm" > > > > %include "Ia32/Flat32ToFlat64.asm" > > %include "Ia32/PageTables64.asm" > > -- > > 2.29.2.windows.2 ^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2021-07-25 7:50 UTC | newest] Thread overview: 16+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2021-07-22 5:52 [PATCH V2 0/4] Add Intel TDX support in OvmfPkg/ResetVector Min Xu 2021-07-22 5:52 ` [PATCH V2 1/4] OvmfPkg: Add Tdx BFV/CFV PCDs and PcdOvmfImageSizeInKb Min Xu 2021-07-22 5:52 ` [PATCH V2 2/4] OvmfPkg: Add Tdx metadata Min Xu 2021-07-22 5:52 ` [PATCH V2 3/4] UefiCpuPkg/ResetVector: Add Main32 entry point in Main.asm Min Xu 2021-07-23 2:33 ` Ni, Ray 2021-07-25 6:07 ` Yao, Jiewen 2021-07-25 7:41 ` Min Xu 2021-07-25 7:43 ` Yao, Jiewen 2021-07-25 7:46 ` Min Xu 2021-07-22 5:52 ` [PATCH V2 4/4] OvmfPkg/ResetVector: Update ResetVector to support Tdx Min Xu 2021-07-22 17:07 ` Lendacky, Thomas 2021-07-22 22:58 ` Min Xu 2021-07-23 13:35 ` Lendacky, Thomas 2021-07-24 1:54 ` [edk2-devel] " Min Xu 2021-07-25 6:00 ` Yao, Jiewen 2021-07-25 7:50 ` Min Xu
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox