1. 程式人生 > >第7章 Smart-VM虛擬化層的實現

第7章 Smart-VM虛擬化層的實現

在使用 Intel-VT 技術之前, Smart-VM 需要先啟用 VMX 模式。為了啟用 VMX 模式,處理器需要先進入保護模式。

當處理器在保護模式下未進入 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 從真