コラム2
実装の前に
このアイデアを実装するにあたっては、いくつかの注意事項があります。
- page tableは単純な木構造ではなく、プロセス間でページを共有していたりします。page tableとして使用されるページが複数のpage table内のどの段数目で使われるかは一定する必要はなく、また読み書き対象ページとしてもアクセスされます。
このような状況でshadowしているpage tableエントリが、不正なページをさすことがない様に管理する必要があります。
- page tableページへの変更の追跡
cpuは性能向上のためtlbキャッシュにアドレス変換をキャッシュし、page tableエントリに変更があってもキャッシュの破棄は行いません。カーネルは変更を有効にする為にtlb flushを発行する必要があります。そこで、単純な実装であればハイパーバイザーはtlb flush毎にshadow page tableを破棄して、新たにshadow page tableを構成し直す事にすれば良いと思われます。しかしそれではオーバーヘッドが大きい為、page tableページに対する書き込みを検出することにより何らかの最適化を行うことになります。 - access bit/dirty bit
プロセスがあるアドレスに読み込み/書き込みを行ったことを対応するpage tableエントリのaccess bit/dirty bitを立てることにより、カーネルに通知する機能があります。実際カーネルがページの使用状況を知るのにこの機能を使っており、access bit/dirty bitを読み出したりクリアすることがあります。そのようなアクセスに対し、何らかの形でエミュレートが必要となります。そのようなアクセスを検出し読み書きをエミュレートする為に、ゲストがpage tableとして使用しているページを追跡し、page tableページをアクセス可能/書き込み可能でマップした場合に、シャドウしているエントリではアクセス不可/書き込み不可とする必要があります。 - ページの使用方法の変化
ページは時間経過にともないある時はプロセスのページとして使用され、ある時はpage tableページとして使用されたりします。特に読み書き可能で使用されていたページがpage tableページとして使用されるようになる時にshadow page table側で書き込み不可であることを保証する必要があります。 - メモリ使用量の制限
shadow pageに使用できるメモリ量は何らかの形で制限を行う必要があります。潜在的にはゲストが使用しているページの全てがpage tableページとして使用される可能性があります。しかしpage shadowingに対してゲストと同量のメモリを割り当てるのではメモリの使い過ぎです。何らかの形で使用量を制限し、超過するようであれば使用しているページの回収を行う必要があります。 - x86アーキテクチャ
x86アーキテクチャは16bitリアルモードから64bitプロテクトモードまで非常に多様なモードを持っています。それらハイパーバイザーの動作モードとゲストの動作モードの組合わせの全てをサポートするのは非常な労力を要します。もっとも、全てをサポートする必要はないかも知れませんが、最低限ゲストOSが動作するモードとゲストOSが起動するまでに使用する機能の部分は実装する必要があります。