From b9ec2099cbfc28d5a27f4197bbab5e272e0f257c Mon Sep 17 00:00:00 2001 From: Chao Peng Date: Sat, 18 Jun 2022 10:50:42 +0800 Subject: [PATCH] i386/tdx: register TDVF as private memory Allocate the dedicated memory to hold bios image instead of re-using mmapped guest memory because the initial memory conversion to private memory wipes out the bios image by madvise(REMOVE). Signed-off-by: Isaku Yamahata Co-developed-by: Xiaoyao Li Signed-off-by: Xiaoyao Li --- accel/kvm/kvm-all.c | 2 +- hw/i386/x86.c | 10 +++++++++- include/sysemu/kvm.h | 2 ++ target/i386/kvm/tdx.c | 20 ++++++++++++++++++++ target/i386/kvm/tdx.h | 2 ++ 5 files changed, 34 insertions(+), 2 deletions(-) diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index 4c97f281be..213262d72f 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -2841,7 +2841,7 @@ static void kvm_eat_signals(CPUState *cpu) } while (sigismember(&chkset, SIG_IPI)); } -static int kvm_encrypt_reg_region(hwaddr start, hwaddr size, bool reg_region) +int kvm_encrypt_reg_region(hwaddr start, hwaddr size, bool reg_region) { int r; struct kvm_memory_attributes attr; diff --git a/hw/i386/x86.c b/hw/i386/x86.c index 9576492833..0ce8197c08 100644 --- a/hw/i386/x86.c +++ b/hw/i386/x86.c @@ -27,6 +27,7 @@ #include "qemu/units.h" #include "qemu/datadir.h" #include "qemu/guest-random.h" +#include "qom/object_interfaces.h" #include "qapi/error.h" #include "qapi/qmp/qerror.h" #include "qapi/qapi-visit-common.h" @@ -1188,8 +1189,15 @@ void x86_bios_rom_init(MachineState *ms, const char *default_firmware, (bios_size % 65536) != 0) { goto bios_error; } + bios = g_malloc(sizeof(*bios)); - memory_region_init_ram(bios, NULL, "pc.bios", bios_size, &error_fatal); + if (is_tdx_vm()) { + memory_region_init_ram_restricted(bios, NULL, "pc.bios", bios_size, &error_fatal); + tdx_set_tdvf_region(bios); + } else { + memory_region_init_ram(bios, NULL, "pc.bios", bios_size, &error_fatal); + } + if (sev_enabled() || is_tdx_vm()) { /* * The concept of a "reset" simply doesn't exist for diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index 869fb82a27..e7c98e2e0d 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -583,4 +583,6 @@ bool kvm_arch_cpu_check_are_resettable(void); bool kvm_dirty_ring_enabled(void); uint32_t kvm_dirty_ring_size(void); + +int kvm_encrypt_reg_region(hwaddr start, hwaddr size, bool reg_region); #endif diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c index 36912a4f6a..81b11cf78d 100644 --- a/target/i386/kvm/tdx.c +++ b/target/i386/kvm/tdx.c @@ -19,6 +19,9 @@ #include "sysemu/kvm.h" #include "sysemu/sysemu.h" +#include "exec/address-spaces.h" +#include "exec/ramblock.h" +#include "hw/i386/apic_internal.h" #include "hw/i386/e820_memory_layout.h" #include "hw/i386/x86.h" #include "hw/i386/tdvf.h" @@ -450,6 +453,12 @@ static void update_tdx_cpuid_lookup_by_tdx_caps(void) (tdx_caps->xfam_fixed1 & CPUID_XSTATE_XSS_MASK) >> 32; } +void tdx_set_tdvf_region(MemoryRegion *tdvf_region) +{ + assert(!tdx_guest->tdvf_region); + tdx_guest->tdvf_region = tdvf_region; +} + static TdxFirmwareEntry *tdx_get_hob_entry(TdxGuest *tdx) { TdxFirmwareEntry *entry; @@ -570,6 +579,7 @@ static void tdx_finalize_vm(Notifier *notifier, void *unused) { TdxFirmware *tdvf = &tdx_guest->tdvf; TdxFirmwareEntry *entry; + RAMBlock *ram_block; int r; tdx_init_ram_entries(); @@ -604,6 +614,12 @@ static void tdx_finalize_vm(Notifier *notifier, void *unused) .nr_pages = entry->size / 4096, }; + r = kvm_encrypt_reg_region(entry->address, entry->size, true); + if (r < 0) { + error_report("Reserve initial private memory failed %s", strerror(-r)); + exit(1); + } + __u32 flags = entry->attributes & TDVF_SECTION_ATTRIBUTES_MR_EXTEND ? KVM_TDX_MEASURE_MEMORY_REGION : 0; @@ -619,6 +635,10 @@ static void tdx_finalize_vm(Notifier *notifier, void *unused) entry->mem_ptr = NULL; } } + + /* Tdvf image was copied into private region above. It becomes unnecessary. */ + ram_block = tdx_guest->tdvf_region->ram_block; + ram_block_discard_range(ram_block, 0, ram_block->max_length); } static Notifier tdx_machine_done_notify = { diff --git a/target/i386/kvm/tdx.h b/target/i386/kvm/tdx.h index 5792518afa..9f53eddcc9 100644 --- a/target/i386/kvm/tdx.h +++ b/target/i386/kvm/tdx.h @@ -35,6 +35,7 @@ typedef struct TdxGuest { uint64_t attributes; /* TD attributes */ TdxFirmware tdvf; + MemoryRegion *tdvf_region; uint32_t nr_ram_entries; TdxRamEntry *ram_entries; @@ -50,6 +51,7 @@ 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); +void tdx_set_tdvf_region(MemoryRegion *tdvf_region); int tdx_parse_tdvf(void *flash_ptr, int size); #endif /* QEMU_I386_TDX_H */