一文讀懂虛擬化原理

1. 前言

虛擬化是現代計算機領域不可或缺的一種技術,它讓公開的虛擬資源等於被虛擬化的底層物理資源,通常是使用多路複用、聚合和模擬中的一種或多種基本技術實現。等效性、安全性和性能是衡量虛擬化的三個重要標準。Gerald Popek 和 Robert Goldberg 在 1974 年就確立了一個指令集架構 (ISA) 是否支持虛擬化的基本要求。直到今天,這個核心思想仍然理解計算機體系結構和支持虛擬機能力的基本原則。

2. 名詞解釋

在開始正文之前,先複習下幾個虛擬化相關的重要名詞。

2.1 虛擬機

英文是 Virtual Machine,簡稱 VM。虛擬機是對完整計算機環境的抽象,它將處理器、內存 (memory) 和 I/O 設備聯合虛擬化,具有自己獨立的處理能力、內存和通信通道。每個虛擬機的內部環境類似於計算機的硬件,都有自己的底層硬件副本,或者至少有自己的某些底層硬件副本,且可以運行自己的獨立客戶操作系統 (Guest OS) 及其應用程序 (App),且與其它虛擬機和環境其餘部分完全隔離,互不影響和感知。虛擬機的運行平臺可以分爲兩類:虛擬機管理程序(Hypervisor) 和機器模擬器(Machine Simulator)。這兩個名詞在下面介紹。

2.2 虛擬機管理程序

英文是 Hypervisor,中文也叫超級監督者。Hypervisor 是管理和運行虛擬機的專用系統軟件。當多個虛擬機同時存在於同一個計算機系統上時,hypervisor 對它們進行調度,使虛擬機之間進行多路複用來分配真實物理資源。Hypervisor 讓虛擬機直接在 CPU 上執行可以獲得最大效率,理想情況下基本不影響性能開銷。Hypervisor 先配置好硬件環境 (寄存器等),隨後讓虛擬機指令在 CPU 上執行。由於虛擬機指令序列必須在虛擬機的抽象中操作,因此執行更新或依賴系統狀態的指令會引起 Trap(捕獲),hypervisor 會處理這個 Trap 並模擬該指令的功能。Hypervisor 設計的核心就是 Trap-and-Emulate 範式。

Hypervisor 分爲 type-1 和 type-2 兩種類型。Type-1 hypervisor 直接控制物理計算機的所有資源。相比之下,type-2 hypervisor 要麼作爲現有主機操作系統 (Host OS) 的一部分運行,要麼直接在現有 Host OS 之上運行,其實就是擴展 Host OS 的功能。常見的 hypervisor 如下圖 1 所示。

圖 1 常見的 hypervisor

最基本的 hypervisor 使用兩種關鍵虛擬化技術:

由於 Hypervisor 允許虛擬 CPU 直接執行物理處理器的指令,這種調度技術被稱爲直接執行 (Direct Execution)。當然,hypervisor 要負責確保虛擬機的安全性。因此,hypervisor 會確保虛擬機總是以更低的特權執行,這樣虛擬 CPU 就不能直接執行特權指令等。只要 Guest OS 試圖執行特權指令,虛擬機的直接執行就會導致 Trap,然後就由 hypervisor 接管去模擬了。因此,圍繞直接執行設計的 hypervisor 遵循 trap-and-emulate 範式,其中大部分執行開銷是用於 hypervisor 代表虛擬機模擬 trap 指令的功能。

2.3 機器模擬器

英文是 Machine Simulator。Machine Simulator 通常使用普通的用戶級應用程序實現,其目標是提供對虛擬架構的精確模擬,取決於模擬細節的級別,它通常會比本機速度慢 x5 到 1000x 不等。因爲 Machine simulators 允許對複雜工作負載的詳細研究,在計算機體系結構研究中起着重要作用。

實際上,Machine Simulator 和 Hypervisor 之間的主要區別在於,前者模擬虛擬機的 CPU 指令集體系結構,而後者對 CPU 進行多路複用。CPU 的多路複用是一個調度任務,與操作系統調度進程任務非常的類似。調度實體 (這裏是 hypervisor) 設置硬件環境 (寄存器等),然後讓被調度實體(虛擬機) 以較低的特權等級直接在硬件上執行。Machine Simulator 可以說是 Full(soft) virtualization,Hypervisor 可以說是 Hardware virtualization(HVM, HV)。

