SOSP 2003 https://www.cl.cam.ac.uk/research/srg/netos/papers/2003-xensosp.pdf
개요
XEN의 원저자가 작성한 최초의 논문으로, 어떻게 XEN을 구현하였는지 저술한 논문이다.
Introduction
VM이 가져야 할 특성들
- Isolation
- Support different operating systems
- Overhead must be small
XEN은 Guest Operating System에 수정을 가하여 위와 같은 성질을 모두 이룰 수 있도록 하였다. Linux, Windows XP 그리고 NetBSD까지 왠만한 운영체제는 모두 가상화 시킬 수 있었다. 그러나 Fork, Execv와 같은 시스템 콜로 프로세스를 형성시키는 것에 비해서 Booting time이 느리고 FullOS를 돌려야 되서 무겁다는 단점이 있다.
Overview
Full virtualization은 모든 운영체제를 modification없이 돌릴 수 있다는 장점이 있지만, 그곳에서 발생하는 overhead가 크다는 단점이 있었다. 이러한 한계를 극복하기 위해서 XEN는 Paravirtualization이라는 기법으로 GuestOS에 적절한 수정을 가하여 시스템을 가속화 하였다.
- 사용자는 어플리케이션을 수정하지 않아도 돌릴 수 있다.
- 사용자는 multicore를 사용할 수 있어야 한다.
- x86과 같이 하드웨어 지원이 미비한 코어에서도 좋은 성능을 내어야 한다.
- AMD-V와 같이 하드웨어 지원이 있어도 Paravitualization은 더 좋은 성능을 낸다.
라는 가설하에 XEN은 위와 같은 목표를 달성 할 수 있도록 노력하였다.
Virtual Machine Interface
- Memory Management
- Segmentation: 세그멘테이션 사용시 DPL 0과 같이 세그멘테이션의 fully-previleged 명령을 줄 수 없고, 또한 dom0와도 겹치지 않아야 한다.
- Paging: GuestOS는 hareware page table에 직접 접근이 가능하지만, page table update는 배칭되어 하이퍼 바이저에 전달되어 검수받아야 한다.
- CPU
- Protection: 게스트 운영체제는 하이퍼 바이저보다 낮은 레벨로 작동되어야 한다.
- 예외 처리: 게스트 운영체제는 하이퍼 바이저에 인터럽트 처리 루틴을 등록하고 이중 page fault는 하이퍼 바이저에 의해서 특별히 처리된다.
- 시스템 콜: 게스트 운영체제는 하이퍼 바이저에 시스템 콜 처리 루틴을 등록할 "수" 있고, 이 처리 루틴으로 시스템콜을 빨리 처리할 "수"도 있다. 일반적인 경우에는 시스템콜 내부는 게스트 운영체제에 의해서 처리된다.
- 인터럽트: 하드웨어 인터럽트는 Event System에 의해서 대체된다. 이는 진짜 인터럽트가 아니라 CPU가 풀링하고 있는 메모리의 특정 영역으로 소프트웨어 인터럽트를 제공하는 것을 말한다.
- Device
- 장치: 가상 장치 드라이버는 매우 간단하게 제작되어서, Event call과 같은 인터럽트가 아닌 다른 방식을 통해서 GuestOS와 Hipervisor간에 공유하게 된다. Virtio와 같은 방식을 사용한다.
메모리
이 논문이 나왔을 당시에는 EPT와 같은 하드워어 가속 시스템이 아직 x86에 없던 시절이었다. 따라서 메모리관리는 GuestOS에 일임하여 하드웨어 페이지 테이블에 접근할 수 있는 권한을 주었다. 그러나 page table update는 반드시 XEN을 통하도록 하였으며, 모든 하이퍼 콜과 같은 하이버 바이저의 협동을 요구하는 작업에는 메모리 상단의 64MB를 XEN에 할당하여 불필요한 TLB flush를 낭비하였다. (즉 update와 access를 구분하였다.)
CPU
GuestOS의 잘못된 동작에 대비하여, 게스트 OS는 하이퍼바이저보다 반드시 낮은 권한으로 작동하여야 한다. 또한 역시 이 당시에는 Guest Mode 이라는 개념이 없어서 guestOS는 ring1,2에서 작동하였다. 이러한 방식으로 GuestOS는 Ring0인 Dom0의 작업을 망치지는 않으면서, Ring3인 Userprog는 제어할 수 있도록 하였다.
또한 Privileged instruction (예를 들어서 halt)와 같은 경우는 XEN에서 작동하도록 paravitualized하였다. 이러한 작업에는 새로운 Page Table설치, hlt, lgdt와 같은 민감한 명령어들이 포함된다.
Exception과 같은 경우에는, Xen에 의해서 검수 받은 interrupt handler에 의해서 처리되었으며, 오직 page fault만이 XEN에 의해서 처리되도록 GuestOS가 intrrupt frame의 copy본을 XEN에 전달하여 작업을 처리하도록 하였다. (page fault는 cr2레지스터의 값을 읽어와야 함으로...)
또한 시스템콜과 같은 경우는 VMM에 있어서 성능 하락의 주범이 되는 녀석이었는데, XEN에서는 fast system call이라는 핸들러를 등록 할 수 있도록 하여서 이러한 한계를 극복하였다. 이러한 핸들러는 Ring0인 xen-hypervisor를 거치지 않고도 처리될 수 있도록 구현하여, 시스템 콜에서 불필요한 context switch에 대한 cost를 낮추었다. 이러한 핸들러 등록에 있어서 체크하는 부분은 핸들러가 절대 ring0에서 실행되지 않도록 하는 것이었다. 이러한 작업을 위반하면 GP로 인해서 double fault가 나게 되는데, 이는 xen에 의해서 감지되어 malacious os를 종료시키게 된다.
Device I/O
실제하는 디바이스를 Emulating하는 것에서 나아가서, I/O 데이터가 XEN에 shared memory하에 도착하도록 하여서, communication cost를 줄였다. 또한 디바이스 드라이버를 추상화 시켜서 제공하여 불필요한 overhead를 줄였다. 마지막으로 interrupt가 event channel로 이루어지 룻 있도록 하여서, 인터럽트에 의한 wake-up notification cost를 줄였다.
Control and Management
전반적인 구조는 H/W <-> Dom0 Interface, VCPU, VDEV, VNET... <-> GuestOS의 구조로 이루어 졌다. 이러한 가상장치들은 event channel을 이용하여 통신할 수 있도록 하였다.
Detailed Design
Hypercall
XEN과 GuestOS의 control interaction방식은 두가지가 있는데, 첫째는 hypercall이고 둘째는 event call이다. 하이퍼콜은 도메인이 동기적인 소프트웨어 트랩을 하이퍼바이저에 걸수 있도록 하였다. 또한 event channel은 기존의 인터럽트를 대체하는 비동기적인 통신 방식으로, per-domain bitmask에 pending event들이 작성되고, xen이 그 bitmask를 처리하면서 update하는 방식으로 구현되었다.
I/O Rings
I/O transfer은 resource management와 event notification을 중점으로 하여 개발되었다. 환형 큐를 이용하여 Request와 Response가 처리되도록 하였으며, 각각의 qeue에는 pointer가 존재하여 도메인이 어느 위치에 request를 쓰고 어느 위치에서 response를 가져가면 되는지 마킹할 수 있도록 하였다.
CPU Scheduling
도메인간의 scheduling 은 BVT(Borrowed Virtual Time) 스케쥴링을 이용하여 구현하였다.
Time and timers
XEN은 real time, virtual time그리고 wall-clock time을 제공하였다. 각각은 부팅후 시간, 게스트 운영체제 동작 시간 그리고 현재 real time에 더해야할 offset을 말한다. 각각의 운영체제는 알람 타이머를 프로그래밍 할 수 있으며 주어진 타이머를 가지고 프로그래밍 하게 된다.
Virtual address translation
Full virtualization이 shadown page table의 사용을 요구하는 것과 다르게, XEN은 페이지 테이블의 관리를 모두 GuestOS에 일임하였다. 그러나 Page Table의 Update는 XEN이 체크하도록 하여서 적합한 것인지를 검수하게 하였다. 즉 이러한 방식을 통해서 shadown page table을 통한 overhead나 additional complexity를 피하였다. GuestOS가 Page table에 대한 접근 권한이 read-only가 되도록 하여서 이러한 분리를 구현하였다.
이러한 일이 가능한것은 GuestOS가 Para이기 때문에, 가상 주소와 머신 주소의 변환테이블을 가지기 때문이다.
Validation을 구현하기 위해서, type과 Reference를 page frame에 대해서 분리하여 구현하였다. 각각의 도메인은 다음 5개의 타입중 여러개를 복수개 가질 수 없도록 하였다. 즉 domiain은 다음 5개의 타입중 하나만을 가질 수 있었다.(page-directory, page table, local descriptor table, global descriptor table, 그리고 writable). 이러한 방식으로 writalbe이면 중요한 정보가 담기지 않으며, writable이 아니여야만 sensitive한 자료에 접근할 수 있도록 하였다 (반드시 refcount는 1이하여야 만 하도록 구현.)
또한 Hypervisor에 이러한 sensitive data에 대한 update를 요청하는 queue는 batching될 수 있도록 하여서, 시스템의 효율을 더욱 끌어 올리고자 하였다.
Physical memory
최초의 메모리 할당은 정적으로 이루어지도록 하였다. 만약 Memory Pressure가 심해진다면, 더 많은 메모리를 할당하도록 XEN에 요청할 수 있고 XEN은 이러한 요청에 답할수도 무시할 수도 있다. 이러한 작업은 Ballon Driver를 이용하여 구현되었다.
Network
Device driver의 일종으로 DMA를 이용하여 메모리 버퍼에 요청하는 qeueue를 작성하는 방식으로 구현하였으며, 이러한 작업의 Virtual Interface는 dom0에 구현되도록 하였다.
Disk I/O
역시나 Ring Buffer를 이용하여 실제 Dom0의 Physical Device와 DomU의 Abstracted driver가 통신하며 서로의 정보를 주고 받을 수 있도록 구현하였다.