From 27aee66f88f895f4f9336fdc93c667edb2709bd1 Mon Sep 17 00:00:00 2001 From: Yichong Tang Date: Mon, 13 Jan 2025 10:31:51 +0800 Subject: [PATCH] hv: hyperv: Add hyperv page destory function In current code process, hyperv data in struct vm_arch is never cleared during VM shutdown and is retained to next VM launch. As the enabled bit of hypercall_page msr is not clear, hypercall page might cause fatal error such as Windows VM BSOD during VM restart and memory remapping. Hyperv page destory function can ensure hyperv page is destory during each VM shutdown so hyperv related config such as hypercall page is established correctly during each VM launch. Tracked-On: #8755 Signed-off-by: Yichong Tang --- hypervisor/arch/x86/guest/hyperv.c | 11 +++++++++++ hypervisor/arch/x86/guest/vm.c | 4 ++++ hypervisor/include/arch/x86/asm/guest/hyperv.h | 1 + 3 files changed, 16 insertions(+) diff --git a/hypervisor/arch/x86/guest/hyperv.c b/hypervisor/arch/x86/guest/hyperv.c index 949ba8095..b4243ceb1 100644 --- a/hypervisor/arch/x86/guest/hyperv.c +++ b/hypervisor/arch/x86/guest/hyperv.c @@ -309,3 +309,14 @@ hyperv_init_vcpuid_entry(uint32_t leaf, uint32_t subleaf, uint32_t flags, dev_dbg(DBG_LEVEL_HYPERV, "hv: %s: leaf=%x subleaf=%x flags=%x eax=%x ebx=%x ecx=%x edx=%x", __func__, leaf, subleaf, flags, entry->eax, entry->ebx, entry->ecx, entry->edx); } + +void +hyperv_page_destory(struct acrn_vm *vm) +{ + /* Reset the hypercall page */ + vm->arch_vm.hyperv.hypercall_page.enabled = 0U; + /* Reset OS id */ + vm->arch_vm.hyperv.guest_os_id.val64 = 0UL; + /* Reset the TSC page */ + vm->arch_vm.hyperv.ref_tsc_page.enabled = 0UL; +} diff --git a/hypervisor/arch/x86/guest/vm.c b/hypervisor/arch/x86/guest/vm.c index 5a4075f23..c2c448064 100644 --- a/hypervisor/arch/x86/guest/vm.c +++ b/hypervisor/arch/x86/guest/vm.c @@ -957,6 +957,10 @@ int32_t shutdown_vm(struct acrn_vm *vm) offline_vcpu(vcpu); } +#ifdef CONFIG_HYPERV_ENABLED + hyperv_page_destory(vm); +#endif + /* after guest_flags not used, then clear it */ vm_config = get_vm_config(vm->vm_id); vm_config->guest_flags &= ~DM_OWNED_GUEST_FLAG_MASK; diff --git a/hypervisor/include/arch/x86/asm/guest/hyperv.h b/hypervisor/include/arch/x86/asm/guest/hyperv.h index a55c29cfd..0329d337f 100644 --- a/hypervisor/include/arch/x86/asm/guest/hyperv.h +++ b/hypervisor/include/arch/x86/asm/guest/hyperv.h @@ -64,4 +64,5 @@ int32_t hyperv_rdmsr(struct acrn_vcpu *vcpu, uint32_t msr, uint64_t *rval); void hyperv_init_time(struct acrn_vm *vm); void hyperv_init_vcpuid_entry(uint32_t leaf, uint32_t subleaf, uint32_t flags, struct vcpuid_entry *entry); +void hyperv_page_destory(struct acrn_vm *vm); #endif