第7章 Smart-VM虛擬化層的實現
在使用 Intel-VT 技術之前, Smart-VM 需要先啟用 VMX 模式。為了啟用 VMX 模式,處理器需要先進入保護模式。
當處理器在保護模式下未進入 VMX 模式的時候,跟普通處理器的保護模式操作是一樣的。當處理器啟用 VMX 模式,進入 VMX 根操作模式時,基本上跟正常的處理器在保護模式下的操作是一樣的,但是 VMX 根操作模式多了幾條操作 VMX 模式的指令。
VMX 非根操作模式下虛擬的是保護模式。但是跟正常的保護模式有差別,比如說當客戶作業系統在 VMX 非根操作模式下執行的時候,需要訪問硬體資源的時候,就需要回到 VMX 根模式,交由虛擬機器監控器處理。
在 VMX
虛擬服務分發器在 Smart-VM 虛擬化層所處的位置如圖 5.4 所示。
虛擬服務分發器會維護一種虛擬服務表,這張表的每個條目對應的是一個服務函式。當處理器從非根操作模式退出到根操作模式下的時候,都可以從這個虛擬服務表中找到相應的服務函式進行處理。從非根操作模式退出到根操作模式下的基本原因存放在 Basic VM-Exit Information 域。
1.3 啟用 VMX 模式
1.3.1
啟用
VMX
模式的條件
第一代 Intel-VT 技術,在啟用 VMX 模式的時候,需要將 CR0.PE , CR0.NE , CR0.PG , CR4.VMXE 設定為 1 ,即開啟 VMX 模式需要先開啟保護模式和分頁機制。
圖 7 . 1 判斷和設定進入 VMX 所需條件的流程圖
圖 7.1 顯示了 Smart-VM 啟用 VMX 模式的流程圖:
a) 開啟保護模式和虛擬記憶體機制:在載入程式的時候,已經開啟了保護模式和分頁機制。具體參看載入程式和載入程式部分;
b) 判斷是否支援 CPUID 指令;
c) 判斷該處理器是否有支援 Intel-VT
d) 開啟 VMX 操作:
i. 啟用 VMX 指令操作:置 IA32_FEATURE_CONTROL.bit2 為 1 ;
ii. 鎖定 MSR 暫存器:置 IA32_FEATURE_CONTROL.bit0 為 1 ;
iii. 置 CR0.NE , CR4.VME 為 1 ;
iv. 設定 VMCS revision id ;
v. 執行 VMXON 指令,啟用 VMX 模式;
真實的機子在啟動的時候,進入的是真實模式,然後從真實模式跳轉到保護模式。虛擬機器監控器也需要虛擬這個過程。但是當處理器進入 VMX 非根操作模式是,處理器只有虛擬 8086 模式和保護模式兩種。因此,要虛擬真實模式,一般採用以下兩種方式:
a) 實現一個模擬真實模式的模組;
b) 利用虛擬 8086 模式;
Smart-VM 採用第二種方法來虛擬真實模式。
利用虛擬 8086 模式來實現真實模式的虛擬化同樣也有兩種方法:
a) 利用保護模式下的虛擬 8086 模式;
b) 利用 VMX 非根操作操作模式下的保護模式下的虛擬 8086 模式;
圖 7.2 的著色部分顯示了虛擬 8086 模式在處理器各個模式中所處的位置。如果利用保護模式下的虛擬 86 模式,那麼需要進行保護模式和 VMX 模式之間的切換,因此,我們採用第二種方法,即使用 VMX 非根操作模式下的保護模式下的虛擬 8086 模式。
圖 7 . 2 虛擬 8086 模式
虛擬 8086 模式在保護模式下是執行在特權級 3 的,因此跟真實模式還是有一些差別的:
1. 不能執行特權級指令;
2. 中斷機制採用的是保護模式下的中斷機制,而不是 BIOS 中斷;
3. I/O 操作,也需要遵循保護模式下的保護機制;
圖 7 . 3 虛擬 8086 在保護模式下的切換
圖 7.3 顯示了虛擬 8086 在保護模式下的切換。
虛擬 8086 監控器實際上是作為 Smart-VM 虛擬化層的一個子模組,如圖 7.4 所示。
圖 7 . 4 Smart-VM 虛擬 8086 監控器架構圖
由圖 7.4 可以看出,虛擬 8086 監控器模組既可以在 VMX 根操作模式下運作,也在 VMX 非根操作模式下運作:
a) 8086 程式在非根操作模式下執行的時候,可能由於一些原因(比如說執行 int 指令)而退出到 VMX 非根操作模式下的虛擬 8086 監控器,此時的虛擬機器監控器是在 VMX 非根操作模式下的特權級 0 下;
b) 虛擬 8086 監控器也可能由於一些原因(比如說 I/O 操作)而退出到 VMX 根操作模式;
在虛擬 8086 模式下虛擬真實模式,需要處理好以下幾個問題:
1.4.1.1 進入 NOT-ROOT 模式下的虛擬 8086 模式
在 VMCS 的 guest-state 中的 eflags 的 VM 置 1 ,即可進入非根操作模式下的虛擬 8086 模式。關於其他客戶域的暫存器的設定,跟進入保護模式下的客戶域的設定有所不同,請參看下面的表。
1.4.1.2 處理軟體異常
Smart-VM 將所有的軟體異常,都轉交給 Smart-VM 虛擬機器監控器,由它處理。
但是當虛擬機器監控器處理完一個異常的時候,需要在進入非根模式的時候,插入事件說明,告訴處理器,虛擬機器監控器處理完了一個異常。如果同一個客戶作業系統,在產生一個異常之後,虛擬機器監控器未處理完,又產生一個異常,那系統就會產生雙重故障。
1.4.1.3 處理特權級指令
在虛擬 8086 模式下,由於是在特權級 3 下執行,因此執行特權級指令會產生異常。 Smart-VM 設定了相關的位,讓處理器能夠捕獲客戶作業系統的軟體異常,並且轉交給 Smart-VM 虛擬機器監控器。
1.4.1.4 非根操作模式下的 BIOS 虛擬化
在真實模式下,需要通過 BIOS 中斷,才能夠訪問硬體,比如說讀取硬碟或者軟盤資料等。但是,在虛擬 8086 模式下,中斷只能通過保護模式下的中斷機制來實現。因此,我們在中斷向量表上,需要根據 BIOS 的中斷向量表實現一整套的 BIOS 中斷。
當虛擬 8086 模式下的程式執行 int 指令的時候,就產生軟體中斷,轉入虛擬 8086 監控器,由虛擬 8086 監控器處理。
1.4.1.5 從非根操作模式下的虛擬 8086 模式進入非根操作模式下的保護模式
置 VMCS 控制域的 CR0 guest/host mask 域置為 0xFFFFFFFF ,這樣,當處理器在操作 CR0 控制暫存器的時候,就會產生 VM-exit 。當 Smart-VM 虛擬機器監控器獲取操作 CR0 暫存器的指令時,就可以分析該指令,以此決定下一步該採取什麼樣的操作。
英特爾手冊規定,在保護模式下,當 cr0.PE 位為 1 時,下一條指令就要是 jmp 或者 call 指令,直接跳轉到保護模式。根據這個規定,當我們獲取在虛擬 8086 模式下將 cr0.pe 位置 1 的指令時,在返回 VMX 非根模式時,返回的是 VMX 非根模式下的保護模式,這樣,當執行 jmp 或者 call 指令的,就可以裝載好選擇子和 EIP 。
在進入保護模式的時候,需要設定好的置如表 7.6[20] 。
1.4.1.6 進入虛擬 8086 模式的 VMCS 配置
客戶域
表 7 . 1 進入虛擬 8086 模式的客戶域配置
Guest-state 暫存器域 |
CR0 = 0xC0000021 CR3 = Smart-VM 虛擬機器監控器的 CR3 CR4 = 0x2000 |
DR7 = 0x400 |
|
RSP = 0x0 RIP = 0x7C00 EFLAGS = 0x23002 |
|
CS_SELECTOR = 0 CS_BASE = 0 CS_LIMIT = 0xFFFF CS_AR_BYTES = 0xF3 SS_SELECTOR = 0 SS_BASE = 0 SS_LIMIT = 0xFFFF SS_AR_BYTES = 0xF3 DS_SELECTOR = 0 DS_BASE = 0 DS_LIMIT = 0xFFFF DS_AR_BYTES = 0xF3 ES_SELECTOR = 0 ES_BASE = 0 ES_LIMIT = 0xFFFF ES_AR_BYTES = 0xF3 FS_SELECTOR = 0 |
|
續表 7 . 2 進入虛擬 8086 模式的客戶域配置 |
|
Guest-state 暫存器域 |
FS_BASE = 0 FS_LIMIT = 0xFFFF FS_AR_BYTES = 0xF3 GS_SELECTOR = 0 GS_BASE = 0 GS_LIMIT = 0xFFFF GS_AR_BYTES = 0xF3 LDTR _SELECTOR = 0 LDTR _BASE = 0 LDTR _LIMIT = 0xFFFF LDTR _AR_BYTES = 0x82 TR _SELECTOR = 0x18 TR _BASE = Smart-VM 虛擬機器監控器的 tss 基址 TR _LIMIT = Smart-VM 虛擬機器監控器的 tss 大小 TR _AR_BYTES = 0x8b |
GDTR_BASE =Smart-VM 虛擬機器監控器 GDT 的基址 GDTR_LIMIT = Smart-VM 虛擬機器監控器的 GDT 的大小 IDTR 的基址 =Smart-VM 虛擬機器監控器 IDT 的基址 IDTR_LIMIT = Smart-VM 虛擬機器監控器的 IDT 的大小 |
|
Guest-state 非暫存器域 |
GUEST_ACTIVITY_STATE = 0 |
GUEST_INTERRUPTIBILITY_INFO = 0 |
|
續表 7 . 3 進入虛擬 8086 模式的客戶域配置 |
|
Guest-state 非暫存器域 |
GUEST_PENDING_DBG_EXCEPTIONS = 0 |
VMCS_LINK_POINTER = 0xFFFFFFFF_FFFFFFFF |
宿主域
表 7 . 4 進入虛擬 8086 模式的宿主域配置
Host-state 暫存器域 |
CR0 = Smart-VM 虛擬機器監控器的 CR0 CR3 = Smart-VM 虛擬機器監控器的 CR3 CR4 = Smart-VM 虛擬機器監控器的 CR4 |
RIP = gos->vmexit_func RSP = 0xC009f000 |
|
CS 的選擇子 = Smart-VM 虛擬機器監控器的 CS 的選擇子 SS 的選擇子 = Smart-VM 虛擬機器監控器的 SS 的選擇子 DS 的選擇子 = Smart-VM 虛擬機器監控器的 DS 的選擇子 ES 的選擇子 = Smart-VM 虛擬機器監控器的 ES 的選擇子 FS 的選擇子 = Smart-VM 虛擬機器監控器的 FS 的選擇子 GS 的選擇子 = Smart-VM 虛擬機器監控器的 GS 的選擇子 TR 的選擇子 = Smart-VM 虛擬機器監控器的 TR 的選擇子 |
|
GDTR 的基址 =Smart-VM 的 GDT 的基址 |
|
續表 7 . 5 進入虛擬 8086 模式的宿主域配置 |
|
Host-state 暫存器域 |
IDTR 的基址 =Smart-VM 虛擬機器監控器 IDT 的基址 |
執行控制域
表 7 . 6 進入虛擬 8086 模式的執行控制域
Pin-Based VM-Execution Controls |
External-interrupt exiting = 0 |
NMI exiting = 0 |
|
Virtual NMIs = 0 |
|
Activate VMX-preemption timer = 0 |
|
Processor-Based VM-Execution Controls |
Interrupt-window exiting = 0 |
Use TSC offsetting = 0 |
|
HLT exiting = 0 |
|
INVLPG exiting = 0 |
|
MWAIT exiting = 0 |
|
RDPMC exiting = 0 |
|
RDTSC exiting = 0 |
|
CR3-load exiting = 0 |
|
CR3-store exiting = 0 |
|
CR8-load exiting = 0 |
|
CR8-store exiting = 0 |
|
Use TPR shadow = 0 |
|
NMI-window exiting = 0 |
|
MOV-DR exiting = 0 |
|
Unconditional I/O exiting = 1 |
|
Use I/O bitmaps = 0 |
|
Monitor trap flag = 0 |
|
Use MSR bitmaps = 0 |
|
MONITOR exiting = 0 |
|
續表 7 . 7 進入虛擬 8086 模式的執行控制域 |
|
Processor-Based VM-Execution Controls |
|
PAUSE exiting = 0 |
|
Activate secondary controls = 0 |
|
EXCEPTION_BITMAP |
全部置為 1 |
進入控制域
表 7 . 8 進入虛擬 8086 模式的進入控制域
VM-Entry Controls |
Load debug controls = 0 |
IA-32e mode guest = 0 |
|
Entry to SMM = 0 |
|
Deactivate dual-monitor treatment = 0 |
|
Load IA32_PERF_GLOBAL_CTRL = 0 |
|
Load IA32_PAT = 0 |
|
Load IA32_EFER = 0 |
退出控制域
表 7 . 9 進入虛擬 8086 模式的退出控制域
VM-Exit Controls |
Save debug controls = 0 |
Host address-space size = 0 |
|
Load IA32_PERF_GLOBAL_CTRL = 0 |
|
Acknowledge interrupt on exit = 0 |
|
Save IA32_PAT = 0 |
|
Load IA32_PAT = 0 |
|
Save IA32_EFER = 0 |
|
Load IA32_EFER = 0 |
|
Save VMX-preemption timer value = 0 |
1.4.1.7 從真實模式跳轉到保護模式下的 VMCS 配置
表 7 . 10 從真