仮想化

コンピュータが開発された当初は、1つのプログラムだけを実行するものであったが、コンピュータの能力向上と使いたいというユーザ数の増加から、MITのMulticsのように多数のユーザのプログラムを時分割で実行するマルチタスクOSが開発された。

パソコンの世界では、DOSの時代には一時には1つのプログラムしか実行できなかったがWindows時代になって、 Windowごとに異なるプログラムが並列に実行できるようになった。

マルチプログラム、あるいはマルチタスクと呼ばれる複数のプログラムを並列(正確には10ms程度の人間には感知できない程度の時間で切り替えて)に実行する機能を持つOSでは、プログラムの切り替えに際して、実行中のプログラムのアーキテクチャレジスタを退避し、次に実行するプログラムのアーキテクチャレジスタを以前の格納データから復元するという操作を行う。

多くの場合、このようなマルチタスクOSで複数のアプリケーションを並列に実行することによりハードウェアを有効利用することができるのであるが、実行するアプリケーションの間の(性能以外の)干渉を無くしたいという場合がある。例えば、銀行のオンラインシステムの改良のための開発は、運用する本番システムでテストする必要があるが、一方、開発中のプログラムのテスト中にプログラムのバグで、サービス中のオンラインが止まってしまっては困る。

また、Webホスティングでは、多数の顧客のWebページをサポートするが、悪意のあるユーザが他のユーザのWebページの実行を阻害したり、最悪、データを盗んだりというような事態を防止しなければならない。このような場合には、それぞれ独立なアプリケーションを1つのOSの下で動かすのではなく、顧客ごとに独立のコンピュータでWebアプリケーションを動かす方が安全である。しかし、これではたくさんのコンピュータが必要となり、経済的ではない。

Webホスティングは典型的な例であるが、個々のサーバは予想される最大のピークアクセスを処理できる能力が必要となるが、平均的なアクセスはずっと低いのでそれぞれのサーバの平均利用率は低い状態であり、無駄が多い。しかし、ホスティングしている全部のサイトのアクセスが同時にピークになることは考えにくく、[平均アクセス]×[サイト数]+[余裕]程度の能力のサーバ1台を仮想的に複数のサーバに見せるという方法で実現すれば平均利用率があがり、効率的である。このようなピークと平均負荷の大きな乖離は、Webホスティングだけでなく多くのケースで存在し、最近、仮想化を利用して複数のサーバを1つにまとめるサーバコンソリデーションによる設備投資や運用費用の削減がもてはやされるようになってきている。

このように仮想化が広く使用されるようになって来たのは最近のことであるが、1967年にIBMのCambridge Scientific CenterにおいてSystem 360/40メインフレームで動作するCP-40という仮想化モニタが作られ、1970年代に入ると仮想メモリをサポートするVM/370シリーズのメインフレームにおいて複数のCambridge Monitor SystemというOSを動作させるCP/CMSが開発されており、メインフレームの世界では、仮想化は40年の歴史のある技術である。

以下では、仮想化の性能を向上させるためのハードウェアアーキテクチャについて述べる。

ユーザ状態とスーパバイザ状態

汎用のプロセサでは、通常、ユーザ状態という状態とスーパバイザ状態(または、特権状態という。IntelアーキテクチャではProtected Modeと呼ぶ)という2つの状態を持っている。図10.7に示すように、スーパバイザ状態では、プロセサの持つすべてのレジスタを利用することができ、すべての命令を実行することができるが、ユーザ状態では操作できるレジスタが制限される。

図10.7 ユーザ状態とスーパバイザ状態で使用できるレジスタ区分

Intelのx86アーキテクチャで言えば、AX、BXなどの汎用レジスタや、MMX、XMMなどのMMX、SSE関係のレジスタ、そして、整数演算と浮動小数演算の比較結果を格納するFlagレジスタ、そして次に実行する命令を指すPC(Program Counter)などがユーザ状態でアクセスできるレジスタである。

一方、プロセサがユーザ状態かスーパバイザ状態であるかを保持するCR0レジスタや、その他の各種のハードウェアの状態の保持や制御を行うCR0~4レジスタ、割り込みテーブルの先頭ポインタを保持するIDT(Interrupt Descriptor Table)レジスタ、アドレス変換テーブルの先頭ポインタを保持するGDTR、LDTRなどは特権レジスタであり、スーパバイザ(Intelの用語ではProtected)状態でないとアクセスできない。

ユーザ状態で実行されるアプリケーションがこられの特権レジスタをアクセスする命令(特権命令)を実行しようとすると、特権違反の例外が発生し、OSに通知される。そして、OSは、通常、そのプログラムの実行を異常終了させる。

このようにして、ユーザ状態で実行されるアプリケーションプログラムがOSや他のアプリケーションの実行に影響(ここで言う影響は、論理的な影響であり、実行時間や共用資源が使われる影響は除く)を与えるような操作を行うことが出来ないようにしている。また、この機構は、ウイルスなどがOS領域に侵入することを阻止することにも貢献している。

しかし、このままでは、ユーザ状態で実行されるアプリケーションは、メモリ領域の獲得やI/Oアダプタのアクセス、割り込みの受け取りなどを実行することができず、演算などの処理はできるものの、入出力ができないので意味のある処理はできない。これを解決するのが、次に述べるシステムコールである。