TDX cannot support pflash device since it doesn't support read-only memslot and doesn't support emulation. Load TDVF(OVMF) with -bios option for TDs. When boot a TD, besides load TDVF to the address below 4G, it needs parse TDVF metadata. Signed-off-by: Xiaoyao Li <xiaoyao.li@xxxxxxxxx> --- hw/i386/pc_sysfw.c | 7 +++++++ hw/i386/x86.c | 3 ++- target/i386/kvm/tdx-stub.c | 5 +++++ target/i386/kvm/tdx.c | 4 ++++ target/i386/kvm/tdx.h | 4 ++++ 5 files changed, 22 insertions(+), 1 deletion(-) diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c index c8d9e71b889b..cf63434ba89d 100644 --- a/hw/i386/pc_sysfw.c +++ b/hw/i386/pc_sysfw.c @@ -37,6 +37,7 @@ #include "hw/block/flash.h" #include "sysemu/kvm.h" #include "sev.h" +#include "kvm/tdx.h" #define FLASH_SECTOR_SIZE 4096 @@ -265,5 +266,11 @@ void x86_firmware_configure(void *ptr, int size) } sev_encrypt_flash(ptr, size, &error_fatal); + } else if (is_tdx_vm()) { + ret = tdx_parse_tdvf(ptr, size); + if (ret) { + error_report("failed to parse TDVF for TDX VM"); + exit(1); + } } } diff --git a/hw/i386/x86.c b/hw/i386/x86.c index 4d0b0047627d..fdf6af2f6add 100644 --- a/hw/i386/x86.c +++ b/hw/i386/x86.c @@ -47,6 +47,7 @@ #include "hw/intc/i8259.h" #include "hw/rtc/mc146818rtc.h" #include "target/i386/sev.h" +#include "kvm/tdx.h" #include "hw/acpi/cpu_hotplug.h" #include "hw/irq.h" @@ -1115,7 +1116,7 @@ void x86_bios_rom_init(MachineState *ms, const char *default_firmware, } bios = g_malloc(sizeof(*bios)); memory_region_init_ram(bios, NULL, "pc.bios", bios_size, &error_fatal); - if (sev_enabled()) { + if (sev_enabled() || is_tdx_vm()) { /* * The concept of a "reset" simply doesn't exist for * confidential computing guests, we have to destroy and diff --git a/target/i386/kvm/tdx-stub.c b/target/i386/kvm/tdx-stub.c index 2871de9d7b56..395a59721266 100644 --- a/target/i386/kvm/tdx-stub.c +++ b/target/i386/kvm/tdx-stub.c @@ -12,3 +12,8 @@ int tdx_pre_create_vcpu(CPUState *cpu) { return -EINVAL; } + +int tdx_parse_tdvf(void *flash_ptr, int size) +{ + return -EINVAL; +} diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c index 23bc3c32b14a..2953d2728b32 100644 --- a/target/i386/kvm/tdx.c +++ b/target/i386/kvm/tdx.c @@ -261,6 +261,10 @@ out: qemu_mutex_unlock(&tdx_guest->lock); return r; } +int tdx_parse_tdvf(void *flash_ptr, int size) +{ + return tdvf_parse_metadata(&tdx_guest->tdvf, flash_ptr, size); +} /* tdx guest */ OBJECT_DEFINE_TYPE_WITH_INTERFACES(TdxGuest, diff --git a/target/i386/kvm/tdx.h b/target/i386/kvm/tdx.h index 46a24ee8c7cc..12bcf25bb95b 100644 --- a/target/i386/kvm/tdx.h +++ b/target/i386/kvm/tdx.h @@ -6,6 +6,7 @@ #endif #include "exec/confidential-guest-support.h" +#include "hw/i386/tdvf.h" #define TYPE_TDX_GUEST "tdx-guest" #define TDX_GUEST(obj) OBJECT_CHECK(TdxGuest, (obj), TYPE_TDX_GUEST) @@ -21,6 +22,8 @@ typedef struct TdxGuest { bool initialized; uint64_t attributes; /* TD attributes */ + + TdxFirmware tdvf; } TdxGuest; #ifdef CONFIG_TDX @@ -33,5 +36,6 @@ int tdx_kvm_init(MachineState *ms, Error **errp); void tdx_get_supported_cpuid(uint32_t function, uint32_t index, int reg, uint32_t *ret); int tdx_pre_create_vcpu(CPUState *cpu); +int tdx_parse_tdvf(void *flash_ptr, int size); #endif /* QEMU_I386_TDX_H */ -- 2.27.0