仮想マシンモニタ

図10.8に示すように、通常のプログラム実行環境は、スーパバイザ状態で実行されるOSがハードウェアを制御し、ユーザ状態で実行されるアプリケーションはOSのサービスを使って特権命令でしか操作できないハードウェアを動かすという階層構造になっている。

図10.8 通常のプログラム実行環境

ユーザ/スーパバイザ機構を持つプロセサで、通常のOSをアプリケーション状態で実行すると、そのOSが特権命令を実行しようとすると、特権違反の例外が発生する。これをスーパバイザ状態で実行する管理プログラムが受け取り、必要な動作をソフトウェアでシミュレートして実行し、あたかもOSの発行した特権命令が実行されたようにして例外から復帰させれば、処理時間は別として、OSとしては自分が実ハードウェアを操作しているのと同じように動作することができるはずである。

図10.9 仮想化されたプロセサでの実行環境

このようにしてユーザ状態で実行されるOSをゲストOSと呼び、スーパバイザ状態で動作する管理プログラムをVMM(Virtual Machine Monitor)あるいは、ハイパーバイザ(Hypervisor)と呼ぶ。そして、VMMは、1つのゲストOSが時間割り当てを消費してしまったり、I/O動作のように時間の掛かる処理を実行しようとしたりする場合には、そのゲストOSのハードウェア状態を退避し、別のゲストOSのハードウェア状態を復元して、ゲストOSを切り替えて実行する。

これがプロセサの仮想化の基本的な概念であり、最低限、ユーザ状態のプログラムからの重要ハードウェア資源へのアクセスを検出して例外を発生するハードウェア機構があれば、性能は別として仮想化を実現することが可能である。

プロセスの切り替えの場合は、汎用レジスタなどのアプリケーションプログラムから見えるユーザ状態で使用できるレジスタだけを退避、復元すればよかったが、VMMでOSを切り替える場合は、特権状態でしかアクセスできない特権レジスタも退避、復元を行う必要があり、相当に多くのレジスタの退避、復元が必要となる。これをスーパバイザ状態で実行するVMMの中でソフトウェアで実行すると時間が掛かるということで、Intelの仮想化テクノロジであるVTやAMDのAMD-V仮想化アーキテクチャでは、仮想化に必要な状態全部の退避、復元をそれぞれ1命令でまとめて実行できる命令を新設している。これにより、切り替えに必要となるロスタイムを削減している。

メモリ管理を行う場合、"メモリ管理"の項で述べたように、ページテーブルを使ってアプリケーションプログラムが使う仮想アドレスから、メモリの物理アドレスに変換を行うのが一般的である。しかし、配下のアプリケーションからの要求などにより、新しいメモリ割り当てを行う場合、各ゲストOSは、自分が全メモリ領域を管理していると思っているので、自分のメモリ空間(以下、ゲスト空間と呼ぶ)にメモリを割り付け、その論理-物理(実は物理ではなく、ゲスト空間)対応をページテーブルに設定しようとする。

しかし、複数のゲストOSがハードウェアを共用している場合は、同じ物理アドレスのページをゲストOSが重複して使ってしまうという問題が発生しうる。このため、VMMはもう1つのページテーブルを持ち、図10.10に示すように、アプリケーションからの仮想アドレスAを、まず、ゲストOSのページテーブルを引いてゲスト空間のアドレスBに変換し、そしてVMMのページテーブルを用いて本当の物理アドレスXに変換してメモリをアクセスするという2段階のメモリ空間の仮想化を行う必要がある。

図10.10 仮想化する場合は、2段階のアドレス変換が必要

なお、この仮想アドレスAは物理アドレスCに対応するという変換結果を、ハードウェアのTLBに書き込んでおけば、次回からのアドレスAのアクセスはTLBがヒットしてハードウェアが変換を行うので、再度、この手順を踏む必要はない。

しかし、ゲストOS空間はゲストOSの数だけ存在し、ユーザ空間は各ゲストOSの上で動くアプリケーション数の合計だけ存在し、ユーザ空間やゲストOS空間が切り替わる度に、仮想アドレスと物理アドレスの対応が切り替わることになる。したがって、実行するユーザ空間のアプリケーションやゲストOSが切り替わる度に、以前のTLBエントリは無効とし、新たに2段階のアドレス変換を行って、その結果をTLBに書き込む必要がある。

このTLBへの書き込みであるが、ソフトウェアでTLBに書き込むアーキテクチャのプロセサの場合は、単純にVMMが2段階のアドレス変換を行った結果のA→CをTLBに書き込めばよいが、x86プロセサの場合は、CR3レジスタにページテーブルの先頭アドレスをセットしておくと、ハードウェアがページテーブルをたどって変換結果を読み出してTLBにセットするというテーブルウオーク動作を自動的に行う。これは、通常は便利な機構であるが、仮想化を行う場合はおせっかいで、VMMは、仮想アドレスAを物理アドレスCに変換するというTLB専用のページテーブルをメモリ上に作ってやる必要が出る。このテーブルをシャドーページテーブルと呼ぶ。