Mở Thông tin hệ thống (msinfo32) trên Windows 11 và bạn thường thấy “Running” ở trường “Virtualization-based security” — ngay cả trên máy bạn chưa bao giờ tạo VM.
Điều đó nghĩa là sự thật sau. Trên PC đó, chính Windows máy chủ đã chạy trên một hypervisor. “Ảo hóa” không còn là công nghệ chỉ dành cho người tạo VM trong Hyper-V Manager. Trên Windows 11, bảo mật dựa trên ảo hóa (VBS) được bật mặc định trên các cấu hình đáp ứng điều kiện — ví dụ cài sạch trên phần cứng tương thích1 — và cả WSL2 lẫn Windows Sandbox đều được xây trên cùng hypervisor Windows. Dưới Windows bạn dùng mỗi ngày, đã có thêm một lớp phần mềm.
Loạt bài này, “Bên trong ảo hóa Windows”, lần theo những gì xảy ra ở lớp đó, bắt đầu từ nền tảng.
“Bên trong ảo hóa Windows” — Cả 3 phần
- Phần 1 (bài này): Hypervisor và phân vùng
Chúng ta lần theo Windows máy chủ kết thúc chạy ở đâu khi bạn bật Hyper-V. - Phần 2: Bộ nhớ ngay cả kernel cũng không thấy — VBS, HVCI và Credential Guard
Chúng ta lần theo nơi Windows đặt những bí mật mà cả quản trị viên lẫn kernel đều không đọc được. - Phần 3: Máy ảo khởi động trong vài giây — WSL2, Windows Sandbox và container
Chúng ta lần theo, từ cách bộ nhớ và ảnh được chia sẻ, vì sao WSL2 và Sandbox lại nhẹ dù một VM đầy đủ thì nặng.
Câu hỏi Phần 1 trả lời chỉ có một.
Khi bạn bật Hyper-V, Windows máy chủ kết thúc chạy ở đâu?
Đối tượng là các nhà phát triển và vận hành dùng Hyper-V, WSL2 hoặc Windows Sandbox và muốn hiểu từ cơ chế lên những gì đang chạy bên dưới. Điều kiện tiên quyết là x64 Windows 10/11 hoặc Windows Server hiện hành (phần thảo luận về ring, VT-x/AMD-V và EPT/RVI trong bài này giả định x64; Arm64 dùng cơ chế khác như mức ngoại lệ). Nền tảng cần có là khoảng sự phân biệt giữa chế độ kernel và chế độ user; bạn không cần kinh nghiệm vận hành VM hay kiến thức phát triển hypervisor. Độ khó là trung cấp. Chúng ta đề cập khái niệm phần mở rộng ảo hóa CPU, nhưng không đi vào chi tiết tập lệnh.
1. Kết luận trước
Khi nghe Hyper-V, người ta có thể hình dung “phần mềm chạy VM nằm trên Windows”. Cấu trúc thực tế thì ngược lại.
Từ lúc bạn bật Hyper-V và khởi động lại, chính hypervisor điều khiển CPU vật lý và bộ nhớ, và Windows máy chủ chạy trên đó như phân vùng đặc quyền đầu tiên — “phân vùng gốc”.
Hypervisor là một lớp phần mềm mỏng nằm giữa phần cứng và hệ điều hành, tạo các môi trường thực thi cô lập gọi là “phân vùng”, và làm trung gian truy cập phần cứng.2 Cái Windows máy chủ đi vào là phân vùng gốc; cái các VM đi vào là các phân vùng con. Phân vùng gốc được đối xử đặc biệt (nó có truy cập trực tiếp tới thiết bị vật lý và giữ ngăn xếp quản lý), nhưng theo nghĩa nó không điều khiển trực tiếp CPU vật lý, nó đứng cùng vị trí với một phân vùng con.
flowchart TB
accTitle: Cấu trúc tổng thể sau khi Hyper-V được bật
accDescr: Hypervisor nằm trực tiếp trên phần cứng vật lý, và phía trên là phân vùng gốc giữ Windows máy chủ cùng các phân vùng con giữ VM
hw["Phần cứng vật lý"] --> hv["Hypervisor"]
hv --> root["Phân vùng gốc(Windows máy chủ)"]
hv --> child1["Phân vùng con(VM)"]
root -.-> stack["Giữ ngăn xếp quản lý ảo hóa và driver thiết bị"]
Hình 1: Hyper-V không phải “phần mềm VM trên Windows” mà là một lớp đi xuống dưới Windows, và chính hệ điều hành máy chủ chạy bên trong phân vùng gốc.
Bạn có thể nghĩ, “Nếu sau khi bật chẳng thấy khác gì, liệu một sự đảo ngược lớn như vậy có thực sự xảy ra không?” Có. Đó chính là lý do cấu trúc này thường không bị để ý. Trong bài này chúng ta tháo sơ đồ duy nhất này theo ba trục: CPU, bộ nhớ, và I/O thiết bị.
2. Từ phía CPU — Thêm một đặc quyền dưới các ring
2.1. Ôn lại bảo vệ ring
CPU x64 có các mức đặc quyền (ring), và Windows chạy chế độ kernel ở ring 0 và chế độ user ở ring 3. Ứng dụng không thể chạm phần cứng trực tiếp vì các lệnh đặc quyền không thể thực thi từ ring 3.
Vậy làm sao bạn chứa an toàn nhiều kernel hệ điều hành, mỗi cái chạy ở ring 0, trên cùng một CPU vật lý? Mỗi kernel được viết với giả định “tôi điều khiển CPU”. Cho tất cả chúng ring 0 thì chúng va nhau; không cho thì chúng không chạy.
flowchart TB
accTitle: Vấn đề nhiều kernel hệ điều hành đòi ring 0
accDescr: Cả kernel máy chủ lẫn kernel khách đều được viết với giả định toàn quyền ở ring 0, nên riêng thang ring truyền thống không chứa chúng an toàn trên cùng CPU vật lý
k1["Kernel máy chủ(giả định ring 0)"] --> want["Đòi điều khiển CPU vật lý"]
k2["Kernel khách(giả định ring 0)"] --> want
want --> conflict["Các ring truyền thống không hòa giải được"]
conflict --> need["Cần một trung gian trên ring 0"]
Hình 2: Thang ring được xây với giả định một hệ điều hành duy nhất, nên chứa nhiều kernel cần thêm một đặc quyền phía trên.
2.2. Phần mở rộng ảo hóa — Một chế độ dành riêng cho hypervisor
Thứ giải quyết vấn đề này là các phần mở rộng ảo hóa của CPU (Intel VT-x/AMD-V). Hyper-V yêu cầu một bộ xử lý có tính năng này.2 Phần mở rộng ảo hóa thêm, trên một trục tách khỏi các ring truyền thống, một “chế độ thực thi cho hypervisor” và một “chế độ thực thi cho khách”. Đó là đặc quyền còn mạnh hơn ring 0, đôi khi được gọi tắt là “ring -1”.
- Kernel khách tiếp tục chạy ở ring 0, như trước. Không cần viết lại.
- Tuy nhiên ring 0 đó là “ring 0 bên trong chế độ khách”, và nó không điều khiển CPU vật lý như một toàn thể.
- Khi khách chạm một thao tác cụ thể cần hypervisor can thiệp (một lệnh được cấu hình là intercept, hoặc một ngoại lệ hay vi phạm), CPU tự động chuyển quyền điều khiển cho hypervisor (VM Exit). Khi hypervisor xử lý xong, nó trở về khách (VM Entry). Các truy cập bộ nhớ thông thường đi qua mà không có VM Exit, miễn là dịch SLAT thành công.
Ngắt hoạt động theo cùng cách. Các phân vùng không chạm bộ xử lý vật lý trực tiếp; hypervisor nhận ngắt và định hướng chúng tới từng phân vùng.2
flowchart TB
accTitle: Luồng thực thi khách và VM Exit
accDescr: Kernel khách và ứng dụng chạy ở ring 0 và ring 3 trong chế độ khách; truy cập bộ nhớ thông thường đi qua nhờ dịch SLAT, trong khi các intercept và ngoại lệ đã cấu hình gây VM Exit chuyển quyền cho hypervisor, rồi hypervisor trở về khách qua VM Entry
guest["Chạy ở chế độ khách(kể cả kernel ring 0)"] --> op{"Thao tác cần can thiệp?(intercept/ngoại lệ đã cấu hình)"}
op -->|Không| cont["Tiếp tục thực thi như cũ"]
op -->|Có| exitEv["VM Exit(CPU chuyển quyền)"]
exitEv --> hvp["Hypervisor xử lý"]
hvp --> entry["Trở về khách qua VM Entry"]
entry --> guest
Hình 3: Hệ điều hành khách tiếp tục chạy ở ring 0 mà không cần viết lại, và CPU chỉ gọi hypervisor khi cần.
Vòng khứ hồi này trông rất giống luồng chúng ta đã theo trong loạt bài bộ nhớ — “vào kernel khi page fault, rồi trở về cùng lệnh”. CPU chặn quyền điều khiển qua cơ chế ngoại lệ hoặc chuyển tiếp, để một người quản lý tầng cao hơn quyết định, rồi trở về. Ở chiều sâu của Windows, hình dạng này xuất hiện hết lần này đến lần khác.
2.3. Type 1 và Type 2 — Khác biệt là nó ngồi ở đâu
Hypervisor được chia rộng thành Type 1 (bare-metal), chạy trực tiếp trên phần cứng, và Type 2 (hosted), chạy trên hệ điều hành máy chủ. Hyper-V là Type 1.3 VirtualBox và VMware Workstation (khi chạy độc lập) được xếp vào Type 2.
Nghe Type 1, người ta dễ hình dung “cấu hình chỉ dành cho máy chủ, không có hệ điều hành máy chủ”, nhưng Hyper-V thì khác. Windows máy chủ không biến mất — nó “chuyển nhà” vào phân vùng gốc. Khi bạn bật Hyper-V và khởi động lại, hypervisor khởi động trước trong quá trình boot, rồi Windows máy chủ lên như phân vùng gốc trên đó.
flowchart TB
accTitle: Khác biệt giữa hypervisor Type 1 và Type 2
accDescr: Ở Type 2 hệ điều hành máy chủ nằm trên phần cứng và hypervisor cùng VM nằm trên hệ điều hành máy chủ, còn ở Type 1 Hyper-V hypervisor nằm trực tiếp trên phần cứng và chính hệ điều hành máy chủ đi vào phân vùng gốc phía trên
subgraph t2 ["Type 2(hosted)"]
hw2["Phần cứng"] --> hostos["Hệ điều hành máy chủ"]
hostos --> hv2["Hypervisor"]
hv2 --> vm2["VM"]
end
subgraph t1 ["Type 1(Hyper-V)"]
hw1["Phần cứng"] --> hv1["Hypervisor"]
hv1 --> root1["Phân vùng gốc(hệ điều hành máy chủ)"]
hv1 --> vm1["VM"]
end
vm2 ~~~ hw1
Hình 4: Ở Type 2 hypervisor nằm trên hệ điều hành máy chủ, còn ở Type 1 Hyper-V thứ tự đảo ngược và chính hệ điều hành máy chủ nằm trên lớp thấp hơn một bậc.
Nhìn trên dòng thời gian boot, thay đổi xảy ra khi bạn bật nó trông như sau.
flowchart TB
accTitle: Thứ tự boot sau khi Hyper-V được bật
accDescr: Sau khi bật nguồn, hypervisor khởi động trước trong quá trình boot, rồi Windows máy chủ lên như phân vùng gốc trên đó, và các VM, VBS cùng những thứ tương tự khởi động sau
poweron["Bật nguồn và bắt đầu boot"] --> bhv["Hypervisor khởi động trước"]
bhv --> broot["Windows máy chủ khởi động như phân vùng gốc"]
broot --> blater["VM, VBS, WSL2 và tương tự khởi động trên đó"]
broot -.-> feel["Trải nghiệm người dùng không đổi"]
Hình 5: Việc đảo thứ tự đã xong trước khi màn hình đăng nhập xuất hiện, và hệ điều hành máy chủ lên trên hypervisor ngay từ đầu.
3. Phân vùng — Đơn vị cô lập
3.1. Những vai trò chỉ phân vùng gốc mới có
Phân vùng là đơn vị cô lập logic mà hypervisor cung cấp.2 Tuy nhiên không phải mọi phân vùng đều ngang nhau. Có những thứ chỉ phân vùng gốc mới có.
- Truy cập trực tiếp tới thiết bị vật lý. Driver thiết bị cho đĩa, NIC, GPU và tương tự sống trong Windows bên trong phân vùng gốc, không trong hypervisor. Hyper-V trên Windows Server có cấu hình gán một thiết bị PCIe cụ thể trực tiếp cho phân vùng con (Discrete Device Assignment); trong trường hợp đó phân vùng gốc buông thiết bị đó (cái này không có trên Windows client).4
- Ngăn xếp quản lý ảo hóa. VMMS (Virtual Machine Management Service), điều phối việc tạo, khởi động và dừng VM, cùng tiến trình worker theo từng VM (vmwp.exe) chạy ở chế độ user trong phân vùng gốc.5 Đây là một phần các tính năng quản lý VM của Hyper-V, nên chúng có thể vắng mặt trên máy chủ nơi chỉ hypervisor đang chạy vì VBS hoặc WSL2.
- Quyền tạo phân vùng con. Phân vùng gốc tạo phân vùng con qua API hypercall (giao diện gọi vào hypervisor).2
Thiết kế này có lý do. Nếu bạn nhét mọi driver thiết bị vào chính hypervisor, hypervisor phình to và số lỗi cùng điểm vào tấn công tăng. Hypervisor tự giới hạn ở công việc tối thiểu là làm trung gian CPU và bộ nhớ, và để việc chăm sóc thiết bị cho Windows trong phân vùng gốc. Sự phân vai này giữ Hyper-V mỏng.
flowchart TB
accTitle: Phân vai giữa phân vùng gốc và phân vùng con
accDescr: Phân vùng gốc giữ ngăn xếp quản lý ảo hóa và driver thiết bị vật lý rồi tạo phân vùng con qua hypercall; phân vùng con thường chỉ thấy thiết bị ảo, và dưới Discrete Device Assignment trên Windows Server nó truy cập trực tiếp thiết bị được gán
subgraph rootp ["Phân vùng gốc"]
vmms["VMMS và tiến trình worker"]
drv["Driver thiết bị vật lý"]
end
subgraph childp ["Phân vùng con"]
gos["Hệ điều hành khách"]
vdev["Ở cấu hình thường, chỉ thấy thiết bị ảo"]
end
vmms -->|Tạo và quản lý qua hypercall| childp
hv2["Hypervisor(tự giới hạn ở trung gian CPU và bộ nhớ)"] --- rootp
hv2 --- childp
Hình 6: Đặt driver thiết bị và ngăn xếp quản lý về phía phân vùng gốc chính là điều giữ bản thân hypervisor mỏng.
3.2. Thế giới nhìn từ một phân vùng con
Hệ điều hành khách trong phân vùng con không thể thấy phần cứng vật lý trực tiếp ở cấu hình thiết bị ảo thông thường (ngoại lệ duy nhất là thiết bị được gán qua Discrete Device Assignment trên Windows Server, như mục trước). Những gì nó thấy được là bộ xử lý ảo, một không gian bộ nhớ trông như của riêng nó, và các thiết bị ảo. Yêu cầu tới thiết bị ảo được chuyển tiếp tới phân vùng gốc qua VMBus hoặc hypervisor.2 Việc phân bổ thời gian CPU và dịch bộ nhớ qua SLAT, mặt khác, do hypervisor xử lý trực tiếp mà không đi qua phân vùng gốc. Thứ phân vùng gốc làm trung gian là I/O thiết bị, không phải mọi tài nguyên vật lý.
flowchart TB
accTitle: Thế giới nhìn từ một phân vùng con
accDescr: Hệ điều hành khách thấy bộ xử lý ảo, không gian bộ nhớ riêng của phân vùng, và thiết bị ảo; yêu cầu tới thiết bị ảo được chuyển tiếp tới phân vùng gốc qua VMBus và tương tự, thời gian CPU và dịch bộ nhớ do hypervisor xử lý trực tiếp, và ở cấu hình Discrete Device Assignment trên Windows Server chỉ các thiết bị được gán được truy cập trực tiếp
gos2["Hệ điều hành khách(con)"] --> vcpu["Bộ xử lý ảo"]
gos2 --> rest{"Bộ nhớ hay thiết bị?"}
rest --> gpa2["Không gian bộ nhớ riêng"]
rest --> vdev2["Thiết bị ảo"]
vdev2 --> rootx["Được chuyển tiếp tới gốc"]
rootx -.-> vbus["Qua VMBus và tương tự"]
gos2 -.-> phys2["CPU, RAM, thiết bị vật lý"]
phys2 -.-> hid["Không thấy trực tiếp"]
phys2 -.-> dda2["DDA: thiết bị được gán"]
dda2 -.-> ddaN["Windows Server"]
vcpu ~~~ phys2
Hình 7: Ở cấu hình thiết bị ảo thông thường mọi thứ khách thấy là cửa sổ ảo và đường tới phần vật lý đi qua trung gian; chỉ thiết bị được gán qua DDA trên Windows Server là ngoại lệ.
Điều quan trọng ở đây là với một ứng dụng chạy trên Windows máy chủ, cấu trúc này gần như trong suốt. Các lời gọi Win32 API và xử lý page fault vẫn được kernel Windows bên trong phân vùng gốc xử lý, như trước. Hypervisor chỉ can thiệp khi một intercept hoặc ngoại lệ đã cấu hình bị chạm.
4. Từ phía bộ nhớ — Dịch địa chỉ thêm một cấp
4.1. Ba loại địa chỉ
Ở Phần 1 của loạt bài bộ nhớ chúng ta đã lần theo luồng một địa chỉ ảo được dịch qua bảng trang thành địa chỉ vật lý (“Khoảnh khắc một địa chỉ ảo trở thành RAM vật lý”). Trong môi trường ảo hóa thêm một cấp nữa dưới lần dịch đó, và có ba loại địa chỉ.
| Địa chỉ | Viết tắt | Ai quản lý |
|---|---|---|
| Địa chỉ ảo của khách | GVA | Bảng trang của hệ điều hành khách |
| Địa chỉ vật lý của khách | GPA | Địa chỉ mà hệ điều hành khách tin là “vật lý” |
| Địa chỉ vật lý hệ thống | SPA | Hypervisor (vị trí thật trong RAM) |
Hệ điều hành khách dịch GVA thành GPA bằng bảng trang của riêng nó. Tuy nhiên GPA mà khách thấy không phải địa chỉ vật lý thật; đó là không gian bộ nhớ riêng dành cho từng phân vùng.2 Ánh xạ GPA lên vị trí thật trong RAM (SPA) là việc của hypervisor.
4.2. SLAT — Dịch hai cấp bằng phần cứng
Nếu bạn làm lần dịch cấp hai này chỉ bằng phần mềm, hypervisor phải theo dõi từng lần cập nhật bảng trang của khách từng cái một, điều không thực tế về hiệu năng. Vì thế CPU cung cấp cơ chế đi bộ các bảng dịch cấp hai bằng phần cứng. Đó là SLAT (Second Level Address Translation); Intel EPT (Extended Page Tables) và AMD RVI là các triển khai. Hyper-V hiện tại yêu cầu bộ xử lý 64-bit có SLAT.4
flowchart TB
accTitle: Dịch địa chỉ hai cấp qua SLAT
accDescr: Địa chỉ ảo của khách được dịch thành địa chỉ vật lý của khách bởi bảng trang hệ điều hành khách, rồi được dịch tiếp thành địa chỉ vật lý hệ thống bởi SLAT mà hypervisor quản lý, và tới RAM thật
gva["Địa chỉ ảo của khách(GVA)"] -->|Bảng trang hệ điều hành khách| gpa["Địa chỉ vật lý của khách(GPA)"]
gpa -->|"SLAT(bảng dịch EPT/RVI)"| spa["Địa chỉ vật lý hệ thống(SPA)"]
spa --> ram["RAM vật lý"]
gpa -.-> note["Một lớp mà khách chỉ tin là vật lý"]
Hình 8: Một bảng dịch khác, do hypervisor quản lý, nằm dưới bảng trang của khách, và CPU đi bộ cả hai bằng phần cứng.
SLAT không phải tính năng chỉ tồn tại vì hiệu quả chạy VM. VBS chúng ta sẽ thấy ở Phần 2 dùng thuộc tính “bạn có thể có một bảng dịch SLAT khác nhau theo từng mức đặc quyền” làm chất liệu cho một ranh giới bảo mật. Lý do bạn có thể tạo bộ nhớ mà ngay cả kernel cũng không thấy được là hypervisor giữ lần dịch cấp hai này. Đây trở thành sợi chỉ xuyên suốt cả loạt, nên chỉ cần nhớ một điểm: “chủ sở hữu các bảng dịch là hypervisor”.
5. Từ phía I/O thiết bị — VMBus và hai loại thiết bị
5.1. Giới hạn của thiết bị mô phỏng
Cách cổ điển để hiện một thiết bị cho phân vùng con là bắt chước đầy đủ phần cứng thật (ví dụ bộ điều khiển IDE cũ) bằng phần mềm. Tính tương thích cao vì các driver inbox của hệ điều hành khách hoạt động nguyên như vậy, nhưng một VM Exit xảy ra mỗi lần khách chạm cổng I/O, và hiệu năng không mở rộng được.
flowchart TB
accTitle: Vì sao I/O tới thiết bị mô phỏng chậm
accDescr: Mỗi lần khách thao tác cổng I/O, quyền điều khiển chuyển sang phía hypervisor qua VM Exit, thiết bị được bắt chước bằng phần mềm, rồi khách được trả về, nên vòng khứ hồi lặp lại và chậm
gio["Khách thao tác cổng I/O"] --> vex["Một VM Exit xảy ra"]
vex --> emu2["Thiết bị được mô phỏng bằng phần mềm"]
emu2 --> back["Trở về khách qua VM Entry"]
back -->|Lặp ở thao tác cổng tiếp| gio
Hình 9: Vòng khứ hồi này chạy nhiều lần phía sau một lần truy cập đĩa, và cái giá của tính tương thích được trả bằng hiệu năng.
5.2. VMBus và VSP/VSC — Đường nhanh được thiết kế cho ảo hóa
Vì thế Hyper-V có cơ chế “thiết bị tổng hợp” được thiết kế với giả định ảo hóa. Có ba nhân vật.2
- VMBus: kênh giao tiếp logic giữa các phân vùng. Nó cung cấp giao tiếp liên phân vùng tốc độ cao dùng bộ nhớ dùng chung.3
- VSP (Virtualization Service Provider): một dịch vụ nằm phía phân vùng gốc, nhận yêu cầu thiết bị từ phía con, và cầu nối chúng tới ngăn xếp thiết bị/backend phía gốc. Một yêu cầu có thể tới thiết bị vật lý, hoặc được xử lý bởi backend phía máy chủ như đĩa ảo hoặc chuyển mạch ảo.
- VSC (Virtualization Service Consumer): một driver thiết bị tổng hợp đi vào hệ điều hành khách phía phân vùng con. Nó gửi yêu cầu tới VSP qua VMBus.
Lấy yêu cầu lưu trữ của hệ điều hành khách làm ví dụ, luồng trông như sau. WriteFile của ứng dụng khách đi xuống ngăn xếp I/O của kernel khách và, ở đáy, tới VSC (thay vì phần cứng thật). VSC đặt yêu cầu lên VMBus và trao nó cho VSP trong phân vùng gốc, rồi VSP chảy yêu cầu vào ngăn xếp I/O phía gốc. Ở cấu hình đĩa ảo (VHDX), lần ghi này được xử lý như ghi vào tệp VHDX trên máy chủ và cuối cùng tới đĩa vật lý. Cách tiếp cận này gọi là Enlightened I/O (I/O nhận thức ảo hóa), và nó nâng hiệu quả bằng cách bỏ qua lớp mô phỏng thiết bị.2
flowchart TB
accTitle: Đường I/O của thiết bị tổng hợp
accDescr: Yêu cầu I/O từ ứng dụng trong phân vùng con tới VSC qua kernel khách, vượt VMBus tới VSP trong phân vùng gốc, và trên ngăn xếp I/O phía gốc mà VSP cầu nối vào nó có thể tới thiết bị thật qua driver thiết bị vật lý, hoặc được xử lý bởi backend phía máy chủ như đĩa ảo hay chuyển mạch ảo
app["Ứng dụng trong phân vùng con"] --> gk["Ngăn xếp I/O kernel khách"]
gk --> vsc["VSC(driver thiết bị tổng hợp)"]
vsc -->|VMBus| vsp["VSP(phía phân vùng gốc)"]
vsp --> rio["Ngăn xếp I/O phía gốc"]
rio --> pdrv["Driver thiết bị vật lý"]
rio --> hb["Backend phía máy chủ(đĩa ảo, chuyển mạch ảo, v.v.)"]
pdrv --> dev["Thiết bị vật lý"]
Hình 10: Với thiết bị tổng hợp, I/O của khách vượt sang phân vùng gốc qua VMBus và, qua ngăn xếp phía gốc, tới thiết bị thật hoặc backend phía máy chủ.
Nói cách khác, I/O đĩa hay mạng của một VM có nhanh hay không không chỉ phụ thuộc phía khách mà còn phụ thuộc trạng thái của ngăn xếp I/O và driver thiết bị phía phân vùng gốc. Lý do quan sát phía máy chủ là không thể thiếu khi bạn điều tra vấn đề hiệu năng VM là vì đường đi thực sự đi qua máy chủ.
flowchart TB
accTitle: Thiết bị mô phỏng đối với thiết bị tổng hợp
accDescr: Thiết bị mô phỏng bắt chước phần cứng thật để driver inbox của khách hoạt động nhưng chậm; thiết bị tổng hợp là driver được xây riêng với giả định VMBus và nhanh
dev2{"Thiết bị hiện cho phân vùng con"} --> emu["Thiết bị mô phỏng"]
dev2 --> syn["Thiết bị tổng hợp"]
emu -.-> emuP["Mô phỏng phần cứng thật; tương thích trước"]
emuP -.-> emuC["Cần can thiệp mỗi I/O; chậm"]
syn -.-> synP["Thiết kế quanh VMBus; nhanh"]
synP -.-> synC["Cần driver khớp ở phía khách"]
Hình 11: Trong hai loại thiết bị ảo, thiết bị mô phỏng mang tính tương thích ngay sau khi cài hệ điều hành, và thiết bị tổng hợp mang hiệu năng trong dùng hàng ngày.
6. Vì sao đây không phải chuyện của người khác, dù bạn không bao giờ dùng VM
Cấu trúc đến đây có thể trông như “câu chuyện dành cho người dựng VM”. Như phần mở đầu đã nói, trên Windows hiện tại hypervisor là một phần đời thường.
- Bảo mật dựa trên ảo hóa (VBS). Nó dùng hypervisor Windows để tạo môi trường cô lập và đặt các tính năng bảo mật vào đó. Trên Windows 11 nó được bật mặc định khi các điều kiện như cài sạch trên phần cứng tương thích được đáp ứng.1 Chi tiết ở Phần 2.
- WSL2. Nó chạy một kernel Linux thật bên trong một VM tiện ích nhẹ.6
- Windows Sandbox. Một môi trường Windows dùng một lần được cô lập bởi hypervisor.7 Cả hai được đề cập ở Phần 3.
flowchart TB
accTitle: Các tính năng đời thường ngồi trên cùng hypervisor
accDescr: Không chỉ VM Hyper-V mà cả VBS, được bật mặc định trên thiết bị đáp ứng điều kiện như cài sạch, cùng WSL2 và Windows Sandbox, đều được xây trên cùng hypervisor Windows
base["Hypervisor Windows"] --> f1["VM Hyper-V"]
base --> f2["VBS(bật mặc định trên cài sạch và tương tự)"]
base --> f3["WSL2"]
base --> f4["Windows Sandbox"]
f2 -.-> daily["Vì sao nó chạy cả trên PC không bao giờ dùng VM"]
Hình 12: Có một nền tảng duy nhất, và đây là chỗ giả định “ảo hóa là chuyện của người dùng VM” sụp đổ.
Một việc nữa người ta thường dẫm phải trong thực tế là sự cùng tồn tại với phần mềm ảo hóa bên thứ ba. Vì hypervisor dùng độc quyền các phần mở rộng ảo hóa của CPU, trong môi trường hypervisor Windows đang chạy, VirtualBox và tương tự không thể chạy theo cách truyền thống (cách tự dùng các phần mở rộng ảo hóa của CPU). Với việc này, một API công khai gọi là Windows Hypervisor Platform được cung cấp, và một ngăn xếp ảo hóa bên thứ ba có thể chạy bằng cách ngồi trên hypervisor Windows.8 VirtualBox/VMware hiện tại có thể cùng tồn tại với WSL2 nhờ cơ chế này, nhưng các khác biệt hiệu năng và tính năng đi kèm việc đổi chế độ đôi khi được quan sát như “sau khi tôi bật Hyper-V (hoặc VBS), phần mềm ảo hóa bắt đầu hành xử khác”.
flowchart TB
accTitle: Ai sở hữu các phần mở rộng ảo hóa CPU, và đường cho phần mềm ảo hóa bên thứ ba
accDescr: Trong khi hypervisor Windows đang chạy nó sở hữu độc quyền các phần mở rộng ảo hóa CPU; phần mềm ảo hóa bên thứ ba hỗ trợ WHP chạy trên đó qua Windows Hypervisor Platform, còn các triển khai không hỗ trợ WHP không chạy được hoặc bị hạn chế tính năng
vt["Phần mở rộng ảo hóa CPU(VT-x/AMD-V)"] --> hvon{"Hypervisor Windows đang chạy?"}
hvon -->|Không| direct["Phần mềm bên thứ ba dùng trực tiếp được"]
hvon -->|Có| own["Hypervisor dùng độc quyền"]
own --> whp["Windows Hypervisor Platform"]
whp --> third["Phần mềm bên thứ ba hỗ trợ WHP chạy trên đó"]
third -.-> nowhp["Triển khai không hỗ trợ không chạy, hoặc bị hạn chế"]
Hình 13: Có một chủ sở hữu duy nhất của các phần mở rộng ảo hóa, và phần mềm bên thứ ba duy nhất có thể cùng tồn tại khi hypervisor đang chạy là phần mềm hỗ trợ API công khai (WHP).
7. Tự xem trên máy của bạn
Bạn có thể xác nhận trên máy mình liệu hypervisor có đang chạy.
Trước hết, một kiểm tra bạn có thể chạy mà không cần đặc quyền quản trị.
# 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 trả về trạng thái chạy của VBS dưới dạng số (2 là “Running”).9
Một lưu ý. Tất cả những gì HypervisorPresent nói với bạn là “liệu chúng ta có đang chạy trên một hypervisor”; nó không phân biệt gốc với con. Nếu bạn chạy nó trên Windows bên trong một VM, nó vẫn trả về True, như một phân vùng con. Nếu nó là True trên Windows trên PC vật lý, Windows đó đang ở trong phân vùng gốc — bạn đọc nó cùng với môi trường thực thi.
Tiếp theo, cách cổ điển từ Command Prompt.
systeminfo
Nhìn “Hyper-V Requirements” ở cuối đầu ra. Trên máy hypervisor chưa chạy, các yêu cầu riêng — hỗ trợ SLAT, liệu phần mở rộng ảo hóa có được bật, v.v. — được liệt kê. Trên máy hypervisor đã chạy, thay vì các yêu cầu bạn nhận một dòng duy nhất: “A hypervisor has been detected. Features required for Hyper-V will not be displayed.”4 Dòng đó vì thế là tuyên bố rằng Windows của bạn đang chạy trên một hypervisor nào đó. Như với HypervisorPresent, bạn cần đọc nó là “bên trong phân vùng gốc” trên PC vật lý, hoặc “như phân vùng con” bên trong một VM.
Dù mọi yêu cầu systeminfo đều là “Yes”, điều đó chỉ nghĩa phía phần cứng đã sẵn. Bản thân tính năng Hyper-V có trên các phiên bản Pro, Enterprise và Education, và không có trên Home.10
Trong GUI, kiểm tra hàng “Virtualization-based security” dưới “System Summary” trong msinfo32. Lưu ý rằng “Virtualization: Enabled” ở ngăn CPU của Task Manager chỉ cho biết liệu các phần mở rộng ảo hóa có được bật trong firmware, đó là thông tin tách biệt với việc hypervisor có đang chạy.
flowchart TB
accTitle: Cách kiểm tra hypervisor có đang chạy
accDescr: Nếu systeminfo nói một hypervisor đã được phát hiện thì bạn đang chạy trên hypervisor(bên trong phân vùng gốc trên PC vật lý); nếu danh sách Hyper-V Requirements xuất hiện thì chưa chạy nên bạn kiểm tra từng yêu cầu như SLAT, VM Monitor Mode Extensions và DEP, nhưng tất cả Yes chỉ nghĩa phía phần cứng đã sẵn và tính năng Hyper-V còn có yêu cầu phiên bản
start2["Chạy systeminfo"] --> q1{"Trường yêu cầu?"}
q1 -->|Detected| running["Hypervisor đang chạy"]
running -.-> runN["Bên trong gốc"]
runN -.-> runN2["trên PC vật lý"]
q1 -->|Listed| notyet["Chưa chạy"]
notyet --> q2{"Mọi yêu cầu đều Yes?"}
q2 -->|Tất cả Yes| can["Phía phần cứng đã sẵn"]
can -.-> ed["Cần Pro / Ent / Edu"]
q2 -->|Một số No| uefi["Kiểm tra mục UEFI/BIOS"]
Hình 14: Trường “Hyper-V Requirements” trong systeminfo kiêm cả kiểm tra trạng thái chạy và kiểm tra điều kiện tiên quyết.
8. Ba cách đọc sai cần tránh trong thực tế
8.1. “Chúng tôi chưa bật Hyper-V, nên ảo hóa chẳng liên quan tới các PC của chúng tôi”
Dù bạn chưa bật tính năng Hyper-V (các công cụ quản lý và môi trường chạy VM), hypervisor Windows vẫn chạy nếu VBS được bật. Khi bạn điều tra vấn đề tương thích driver, bài kiểm tra hiệu năng, hoặc sự cố với phần mềm ảo hóa bên thứ ba, hãy kiểm tra HypervisorPresent và trạng thái chạy của VBS — không phải việc tính năng có được bật.
8.2. “Task Manager nói ‘Virtualization: Enabled’, nên Hyper-V đang chạy”
Hiển thị đó là về thiết lập firmware (liệu VT-x/AMD-V có sẵn). Hãy phán trạng thái chạy của hypervisor từ “A hypervisor has been detected” trong systeminfo. Ngược lại, nếu Task Manager nói “Disabled”, bạn cũng không thể bật Hyper-V hay WSL2, nên hãy kiểm tra thiết lập UEFI/BIOS trước.
flowchart TB
accTitle: Ba kiểm tra dễ bị nhầm
accDescr: Trường Virtualization của Task Manager cho thấy thiết lập firmware, danh sách Windows Features cho thấy trạng thái cài, và systeminfo hoặc HypervisorPresent cho thấy trạng thái chạy; mỗi cái trả lời một câu hỏi khác
q3{"Câu hỏi nào?"}
q3 --> fw{"Firmware hay Windows?"}
q3 --> c3["Hypervisor đang chạy?"]
fw --> a3["Phần mở rộng firmware?"]
fw --> b3["Tính năng Hyper-V bật?"]
a3 -.-> a3t["Ngăn CPU Task Manager"]
b3 -.-> b3t["Giao diện Windows Features"]
c3 -.-> c3t["systeminfo"]
c3 -.-> c3tp["HypervisorPresent"]
Hình 15: Đây là ba câu hỏi độc lập, và suy ra hai cái kia từ bất kỳ một hiển thị nào là cách đọc sai.
8.3. “Nếu VM chậm, đó là vấn đề hệ điều hành khách”
I/O của thiết bị tổng hợp vượt VMBus tới VSP trong phân vùng gốc và đi qua ngăn xếp thiết bị/backend phía gốc (driver vật lý, cộng xử lý chuyển mạch ảo và đĩa ảo). Nếu bạn chỉ xem bộ đếm bên trong khách, bạn sẽ không tìm thấy nút thắt nằm ở lưu trữ phía máy chủ hoặc một NIC. Nguyên tắc với vấn đề hiệu năng VM là quan sát từ cả hai phía: khách và máy chủ (phân vùng gốc).
9. Tóm tắt
- Khi bạn bật Hyper-V, hypervisor chạy trực tiếp trên phần cứng và Windows máy chủ chạy như phân vùng gốc.2
- Kernel của hệ điều hành khách tiếp tục chạy ở ring 0, và chỉ các thao tác được cấu hình là intercept, cộng các ngoại lệ, được trao cho hypervisor qua VM Exit. Các truy cập bộ nhớ thông thường đi qua nhờ dịch SLAT.
- Chỉ phân vùng gốc giữ driver thiết bị vật lý và ngăn xếp quản lý ảo hóa, và nó tạo phân vùng con qua hypercall.2
- Bộ nhớ trở thành dịch hai cấp GVA→GPA→SPA, và cấp hai được xử lý bằng phần cứng bởi SLAT (EPT/RVI). Hyper-V hiện tại yêu cầu SLAT.4
- I/O thiết bị bị chi phối bởi đường thiết bị tổng hợp VSC→VMBus→VSP, và hiệu năng cũng phụ thuộc ngăn xếp I/O phía máy chủ.2
- Trên Windows 11, vì VBS được bật mặc định trên các thiết bị đáp ứng điều kiện như cài sạch, việc hypervisor chạy ngay cả trên PC không bao giờ dùng VM không phải chuyện lạ.1 Bạn có thể xác nhận trạng thái chạy bằng
HypervisorPresentvà systeminfo.
Bức tranh lớn của Phần 1 cô đọng vào sơ đồ duy nhất này.
flowchart TB
accTitle: Bức tranh lớn của Phần 1
accDescr: Hypervisor nằm dưới phân vùng gốc và phân vùng con; CPU được phân bổ bằng lập lịch bộ xử lý ảo(VM Exit chỉ khi intercept và ngoại lệ đã cấu hình), bộ nhớ được làm trung gian bởi dịch SLAT hai cấp, I/O thiết bị tổng hợp được chuyển tiếp qua VMBus và xử lý bởi VSP của phân vùng gốc, còn thiết bị mô phỏng và Discrete Device Assignment có đường khác
up["Phân vùng gốc + con"] --> hvS["Hypervisor"]
hvS --> cpuS["CPU: lập lịch VP"]
hvS --> memS["Bộ nhớ: SLAT"]
cpuS -.-> cpuN["VM Exit khi intercept"]
memS -.-> memN["Dịch hai cấp"]
memS ~~~ devS
devS["Thiết bị: I/O VMBus"] --> vspS["VSP phía gốc xử lý"]
devS -.-> devN["Mô phỏng / DDA: đường khác"]
Hình 16: Lập lịch CPU và dịch bộ nhớ do hypervisor xử lý trực tiếp (VM Exit chỉ khi can thiệp), và I/O thiết bị tổng hợp được phân vùng gốc (VSP) làm trung gian phía kia của VMBus.
Tiếp theo ở Phần 2, “Bộ nhớ ngay cả kernel cũng không thấy — VBS, HVCI và Credential Guard“.
Chúng ta nhặt sợi chỉ xuyên suốt của bài này — rằng hypervisor giữ các bảng dịch SLAT — và lần theo cách Windows tạo “bộ nhớ mà cả quản trị viên lẫn kernel đều không đọc được”.
Bài viết liên quan
- Chiều sâu bộ nhớ Windows (Phần 1) — Khoảnh khắc một địa chỉ ảo trở thành RAM vật lý: Page fault từ đầu tới cuối
- “Mức dùng bộ nhớ” của Windows thực sự nghĩa là gì? — Đọc đúng Working Set, Private Bytes, Commit và Page File
- Cách tăng tốc xác thực ứng dụng bằng Windows Sandbox
- Thiết lập lập lịch bộ xử lý Windows - Dịch vụ nền và nhân P/E
Lĩnh vực tư vấn liên quan
KomuraSoft LLC đảm nhận thiết kế môi trường xác thực cho ứng dụng Windows, điều tra hiệu năng trong môi trường ảo hóa, và phân tích vấn đề tương thích của driver cùng thiết bị ngoại vi.
- Phát triển ứng dụng Windows
- Điều tra lỗi và phân tích nguyên nhân gốc rễ
- Tái sử dụng và di chuyển tài sản hiện có
- Liên hệ với chúng tôi
Liên kết tham khảo
-
Microsoft Learn, Silicon assisted security. Về việc VBS dùng ảo hóa phần cứng để cô lập Secure Kernel khỏi hệ điều hành thông thường, và về việc VBS cùng HVCI được bật mặc định trên các thiết bị đáp ứng điều kiện tiên quyết khi cài mới Windows 11. ↩ ↩2 ↩3
-
Microsoft Learn, Hyper-V Architecture. Về việc hypervisor cung cấp phân vùng như đơn vị cô lập; phân vùng gốc tạo phân vùng con qua API hypercall; các phân vùng chạy trong không gian bộ nhớ ảo riêng mà không truy cập trực tiếp bộ xử lý vật lý; vai trò của VMBus, VSP, VSC và Enlightened I/O; và việc các phần mở rộng ảo hóa phần cứng (Intel VT/AMD-V) là bắt buộc. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9 ↩10 ↩11 ↩12
-
Microsoft Learn, Hyper-V architecture (Performance Tuning). Về việc Hyper-V là hypervisor Type 1, phân vùng gốc sở hữu các thiết bị I/O vật lý, và VMBus cung cấp giao tiếp liên phân vùng hiệu năng cao dùng bộ nhớ dùng chung. ↩ ↩2
-
Microsoft Learn, System requirements for Hyper-V on Windows and Windows Server. Về việc bộ xử lý 64-bit có SLAT và VM Monitor Mode Extensions là bắt buộc; khả năng xác nhận các yêu cầu được đáp ứng trong trường “Hyper-V Requirements” của systeminfo; “A hypervisor has been detected” được hiển thị khi hypervisor đang chạy; và Discrete Device Assignment có thể gán một thiết bị cụ thể trực tiếp cho phân vùng con. ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, Appendix B: Hyper-V Architecture and Feature Overview. Về việc VMMS (Virtual Machine Management Service) quản lý trạng thái các VM trong phân vùng con, và một tiến trình worker (VMWP) khởi động ở chế độ user trong phân vùng gốc cho mỗi VM. ↩
-
Microsoft Learn, Comparing WSL Versions. Về việc WSL2 chạy một kernel Linux thật bên trong một VM tiện ích nhẹ, và về các lưu ý khi dùng cùng VMware và VirtualBox hiện tại. ↩
-
Microsoft Learn, Windows Sandbox architecture. Về việc Windows Sandbox là môi trường Windows nhẹ kết hợp công nghệ container với cô lập bởi hypervisor. ↩
-
Microsoft Learn, Windows Hypervisor Platform. Về việc một API chế độ user được cung cấp để ngăn xếp ảo hóa bên thứ ba có thể tạo và quản lý phân vùng trên hypervisor Windows. ↩
-
Microsoft Learn, Enable Hotpatch for Azure Arc-enabled servers. Về việc có thể xác nhận trạng thái chạy của VBS (virtual secure mode) qua VirtualizationBasedSecurityStatus trên lớp Win32_DeviceGuard. ↩
-
Microsoft Learn, Install Hyper-V. Về việc Hyper-V có thể bật trên Windows 10/11 Pro hoặc Enterprise và tương tự, và không cài được trên phiên bản Home. ↩
Bài viết liên quan
Các bài viết gần đây có cùng thẻ để tìm hiểu sâu hơn những chủ đề lân cận.
Bên trong ảo hóa Windows (Phần 3) — Máy ảo khởi động trong vài giây: Vì sao WSL2, Windows Sandbox và container lại nhẹ
Vì sao WSL2 và Windows Sandbox khởi động trong vài giây và cảm giác nhẹ đến vậy? Bài viết này giải thích các cơ chế, từ ảnh cơ sở động và...
Bên trong ảo hóa Windows (Phần 2) — Bộ nhớ ngay cả kernel cũng không thấy: VBS, HVCI và Credential Guard
Khi cài sạch trên phần cứng tương thích, VBS được bật mặc định và dùng hypervisor cùng SLAT để tạo cô lập mạnh hơn kernel. Bài viết này g...
API thread pool Win32 — Đồng thời mà không tạo luồng, với CreateThreadpoolWork
Bạn đang rải các lời gọi CreateThread khắp mã native? Bài viết này giải thích API thread pool Win32 được thiết kế lại từ Vista — bốn đối ...
Named pipe trong thực tiễn — IPC chuẩn của Windows, từ thiết kế đến bảo mật
Hướng dẫn thực tiễn về named pipe, cơ chế giao tiếp giữa các tiến trình chuẩn của Windows. Bài viết sắp xếp, từ nguồn gốc, việc chọn giữa...
Giúp website xuất hiện khi khách tìm theo tên khu vực — Hướng dẫn Local SEO thực tiễn cho doanh nghiệp vừa và nhỏ (trang khu vực và Google Business Profile)
Dành cho các doanh nghiệp vừa và nhỏ có website không xuất hiện khi ai đó tìm kiếm "tên khu vực + ngành nghề". Bài viết này trình bày thứ...
Chủ đề liên quan
Các trang này đặt chủ đề trong bối cảnh rộng hơn của dịch vụ và quyết định.
Chủ đề kỹ thuật Windows
Cổng vào phát triển Windows, điều tra lỗi và khai thác tài sản hiện có.
Dịch vụ liên quan đến chủ đề này
Bài viết liên quan trực tiếp đến các dịch vụ sau.
Phát triển ứng dụng Windows
Ứng dụng nghiệp vụ, tích hợp thiết bị và công cụ liên lạc, từ yêu cầu đến phát triển.
Câu hỏi thường gặp
Các câu hỏi thường gặp khi tư vấn về chủ đề của bài viết.
- Khi bạn bật Hyper-V, Windows máy chủ thực sự chạy ở đâu?
- Hypervisor nắm trực tiếp việc phân bổ CPU vật lý và bộ nhớ, và Windows máy chủ chạy bên trong một phân vùng đặc biệt gọi là phân vùng gốc. Việc điều khiển thiết bị vật lý thường do các driver phía phân vùng gốc đảm nhận. Phân vùng gốc giữ các driver thiết bị và ngăn xếp quản lý ảo hóa, nhưng quyền sở hữu CPU vật lý thuộc về hypervisor.
- "Ảo hóa: Đã bật" trên Task Manager có nghĩa Hyper-V đang chạy không?
- Không. Hiển thị đó cho biết các phần mở rộng ảo hóa của CPU (Intel VT-x/AMD-V) có được bật trong firmware hay không. Để xem hypervisor có thực sự đang chạy, hãy tìm "A hypervisor has been detected" trong systeminfo, hoặc kiểm tra Win32_ComputerSystem.HypervisorPresent.
- Vì sao hypervisor vẫn chạy dù tôi chưa bao giờ tạo VM?
- Trên Windows 11, bảo mật dựa trên ảo hóa (VBS) được bật mặc định trên các thiết bị đáp ứng điều kiện — ví dụ cài sạch trên phần cứng tương thích — và VBS được xây trên hypervisor Windows. Điều tương tự cũng đúng nếu bạn dùng WSL2 hoặc Windows Sandbox. Việc hypervisor chạy mà không liên quan tới ai đó dùng VM không phải chuyện lạ.
- SLAT là gì, và vì sao Hyper-V yêu cầu nó?
- SLAT (Second Level Address Translation) là cơ chế CPU dịch địa chỉ vật lý của khách thành địa chỉ vật lý thật; Intel EPT và AMD RVI là các triển khai. Không có nó thì hypervisor phải duy trì bảng dịch bằng phần mềm, điều không thực tế về hiệu năng, nên Hyper-V hiện tại coi đó là yêu cầu cứng.
- Nếu tôi bật Hyper-V, VirtualBox và VMware có ngừng hoạt động không?
- Vì hypervisor dùng độc quyền các phần mở rộng ảo hóa của CPU, một hypervisor bên thứ ba không thể chạy theo cách truyền thống. Tuy nhiên VirtualBox và VMware hiện tại có chế độ chạy trên hypervisor Windows (qua Windows Hypervisor Platform), nên các phiên bản gần đây của mỗi bên có thể cùng tồn tại.