VM-Exit 可以是一種邊界事件,當 Guest 嘗試執行超出自身權限的操作時,處理器會立即介入,並把控制權交回給 Hypervisor。
在虛擬化環境中,Guest 不能直接操作 CPU 或 I/O 設備,必須透過 VM-Exit 轉交 Hypervisor 處理。
在 Intel 官方手冊(SDM Vol. 3C §25) 對 VM-Exit 的行為有詳細描述。
只要在 VMX non-root 模式 下,一旦執行某些指令,將觸發 VM-Exit 事件。這些事件屬於 fault-like,該指令本身不會真正被執行,也不會改變處理器狀態,而是被攔截並交給 Hypervisor 處理。
這些指令大致可分為 2 類:
這些指令只要在 VMX non-root 模式執行,一定會觸發 VM-Exit。
舉例: CPUID、GETSEC、INVD 或者各類 VMX 指令 VMCALL, VMLAUNCH, VMRESUME, VMXOFF, VMCLEAR 等。
這些指令是否觸發 VM-Exit,取決於 VMCS 中的控制位設定。
以 I/O 指令 (IN/OUT) 為例,當 Guest 嘗試存取 I/O port 時,是否觸發 VM-exit 由兩個控制位決定:
圖片取自於 Intel 官方手冊(SDM Vol. 3C)
有了這些規則,我們就能夠過簡單的 Guest 程式,觀察 VM-Exit 行為。
mov al, 'H'
out 0xE9, al
hlt
I/O 指令通常會被 Hypervisor 攔截。因為大部分 I/O 設備不允許 Guest 直接操作,處理器會依 VMCS 控制位與 I/O bitmap 判斷後會產生 VM-Exit,由 Hypervisor 來決定如何處理。
而當 Guest 嘗試執行 HLT 指令時,若 VMCS 中啟用了 HLT exiting 控制,處理器會立即產生 VM-Exit,把控制權交回 Hypervisor。
在 Using the KVM API 的範例就是如此。
add %bl, %al
add $'0', %al
out %al, (%dx)
mov $'\n', %al
out %al, (%dx)
hlt