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 <haiwei.li@intel.com>
This commit is contained in:
Haiwei Li 2023-09-09 05:45:42 +08:00 committed by acrnsi-robot
parent 9c139681f2
commit 81935737ff
3 changed files with 7 additions and 9 deletions

View File

@ -995,7 +995,7 @@ void start_vm(struct acrn_vm *vm)
* @pre vm != NULL * @pre vm != NULL
* @pre vm->state == VM_PAUSED * @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; uint16_t i;
uint64_t mask; uint64_t mask;
@ -1016,7 +1016,7 @@ int32_t reset_vm(struct acrn_vm *vm)
*/ */
vm->arch_vm.vlapic_mode = VM_VLAPIC_XAPIC; 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); (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); struct acrn_vcpu *bsp = vcpu_from_vid(vm, BSP_CPU_ID);
vm->state = VM_RUNNING; reset_vm(vm, RESUME_FROM_S3);
reset_vcpu(bsp, POWER_ON_RESET);
/* When Service VM resume from S3, it will return to real mode /* When Service VM resume from S3, it will return to real mode
* with entry set to wakeup_vec. * with entry set to wakeup_vec.
*/ */
set_vcpu_startup_entry(bsp, wakeup_vec); set_vcpu_startup_entry(bsp, wakeup_vec);
init_vmcs(bsp); start_vm(vm);
launch_vcpu(bsp);
} }
static uint8_t loaded_pre_vm_nr = 0U; static uint8_t loaded_pre_vm_nr = 0U;

View File

@ -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)) { if (is_paused_vm(target_vm)) {
/* TODO: check target_vm guest_flags */ /* TODO: check target_vm guest_flags */
ret = reset_vm(target_vm); ret = reset_vm(target_vm, COLD_RESET);
} }
return ret; return ret;
} }

View File

@ -39,6 +39,7 @@ enum reset_mode {
WARM_RESET, /* behavior slightly differ from cold reset, that some MSRs might be retained. */ WARM_RESET, /* behavior slightly differ from cold reset, that some MSRs might be retained. */
INIT_RESET, /* reset by INIT */ INIT_RESET, /* reset by INIT */
SOFTWARE_RESET, /* reset by software disable<->enable */ SOFTWARE_RESET, /* reset by software disable<->enable */
RESUME_FROM_S3, /* reset core states after resuming from S3 */
}; };
struct vm_hw_info { 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 pause_vm(struct acrn_vm *vm);
void resume_vm_from_s3(struct acrn_vm *vm, uint32_t wakeup_vec); void resume_vm_from_s3(struct acrn_vm *vm, uint32_t wakeup_vec);
void start_vm(struct acrn_vm *vm); 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 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); int32_t prepare_vm(uint16_t vm_id, struct acrn_vm_config *vm_config);
void launch_vms(uint16_t pcpu_id); void launch_vms(uint16_t pcpu_id);