虛擬化(VT)技術 之 CPU虛擬化探討

VMX運行模式 只有以下兩種:
vmx root狀態 -> vmm運行時的狀態
vmx non-root -> 離開vmm後, 普通CPU的狀態

VMEXIT: 引發VMM的時侯
VMENTRY: 離開VMM的時侯

VMCS:
VMCS是指一塊4KB內存, 用於VMEXIT 及VMENTRY切換時 更換CPU狀態

一個CPU只可以綁定一個VMCS

使用VMPTRLD 可以將當前運行這一句的CPU 綁定到對應的VMCS
使用VMCLEAR , 解除綁定現在CPU的VMCS

VMCS的變換過程:
(1) CPU1 上執行VMCLEAR解除綁定
(2) CPU2 上執行VMPTRLD 綁定新的VMCS

VMCS主要偏移:
(1) 偏移0 : 是VMCS版本標誌 表示VMCS的數據格式的版本
(2) 偏移4 : VMX中止指示, VMEXIT不成功的時侯產生VMX中止, CPU會在此處存入VMX意外中止的原因
(3) 偏移8 : VMCS數據域,該域的格式是隨著CPU不同而有所變化->具體用偏移0判斷哪一種格式

x86 CPU 提供兩條新引入的匯編指令:
VMREAD<索引> : 讀取VMCS中<索引>指定的域
VMWRITE<索引><數據> : 寫入<索引>中指定的域

VT-x 為VMCS數據域每一個字段也定義了相應的<索引> 因此令以上兩條指令成立
具體VMCS數據域包含以下六大信息
(1)客戶機狀態域: 進入VMM時保留, 離開VMM時取回
(2)宿主機狀態域: 進入VMM時取回, 離開VMM時保留
(3)VM-Entry控制域: 控制VM-Entry的過程
(4)VM-Execution控制域: 控制處理器在vmx non-root模式時的行為
(5)VM-Exit控制域: 控制vm-exit的過程
(6)VM-Exit數據域: 提供vm-exit的原因及相關信息, 注意這是只讀(read-only)的


(1) 客戶機狀態域: 用於保存CPU在NON-ROOT模式下的CPU上下文(Context)
VM-Entry時會提取恢復到CPU, VM-Exit時會保留

它保存了段寄存器, CR3, IDTR, GDTR等寄存器 CPU通過他們來切換實現客戶機地址空間與VMM地址空間的切換

客戶機狀態域並不包含通用寄存器或浮點數寄存器, 它們的保存與恢復是由VMM自身決定

基本保存的寄存器如下:
1. 控制寄存器: CR0,CR3,CR4
2. 調試寄存器: CR7
3. RSP RIP 和RFLAGS
4. CS,SS,DS,ES,FS,GS,LDTR,TR,及對應影子段描述寄存器
5. GDTR,IDTR,及對應影子段描述符寄存器
6. MSR寄存器 --> VMCS可以決定由誰切換他們
7. 此外, 非寄存器內容,如中斷狀態域 也被保存

(2) 宿主機狀態域: 用於保存CPU在vmx root狀態下的上下文, 只在VM-Exit時會使用到, 在vm-entry時不用保存 , 因為不會改變 -> 即使

進入vmx要處理的事或信息基本上每次都一樣
例如vm-exit的入口RIP,永遠不會改變, 需要改變時VMM可以直接修改

它包含了以下寄存器(亦只包含)
1. 控制寄存器: CR0,CR3,CR4
2. 調試寄存器: CR7
3. RSP RIP 和RFLAGS
4. CS,SS,DS,ES,FS,GS,TR,及對應影子段描述寄存器
5. GDTR,IDTR,及對應影子段描述符寄存器
6. IA32_SYSENTER_CS
7. IA32_SYSTENER_ESP
8. IA32_SYSTENER_EIP

VM-EXIT發生時,CS:RIP指定了入口地址, SS:RSP指定了棧地址

VMX操作模式:

由於VT-X只是一種基於IA-32 CPU的一種擴展, 因此VMX在默認情況下是關閉的

VT-x引入了以下兩條新指令:
VMXON: 打開VMX操作模式
VMXOFF: 關閉VMX操作模式

以下為基本運作概念:
1. VMM執行VMXON指令進入VMX操作模式, 即虛擬的CPU (現在是VMX ROOT)
2. VMM執行VMLAUNCH或VMRESUME,產生VM-ENTRY返回到真實CPU(現在是VMX NON ROOT)
3. 虛擬CPU執行特權級指令:如SYSENTER, 或者發生中斷/異常, 使虛擬CPU陷入真實CPU(即發生VM-EXIT, 進入VMX ROOT狀態)
4. 真實CPU處理好後, 轉到第二步返回到虛擬CPU(沒什麼特別事別來找我)
5. 如果VMM決定退出,則執行VMXOFF 關閉操作模式


