mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-18 19:57:31 +00:00
vmexit: refine vmexit loop
- move vmexit handling into vmexit_handler - add error handling, failure will inject #GP Signed-off-by: Jason Chen CJ <jason.cj.chen@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
parent
2ff7bf826e
commit
67dfec8799
@ -156,10 +156,16 @@ static const struct vm_exit_dispatch dispatch_table[] = {
|
|||||||
.need_exit_qualification = 1}
|
.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;
|
struct vm_exit_dispatch *dispatch = HV_NULL;
|
||||||
uint16_t basic_exit_reason;
|
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 */
|
/* Obtain interrupt info */
|
||||||
vcpu->arch_vcpu.idt_vectoring_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 */
|
/* Update current vcpu in VM that caused vm exit */
|
||||||
vcpu->vm->current_vcpu = vcpu;
|
vcpu->vm->current_vcpu = vcpu;
|
||||||
|
|
||||||
/* Return pointer to exit dispatch entry */
|
/* exit dispatch handling */
|
||||||
return dispatch;
|
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)
|
static int unhandled_vmexit_handler(__unused struct vcpu *vcpu)
|
||||||
|
@ -53,7 +53,6 @@ void vcpu_thread(struct vcpu *vcpu)
|
|||||||
uint64_t vmexit_begin = 0, vmexit_end = 0;
|
uint64_t vmexit_begin = 0, vmexit_end = 0;
|
||||||
uint16_t basic_exit_reason = 0;
|
uint16_t basic_exit_reason = 0;
|
||||||
uint64_t tsc_aux_hyp_cpu = vcpu->pcpu_id;
|
uint64_t tsc_aux_hyp_cpu = vcpu->pcpu_id;
|
||||||
struct vm_exit_dispatch *vmexit_hdlr;
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
/* If vcpu is not launched, we need to do init_vmcs first */
|
/* 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);
|
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();
|
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);
|
CPU_MSR_READ(MSR_IA32_TSC_AUX, &vcpu->msr_tsc_aux_guest);
|
||||||
/* Restore native TSC_AUX */
|
/* Restore native TSC_AUX */
|
||||||
CPU_MSR_WRITE(MSR_IA32_TSC_AUX, tsc_aux_hyp_cpu);
|
CPU_MSR_WRITE(MSR_IA32_TSC_AUX, tsc_aux_hyp_cpu);
|
||||||
ASSERT((int)get_cpu_id() == vcpu->pcpu_id, "");
|
|
||||||
|
|
||||||
/* Dispatch handler */
|
/* Dispatch handler */
|
||||||
vmexit_hdlr = vmexit_handler(vcpu);
|
ret = vmexit_handler(vcpu);
|
||||||
ASSERT(vmexit_hdlr != 0,
|
if (ret < 0) {
|
||||||
"Unable to dispatch VM exit handler!");
|
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;
|
basic_exit_reason = vcpu->arch_vcpu.exit_reason & 0xFFFF;
|
||||||
per_cpu(vmexit_cnt, vcpu->pcpu_id)[basic_exit_reason]++;
|
per_cpu(vmexit_cnt, vcpu->pcpu_id)[basic_exit_reason]++;
|
||||||
TRACE_2L(TRACE_VM_EXIT, basic_exit_reason,
|
TRACE_2L(TRACE_VM_EXIT, basic_exit_reason,
|
||||||
vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].rip);
|
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);
|
} while (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ struct vm_exit_dispatch {
|
|||||||
uint32_t need_exit_qualification;
|
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 vmcall_vmexit_handler(struct vcpu *vcpu);
|
||||||
int cpuid_vmexit_handler(struct vcpu *vcpu);
|
int cpuid_vmexit_handler(struct vcpu *vcpu);
|
||||||
int cr_access_vmexit_handler(struct vcpu *vcpu);
|
int cr_access_vmexit_handler(struct vcpu *vcpu);
|
||||||
|
Loading…
Reference in New Issue
Block a user