Windows 11에서 시스템 정보(msinfo32)를 열면, VM을 만든 적 없는 머신에서도 「가상화 기반 보안」란에 「실행 중」이 자주 보입니다.
그게 의미하는 사실은 이것입니다. 그 PC에서 호스트 Windows 자체는 이미 하이퍼바이저 위에서 움직이고 있습니다. 「가상화」는 더 이상 Hyper-V 관리자에서 VM을 만드는 사람만의 기술이 아닙니다. Windows 11에서는 가상화 기반 보안(VBS)이, 예를 들어 호환 하드웨어에 대한 클린 설치처럼 조건을 충족하는 구성에서 기본으로 켜지고1, WSL2와 Windows Sandbox도 같은 Windows 하이퍼바이저 위에 만들어집니다. 매일 쓰는 Windows 아래에는, 이미 소프트웨어 층이 하나 더 있습니다.
이 연재 「Windows 가상화의 심층」은 그 층에서 일어나는 일을, 토대부터 따라갑니다.
「Windows 가상화의 심층」── 전 3회
- 제1회(본 글): 하이퍼바이저와 파티션
Hyper-V를 켰을 때 호스트 Windows가 어디서 움직이게 되는지를 따라갑니다. - 제2회: 커널에서도 보이지 않는 메모리 ── VBS, HVCI, Credential Guard
관리자도 커널도 읽을 수 없는 비밀을 Windows가 어디에 두는지를 따라갑니다. - 제3회: 수초 만에 기동하는 가상 머신 ── WSL2, Windows Sandbox, 컨테이너
풀 VM은 무거운데 WSL2와 Sandbox가 가벼운 이유를, 메모리와 이미지의 공유 방식에서 따라갑니다.
제1회가 답하는 질문은 하나뿐입니다.
Hyper-V를 켜면 호스트 Windows는 어디서 움직이게 되는가?
대상 독자는 Hyper-V, WSL2, Windows Sandbox를 쓰면서, 그 아래에서 무엇이 도는지 구조부터 이해하고 싶은 개발자와 운용자입니다. 전제 환경은 x64 Windows 10/11 또는 현행 Windows Server입니다(이 글의 링, VT-x/AMD-V, EPT/RVI 논의는 x64를 가정합니다. Arm64는 예외 수준 등 다른 장치를 씁니다). 필요한 배경은 커널 모드와 사용자 모드의 구분 정도이며, VM 조작 경험이나 하이퍼바이저 개발 지식은 필요 없습니다. 난이도는 중급입니다. CPU 가상화 확장의 개념은 다루지만, 명령 집합의 세부는 들어가지 않습니다.
1. 먼저 결론
Hyper-V라고 하면 「Windows 위에 앉는 VM 실행 소프트웨어」를 떠올릴 수 있습니다. 실제 구조는 반대입니다.
Hyper-V를 켜고 재부팅한 순간부터, 물리 CPU와 메모리를 제어하는 것은 하이퍼바이저이고, 호스트 Windows는 그 위에서 첫 번째 특권 파티션──「루트 파티션」──으로 움직입니다.
하이퍼바이저는 하드웨어와 OS 사이에 앉는 얇은 소프트웨어 층으로, 「파티션」이라는 격리된 실행 환경을 만들고 하드웨어 접근을 중개합니다.2 호스트 Windows가 들어가는 곳이 루트 파티션이고, VM이 들어가는 곳이 자식 파티션입니다. 루트 파티션은 특별 취급을 받지만(물리 디바이스에 직접 접근하고 관리 스택을 갖습니다), 물리 CPU를 직접 제어하지 않는다는 점에서는 자식 파티션과 같은 자리에 있습니다.
flowchart TB
accTitle: Hyper-V를 켠 뒤의 전체 구조
accDescr: 하이퍼바이저가 물리 하드웨어 바로 위에 앉고, 그 위에 호스트 Windows를 담는 루트 파티션과 VM을 담는 자식 파티션이 앉는다
hw["물리 하드웨어"] --> hv["하이퍼바이저"]
hv --> root["루트 파티션(호스트 Windows)"]
hv --> child1["자식 파티션(VM)"]
root -.-> stack["가상화 관리 스택과 디바이스 드라이버를 보유"]
그림 1: Hyper-V는 「Windows 위의 VM 소프트웨어」가 아니라 Windows 아래로 들어가는 층이며, 호스트 OS 자체는 루트 파티션 안에서 움직인다.
「켜도 느낌이 다르지 않은데, 그런 큰 역전이 정말 일어났나?」라고 생각할 수 있습니다. 일어났습니다. 바로 그래서 이 구조는 보통 눈에 띄지 않습니다. 이 글에서는 이 한 장의 그림을 CPU, 메모리, 디바이스 I/O라는 세 축으로 분해합니다.
2. CPU부터 ── 링 아래에 특권이 하나 더
2.1. 링 보호의 복습
x64 CPU에는 특권 수준(링)이 있고, Windows는 커널 모드를 링 0, 사용자 모드를 링 3에서 돌립니다. 애플리케이션이 하드웨어를 직접 만질 수 없는 것은, 특권 명령을 링 3에서 실행할 수 없기 때문입니다.
그렇다면 각각 링 0에서 도는 OS 커널을 같은 물리 CPU에 어떻게 안전하게 넣을까요? 모든 커널은 「내가 CPU를 제어한다」는 가정으로 쓰여 있습니다. 모두에게 링 0을 주면 충돌하고, 주지 않으면 돌지 않습니다.
flowchart TB
accTitle: 여러 OS 커널이 링 0을 요구하는 문제
accDescr: 호스트와 게스트 커널 모두 링 0의 전권을 가정하고 쓰여 있어, 전통적인 링 사다리만으로는 같은 물리 CPU에 안전하게 넣을 수 없다
k1["호스트 커널(링 0을 가정)"] --> want["물리 CPU의 제어를 요구"]
k2["게스트 커널(링 0을 가정)"] --> want
want --> conflict["전통적인 링으로는 화해할 수 없다"]
conflict --> need["링 0 위의 중개자가 필요하다"]
그림 2: 링 사다리는 단일 OS를 가정하고 만들어졌으므로, 여러 커널을 넣으려면 그 위에 특권이 하나 더 필요하다.
2.2. 가상화 확장 ── 하이퍼바이저 전용 모드
이 문제를 푸는 것이 CPU의 가상화 확장(Intel VT-x/AMD-V)입니다. Hyper-V는 이 기능을 가진 프로세서를 요구합니다.2 가상화 확장은 전통적인 링과 다른 축에, 「하이퍼바이저용 실행 모드」와 「게스트용 실행 모드」를 더합니다. 링 0보다도 강한 특권이며, 가끔 「링 -1」이라는 별명으로 불립니다.
- 게스트 커널은 예전처럼 링 0에서 계속 돕니다. 다시 쓸 필요는 없습니다.
- 다만 그 링 0은 「게스트 모드 안의 링 0」이며, 물리 CPU 전체를 제어하지 않습니다.
- 게스트가 하이퍼바이저 개입이 필요한 특정 작업(인터셉트로 설정된 명령, 또는 예외나 위반)에 닿으면, CPU는 자동으로 제어를 하이퍼바이저에 넘깁니다(VM Exit). 하이퍼바이저가 처리를 마치면 게스트로 돌아갑니다(VM Entry). 평범한 메모리 접근은 SLAT 변환이 성공하는 한 VM Exit 없이 통과합니다.
인터럽트도 같습니다. 파티션은 물리 프로세서를 직접 만지지 않고, 하이퍼바이저가 인터럽트를 받아 각 파티션으로 보냅니다.2
flowchart TB
accTitle: 게스트 실행과 VM Exit의 흐름
accDescr: 게스트 커널과 앱은 게스트 모드의 링 0과 링 3에서 돈다. 평범한 메모리 접근은 SLAT 변환으로 통과하고, 설정된 인터셉트와 예외는 VM Exit로 하이퍼바이저에 제어를 넘긴 뒤 VM Entry로 게스트로 돌아온다
guest["게스트 모드에서 실행(링 0 커널 포함)"] --> op{"개입이 필요한 작업?(설정된 인터셉트/예외)"}
op -->|아니오| cont["그대로 실행을 계속"]
op -->|예| exitEv["VM Exit(CPU가 제어를 넘김)"]
exitEv --> hvp["하이퍼바이저가 처리"]
hvp --> entry["VM Entry로 게스트로 복귀"]
entry --> guest
그림 3: 게스트 OS는 다시 쓰지 않고 링 0에서 계속 돌고, CPU는 필요할 때만 하이퍼바이저를 부른다.
이 왕복은 메모리 연재에서 따라간 「페이지 폴트로 커널에 들어갔다가 같은 명령으로 돌아온다」는 흐름과 많이 닮았습니다. CPU가 예외나 전환 장치로 제어를 가로채고, 더 높은 관리자에게 맡긴 뒤 돌아옵니다. Windows의 심층에서는 이 형태가 반복해서 나타납니다.
2.3. Type 1과 Type 2 ── 차이는 앉는 자리
하이퍼바이저는 크게, 하드웨어 바로 위에서 도는 Type 1(베어메탈)과, 호스트 OS 위에서 도는 Type 2(호스티드)로 나뉩니다. Hyper-V는 Type 1입니다.3 VirtualBox와 VMware Workstation(단독으로 돌릴 때)은 Type 2로 분류됩니다.
Type 1이라고 하면 「호스트 OS가 없는 서버 전용 구성」을 떠올리기 쉽지만, Hyper-V는 다릅니다. 호스트 Windows는 사라지지 않고──루트 파티션으로 「이사를 갑니다」. Hyper-V를 켜고 재부팅하면, 부트 중에 하이퍼바이저가 먼저 시작하고, 그 위에서 호스트 Windows가 루트 파티션으로 올라옵니다.
flowchart TB
accTitle: Type 1과 Type 2 하이퍼바이저의 차이
accDescr: Type 2에서는 호스트 OS가 하드웨어 위에 앉고 하이퍼바이저와 VM이 호스트 OS 위에 앉는 반면, Type 1 Hyper-V에서는 하이퍼바이저가 하드웨어 바로 위에 앉고 호스트 OS 자체가 그 위 루트 파티션으로 들어간다
subgraph t2 ["Type 2(호스티드)"]
hw2["하드웨어"] --> hostos["호스트 OS"]
hostos --> hv2["하이퍼바이저"]
hv2 --> vm2["VM"]
end
subgraph t1 ["Type 1(Hyper-V)"]
hw1["하드웨어"] --> hv1["하이퍼바이저"]
hv1 --> root1["루트 파티션(호스트 OS)"]
hv1 --> vm1["VM"]
end
vm2 ~~~ hw1
그림 4: Type 2에서는 하이퍼바이저가 호스트 OS 위에 앉고, Type 1 Hyper-V에서는 순서가 뒤집혀 호스트 OS 자체가 한 층 아래의 층 위에 앉는다.
부트 시간축으로 보면, 켰을 때 일어나는 변화는 이렇게 보입니다.
flowchart TB
accTitle: Hyper-V를 켠 뒤의 부트 순서
accDescr: 전원 인가 후 부트 중에 하이퍼바이저가 먼저 시작하고, 호스트 Windows가 그 위 루트 파티션으로 올라온 뒤, VM이나 VBS 등이 그다음에 시작된다
poweron["전원 인가와 부트 시작"] --> bhv["하이퍼바이저가 먼저 시작"]
bhv --> broot["호스트 Windows가 루트 파티션으로 시작"]
broot --> blater["그 위에서 VM, VBS, WSL2 등이 시작"]
broot -.-> feel["사용자의 체감은 변하지 않는다"]
그림 5: 순서의 역전은 로그온 화면이 나오기 전에 이미 끝나 있고, 호스트 OS는 처음부터 하이퍼바이저 위에서 올라온다.
3. 파티션 ── 격리의 단위
3.1. 루트 파티션만 가진 역할
파티션은 하이퍼바이저가 제공하는 논리적 격리 단위입니다.2 다만 모든 파티션이 동등하지는 않습니다. 루트 파티션만 가진 것이 있습니다.
- 물리 디바이스에 대한 직접 접근. 디스크, NIC, GPU 등의 디바이스 드라이버는 하이퍼바이저가 아니라 루트 파티션 안의 Windows에 있습니다. Windows Server의 Hyper-V에는 특정 PCIe 디바이스를 자식 파티션에 직접 할당하는 구성(Discrete Device Assignment)이 있고, 그때 루트는 그 디바이스를 놓습니다(클라이언트 Windows에는 없습니다).4
- 가상화 관리 스택. VM의 생성·시작·중지를 관장하는 VMMS(Virtual Machine Management Service)와 VM마다의 워커 프로세스(vmwp.exe)는 루트 파티션의 사용자 모드에서 돕니다.5 이들은 Hyper-V의 VM 관리 기능의 일부이므로, VBS나 WSL2만을 위해 하이퍼바이저가 도는 호스트에는 없을 수 있습니다.
- 자식 파티션을 만들 권리. 루트 파티션은 하이퍼콜 API(하이퍼바이저로의 호출 인터페이스)로 자식 파티션을 만듭니다.2
이 설계에는 이유가 있습니다. 모든 디바이스 드라이버를 하이퍼바이저 자체에 넣으면 하이퍼바이저가 커지고, 버그와 공격 입구의 수가 늘어납니다. 하이퍼바이저는 CPU와 메모리 중개라는 최소 작업에 머물고, 디바이스 관리는 루트 파티션의 Windows에 맡깁니다. 이 역할 분담이 Hyper-V를 얇게 유지합니다.
flowchart TB
accTitle: 루트 파티션과 자식 파티션의 역할 분담
accDescr: 루트 파티션은 가상화 관리 스택과 물리 디바이스 드라이버를 갖고 하이퍼콜로 자식 파티션을 만든다. 자식 파티션은 보통 가상 디바이스만 보고, Windows Server의 Discrete Device Assignment에서는 할당된 디바이스에 직접 접근한다
subgraph rootp ["루트 파티션"]
vmms["VMMS와 워커 프로세스"]
drv["물리 디바이스 드라이버"]
end
subgraph childp ["자식 파티션"]
gos["게스트 OS"]
vdev["보통 구성에서는 가상 디바이스만 보인다"]
end
vmms -->|하이퍼콜로 생성·관리| childp
hv2["하이퍼바이저(CPU와 메모리 중개에 머문다)"] --- rootp
hv2 --- childp
그림 6: 디바이스 드라이버와 관리 스택을 루트 파티션 측에 두는 것이, 하이퍼바이저 자체를 얇게 유지한다.
3.2. 자식 파티션에서 본 세계
자식 파티션의 게스트 OS는, 보통의 가상 디바이스 구성에서는 물리 하드웨어를 직접 볼 수 없습니다(유일한 예외는 앞 절에서 말한, Windows Server의 Discrete Device Assignment로 할당된 디바이스입니다). 볼 수 있는 것은 가상 프로세서, 자신의 것처럼 보이는 메모리 공간, 가상 디바이스입니다. 가상 디바이스에 대한 요청은 VMBus나 하이퍼바이저를 거쳐 루트 파티션으로 전달됩니다.2 한편 CPU 시간 할당과 SLAT를 통한 메모리 변환은 루트를 거치지 않고 하이퍼바이저가 직접 처리합니다. 루트가 중개하는 것은 디바이스 I/O이지, 모든 물리 자원이 아닙니다.
flowchart TB
accTitle: 자식 파티션에서 본 세계
accDescr: 게스트 OS가 보는 것은 가상 프로세서, 파티션 전용 메모리 공간, 가상 디바이스다. 가상 디바이스 요청은 VMBus 등으로 루트 파티션에 전달되고, CPU 시간과 메모리 변환은 하이퍼바이저가 직접 처리하며, Windows Server의 Discrete Device Assignment 구성에서만 할당된 디바이스에 직접 접근한다
gos2["게스트 OS(자식)"] --> 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 커널이 처리합니다. 하이퍼바이저가 개입하는 것은 설정된 인터셉트나 예외에 닿았을 때뿐입니다.
4. 메모리부터 ── 주소 변환이 한 단계 더
4.1. 세 종류의 주소
메모리 연재 제1회에서는 가상 주소가 페이지 테이블을 거쳐 물리 주소로 변환되는 흐름을 따라갔습니다(「가상 주소가 물리 RAM이 되는 순간」). 가상화 환경에서는 그 변환 아래에 단계가 하나 더 더해지고, 주소는 세 종류가 됩니다.
| 주소 | 약칭 | 누가 관리하는가 |
|---|---|---|
| 게스트 가상 주소 | GVA | 게스트 OS 페이지 테이블 |
| 게스트 물리 주소 | GPA | 게스트 OS가 「물리」라고 믿는 주소 |
| 시스템 물리 주소 | SPA | 하이퍼바이저(RAM의 실제 위치) |
게스트 OS는 자신의 페이지 테이블로 GVA를 GPA로 변환합니다. 다만 게스트가 보는 GPA는 진짜 물리 주소가 아니라, 각 파티션 전용의 사적 메모리 공간입니다.2 GPA를 RAM의 실제 위치(SPA)에 대응시키는 일은 하이퍼바이저의 일입니다.
4.2. SLAT ── 하드웨어에서의 2단계 변환
이 두 번째 변환을 소프트웨어만으로 하면, 하이퍼바이저가 게스트 페이지 테이블의 모든 갱신을 하나씩 추적해야 해서 성능상 현실적이지 않습니다. 그래서 CPU는 두 번째 변환 테이블을 하드웨어로 걷는 장치를 제공합니다. 그게 SLAT(Second Level Address Translation)이며, Intel EPT(Extended Page Tables)와 AMD RVI가 그 구현입니다. 현행 Hyper-V는 SLAT 대응 64비트 프로세서를 요구합니다.4
flowchart TB
accTitle: SLAT를 통한 2단계 주소 변환
accDescr: 게스트 가상 주소는 게스트 OS 페이지 테이블로 게스트 물리 주소가 되고, 하이퍼바이저가 관리하는 SLAT로 시스템 물리 주소로 더 변환되어 실제 RAM에 도달한다
gva["게스트 가상 주소(GVA)"] -->|게스트 OS 페이지 테이블| gpa["게스트 물리 주소(GPA)"]
gpa -->|"SLAT(EPT/RVI 변환 테이블)"| spa["시스템 물리 주소(SPA)"]
spa --> ram["물리 RAM"]
gpa -.-> note["게스트가 물리라고 믿을 뿐인 층"]
그림 8: 게스트의 페이지 테이블 아래에 하이퍼바이저가 관리하는 또 하나의 변환 테이블이 있고, CPU는 둘을 하드웨어로 걷는다.
SLAT는 VM 실행 효율만을 위한 기능이 아닙니다. 제2회에서 볼 VBS는 「특권 수준마다 다른 SLAT 변환 테이블을 가질 수 있다」는 성질을 보안 경계의 재료로 씁니다. 커널조차 볼 수 없는 메모리를 만들 수 있는 이유는, 하이퍼바이저가 이 두 번째 변환을 쥐고 있기 때문입니다. 이건 연재 전체의 관통선이므로, 「변환 테이블의 주인은 하이퍼바이저」라는 한 점만 기억해 두십시오.
5. 디바이스 I/O부터 ── VMBus와 두 종류의 디바이스
5.1. 에뮬레이트 디바이스의 한계
자식 파티션에 디바이스를 보여 주는 고전적 방법은, 실제 하드웨어(예를 들어 옛 IDE 컨트롤러)를 소프트웨어로 완전히 흉내 내는 것입니다. 게스트 OS의 인박스 드라이버가 그대로 동작하므로 호환성은 높지만, 게스트가 I/O 포트에 닿을 때마다 VM Exit가 나고 성능이 스케일되지 않습니다.
flowchart TB
accTitle: 에뮬레이트 디바이스에 대한 I/O가 느린 이유
accDescr: 게스트가 I/O 포트를 조작할 때마다 VM Exit로 제어가 하이퍼바이저 측으로 넘어가고, 디바이스를 소프트웨어로 흉내 낸 뒤 게스트로 돌아가므로, 왕복이 반복되어 느리다
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): 자식 파티션 측 게스트 OS에 들어가는 합성 디바이스 드라이버입니다. 요청을 VMBus로 VSP에 보냅니다.
게스트 OS의 스토리지 요청을 예로 들면 흐름은 이렇습니다. 게스트 앱의 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를 건너 루트 파티션으로 가고, 루트 측 스택을 거쳐 실제 디바이스나 호스트 측 백엔드에 도달한다.
즉 VM의 디스크 I/O나 네트워킹이 빠른지는 게스트 측만이 아니라, 루트 파티션 측 I/O 스택과 디바이스 드라이버의 상태에도 달립니다. VM 성능 문제를 조사할 때 호스트 측 관찰이 빠질 수 없는 이유는, 경로가 실제로 호스트를 지나기 때문입니다.
flowchart TB
accTitle: 에뮬레이트 디바이스와 합성 디바이스
accDescr: 에뮬레이트 디바이스는 실제 하드웨어를 흉내 내 인박스 게스트 드라이버가 동작하지만 느리고, 합성 디바이스는 VMBus를 가정한 전용 드라이버로 빠르다
dev2{"자식 파티션에 보여 주는 디바이스"} --> emu["에뮬레이트 디바이스"]
dev2 --> syn["합성 디바이스"]
emu -.-> emuP["실제 하드웨어를 에뮬레이트. 호환성 우선"]
emuP -.-> emuC["I/O마다 개입. 느림"]
syn -.-> synP["VMBus를 전제로 설계. 빠름"]
synP -.-> synC["게스트에 대응 드라이버가 필요"]
그림 11: 두 종류의 가상 디바이스 중, 에뮬레이트 디바이스는 OS 설치 직후의 호환성을, 합성 디바이스는 일상의 성능을 담당한다.
6. VM을 쓰지 않아도 남의 이야기가 아닌 이유
지금까지의 구조는 「VM을 세우는 사람의 이야기」처럼 보일 수 있습니다. 다만 서두에서 말했듯이, 현행 Windows에서 하이퍼바이저는 일상의 일부입니다.
- 가상화 기반 보안(VBS). Windows 하이퍼바이저로 격리 환경을 만들고 보안 기능을 그곳에 둡니다. Windows 11에서는 호환 하드웨어에 대한 클린 설치 같은 조건을 충족하면 기본으로 켜집니다.1 세부는 제2회입니다.
- WSL2. 가벼운 유틸리티 VM 안에서 진짜 Linux 커널을 돌립니다.6
- Windows Sandbox. 하이퍼바이저가 격리한 일회용 Windows 환경입니다.7 둘 다 제3회에서 다룹니다.
flowchart TB
accTitle: 같은 하이퍼바이저 위에 앉는 일상의 기능
accDescr: Hyper-V VM뿐 아니라, 클린 설치 같은 조건을 충족하는 장치에서 기본으로 켜지는 VBS와, WSL2, Windows Sandbox 모두 같은 Windows 하이퍼바이저 위에 만들어진다
base["Windows 하이퍼바이저"] --> f1["Hyper-V VM"]
base --> f2["VBS(클린 설치 등에서 기본 사용)"]
base --> f3["WSL2"]
base --> f4["Windows Sandbox"]
f2 -.-> daily["VM을 쓰지 않는 PC에서도 도는 이유"]
그림 12: 토대는 하나이며, 「가상화는 VM을 쓰는 사람의 이야기」라는 가정이 여기서 무너진다.
실무에서 자주 밟는 또 하나는 타사 가상화 소프트웨어와의 공존입니다. 하이퍼바이저가 CPU의 가상화 확장을 독점하므로, Windows 하이퍼바이저가 도는 환경에서는 VirtualBox 등이 전통적인 방식(CPU 가상화 확장을 스스로 쓰는 방식)으로 돌지 못합니다. 이를 위해 Windows Hypervisor Platform이라는 공개 API가 있고, 타사 가상화 스택은 Windows 하이퍼바이저 위에 앉아 돌 수 있습니다.8 현행 VirtualBox/VMware는 이 장치 덕분에 WSL2와 공존할 수 있지만, 모드 전환에 따른 성능·기능 차이는 「Hyper-V(또는 VBS)를 켠 뒤 가상화 소프트웨어의 거동이 달라졌다」로 관측되기도 합니다.
flowchart TB
accTitle: CPU 가상화 확장의 주인과 타사 가상화 소프트웨어의 경로
accDescr: Windows 하이퍼바이저가 도는 동안에는 CPU 가상화 확장을 독점한다. WHP를 지원하는 타사 가상화 소프트웨어는 Windows Hypervisor Platform을 거쳐 그 위에서 돌고, WHP를 지원하지 않는 구현은 돌지 못하거나 기능이 제한된다
vt["CPU 가상화 확장(VT-x/AMD-V)"] --> hvon{"Windows 하이퍼바이저가 도는가?"}
hvon -->|아니오| direct["타사 소프트웨어가 직접 사용할 수 있다"]
hvon -->|예| own["하이퍼바이저가 독점 사용"]
own --> whp["Windows Hypervisor Platform"]
whp --> third["WHP 대응 타사 소프트웨어가 그 위에서 돈다"]
third -.-> nowhp["비대응 구현은 돌지 못하거나 제한된다"]
그림 13: 가상화 확장의 주인은 하나이며, 하이퍼바이저가 도는 동안 공존할 수 있는 타사 소프트웨어는 공개 API(WHP)를 지원하는 것뿐이다.
7. 직접 확인해 보기
하이퍼바이저가 도는지는 자기 머신에서 확인할 수 있습니다.
먼저 관리자 권한 없이 돌릴 수 있는 확인입니다.
# 하이퍼바이저 위에서 도는지
(Get-CimInstance Win32_ComputerSystem).HypervisorPresent
# VBS 상태 (msinfo32의 「가상화 기반 보안」과 같은 출처)
Get-CimInstance -Namespace root/Microsoft/Windows/DeviceGuard `
-ClassName Win32_DeviceGuard |
Select-Object VirtualizationBasedSecurityStatus
VirtualizationBasedSecurityStatus는 VBS 실행 상태를 숫자로 반환합니다(2가 「실행 중」).9
주의할 점이 하나 있습니다. HypervisorPresent가 말해 주는 것은 「하이퍼바이저 위에서 도는지」뿐이며, 루트와 자식을 구분하지 않습니다. VM 안의 Windows에서 돌려도, 자식 파티션으로서 True가 나옵니다. 물리 PC의 Windows에서 True이면 그 Windows는 루트 파티션 안에 있습니다──실행 환경과 함께 읽으십시오.
다음은 명령 프롬프트의 고전입니다.
systeminfo
출력 끝의 「Hyper-V Requirements」를 보십시오. 하이퍼바이저가 아직 돌지 않는 머신에서는 SLAT 지원, 가상화 확장이 켜져 있는지 등 개별 요건이 나열됩니다. 하이퍼바이저가 이미 도는 머신에서는 요건 대신 한 줄이 나옵니다. 「A hypervisor has been detected. Features required for Hyper-V will not be displayed.」4 그 한 줄은 따라서 당신의 Windows가 어떤 하이퍼바이저 위에서 움직이고 있다는 선언입니다. HypervisorPresent와 같이, 물리 PC에서는 「루트 파티션 안」, VM 안에서는 「자식 파티션으로서」로 읽어야 합니다.
systeminfo의 요건이 모두 「Yes」여도, 그건 하드웨어 측이 준비되었다는 뜻일 뿐입니다. Hyper-V 기능 자체는 Pro, Enterprise, Education 에디션에서 쓸 수 있고, Home에는 없습니다.10
GUI에서는 msinfo32의 「시스템 요약」아래 「가상화 기반 보안」행을 확인하십시오. 작업 관리자 CPU 창의 「가상화: 사용」은 가상화 확장이 펌웨어에서 켜져 있는지만 보여 주며, 하이퍼바이저가 도는지와는 별개 정보입니다.
flowchart TB
accTitle: 하이퍼바이저가 도는지 확인하는 방법
accDescr: systeminfo가 하이퍼바이저가 검출되었다고 하면 하이퍼바이저 위에서 돈다(물리 PC에서는 루트 파티션 안). Hyper-V Requirements 목록이 나오면 아직 돌지 않으므로 SLAT, VM Monitor Mode Extensions, DEP 등 각 요건을 확인하지만, 모두 Yes여도 하드웨어 측이 준비된 것일 뿐이며 Hyper-V 기능에는 에디션 요건도 있다
start2["systeminfo를 실행"] --> q1{"요건 란?"}
q1 -->|Detected| running["하이퍼바이저가 돈다"]
running -.-> runN["루트 안"]
runN -.-> runN2["물리 PC에서"]
q1 -->|Listed| 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 기능(관리 도구와 VM 실행 환경)을 켜지 않았더라도, VBS가 켜져 있으면 Windows 하이퍼바이저는 돕니다. 드라이버 호환 문제, 성능 테스트, 타사 가상화 소프트웨어의 장애를 조사할 때는, 기능이 켜져 있는지가 아니라 HypervisorPresent와 VBS 실행 상태를 확인하십시오.
8.2. 「작업 관리자가 『가상화: 사용』이니 Hyper-V가 돈다」
그 표시는 펌웨어 설정(VT-x/AMD-V를 쓸 수 있는지)입니다. 하이퍼바이저의 실행 상태는 systeminfo의 「A hypervisor has been detected」로 판단하십시오. 반대로 작업 관리자가 「사용 안 함」이면 Hyper-V나 WSL2도 켤 수 없으므로, 먼저 UEFI/BIOS 설정을 확인하십시오.
flowchart TB
accTitle: 혼동하기 쉬운 세 가지 확인
accDescr: 작업 관리자의 가상화 란은 펌웨어 설정, Windows 기능 목록은 설치 상태, systeminfo나 HypervisorPresent는 실행 상태를 보여 주며, 각각 다른 질문에 답한다
q3{"어느 질문인가?"}
q3 --> fw{"펌웨어 또는 Windows?"}
q3 --> c3["하이퍼바이저가 도는가?"]
fw --> a3["펌웨어 확장?"]
fw --> b3["Hyper-V 기능이 켜져 있나?"]
a3 -.-> a3t["작업 관리자 CPU 창"]
b3 -.-> b3t["Windows 기능 UI"]
c3 -.-> c3t["systeminfo"]
c3 -.-> c3tp["HypervisorPresent"]
그림 15: 이들은 독립된 세 질문이며, 어느 한 표시에서 나머지 둘을 추론하는 것은 오해다.
8.3. 「VM이 느리면 게스트 OS의 문제다」
합성 디바이스 I/O는 VMBus를 건너 루트 파티션의 VSP로 가고, 루트 측 디바이스/백엔드 스택(물리 드라이버, 그리고 가상 스위치·가상 디스크 처리)을 지납니다. 게스트 안의 카운터만 보면, 호스트 측 스토리지나 NIC에 있는 병목을 찾지 못합니다. VM 성능 문제의 원칙은 게스트와 호스트(루트 파티션) 양쪽에서 관찰하는 것입니다.
9. 정리
- Hyper-V를 켜면 하이퍼바이저가 하드웨어 바로 위에서 돌고, 호스트 Windows는 루트 파티션으로 움직입니다.2
- 게스트 OS 커널은 링 0에서 계속 돌고, 인터셉트로 설정된 작업과 예외만 VM Exit로 하이퍼바이저에 넘어갑니다. 평범한 메모리 접근은 SLAT 변환으로 통과합니다.
- 루트 파티션만 물리 디바이스 드라이버와 가상화 관리 스택을 갖고, 하이퍼콜로 자식 파티션을 만듭니다.2
- 메모리는 GVA→GPA→SPA의 2단계 변환이 되고, 두 번째 단계는 SLAT(EPT/RVI)가 하드웨어로 처리합니다. 현행 Hyper-V는 SLAT를 요구합니다.4
- 디바이스 I/O는 VSC→VMBus→VSP의 합성 디바이스 경로가 주력이며, 성능은 호스트 측 I/O 스택에도 달립니다.2
- Windows 11에서는 클린 설치 같은 조건을 충족하는 장치에서 VBS가 기본으로 켜지므로, VM을 쓰지 않는 PC에서도 하이퍼바이저가 도는 일은 드물지 않습니다.1 실행 상태는
HypervisorPresent와 systeminfo로 확인할 수 있습니다.
제1회의 큰 그림은 이 한 장으로 압축됩니다.
flowchart TB
accTitle: 제1회의 큰 그림
accDescr: 하이퍼바이저는 루트 파티션과 자식 파티션 아래에 앉는다. CPU는 가상 프로세서를 스케줄하고(설정된 인터셉트와 예외에서만 VM Exit), 메모리는 2단계 SLAT 변환으로 중개하며, 합성 디바이스 I/O는 VMBus를 건너 루트 파티션의 VSP가 처리하고, 에뮬레이트 디바이스와 Discrete Device Assignment는 다른 경로를 갖는다
up["루트 + 자식 파티션"] --> hvS["하이퍼바이저"]
hvS --> cpuS["CPU: VP를 스케줄"]
hvS --> memS["메모리: SLAT"]
cpuS -.-> cpuN["인터셉트 시 VM Exit"]
memS -.-> memN["2단계 변환"]
memS ~~~ devS
devS["디바이스: VMBus I/O"] --> vspS["루트 측 VSP가 처리"]
devS -.-> devN["에뮬레이트 / DDA: 다른 경로"]
그림 16: CPU 스케줄과 메모리 변환은 하이퍼바이저가 직접 처리하고(개입이 필요할 때만 VM Exit), 합성 디바이스 I/O는 VMBus 너머의 루트 파티션(VSP)이 중개한다.
이어지는 제2회, 「커널에서도 보이지 않는 메모리 ── VBS, HVCI, Credential Guard」.
이 글의 관통선──하이퍼바이저가 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 코어 / E 코어까지 정리
관련 상담 영역
합동회사 코무라소프트에서는 Windows 앱의 검증 환경 설계, 가상화 환경의 성능 조사, 드라이버와 주변 기기의 호환 문제 분석을 다루고 있습니다.
참고 링크
-
Microsoft Learn, Silicon assisted security. VBS가 하드웨어 가상화로 Secure Kernel을 일반 OS에서 격리한다는 점, Windows 11의 신규 설치에서 전제를 충족하는 장치에 VBS와 HVCI가 기본으로 켜진다는 점에 대해. ↩ ↩2 ↩3
-
Microsoft Learn, Hyper-V Architecture. 하이퍼바이저가 파티션을 격리 단위로 제공한다는 점, 루트 파티션이 하이퍼콜 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 하이퍼바이저라는 점, 루트 파티션이 물리 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」란에서 요건 충족을 확인할 수 있다는 점, 하이퍼바이저가 도는 동안 「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)가 자식 파티션의 VM 상태를 관리하고, VM마다 워커 프로세스(VMWP)가 루트 파티션의 사용자 모드에서 시작된다는 점에 대해. ↩
-
Microsoft Learn, Comparing WSL Versions. WSL2가 가벼운 유틸리티 VM 안에서 진짜 Linux 커널을 돌린다는 점, 현행 VMware·VirtualBox와 함께 쓸 때의 주의에 대해. ↩
-
Microsoft Learn, Windows Sandbox architecture. Windows Sandbox가 컨테이너 기술과 하이퍼바이저의 격리를 결합한 가벼운 Windows 환경이라는 점에 대해. ↩
-
Microsoft Learn, Windows Hypervisor Platform. 타사 가상화 스택이 Windows 하이퍼바이저 위에서 파티션을 만들고 관리할 수 있도록 사용자 모드 API가 제공된다는 점에 대해. ↩
-
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가 수초 만에 기동하고 가벼운 이유는 무엇일까요. 동적 베이스 이미지와 다이렉트 맵, 동적 메모리 할당부터 Hyper-V 격리 컨테이너까지 구조를 해설합니다.
Windows 가상화의 심층(제2회) ── 커널에서도 보이지 않는 메모리: VBS, HVCI, Credential Guard의 구조
호환 하드웨어에 대한 클린 설치에서 기본으로 켜지는 VBS는, 하이퍼바이저와 SLAT로 커널보다 강한 격리를 만듭니다. VTL, Secure Kernel, HVCI, Credential Guard의 구조를 해설합니다.
Win32 스레드 풀 API ── CreateThreadpoolWork로 「스레드를 만들지 않는」병렬 처리
네이티브 코드에서 CreateThread를 여기저기 만들고 있지는 않은가요. Vista에서 개편된 Win32 스레드 풀 API의 work·timer·wait·io 네 객체, 클린업 그룹, 콜백에서 해서는 안 되는 일까지 1차 정보를 바탕으로 해설...
네임드 파이프의 실무 ── Windows 프로세스 간 통신의 정석을 설계부터 보안까지
Windows 프로세스 간 통신의 정석인 네임드 파이프를 실무 관점에서 정리합니다. 바이트/메시지 모드 선택, 여러 클라이언트를 받는 서버 설계, ACL과 위장 보안, .NET NamedPipeStream까지 1차 정보를 바탕으로 설명합니다.
Windows의 「메모리 사용량」은 무엇을 나타내는가 ── Working Set·Private Bytes·Commit·페이지 파일을 올바르게 읽는 법
작업 관리자의 메모리, Working Set, Private Bytes, Commit은 같은 값이 아닙니다. Windows의 가상 메모리와 물리 메모리의 관계, 페이지 파일의 역할, 메모리 부족이나 누수 조사에서 봐야 할 지표를 설명합니다.
관련 토픽
이 기사와 가까운 토픽 페이지입니다. 기사를 출발점 삼아 관련 서비스와 다른 기사로 이어집니다.
Windows 기술 토픽
Windows 개발, 장애 조사, 기존 자산 활용에 관한 KomuraSoft LLC 기사를 모은 토픽 허브입니다.
이 주제와 연결되는 서비스
이 기사는 다음 서비스 페이지로 이어집니다. 가까운 입구부터 확인해 주세요.
Windows 앱 개발
상주 처리, 장비 연동, 운영 로그, 유지 보수 가능한 구조가 필요한 Windows 데스크톱 애플리케이션을 지원합니다.
자주 묻는 질문
이 기사 주제에 대해 상담 시 자주 나오는 질문을 모았습니다.
- Hyper-V를 켜면 호스트 Windows는 실제로 어디서 움직이나요?
- 하이퍼바이저가 물리 CPU와 메모리의 할당을 직접 제어하고, 호스트 Windows는 루트 파티션이라는 특수 파티션 안에서 움직입니다. 물리 디바이스의 제어는 보통 루트 파티션 측의 드라이버가 담당합니다. 루트 파티션은 디바이스 드라이버와 가상화 관리 스택을 갖지만, 물리 CPU의 소유권은 하이퍼바이저에 있습니다.
- 작업 관리자의 「가상화: 사용」은 Hyper-V가 돌고 있다는 뜻인가요?
- 아닙니다. 그 표시는 CPU의 가상화 확장(Intel VT-x/AMD-V)이 펌웨어에서 켜져 있는지를 보여 줍니다. 하이퍼바이저가 실제로 돌고 있는지는 systeminfo의 「A hypervisor has been detected」, 또는 Win32_ComputerSystem.HypervisorPresent를 보십시오.
- VM을 만든 적이 없는데도 하이퍼바이저가 도는 이유는 무엇인가요?
- Windows 11에서는 가상화 기반 보안(VBS)이, 예를 들어 호환 하드웨어에 대한 클린 설치처럼 조건을 충족하는 장치에서 기본으로 켜지고, VBS는 Windows 하이퍼바이저 위에 만들어집니다. WSL2나 Windows Sandbox를 쓰는 경우도 같습니다. VM을 쓰는 사람과 무관하게 하이퍼바이저가 도는 일은 드물지 않습니다.
- SLAT란 무엇이며, 왜 Hyper-V에 필수인가요?
- SLAT(Second Level Address Translation)는 CPU가 게스트 물리 주소를 실제 물리 주소로 변환하는 장치이며, Intel EPT와 AMD RVI가 그 구현입니다. 없으면 하이퍼바이저가 변환 테이블을 소프트웨어로 유지해야 해서 성능상 현실적이지 않으므로, 현행 Hyper-V는 이를 필수 요건으로 둡니다.
- Hyper-V를 켜면 VirtualBox와 VMware가 멈추나요?
- 하이퍼바이저가 CPU의 가상화 확장을 독점하므로, 타사 하이퍼바이저는 전통적인 방식으로는 돌지 못합니다. 다만 현행 VirtualBox와 VMware에는 Windows 하이퍼바이저 위에서 도는 모드(Windows Hypervisor Platform 경유)가 있어, 최근 버전끼리는 공존할 수 있습니다.