VM-ENTRY詳解:
VM-ENTRY是指CPU由vmx root mode切換到non-root mode
即意指由真實CPU(宿主機) 返回虛擬CPU(客戶機) 的一個過程

一般情況下是由VMM主動發起

VT-x引入了以下兩條新指令:
VMLAUNCH: 用於剛執行過的VMCLEAR的VMCS的第一次VM-ENTRY
VMRESUME: 用於執行過VMLAUNCH的VMCS的以後的VM-ENTRY

VMCS的VM-Entry控制域包含:
1. IA-32E mode guest : 是否支持Intel 64架構
2. MSR VM-entry控制: 在vm-entry發生時,vmm可以指示 真實cpu(宿主機) 在切換到虛擬cpu(客戶機) 時正確加載msr的值,VM-Entry MSR

load count(指定要加載的msr數目) 及VM-Entry-load address (指定要加載的msr區域的物理地址)

3. 在vm-entry發生時, vmm可以操作vmcs相關字段 來注入一個事件 , 這個事件指同步的異常或 異步的中斷及NMI
例子1: 當客戶機意外訪問一個保留的(vmm所監視的)虛擬MSR寄存器,導致VM-exit, 就可以在vm-exit的處理函數中向VM-Entry

Interruption-Information域寫入需要信息來注入#GP異常(實際不存在這個異常)

例子2: 我們模疑的虛擬設備在一個DMA操作結束後,需要向客戶機注入一個虛擬中斷,也是通過寫VMCS這個字段實現

VMM如何實現注入事件:

在返回到虛擬CPU時,要執行第一句代碼之前, CPU檢測VM-Entry Interruption-Information 字段的最高位(31位) 如果為1 則根據(10-8位

)指定的中斷類型,和(7:0位)指定的向量號,在當前的客戶機引發一個異常, 中斷, 甚至NMI, 此外還可以在(11位)寫入一個錯誤碼,錯誤碼

由VMCS的寄存器VM-Entry execetpion error code指定

(以上一套異常邏輯 不是真實地發生, 而是vmm在返回後 假定注入的一個事件, 但cpu則會以為是真正發生了 並且由他的IDT處理)

VM-Entry的過程:
(1) 執行基本的參數檢查(詳情看intel手册) 確保可以返回到虛擬cpu
(2) 對VMCS中的宿主機(真實CPU)狀態域進行有效性檢查, 確保下一次虛擬CPU可以成功進入VMM
(3) 對VMCS中的客戶機(虛擬CPU)狀態域進行有效性檢查, 根據它來裝載虛擬CPU的狀態
(4) 根據VMCS中的VM-Entry MSR-load區域 裝載msr寄存器
(5) 根據VMCS中的VM-Entry event injection control的配置, 用作真正返回到虛擬cpu後引發的最後一個動作(對於vmm)
(6) 開始繼續執行指令(直至下次vm-Exit)


VM-Exit: 意指CPU從non root mode 切換到root mode(即客戶機陷入到vmm的一個過程)
引發vm-exit原因很多, 對於一條任意的敏感指令,有可能在陷入vmm之後與本身預期的操作有所變化:
如:
1. 行為不變化, 但不引起vm-exit
2. 行為變化,產生vm-exit (典型需要截獲的敏感指令)
3. 行為變化,產生vm-exit (這類指令不一定會產生vm-exit, 但可以通過VM-Execution域控制)

同樣地, 我們可以讓某些指令不產生vm-exit, 以減小切換, 提高效率

----------------------------------------------------------------------------------------
VM-Execution控制域(VM Execution Control):

VM-Execution控制域用來控制CPU在non root mode時的行為,即客戶機(虛擬CPU,還沒有陷入VMM之前)
(1) 控制某條敏感指令是否產生VM-EXIT
(2) 在某些敏感指令不產生VM-EXIT時,控制該指令的行為
(3) 異常和中斷是否產生VM-EXIT

External-interrupt exiting : 控制外部中斷是否陷入vmm , 1為陷入, 0為直接交給客戶機的操作系統(以下忽略)

HLT exiting : 控制HLT指令是否陷入vmm, 如果客戶機使用HLT, 通常意味客戶機操作系統空閒, VMM可以暫時掛起客戶機, 而運行其他客

戶機,直到某種條件產生,才喚醒客戶機

INVLPG Exiting : 控制INVLPG 指令是否陷入VMM

WBINVD Exiting : 控制指令是否陷入vmm (這個位和INVLPG一起使用可以幫助MMU虛擬化)

RDPMC Exiting : 控制RDPMC指令是否陷入VMM (這個位的使用可以幫助performance monitor虛擬化)

