2009年1月19日月曜日

QEMU internal timer interrupts

cpu_exec の内部では、TB (TranslationBlock) の実行ループが延々と行われている (TB には、ブレークポイントやジャンプ命令は入っていないので、無限ループを実行中でも必ず止まる。止まっては、また実行し、の繰り返し)。

しかし、これだけでは、仮想 CPU の上でエミュレートしている外部ペリフェラル (= 実行中のプログラム) などから割り込みが入らない限り、QEMU の内部の時間を進めることができなくなってしまう。

そこで QEMU は、自ら定期的に割り込み (CPU_INTERRUPT_EXIT) を CPU に入れることにより、cpu_exec 内部の TB (JIT 済みのコード)実行ループから抜けているようだ。これで、QEMU 内部の時間が進み、様々な内部処理を一定間隔で行うことが可能になる。

つまり、TB チェーンの実行を繰り返す小さなループと、定期的に割り込みをチェックして、割り込み要因に合わせて CPU の状態を変化させるための大きなループの、2 つのループが回っている。

exec.c に以下のようなコメントがある。
        /* CPU_INTERRUPT_EXIT isn't a real interrupt.  It just means
           an async event happened and we need to process it.  */
大きいほうのループを動かすため、小さいほうのループに定期的に割り込みを入れる際には、Windows のマルチメディアタイマーを使用しているようだ。

Windows 対応 patch の開発者の方のブログ記事。

(核心部分)

このほかにもたくさん参考になる記事があって、ゲスト OS の時計の進め方を正確にしようと思うと、非常に大変ということがよくわかる。

vl.c を使う (普通に QEMU システム全体を使う) 場合は考えなくても良いけど、仮想 CPU ライブラリ (libqemu.a) の部分だけを使う場合は、ここらへんも考えないとちゃんと動かない。

ちょっと気になった記事。デバッガと繋げる際のはまりポイント。

0 件のコメント:

コメントを投稿