When the kvm file descriptor changes as a part of confidential guest reset, some architecture specific setups including SEV/SEV-SNP/TDX specific setups needs to be redone. These changes are implemented as a part of the kvm_arch_on_vmfd_change() callback which was introduced previously.
Signed-off-by: Ani Sinha <[email protected]> --- target/i386/kvm/kvm.c | 82 ++++++++++++++++++++++++++---------- target/i386/kvm/trace-events | 1 + 2 files changed, 60 insertions(+), 23 deletions(-) diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c index e28ab18a14..e27ccff7a6 100644 --- a/target/i386/kvm/kvm.c +++ b/target/i386/kvm/kvm.c @@ -3269,14 +3269,52 @@ static int kvm_vm_enable_energy_msrs(KVMState *s) return 0; } +static int xen_init_wrapper(MachineState *ms, KVMState *s); + int kvm_arch_on_vmfd_change(MachineState *ms, KVMState *s) { - abort(); + int ret; + + ret = kvm_arch_init(ms, s); + if (ret < 0) { + return ret; + } + + if (object_dynamic_cast(OBJECT(ms), TYPE_X86_MACHINE)) { + X86MachineState *x86ms = X86_MACHINE(ms); + + if (x86_machine_is_smm_enabled(x86ms)) { + memory_listener_register(&smram_listener.listener, + &smram_address_space); + } + kvm_set_max_apic_id(x86ms->apic_id_limit); + } + + trace_kvm_arch_on_vmfd_change(); + return 0; +} + +static int xen_init_wrapper(MachineState *ms, KVMState *s) +{ + int ret = 0; +#ifdef CONFIG_XEN_EMU + if (!object_dynamic_cast(OBJECT(ms), TYPE_PC_MACHINE)) { + error_report("kvm: Xen support only available in PC machine"); + return -ENOTSUP; + } + /* hyperv_enabled() doesn't work yet. */ + uint32_t msr = XEN_HYPERCALL_MSR; + ret = kvm_xen_init(s, msr); +#else + error_report("kvm: Xen support not enabled in qemu"); + return -ENOTSUP; +#endif + return ret; } bool kvm_arch_supports_vmfd_change(void) { - return false; + return true; } int kvm_arch_init(MachineState *ms, KVMState *s) @@ -3284,6 +3322,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s) int ret; struct utsname utsname; Error *local_err = NULL; + static bool first = true; /* * Initialize confidential guest (SEV/TDX) context, if required @@ -3312,21 +3351,10 @@ int kvm_arch_init(MachineState *ms, KVMState *s) } if (s->xen_version) { -#ifdef CONFIG_XEN_EMU - if (!object_dynamic_cast(OBJECT(ms), TYPE_PC_MACHINE)) { - error_report("kvm: Xen support only available in PC machine"); - return -ENOTSUP; - } - /* hyperv_enabled() doesn't work yet. */ - uint32_t msr = XEN_HYPERCALL_MSR; - ret = kvm_xen_init(s, msr); + ret = xen_init_wrapper(ms, s); if (ret < 0) { return ret; } -#else - error_report("kvm: Xen support not enabled in qemu"); - return -ENOTSUP; -#endif } ret = kvm_get_supported_msrs(s); @@ -3353,16 +3381,17 @@ int kvm_arch_init(MachineState *ms, KVMState *s) return ret; } - /* Tell fw_cfg to notify the BIOS to reserve the range. */ - e820_add_entry(KVM_IDENTITY_BASE, 0x4000, E820_RESERVED); - + if (first) { + /* Tell fw_cfg to notify the BIOS to reserve the range. */ + e820_add_entry(KVM_IDENTITY_BASE, 0x4000, E820_RESERVED); + } ret = kvm_vm_set_nr_mmu_pages(s); if (ret < 0) { return ret; } if (object_dynamic_cast(OBJECT(ms), TYPE_X86_MACHINE) && - x86_machine_is_smm_enabled(X86_MACHINE(ms))) { + x86_machine_is_smm_enabled(X86_MACHINE(ms)) && first) { smram_machine_done.notify = register_smram_listener; qemu_add_machine_init_done_notifier(&smram_machine_done); } @@ -3409,15 +3438,22 @@ int kvm_arch_init(MachineState *ms, KVMState *s) return ret; } - ret = kvm_msr_energy_thread_init(s, ms); - if (ret < 0) { - error_report("kvm : error RAPL feature requirement not met"); - return ret; + if (first) { + ret = kvm_msr_energy_thread_init(s, ms); + if (ret < 0) { + error_report("kvm : " + "error RAPL feature requirement not met"); + return ret; + } } } } - kvm_vmfd_add_change_notifier(&kvm_vmfd_change_notifier); + if (first) { + kvm_vmfd_add_change_notifier(&kvm_vmfd_change_notifier); + } + + first = false; return 0; } diff --git a/target/i386/kvm/trace-events b/target/i386/kvm/trace-events index 74a6234ff7..2d213c9f9b 100644 --- a/target/i386/kvm/trace-events +++ b/target/i386/kvm/trace-events @@ -6,6 +6,7 @@ kvm_x86_add_msi_route(int virq) "Adding route entry for virq %d" kvm_x86_remove_msi_route(int virq) "Removing route entry for virq %d" kvm_x86_update_msi_routes(int num) "Updated %d MSI routes" kvm_hc_map_gpa_range(uint64_t gpa, uint64_t size, uint64_t attributes, uint64_t flags) "gpa 0x%" PRIx64 " size 0x%" PRIx64 " attributes 0x%" PRIx64 " flags 0x%" PRIx64 +kvm_arch_on_vmfd_change(void) "" # xen-emu.c kvm_xen_hypercall(int cpu, uint8_t cpl, uint64_t input, uint64_t a0, uint64_t a1, uint64_t a2, uint64_t ret) "xen_hypercall: cpu %d cpl %d input %" PRIu64 " a0 0x%" PRIx64 " a1 0x%" PRIx64 " a2 0x%" PRIx64" ret 0x%" PRIx64 -- 2.42.0
