For each TDVF sections, QEMU needs to copy the content to guest private memory via KVM API (KVM_TDX_INIT_MEM_REGION). Introduce a field @mem_ptr for TdxFirmwareEntry to track the memory pointer of each TDVF sections. So that QEMU can add/copy them to guest private memory later. TDVF sections can be classified into two groups: - Firmware itself, e.g., BFV and CFV, that locates separated from guest RAM. It's memory pointer is the bios pointer. - Sections located at guest RAM, e.g., TEMP_MEM and TD_HOB. mmap a new memory range for them. Signed-off-by: Xiaoyao Li <xiaoyao.li@xxxxxxxxx> --- hw/i386/tdvf.c | 1 + include/hw/i386/tdvf.h | 7 +++++++ target/i386/kvm/tdx.c | 22 +++++++++++++++++++++- 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/hw/i386/tdvf.c b/hw/i386/tdvf.c index a691d92eee6e..8776a2f39f01 100644 --- a/hw/i386/tdvf.c +++ b/hw/i386/tdvf.c @@ -187,6 +187,7 @@ int tdvf_parse_metadata(TdxFirmware *fw, void *flash_ptr, int size) } g_free(sections); + fw->mem_ptr = flash_ptr; return 0; err: diff --git a/include/hw/i386/tdvf.h b/include/hw/i386/tdvf.h index 593341eb2e93..d880af245a73 100644 --- a/include/hw/i386/tdvf.h +++ b/include/hw/i386/tdvf.h @@ -39,13 +39,20 @@ typedef struct TdxFirmwareEntry { uint64_t size; uint32_t type; uint32_t attributes; + + void *mem_ptr; } TdxFirmwareEntry; typedef struct TdxFirmware { + void *mem_ptr; + uint32_t nr_entries; TdxFirmwareEntry *entries; } TdxFirmware; +#define for_each_tdx_fw_entry(fw, e) \ + for (e = (fw)->entries; e != (fw)->entries + (fw)->nr_entries; e++) + int tdvf_parse_metadata(TdxFirmware *fw, void *flash_ptr, int size); #endif /* HW_I386_TDVF_H */ diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c index a95d5b894c34..8bac49419f37 100644 --- a/target/i386/kvm/tdx.c +++ b/target/i386/kvm/tdx.c @@ -12,6 +12,7 @@ */ #include "qemu/osdep.h" +#include "qemu/mmap-alloc.h" #include "qapi/error.h" #include "qom/object_interfaces.h" #include "standard-headers/asm-x86/kvm_para.h" @@ -19,6 +20,7 @@ #include "sysemu/sysemu.h" #include "hw/i386/x86.h" +#include "hw/i386/tdvf.h" #include "kvm_i386.h" #include "tdx.h" @@ -129,7 +131,25 @@ static void get_tdx_capabilities(void) static void tdx_finalize_vm(Notifier *notifier, void *unused) { - /* TODO */ + TdxFirmware *tdvf = &tdx_guest->tdvf; + TdxFirmwareEntry *entry; + + for_each_tdx_fw_entry(tdvf, entry) { + switch (entry->type) { + case TDVF_SECTION_TYPE_BFV: + case TDVF_SECTION_TYPE_CFV: + entry->mem_ptr = tdvf->mem_ptr + entry->data_offset; + break; + case TDVF_SECTION_TYPE_TD_HOB: + case TDVF_SECTION_TYPE_TEMP_MEM: + entry->mem_ptr = qemu_ram_mmap(-1, entry->size, + qemu_real_host_page_size(), 0, 0); + break; + default: + error_report("Unsupported TDVF section %d", entry->type); + exit(1); + } + } } static Notifier tdx_machine_done_notify = { -- 2.27.0