1*b65a6011SIsaku Yamahata /* 2*b65a6011SIsaku Yamahata * Copyright (c) 2025 Intel Corporation 3*b65a6011SIsaku Yamahata * Author: Isaku Yamahata <isaku.yamahata at gmail.com> 4*b65a6011SIsaku Yamahata * <isaku.yamahata at intel.com> 5*b65a6011SIsaku Yamahata * Xiaoyao Li <xiaoyao.li@intel.com> 6*b65a6011SIsaku Yamahata * 7*b65a6011SIsaku Yamahata * SPDX-License-Identifier: GPL-2.0-or-later 8*b65a6011SIsaku Yamahata */ 9*b65a6011SIsaku Yamahata 10*b65a6011SIsaku Yamahata #include "qemu/osdep.h" 11*b65a6011SIsaku Yamahata #include "qemu/error-report.h" 12*b65a6011SIsaku Yamahata 13*b65a6011SIsaku Yamahata #include "hw/i386/pc.h" 14*b65a6011SIsaku Yamahata #include "hw/i386/tdvf.h" 15*b65a6011SIsaku Yamahata #include "system/kvm.h" 16*b65a6011SIsaku Yamahata 17*b65a6011SIsaku Yamahata #define TDX_METADATA_OFFSET_GUID "e47a6535-984a-4798-865e-4685a7bf8ec2" 18*b65a6011SIsaku Yamahata #define TDX_METADATA_VERSION 1 19*b65a6011SIsaku Yamahata #define TDVF_SIGNATURE 0x46564454 /* TDVF as little endian */ 20*b65a6011SIsaku Yamahata #define TDVF_ALIGNMENT 4096 21*b65a6011SIsaku Yamahata 22*b65a6011SIsaku Yamahata /* 23*b65a6011SIsaku Yamahata * the raw structs read from TDVF keeps the name convention in 24*b65a6011SIsaku Yamahata * TDVF Design Guide spec. 25*b65a6011SIsaku Yamahata */ 26*b65a6011SIsaku Yamahata typedef struct { 27*b65a6011SIsaku Yamahata uint32_t DataOffset; 28*b65a6011SIsaku Yamahata uint32_t RawDataSize; 29*b65a6011SIsaku Yamahata uint64_t MemoryAddress; 30*b65a6011SIsaku Yamahata uint64_t MemoryDataSize; 31*b65a6011SIsaku Yamahata uint32_t Type; 32*b65a6011SIsaku Yamahata uint32_t Attributes; 33*b65a6011SIsaku Yamahata } TdvfSectionEntry; 34*b65a6011SIsaku Yamahata 35*b65a6011SIsaku Yamahata typedef struct { 36*b65a6011SIsaku Yamahata uint32_t Signature; 37*b65a6011SIsaku Yamahata uint32_t Length; 38*b65a6011SIsaku Yamahata uint32_t Version; 39*b65a6011SIsaku Yamahata uint32_t NumberOfSectionEntries; 40*b65a6011SIsaku Yamahata TdvfSectionEntry SectionEntries[]; 41*b65a6011SIsaku Yamahata } TdvfMetadata; 42*b65a6011SIsaku Yamahata 43*b65a6011SIsaku Yamahata struct tdx_metadata_offset { 44*b65a6011SIsaku Yamahata uint32_t offset; 45*b65a6011SIsaku Yamahata }; 46*b65a6011SIsaku Yamahata 47*b65a6011SIsaku Yamahata static TdvfMetadata *tdvf_get_metadata(void *flash_ptr, int size) 48*b65a6011SIsaku Yamahata { 49*b65a6011SIsaku Yamahata TdvfMetadata *metadata; 50*b65a6011SIsaku Yamahata uint32_t offset = 0; 51*b65a6011SIsaku Yamahata uint8_t *data; 52*b65a6011SIsaku Yamahata 53*b65a6011SIsaku Yamahata if ((uint32_t) size != size) { 54*b65a6011SIsaku Yamahata return NULL; 55*b65a6011SIsaku Yamahata } 56*b65a6011SIsaku Yamahata 57*b65a6011SIsaku Yamahata if (pc_system_ovmf_table_find(TDX_METADATA_OFFSET_GUID, &data, NULL)) { 58*b65a6011SIsaku Yamahata offset = size - le32_to_cpu(((struct tdx_metadata_offset *)data)->offset); 59*b65a6011SIsaku Yamahata 60*b65a6011SIsaku Yamahata if (offset + sizeof(*metadata) > size) { 61*b65a6011SIsaku Yamahata return NULL; 62*b65a6011SIsaku Yamahata } 63*b65a6011SIsaku Yamahata } else { 64*b65a6011SIsaku Yamahata error_report("Cannot find TDX_METADATA_OFFSET_GUID"); 65*b65a6011SIsaku Yamahata return NULL; 66*b65a6011SIsaku Yamahata } 67*b65a6011SIsaku Yamahata 68*b65a6011SIsaku Yamahata metadata = flash_ptr + offset; 69*b65a6011SIsaku Yamahata 70*b65a6011SIsaku Yamahata /* Finally, verify the signature to determine if this is a TDVF image. */ 71*b65a6011SIsaku Yamahata metadata->Signature = le32_to_cpu(metadata->Signature); 72*b65a6011SIsaku Yamahata if (metadata->Signature != TDVF_SIGNATURE) { 73*b65a6011SIsaku Yamahata error_report("Invalid TDVF signature in metadata!"); 74*b65a6011SIsaku Yamahata return NULL; 75*b65a6011SIsaku Yamahata } 76*b65a6011SIsaku Yamahata 77*b65a6011SIsaku Yamahata /* Sanity check that the TDVF doesn't overlap its own metadata. */ 78*b65a6011SIsaku Yamahata metadata->Length = le32_to_cpu(metadata->Length); 79*b65a6011SIsaku Yamahata if (offset + metadata->Length > size) { 80*b65a6011SIsaku Yamahata return NULL; 81*b65a6011SIsaku Yamahata } 82*b65a6011SIsaku Yamahata 83*b65a6011SIsaku Yamahata /* Only version 1 is supported/defined. */ 84*b65a6011SIsaku Yamahata metadata->Version = le32_to_cpu(metadata->Version); 85*b65a6011SIsaku Yamahata if (metadata->Version != TDX_METADATA_VERSION) { 86*b65a6011SIsaku Yamahata return NULL; 87*b65a6011SIsaku Yamahata } 88*b65a6011SIsaku Yamahata 89*b65a6011SIsaku Yamahata return metadata; 90*b65a6011SIsaku Yamahata } 91*b65a6011SIsaku Yamahata 92*b65a6011SIsaku Yamahata static int tdvf_parse_and_check_section_entry(const TdvfSectionEntry *src, 93*b65a6011SIsaku Yamahata TdxFirmwareEntry *entry) 94*b65a6011SIsaku Yamahata { 95*b65a6011SIsaku Yamahata entry->data_offset = le32_to_cpu(src->DataOffset); 96*b65a6011SIsaku Yamahata entry->data_len = le32_to_cpu(src->RawDataSize); 97*b65a6011SIsaku Yamahata entry->address = le64_to_cpu(src->MemoryAddress); 98*b65a6011SIsaku Yamahata entry->size = le64_to_cpu(src->MemoryDataSize); 99*b65a6011SIsaku Yamahata entry->type = le32_to_cpu(src->Type); 100*b65a6011SIsaku Yamahata entry->attributes = le32_to_cpu(src->Attributes); 101*b65a6011SIsaku Yamahata 102*b65a6011SIsaku Yamahata /* sanity check */ 103*b65a6011SIsaku Yamahata if (entry->size < entry->data_len) { 104*b65a6011SIsaku Yamahata error_report("Broken metadata RawDataSize 0x%x MemoryDataSize 0x%lx", 105*b65a6011SIsaku Yamahata entry->data_len, entry->size); 106*b65a6011SIsaku Yamahata return -1; 107*b65a6011SIsaku Yamahata } 108*b65a6011SIsaku Yamahata if (!QEMU_IS_ALIGNED(entry->address, TDVF_ALIGNMENT)) { 109*b65a6011SIsaku Yamahata error_report("MemoryAddress 0x%lx not page aligned", entry->address); 110*b65a6011SIsaku Yamahata return -1; 111*b65a6011SIsaku Yamahata } 112*b65a6011SIsaku Yamahata if (!QEMU_IS_ALIGNED(entry->size, TDVF_ALIGNMENT)) { 113*b65a6011SIsaku Yamahata error_report("MemoryDataSize 0x%lx not page aligned", entry->size); 114*b65a6011SIsaku Yamahata return -1; 115*b65a6011SIsaku Yamahata } 116*b65a6011SIsaku Yamahata 117*b65a6011SIsaku Yamahata switch (entry->type) { 118*b65a6011SIsaku Yamahata case TDVF_SECTION_TYPE_BFV: 119*b65a6011SIsaku Yamahata case TDVF_SECTION_TYPE_CFV: 120*b65a6011SIsaku Yamahata /* The sections that must be copied from firmware image to TD memory */ 121*b65a6011SIsaku Yamahata if (entry->data_len == 0) { 122*b65a6011SIsaku Yamahata error_report("%d section with RawDataSize == 0", entry->type); 123*b65a6011SIsaku Yamahata return -1; 124*b65a6011SIsaku Yamahata } 125*b65a6011SIsaku Yamahata break; 126*b65a6011SIsaku Yamahata case TDVF_SECTION_TYPE_TD_HOB: 127*b65a6011SIsaku Yamahata case TDVF_SECTION_TYPE_TEMP_MEM: 128*b65a6011SIsaku Yamahata /* The sections that no need to be copied from firmware image */ 129*b65a6011SIsaku Yamahata if (entry->data_len != 0) { 130*b65a6011SIsaku Yamahata error_report("%d section with RawDataSize 0x%x != 0", 131*b65a6011SIsaku Yamahata entry->type, entry->data_len); 132*b65a6011SIsaku Yamahata return -1; 133*b65a6011SIsaku Yamahata } 134*b65a6011SIsaku Yamahata break; 135*b65a6011SIsaku Yamahata default: 136*b65a6011SIsaku Yamahata error_report("TDVF contains unsupported section type %d", entry->type); 137*b65a6011SIsaku Yamahata return -1; 138*b65a6011SIsaku Yamahata } 139*b65a6011SIsaku Yamahata 140*b65a6011SIsaku Yamahata return 0; 141*b65a6011SIsaku Yamahata } 142*b65a6011SIsaku Yamahata 143*b65a6011SIsaku Yamahata int tdvf_parse_metadata(TdxFirmware *fw, void *flash_ptr, int size) 144*b65a6011SIsaku Yamahata { 145*b65a6011SIsaku Yamahata g_autofree TdvfSectionEntry *sections = NULL; 146*b65a6011SIsaku Yamahata TdvfMetadata *metadata; 147*b65a6011SIsaku Yamahata ssize_t entries_size; 148*b65a6011SIsaku Yamahata int i; 149*b65a6011SIsaku Yamahata 150*b65a6011SIsaku Yamahata metadata = tdvf_get_metadata(flash_ptr, size); 151*b65a6011SIsaku Yamahata if (!metadata) { 152*b65a6011SIsaku Yamahata return -EINVAL; 153*b65a6011SIsaku Yamahata } 154*b65a6011SIsaku Yamahata 155*b65a6011SIsaku Yamahata /* load and parse metadata entries */ 156*b65a6011SIsaku Yamahata fw->nr_entries = le32_to_cpu(metadata->NumberOfSectionEntries); 157*b65a6011SIsaku Yamahata if (fw->nr_entries < 2) { 158*b65a6011SIsaku Yamahata error_report("Invalid number of fw entries (%u) in TDVF Metadata", 159*b65a6011SIsaku Yamahata fw->nr_entries); 160*b65a6011SIsaku Yamahata return -EINVAL; 161*b65a6011SIsaku Yamahata } 162*b65a6011SIsaku Yamahata 163*b65a6011SIsaku Yamahata entries_size = fw->nr_entries * sizeof(TdvfSectionEntry); 164*b65a6011SIsaku Yamahata if (metadata->Length != sizeof(*metadata) + entries_size) { 165*b65a6011SIsaku Yamahata error_report("TDVF metadata len (0x%x) mismatch, expected (0x%x)", 166*b65a6011SIsaku Yamahata metadata->Length, 167*b65a6011SIsaku Yamahata (uint32_t)(sizeof(*metadata) + entries_size)); 168*b65a6011SIsaku Yamahata return -EINVAL; 169*b65a6011SIsaku Yamahata } 170*b65a6011SIsaku Yamahata 171*b65a6011SIsaku Yamahata fw->entries = g_new(TdxFirmwareEntry, fw->nr_entries); 172*b65a6011SIsaku Yamahata sections = g_new(TdvfSectionEntry, fw->nr_entries); 173*b65a6011SIsaku Yamahata 174*b65a6011SIsaku Yamahata memcpy(sections, (void *)metadata + sizeof(*metadata), entries_size); 175*b65a6011SIsaku Yamahata 176*b65a6011SIsaku Yamahata for (i = 0; i < fw->nr_entries; i++) { 177*b65a6011SIsaku Yamahata if (tdvf_parse_and_check_section_entry(§ions[i], &fw->entries[i])) { 178*b65a6011SIsaku Yamahata goto err; 179*b65a6011SIsaku Yamahata } 180*b65a6011SIsaku Yamahata } 181*b65a6011SIsaku Yamahata 182*b65a6011SIsaku Yamahata return 0; 183*b65a6011SIsaku Yamahata 184*b65a6011SIsaku Yamahata err: 185*b65a6011SIsaku Yamahata fw->entries = 0; 186*b65a6011SIsaku Yamahata g_free(fw->entries); 187*b65a6011SIsaku Yamahata return -EINVAL; 188*b65a6011SIsaku Yamahata } 189