硬體輔助虛擬化(hardware-assisted virtualization)
在 CPU 廠商讓虛擬化痛苦了好些年之後,Intel 與 AMD 做了件誠實的事:把虛擬化支援直接造進處理器裡。Intel 把它的版本叫 VT-x(指令集名為 VMX);AMD 把它的版本叫 AMD-V(指令集 SVM)。這點子說起來很簡單:給 CPU 加上一個全新的運作模式,它唯一的工作就是乾淨地托管客體,於是超管理器再也不需要二進位翻譯或被改過的客體。它直接跑未經修改的客體作業系統,讓硬體去逮該逮的東西。
具體而言,這些擴充加上兩個執行情境。根模式(root mode)是超管理器跑的地方——最有特權的位置,完全掌控。非根(客體)模式是正常特權結構的一份忠實複本,「但」在超管理器的掌握之下:客體核心能跑在它自己的 ring 0、自以為享有完整特權,而硬體則悄悄把那些危險時刻轉交給主機。超管理器為每顆虛擬 CPU 設定一個手冊稱為 VMCS 的資料結構(Intel 的虛擬機控制結構;AMD 上叫 VMCB):這是一個控制區塊,說明哪些客體操作應該踢回主機,並儲存客體的整套暫存器狀態,好讓一個客體能被精確地暫停與恢復。要啟動一個客體,你執行一次 VM-entry;當客體碰上一個被設定的條件時,CPU 便執行一次 VM-exit,回到超管理器。
它為何改變了一切:硬體輔助直接補上了 Popek-Goldberg 那道缺口——現在那些危險指令「確實」會引發一次受控的退出,於是純粹的陷阱與模擬在 x86 上又行得通了,不必改寫客體、也不必半虛擬化。它讓「拿未經修改的 Windows 或 Linux 當客體來跑」變得又快又是家常便飯,並且是 KVM、現代 Hyper-V、ESXi 與雲端底下的基石。誠實的告誡是:每次 VM-exit 仍要花上數百到數千個週期,所以工程目標轉向了「讓退出變稀少」——這正是巢狀分頁這類配套功能存在的原因。
在 Intel 上,超管理器為一顆虛擬 CPU 設好一份 VMCS,接著執行 vmlaunch 指令做一次 VM-entry。客體以原生速度執行,直到——比方說——它存取一個被模擬的裝置暫存器;硬體於是執行一次 VM-exit,超管理器再讀取 VMCS,得知究竟為何退出、以及該模擬什麼。
VT-x/AMD-V 加上一個客體模式與一份 VMCS,讓未經修改的客體跑得快、只在需要時才退出。
硬體輔助並沒有讓虛擬化變免費——每次 VM-exit 仍要花真實的週期。早期的 VT-x 有時還「慢過」一個優秀的二進位翻譯超管理器;真正的勝利,是在退出被弄稀少、且記憶體虛擬化也搬進硬體之後才到來的。