1. 程式人生 > >QEMU KVM系列一: Intel VT-x 硬體虛擬化產生的背景

QEMU KVM系列一: Intel VT-x 硬體虛擬化產生的背景

參考文章:http://blog.csdn.net/yearn520/article/details/6461047

虛擬化分為 para-virtualization 和 full virtualization. Para-Virtualization 的主要目的是在不支援硬體虛擬化的平臺上面實現虛擬化,但是需要改動作業系統。而FULL virtualization是由硬體提供支援的虛擬化解決方案,不需要改動作業系統。那麼intel,AMD 等CPU廠商為什麼要推出硬體虛擬化呢?基於軟體的虛擬化存在一些什麼問題。

1. Intel VT-x的產生背景

我們知道處理器一般存在應用程式設計介面和系統程式設計介面。對於x86處理器來說,應用程式設計介面僅嚮應用程式暴露了通用暫存器、RFLAGS、RIP和一組非特權指令,而系統程式設計介面向作業系統暴露了全部的ISA(Instruction Set Architecture)。傳統的程序/執行緒模型也是對處理器的一種虛擬化,但只是對處理器的應用程式設計介面的虛擬化,而所謂的系統虛擬化(system virtualization)是要實現處理器系統程式設計介面的虛擬化。從這個角度講,系統虛擬化與程序/執行緒模型相比並無本質的區別。

處理器虛擬化的本質是分時共享。實現虛擬化需要兩個必要條件,第一是能夠讀取和恢復處理器的當前狀態,第二是有某種機制防止虛擬機器對系統全域性狀態進行修改。

第一個必要條件沒有必要一定由硬體來實現,雖然硬體實現可能比軟體實現更為簡單。例如,x86處理器對多工,也就是應用程式設計介面虛擬化,提供了硬體的支援,軟體通常只需要執行一條指令,就可以實現任務切換,處理器硬體負責儲存當前應用程式設計介面的狀態,併為目標任務恢復應用程式設計介面的狀態。但作業系統並不一定要使用處理器提供的這種虛擬化機制,完全可以使用軟體來完成應用介面狀態的切換。例如,Linux就沒有使用x86處理器提提供多工機制,完全依賴軟體實現任務切換。

第二個必要條件一定要由硬體來實現,通常處理器採用多模式操作(multi-mode operation)來確保這一點。在傳統x86處理器上,共有4種模式的操作,也就是常說的4個特權級。虛擬機器(這裡指程序/執行緒)通常執行在特權級3上,而虛擬機器監控器(這裡指作業系統)運行於特權級0上,程序/執行緒的所有訪問全域性的操作,如訪問共享的作業系統所在的地址空間,訪問I/O等等,均會導致異常的發生,被作業系統所截獲並處理,使作業系統有機會向程序/執行緒提供一個虛擬的世界。

系統虛擬化與程序/執行緒模型相比並無本質的區別。x86處理器完全有機會以較小的代價提供對系統虛擬化的支援,但很可惜Intel沒有考慮那麼長遠。x86的4個特權級對於實現系統虛擬化已經足夠了,但傳統的x86處理器上,許多特權指令要求必須在特權級0上執行,如LGDT,因此通常作業系統都佔用了特權級0,也就沒有特權級供虛擬機器監控器使用了。為此,許多基於傳統x86處理器的虛擬化軟體不得不採用ring deprivileging方法,讓作業系統運行於特權級1,而由虛擬機器監控器使用特權級0。ring deprivileging方法帶來了許多問題,包括:ring aliasing、address space compression、nonfaulting accessing to privileged state、adverse impact on guest transitions、interrupt virtualization、access to hidden state等問題,通常將以上問題統稱為x86平臺的虛擬化漏洞。

ring aliasing問題是指,採用ring deprivileging方法時,由於處理器的CPL儲存在CS的低兩位,所以作業系統通過執行PUSH CS指令和一條POP EAX指令可以很容易發現其目前不在特權級0上執行,這違背了虛擬化對作業系統透明的原則。

address space compression問題是指,作業系統通常期望能夠訪問整個4GB線性地址空間,但虛擬機器監控器可能也需要佔用作業系統的一部分線性地址空間,以便其能夠方便地訪問作業系統的地址空間。但如果作業系統是運行於特權級1,那麼作業系統也同樣可以訪問虛擬機器監控器的儲存空間,對虛擬機器監控器造成威脅。

nonfaulting accessing to privileged state問題是指,Intel的特權級機制不能確保所有的訪問處理器狀態的指令在低特權級狀態下執行時都產生故障(Fault),這使得作業系統在訪問某些處理器狀態時虛擬機器監控器無法獲得控制,也就無法對這些指令進行模擬。例如,IA-32的GDTR, LDTR, IDTR, TR包含了控制處理器狀態的指標,對這些暫存器的修改只能在特權級0進行,但IA-32允許在所有的特權級中讀取這些暫存器的值。作業系統可以讀取這些暫存器的值,如果與真實的計算機上的值不同,作業系統就可以認為自己正執行在虛擬機器環境中。

