Skip to content

Commit 277830a

Browse files
JasonChenCJlijinxia
authored andcommitted
exception: add vcpu_queue_exception function
add func vcpu_queue_exception to queue exception based on SDM Vol3 Table 6-5, which may cause #DF or triple fault Signed-off-by: Jason Chen CJ <jason.cj.chen@intel.com> Acked-by: Tian, Kevin <kevin.tian@intel.com>
1 parent 44af269 commit 277830a

File tree

3 files changed

+59
-0
lines changed

3 files changed

+59
-0
lines changed

hypervisor/arch/x86/interrupt.c

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@
3535

3636
#define ACRN_DBG_INTR 6
3737

38+
#define EXCEPTION_CLASS_BENIGN 1
39+
#define EXCEPTION_CLASS_CONT 2
40+
#define EXCEPTION_CLASS_PF 3
41+
3842
static const uint16_t exception_type[] = {
3943
[0] = VMX_INT_TYPE_HW_EXP,
4044
[1] = VMX_INT_TYPE_HW_EXP,
@@ -229,6 +233,59 @@ void dump_lapic(void)
229233
mmio_read_long(HPA2HVA(LAPIC_BASE + LAPIC_INT_REQUEST_REGISTER_7)));
230234
}
231235

236+
/* SDM Vol3 -6.15, Table 6-4 - interrupt and exception classes */
237+
static int get_excep_class(int32_t vector)
238+
{
239+
if (vector == IDT_DE || vector == IDT_TS || vector == IDT_NP ||
240+
vector == IDT_SS || vector == IDT_GP)
241+
return EXCEPTION_CLASS_CONT;
242+
else if (vector == IDT_PF || vector == IDT_VE)
243+
return EXCEPTION_CLASS_PF;
244+
else
245+
return EXCEPTION_CLASS_BENIGN;
246+
}
247+
248+
int vcpu_queue_exception(struct vcpu *vcpu, int32_t vector,
249+
uint32_t err_code)
250+
{
251+
if (vector >= 32) {
252+
pr_err("invalid exception vector %d", vector);
253+
return -EINVAL;
254+
}
255+
256+
if (vcpu->arch_vcpu.exception_info.exception >= 0) {
257+
int32_t prev_vector =
258+
vcpu->arch_vcpu.exception_info.exception;
259+
int32_t new_class, prev_class;
260+
261+
/* SDM vol3 - 6.15, Table 6-5 - conditions for generating a
262+
* double fault */
263+
prev_class = get_excep_class(prev_vector);
264+
new_class = get_excep_class(vector);
265+
if (prev_vector == IDT_DF &&
266+
new_class != EXCEPTION_CLASS_BENIGN) {
267+
/* triple fault happen - shutdwon mode */
268+
return vcpu_make_request(vcpu, ACRN_REQUEST_TRP_FAULT);
269+
} else if ((prev_class == EXCEPTION_CLASS_CONT &&
270+
new_class == EXCEPTION_CLASS_CONT) ||
271+
(prev_class == EXCEPTION_CLASS_PF &&
272+
new_class != EXCEPTION_CLASS_BENIGN)) {
273+
/* generate double fault */
274+
vector = IDT_DF;
275+
err_code = 0;
276+
}
277+
}
278+
279+
vcpu->arch_vcpu.exception_info.exception = vector;
280+
281+
if (exception_type[vector] & EXCEPTION_ERROR_CODE_VALID)
282+
vcpu->arch_vcpu.exception_info.error = err_code;
283+
else
284+
vcpu->arch_vcpu.exception_info.error = 0;
285+
286+
return 0;
287+
}
288+
232289
int vcpu_inject_extint(struct vcpu *vcpu)
233290
{
234291
return vcpu_make_request(vcpu, ACRN_REQUEST_EXTINT);

hypervisor/include/arch/x86/cpu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@
109109
#define IDT_AC 17 /* #AC: Alignment Check */
110110
#define IDT_MC 18 /* #MC: Machine Check */
111111
#define IDT_XF 19 /* #XF: SIMD Floating-Point Exception */
112+
#define IDT_VE 20 /* #VE: Virtualization Exception */
112113

113114
/*Bits in EFER special registers */
114115
#define EFER_LMA 0x000000400 /* Long mode active (R) */

hypervisor/include/arch/x86/irq.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ int vcpu_inject_extint(struct vcpu *vcpu);
185185
int vcpu_inject_nmi(struct vcpu *vcpu);
186186
int vcpu_inject_gp(struct vcpu *vcpu);
187187
int vcpu_make_request(struct vcpu *vcpu, int eventid);
188+
int vcpu_queue_exception(struct vcpu *vcpu, int32_t vector, uint32_t err_code);
188189

189190
int exception_vmexit_handler(struct vcpu *vcpu);
190191
int interrupt_window_vmexit_handler(struct vcpu *vcpu);

0 commit comments

Comments
 (0)