CPU純軟體半虛擬化技術

來源:互聯網
上載者:User

標籤:寄存器   citrix   cpu半虛擬化   hypercall   cpu特權級   


在2003年出現的Xen,使用了另外的一種半虛擬化的方案來解決x86架構下CPU的敏感指令問題。主要採用Hypercall技術。Guest OS的部分代碼被改變,從而使Guest OS會將和特權指令相關的操作都轉換為發給VMM的Hypercall(超級調用),由VMM繼續進行處理。而Hypercall支援的批處理和非同步這兩種最佳化方式,使得通過Hypercall能得到近似於物理機的速度。

650) this.width=650;" src="http://s4.51cto.com/wyfs02/M02/79/F3/wKiom1afF8rRLK3ZAACfLO6bwIA867.png" title="1.png" alt="wKiom1afF8rRLK3ZAACfLO6bwIA867.png" />

1、Hypercall技術

  對於x86體繫結構CPU,Xen使用超級調用來替換被監控的操作,其中包括x86架構下的敏感指令。Xen所採用的超級替換的方法是一種全新的設計理念:它將問題的中心,由VMM移向Guest OS自身,通過主動的方式由Guest OS去處理這些指令,而不是被移交給VMM做處理,在這種設計理念下,修改Guest OS核心。

   能修改Guest OS是半虛擬化的一個技術核心。通過修改Guest OS的核心。使Guest OS明確知道自己是運行在1環上,而不是通常OS的0環,有效避免了虛擬化的執行衝突問題。Guest OS也清楚VMM給自己提供了一個虛擬寄存器組,並能通過其他方式去訪問他們,避免了存取違規的問題。

    解決了敏感指令問題只是解決了x86架構下的半虛擬化的第一步。運行在1環的作業系統沒有許可權執行的指令,交給0環的VMM來處理,這個很大程度上與應用程式的系統調用很類似:系統調用的作用是把應用程式無權執行的指令交給作業系統完成。因此,Xen向Guest OS提供了一套“系統調用”。以方便Guest OS調用,這部分”系統調用“就是超級調用Hypercall。

超級調用Hypercall的機制使用,不僅使x86架構的指令虛擬化得以實現,也為後面的記憶體虛擬化和I/O虛擬化提供了新的思路和方法,超級調用和事件通道是整個半虛擬化的基礎。

下面我們來看看半虛擬化情況下整體的訪問流程圖,。

650) this.width=650;" src="http://s2.51cto.com/wyfs02/M01/79/F3/wKiom1afF9-BZbZuAAAotW_0zjg092.png" title="1.png" alt="wKiom1afF9-BZbZuAAAotW_0zjg092.png" />

CPU半虛擬化技術

明確的顯示了Hypercall的調用位置,在Xen中,各組件通訊方式如下所示,Hypercall的調用性質是同步的。其他Xen的通訊方式幾乎都是非同步。

650) this.width=650;" src="http://s4.51cto.com/wyfs02/M00/79/F3/wKiom1afF_iQ2q87AACww5CfWNE788.png" title="1.png" width="578" height="213" border="0" hspace="0" vspace="0" style="width:578px;height:213px;" alt="wKiom1afF_iQ2q87AACww5CfWNE788.png" />

其中,在虛擬機器和Xen的通訊過程中,如果虛擬機器需要調用敏感指令,會主動向虛擬機器監控器發起Hypercall調用。Hypercall就如同傳統作業系統下的系統調用,監管程式通過它向其上各虛擬機器提供各種服務,如MMU 更新、Domain0 操作請求和虛擬處理器狀態等。

顯示了半虛擬化模式下的特權模式:

650) this.width=650;" src="http://s2.51cto.com/wyfs02/M01/79/F2/wKioL1afGFCTwrrgAADLqoaNu8Q729.png" title="1.png" alt="wKioL1afGFCTwrrgAADLqoaNu8Q729.png" />

在x86架構下,原生系統和半虛擬化環境下存在差異。原生環境下,CPU有4個特權級(ring0--ring3),作業系統是處於最進階別的ring0,應用程式處於最低層級的ring3。而在半虛擬化環境下,虛擬機器監視器是處於最進階別的ring0,作業系統是處於中級層級的ring1,應用程式處於最低層級的ring3。

650) this.width=650;" src="http://s5.51cto.com/wyfs02/M01/79/F3/wKiom1afGCqRoKQeAABTEciqbX8993.png" title="1.png" alt="wKiom1afGCqRoKQeAABTEciqbX8993.png" />

只有特權層級為1 的代碼(准虛擬化Guest VM 的核心)才能向Xen 發送Hypercall 請求,以防止應用程式(特權級3)的錯誤調用導致對系統可能的破壞。因此,只有運行在特權級1 的虛擬機器作業系統核心才能申請Hypercall。但是,一些Xen 專用的特別程式,如xend 或xe也需要有Hypervisor 的服務來完成特殊的操作,如產生一個新的GuestVM 等,這在Xen Linux 中是通過一個稱為privcmd 的核心驅動程式實現。應用程式通過ioctl 向該驅動程式提出服務要求,運行在虛擬機器核心(特權級1)的privcmd 驅動程式再將服務要求以Hypercall 形式轉向Hypervisor,並由後者真正完成組建新Guest VM 的動作。

650) this.width=650;" src="http://s2.51cto.com/wyfs02/M02/79/F2/wKioL1afGH6wRgTgAAELB5Omcd0071.png" title="1.png" alt="wKioL1afGH6wRgTgAAELB5Omcd0071.png" />

中顯示了Hypercall所在的位置,Hypercall位於圖中右上方,核心向Hypervisor發起調用的哪裡。Xen啟用130號中斷向量連接埠(十六進位的82H)作為超級調用的中斷號。這一個中斷向量的DPL被設定為類型為1,類型為中斷門。這樣,超級調用能夠由處於特權級1的客戶機作業系統發起,而不能從使用者態發起。

