156 Views
May 05, 20
スライド概要
INVLPG invalidates an TLB entry. If you forget to issue INVLPG, you may encounter memory inconsistency.
サイボウズ・ラボ株式会社で教育向けのOSやCPU、コンパイラなどの研究開発をしています。
1を書いても0が読める!? 隠れた重要命令INVLPG ゆるバグ2 @uchan_nos 2020年5月6日
先週のゆるバグでバグを発表した 自作OS「MikanOS」の一部のアプリが実機GPD MicroPCで動かない 調査を進めると あるメモリ領域に1を書いたはずなのに読むと0 1を2回書くと1が読める などの謎挙動が観測された
fprintfでgrepが死ぬ
extern "C" void main(int argc, char** argv) {
// コメントアウトすると死なない
//DumpMem(reinterpret_cast<uint64_t>(_impure_ptr) + offsetof(_reent, __sdidinit), 2);
//fprintf(stderr, "hoge¥n");
//DumpMem(reinterpret_cast<uint64_t>(_impure_ptr) + offsetof(_reent, __sdidinit), 2);
// "argv[" を表示した時点で死んでしまう
for (int i = 0; i < argc; ++i) {
fprintf(stderr, "argv[%d] = %s¥n", i, argv[i]);
}
fprintf(stderr, "----¥n");
原因判明 MikanOSのアプリはまずROでマップされる .text,.data,.bss 初めての書き込みでCoW 最終的に.textだけは各プロセスで共通になる RO 仮想ページ コピー RW CoWしたときにINVLPGしてなかった 物理フレーム 物理フレーム
INVLPG TLBエントリを無効化(invalidate)する TLB???
TLB 1回のメモリアクセスをするために リニアアドレス→物理アドレス 変換が必要 毎回階層ページング構造を辿るのは高コスト 64ビットモードでは4レベル:PML4,PDP,PD,PT メモリアクセスが5倍になってしまう… 変換結果をTLBにキャッシュして高速化! ページ番号 物理アドレス アクセス権 フラグ TLBエントリ
INVLPGを忘れると… INVLPGを忘れると, mov [mem], 1 ; CoW mov rax, [mem] ; rax == 0 メモリに1を書いても0が読める, というような不整合が発生する RO mem: 0 RW mem: 0 仮想ページ 実機ではどっちも0のまま…