本文主要记录SDM中Information for VM Exits During Event Delivery一节的相关笔记。

1. Introduction

Information for VM Exits That Occur During Event Delivery defined fields containing information for VM exits that occur while delivering an event through the IDT and as a result of any of the following cases:

  • A fault occurs during event delivery and causes a VM exit (because the bit associated with the fault is set to 1 in the exception bitmap).
  • A task switch is invoked through a task gate in the IDT. The VM exit occurs due to the task switch only after the initial checks of the task switch pass.
  • Event delivery causes an APIC-access VM exit.
  • An EPT violation, EPT misconfiguration, page-modification log-full event, or SPP-related event that occurs during event delivery.

ACRN中的实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
vcpu->arch.idt_vectoring_info = exec_vmread32(VMX_IDT_VEC_INFO_FIELD);
if ((vcpu->arch.idt_vectoring_info & VMX_INT_INFO_VALID) != 0U) {
uint32_t vector_info = vcpu->arch.idt_vectoring_info;
uint32_t vector = vector_info & 0xffU;
uint32_t type = (vector_info & VMX_INT_TYPE_MASK) >> 8U;
uint32_t err_code = 0U;

if (type == VMX_INT_TYPE_HW_EXP) {
if ((vector_info & VMX_INT_INFO_ERR_CODE_VALID) != 0U) {
err_code = exec_vmread32(VMX_IDT_VEC_ERROR_CODE);
}
(void)vcpu_queue_exception(vcpu, vector, err_code);
vcpu->arch.idt_vectoring_info = 0U;
} else if (type == VMX_INT_TYPE_NMI) {
if (is_notification_nmi(vcpu->vm)) {
pr_dbg("This NMI is used as notification signal. So ignore it.");
} else {
vcpu_make_request(vcpu, ACRN_REQUEST_NMI);
vcpu->arch.idt_vectoring_info = 0U;
}
} else {
/* No action on EXT_INT or SW exception. */
}
}

hardware exception的定义:

2. 测试用例

对于A fault occurs during event delivery and causes a VM exit case,可以利用如下测试用例复现:

  1. 设置guest IDT中Divide Error vector项的present位为0(to trigger NP fault);
  2. 设置VMCS exception bitmap field中的NP fault位为1(to trigger VM exit);
  3. guest执行divide 0指令。