除了 Hypervisor 和 Machine Simulator,其實還有一種半虛擬化 (paravirtualization)。它是由於早期處理器缺乏對虛擬化清晰的體系結構支持,因此出現了一系列解決運行與底層硬件相似或兼容相同虛擬機問題的方法。這種方法做出了不同的權衡,將簡單性和整體效率置於與底層硬件的完全兼容性之上。

在早期沒有虛擬化體系結構支持的平臺上,paravirtualization 需要更改與底層硬件不兼容的 Guest OS。在具有 Full virtualization 支持的體系結構的當前使用中,通過平臺特定的擴展,paravirtualization 仍然用於增強 HWM,通常在設備驅動程序中實現,例如管理協作內存或實現高性能前端設備。

2.4 虛擬機監控器

英文是 Virtual Machine Monitor,簡稱 VMM。VMM 是 hypervisor 中專門用於 CPU 和內存虛擬化的部分。不過有些文獻中,VMM 和 hypervisor 是一樣。在 Type-1 hypervisor 中,VMM 直接在裸機上運行,type-2 hypervisor 中,VMM 運行在 Host OS 之下。Type-1 和 type-2 的 hypervisor 中,VMM 都需要創建虛擬機。

Type-1 環境中,裸機上的 VMM 必須執行系統的調度和實際的資源分配,因此,type-1 VMM 需要編寫額外的資源調度和分配代碼。Type-2 環境中,Host OS 調度所有的系統資源,Host OS 像調度進程一樣調度 hypervisor,儘管這種模式需要依賴繁瑣的 Kernel 模式來執行虛擬機,但好處就是可移植性強、代碼改動量少。

VMM 的基本結構如圖 2 所示,每個 Processing Element(PE) 包括了 CPU 和物理內存。PE 連接到 I/O 總線上,並附帶兩個 I/O 設備:磁盤和網絡接口卡。該圖也是服務器部署的典型代表。PC 的話可能還包括鍵盤、鼠標、串行接口和 USB 等附加設備。移動平臺可能還需要 GPS、加速度計和收音機等。圖中有三個虛擬機,每個虛擬機都有自己的虛擬硬件、自己的 Guest OS 和自己的應用程序。Hypervisor 直接運行在真實硬件上,且控制着實際的物理資源。

圖 2 VMM 的基本架構

2.5 內存

英文是 Memory。內存有很多種類定義,不過大致分爲兩種類型:Virtual memory(虛擬內存)Physical memory(物理內存),虛擬內存通過分段或分頁的組合轉換爲物理內存。

虛擬內存通常就是處理器執行指令時所使用的地址空間。除了極少數例外,所有指向內存位置的寄存器和指令地址都包含一個虛擬地址。在分段體系結構中,虛擬地址空間是由基址和偏移限制決定的。基址會被添加到虛擬地址中,偏移限制會用於檢查以進行保護地址是否越界。在分頁體系結構中,虛擬地址空間由內存管理單元 (MMU) 在逐頁的基礎上確定,其映射由頁表或軟件 TLB miss 處理程序定義。有些體系結構(如 x86-32)將分段與分頁結合起來,虛擬地址首先(通過分段)轉換成線性地址,然後(通過分頁)轉換成物理地址。

物理內存就是處理器的內存層次結構訪問所使用的地址空間,通常由 DRAM 提供支持。在非虛擬化的計算機系統中,物理地址空間通常由硬件資源決定,並由處理器的內存控制器定義。在虛擬計算機系統中,hypervisor 定義虛擬機可用物理內存大小。從技術上講,對虛擬機可見的抽象應該稱爲 “virtual physical memory”(虛擬物理內存)。然而,爲了避免與虛擬內存混淆,它通常被稱謂 guest-physical memory。爲了進一步避免歧義,底層資源被稱爲 host-physical memory。不過要注意,一些早期的虛擬化論文使用了不同的術語,特別是分別使用 physical memory 和 machine memory 來指代 guest-physical memory 和 host-physical memory。

3. 虛擬化模型