adverse impact on guest transitions問題是指,為加快系統呼叫的速度,Intel引入了SYSENTER和SYSEXIT指令,但SYSENTER指令總是將特權級切換到0,且從0以外的特權級執行SYSEXIT指令將導致故障。因此,在採用ring deprivileging方法實現虛擬化時,SYSENTER和SYSEXIT指令總是先陷入到虛擬機器監控器,經後者模擬後再交給作業系統,這使系統呼叫的速度減慢。

interrupt virtualization問題是指,IA-32使用EFLAGS.IF位來控制中斷的遮蔽,修改IF位需要在CPL<=IOPL的情況下進行,否則將產生故障。作業系統可能需要頻繁地修改IF位,會頻繁地導致虛擬機器監控器的陷入,影響系統性能。而且,有些情況下,虛擬機器監控器需要向虛擬機器注入事件,但如果虛擬機器正處於中斷遮蔽狀態,虛擬機器監控器就必須等待,直到虛擬機器開啟中斷。虛擬機器監控器為了及時得知虛擬機器已開啟中斷,也必須截獲作業系統對EFLAGS.IF位的修改。

access to hidden state問題是指,IA-32處理器的某些狀態,例如段描述符快取記憶體,是無法通過指令訪問的。當虛擬機器切換時,IA-32沒有提供儲存和恢復段描述符快取記憶體的手段。也就是說,上文所述的實現虛擬化的第一個必要條件,能夠讀取和恢復處理器的當前狀態,並不完全具備。

總之,雖然採用ring deprivileging方法可能實現系統虛擬化,但具有很多缺陷,且軟體上比較複雜。為此,Intel提出了VT-x技術來解決系統虛擬化問題,其主要思路是增加一個新的比0還高的特權級,通常稱之為特權級-1,並在硬體上支援系統程式設計介面狀態的儲存和恢復。

首先,VT-x提供了一套稱作VMX(Virtual Machine eXtension)的新的工作模式,工作在該模式下的處理器又具有兩類操作模式:VMX root operation和VMX non-root operation。通常,虛擬機器監控器執行在VMX root operation模式下,即所謂的特權級-1,客戶作業系統執行在VMX non-root operation模式下。VMX non-root operation模式仍保留4個特權級,對作業系統來說,VMX non-root operation模式與傳統的x86處理器相容,最大的差別在於當虛擬機器執行一些訪問全域性資源的指令時將導致虛擬機器退出操作(VM exit),從而使虛擬機器監控器獲得控制權,以便對訪問全域性資源的指令進行模擬。以後,虛擬機器監控器可以通過虛擬機器進入操作(VM entry)使虛擬機器重新獲得控制權。

其次,VT-x為系統程式設計介面狀態的切換提供硬體支援。VT-x為每個虛擬機器維護至少一個VMCS(Virtual Machine Control Structure)結構,其中儲存了虛擬機器和虛擬機器監控器的系統程式設計介面狀態。當執行VM exit和VM entry操作時,VT-x自動根據VMCS中的內容完成虛擬機器和虛擬機器監控器間的系統程式設計介面狀態切換。為系統程式設計介面狀態的切換提供硬體支援是必要的,因為x86處理器的系統程式設計介面相比應用程式設計介面要複雜的多,且在不停的變化,如較新的處理器可能增加一些MSR(Model Specific Register),這使得單獨依靠軟體來實現系統程式設計介面的儲存和恢復工作變得十分複雜。另外,VT-x還提供了一組指令,使得虛擬機器監控器通過一條指令就可以完成虛擬機器間的切換。

VT-x解決了ring deprivileging方法的一系列問題,從硬體上堵住了所謂的x86平臺的虛擬化漏洞。由於作業系統所在的VMX non-root operation模式仍具有4個特權級,使得ring aliasing問題不存在了。同時,由於SYSENTER和SYSEXIT指令所引起的adverse impact on guest transitions問題也不存在了;由於VT-x在VM exit和VM entry時完成系統程式設計介面的切換,也就是說虛擬機器和虛擬機器監控器擁有各自的GDT,也就擁有了各自的地址空間,解決了address space compression問題。同時,虛擬機器和虛擬機器監控器擁有各自的GDTR/IDTR等暫存器,在虛擬機器中訪問這些暫存器無需陷入,解決了nonfaulting accessing to privileged state問題,再者,VMCS中儲存了虛擬機器的段描述符快取記憶體,因此在虛擬機器切換時不會出現access to hidden state問題;通過對VMCS進行設定,可以使處理器在VMX non-root operation模式時的EFLAGS.IF失效,即該標誌位不再對中斷遮蔽產生影響,因此作業系統對EFLAGS.IF的頻繁操作不會導致頻繁的VM exit,解決了interrupt virtualization的問題。

VT-x提供了完備的處理器虛擬化機制,利用VT-x可以在單個硬體平臺上虛擬出任意數量的虛擬處理器VCPU。VT-x除了解決了處理器虛擬化的問題之外,還為記憶體虛擬化和I/O虛擬化提供了支撐。在記憶體虛擬化方面,VT-x為影子頁表的實現提供了支撐,並且在較新的處理器中還提供了EPT機制,進一步提高了記憶體虛擬化的效率。在I/O虛擬化方面,通過I/O點陣圖機制可以方便地實現對Programmed I/O的虛擬化,除此之外,VT-x還提供了中斷事件退出機制和中斷事件注入機制,方便對裝置中斷進行虛擬化。