- 物理機リージョン/AZ
- ハイパーバイザVM exit で捕まえる今ここ
- VMゲストOS今ここ
- コンテナnamespace / cgroup
- プロセスアプリ / DB
第9週で学んだ表引きが、VMの中では2段重ねになります。表の形は同じまま、辿る回数が増えます。
まず結論
ゲストOSが「物理アドレス」と思って使う番号は、ホストから見ればまだ仮想アドレスです。表引きが2段重ねになり、両方の表を辿ってはじめて実物の番地に着きます。
帰結として変換の代償が桁で増え、4階層×4階層では最悪24回のメモリ参照が要る計算になります。そしてVM内の free が見せる量は、ホストの物理メモリではなく割り当てです。
VMの中で `free -m` を見たら空きが2GBあった。ホストの物理メモリが2GB空いていると言えるでしょうか。
当てることが目的ではありません。外した予測ほど記憶に残るので、直感で選んでください。
「物理アドレス」が2人ぶんある
前のレッスンで、ハイパーバイザが特権的な操作を捕まえて処理する様子を見ました。メモリでも同じ問題が起きます。ゲストOSは機械を独占している前提でページテーブルを組み立てるからです。
第9週で、プロセスが見ているアドレスは偽物で、CPUが表を辿って実物の番地へ変換していると学びました。VMではこれがもう一段増えます。ゲストOSが「物理アドレス」と呼ぶ番号は、ホストにはまだ変換前の値です。その番号空間ごとホストの作り物なのです。
CPUには、この2段目を専用にこなす仕組みがあります。Intelの呼び名がEPT、AMDの呼び名が Nested Paging です。
根が2つある
AMDのマニュアル(Rev.3.23)§15.25 は、この2段を表の根から説明します。
段 表 根 写す向き1段目 gPT gCR3 guest linear → guest physical2段目 nPT nCR3 guest physical → system physical
同じ節に次の一文があります。
It is important to note that gCR3 and the guest page table entries contain guest physical addresses, not system physical addresses. Hence, before accessing a guest page table entry, the table walker first translates that entry's guest physical address into a system physical address.
つまりゲストの表そのものの置き場所も、ゲスト物理アドレスで書かれているのです。1段辿るには、その所在を先に2段目の表で引かねばなりません。この入れ子が回数の増え方を生みます。
EPTやNested Pagingが入ると、ゲストのページテーブルが指す番号はどう扱われますか。
足し算ではなく、掛け算に近い
Bhargava らの2008年の論文(ASPLOS XIII)の一般式です。
If a guest page walk has n levels and a nested page walk has m levels, a 2D walk requires nm + n + m page entry references.
n がゲスト表の階層数、m がホスト表の階層数です。x86-64 はどちらも4階層なので 16 + 4 + 4 = 24回。(4+1)×(4+1) − 1 と書いても同じ値です(展開すると nm + n + m + 1 − 1)。
同論文 §2.2 の内訳です。
A single four-level guest table walk invokes the nested page walker five times, once for each guest page entry (gL4 to gL1) and once for the final translation of the guest physical address of the datum itself (gPA).
ゲスト表の4段ぶんの入口と、データ本体のゲスト物理アドレス。この5箇所をホストの4階層で引くので 5 × 4 = 20回。加えてゲスト表自身の4回で合計24回です。足し算で8回にならないのは、各段の所在がゲスト物理アドレスだからでした。
論文は、この24回がネイティブなページウォーク(4回)の6倍だと述べています。
見えている総量は、割り当ての内側
もう一つ読み違えやすいものがあります。VMの中から見えるメモリの総量です。手元のMacとその上のLinux VMを並べます。
$ sysctl hw.memsizehw.memsize: 25769803776$ docker info | grep -i 'total memory\|kernel version'Kernel Version: 6.10.14-linuxkitTotal Memory: 7.654GiB$ docker run --rm alpine free -mtotal used free shared buff/cache availableMem: 7837 2154 230 113 5454 5373
ホストの搭載量は 25769803776 バイト(24GiB)。しかしVMの中の total は 7837MiB で、docker info の Total Memory: 7.654GiB と一致します。見えているのはこのVMへの割り当てです。free が空きを報告しても、ホストの余裕は分かりません。
持ち分は固定でもありません。virtio の仕様の balloon デバイスの説明です。
The traditional virtio memory balloon device is a primitive device for managing guest memory: the device asks for a certain amount of memory, and the driver supplies it (or withdraws it, if the device has more than it asks for). This allows the guest to adapt to changes in allowance of underlying physical memory.
デバイス側が量を求め、ドライバ(ゲスト)が差し出す。ゲストが見る量は、ホストが許した allowance の内側で動きます。
4階層のゲスト表と4階層のホスト表で、1つの変換に必要なメモリ参照が最悪24回になるのはなぜですか。
第9週『仮想メモリ』の4階層×1回
物理機の上のプロセスの変換です。x86-64では仮想アドレスを4階層の表で辿り実物の番地へ着きます。表のエントリの所在は最初から物理アドレスなので、追加の変換は要りません。
walk refsgL4 → gL3 → gL2 → gL1 4-----------------------------total 4
4階層×4階層の2次元ウォーク
VMの中の変換です。ゲストの表のエントリはゲスト物理アドレスなので、1段辿るごとホストの表を引き直します。データ本体のゲスト物理アドレスも変換が要ります。
walk refsgL4..gL1 の入口 × nPT 4段 16gPA (データ本体) × nPT 4段 4gL4 → gL3 → gL2 → gL1 4---------------------------------total 24
表引きを2段重ねると、1つのアドレス変換が何回のメモリ参照になりうるでしょうか。なぜ 4 + 4 = 8 にならず、掛け算に近くなるのでしょうか。
ゲストのページテーブルそのものが、どの番号空間に置かれているか考えてみてください。
図にすると、変換が2本ぶら下がっている
- ・1段目の表のエントリ自体もゲスト物理アドレスなので、辿るたび2段目を引き直す
- ・TLBが当たっていれば、この道のりはまるごと省かれる
この章のまとめ
- ゲストOSが「物理アドレス」と呼ぶ番号は、ホストにはまだ変換前の値。だから表引きが2段重ねになる(Intelの呼び名がEPT、AMDの呼び名がNested Paging)。
- ゲストの表のエントリ自体もゲスト物理アドレスなので、1段辿るたび2段目を引き直す。
- 4階層×4階層では参照が nm + n + m = 24回。ネイティブの4回の6倍だが、これは回数の比で速度比ではなく、TLBが外れた場合の上限。
- VM内の free が見せる総量は、そのVMへの割り当て。ホストの余裕は示さない。持ち分は balloon デバイス経由で動くこともある。
この先の学びにどう繋がるか
次は、ゲストOSを増やさずに「見える世界」だけを分ける方法へ進みます。手を動かすなら、クイズ群「仮想化とコンテナ隔離の原理」の『仮想化II(メモリとI/Oの仮想化)』がこの2段変換を扱っています。
自分の現場で確かめる
読んだだけでは身につきません。手元の環境で実際に見てみてください。
理解度チェック
読んだ直後は「分かった」と感じやすいものです。実際に解いて確かめてください。
二重のアドレス変換で、ゲストOSが扱う「物理アドレス」の位置づけとして正しいものはどれですか。
用語集(5語)
- ゲスト物理アドレス
- ゲストOSが物理アドレスだと思って扱う番号。ホストにはまだ変換前の値で、もう一組の表を通して実物の番地になる。
- EPT (Extended Page Tables)
- Intelの拡張ページテーブル機構。ゲスト物理アドレスをEPTページング構造で辿り、メモリアクセスに使う物理アドレスを作る。
- Nested Paging
- AMDの同種の機構の呼び名。gPT と nPT の2段で、それぞれ gCR3 / nCR3 が根を指す。
- 2次元ページウォーク
- ゲスト表とホスト表を重ねた表引き。ゲストがn階層、ホストがm階層なら、ページエントリ参照は nm + n + m 回。
- balloon デバイス
- ゲストのメモリ持ち分を動かす仮想デバイス。デバイス側が量を求め、ドライバ(ゲスト)が差し出したり引き戻したりする。
出典(一次ソース)
- Intel 64 and IA-32 Architectures SDM Vol.3 (Order 325384-092US, June 2026) §31.3 The Extended Page Table Mechanism (EPT) ↗
- AMD64 Architecture Programmer's Manual Vol.2 (Rev.3.23, May 2013) §15.25 Nested Paging ↗
- Bhargava et al., Accelerating Two-Dimensional Page Walks for Virtualized Systems (ASPLOS XIII, 2008) ↗
- OASIS virtio specification — Traditional Memory Balloon Device ↗