From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by mx.groups.io with SMTP id smtpd.web10.2727.1634775565150108185 for ; Wed, 20 Oct 2021 17:19:32 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 134.134.136.65, mailfrom: min.m.xu@intel.com) X-IronPort-AV: E=McAfee;i="6200,9189,10143"; a="228860527" X-IronPort-AV: E=Sophos;i="5.87,168,1631602800"; d="scan'208";a="228860527" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Oct 2021 17:19:31 -0700 X-IronPort-AV: E=Sophos;i="5.87,168,1631602800"; d="scan'208";a="494875995" Received: from mxu9-mobl1.ccr.corp.intel.com ([10.238.4.37]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Oct 2021 17:19:29 -0700 From: "Min Xu" To: devel@edk2.groups.io Cc: Min Xu , Ard Biesheuvel , Jordan Justen , Gerd Hoffmann , Brijesh Singh , Erdem Aktas , James Bottomley , Jiewen Yao , Tom Lendacky Subject: [PATCH V10 3/4] OvmfPkg: Add IntelTdxMetadata.asm Date: Thu, 21 Oct 2021 08:17:33 +0800 Message-Id: X-Mailer: git-send-email 2.29.2.windows.2 In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3429 In TDX when host VMM creates a new guest TD, some initial set of TD-private pages are added using the TDH.MEM.PAGE.ADD function. These pages typically contain Virtual BIOS code and data along with some clear pages for stacks and heap. In the meanwhile, some configuration data need be measured by host VMM. Tdx Metadata is designed for this purpose to indicate host VMM how to do the above tasks. More detailed information of Metadata is in [TDVF] Section 11. Tdx Metadata describes the information about the image for VMM use. For example, the base address and length of the TdHob, Bfv, Cfv, etc. The offset of the Metadata is stored in a GUID-ed structure which is appended in the GUID-ed chain from a fixed GPA (0xffffffd0). In this commit there are 2 new definitions of BFV & CFV. 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 (OVMF_CODE.fd). CFV is the vars part of Ovmf image (OVMF_VARS.fd). Since AMD SEV has already defined some SEV specific memory region in MEMFD. TDX re-uses some of the memory regions defined by SEV. - MailBox : PcdOvmfSecGhcbBackupBase|PcdOvmfSecGhcbBackupSize - TdHob : PcdOvmfSecGhcbBase|PcdOvmfSecGhcbSize [TDVF] https://software.intel.com/content/dam/develop/external/us/en/ documents/tdx-virtual-firmware-design-guide-rev-1.pdf Cc: Ard Biesheuvel Cc: Jordan Justen Cc: Gerd Hoffmann Cc: Brijesh Singh Cc: Erdem Aktas Cc: James Bottomley Cc: Jiewen Yao Cc: Tom Lendacky Acked-by: Gerd Hoffmann Signed-off-by: Min Xu --- OvmfPkg/OvmfPkg.dec | 9 ++ OvmfPkg/OvmfPkgDefines.fdf.inc | 9 ++ OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm | 19 +++ OvmfPkg/ResetVector/ResetVector.inf | 9 ++ OvmfPkg/ResetVector/ResetVector.nasmb | 27 +++++ OvmfPkg/ResetVector/X64/IntelTdxMetadata.asm | 115 +++++++++++++++++++ 6 files changed, 188 insertions(+) create mode 100644 OvmfPkg/ResetVector/X64/IntelTdxMetadata.asm diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec index 1be8d5dccbc7..340d83f794d0 100644 --- a/OvmfPkg/OvmfPkg.dec +++ b/OvmfPkg/OvmfPkg.dec @@ -340,6 +340,15 @@ # header definition. gUefiOvmfPkgTokenSpaceGuid.PcdOvmfConfidentialComputingWorkAreaHeader|4|UINT32|0x51 + ## The base address and size of the TDX Cfv base and size. + gUefiOvmfPkgTokenSpaceGuid.PcdCfvBase|0|UINT32|0x52 + gUefiOvmfPkgTokenSpaceGuid.PcdCfvRawDataOffset|0|UINT32|0x53 + gUefiOvmfPkgTokenSpaceGuid.PcdCfvRawDataSize|0|UINT32|0x54 + + ## The base address and size of the TDX Bfv base and size. + gUefiOvmfPkgTokenSpaceGuid.PcdBfvBase|0|UINT32|0x55 + gUefiOvmfPkgTokenSpaceGuid.PcdBfvRawDataOffset|0|UINT32|0x56 + gUefiOvmfPkgTokenSpaceGuid.PcdBfvRawDataSize|0|UINT32|0x57 [PcdsDynamic, PcdsDynamicEx] gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2 diff --git a/OvmfPkg/OvmfPkgDefines.fdf.inc b/OvmfPkg/OvmfPkgDefines.fdf.inc index 3b5e45253916..6170c5993ce5 100644 --- a/OvmfPkg/OvmfPkgDefines.fdf.inc +++ b/OvmfPkg/OvmfPkgDefines.fdf.inc @@ -9,6 +9,7 @@ ## DEFINE BLOCK_SIZE = 0x1000 +DEFINE VARS_OFFSET = 0 # # A firmware binary built with FD_SIZE_IN_KB=1024, and a firmware binary built @@ -88,6 +89,14 @@ SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize = $(VARS_SPARE_ # Computing Work Area header defined in the Include/WorkArea.h SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfConfidentialComputingWorkAreaHeader = 4 +SET gUefiOvmfPkgTokenSpaceGuid.PcdCfvBase = $(FW_BASE_ADDRESS) +SET gUefiOvmfPkgTokenSpaceGuid.PcdCfvRawDataOffset = $(VARS_OFFSET) +SET gUefiOvmfPkgTokenSpaceGuid.PcdCfvRawDataSize = $(VARS_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 diff --git a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm index 7ec3c6e980c3..7be43fb44a69 100644 --- a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm +++ b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm @@ -47,6 +47,25 @@ TIMES (15 - ((guidedStructureEnd - guidedStructureStart + 15) % 16)) DB 0 ; guidedStructureStart: +%ifdef ARCH_X64 +; +; TDX Metadata offset block +; +; TdxMetadata.asm is included in ARCH_X64 because Inte TDX is only +; available in ARCH_X64. Below block describes the offset of +; TdxMetadata block in Ovmf image +; +; GUID : e47a6535-984a-4798-865e-4685a7bf8ec2 +; +tdxMetadataOffsetStart: + DD fourGigabytes - TdxMetadataGuid - 16 + DW tdxMetadataOffsetEnd - tdxMetadataOffsetStart + DB 0x35, 0x65, 0x7a, 0xe4, 0x4a, 0x98, 0x98, 0x47 + DB 0x86, 0x5e, 0x46, 0x85, 0xa7, 0xbf, 0x8e, 0xc2 +tdxMetadataOffsetEnd: + +%endif + ; SEV Hash Table Block ; ; This describes the guest ram area where the hypervisor should diff --git a/OvmfPkg/ResetVector/ResetVector.inf b/OvmfPkg/ResetVector/ResetVector.inf index a2520dde5508..320e5f2c6527 100644 --- a/OvmfPkg/ResetVector/ResetVector.inf +++ b/OvmfPkg/ResetVector/ResetVector.inf @@ -44,6 +44,15 @@ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaSize + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupBase + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupSize + 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 21b5fd82b830..eb9733e40256 100644 --- a/OvmfPkg/ResetVector/ResetVector.nasmb +++ b/OvmfPkg/ResetVector/ResetVector.nasmb @@ -69,6 +69,31 @@ %error "This implementation inherently depends on PcdOvmfSecGhcbBase not straddling a 2MB boundary" %endif + %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_STACK_BASE FixedPcdGet32 (PcdOvmfSecPeiTempRamBase) + %define TDX_HEAP_STACK_SIZE FixedPcdGet32 (PcdOvmfSecPeiTempRamSize) + + %define TDX_HOB_MEMORY_BASE FixedPcdGet32 (PcdOvmfSecGhcbBase) + %define TDX_HOB_MEMORY_SIZE FixedPcdGet32 (PcdOvmfSecGhcbSize) + + %define TDX_INIT_MEMORY_BASE FixedPcdGet32 (PcdOvmfWorkAreaBase) + %define TDX_INIT_MEMORY_SIZE (FixedPcdGet32 (PcdOvmfWorkAreaSize) + FixedPcdGet32 (PcdOvmfSecGhcbBackupSize)) + + %define OVMF_PAGE_TABLE_BASE FixedPcdGet32 (PcdOvmfSecPageTablesBase) + %define OVMF_PAGE_TABLE_SIZE FixedPcdGet32 (PcdOvmfSecPageTablesSize) + + %define TDX_WORK_AREA_PGTBL_READY (FixedPcdGet32 (PcdOvmfWorkAreaBase) + 4) + %define TDX_WORK_AREA_GPAW (FixedPcdGet32 (PcdOvmfWorkAreaBase) + 8) + %define PT_ADDR(Offset) (FixedPcdGet32 (PcdOvmfSecPageTablesBase) + (Offset)) %define GHCB_PT_ADDR (FixedPcdGet32 (PcdOvmfSecGhcbPageTableBase)) @@ -78,6 +103,8 @@ %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 "X64/IntelTdxMetadata.asm" %include "Ia32/Flat32ToFlat64.asm" %include "Ia32/AmdSev.asm" %include "Ia32/PageTables64.asm" diff --git a/OvmfPkg/ResetVector/X64/IntelTdxMetadata.asm b/OvmfPkg/ResetVector/X64/IntelTdxMetadata.asm new file mode 100644 index 000000000000..07f89ef4931f --- /dev/null +++ b/OvmfPkg/ResetVector/X64/IntelTdxMetadata.asm @@ -0,0 +1,115 @@ +;------------------------------------------------------------------------------ +; @file +; Tdx Virtual Firmware metadata +; +; When host VMM creates a new guest TD, some initial set of TD-private pages +; are added using the TDH.MEM.PAGE.ADD function. These pages typically contain +; Virtual BIOS code and data along with some clear pages for stacks and heap. +; In the meanwhile, some configuration data need be measured by host VMM. +; Tdx Metadata is designed for this purpose to indicate host VMM how to do the +; above tasks. +; +; Tdx Metadata consists of a DESCRIPTOR as the header followed by several +; SECTIONs. Host VMM sets up the memory for TDVF according to these sections. +; +; _Bfv is the example (Bfv refers to the Virtual BIOS code). +; - By DataOffset/RawDataSize host VMM knows about the position of the code +; in the binary image. +; - MemoryAddress/MemoryDataSize indicates the guest physical address/size of +; the Bfv to be loaded. +; - Type field means this section is of BFV. This field is designed for the +; purpose that in some case host VMM may do some additional processing based +; upon the section type. TdHob section is an example. Host VMM pass the +; physical memory information to the guest firmware by writing the data in +; the memory region designated by TdHob section. +; - By design code part of the binary image (Bfv) should be measured by host +; VMM. This is indicated by the Attributes field. +; +; So put all these information together, when a new guest is being created, +; the initial TD-private pages for BFV is added by TDH.MEM.PAGE.ADD function, +; and Bfv is loaded at the guest physical address indicated by MemoryAddress. +; Since the Attributes is TDX_METADATA_ATTRIBUTES_EXTENDMR, Bfv is measured by +; host VMM. +; +; Copyright (c) 2021, Intel Corporation. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent +; +;------------------------------------------------------------------------------ + +BITS 64 + +%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 + +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 + +_TdxHeapStack: + DD 0 + DD 0 + DQ TDX_HEAP_STACK_BASE + DQ TDX_HEAP_STACK_SIZE + DD TDX_METADATA_SECTION_TYPE_TEMP_MEM + DD 0 + +_TdxInitMem: + DD 0 + DD 0 + DQ TDX_INIT_MEMORY_BASE + DQ TDX_INIT_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 + +_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