diff --git a/hypervisor/arch/x86/vmexit.c b/hypervisor/arch/x86/vmexit.c index 2a2151eda..bea3a7b49 100644 --- a/hypervisor/arch/x86/vmexit.c +++ b/hypervisor/arch/x86/vmexit.c @@ -156,10 +156,16 @@ static const struct vm_exit_dispatch dispatch_table[] = { .need_exit_qualification = 1} }; -struct vm_exit_dispatch *vmexit_handler(struct vcpu *vcpu) +int vmexit_handler(struct vcpu *vcpu) { struct vm_exit_dispatch *dispatch = HV_NULL; uint16_t basic_exit_reason; + int ret; + + if ((int)get_cpu_id() != vcpu->pcpu_id) { + pr_fatal("vcpu is not running on its pcpu!"); + return -EINVAL; + } /* Obtain interrupt info */ vcpu->arch_vcpu.idt_vectoring_info = @@ -190,8 +196,19 @@ struct vm_exit_dispatch *vmexit_handler(struct vcpu *vcpu) /* Update current vcpu in VM that caused vm exit */ vcpu->vm->current_vcpu = vcpu; - /* Return pointer to exit dispatch entry */ - return dispatch; + /* exit dispatch handling */ + if (basic_exit_reason == VMX_EXIT_REASON_EXTERNAL_INTERRUPT) { + /* Handling external_interrupt + * should disable intr + */ + ret = dispatch->handler(vcpu); + } else { + CPU_IRQ_ENABLE(); + ret = dispatch->handler(vcpu); + CPU_IRQ_DISABLE(); + } + + return ret; } static int unhandled_vmexit_handler(__unused struct vcpu *vcpu) diff --git a/hypervisor/common/hv_main.c b/hypervisor/common/hv_main.c index f3417a95d..2c6699c7c 100644 --- a/hypervisor/common/hv_main.c +++ b/hypervisor/common/hv_main.c @@ -53,7 +53,6 @@ void vcpu_thread(struct vcpu *vcpu) uint64_t vmexit_begin = 0, vmexit_end = 0; uint16_t basic_exit_reason = 0; uint64_t tsc_aux_hyp_cpu = vcpu->pcpu_id; - struct vm_exit_dispatch *vmexit_hdlr; int ret = 0; /* If vcpu is not launched, we need to do init_vmcs first */ @@ -97,7 +96,11 @@ void vcpu_thread(struct vcpu *vcpu) } ret = start_vcpu(vcpu); - ASSERT(ret == 0, "vcpu resume failed"); + if (ret != 0) { + pr_fatal("vcpu resume failed"); + pause_vcpu(vcpu, VCPU_ZOMBIE); + continue; + } vmexit_begin = rdtsc(); @@ -106,28 +109,21 @@ void vcpu_thread(struct vcpu *vcpu) CPU_MSR_READ(MSR_IA32_TSC_AUX, &vcpu->msr_tsc_aux_guest); /* Restore native TSC_AUX */ CPU_MSR_WRITE(MSR_IA32_TSC_AUX, tsc_aux_hyp_cpu); - ASSERT((int)get_cpu_id() == vcpu->pcpu_id, ""); /* Dispatch handler */ - vmexit_hdlr = vmexit_handler(vcpu); - ASSERT(vmexit_hdlr != 0, - "Unable to dispatch VM exit handler!"); + ret = vmexit_handler(vcpu); + if (ret < 0) { + pr_fatal("dispatch VM exit handler failed for reason" + " %d, ret = %d!", + vcpu->arch_vcpu.exit_reason & 0xFFFF, ret); + vcpu_inject_gp(vcpu); + continue; + } basic_exit_reason = vcpu->arch_vcpu.exit_reason & 0xFFFF; per_cpu(vmexit_cnt, vcpu->pcpu_id)[basic_exit_reason]++; TRACE_2L(TRACE_VM_EXIT, basic_exit_reason, vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].rip); - - if (basic_exit_reason == VMX_EXIT_REASON_EXTERNAL_INTERRUPT) { - /* Handling external_interrupt - * should disable intr - */ - vmexit_hdlr->handler(vcpu); - } else { - CPU_IRQ_ENABLE(); - vmexit_hdlr->handler(vcpu); - CPU_IRQ_DISABLE(); - } } while (1); } diff --git a/hypervisor/include/arch/x86/vmexit.h b/hypervisor/include/arch/x86/vmexit.h index b01061600..b5a771662 100644 --- a/hypervisor/include/arch/x86/vmexit.h +++ b/hypervisor/include/arch/x86/vmexit.h @@ -36,7 +36,7 @@ struct vm_exit_dispatch { uint32_t need_exit_qualification; }; -struct vm_exit_dispatch *vmexit_handler(struct vcpu *vcpu); +int vmexit_handler(struct vcpu *vcpu); int vmcall_vmexit_handler(struct vcpu *vcpu); int cpuid_vmexit_handler(struct vcpu *vcpu); int cr_access_vmexit_handler(struct vcpu *vcpu);