Virtual Machines, Chapter 3 Process VM(第二回)
互換性
まずは、仮想マシンの中身を議論する前に、互換性の話をします。
さらに互換性を考える前に、仮想マシンの定義を考えておきましょう。
仮想マシンは
- ゲストとホストの間での状態の写像(state mapping)
- ゲストとホスト上での状態を遷移させるオペレーション
の二つで定義されます。ここでいっている状態とはメモリやレジスタの事です。
仮想マシンを用いることで、ホスト環境(他のホストプロセスやホストOSなど)からゲストプロセスがホストプロセスであるかのように見える必要があります。よって、上の一つ目の要素である、ゲストの状態をホストの状態に移す写像が必要となります。逆にゲストプロセスからは、ホスト環境が自分と同じABIに見える必要があるので、ホストの状態をゲストの状態に移す写像も必要です。
そして、もちろん2つ目の要素であるオペレーションによって状態を遷移させても、状態の写像によってゲストとホストの状態の等価性が保たれる必要があります。
以上で仮想マシンの定義ができたので、今度は互換性について考えましょう。
仮想マシンでゲストプロセスを動かすと、当然多くのオペレーションを行います。そして、そういったオペレーションによってプロセスの状態を遷移させていったときに、常にゲストとホストの間で、状態の写像を用いることで状態が等価であるということを保証する必要はありません。なぜなら、オペレーションには、ユーザーレベルで行うものと、OSレベルで行うものがあり、ユーザーレベルで行うオペレーションは、プロセス内のリソースしか状態遷移を行わないからです。つまり、ユーザーレベルのオペレーションでは、プロセスの外部に影響を及ぼすことがないので、このレベルでの状態の等価性は必要はなく、OSレベルで行われるシステムコールやトラップによるオペレーションを行う時点での状態の等価性だけが必要なのです。
互換性に関して以上のように考えることで、ユーザーレベルのオペレーションを最適化するなど、仮想マシンを考える上での自由度が増します。
それでは、仮想マシンの中身について考えることにしましょう。
仮想マシンの中身を考えるときには、上の定義に従って、状態の写像とオペレーションのエミュレーションについて考えてあげれば良いことになります。
状態の写像
まずは、ユーザーレベルで管理している状態の写像を考えましょう。つまり、レジスタとメモリの状態に関する写像です。
典型的な仮想マシンでは、仮想マシンに割り当てられたホストのアドレス空間に、ゲストプロセスのデータとコード(もちろん仮想マシンのランタイムのデータとコードもここにあります)を割り当てています。そして、ゲストのレジスタの内容は、可能であればホストのレジスタに、(ゲスト環境で想定されているレジスタの数よりホストのレジスタの数が少ないなどの理由で)可能でない場合は、仮想マシンのランタイムデータに割り当てます。
ここで押さえるべき点は、ゲストのレジスタの内容を必ずしもホストのレジスタに割り当てる必要がない、ということです。つまり、ゲストの状態はホストの同じタイプのリソースに割り当てられる必要がないのです(とりあえず、パフォーマンスのことは抜きにして)。
メモリアドレス空間の写像
ゲストプロセスに、想定しているのとは異なる環境で動作していることを意識させないために、メモリのアドレス空間をホストのアドレス空間に変換する必要があります。
単純に考えると、これはOSの仮想メモリを実現している手法と同様に変換テーブルをソフトウェア的に保持してあげれば実現できます。そして、ゲストプロセスがメモリアクセスを行うたびに、アドレスを変換テーブルを参照して変換してあげるのです。
その他の手法としては、ゲストプロセスのアドレス空間をそのままホストのメモリ空間に割り当ててやるというものもあります。しかし、仮想マシン自身が使うメモリも同じアドレス空間に保持しないといけないので、この手法を実現するには、ホストのアドレス空間がゲストのアドレス空間より大きい必要があります。この手法は、64ビットプラットフォームの上でIA-32 ISAをエミュレートする時などに使うことができます。
まだ、
といった項目が残っていますが、今日は切りがいいのでここまでで。