]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg: Add IntelTdxMetadata.asm
authorMin Xu <min.m.xu@intel.com>
Tue, 28 Sep 2021 02:47:29 +0000 (10:47 +0800)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Sun, 24 Oct 2021 02:09:27 +0000 (02:09 +0000)
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 <ardb+tianocore@kernel.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.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>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
OvmfPkg/OvmfPkg.dec
OvmfPkg/OvmfPkgDefines.fdf.inc
OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
OvmfPkg/ResetVector/ResetVector.inf
OvmfPkg/ResetVector/ResetVector.nasmb
OvmfPkg/ResetVector/X64/IntelTdxMetadata.asm [new file with mode: 0644]

index 1be8d5dccbc77821ca95116fadbcc483a884ae2c..340d83f794d06c69bd5094068cfda16681a560c4 100644 (file)
   # header definition.\r
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfConfidentialComputingWorkAreaHeader|4|UINT32|0x51\r
 \r
+  ## The base address and size of the TDX Cfv base and size.\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdCfvBase|0|UINT32|0x52\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdCfvRawDataOffset|0|UINT32|0x53\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdCfvRawDataSize|0|UINT32|0x54\r
+\r
+  ## The base address and size of the TDX Bfv base and size.\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdBfvBase|0|UINT32|0x55\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdBfvRawDataOffset|0|UINT32|0x56\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdBfvRawDataSize|0|UINT32|0x57\r
 \r
 [PcdsDynamic, PcdsDynamicEx]\r
   gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2\r
index 3b5e452539165a42e1d5ff19d553e23c7e42a9ab..6170c5993ce5fb39b4fbc94ddff31f2f1ab7f20a 100644 (file)
@@ -9,6 +9,7 @@
 ##\r
 \r
 DEFINE BLOCK_SIZE        = 0x1000\r
+DEFINE VARS_OFFSET       = 0\r
 \r
 #\r
 # A firmware binary built with FD_SIZE_IN_KB=1024, and a firmware binary built\r
