はい、マシンコードとすべてのメモリオペランドが必要です。
CPUはメモリページに順次アクセスするべきではありませんか。つまり、最初に命令を読み取ってから、メモリオペランドにアクセスしますか?
はい、それは論理的に何が起こるかですが、ページフォールト例外が2ステップのプロセスを中断し、進行状況を破棄します。CPUには、ページフォールトが発生したときの途中の命令を記憶する方法がありません。
有効なページフォールトを処理した後にページフォールトハンドラーが戻ると、RIP =フォールトが発生した命令のアドレスであるため、CPUはその実行を再試行します。 は最初からます。
OSが障害のある命令のマシンコードを変更し、その後に別の命令を実行することを期待することは合法です iret
障害し、ページフォールトハンドラー(またはその他の例外ハンドラーまたは割り込みハンドラー)から。つまり、あなたが話している場合に備えて、CPUがCS:RIPからのコードフェッチをやり直すことがアーキテクチャ上要求されています。(ハードページフォールトでディスクを待機している間に別のプロセスをスケジュールしたり、無効なページフォールトでSIGSEGVをシグナルハンドラーに配信したりする代わりに、障害のあるCS:RIPに戻ると仮定します。)
また、ハイパーバイザーの入り口/出口にもアーキテクチャ上必要となるでしょう。また、紙で明示的に禁止されていなくても、CPUの動作方法ではありません。
@torekは、一部の(CISC)マイクロプロセッサが部分的に命令をデコードし、ページフォールト時にマイクロレジスタの状態をダンプするとコメントしていますが、x86はそうではありません。
いくつかの命令は割り込み可能rep movs
で、(canのmemcpy)や他の文字列命令のように部分的に進行したり、ロード/スキャッターストアを収集したりできます。ただし、唯一のメカニズムは、文字列操作の場合はRCX / RSI / RDIなどのアーキテクチャレジスタ、または収集の場合は宛先およびマスクレジスタを更新することです(AVX2のマニュアルなど)。vpgatherdd
)。opcode / decodeを保持しないと、一部の非表示の内部レジスタが発生し、ページフォールトハンドラーからiretした後に再起動します。これらは、複数の個別のデータアクセスを行う命令です。
また、x86(ほとんどのISAと同様)は、命令がアトミックなwrtであることを保証することにも留意してください。割り込み/例外:割り込みの前に完全に発生するか、まったく発生しないかのいずれかです。 動作中にアセンブリ命令に割り込む。したがって、たとえばadd [mem], reg
、lock
プリフィックスがなくてもストアパーツに障害が発生した場合は、ロードを破棄する必要があります。
前進するために存在するゲストユーザー空間ページの最悪の場合の数は6(さらに、それぞれに個別のゲストカーネルページテーブルサブツリー)になる可能性があります。
movsq
またはmovsw
、ページ境界にまたがる2バイトの命令なので、デコードするには両方のページが必要です。
- qwordソースオペランド
[rsi]
もページ分割
- qword宛先オペランド
[rdi]
もページ分割
これらの6ページのいずれかに障害が発生した場合は、スクエアページに戻ります。
rep movsd
も2バイトの命令であり、その1つのステップで進行する場合も同じ要件があります。同様の例は好きpush [mem]
かpop [mem]
ずれスタックで構成することができます。
ギャザーロード/スキャッターストアを「中断可能」にする(マスクベクトルを進行状況に合わせて更新する)理由の1つ(または副次的な利点)は、この最小フットプリントを増やして単一の命令を実行しないようにすることです。また、1回の収集または分散中に複数の障害を処理する効率を改善します。
@Brandonは、ゲストがメモリ内のページテーブルを必要とすることをコメントで指摘しており、ユーザー空間のページ分割を1GiB分割にすることもできるため、2つのサイドがトップレベルのPML4の異なるサブツリーにあります。HWページウォークは、これらのゲストページテーブルのすべてのページに触れて、進行する必要があります。この病理学的な状況が偶然に起こることはまずありません。
TLB(およびページウォーカーの内部)は、ページテーブルデータの一部をキャッシュすることができ、OSがinvlpg
新しいCR3トップレベルページディレクトリを設定または設定しない限り、ページウォークを最初から再起動する必要はありません。ページを存在しない状態から存在する状態に変更する場合、これらはどちらも必要ありません。紙の上のx86は、それが不要であることを保証します(したがって、存在しないPTEの「ネガティブキャッシング」は許可されません。少なくともソフトウェアからは見えません)。そのため、ゲスト物理ページテーブルページの一部が実際に存在しない場合でも、CPUはVMexitしない可能性があります。
PMUパフォーマンスカウンターを有効にして、命令がその命令のPEBSバッファーに書き込むためのパフォーマンスイベントも必要とするように構成できます。カーネルではなく、ユーザー空間の命令のみをカウントするようにカウンターのマスクを構成すると、ユーザー空間に戻るたびにカウンターがオーバーフローし、サンプルがバッファーに格納され続け、ページフォールトが発生する可能性があります。