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:
parent
ebf5c5eb5d
commit
09a63560f4
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
(void)shutdown_vm(vm);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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_ */
|
||||
|
|
Loading…
Reference in New Issue