針對不同的資源,虛擬化主要包含三個方面的內(nèi)容:計算虛擬化、存儲虛擬化和網(wǎng)絡(luò)虛擬化,接下來咱們就分別詳細(xì)介紹這三類資源的虛擬化手段和技術(shù)。今天主要聊虛擬化中的“計算虛擬化”,也就是主要針對 CPU 的虛擬化。
1. 計算虛擬化
計算虛擬化通常包括三方面的內(nèi)容
(1)CPU虛擬化:由于多個 VM 共享 CPU 資源,需要對 VM 中的敏感指令進(jìn)行截獲并模擬執(zhí)行。
(2)內(nèi)存虛擬化:由于多個 VM 共享同一物理內(nèi)存,需要相互隔離
(3)I/O虛擬化:由于多個 VM 共享一個物理設(shè)備,如磁盤、網(wǎng)卡,一般借用 TDMA 的思想,通過分時多路技術(shù)進(jìn)行復(fù)用。
?CPU虛擬化簡介
對于 X86 處理器來說,CPU 虛擬化的基礎(chǔ)是因為其保護(hù)模式下一共有 4 個不同優(yōu)先級,分別從 Ring 0 直到 Ring3。這些 Ring 的優(yōu)先級隨其所執(zhí)行功能的不同也有所不同。其中Ring 0 用于操作系統(tǒng)內(nèi)核和驅(qū)動,優(yōu)先級最高,擁有最高的“特權(quán)”,Ring 1 和 Ring 2 用于操作系統(tǒng)服務(wù),優(yōu)先級次之,Ring 3 用于應(yīng)用程序,優(yōu)先級最低。一般應(yīng)用程序都放在 Ring 3 等級,至于 Ring 1 和 2 則很少被使用。對于應(yīng)用程序與 OS 發(fā)出的命令要求,CPU 一律采取 Direct Execution,如下圖所示:
如果要進(jìn)行虛擬化,Ring 0 這一層就必須交給 VMM來掌控,進(jìn)行硬件資源的分配處理。
那么問題來了,由于 OS 一定要在 Ring 0 進(jìn)行訪問,直接控制硬件,而現(xiàn)在 Ring 0 的部分已經(jīng)交給 VMM,操作系統(tǒng)則被調(diào)降到 Ring 1,但是由于 X86 CPU 最初定位為單個用戶使用,當(dāng)時并沒有考慮到將計算資源分配給不同 OS 的問題;而且 X86 的指令集架構(gòu)(即ISA,是處理器的一個抽象描述,即設(shè)計規(guī)范,定義處理器能夠做什么。其本質(zhì)就是一系列的指令集綜合。當(dāng)前主流的 ISA 有 X86、ARM、MIPS、Power 等,這里我們僅講 X86 ISA)中有 19 條敏感指令不是特權(quán)指令,這些指令必須要在 Ring 0 這個層級才能作用,否則操作系統(tǒng)將會產(chǎn)生警告、終止掉應(yīng)用程序甚至導(dǎo)致系統(tǒng)崩潰。
于是,經(jīng)過研究,我們的攻城獅們提出以下三種方法來解決這個問題。
(1)全虛擬化(Full Virtualization)
這一方法最初由 VMware 在 1999 年提出,這是一種叫做二進(jìn)制翻譯(Binary Translation)的技術(shù),原理是通過 VMM 來預(yù)先攔截這些 OS 當(dāng)中原本不能被虛擬化的命令(nonvirtualizable instructions),并將其進(jìn)行二進(jìn)制轉(zhuǎn)譯的替換操作,使操作系統(tǒng)認(rèn)為自己可以直接掌控硬件,并不知道實際上已經(jīng)被虛擬化成為虛擬機(jī)了。如下圖所示:
而應(yīng)用程序一般性的命令則還是直接向硬件請求,以維持良好的性能。
全虛擬化的好處是 OS 不必做任何修改,直接安裝即可使用。而且所支持的 OS 種類也最多,但若不靠硬件輔助(Hardware Assisted Virtualization),全虛擬化的實現(xiàn)難度是非常大。
(2)半虛擬化( ParaVirtualization)
半虛擬化的原理是修改 Guest OS 核心中部分代碼,植入了 Hypercall(超級調(diào)用),從而使 Guest OS 會將和特權(quán)指令相關(guān)的操作都轉(zhuǎn)換為發(fā)給 VMM 的 Hypercall(超級調(diào)用),由 VMM 繼續(xù)進(jìn)行處理。而 Hypercall 支持的批處理和異步這兩種優(yōu)化方式,使得通過Hypercall 能得到近似于物理機(jī)的速度。
這樣就能讓原本不能被虛擬化的命令(nonvirtualizable instructions)可以經(jīng)過 Hypercall interfaces 直接向硬件提出請求,Guest OS 的部分還是一樣在Ring 0,不用被調(diào)降到 Ring 1。如下圖所示:
半虛擬化的優(yōu)點(diǎn)是 CPU、I/O 損耗減到最低,理論上性能勝過全虛擬化技術(shù),缺點(diǎn)則是必須要修改 OS 內(nèi)核才行,只有 SuSE、Ubuntu 等少數(shù) Linux 版本才支持,OS 兼容性不佳,因為微軟不肯修改自家的操作系統(tǒng)內(nèi)核,因此如果是 Windows 系統(tǒng),就無法使用半虛擬化了。
VMware 在 2005 年發(fā)表了透明半虛擬化(Transparent Paravirtualization),針對支持半虛擬化的 OS 可以在 VMware 的平臺通過 VMI(Virtual Machine Interface)打開半虛擬化來增加 I/O 性能,降低CPU 的使用率。
其原理是在支持半虛擬化的 Guest OS 上面由 VMware tools 開一道后門,與 VMM 進(jìn)行溝通,然后在 OS 上安裝半虛擬優(yōu)化驅(qū)動程序,以提高 I/O 性能,降低 CPU 使用率。這是一種在 VMware 平臺上可以支持半虛擬化 OS 的最佳方式,但是必須要注意的是,底層 CPU Virtualization 仍然是使用二進(jìn)制轉(zhuǎn)換(Binary Translation)的全虛擬化技術(shù)(Full Virtualization),而不是半虛擬化技術(shù)。
(3)CPU 硬件輔助虛擬化( Hardware Assisted Virtualization)
2005 年后,虛擬化漸漸成為潮流,勢不可擋。Intel 與 AMD 決定從 CPU 根本架構(gòu)著手,更改原來的特權(quán)等級 Ring 0、1、2、3,將之歸類為 Non-Root mode,又新增了一個 Root Mode 特權(quán)等級(有人稱為Ring -1),這樣一來,OS 便可以在原來Ring 0 的等級,而VMM 則調(diào)整到更底層的 Root Mode 等級。如下圖所示:
目前主要有 Intel 的 VT-x 和 AMD 的 AMD-V 這兩種技術(shù)。其核心思想都是通過引入新的指令和運(yùn)行模式,使 VMM 和 Guest OS 分別運(yùn)行在不同模式(ROOT 模式和非 ROOT 模式)下,且 Guest OS 運(yùn)行在 Ring 0 下。通常情況下,Guest OS 的核心指令可以直接下達(dá)到計算機(jī)系統(tǒng)硬件執(zhí)行,而不需要經(jīng)過 VMM。當(dāng) Guest OS 執(zhí)行到特殊指令的時候,系統(tǒng)會切換到 VMM,讓 VMM 來處理特殊指令。
?硬件輔助虛擬化擴(kuò)展話題
在硬件輔助虛擬化中,虛擬機(jī)的指令集直接運(yùn)行在宿主機(jī)物理 CPU 上,當(dāng)虛擬機(jī)中的指令設(shè)計到 I/O 操作或者一些特殊指令的時候,控制權(quán)轉(zhuǎn)讓給了宿主機(jī)(這里其實是轉(zhuǎn)讓給了 VMM),也就是一個進(jìn)程,它在宿主機(jī)上的表現(xiàn)形式也就是一個用戶級進(jìn)程。
下圖以 KVM 為例。
從上圖可以比較直觀的看到,VMM 完成 vCPU 和內(nèi)存的初始化后,通過 ioctl 調(diào)用 KVM 的接口,完成虛擬機(jī)的創(chuàng)建,并創(chuàng)建一個線程來運(yùn)行 VM,由于 VM 在前期初始化的時候會設(shè)置各種寄存器來幫助 KVM 查找到需要加載的指令的入口(main 函數(shù))。所以線程在調(diào)用了 KVM 接口后,物理 CPU 的控制權(quán)就交給了 VM。VM 運(yùn)行在 VMX non-root 模式,這是 Intel 的 VT-x 提供的一種特殊的 CPU 執(zhí)行模式。然后當(dāng) VM 執(zhí)行了特殊指令的時候,CPU 將當(dāng)前 VM 的上下文保存到 VMCS 寄存器(這個寄存器是一個指針,保存了實際的上下文地址),然后執(zhí)行權(quán)切換到 VMM。VMM 獲取 VM 返回原因,并做處理。如果是 I/O 請求,VMM 可以直接讀取 VM 的內(nèi)存并將 I/O 操作模擬出來,然后再調(diào)用 VMRESUME 指令,VM 繼續(xù)執(zhí)行,此時在 VM 看來,I/O 操作的指令被 CPU 執(zhí)行了。
下面我們僅針對 VT-x 的一些重點(diǎn)概念展開談一下。
(1)兩種模式
VT-x 為 IA 32 處理器增加了兩種操作模式:VMX root operation 和 VMX non-root operation。
VMM 自己運(yùn)行在 VMX root operation 模式,VMX non-root operation 模式則由 Guest OS 使用。兩種操作模式都支持 Ring 0 ~ Ring 3 這 4 個特權(quán)級,因此 VMM 和 Guest OS 都可以自由選擇它們所期望的運(yùn)行級別。
(2)模式轉(zhuǎn)換 VM entry,運(yùn)行 Guest OS
這兩種操作模式可以互相轉(zhuǎn)換。運(yùn)行在 VMX root operation 模式下的 VMM 通過顯式調(diào)用 VMLAUNCH 或 VMRESUME 指令切換到 VMX non-root operation 模式,硬件自動加載 Guest OS 的上下文,于是 Guest OS 獲得運(yùn)行,這種轉(zhuǎn)換稱為 VM entry。
(3)模式轉(zhuǎn)換 VM exit,運(yùn)行 VMM
Guest OS 運(yùn)行過程中遇到需要 VMM 處理的事件,例如外部中斷或缺頁異常,或者主動調(diào)用 VMCALL 指令調(diào)用 VMM 的服務(wù)的時候(與系統(tǒng)調(diào)用類似),硬件自動掛起 Guest OS,切換到 VMX root operation 模式,恢復(fù) VMM 的運(yùn)行,這種轉(zhuǎn)換稱為 VM exit。
VMX root operation 模式下,軟件的行為與在沒有 VT-x 技術(shù)的處理器上的行為基本一致;而 VMX non-root operation 模式則有很大不同,最主要的區(qū)別是此時運(yùn)行某些指令或遇到某些事件時,發(fā)生 VM exit。
(4) VMM 的生命周期
VMM 開始于 VMXON 指令,結(jié)束與 VMXOFF 指令。
第一次啟動 Guest,通過 VMLAUNCH 指令加載 Guest,這時候一切都是新的,比如說起始的 rip 寄存器等。后續(xù) Guest exit 后再 entry,是通過 VMRESUME 指令,此指令會將VMCS(后面會介紹到)所指向的內(nèi)容加載到當(dāng)前 Guest 的上下文,以便 Guest 繼續(xù)執(zhí)行。
(5)虛擬機(jī)控制塊 VMCS(Virtual-Machine control structure)
VMCS 是一個 64 位的指針,指向一個真實的內(nèi)存地址,VMCS 是以 vCPU 為單位的,就是說當(dāng)前有多少個 vCPU,就有多少個 VMCS 指針。
VMM 和 Guest OS 共享底層的處理器資源,因此硬件需要一個物理內(nèi)存區(qū)域來自動保存或恢復(fù)彼此執(zhí)行的上下文。這個區(qū)域稱為虛擬機(jī)控制塊(VMCS),包括客戶機(jī)狀態(tài)區(qū)(Guest State Area),主機(jī)狀態(tài)區(qū)(Host State Area)和執(zhí)行控制區(qū)。
VM entry 時,硬件自動從客戶機(jī)狀態(tài)區(qū)加載 Guest OS 的上下文。并不需要保存 VMM 的上下文,原因與中斷處理程序類似,因為 VMM 如果開始運(yùn)行,就不會受到 Guest OS的干擾,只有 VMM 將工作徹底處理完畢才可能自行切換到 Guest OS。而 VMM 的下次運(yùn)行必然是處理一個新的事件,因此每次 VMM entry 時, VMM 都從一個通用事件處理函數(shù)開始執(zhí)行;
VM exit 時,硬件自動將 Guest OS 的上下文保存在客戶機(jī)狀態(tài)區(qū),從主機(jī)狀態(tài)區(qū)中加載 VMM 的通用事件處理函數(shù)的地址,VMM 開始執(zhí)行。而執(zhí)行控制區(qū)存放的則是可以操控 VM entry 和 exit 的標(biāo)志位,例如標(biāo)記哪些事件可以導(dǎo)致 VM exit,VM entry 時準(zhǔn)備自動給 Guest OS “塞”入哪種中斷等等。
(6)VMCS 中的客戶機(jī)狀態(tài)區(qū)和主機(jī)狀態(tài)區(qū)
客戶機(jī)狀態(tài)區(qū)和主機(jī)狀態(tài)區(qū)都應(yīng)該包含部分物理寄存器的信息,例如控制寄存器 CR0,CR3,CR4;ESP(ESP 寄存器里存儲的是在調(diào)用函數(shù) fun() 之后,棧的棧頂。并且始終指向棧頂,還有一個 EBP 寄存器,存儲的是棧的棧底指針,通常叫棧基址,這個是一開始進(jìn)行 fun() 函數(shù)調(diào)用之前,由 ESP 傳遞給 EBP 的) 和 EIP(EIP寄存器里存儲的是 CPU 下次要執(zhí)行的指令的地址)(如果處理器支持 64 位擴(kuò)展,則為 RSP,RIP);CS,SS,DS,ES,F(xiàn)S,GS 等段寄存器及其描述項;TR,GDTR,IDTR 寄存器;IA32_SYSENTER_CS,IA32_SYSENTER_ESP,IA32_SYSENTER_EIP 和 IA32_PERF_GLOBAL_CTRL 等 MSR 寄存器。
客戶機(jī)狀態(tài)區(qū)并不包括通用寄存器的內(nèi)容,VMM 自行決定是否在 VM exit 的時候保存它們,從而提高了系統(tǒng)性能??蛻魴C(jī)狀態(tài)區(qū)還包括非物理寄存器的內(nèi)容,比如一個 32 位的 Active State 值表明 Guest OS 執(zhí)行時處理器所處的活躍狀態(tài),如果正常執(zhí)行指令就是處于 Active 狀態(tài),如果觸發(fā)了三重故障(Triple Fault)或其它嚴(yán)重錯誤就處于 Shutdown 狀態(tài),等等。
前文已經(jīng)提過,執(zhí)行控制區(qū)用于存放可以操控 VM entry 和 VM exit 的標(biāo)志位,包括:
External-interrupt exiting:用于設(shè)置是否外部中斷可以觸發(fā) VM exit,而不論 Guest OS 是否屏蔽了中斷。
(7)Interrupt-window exiting:
如果設(shè)置,當(dāng) Guest OS 解除中斷屏蔽時,觸發(fā) VM exit。
(8)Use TPR shadow:
通過 CR8 訪問 Task Priority Register(TPR 任務(wù)優(yōu)先級寄存器)的時候,使用 VMCS 中的影子 TPR,可以避免觸發(fā) VM exit。同時執(zhí)行控制區(qū)還有一個 TPR 閾值的設(shè)置,只有當(dāng) Guest OS 設(shè)置的 TR 值小于該閾值時,才觸發(fā) VM exit。
(9)CR masks and shadows:
每個控制寄存器的每一位都有對應(yīng)的掩碼,控制 Guest OS 是否可以直接寫相應(yīng)的位,或是觸發(fā) VM exit。同時 VMCS 中包括影子控制寄存器,Guest OS 讀取控制寄存器時,硬件將影子控制寄存器的值返回給 Guest OS。
(10)位圖 bitmap:
VMCS 還包括一組位圖以提供更好的適應(yīng)性:
Exception bitmap:選擇哪些異??梢杂|發(fā) VM exit,
I/O bitmap:對哪些 16 位的 I/O 端口的訪問觸發(fā) VM exit。
MSR bitmaps:與控制寄存器掩碼相似,每個 MSR 寄存器都有一組“讀”的位圖掩碼和一組“寫”的位圖掩碼。
每次發(fā)生 VM exit 時,硬件自動在 VMCS 中存入豐富的信息,方便 VMM 甄別事件的種類和原因。VM entry 時,VMM 可以方便地為 Guest OS 注入事件(中斷和異常),因為 VMCS 中存有 Guest OS 的中斷描述表(IDT)的地址,因此硬件能夠自動地調(diào)用 Guest OS 的處理程序。
硬件輔助技術(shù)的出現(xiàn),使得 VMM 和 Guest OS 的執(zhí)行通過硬件,自動隔離開來,任何關(guān)鍵的事件都可以將系統(tǒng)控制權(quán)自動轉(zhuǎn)移到 VMM,因此 VMM 能夠完全控制系統(tǒng)的全部資源。
Guest OS 不但可以運(yùn)行在它所期望的最高特權(quán)級別,因此特權(quán)級壓縮和特權(quán)級別名的問題迎刃而解,而且 Guest OS 中的系統(tǒng)調(diào)用也不會觸發(fā) VM exit。
硬件使用物理地址訪問虛擬機(jī)控制塊(VMCS),而 VMCS 保存了 VMM 和 Guest OS 各自的 IDTR 和 CR3 寄存器,因此 VMM 可以擁有獨(dú)立的地址空間,Guest OS 能夠完全控制自己的地址空間,地址空間壓縮的問題也不存在了。
中斷和異常虛擬化的問題也得到了很好的解決。VMM 只用簡單地設(shè)置需要轉(zhuǎn)發(fā)的虛擬中斷或異常,在 VM entry 時,硬件自動調(diào)用 Guest OS 的中斷和異常處理程序,大大簡化 VMM 的設(shè)計。同時,Guest OS 對中斷的屏蔽及解除可以不觸發(fā) VM exit,從而提高了性能。而且 VMM 還可以設(shè)置當(dāng) Guest OS 解除中斷屏蔽時觸發(fā) VM exit,因此能夠及時地轉(zhuǎn)發(fā)積累的虛擬中斷和異常。
CPU 硬件輔助虛擬化其實又分成初代和二代,二代新增了 MMU(memory management unit)虛擬化,也就是 Intel EPT 和 AMD RVI,如果各位小伙伴有興趣,可以登錄到
VMware、Citrix、Intel 與 AMD 網(wǎng)站查詢更詳細(xì)的相關(guān)信息。
有了 CPU 硬件支持虛擬化技術(shù)之后,最大的好處就是不再需要以前 BinaryTranslation 或ParaVirtualization 的操作,虛擬化廠商再也不用費(fèi)心在這里想辦法解決問題,全虛擬化廠商的性能追上了半虛擬化廠商,半虛擬化廠商也可支持不修改內(nèi)核的操作系統(tǒng)了(例如Windows 或絕大多數(shù)的 Linux )。
CPU 虛擬化可以說是計算虛擬化最關(guān)鍵的核心,弄清楚了 VM Exit 和 VM Entry。后續(xù)的I/O 虛擬化,內(nèi)存虛擬化都是建立在這個基礎(chǔ)上。
評論
查看更多