hv: vm_manage: minor fix about triple_fault_shutdown_vm

The current implement will trigger shutdown vm request on the BSP VCPU on the VM,
not the VCPU will trap out because triple fault. However, if the BSP VCPU on the VM
is handling another IO emulation, it may overwrite the triple fault IO request on
the vhm_request_buffer in function acrn_insert_request. The atomic operation of
get_vhm_req_state can't guarantee the vhm_request_buffer will not access by another
IO request if it is not running on the corresponding VCPU. So it should trigger
triple fault shutdown VM IO request on the VCPU which trap out because of triple
fault exception.
Besides, rt_vm_pm1a_io_write will do the right thing which we shouldn't do it in
triple_fault_shutdown_vm.

Tracked-On: #1842
Signed-off-by: Li, Fei1 <fei1.li@intel.com>
This commit is contained in:
Li, Fei1 2019-07-03 00:00:46 +08:00 committed by ACRN System Integration
parent ebf5c5eb5d
commit 09a63560f4
4 changed files with 6 additions and 16 deletions

View File

@ -34,6 +34,7 @@
#include <logmsg.h>
#include <host_pm.h>
#include <acrn_common.h>
#include <vcpu.h>
#include <vm_reset.h>
/* Per ACPI spec:

View File

@ -32,21 +32,13 @@ struct acpi_reset_reg *get_host_reset_reg_data(void)
/**
* @pre vm != NULL
*/
void triple_fault_shutdown_vm(struct acrn_vm *vm)
void triple_fault_shutdown_vm(struct acrn_vcpu *vcpu)
{
struct acrn_vcpu *vcpu = vcpu_from_vid(vm, BOOT_CPU_ID);
struct acrn_vm *vm = vcpu->vm;
if (is_postlaunched_vm(vm)) {
struct io_request *io_req = &vcpu->req;
/*
* Hypervisor sets VM_POWERING_OFF to authenticate that the reboot request is
* actually from the guest itself, not from external entities. (for example acrn-dm)
*/
if (is_rt_vm(vm)) {
vm->state = VM_POWERING_OFF;
}
/* Device model emulates PM1A for post-launched VMs */
io_req->io_type = REQ_PORTIO;
io_req->reqs.pio.direction = REQUEST_WRITE;
@ -258,9 +250,6 @@ void register_reset_port_handler(struct acrn_vm *vm)
void shutdown_vm_from_idle(uint16_t pcpu_id)
{
struct acrn_vm *vm = get_vm_from_vmid(per_cpu(shutdown_vm_id, pcpu_id));
const struct acrn_vcpu *vcpu = vcpu_from_vid(vm, BOOT_CPU_ID);
if (vcpu->pcpu_id == pcpu_id) {
(void)shutdown_vm(vm);
}
}

View File

@ -255,7 +255,7 @@ static int32_t triple_fault_vmexit_handler(struct acrn_vcpu *vcpu)
{
pr_fatal("VM%d: triple fault @ guest RIP 0x%016llx, exit qualification: 0x%016llx",
vcpu->vm->vm_id, exec_vmread(VMX_GUEST_RIP), exec_vmread(VMX_EXIT_QUALIFICATION));
triple_fault_shutdown_vm(vcpu->vm);
triple_fault_shutdown_vm(vcpu);
return 0;
}

View File

@ -16,7 +16,7 @@ struct acpi_reset_reg {
void register_reset_port_handler(struct acrn_vm *vm);
void shutdown_vm_from_idle(uint16_t pcpu_id);
void triple_fault_shutdown_vm(struct acrn_vm *vm);
void triple_fault_shutdown_vm(struct acrn_vcpu *vcpu);
struct acpi_reset_reg *get_host_reset_reg_data(void);
#endif /* VM_RESET_H_ */