1974 年,Gerald Popek 和 Robert Goldberg 在 Communications of the ACM 上發表了一篇名爲 “Formal Requirements for Virtualizable Third-Generation Architectures”的論文,其中定義決定了一個給定的指令集架構 (ISA) 是否可以被一個使用多路複用的 VMM 虛擬化。對於任何滿足定義假設的體系結構,任何可以直接在硬件上運行的操作系統也可以在虛擬機中運行,而無需修改操作系統代碼。這項工作的動機是解決新架構可能阻礙 VMM 構建,讓架構師在設計時就考慮這個問題。直到今天,這個定理仍然是理解計算機體系結構與其支持虛擬機的能力之間的基本關係的起點。具體地說,該定理決定了僅依賴於直接執行的 VMM 是否能夠支持任意 Guest OS。

這個定理假設有一個標準的計算機體系結構的處理器,處理器有兩種執行模式:用戶級 (user-level) 和主管級(supervisor),且支持虛擬內****存。特別是,操作系統可以將硬件配置爲相互隔離地運行多個任意的應用程序。爲了證明,文章定義了一個簡單的模型,該模型具有以下特點:

我們首先考慮這種體系結構的操作系統是什麼樣的 (在沒有 VMM 的情況下)。

  1. Kernel 將在 supervisor 模式 (M=s) 下運行,而應用程序將始終在 user 模式 (M=u) 下運行;

  2. 在初始化過程中,kernel 首先設置 Trap 入口點:MEM[0]←(M:s,B:0,L:SZ,PC:trap_en);

  3. Kernel 將爲每個應用程序分配一個連續的物理內存範圍;

  4. 要啓動或恢復存儲在物理內存 [B, B+L] 中的應用程序和當前正在執行指令 PC,操作系統只需要把 (M:u, B, L, PC) 加載到 PSW 中;

  5. 在 Trap 入口點 (PC=trap_en),kernel 首先解碼存儲在 MEM[1].PC 中的指令,確定產生 Trap 的原因,然後採取適當的行動;

這個體系結構比較理想化,特別是缺少寄存器,但與現今所熟悉的體系結構本質上沒有什麼不同。對於這樣的架構,Popek 和 Goldberg 提出了以下正式的研究問題。

給一臺滿足這個基本體系結構模型的計算機,在這個模型的精確條件下可以構造 VMM,使 VMM:

這個問題的答案決定了是否可以爲特定的體系結構構造 VMM,從而得到的虛擬機可以是真實機器的高效、獨立的副本。當條件滿足時,定理必須確保符合以下三個標準:

4. 虛擬化定理

基於上述虛擬化模型,Gerald Popek 和 Robert Goldberg 提出了以下定義:對於任何計算機,如果該計算機的敏感指令集 (sensitive instructions) 是特權指令集 (privileged instructions) 的子集,則可以構造虛擬機監視器(virtual machine monitor, VMM),也稱 hypervisor。

Popek 和 Goldberg 研究的問題的答案取決於 ISA 指令的分類。如果一條指令可以更新系統狀態,那麼他就是控制敏感指令 (control-sensitive);如果一條指令的語義依賴於系統狀態中設置的實際值,那麼它就是行爲敏感指令 (behavior-sensitive);否則,就是無害指令 (innocuous instruction)。如果一條指令只能在 supervisor 模式下執行,並且嘗試從 user 模式下執行時會產生 Trap,那麼它具有特權 (privileged)當所有 control-sensitive 和 behavior-sensitive 指令都具有特權時,則可以構造 VMM。如:

control-sensitive || behavior-sensitive ≤ privileged

圖 3(a) 描述了三種主要形式的內存之間的關係:host-physical memory, guest-physical memory 和 virtual memory。圖 3 也表述了在三種不同情況下,處理器的 PSW,以及執行級別 M 和 relocation-bound pair(B, L) 是如何配置的。

(a) host-physical memory, guest-physical memory 和 virtual memory

(b) 執行應用程序、Guest OS 和 VMM 時的硬件配置

圖 3 VMM 的構造