CR8-load Exiting : 控制CR8 LOAD 指令是否陷入VMM

CR8-store Exiting : 控制CR8 STRORE 指令是否陷入vmm

MOV-DR Exiting : 控制mov dr 指令是否陷入VMM (這個位有助於調試寄存器虛擬化)

Unconditional I/O Exiting : 控制端口i/o 是否陷入VMM 如:IN, INS, INSB ,INSW,INSD,OUT,OUTS,OUTSB,OUTSW,OUTSD,(這個位有助於

I/O設備虛擬化), 當Use I/O bitmaps 為1時, 這個位會被忽略, 而轉向使用I/O bitmap來控制

Use I/O bitmaps : 是否使用I/O bitmaps 來控制以上的I/O指令

Use MSR bitmaps : 是否使用msr bitmaps 來控制msr的訪問

Use TSC Offset: 當RDTSC為1, 提供客戶機(虛擬CPU)TSC 和宿主機(物理CPU) TSC之間的偏移

Exception bitmap, 異常是否產生vm-exit, 字段位32位, 某位置1 表示異常發生時陷入vmm, (缺頁異常有特殊處理)

-------------------------------------------------------------------------------------

VM-Exit控制域:

Host Address Space : 是否支持intel-64架構cpu,64位的vmm需要打開
Acknowledgement interrupt on exit: 如果vm-exit 由外部中斷引發, 這個位則決定是否應該回答中斷控制器
VM-Exit MSR-store count: 指定VM-Exit(陷入vmm)時, 虛擬CPU要保存的MSR數目
VM-Exit MSR-store address: 指定VM-Exit(陷入vmm)時, 虛擬CPU要保存的MSR區域的物理地址
VM-Exit MSR-load count: 指定VM-Exit(陷入vmm)時, 物理CPU要裝載的MSR數目
VM-Exit MSR-load address : 指定VM-Exit(陷入vmm)時, 物理CPU要裝載的MSR區域的物理地址


VM-Exit信息域:
VMM除了要通過VM-Exit控制域來控制vm-exit控制域, 還需要使用vm-exit的相關信息(如退出原因)
如:
Basic exit reason: VM-Exit的基本原因(如因外部中斷陷入) 如vm-entry failure 為1, 該字段為VM-Entry失敗的原因
VM-Exit from VMX root : 該位為1時表示一次vm-exit發生在CPU 處於VMX ROOT狀態時
VM-Entry Failure : 該位為1 , 表示一次vm-entry失敗

Exit qualification:

(1)提供陷入VMM的進一步原因: 如對於因為訪問CR訪問導致VM-exit, Exit qualification提供的信息會包括: 哪個CR寄存器,訪問類型是

讀還是寫,訪問的內容等, 同樣的,VT-X也完整定義了所有VM-EXIT所對應的Exit-qualification(有些陷入不用其他信息則忽略)

(2)事件觸發導致VM-Exit : 事件是指外部中斷, 異常(包含INT3/INT0)BOUND,UD2) 和NMI, 對於此類VM-Exit VMM可以通過VM-Exit

interruption-information 和 vm-exit interruption error code 獲取更多信息 如事件相關的類型及IDT向量

(3) 事件注入導致VM-exit: 以上提及到 vmm在返回時可以提供一個事件注入到客戶機, 但由於某種原因再次引發vm-exit, 此時VMM可以從

IDT-Vectoring information和IDT-vectoring error code 獲取更多信息, 同上

(4) 還有更多信息可以在vmcs獲取,如:
Guest Liner Address: 客戶機引發vm-exit的指令的虛擬地址
VM-Exit instruction length: 引發vm-exit的指令的長度
VM-Exit instruction information: 其他有關信息

最後VM-Exit的具體過程:
(1) 當前CPU首先將此次VM-EXIT原因信息保存到VMCS , 清除VM-Entry interruption infomation 第31位
(2) 當前CPU狀態保存到VMCS客戶機狀態域, 根據設置,CPU也可能將客戶機的MSR保存到VM-EXIT MSR-STORE區域
(3) 根據VMCS宿主機狀態,和VM-EXIT控制域中的設置,將宿主機狀態加載到真實CPU, CPU也可能根據VM-EXIT msr-store區域來加載vmm的

msr
(4) CPU由Non-root模式切換到root模式, 從宿主機的cs:RIP 指定到VM-EXIT的入口地址(像R3到R0)
(5) 處理完畢後通過VMLAUNCH / VMRESUME 返回客戶機

更詳細的解說可參考INTEL VOL 3C 手册

Comments

Popular posts from this blog

Android Kernel Development - Kernel compilation and Hello World

How does Nested-Virtualization works?

Understanding ACPI and Device Tree