hv: shutdown guest VM upon triple fault exceptions

This patch implements triple fault vmexit handler and base on VM types:

- post-launched VMs: shutdown_target_vm() injects S5 PIO write to request
  DM to shut down the target VM.
- pre-launched VMs: shut down the guest.
- SOS: similarly, but shut down all the non real-time post-launched VMs that
  depend to SOS before shutting down SOS.

Tracked-On: #2700
Signed-off-by: Zide Chen <zide.chen@intel.com>
Signed-off-by: Sainath Grandhi <sainath.grandhi@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
Zide Chen
2019-05-08 22:39:05 -07:00
committed by wenlingz
parent 9aa3fe646b
commit 26f08680eb
3 changed files with 62 additions and 1 deletions

View File

@@ -10,6 +10,55 @@
#include <per_cpu.h>
#include <vm_reset.h>
/**
* @pre vm != NULL
*/
void triple_fault_shutdown_vm(struct acrn_vm *vm)
{
struct acrn_vcpu *vcpu = vcpu_from_vid(vm, BOOT_CPU_ID);
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;
io_req->reqs.pio.address = VIRTUAL_PM1A_CNT_ADDR;
io_req->reqs.pio.size = 2ULL;
io_req->reqs.pio.value = (VIRTUAL_PM1A_SLP_EN | (5U << 10U));
/* Inject pm1a S5 request to SOS to shut down the guest */
(void)emulate_io(vcpu, io_req);
} else {
if (is_sos_vm(vm)) {
uint16_t vm_id;
/* Shut down all non real time post-launched VMs */
for (vm_id = 0U; vm_id < CONFIG_MAX_VM_NUM; vm_id++) {
struct acrn_vm *pl_vm = get_vm_from_vmid(vm_id);
if (!is_poweroff_vm(pl_vm) && is_postlaunched_vm(pl_vm) && !is_rt_vm(pl_vm)) {
(void)shutdown_vm(pl_vm);
}
}
}
/* Either SOS or pre-launched VMs */
pause_vm(vm);
per_cpu(shutdown_vm_id, vcpu->pcpu_id) = vm->vm_id;
make_shutdown_vm_request(vcpu->pcpu_id);
}
}
/**
* @pre vcpu != NULL && vm != NULL
*/