如果滿足定理的條件,則 VMM 的操作如下:

  1. VMM 是唯一實際運行在 supervisor 模式下的軟件。VMM 爲自己的代碼和數據結構保留了一部分物理內存,這些內存永遠不會映射到任何虛擬機的任何虛擬地址空間。

  2. VMM 在 host-physical 地址空間中爲每個虛擬機連續分配 guest-physical memory,每個虛擬機都有固定的內存大小。這些參數如圖 3 中的 addr0 和 memsize。

  3. VMM 在內存中保存每個虛擬機的系統狀態的副本:vPSW。與硬件類似,vPSW 由虛擬機的執行層、段寄存器 (B, L) 和 PC 組成。

  4. 虛擬機通過從內存加載元組 (M’, B’, L’, PC’) 恢復 PSW 來執行:

    1. M’←u:虛擬機始終以用戶模式執行;

    2. B’←addr0+vPSW.B:將 guest-physical 偏移量添加到虛擬機的段基址中;

    3. L’←min(vPSW.L, vPSW.memsize-vPSW.B):一般情況下,是直接使用虛擬機的段限制。然而,惡意 Guest OS 可能會嘗試允許其應用程序讀取超出 guest-physical memory 末端的內容。這樣 min() 是放置了這種情況,以確保安全性;

    4. PC’←vPSW.PC:恢復虛擬機的執行;

  5. 在每次 Trap 時,VMM 更新 PC 值 (vPSW.PC←PSW.PC)。vPSW 的其它域段即使在任意長的直接執行週期之後也不需要更新。實際上,任何可以更新 PSW 的 B/L/M 的指令都是 control-sensitive 的。VMM 假定所有 control-sensitive 的指令都是 privileged,並依賴於虛擬機始終使用 PSW.M==u 來執行。

  6. VMM 模擬引起 Trap 的指令。如果 guest OS 正在運行 (vPSW.M==u),VMM 首先對指令進行解碼,然後根據 ISA 模擬特權指令的語義。例如,根據 Guest OS 設置的新值,VMM 通過更新 vPSW.B 和 vPSW.L 來模擬更改 segment register pair。在成功模擬後,VMM 增加 PC(vPSW.PC++),然後根據步驟 4 恢復虛擬機的執行。

  7. 然而,VMM 可能得出結論,根據 ISA,指令的模擬實際上是一個 Trap。例如,考慮虛擬機處於 user 模式的情況 (vPSW.M==u),惡意應用程序試圖發出特權指令,或者如果應用程序訪問內存超出了 Guest OS 在段描述符(B) 中設置的限制。根據架構,VMM 會模擬 Trap,即:

    1. MEM[addr0]←vPSW:根據體系結構將虛擬機的 vPSW 存儲到 Guest-physical memory 的第一個字;

    2. vPSW←MEM[addr0+1] 根據體系結構將 Guest-physical memory 中的第二個字複製到 vPSW 中。根據 Guest OS 設置的配置更新虛擬機的狀態;

    3. 按照步驟 4 恢復執行;

  8. 如果滿足定理的假設,所有更新系統狀態的指令 (程序計數器除外) 是 control-sensitive,且具有 privileged。在 user 模式下執行這些指令將會造成 Trap。它將包括任何改變定義虛擬地址空間的 base-bound registers 指令、或在 user 和 supervisor 模式之間轉換的指令。VMM 根據體系結構規範模擬這些指令。

  9. 如果這個假設得到滿足,那麼任何 behavior-sensitive 指令都將擁有特權,在 user 模式下執行將會導致 Trap。VMM 也會模擬這些指令,例如,考慮一條指令需要讀取執行層 (PSW.M) 或段基址(PSW.B),這種指令的行爲直接依賴於處理器狀態的實際值,而處理器狀態的實際值會在虛擬化過程中發生變化。這些指令必須具有特權,以確保正確的值返回給程序。

5. 遞歸虛擬化

實際上,滿足定理標準的理想化架構也可以支持遞歸虛擬化 (recursive virtualization)。在這個場景中,虛擬機可以在 Guest-supervisor 模式下運行 VMM,而不是在操作系統模式下運行 VMM。當然,VMM 可以運行多個虛擬機、它們的 Guest OS 和各自的應用程序。在遞歸虛擬化中,VMM 本身必須在虛擬機中運行。

6. 總結

本文旨在用最簡單的方式描述虛擬化的本質和基本實現框架,任何複雜的虛擬機都是基於此基本原理上增補功能來的。只要大家心裏有個虛擬機原理框架,我相信學習任何虛擬機都能很快入手,擺脫只見樹木,不見森林的狀態。

本文從名詞解釋,在使用一個基本簡單的模型,引出了 Popek 和 Goldberg 研究的虛擬化定理,根據這個定理,可比較快判斷一個處理器體系結構是否好支持 Hypervisor。Hypervisor 實際上也是一個 OS,兩者都必須確保保持控制,並且必須正確配置硬件以實現其目標。不同之處在於,OS 運行應用程序,而 hypervisor 運行整個虛擬機 (包括 Guest OS 和應用程序)。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/ItKrxXjB1IaxlaLBeJYn6Q