Skip to content

Commit 67dfec8

Browse files
JasonChenCJlijinxia
authored andcommitted
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>
1 parent 2ff7bf8 commit 67dfec8

File tree

3 files changed

+34
-21
lines changed

3 files changed

+34
-21
lines changed

hypervisor/arch/x86/vmexit.c

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -156,10 +156,16 @@ static const struct vm_exit_dispatch dispatch_table[] = {
156156
.need_exit_qualification = 1}
157157
};
158158

159-
struct vm_exit_dispatch *vmexit_handler(struct vcpu *vcpu)
159+
int vmexit_handler(struct vcpu *vcpu)
160160
{
161161
struct vm_exit_dispatch *dispatch = HV_NULL;
162162
uint16_t basic_exit_reason;
163+
int ret;
164+
165+
if ((int)get_cpu_id() != vcpu->pcpu_id) {
166+
pr_fatal("vcpu is not running on its pcpu!");
167+
return -EINVAL;
168+
}
163169

164170
/* Obtain interrupt info */
165171
vcpu->arch_vcpu.idt_vectoring_info =
@@ -190,8 +196,19 @@ struct vm_exit_dispatch *vmexit_handler(struct vcpu *vcpu)
190196
/* Update current vcpu in VM that caused vm exit */
191197
vcpu->vm->current_vcpu = vcpu;
192198

193-
/* Return pointer to exit dispatch entry */
194-
return dispatch;
199+
/* exit dispatch handling */
200+
if (basic_exit_reason == VMX_EXIT_REASON_EXTERNAL_INTERRUPT) {
201+
/* Handling external_interrupt
202+
* should disable intr
203+
*/
204+
ret = dispatch->handler(vcpu);
205+
} else {
206+
CPU_IRQ_ENABLE();
207+
ret = dispatch->handler(vcpu);
208+
CPU_IRQ_DISABLE();
209+
}
210+
211+
return ret;
195212
}
196213

197214
static int unhandled_vmexit_handler(__unused struct vcpu *vcpu)

hypervisor/common/hv_main.c

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ void vcpu_thread(struct vcpu *vcpu)
5353
uint64_t vmexit_begin = 0, vmexit_end = 0;
5454
uint16_t basic_exit_reason = 0;
5555
uint64_t tsc_aux_hyp_cpu = vcpu->pcpu_id;
56-
struct vm_exit_dispatch *vmexit_hdlr;
5756
int ret = 0;
5857

5958
/* If vcpu is not launched, we need to do init_vmcs first */
@@ -97,7 +96,11 @@ void vcpu_thread(struct vcpu *vcpu)
9796
}
9897

9998
ret = start_vcpu(vcpu);
100-
ASSERT(ret == 0, "vcpu resume failed");
99+
if (ret != 0) {
100+
pr_fatal("vcpu resume failed");
101+
pause_vcpu(vcpu, VCPU_ZOMBIE);
102+
continue;
103+
}
101104

102105
vmexit_begin = rdtsc();
103106

@@ -106,28 +109,21 @@ void vcpu_thread(struct vcpu *vcpu)
106109
CPU_MSR_READ(MSR_IA32_TSC_AUX, &vcpu->msr_tsc_aux_guest);
107110
/* Restore native TSC_AUX */
108111
CPU_MSR_WRITE(MSR_IA32_TSC_AUX, tsc_aux_hyp_cpu);
109-
ASSERT((int)get_cpu_id() == vcpu->pcpu_id, "");
110112

111113
/* Dispatch handler */
112-
vmexit_hdlr = vmexit_handler(vcpu);
113-
ASSERT(vmexit_hdlr != 0,
114-
"Unable to dispatch VM exit handler!");
114+
ret = vmexit_handler(vcpu);
115+
if (ret < 0) {
116+
pr_fatal("dispatch VM exit handler failed for reason"
117+
" %d, ret = %d!",
118+
vcpu->arch_vcpu.exit_reason & 0xFFFF, ret);
119+
vcpu_inject_gp(vcpu);
120+
continue;
121+
}
115122

116123
basic_exit_reason = vcpu->arch_vcpu.exit_reason & 0xFFFF;
117124
per_cpu(vmexit_cnt, vcpu->pcpu_id)[basic_exit_reason]++;
118125
TRACE_2L(TRACE_VM_EXIT, basic_exit_reason,
119126
vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].rip);
120-
121-
if (basic_exit_reason == VMX_EXIT_REASON_EXTERNAL_INTERRUPT) {
122-
/* Handling external_interrupt
123-
* should disable intr
124-
*/
125-
vmexit_hdlr->handler(vcpu);
126-
} else {
127-
CPU_IRQ_ENABLE();
128-
vmexit_hdlr->handler(vcpu);
129-
CPU_IRQ_DISABLE();
130-
}
131127
} while (1);
132128
}
133129

hypervisor/include/arch/x86/vmexit.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ struct vm_exit_dispatch {
3636
uint32_t need_exit_qualification;
3737
};
3838

39-
struct vm_exit_dispatch *vmexit_handler(struct vcpu *vcpu);
39+
int vmexit_handler(struct vcpu *vcpu);
4040
int vmcall_vmexit_handler(struct vcpu *vcpu);
4141
int cpuid_vmexit_handler(struct vcpu *vcpu);
4242
int cr_access_vmexit_handler(struct vcpu *vcpu);

0 commit comments

Comments
 (0)