2018-03-07 20:57:14 +08:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2018 Intel Corporation. All rights reserved.
|
|
|
|
*
|
2018-05-26 01:49:13 +08:00
|
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
2018-03-07 20:57:14 +08:00
|
|
|
*/
|
|
|
|
|
2019-02-26 15:42:56 +08:00
|
|
|
#include <vm.h>
|
2019-02-28 01:54:58 +08:00
|
|
|
#include <vm_reset.h>
|
2019-02-26 15:42:56 +08:00
|
|
|
#include <vmcs.h>
|
|
|
|
#include <vmexit.h>
|
|
|
|
#include <irq.h>
|
2018-03-07 20:57:14 +08:00
|
|
|
#include <schedule.h>
|
2019-02-26 15:42:56 +08:00
|
|
|
#include <profiling.h>
|
|
|
|
#include <trace.h>
|
|
|
|
#include <logmsg.h>
|
2018-03-07 20:57:14 +08:00
|
|
|
|
2019-05-23 16:17:28 +08:00
|
|
|
void vcpu_thread(struct thread_object *obj)
|
2018-03-07 20:57:14 +08:00
|
|
|
{
|
2019-05-23 16:17:28 +08:00
|
|
|
struct acrn_vcpu *vcpu = list_entry(obj, struct acrn_vcpu, thread_obj);
|
2018-07-17 14:16:06 +08:00
|
|
|
uint32_t basic_exit_reason = 0U;
|
2018-06-28 16:27:12 +08:00
|
|
|
int32_t ret = 0;
|
2018-03-07 20:57:14 +08:00
|
|
|
|
|
|
|
do {
|
2019-06-11 13:22:32 +08:00
|
|
|
if (!is_lapic_pt_enabled(vcpu)) {
|
2018-11-11 14:07:33 +08:00
|
|
|
CPU_IRQ_DISABLE();
|
|
|
|
}
|
2018-03-07 20:57:14 +08:00
|
|
|
|
2019-06-24 15:28:10 +08:00
|
|
|
/* Don't open interrupt window between here and vmentry */
|
|
|
|
if (need_reschedule(vcpu->pcpu_id)) {
|
|
|
|
schedule();
|
|
|
|
}
|
|
|
|
|
2018-05-25 12:29:00 +08:00
|
|
|
/* Check and process pending requests(including interrupt) */
|
2018-05-28 13:00:04 +08:00
|
|
|
ret = acrn_handle_pending_request(vcpu);
|
|
|
|
if (ret < 0) {
|
|
|
|
pr_fatal("vcpu handling pending request fail");
|
|
|
|
pause_vcpu(vcpu, VCPU_ZOMBIE);
|
2019-07-09 18:02:57 +08:00
|
|
|
/* Fatal error happened (triple fault). Stop the vcpu running. */
|
|
|
|
schedule();
|
2018-05-28 13:00:04 +08:00
|
|
|
}
|
2018-03-07 20:57:14 +08:00
|
|
|
|
2018-10-23 03:29:21 +08:00
|
|
|
profiling_vmenter_handler(vcpu);
|
|
|
|
|
2019-01-14 11:30:36 +08:00
|
|
|
TRACE_2L(TRACE_VM_ENTER, 0UL, 0UL);
|
2018-09-07 22:36:12 +08:00
|
|
|
ret = run_vcpu(vcpu);
|
2018-05-22 14:33:13 +08:00
|
|
|
if (ret != 0) {
|
|
|
|
pr_fatal("vcpu resume failed");
|
|
|
|
pause_vcpu(vcpu, VCPU_ZOMBIE);
|
2019-07-09 18:02:57 +08:00
|
|
|
/* Fatal error happened (resume vcpu failed). Stop the vcpu running. */
|
|
|
|
schedule();
|
2018-05-22 14:33:13 +08:00
|
|
|
}
|
2019-01-14 11:30:36 +08:00
|
|
|
basic_exit_reason = vcpu->arch.exit_reason & 0xFFFFU;
|
|
|
|
TRACE_2L(TRACE_VM_EXIT, basic_exit_reason, vcpu_get_rip(vcpu));
|
2018-03-07 20:57:14 +08:00
|
|
|
|
2018-11-05 13:27:01 +08:00
|
|
|
vcpu->arch.nrexits++;
|
2018-03-07 20:57:14 +08:00
|
|
|
|
2018-12-13 07:12:42 +08:00
|
|
|
profiling_pre_vmexit_handler(vcpu);
|
|
|
|
|
2019-06-11 13:22:32 +08:00
|
|
|
if (!is_lapic_pt_enabled(vcpu)) {
|
2018-11-11 14:07:33 +08:00
|
|
|
CPU_IRQ_ENABLE();
|
|
|
|
}
|
2018-03-07 20:57:14 +08:00
|
|
|
/* Dispatch handler */
|
2018-05-22 14:33:13 +08:00
|
|
|
ret = vmexit_handler(vcpu);
|
|
|
|
if (ret < 0) {
|
|
|
|
pr_fatal("dispatch VM exit handler failed for reason"
|
2018-08-13 13:20:24 +08:00
|
|
|
" %d, ret = %d!", basic_exit_reason, ret);
|
2018-07-04 16:04:40 +08:00
|
|
|
vcpu_inject_gp(vcpu, 0U);
|
2018-05-22 14:33:13 +08:00
|
|
|
continue;
|
|
|
|
}
|
2018-03-07 20:57:14 +08:00
|
|
|
|
2018-12-13 07:12:42 +08:00
|
|
|
profiling_post_vmexit_handler(vcpu);
|
2018-03-07 20:57:14 +08:00
|
|
|
} while (1);
|
|
|
|
}
|
2018-12-20 15:15:20 +08:00
|
|
|
|
2019-05-23 16:17:28 +08:00
|
|
|
void default_idle(__unused struct thread_object *obj)
|
2018-12-20 15:15:20 +08:00
|
|
|
{
|
2019-04-22 05:52:12 +08:00
|
|
|
uint16_t pcpu_id = get_pcpu_id();
|
2018-12-20 15:15:20 +08:00
|
|
|
|
|
|
|
while (1) {
|
2018-12-25 14:48:17 +08:00
|
|
|
if (need_reschedule(pcpu_id)) {
|
2018-12-20 15:15:20 +08:00
|
|
|
schedule();
|
2019-07-15 17:43:49 +08:00
|
|
|
} else if (need_offline(pcpu_id)) {
|
2018-12-20 15:15:20 +08:00
|
|
|
cpu_dead();
|
2019-02-28 01:54:58 +08:00
|
|
|
} else if (need_shutdown_vm(pcpu_id)) {
|
|
|
|
shutdown_vm_from_idle(pcpu_id);
|
2018-12-20 15:15:20 +08:00
|
|
|
} else {
|
|
|
|
CPU_IRQ_ENABLE();
|
|
|
|
cpu_do_idle();
|
|
|
|
CPU_IRQ_DISABLE();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|