CPUの二重障害の原因は何ですか


0

例外(同期)が発生し、それ以外の場合にプロセッサのカーネルモード(またはx86の場合はリング0)でのみ二重フォールトが発生する可能性があると言う場合、それは私の仮定です。

答えが「はい」の場合、古いプロセッサと互換性のある新しいプロセッサでは、カーネルモードで実行されるコード、未定義の命令の理由でこの互換性を維持したい場合は既に定義された命令(新しいCPU)で使用できません例外は、正しいですか?そしてもう1つの質問。CPUがカーネルモードで実行されるコードを実行する場合、ページフォールトの理由でメモリに表示する必要がありますか?

そして、私の追加の考え。割り込み/例外の発生とその戻りで自動的に設定およびクリアされるステータスレジスタの「内部INTイネーブルビット」が実装され、例外が発生した場合にHWがこのビットを読み取り、設定されている場合は、例外ハンドラのアドレス、そうでなければirは二重障害ハンドラにジャンプしますか?

アーキテクチャ/ OSに依存する場合、MIPS上のLinuxを選択します。

私の英語でごめんなさい。


1
質問をStackOverflowに送信することをお勧めします。あなたの質問はハードウェアと多くの関係がありますが、ここにはアセンブラープログラマーやカーネルハッカーはほとんどいません。頑張って。
フランクトーマス

彼らはその移住を拒否します
。...-ラムハウンド

1
コードも要求もありません。なぜここにトピックがないのですか?
ラムハウンド

そこに4つの質問があるように思えるので、私はあまりにも広大であるとして終了することに投票しています。
DavidPostill

回答:


1

私があなたに与えることができる最善の答えは、はい、ほとんどの最新のCPUではカーネルモードで実行されているコードのみが二重または三重障害を引き起こすことができるということです。非カーネル起動命令がハードフォールトをトリガーすることは非常にまれです(不可能ではありません)。これは、無効なレジスタアドレスに分岐できなくなるように物理アドレス指定を抽象化するProtectedModeオペレーションのためです。

そういうわけで、はい、ProtectedModeなしでCPU用にアセンブルされたマシンコードは、変更されていなければ、少なくとも新しいCPUで動作するように再アセンブルする必要があります。

ウィキペディアから:https : //en.wikipedia.org/wiki/Protected_mode#Virtual_8086_mode

仮想8086モード主な記事:仮想8086モード

386のリリースでは、プロテクトモードは、Intelのマニュアルで仮想8086モードと呼ばれるものを提供します。仮想8086モードは、以前に8086用に記述されたコードを、セキュリティやシステムの安定性を損なうことなく、変更せずに他のタスクと同時に実行できるように設計されています。

ただし、仮想8086モードには、すべてのプログラムとの完全な下位互換性はありません。セグメント操作、特権命令、ハードウェアへの直接アクセスを必要とするプログラム、または自己変更コードを使用するプログラムは、オペレーティングシステムによって処理される必要がある例外を生成します。[30] さらに、仮想8086モードで実行されているアプリケーションは、入出力(I / O)を伴う命令を使用してトラップを生成します。これは、パフォーマンスに悪影響を与える可能性があります。[31]

これらの制限により、元々8086で実行するように設計された一部のプログラムは、仮想8086モードで実行できません。その結果、システムソフトウェアは、レガシーソフトウェアを扱う際に、システムのセキュリティを侵害するか、下位互換性を強制されます。このような妥協の例は、Windows NTのリリースで見ることができます。WindowsNTでは、「不正な」DOSアプリケーションの後方互換性が低下しました。[32]

それが少し助けになり、それが不十分な場合、別の人が私の理解のギャップを埋めることができることを願っています。


ご回答いただきありがとうございますが、申し訳ありませんが、私の質問には回答していません。新しいCPUでは、実際のアドレスで動作するプロセッサと仮想アドレスで動作するプロセッサの間の移行を意味しませんでした。何らかのCPUの後継(一部の保護を備えた仮想アドレス指定をサポートし、完全に前方互換性がある)が新しい命令を追加した場合、この命令がこれらのCPUの両方で実行されるソフトウェアのカーネルモードで使用できる場合 この場合、カーネルモードのCPUは、未定義の命令例外のために、古いCPUで二重フォールトを呼び出しますが、本当ではありませんか?
ニックノヴァーク

