レベル: 初級 高橋 浩和, VA Linux Systems Japan, ITmedia
2007年 3月 30日 Xenが仮想マシン環境を実現するために行っていることの全体を眺めてみましょう
Xenの内部設計
Xenが仮想マシン環境を実現するために行っていることの全体を眺めてみましょう。一つ一つの機能については、今後の連載で詳細に説明していきます。今回は、Xenがどのような設計になっているか、全体をイメージできれば十分だと思います。
空間レイアウト
Xenの環境では、それぞれのドメインに1つの仮想空間を割り当てています*(多重仮想空間)。x86(IA-32)用Xenでは、仮想空間の上位アドレスの64MバイトはXenが予約しており、ゲストOSが利用できるのは、残りの4Gバイトから64Mバイトを除いた空間です。Xen本体は仮想空間の最上位アドレスに存在し、ゲストOS空間の最上位アドレスには、ゲストOS依存のデータを配置します。物理アドレスとマシンアドレスの対応表もこの領域に配置され、必要に応じてゲストOSから参照します(図5)。
図5 x86用Xenの空間レイアウト
特権レベルとハイパーバイザ呼び出し
IA-32アーキテクチャーでは、リングプロテクション機能を利用して保護するのが一般的です。IA-32アーキテクチャーの実ハードウェア上でOSが動作している場合、OSを特権レベル0(リング0)に配置し、アプリケーションを特権レベル1~3(Linuxではレベル3)に配置することで、アプリケーションの動作からOSを保護しています(図6)。
図6 リングプロテクション(実ハードウェア上のOS)
アプリケーションがリングの壁を超えてOSの機能を呼び出すための仕掛けとして、システムコールを用意しています。
Xen環境では、Xenが存在する領域を、ゲストOSから壊されないようにする必要があります。IA-32用Xenでは、Xenを特権レベル0に配置し、準仮想化ドメインのゲストOSを特権レベル1に配置します(図7)。アプリケーションは、特権レベル2または3に配置しなければなりません。
図7 リングプロテクション(Xen環境)
ゲストOSがLinuxの場合、アプリケーションはレベル3に置きます。アプリケーションがOSを呼び出すときには、システムコールという仕掛けを利用します。同様に、ゲストOSがXenを呼び出したいときには、ハイパーバイザコールを利用します。また、例外を利用してゲストOSの動きを捕捉し、特権レベル0のXenがゲストOSから実行権を奪い取ることもあります。
完全仮想化ドメインの場合は、XenもゲストOSのどちらも、特権レベル0に配置します。ただし、VT機能を利用してXenをVMX rootオペレーションモードの領域に配置し、ゲストOSのあるドメインをVMXnon-rootオペレーションモードの領域に配置します(図8)。
図8 準仮想化と完全仮想化
ゲストOSからXenを呼び出すのは、VM exitが発生する命令*を実行したときになります。
CPUの扱い
Xen上では複数のドメインが同時に動作します。しかしこれは見かけ上そう見えるというだけで、実際にはそれぞれのドメインに対してCPUの実行権を細かく振り分けるということをXenが行っています。
このためにXenでは、仮想CPUというものを定義しています。Xenにおける仮想CPUは実行の単位であり、ゲストOSの要求に応じて各ドメインに幾つかの仮想CPUが割り当てられます。仮想CPUは、ドメイン上のゲストOSから見ると実CPUのように見えます。
Xenは仮想CPUの実CPUへの割り当てを制御しますが、この仕事を行う機能はドメインスケジューラと呼ばれています。ドメインスケジューラは、いつ、どの仮想CPUに、どれだけの実行時間を与えるかを制御するものです。ある一瞬を見ると、実CPUはある特定の仮想CPUにアタッチされています(図9)。
図9 ドメインと仮想CPU
実はこの仕組みは、プロセスとスレッド*の関係に似ています。マルチスレッドプログラミングを利用する場合、1つのプロセス中で複数のスレッドが並列動作することになります。UNIX/Linuxは、スレッドをスケジューリングして、実行するのに最もふさわしいスレッドにCPUの使用権を与えます*。
ドメインスケジューラには、sedfとbvtという2種類のスケジューリングポリシーが用意されていて、Xen起動時に選択できるようになっています。sedfは、SimpleEarly Deadline First schedulerの略で、bvdは、Borrowed VirtualTimer schedulerの略です。どちらも、リアルタイムスケジューリングがベースとなっていて、標準スケジューラはsedfです。
sedfは、一定期間ごとに一定のCPU時間をドメインに割り当てるアルゴリズムになっています。ドメインスケジューラが再スケジューリングを行うと、仮想CPUの切り替えが発生します。仮想CPUの切り替えが発生すると、現在動作している仮想CPUのコンテキストを待避させ、次に動作すべき仮想CPUのコンテキストを読み込みます。これは、プロセス(スレッド)と似た処理といえるでしょう。
メモリの扱い
ゲストOSが物理アドレスと思って扱っているものは、本当の物理アドレスではありません。物理アドレスはXenによって仮想化されており、本当の物理アドレスは、マシンアドレス*と呼ばれています。Xenはマシンアドレスで管理されるメモリ領域の一部を、あるドメイン空間の物理アドレスにマップし、そのドメインに貸し出します。
Xenの環境では、同じ物理アドレスを持つメモリが複数存在することになるので、多重物理メモリ空間とでも呼ぶべきかもしれません。XenはそれぞれのメモリにドメインIDをつけ、どのドメインの物理アドレスであるかを管理します。実CPUがメモリを操作するとき、または実デバイスを操作するときは、マシンアドレスを使わねばなりません*
(図10)。
図10 さまざまなアドレスとその関係
また、Xenの環境では本来CPUが提供しているMMU(メモリマネジメントユニット)の仮想化が必要です。実ハードウェア上でOSが動作している場合、仮想アドレスへのアクセスを、MMUが物理アドレスへのアクセスに変換してくれます。しかしXenの環境では、仮想アドレスへのアクセスを、マシンアドレスに変換する必要があります。これには、準仮想化ドメインと完全仮想化ドメインでは、異なる手法を採用しています。
準仮想化ドメインでのアドレス変換
準仮想化ドメインでは、マシンアドレスを意識します。通常の処理は、標準のOSと同じく物理アドレスでメモリを扱いますが、ページテーブルを操作するときとI/O要求を出すときは、物理アドレスをマシンアドレスに変換します。マシンアドレスはXenが管理するものですが、この2つの作業に限って、ゲストOSにマシンアドレスを意識させます。
準仮想化ドメインでは、ドメインが管理するページテーブルをCPUが直接参照し、アドレス変換を行います。Xenは、そのページテーブルに設定される値(マシンアドレス)が妥当であるか否かのチェックを行うのみで、仮想アドレスからマシンアドレスへの変換をゲストOSにすべて委ねています。ゲストOSでは、ページテーブルの更新手段としてXenが用意している2種類の方法を使用します。
1つはダイレクトモードと呼ばれる方式で、ハイパーバイザコールを利用してページテーブルを変更する方式です。もう1つは書き換え可能ページテーブルモードと呼ばれる方式です。通常、ページテーブルは不正な値が書き込まれないように書き込み保護がなされていますが、書き換え可能モードを利用すると、一時的にページテーブルへの書き込みが可能となり、その妥当性確認は、ページテーブル更新後にXenがまとめて行います。
後者の方式を使うとページテーブルの更新が高速になるため、これら2つが併用されています(図11)。
図11 準仮想化時のページテーブル
完全仮想化ドメインでのアドレス変換
完全仮想化ドメインでは、もちろんマシンアドレスは意識しませんし、またすることもできません。ドメインが物理アドレスで操作すると、Xenがそれを捕捉し、マシンアドレスに変換し処理を代行します。
完全仮想化ドメインでは、ゲストOSはページテーブルにすべて物理アドレス(と信じているアドレス)を設定します。しかし、これは本当にアクセスしたいメモリ(マシンアドレスで示されるメモリ)ではないため、CPUのMMUは利用できません。そこでXenは、ゲストOSが作るページテーブルに1対1に対応するシャドウページテーブルを用意し、そこにマシンアドレスを登録します。CPUには、このシャドウページテーブルを用いてアドレス変換を行わせます(図12)。
図12 シャドウページテーブル
このページで出てきた専門用語
-
それぞれのドメインに1つの仮想空間を割り当てています
- もちろん各ドメインのゲストOSは、プロセスやタスクのために、そのドメイン内にさらに複数の仮想空間を作りあげます。
-
VM exitが発生する命令
- 通常の命令であり、ゲストOSからは、直接CPUを制御しているか、Xenの呼び出しになっているかの区別はできません。
-
スレッド
- 書籍「Linux 2.6カーネル解読室」の「Part2 プロセス管理」参照。
-
実行するのに最もふさわしいスレッドにCPUの使用権を与えます
- 書籍「Linux 2.6カーネル解読室」の「Part1 カーネルプリミティブ」内「第1章 プロセススケジューリング」参照。
-
マシンアドレス
- Xenで使われている言葉で、一般的ではありません。
-
マシンアドレスを使わねばなりません
- 正確には、実デバイスにI/Oを要求する場合はマシンアドレスをさらにDMAアドレスに変換する必要があります。DMAアドレスはI/Oコントローラーから見たときのメモリアドレスです。
参考文献
著者について  | |  | 高橋浩和(VA Linux Systems Japan),ITmedia |
記事の評価
|