@@ -88,6 +89,14 @@ SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize = $(VARS_SPARE_
 # Computing Work Area header defined in the Include/WorkArea.h\r
 SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfConfidentialComputingWorkAreaHeader  = 4\r
 \r
+SET gUefiOvmfPkgTokenSpaceGuid.PcdCfvBase           = $(FW_BASE_ADDRESS)\r
+SET gUefiOvmfPkgTokenSpaceGuid.PcdCfvRawDataOffset  = $(VARS_OFFSET)\r
+SET gUefiOvmfPkgTokenSpaceGuid.PcdCfvRawDataSize    = $(VARS_SIZE)\r
+\r
+SET gUefiOvmfPkgTokenSpaceGuid.PcdBfvBase           = $(CODE_BASE_ADDRESS)\r
+SET gUefiOvmfPkgTokenSpaceGuid.PcdBfvRawDataOffset  = $(VARS_SIZE)\r
+SET gUefiOvmfPkgTokenSpaceGuid.PcdBfvRawDataSize    = $(CODE_SIZE)\r
+\r
 !if $(SMM_REQUIRE) == TRUE\r
 SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64 = gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageVariableBase\r
 SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase = gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageFtwWorkingBase\r
index 7ec3c6e980c39f255ff9b8d8f842d116d5a33ea9..7be43fb44a69f2376a999685f7832378acc17795 100644 (file)
@@ -47,6 +47,25 @@ TIMES (15 - ((guidedStructureEnd - guidedStructureStart + 15) % 16)) DB 0
 ;\r
 guidedStructureStart:\r
 \r
+%ifdef ARCH_X64\r
+;\r
+; TDX Metadata offset block\r
+;\r
+; TdxMetadata.asm is included in ARCH_X64 because Inte TDX is only\r
+; available in ARCH_X64. Below block describes the offset of\r
+; TdxMetadata block in Ovmf image\r
+;\r
+; GUID : e47a6535-984a-4798-865e-4685a7bf8ec2\r
+;\r
+tdxMetadataOffsetStart:\r
+    DD      fourGigabytes - TdxMetadataGuid - 16\r
+    DW      tdxMetadataOffsetEnd - tdxMetadataOffsetStart\r
+    DB      0x35, 0x65, 0x7a, 0xe4, 0x4a, 0x98, 0x98, 0x47\r
+    DB      0x86, 0x5e, 0x46, 0x85, 0xa7, 0xbf, 0x8e, 0xc2\r
+tdxMetadataOffsetEnd:\r
+\r
+%endif\r
+\r
 ; SEV Hash Table Block\r
 ;\r
 ; This describes the guest ram area where the hypervisor should\r
index a2520dde5508ef938be3a739338c378ec11bae37..320e5f2c65276691550aa32cfa89e5af64e87e5d 100644 (file)
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase\r
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize\r
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaSize\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupBase\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupSize\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdCfvBase\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdCfvRawDataOffset\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdCfvRawDataSize\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdBfvBase\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdBfvRawDataOffset\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdBfvRawDataSize\r
 \r
 [FixedPcd]\r
   gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretBase\r
index 21b5fd82b830cf4226ea76e0a0b37df436f101c5..eb9733e402561dcc6834f64556492bc565af69b7 100644 (file)
     %error "This implementation inherently depends on PcdOvmfSecGhcbBase not straddling a 2MB boundary"\r
   %endif\r
 \r
+  %define TDX_BFV_RAW_DATA_OFFSET   FixedPcdGet32 (PcdBfvRawDataOffset)\r
+  %define TDX_BFV_RAW_DATA_SIZE     FixedPcdGet32 (PcdBfvRawDataSize)\r
+  %define TDX_BFV_MEMORY_BASE       FixedPcdGet32 (PcdBfvBase)\r
+  %define TDX_BFV_MEMORY_SIZE       FixedPcdGet32 (PcdBfvRawDataSize)\r
+\r
+  %define TDX_CFV_RAW_DATA_OFFSET   FixedPcdGet32 (PcdCfvRawDataOffset)\r
+  %define TDX_CFV_RAW_DATA_SIZE     FixedPcdGet32 (PcdCfvRawDataSize)\r
+  %define TDX_CFV_MEMORY_BASE       FixedPcdGet32 (PcdCfvBase),\r
+  %define TDX_CFV_MEMORY_SIZE       FixedPcdGet32 (PcdCfvRawDataSize),\r
+\r
+  %define TDX_HEAP_STACK_BASE       FixedPcdGet32 (PcdOvmfSecPeiTempRamBase)\r
+  %define TDX_HEAP_STACK_SIZE       FixedPcdGet32 (PcdOvmfSecPeiTempRamSize)\r
+\r
+  %define TDX_HOB_MEMORY_BASE       FixedPcdGet32 (PcdOvmfSecGhcbBase)\r
+  %define TDX_HOB_MEMORY_SIZE       FixedPcdGet32 (PcdOvmfSecGhcbSize)\r
+\r
+  %define TDX_INIT_MEMORY_BASE      FixedPcdGet32 (PcdOvmfWorkAreaBase)\r
+  %define TDX_INIT_MEMORY_SIZE      (FixedPcdGet32 (PcdOvmfWorkAreaSize) + FixedPcdGet32 (PcdOvmfSecGhcbBackupSize))\r
+\r
+  %define OVMF_PAGE_TABLE_BASE      FixedPcdGet32 (PcdOvmfSecPageTablesBase)\r
+  %define OVMF_PAGE_TABLE_SIZE      FixedPcdGet32 (PcdOvmfSecPageTablesSize)\r
+\r
+  %define TDX_WORK_AREA_PGTBL_READY (FixedPcdGet32 (PcdOvmfWorkAreaBase) + 4)\r
+  %define TDX_WORK_AREA_GPAW        (FixedPcdGet32 (PcdOvmfWorkAreaBase) + 8)\r
+\r
   %define PT_ADDR(Offset) (FixedPcdGet32 (PcdOvmfSecPageTablesBase) + (Offset))\r
 \r
   %define GHCB_PT_ADDR (FixedPcdGet32 (PcdOvmfSecGhcbPageTableBase))\r
   %define SEV_ES_WORK_AREA_RDRAND (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 8)\r
   %define SEV_ES_WORK_AREA_ENC_MASK (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 16)\r
   %define SEV_ES_VC_TOP_OF_STACK (FixedPcdGet32 (PcdOvmfSecPeiTempRamBase) + FixedPcdGet32 (PcdOvmfSecPeiTempRamSize))\r
+\r
+%include "X64/IntelTdxMetadata.asm"\r
 %include "Ia32/Flat32ToFlat64.asm"\r
 %include "Ia32/AmdSev.asm"\r
 %include "Ia32/PageTables64.asm"\r
diff --git a/OvmfPkg/ResetVector/X64/IntelTdxMetadata.asm b/OvmfPkg/ResetVector/X64/IntelTdxMetadata.asm
new file mode 100644 (file)
index 0000000..07f89ef
--- /dev/null
@@ -0,0 +1,115 @@
+;------------------------------------------------------------------------------\r
+; @file\r
+; Tdx Virtual Firmware metadata\r
+;\r
+; When host VMM creates a new guest TD, some initial set of TD-private pages\r
+; are added using the TDH.MEM.PAGE.ADD function. These pages typically contain\r
+; Virtual BIOS code and data along with some clear pages for stacks and heap.\r
+; In the meanwhile, some configuration data need be measured by host VMM.\r
+; Tdx Metadata is designed for this purpose to indicate host VMM how to do the\r
+; above tasks.\r
+;\r
+; Tdx Metadata consists of a DESCRIPTOR as the header followed by several\r
+; SECTIONs. Host VMM sets up the memory for TDVF according to these sections.\r
+;\r
+; _Bfv is the example (Bfv refers to the Virtual BIOS code).\r
+; - By DataOffset/RawDataSize host VMM knows about the position of the code\r
+;   in the binary image.\r
+; - MemoryAddress/MemoryDataSize indicates the guest physical address/size of\r
+;   the Bfv to be loaded.\r
+; - Type field means this section is of BFV. This field is designed for the\r
+;   purpose that in some case host VMM may do some additional processing based\r
+;   upon the section type. TdHob section is an example. Host VMM pass the\r
+;   physical memory information to the guest firmware by writing the data in\r
+;   the memory region designated by TdHob section.\r
+; - By design code part of the binary image (Bfv) should be measured by host\r
+;   VMM. This is indicated by the Attributes field.\r
+;\r
+; So put all these information together, when a new guest is being created,\r
+; the initial TD-private pages for BFV is added by TDH.MEM.PAGE.ADD function,\r
+; and Bfv is loaded at the guest physical address indicated by MemoryAddress.\r
+; Since the Attributes is TDX_METADATA_ATTRIBUTES_EXTENDMR, Bfv is measured by\r
+; host VMM.\r
+;\r
+; Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>\r
+; SPDX-License-Identifier: BSD-2-Clause-Patent\r
+;\r
+;------------------------------------------------------------------------------\r
+\r
+BITS    64\r
+\r
+%define TDX_METADATA_SECTION_TYPE_BFV       0\r
+%define TDX_METADATA_SECTION_TYPE_CFV       1\r
+%define TDX_METADATA_SECTION_TYPE_TD_HOB    2\r
+%define TDX_METADATA_SECTION_TYPE_TEMP_MEM  3\r
+%define TDX_METADATA_VERSION                1\r
+%define TDX_METADATA_ATTRIBUTES_EXTENDMR    0x00000001\r
+\r
+ALIGN   16\r
+TIMES (15 - ((TdxGuidedStructureEnd - TdxGuidedStructureStart + 15) % 16)) DB 0\r
+\r
+TdxGuidedStructureStart:\r
+\r
+;\r
+; TDVF meta data\r
+;\r
+TdxMetadataGuid:\r
+  DB  0xf3, 0xf9, 0xea, 0xe9, 0x8e, 0x16, 0xd5, 0x44\r
+  DB  0xa8, 0xeb, 0x7f, 0x4d, 0x87, 0x38, 0xf6, 0xae\r
+\r
+_Descriptor:\r
+  DB 'T','D','V','F'                                  ; Signature\r
+  DD TdxGuidedStructureEnd - _Descriptor              ; Length\r
+  DD TDX_METADATA_VERSION                             ; Version\r
+  DD (TdxGuidedStructureEnd - _Descriptor - 16)/32    ; Number of sections\r
+\r
+_Bfv:\r
+  DD TDX_BFV_RAW_DATA_OFFSET\r
+  DD TDX_BFV_RAW_DATA_SIZE\r
+  DQ TDX_BFV_MEMORY_BASE\r
+  DQ TDX_BFV_MEMORY_SIZE\r
+  DD TDX_METADATA_SECTION_TYPE_BFV\r
+  DD TDX_METADATA_ATTRIBUTES_EXTENDMR\r
+\r
+_Cfv:\r
+  DD TDX_CFV_RAW_DATA_OFFSET\r
+  DD TDX_CFV_RAW_DATA_SIZE\r
+  DQ TDX_CFV_MEMORY_BASE\r
+  DQ TDX_CFV_MEMORY_SIZE\r
+  DD TDX_METADATA_SECTION_TYPE_CFV\r
+  DD 0\r
+\r
+_TdxHeapStack:\r
+  DD 0\r
+  DD 0\r
+  DQ TDX_HEAP_STACK_BASE\r
+  DQ TDX_HEAP_STACK_SIZE\r
+  DD TDX_METADATA_SECTION_TYPE_TEMP_MEM\r
+  DD 0\r
+\r
+_TdxInitMem:\r
+  DD 0\r
+  DD 0\r
+  DQ TDX_INIT_MEMORY_BASE\r
+  DQ TDX_INIT_MEMORY_SIZE\r
+  DD TDX_METADATA_SECTION_TYPE_TEMP_MEM\r
+  DD 0\r
+\r
+_TdHob:\r
+  DD 0\r
+  DD 0\r
+  DQ TDX_HOB_MEMORY_BASE\r
+  DQ TDX_HOB_MEMORY_SIZE\r
+  DD TDX_METADATA_SECTION_TYPE_TD_HOB\r
+  DD 0\r
+\r
+_OvmfPageTable:\r
+  DD 0\r
+  DD 0\r
+  DQ OVMF_PAGE_TABLE_BASE\r
+  DQ OVMF_PAGE_TABLE_SIZE\r
+  DD TDX_METADATA_SECTION_TYPE_TEMP_MEM\r
+  DD 0\r
+\r
+TdxGuidedStructureEnd:\r
+ALIGN   16\r