另外,在x86指令集的指令中,有17 條指令不能有效在ring 1 特權級上運行,Hypercall 的存在解決了這些指令不能正常執行的問題。

650) this.width=650;" src="http://s3.51cto.com/wyfs02/M02/79/F2/wKioL1afGJeBGHKJAAGdRJhdhPM639.png" title="1.png" alt="wKioL1afGJeBGHKJAAGdRJhdhPM639.png" />

Hypercall 機制中,在32 位x86 架構下,Hypercall 通過int0x82陷阱(Trap)指令實現,因為傳統作業系統本身並不使用int0x82 (Linux 使用int 0x80 作為系統調用指令,int 0x82 並未使用)。

  int0x82包括:

  • 超級調用號:xen/include/public/xen.h中定義了45個超級調用,其中有7個是平台相關調用。

  • 超級調用表:xen/arch/x86/x86_32/entry.S中定義了超級調用表,通過超級調用號索引就可以方便的找到對應的處理函數。

  • 超級調用頁:超級調用頁是Xen為Guest OS準備的一個頁,可以做到不同Guest OS有不同的超級調用頁內容。

  Hypercall 的具體功能識別號由eax 表明,而其他參數則在ebx, ecx, edx, esi 和edi 中。為了減少虛擬機器和Hypervisor 之間的特權層級(Ring)切換次數,Xen 提供對Hypercall的批處理,即將幾個Hypercall 功能請求放在一個列表中由專門的Hypercall 批處理請求完成。在Xen 中,系統調用表與Hypercall 表都在entry.S 檔案中被定義。

 

 

2、X86架構特權級

x86 硬體支援 4 個特權級 (Ring),一般核心運行在 Ring 0, 使用者應用運行在 Ring 3, 更小的 Ring 有比更高的 Ring 能訪問更多的系統全域資源,即更高的特權。有些指令只能在 Ring 0 才能正確執行,如 LGDT、LMSW 指令,我們稱之為特權指令;另外有些指令可以在 Ring 3 正確執行,如 SGDT、 SMSW、PUSHF/POPF,我們稱之為非特權指令。

正常模式和虛擬化兩種情況敘述下,特權模式說明如下:

正常模式:特權層級是針對段來講的,段描述符的最後兩位標識了該段所位於的特權層級,比如,中斷處理常式運行於ring0(),此時的核心程式是具有特權的,即ring0。位於ring3使用者程式可以通過系統調用的方式,int80,後特權翻轉入ring0,然後就可以順利執行中斷處理常式(好像是使用者程式調用核心程式的唯一途徑)。

虛擬化情況下

特權解除:是指解除正常情況下運行於ring0的段,比如中斷處理常式,為了虛擬化需要,此時解除其特權,將其運行於ring1。當使用者程式通過系統調用時,其跳轉到的中斷處理常式運行於ring1。但是,在中斷處理常式中,有部分指令是必須在ring0才能執行的,此時,便會自動陷入,然後類比。也就是說,使用者程式運行特權指令,會有兩次特權下降,一次是通過系統調用進入ring1,第二次是通過特權指令陷入進入ring0。這說明,中斷髮生時的中斷處理常式還是以前的位於核心的代碼,但是其運行層級為ring1,部分指令還需要再次陷入,才能執行。另外,還有一個重要問題,就是部分敏感非特權指令無法陷入的問題:存在二進位翻譯、超級調用等方式,強迫其陷入,然後類比。

  在傳統的 X86 平台上支援虛擬化上存在如下問題 :

X86 指令集中存在 17 條敏感的非特權指令,“非特權指令”表明這些指令可以在 x86 的 ring 3 執行, 而“敏感性”說明 VMM 是不可以輕易讓客作業系統執行這些指令的。 這 17 條指令在客作業系統上的執行或者會導致系統全域狀態的破壞,如 POPF 指令,或者會導致客作業系統邏輯上的問題,如 SMSW 等讀系統狀態或控制寄存器的指令。傳統的 X86 沒法捕獲這些敏感的非特權指令。

除了那 17 條敏感的非特權指令,其他敏感的指令都是敏感的特權指令。在 x86 虛擬化環境,VMM 需要對系統資源進行統一的控制,所以其必然要佔據最高的特權級,即 Ring 0, 所以為了捕獲特權指令,在傳統 x86 上一個直接可行的方法是 “Ring deprivileging”, 如將客作業系統核心的特權級從 Ring 0改為 Ring 1 或 Ring 3, 即 “消除” 客核心的特權,以低於 VMM所在的 Ring 0, 從而讓 VMM 捕獲敏感的特權指令。

 

3、總結

  半虛擬化的思想就是,讓客戶作業系統知道自己是在虛擬機器上跑的,工作在非ring0狀態,那麼它原先在物理機上執行的一些特權指令,就會修改成其他方式,這種方式是可以和VMM約定好的,這就相當於,通過修改代碼把作業系統移植到一種新的架構上來,就像是定製化。所以XEN這種半虛擬化技術,客戶機作業系統都是有一個專門的定製核心版本,和x86、mips、arm這些核心版本。這樣以來,就不會有捕獲異常、翻譯、類比的過程了,效能損耗非常低。這就是XEN這種半虛擬化架構的優勢。這也是為什麼XEN半虛擬化只支援虛擬化Linux,無法虛擬化windows原因,微軟不修改代碼無法實現半虛擬化。


本文出自 “我拿流年亂了浮生” 部落格,請務必保留此出處http://tasnrh.blog.51cto.com/4141731/1736761

CPU純軟體半虛擬化技術

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.