在 Windows 11 開啟系統資訊(msinfo32),「以虛擬化為基礎的安全性」欄位常常顯示「執行中」──即使那台機器從沒建立過虛擬機器。
那代表下面這個事實。在那台 PC 上,主機 Windows 本身已經跑在 Hypervisor 之上。「虛擬化」不再只是給在 Hyper-V 管理員裡建立虛擬機器的人用的技術。在 Windows 11,符合條件的組態──例如在相容硬體上全新安裝1──會預設啟用以虛擬化為基礎的安全性(VBS),而 WSL2 與 Windows Sandbox 也建立在同一個 Windows Hypervisor 上。你每天使用的 Windows 底下,已經多了一層軟體。
本系列「Windows 虛擬化的深層」從基礎開始,追那一層裡發生的事。
「Windows 虛擬化的深層」── 全 3 回
- 第 1 回(本文):Hypervisor 與分割區
追啟用 Hyper-V 之後,主機 Windows 最後跑在哪裡。 - 第 2 回:連核心都看不到的記憶體 ── VBS、HVCI 與 Credential Guard
追 Windows 把系統管理員和核心都讀不到的秘密放在哪裡。 - 第 3 回:數秒就能啟動的虛擬機器 ── WSL2、Windows Sandbox 與容器
從記憶體與映像如何共用,追為什麼完整虛擬機器很重,WSL2 與 Sandbox 卻很輕。
第 1 回要回答的問題只有一個。
啟用 Hyper-V 之後,主機 Windows 最後跑在哪裡?
對象讀者是使用 Hyper-V、WSL2 或 Windows Sandbox,想從機制往上理解底下在跑什麼的開發者與維運人員。前提環境是 x64 Windows 10/11 或現行 Windows Server(本文對 ring、VT-x/AMD-V、EPT/RVI 的討論假設 x64;Arm64 使用例外層級等不同機制)。所需背景大約是核心模式與使用者模式的區別;不需要虛擬機器操作經驗或 Hypervisor 開發知識。難度為中階。我們涵蓋 CPU 虛擬化擴充的概念,但不進入指令集細節。
1. 先講結論
聽到 Hyper-V,人們可能想像「坐在 Windows 上面、負責跑虛擬機器的軟體」。實際結構正好相反。
從你啟用 Hyper-V 並重新開機的那一刻起,控制實體 CPU 與記憶體的是 Hypervisor,主機 Windows 作為第一個、具特權的分割區──「根分割區」──跑在它上面。
Hypervisor 是夾在硬體與作業系統之間的薄軟體層,建立稱為「分割區」的隔離執行環境,並仲介對硬體的存取。2 主機 Windows 進入的是根分割區;虛擬機器進入的是子分割區。根分割區被特別對待(能直接存取實體裝置,並持有管理堆疊),但就「不直接控制實體 CPU」這一點,它和子分割區站在同一個位置。
flowchart TB
accTitle: 啟用 Hyper-V 後的整體結構
accDescr: Hypervisor 直接坐在實體硬體上,其上是持有主機 Windows 的根分割區,以及持有虛擬機器的子分割區
hw["實體硬體"] --> hv["Hypervisor"]
hv --> root["根分割區(主機 Windows)"]
hv --> child1["子分割區(虛擬機器)"]
root -.-> stack["持有虛擬化管理堆疊與裝置驅動程式"]
圖 1: Hyper-V 不是「Windows 上面的虛擬機器軟體」,而是鑽到 Windows 底下的一層,主機作業系統本身跑在根分割區裡。
你可能想:「啟用後感覺沒什麼不同,真的發生了這麼大的顛倒嗎?」有。正因如此,這個結構通常不被察覺。本文沿著 CPU、記憶體、裝置 I/O 三條軸,把這張圖拆開。
2. 從 CPU 看 ── Ring 下面再多一層特權
2.1. Ring 保護的複習
x64 CPU 有特權層級(ring),Windows 把核心模式跑在 ring 0、使用者模式跑在 ring 3。應用程式不能直接碰硬體,因為特權指令不能從 ring 3 執行。
那麼,要如何在同一個實體 CPU 上,安全地安頓每個都跑在 ring 0 的多個作業系統核心?每個核心都按「我控制 CPU」來寫。把 ring 0 都給它們就會碰撞;不給它們就跑不起來。
flowchart TB
accTitle: 多個作業系統核心都要 ring 0 的問題
accDescr: 主機與客體核心都假設自己在 ring 0 擁有完整權限,因此單靠傳統 ring 階梯無法把它們安全安頓在同一個實體 CPU 上
k1["主機核心(假設 ring 0)"] --> want["要求控制實體 CPU"]
k2["客體核心(假設 ring 0)"] --> want
want --> conflict["傳統 ring 無法調和"]
conflict --> need["需要高於 ring 0 的仲介"]
圖 2: Ring 階梯是按單一作業系統假設打造的,安頓多個核心需要再高一層特權。
2.2. 虛擬化擴充 ── 保留給 Hypervisor 的模式
解決這個問題的,是 CPU 的虛擬化擴充(Intel VT-x/AMD-V)。Hyper-V 需要具備這項功能的處理器。2 虛擬化擴充在與傳統 ring 不同的軸上,加上「給 Hypervisor 的執行模式」與「給客體的執行模式」。那是比 ring 0 更強的特權,有時被暱稱為「ring -1」。
- 客體核心繼續像以前一樣跑在 ring 0。不需要改寫。
- 不過那個 ring 0 是「客體模式裡的 ring 0」,並不控制整個實體 CPU。
- 當客體碰到需要 Hypervisor 介入的特定操作(被設成攔截的指令,或例外/違規),CPU 會自動把控制權交給 Hypervisor(VM Exit)。Hypervisor 處理完後回到客體(VM Entry)。一般記憶體存取只要 SLAT 轉譯成功,就不會發生 VM Exit。
中斷也一樣。分割區不直接碰實體處理器;Hypervisor 接收中斷並導向各分割區。2
flowchart TB
accTitle: 客體執行與 VM Exit 的流程
accDescr: 客體核心與應用程式在客體模式的 ring 0 與 ring 3 執行;一般記憶體存取經 SLAT 轉譯直接通過,被設定的攔截與例外會造成 VM Exit,把控制權交給 Hypervisor,再經 VM Entry 回到客體
guest["在客體模式執行(含 ring 0 核心)"] --> op{"需要介入的操作?(已設定的攔截/例外)"}
op -->|否| cont["照原樣繼續執行"]
op -->|是| exitEv["VM Exit(CPU 移交控制權)"]
exitEv --> hvp["Hypervisor 處理"]
hvp --> entry["經 VM Entry 回到客體"]
entry --> guest
圖 3: 客體作業系統不必改寫就能繼續跑在 ring 0,CPU 只在需要時呼叫 Hypervisor。
這趟來回很像記憶體系列追過的流程──「分頁錯誤時進入核心,再回到同一條指令」。CPU 透過例外或轉移機制攔截控制權,讓更高層的管理者決定,然後返回。在 Windows 的深層,這個形狀一再出現。
2.3. Type 1 與 Type 2 ── 差別在坐在哪裡
Hypervisor 大致分成直接跑在硬體上的 Type 1(裸機),以及跑在主機作業系統之上的 Type 2(託管)。Hyper-V 是 Type 1。3 VirtualBox 與 VMware Workstation(獨立執行時)被歸類為 Type 2。
聽到 Type 1,人們容易想像「沒有主機作業系統的伺服器專用組態」,但 Hyper-V 不同。主機 Windows 沒有消失──它「搬家」進根分割區。啟用 Hyper-V 並重新開機後,開機過程中 Hypervisor 先啟動,主機 Windows 再作為其上的根分割區起來。
flowchart TB
accTitle: Type 1 與 Type 2 Hypervisor 的差異
accDescr: Type 2 中主機作業系統坐在硬體上,Hypervisor 與虛擬機器坐在主機作業系統上;Type 1 的 Hyper-V 則是 Hypervisor 直接坐在硬體上,主機作業系統本身進入其上的根分割區
subgraph t2 ["Type 2(託管)"]
hw2["硬體"] --> hostos["主機作業系統"]
hostos --> hv2["Hypervisor"]
hv2 --> vm2["虛擬機器"]
end
subgraph t1 ["Type 1(Hyper-V)"]
hw1["硬體"] --> hv1["Hypervisor"]
hv1 --> root1["根分割區(主機作業系統)"]
hv1 --> vm1["虛擬機器"]
end
vm2 ~~~ hw1
圖 4: Type 2 的 Hypervisor 坐在主機作業系統上;Type 1 的 Hyper-V 順序相反,主機作業系統本身坐在再下一層。
從開機時間軸來看,啟用後發生的變化是這樣。
flowchart TB
accTitle: 啟用 Hyper-V 後的開機順序
accDescr: 開機後,開機過程中 Hypervisor 先啟動,主機 Windows 再作為其上的根分割區起來,虛擬機器、VBS 等在那之後啟動
poweron["開機並開始啟動"] --> bhv["Hypervisor 先啟動"]
bhv --> broot["主機 Windows 作為根分割區啟動"]
broot --> blater["虛擬機器、VBS、WSL2 等在其上啟動"]
broot -.-> feel["使用者體驗不變"]
圖 5: 順序顛倒在登入畫面出現前就已完成,主機作業系統從一開始就在 Hypervisor 上起來。
3. 分割區 ── 隔離的單位
3.1. 只有根分割區才有的角色
分割區是 Hypervisor 提供的邏輯隔離單位。2 不過並非每個分割區都平等。有些事只有根分割區才有。
- 直接存取實體裝置。磁碟、網路介面卡、GPU 等的裝置驅動程式住在根分割區裡的 Windows,而不是 Hypervisor。Windows Server 上的 Hyper-V 有一種把特定 PCIe 裝置直接指派給子分割區的組態(Discrete Device Assignment);那時根分割區會放開該裝置(用戶端 Windows 沒有這項功能)。4
- 虛擬化管理堆疊。掌管建立、啟動、停止虛擬機器的 VMMS(Virtual Machine Management Service),以及每個虛擬機器的工作者處理程序(vmwp.exe),跑在根分割區的使用者模式。5 這些屬於 Hyper-V 的虛擬機器管理功能,因此只為 VBS 或 WSL2 跑 Hypervisor 的主機上可能沒有。
- 建立子分割區的權利。根分割區透過 hypercall API(呼叫進 Hypervisor 的介面)建立子分割區。2
這個設計有理由。若把每個裝置驅動程式都放進 Hypervisor 本身,Hypervisor 會變巨大,錯誤與攻擊入口也會增加。Hypervisor 把自己限制在仲介 CPU 與記憶體的最小工作,把裝置的照料留給根分割區裡的 Windows。這份角色分工讓 Hyper-V 保持精薄。
flowchart TB
accTitle: 根分割區與子分割區的角色分工
accDescr: 根分割區持有虛擬化管理堆疊與實體裝置驅動程式,並經由 hypercall 建立子分割區;子分割區通常只看到虛擬裝置,在 Windows Server 的 Discrete Device Assignment 下則直接存取被指派的裝置
subgraph rootp ["根分割區"]
vmms["VMMS 與工作者處理程序"]
drv["實體裝置驅動程式"]
end
subgraph childp ["子分割區"]
gos["客體作業系統"]
vdev["一般組態下只看得到虛擬裝置"]
end
vmms -->|經由 hypercall 建立與管理| childp
hv2["Hypervisor(只仲介 CPU 與記憶體)"] --- rootp
hv2 --- childp
圖 6: 把裝置驅動程式與管理堆疊放在根分割區端,正是讓 Hypervisor 本身保持精薄的原因。
3.2. 從子分割區看到的世界
子分割區裡的客體作業系統,在一般虛擬裝置組態下不能直接看到實體硬體(唯一例外是上一節說的、Windows Server 上經 Discrete Device Assignment 指派的裝置)。它能看到的是虛擬處理器、看起來屬於自己的記憶體空間,以及虛擬裝置。對虛擬裝置的要求經由 VMBus 或 Hypervisor 轉送到根分割區。2 另一方面,CPU 時間配置與經由 SLAT 的記憶體轉譯,由 Hypervisor 直接處理,不經過根分割區。根分割區仲介的是裝置 I/O,不是每一項實體資源。
flowchart TB
accTitle: 從子分割區看到的世界
accDescr: 客體作業系統看到的是虛擬處理器、分割區私有的記憶體空間,以及虛擬裝置;對虛擬裝置的要求經由 VMBus 等轉送到根分割區,CPU 時間與記憶體轉譯由 Hypervisor 直接處理,Windows Server 的 Discrete Device Assignment 組態下只有被指派的裝置被直接存取
gos2["客體作業系統(子)"] --> vcpu["虛擬處理器"]
gos2 --> rest{"記憶體或裝置?"}
rest --> gpa2["私有記憶體空間"]
rest --> vdev2["虛擬裝置"]
vdev2 --> rootx["轉送到根分割區"]
rootx -.-> vbus["經由 VMBus 等"]
gos2 -.-> phys2["實體 CPU、RAM、裝置"]
phys2 -.-> hid["不能直接看見"]
phys2 -.-> dda2["DDA:被指派的裝置"]
dda2 -.-> ddaN["Windows Server"]
vcpu ~~~ phys2
圖 7: 一般虛擬裝置組態下,客體看到的一切都是虛擬視窗,通往實體的路徑經過仲介;只有 Windows Server 上經 DDA 指派的裝置是例外。
這裡重要的是:對跑在主機 Windows 上的應用程式來說,這個結構幾乎透明。Win32 API 呼叫與分頁錯誤處理,仍由根分割區裡的 Windows 核心照舊處理。Hypervisor 只在碰到已設定的攔截或例外時介入。
4. 從記憶體看 ── 位址轉譯再多一層
4.1. 三種位址
記憶體系列第 1 回追過虛擬位址經分頁表轉成實體位址的流程(「虛擬位址變成實體 RAM 的那一刻」)。在虛擬化環境裡,那層轉譯底下再加一層,於是有三種位址。
| 位址 | 縮寫 | 誰管理 |
|---|---|---|
| 客體虛擬位址 | GVA | 客體作業系統分頁表 |
| 客體實體位址 | GPA | 客體作業系統以為是「實體」的位址 |
| 系統實體位址 | SPA | Hypervisor(RAM 上的實際位置) |
客體作業系統用自己的分頁表把 GVA 轉成 GPA。不過客體看到的 GPA 不是真正的實體位址;那是每個分割區專用的私有記憶體空間。2 把 GPA 對應到 RAM 上的實際位置(SPA)是 Hypervisor 的工作。
4.2. SLAT ── 硬體上的兩層轉譯
若只用軟體做這第二層轉譯,Hypervisor 就得逐一追蹤客體分頁表的每次更新,從效能來看不切實際。因此 CPU 提供在硬體上走第二層轉譯表的機制。那就是 SLAT(Second Level Address Translation);Intel EPT(Extended Page Tables)與 AMD RVI 是實作。現行 Hyper-V 需要具備 SLAT 的 64 位元處理器。4
flowchart TB
accTitle: 經由 SLAT 的兩層位址轉譯
accDescr: 客體虛擬位址由客體作業系統分頁表轉成客體實體位址,再由 Hypervisor 管理的 SLAT 進一步轉成系統實體位址,到達真正的 RAM
gva["客體虛擬位址(GVA)"] -->|客體作業系統分頁表| gpa["客體實體位址(GPA)"]
gpa -->|"SLAT(EPT/RVI 轉譯表)"| spa["系統實體位址(SPA)"]
spa --> ram["實體 RAM"]
gpa -.-> note["客體只是以為它是實體的一層"]
圖 8: 客體分頁表底下還有一張由 Hypervisor 管理的轉譯表,CPU 用硬體走完兩層。
SLAT 不是只為虛擬機器執行效率而存在的功能。第 2 回會看到的 VBS,把「每個特權層級可以有不同的 SLAT 轉譯表」這個性質當成安全性邊界的材料。之所以能做出連核心都看不到的記憶體,是因為 Hypervisor 持有這第二層轉譯。這會成為整個系列的貫穿線,所以先記住一點:「轉譯表的擁有者是 Hypervisor」。
5. 從裝置 I/O 看 ── VMBus 與兩種裝置
5.1. 模擬裝置的極限
把裝置秀給子分割區看的經典做法,是用軟體完整模仿真實硬體(例如舊的 IDE 控制器)。相容性高,因為客體作業系統內建驅動程式能原樣使用,但客體每次碰到 I/O 連接埠都會發生 VM Exit,效能無法擴展。
flowchart TB
accTitle: 對模擬裝置的 I/O 為什麼慢
accDescr: 客體每次操作 I/O 連接埠,控制權就經 VM Exit 轉到 Hypervisor 端,用軟體模仿裝置,再回到客體,來回重覆因此慢
gio["客體操作 I/O 連接埠"] --> vex["發生 VM Exit"]
vex --> emu2["用軟體模擬裝置"]
emu2 --> back["經 VM Entry 回到客體"]
back -->|下一次連接埠操作再重覆| gio
圖 9: 單一次磁碟存取背後,這趟來回會跑很多次,相容性的代價用效能來付。
5.2. VMBus 與 VSP/VSC ── 為虛擬化設計的快速路徑
因此 Hyper-V 有一套假設虛擬化存在的「合成裝置」機制。角色有三個。2
- VMBus:分割區之間的邏輯通訊通道。提供使用共享記憶體的高速分割區間通訊。3
- VSP(Virtualization Service Provider):住在根分割區端的服務,接收來自子分割區的裝置要求,並把它們橋接到根端的裝置/後端堆疊。要求可能到達實體裝置,也可能由虛擬磁碟或虛擬交換器這類主機端後端處理。
- VSC(Virtualization Service Consumer):進入子分割區端客體作業系統的合成裝置驅動程式。它經由 VMBus 把要求送給 VSP。
以客體作業系統的儲存要求為例,流程是這樣。客體應用程式的 WriteFile 沿著客體核心的 I/O 堆疊往下,在底部到達 VSC(而不是真實硬體)。VSC 把要求放到 VMBus,交給根分割區的 VSP,VSP 再把要求流入根端 I/O 堆疊。在虛擬磁碟(VHDX)組態下,這次寫入被當成對主機上 VHDX 檔案的寫入,最後到達實體磁碟。這種做法稱為 Enlightened I/O(意識到虛擬化的 I/O),藉由繞過裝置模擬層來提高效率。2
flowchart TB
accTitle: 合成裝置的 I/O 路徑
accDescr: 子分割區應用程式的 I/O 要求經客體核心到達 VSC,越過 VMBus 到根分割區的 VSP,在 VSP 橋接進去的根端 I/O 堆疊上,可能經實體裝置驅動程式到達真實裝置,也可能由虛擬磁碟或虛擬交換器等主機端後端處理
app["子分割區裡的應用程式"] --> gk["客體核心 I/O 堆疊"]
gk --> vsc["VSC(合成裝置驅動程式)"]
vsc -->|VMBus| vsp["VSP(根分割區端)"]
vsp --> rio["根端 I/O 堆疊"]
rio --> pdrv["實體裝置驅動程式"]
rio --> hb["主機端後端(虛擬磁碟、虛擬交換器等)"]
pdrv --> dev["實體裝置"]
圖 10: 有了合成裝置,客體 I/O 經 VMBus 跨到根分割區,再經根端堆疊到達真實裝置或主機端後端。
也就是說,虛擬機器的磁碟 I/O 或網路快不快,不只取決於客體端,也取決於根分割區端 I/O 堆疊與裝置驅動程式的狀態。調查虛擬機器效能問題時,主機端觀測不可或缺,原因是路徑實際上經過主機。
flowchart TB
accTitle: 模擬裝置與合成裝置
accDescr: 模擬裝置模仿真實硬體,讓內建客體驅動程式能用但較慢;合成裝置是假設 VMBus 的專用驅動程式,較快
dev2{"秀給子分割區看的裝置"} --> emu["模擬裝置"]
dev2 --> syn["合成裝置"]
emu -.-> emuP["模仿真實硬體;相容性優先"]
emuP -.-> emuC["每次 I/O 都要介入;慢"]
syn -.-> synP["圍繞 VMBus 設計;快"]
synP -.-> synC["客體需要對應驅動程式"]
圖 11: 兩種虛擬裝置裡,模擬裝置承擔剛裝完作業系統後的相容性,合成裝置承擔日常使用的效能。
6. 就算從沒使用虛擬機器,這也不是別人的事
到目前的結構看起來像「給把虛擬機器拉起來的人聽的故事」。不過如開頭所說,在現行 Windows 上,Hypervisor 已是日常的一部分。
- 以虛擬化為基礎的安全性(VBS)。它用 Windows Hypervisor 建立隔離環境,並把安全性功能放進去。在 Windows 11,符合在相容硬體上全新安裝等條件時預設啟用。1 細節見第 2 回。
- WSL2。它在輕量公用虛擬機器裡跑真正的 Linux 核心。6
- Windows Sandbox。由 Hypervisor 隔離的一次用 Windows 環境。7 兩者都在第 3 回談。
flowchart TB
accTitle: 坐在同一個 Hypervisor 上的日常功能
accDescr: 不只 Hyper-V 虛擬機器,在符合全新安裝等條件的裝置上預設啟用的 VBS,以及 WSL2 與 Windows Sandbox,全都建立在同一個 Windows Hypervisor 上
base["Windows Hypervisor"] --> f1["Hyper-V 虛擬機器"]
base --> f2["VBS(全新安裝等情況下預設啟用)"]
base --> f3["WSL2"]
base --> f4["Windows Sandbox"]
f2 -.-> daily["為什麼從沒使用虛擬機器的 PC 也在跑"]
圖 12: 基礎只有一個,這張圖就是「虛擬化是給使用虛擬機器的人聽的故事」這個假設崩掉的地方。
實務上常踩到的另一件事,是與第三方虛擬化軟體共存。因為 Hypervisor 獨占使用 CPU 的虛擬化擴充,在 Windows Hypervisor 正在執行的環境裡,VirtualBox 等無法用傳統方式(自己使用 CPU 虛擬化擴充的方式)執行。對此提供了稱為 Windows Hypervisor Platform 的公開 API,第三方虛擬化堆疊可以坐在 Windows Hypervisor 上執行。8 現行 VirtualBox/VMware 靠這個機制能與 WSL2 共存,但切換模式帶來的效能與功能差異,有時會被觀察成「啟用 Hyper-V(或 VBS)之後,虛擬化軟體開始表現不同」。
flowchart TB
accTitle: 誰擁有 CPU 虛擬化擴充,以及第三方虛擬化軟體的路徑
accDescr: Windows Hypervisor 執行中時獨占 CPU 虛擬化擴充;支援 WHP 的第三方虛擬化軟體經由 Windows Hypervisor Platform 跑在它上面,不支援 WHP 的實作無法執行或功能受限
vt["CPU 虛擬化擴充(VT-x/AMD-V)"] --> hvon{"Windows Hypervisor 在跑嗎?"}
hvon -->|否| direct["第三方軟體可直接使用"]
hvon -->|是| own["Hypervisor 獨占使用"]
own --> whp["Windows Hypervisor Platform"]
whp --> third["支援 WHP 的第三方軟體跑在其上"]
third -.-> nowhp["不支援的實作無法執行或受限"]
圖 13: 虛擬化擴充的擁有者只有一個,Hypervisor 執行中能共存的第三方軟體,只有支援公開 API(WHP)的軟體。
7. 自己看一看
你可以在自己的機器上確認 Hypervisor 是否在跑。
首先,不需要系統管理員權限就能做的檢查。
# Whether we are running on top of a hypervisor
(Get-CimInstance Win32_ComputerSystem).HypervisorPresent
# VBS status (same source as "Virtualization-based security" in msinfo32)
Get-CimInstance -Namespace root/Microsoft/Windows/DeviceGuard `
-ClassName Win32_DeviceGuard |
Select-Object VirtualizationBasedSecurityStatus
VirtualizationBasedSecurityStatus 用數字傳回 VBS 的執行狀態(2 是「執行中」)。9
一個注意。HypervisorPresent 只告訴你「是否跑在某個 Hypervisor 之上」;它不區分根與子。若在虛擬機器裡的 Windows 上執行,它仍會傳回 True,因為那是子分割區。若實體 PC 上的 Windows 為 True,那個 Windows 就在根分割區裡──要和執行環境一起讀。
接著,命令提示字元裡的經典做法。
systeminfo
看輸出末尾的「Hyper-V Requirements」。Hypervisor 尚未執行的機器會列出個別需求──SLAT 支援、虛擬化擴充是否啟用等。Hypervisor 已經在跑的機器,不會列出需求,而是一行:「A hypervisor has been detected. Features required for Hyper-V will not be displayed.」4 因此那一行就是在說你的 Windows 跑在某個 Hypervisor 之上。和 HypervisorPresent 一樣,要讀成實體 PC 上是「在根分割區裡」,虛擬機器裡是「作為子分割區」。
即使 systeminfo 每一項需求都是「Yes」,那只代表硬體端準備好了。Hyper-V 功能本身在 Pro、Enterprise、Education 版本可用,Home 沒有。10
在圖形介面,看 msinfo32「系統摘要」底下的「以虛擬化為基礎的安全性」列。注意工作管理員 CPU 窗格的「虛擬化:已啟用」只顯示虛擬化擴充是否已在韌體中啟用,與 Hypervisor 是否在跑是分開的資訊。
flowchart TB
accTitle: 如何檢查 Hypervisor 是否在跑
accDescr: 若 systeminfo 說已偵測到 Hypervisor,你就跑在 Hypervisor 上(實體 PC 上是在根分割區裡);若出現 Hyper-V Requirements 清單則尚未執行,因此檢查 SLAT、VM Monitor Mode Extensions、DEP 等每一項需求,但全部 Yes 只代表硬體端準備好,Hyper-V 功能還有版本需求
start2["執行 systeminfo"] --> q1{"需求欄位?"}
q1 -->|已偵測| running["Hypervisor 正在執行"]
running -.-> runN["在根分割區裡"]
runN -.-> runN2["(實體 PC 上)"]
q1 -->|已列出| notyet["尚未執行"]
notyet --> q2{"所有需求都是 Yes?"}
q2 -->|全部 Yes| can["硬體端準備好了"]
can -.-> ed["需要 Pro/Ent/Edu"]
q2 -->|有些 No| uefi["檢查 UEFI/BIOS 項目"]
圖 14: systeminfo 的「Hyper-V Requirements」欄位同時兼作執行狀態檢查與前提檢查。
8. 實務上要避開的三種誤讀
8.1. 「我們沒啟用 Hyper-V,所以虛擬化和我們的 PC 無關」
即使沒啟用 Hyper-V 功能(管理工具與虛擬機器執行環境),只要 VBS 啟用,Windows Hypervisor 就在跑。調查驅動程式相容性問題、效能測試,或第三方虛擬化軟體的麻煩時,要查 HypervisorPresent 與 VBS 執行狀態──不是功能有沒有啟用。
8.2. 「工作管理員寫『虛擬化:已啟用』,所以 Hyper-V 在跑」
那個顯示是韌體設定(VT-x/AMD-V 是否可用)。Hypervisor 的執行狀態要從 systeminfo 的「A hypervisor has been detected」判斷。反過來說,若工作管理員寫「已停用」,也無法啟用 Hyper-V 或 WSL2,因此先檢查 UEFI/BIOS 設定。
flowchart TB
accTitle: 容易混淆的三項檢查
accDescr: 工作管理員的虛擬化欄位顯示韌體設定,Windows 功能清單顯示安裝狀態,systeminfo 或 HypervisorPresent 顯示執行狀態;各自回答不同的問題
q3{"哪一個問題?"}
q3 --> fw{"韌體還是 Windows?"}
q3 --> c3["Hypervisor 在跑嗎?"]
fw --> a3["韌體擴充?"]
fw --> b3["Hyper-V 功能開了?"]
a3 -.-> a3t["工作管理員 CPU 窗格"]
b3 -.-> b3t["Windows 功能介面"]
c3 -.-> c3t["systeminfo"]
c3 -.-> c3tp["HypervisorPresent"]
圖 15: 這是三個獨立的問題,從任何一個顯示去推論另外兩個都是誤讀。
8.3. 「虛擬機器慢,就是客體作業系統的問題」
合成裝置 I/O 經 VMBus 跨到根分割區的 VSP,再經過根端裝置/後端堆疊(實體驅動程式,加上虛擬交換器與虛擬磁碟處理)。若只看客體內的計數器,找不到坐在主機端儲存或網路介面卡上的瓶頸。虛擬機器效能問題的原則,是從兩側觀測:客體與主機(根分割區)。
9. 總結
- 啟用 Hyper-V 後,Hypervisor 直接跑在硬體上,主機 Windows 作為根分割區執行。2
- 客體作業系統核心繼續跑在 ring 0,只有被設成攔截的操作,加上例外,才經 VM Exit 交給 Hypervisor。一般記憶體存取經 SLAT 轉譯通過。
- 只有根分割區持有實體裝置驅動程式與虛擬化管理堆疊,並經由 hypercall 建立子分割區。2
- 記憶體變成 GVA→GPA→SPA 的兩層轉譯,第二層由 SLAT(EPT/RVI)用硬體處理。現行 Hyper-V 需要 SLAT。4
- 裝置 I/O 由 VSC→VMBus→VSP 的合成裝置路徑主導,效能也取決於主機端 I/O 堆疊。2
- 在 Windows 11,因為符合全新安裝等條件的裝置會預設啟用 VBS,從沒使用虛擬機器的 PC 上 Hypervisor 也在跑,並不罕見。1 可用
HypervisorPresent與 systeminfo 確認執行狀態。
第 1 回的全貌濃縮成這張圖。
flowchart TB
accTitle: 第 1 回的全貌
accDescr: Hypervisor 坐在根分割區與子分割區底下;CPU 以排程虛擬處理器配置(只在已設定的攔截與例外時 VM Exit),記憶體由兩層 SLAT 轉譯仲介,合成裝置 I/O 經 VMBus 轉送並由根分割區的 VSP 處理,模擬裝置與 Discrete Device Assignment 有其他路徑
up["根+子分割區"] --> hvS["Hypervisor"]
hvS --> cpuS["CPU:排程 VP"]
hvS --> memS["記憶體:SLAT"]
cpuS -.-> cpuN["攔截時 VM Exit"]
memS -.-> memN["兩層轉譯"]
memS ~~~ devS
devS["裝置:VMBus I/O"] --> vspS["根端 VSP 處理"]
devS -.-> devN["模擬/DDA:其他"]
圖 16: CPU 排程與記憶體轉譯由 Hypervisor 直接處理(只在介入時 VM Exit),合成裝置 I/O 由 VMBus 另一端的根分割區(VSP)仲介。
續篇見第 2 回,「連核心都看不到的記憶體 ── VBS、HVCI 與 Credential Guard」。
我們接過本文的貫穿線──Hypervisor 持有 SLAT 轉譯表──追 Windows 如何做出「系統管理員和核心都讀不到的記憶體」。
相關文章
- The Depths of Windows Memory (Part 1) — The Moment a Virtual Address Becomes Physical RAM: A Page Fault from Start to Finish
- Windows 的「記憶體使用量」代表什麼 ── 正確解讀 Working Set、Private Bytes、Commit 與分頁檔
- 用 Windows 沙箱加速 Windows 應用程式開發的驗證 - 以實務向整理管理員權限問題、乾淨環境、權限不足・資源不足的重現
- 把 Windows 的「處理器排程」改成「背景服務」會發生什麼 - 整理 quantum、優先權提升、P-Core/E-Core
相關諮詢領域
小村軟體有限公司承接 Windows 應用程式的驗證環境設計、虛擬化環境中的效能調查,以及驅動程式與周邊相容性問題的分析。
參考連結
-
Microsoft Learn, Silicon assisted security. 關於 VBS 使用硬體虛擬化把 Secure Kernel 與一般作業系統隔離,以及在符合前提的裝置上全新安裝 Windows 11 時 VBS 與 HVCI 預設啟用。 ↩ ↩2 ↩3
-
Microsoft Learn, Hyper-V Architecture. 關於 Hypervisor 以分割區作為隔離單位;根分割區經由 hypercall API 建立子分割區;分割區跑在私有虛擬記憶體空間中,不直接存取實體處理器;VMBus、VSP、VSC 與 Enlightened I/O 的角色;以及需要硬體虛擬化擴充(Intel VT/AMD-V)。 ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9 ↩10 ↩11 ↩12
-
Microsoft Learn, Hyper-V architecture (Performance Tuning). 關於 Hyper-V 是 Type 1 Hypervisor、根分割區擁有實體 I/O 裝置,以及 VMBus 提供使用共享記憶體的高效能分割區間通訊。 ↩ ↩2
-
Microsoft Learn, System requirements for Hyper-V on Windows and Windows Server. 關於需要具備 SLAT 的 64 位元處理器與 VM Monitor Mode Extensions;能在 systeminfo 的「Hyper-V Requirements」欄位確認需求是否滿足;Hypervisor 執行中會顯示「A hypervisor has been detected」;以及 Discrete Device Assignment 能把特定裝置直接指派給子分割區。 ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, Appendix B: Hyper-V Architecture and Feature Overview. 關於 VMMS(Virtual Machine Management Service)管理子分割區中虛擬機器的狀態,以及每個虛擬機器在根分割區的使用者模式啟動一個工作者處理程序(VMWP)。 ↩
-
Microsoft Learn, Comparing WSL Versions. 關於 WSL2 在輕量公用虛擬機器裡跑真正的 Linux 核心,以及與現行 VMware、VirtualBox 併用時的注意事項。 ↩
-
Microsoft Learn, Windows Sandbox architecture. 關於 Windows Sandbox 是結合容器技術與 Hypervisor 隔離的輕量 Windows 環境。 ↩
-
Microsoft Learn, Windows Hypervisor Platform. 關於提供使用者模式 API,讓第三方虛擬化堆疊能在 Windows Hypervisor 之上建立與管理分割區。 ↩
-
Microsoft Learn, Enable Hotpatch for Azure Arc-enabled servers. 關於能經由 Win32_DeviceGuard 類別的 VirtualizationBasedSecurityStatus 確認 VBS(虛擬安全模式)的執行狀態。 ↩
-
Microsoft Learn, Install Hyper-V. 關於 Hyper-V 可在 Windows 10/11 Pro 或 Enterprise 等版本啟用,Home 版本無法安裝。 ↩
相關文章
共用相同標籤的最新文章。能以相近的主題延伸理解。
Windows 虛擬化的深層(第 3 回)── 數秒就能啟動的虛擬機器:為什麼 WSL2、Windows Sandbox 與容器這麼輕
為什麼 WSL2 與 Windows Sandbox 能在數秒內啟動、感覺這麼輕?本文從動態基礎映像、direct map、動態記憶體配置到 Hyper-V 隔離容器,解說這些機制。
Windows 虛擬化的深層(第 2 回)── 連核心都看不到的記憶體:VBS、HVCI 與 Credential Guard 如何運作
在相容硬體上全新安裝時,VBS 預設啟用,並用 Hypervisor 與 SLAT 做出比核心更強的隔離。本文解說 VTL、Secure Kernel、HVCI 與 Credential Guard 的結構。
Win32 執行緒集區 API ── 用 CreateThreadpoolWork 做「不自己建立執行緒」的並行
原生程式碼裡到處呼叫 CreateThread 嗎?本文依一次資訊解說 Vista 重新設計的 Win32 執行緒集區 API──work、timer、wait、io 四種物件、清理群組,以及回呼裡不該做的事。
具名管道實務 ── 從設計到安全性,整理 Windows 的標準 IPC
以實務角度解說 Windows 標準行程間通訊──具名管道。從一次資訊整理位元組/訊息模式的選擇、同時服務多個用戶端的伺服器設計、ACL 與偽裝的安全性,以及 .NET 的具名管道串流。
Windows 的「記憶體使用量」代表什麼 ── 正確解讀 Working Set、Private Bytes、Commit 與分頁檔
工作管理員的記憶體、Working Set、Private Bytes、Commit 並非同一個數值。本文解說 Windows 虛擬記憶體與實體記憶體的關係、分頁檔的角色,以及在記憶體不足或洩漏調查時應該檢視的指標。
相關主題
與本文相近的主題頁面。以本文為起點,可進一步連到相關服務與其他文章。
Windows 技術主題
彙整 KomuraSoft LLC 關於 Windows 開發、故障調查與既有資產活用文章的主題中心。
常見問題
整理諮詢這個主題時常見的問題。
- 啟用 Hyper-V 之後,主機 Windows 其實跑在哪裡?
- Hypervisor 直接控制實體 CPU 與記憶體如何配置,主機 Windows 跑在稱為根分割區的特殊分割區裡。實體裝置的控制通常由根分割區端的驅動程式處理。根分割區持有裝置驅動程式與虛擬化管理堆疊,但實體 CPU 的所有權屬於 Hypervisor。
- 工作管理員的「虛擬化:已啟用」代表 Hyper-V 正在執行嗎?
- 不是。那個顯示表示 CPU 的虛擬化擴充(Intel VT-x/AMD-V)是否已在韌體中啟用。要看 Hypervisor 是否真的在跑,請看 systeminfo 的「A hypervisor has been detected」,或檢查 Win32_ComputerSystem.HypervisorPresent。
- 我從沒建立過虛擬機器,為什麼 Hypervisor 還在跑?
- 在 Windows 11,符合條件的裝置──例如在相容硬體上全新安裝──會預設啟用以虛擬化為基礎的安全性(VBS),而 VBS 建立在 Windows Hypervisor 之上。使用 WSL2 或 Windows Sandbox 也一樣。Hypervisor 在和「有沒有人用虛擬機器」無關的情況下執行,並不罕見。
- SLAT 是什麼,為什麼 Hyper-V 需要它?
- SLAT(Second Level Address Translation)是 CPU 把客體實體位址轉成真正實體位址的機制;Intel EPT 與 AMD RVI 是實作。沒有它,Hypervisor 就得用軟體維護轉譯表,從效能來看不切實際,因此現行 Hyper-V 把它當成硬性需求。
- 啟用 Hyper-V 之後,VirtualBox 和 VMware 會不能用嗎?
- 因為 Hypervisor 獨占使用 CPU 的虛擬化擴充,第三方 Hypervisor 無法用傳統方式執行。不過現行 VirtualBox 與 VMware 有一種跑在 Windows Hypervisor 之上的模式(經由 Windows Hypervisor Platform),因此近期版本可以共存。