From 81935737ff01b7ce7def5c63629ca41b62b3adbc Mon Sep 17 00:00:00 2001 From: Haiwei Li Date: Sat, 9 Sep 2023 05:45:42 +0800 Subject: [PATCH] hv: s3: reset vm after resume Now only BSP is reset. After Service VM OS resumes from s3, APs' apic_base_msr are incorrect with x2apic bit en. To avoid incorrect states, do `reset_vm` after resume. Tracked-On: #8623 Signed-off-by: Haiwei Li --- hypervisor/arch/x86/guest/vm.c | 11 ++++------- hypervisor/common/hypercall.c | 2 +- hypervisor/include/arch/x86/asm/guest/vm.h | 3 ++- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/hypervisor/arch/x86/guest/vm.c b/hypervisor/arch/x86/guest/vm.c index 1ab7eb312..f4a247be8 100644 --- a/hypervisor/arch/x86/guest/vm.c +++ b/hypervisor/arch/x86/guest/vm.c @@ -995,7 +995,7 @@ void start_vm(struct acrn_vm *vm) * @pre vm != NULL * @pre vm->state == VM_PAUSED */ -int32_t reset_vm(struct acrn_vm *vm) +int32_t reset_vm(struct acrn_vm *vm, enum reset_mode mode) { uint16_t i; uint64_t mask; @@ -1016,7 +1016,7 @@ int32_t reset_vm(struct acrn_vm *vm) */ vm->arch_vm.vlapic_mode = VM_VLAPIC_XAPIC; - if (is_service_vm(vm)) { + if ((mode == POWER_ON_RESET) && is_service_vm(vm)) { (void)prepare_os_image(vm); } @@ -1078,17 +1078,14 @@ void resume_vm_from_s3(struct acrn_vm *vm, uint32_t wakeup_vec) { struct acrn_vcpu *bsp = vcpu_from_vid(vm, BSP_CPU_ID); - vm->state = VM_RUNNING; - - reset_vcpu(bsp, POWER_ON_RESET); + reset_vm(vm, RESUME_FROM_S3); /* When Service VM resume from S3, it will return to real mode * with entry set to wakeup_vec. */ set_vcpu_startup_entry(bsp, wakeup_vec); - init_vmcs(bsp); - launch_vcpu(bsp); + start_vm(vm); } static uint8_t loaded_pre_vm_nr = 0U; diff --git a/hypervisor/common/hypercall.c b/hypervisor/common/hypercall.c index 12bf26880..bf4d74d5c 100644 --- a/hypervisor/common/hypercall.c +++ b/hypervisor/common/hypercall.c @@ -348,7 +348,7 @@ int32_t hcall_reset_vm(__unused struct acrn_vcpu *vcpu, struct acrn_vm *target_v if (is_paused_vm(target_vm)) { /* TODO: check target_vm guest_flags */ - ret = reset_vm(target_vm); + ret = reset_vm(target_vm, COLD_RESET); } return ret; } diff --git a/hypervisor/include/arch/x86/asm/guest/vm.h b/hypervisor/include/arch/x86/asm/guest/vm.h index 0503ed8b4..5bb5deea0 100644 --- a/hypervisor/include/arch/x86/asm/guest/vm.h +++ b/hypervisor/include/arch/x86/asm/guest/vm.h @@ -39,6 +39,7 @@ enum reset_mode { WARM_RESET, /* behavior slightly differ from cold reset, that some MSRs might be retained. */ INIT_RESET, /* reset by INIT */ SOFTWARE_RESET, /* reset by software disable<->enable */ + RESUME_FROM_S3, /* reset core states after resuming from S3 */ }; struct vm_hw_info { @@ -239,7 +240,7 @@ void poweroff_if_rt_vm(struct acrn_vm *vm); void pause_vm(struct acrn_vm *vm); void resume_vm_from_s3(struct acrn_vm *vm, uint32_t wakeup_vec); void start_vm(struct acrn_vm *vm); -int32_t reset_vm(struct acrn_vm *vm); +int32_t reset_vm(struct acrn_vm *vm, enum reset_mode mode); int32_t create_vm(uint16_t vm_id, uint64_t pcpu_bitmap, struct acrn_vm_config *vm_config, struct acrn_vm **rtn_vm); int32_t prepare_vm(uint16_t vm_id, struct acrn_vm_config *vm_config); void launch_vms(uint16_t pcpu_id);