未定義の命令例外は、割り込みまたは例外ルーチンで指示された命令である場合に、ダブル/トリプルフォールトを引き起こします。ただし、通常のコード内にある場合は、そうではありません。障害が発生し、例外処理への分岐は通常どおり発生するはずです。ただし、保護モードまたはカーネルモードがどこに来るのかはよくわかりません。プロテクトモードの互換性を回避するためにいくつかのコードをカーネルとして実行し、このアプローチが問題を引き起こす可能性があるかどうかを尋ねることを計画していますか?はい、可能だからです。しますか?コードとハードウェアに依存します。
フランクトーマス

ご回答ありがとうございます。いいえ、これは私の計画ではありません。それで、「通常の」コードがカーネルモードで実行されている場合、二重フォールトハンドラーを直接呼び出して例外は発生しませんが、適切な例外ハンドラーを呼び出しますか?もしそうなら、「通常の」コードと割り込みハンドラーコードの違いはどこにあり、どの例外ハンドラーが呼び出すべきかをCPUがどのように知るか?(すべての例外ハンドラーと二重障害ハンドラーを意味します)
ニックノヴァーク

二重障害は、1つの障害があるときに発生し、その後、CPUがそれを処理しようとすると、ハンドラー内で別の障害が発生します。二重フォールトはハンドラーコードでのみ発生します。だから、問題の命令は例外/割り込みハンドラの一部ですか?その場合、二重障害が発生する可能性があります。そうでない場合、できません。
フランクトーマス

ご回答ありがとうございます。あなたによって、カーネルスレッドは通常例外を引き起こすことができますか?(プログラマーのミスを意味するわけではありませんが、たとえば、既に定義されていない命令、ページフォールト(カーネルスレッドで可能な場合はスワップアウトされている可能性があります))例外(両方ともCPUカーネルモードで実行)が発生しますか?
ニックノヴァーク

1

私はx86で多くの経験を持っていますが、MIPSには何もありません。申し訳ありませんが、とにかく以下の説明が当てはまると思います。

二重障害は、非常に特定の状況でのみ発生します。例外ハンドラを開始しようとしたときに別の例外が発生すると、最初の例外が破棄され、代わりに二重障害例外ハンドラが呼び出されます。

単純な障害の例を次に示します。コードが無効なメモリにアクセスしようとする場合:

*(int *)0 = 0xdead;

次に、CPUはNULLポインター参照を検出し、メモリ障害ハンドラーの起動を試みます。これは、ユーザー(リング3)またはスーパーバイザー(リング0)コードにあり、二重フォールトは発生しません。CPUは、単純にメモリフォールトハンドラーを開始しようとします。

OSにバグがあり、メモリー障害ハンドラー自体が無効なメモリーにあったと想像してください。したがって、メモリー障害ハンドラーを開始しようとしたときに、別の障害が発生し、最初の障害を処理できませんでした。その後、二重障害ハンドラーが呼び出されます。(二重障害ハンドラーを開始しようとして障害が発生した場合、x86 CPUは単純に三重障害でシャットダウンします。PCハードウェアはこれを検出し、CPUをリセットします。)

障害ハンドラーが正常に開始されると、二重障害は発生しなくなるため、開始を繰り返し強調しました。最初の障害の処理が開始され、CPUが新しい障害を処理できるようになりました。CPUは、フォールトハンドラー内にあることを「記憶」せず、新しいフォールトが発生した場合に二重フォールトを引き起こします。

あなたの例では、フォルトハンドラが未定義のオペコードを使用しようとすると、その命令で未定義のオペコードフォルトハンドラが呼び出されます。これは二重障害ではなく、障害内の障害にすぎません。

もちろん、メモリフォールトハンドラーが起動し、処理中にメモリフォールトが発生した場合、メモリフォールトハンドラーが再起動されます。これにより、同じメモリ障害が再び発生する可能性があり、メモリ障害ハンドラが再起動されます-毎回、より多くのスタックを使用するたびに、最終的にスタック自体がオーバーフローします(x86では異なる障害ハンドラです)。


そして最後に、メモリフォールトハンドラーを呼び出そうとしてスタックオーバーフローが発生すると、ダブルフォールトが発生します。
ルスラン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.