36


30

コールゲート、割り込みゲート、トラップゲートの違いは?

Intel保護モードを勉強しています。 コールゲート、割り込みゲート、トラップゲートはほぼ同じであることがわかりました。 実際、Call Gateにはパラメーターカウンター用のフィールドがあり、これら3つのゲートには異なるタイプのフィールドがあるだけでなく、他のすべてのフィールドでも同じです。

それらの機能に関しては、それらはすべて、コード制御をあるコードセグメント内のあるプロシージャに転送するために使用されます。

これら3つのゲートにはすべて、特権の境界を越えた呼び出しに必要な情報が含まれているので、私は疑問に思っています。 なぜ3種類必要なのですか? 1だけでは十分ではありませんか?

お時間をいただきありがとうございます。

更新1

関連する質問:https://stackoverflow.com/questions/3442193/when-to-use-interrupt-gate-or-trap-gate[Interrupt GateまたはTrap Gateを使用するタイミング]

更新2

今日、私はこの考えを思いつきました:

異なる目的、異なるゲート、異なるCPU動作の詳細が実行されます。 IFフラグ処理など。

3 Answer


58


ゲート(呼び出し、割り込み、タスク、またはトラップ)は、セグメント間で実行の制御を転送するために使用されます。 特権レベルのチェックは、使用する宛先と命令のタイプによって異なります。

コールゲートは、CALLおよびJMP命令を使用します。 コールゲートは、低い特権コードから高い特権コードに制御を移します。 ゲートDPLは、ゲートにアクセスできる特権レベルを決定するために使用されます。 コールゲートは、より高速なSYSENTER / SYSEXITメカニズムを優先して徐々に(またはおそらく)放棄されています。

タスクゲートは、ハードウェアマルチタスクのサポートに使用されます。 ハードウェアタスクの切り替えは、自発的に(タスクゲート記述子へのCALL / JMP)、またはNTフラグが設定されているときに割り込みまたはIRETを介して発生します。 割り込みゲートまたはトラップゲートでも同じように機能します。 私の知る限り、タスクゲートは使用されません。カーネルは通常、タスクの切り替え時に余分な作業を行う必要があるためです。

割り込みゲートとトラップゲートは、タスクゲートとともに、割り込み記述子テーブルとして知られています。 これらは、1つの特権スタックから別の特権スタックへのパラメーターの転送を除き、コールゲートと同じように機能します。 1つの違いは、割り込みゲートはEFLAGSのIFビットをクリアしますが、トラップゲートはクリアしないことです。 これにより、ハードウェア割り込みの処理に最適です。 トラップは、ハードウェア支援の仮想化で広く使用されています。

詳細については、興味のあるプロセッサのIntelアーキテクチャマニュアルを参照してください。

更新

コメントに回答するには:

割り込みとトラップを区別する理由はたくさんあります。 1つはスコープの違いです。割り込みゲートはカーネルスペースを指します(結局、ハードウェアを管理するのはカーネルです)が、トラップはユーザースペースで呼び出されます。 割り込みハンドラはハードウェアイベントに応答して呼び出され、トラップはCPU命令に応答して実行されます。

割り込みゲートとトラップゲートがEFLAGSを異なる方法で処理する理由をよりよく理解するための簡単な(しかし非実用的な)例については、ユニプロセッサシステムでハードウェアイベントの割り込みハンドラを記述していて、IFビットをクリアできない場合にどうなるかを考えてください1つを提供していました。 最初のサービスを提供している間に2回目の割り込みが発生する可能性があります。 それから、割り込みハンドラは、IH実行中のランダムなポイントでプロセッサによって呼び出されます。 これは、データの破損、デッドロック、またはその他の悪い魔法につながる可能性があります。 実際には、割り込みの無効化は、一連のカーネルステートメントがクリティカルセクションのように扱われるようにするメカニズムの1つです。

ただし、上記の例では、マスク可能な割り込みを想定しています。 とにかく、NMIを無視したくないでしょう。

今日もほとんど関係ありません。 現在、http://www.xml.com/ldd/chapter/book/ch09.html#t3 [高速割り込みハンドラーと低速割り込みハンドラー](「高速ハンドラーと低速ハンドラー」を検索)の間に実質的な区別はありません。ネストされた方法では、SMPプロセッサは、ローカル割り込みの無効化とスピンロックの結合などを必須にします。

現在、トラップゲートは、ソフトウェアの割り込み、例外などを処理するために実際に使用されています。 プロセッサのページフォールトまたはゼロ除算例外は、おそらくトラップゲートを介して処理されます。 トラップゲートを使用してプログラムの実行を制御する最も簡単な例は、デバッガーにブレークポイントを実装するために使用されるINT 3命令です。 仮想化を行うと、ハイパーバイザーはリング0で実行され、ゲストカーネルは通常リング1で実行されます-特権コードは一般的な例外エラーで失敗します。 WitchelとRosenblumはhttp://portal.acm.org/citation.cfm?doid=233013.233025[binary translation]を開発しました。これは基本的に、命令を書き換えて効果をシミュレートします。 重要な指示が検出され、トラップに置き換えられます。 次に、トラップが実行されると、リング0の重要な命令をエミュレートするVMM /ハイパーバイザーに制御が渡されます。

ハードウェア支援の仮想化では、トラップアンドエミュレート手法の使用は多少制限されています(特に動的な場合は非常に高価なので)が、バイナリ変換の実践はhttp://www.cse.ucsd.edu/ 〜jfisherogden / hardwareVirt.pdf [まだ広く使用されています]。

詳細については、チェックアウトすることをお勧めします。

  • Linuxデバイスドライバー、第3版(利用可能 online

  • バイナリ翻訳の場合、http://wiki.qemu.org/Main_Page [QEMU]は 素晴らしいスタート。

  • トラップアンドエミュレートについては、こちらをご覧ください http://www.vmware.com/pdf/asplos235_adams.pdf [比較]ソフトウェア/ハードウェア技術の比較。

お役に立てれば!


17


建築とデザイン

保護の観点から、x86アーキテクチャは階層リングに基づいており、プロセッサによって配信されるすべての実行スペースは、それぞれが4つのhttps://en.wikipedia.org/wiki/Protection_ring[hierarchical protection domains]に分割されます。そのうち独自のレベルの特権が割り当てられています。 この設計では、ほとんどの時間コードが最小特権ドメインで実行され、場合によってはより高い特権のセキュリティドメインからのサービスが要求され、このサービスは低い特権のアクティビティをスタックに差し替えて、次のように復元することを想定しています特権の少ないコードでは、プリエンプション全体が見えなくなります。

階層保護ドメインの設計では、異なるセキュリティドメイン間でコントロールを任意に渡すことはできないとされています。

ゲートは、特権の少ないコードセグメントから特権の高いコードセグメントへの制御転送のためのx86アーキテクチャの機能ですが、その逆はできません。 さらに、制御が渡される特権レベルの低いセグメントのポイントは任意ですが、制御が渡される特権レベルの高いセグメントのポイントは厳密に指定されます。 特権の少ないセグメントへの後方制御の受け渡しは、「IRET」命令によってのみ許可されます。 これに関して、Intel Software開発者マニュアルの主張:

_ 低い特権セグメントのコードモジュールは、ゲートと呼ばれる厳重に制御され保護されたインターフェイスを使用して、高い特権セグメントで動作するモジュールにのみアクセスできます。 保護ゲートを通過せず、十分なアクセス権を持たずに、より高い特権のセグメントにアクセスしようとすると、一般保護例外( #GP)が生成されます。 _

つまり、ゲートは、必要なアクセス権とターゲットアドレスを持つ特権ドメインエントリポイントです。 このように、すべてのゲートは類似しており、ほぼ同じ目的に使用されます。すべてのゲート記述子には、アクセス権を制御するためにプロセッサが使用するDPLフィールドが含まれます。 ただし、プロセッサは、呼び出しのソースがソフトウェアの「CALL」、「JMP」、または「INT」命令である場合にのみゲートのDPLをチェックし、呼び出しのソースがハードウェアの場合、このチェックをバイパスします。

ゲートの種類

すべてのゲートが類似しているという事実にもかかわらず、元々インテルのエンジニアは異なるゲートが異なる目的に使用されると考えていたため、いくつかの違いがあります。

タスクゲート

タスクゲートはIDTとGDTにのみ保存され、「INT」命令によって呼び出されます。 これは非常に特殊なタイプのゲートであり、他とは大きく異なります。

当初、Intelのエンジニアは、タスクスイッチング用のCPUベースの機能を提供することにより、マルチタスクに革命を起こすと考えていました。 彼らは、タスクのレジスタ状態を保持し、ハードウェアタスクの切り替えに使用できるTSS(タスク状態セグメント)を導入しました。 ハードウェアタスクの切り替えをトリガーするには、TSS自体を使用する方法とタスクゲートを使用する方法の2つがあります。 ハードウェアタスクスイッチを作成するには、 CALL`または JMP`命令を使用できます。 私が正しく理解している場合、タスクゲートの導入の主な理由は、ハードウェアタスクスイッチはTSSセレクターへの「JMP」によってトリガーできないため、割り込みの到着に応答してハードウェアタスクスイッチをトリガーする機能を持つことでした。

実際には、誰もそれもハードウェアコンテキストスイッチングも使用しません。 実際には、この機能はパフォーマンスの観点から最適ではなく、使用するのに便利ではありません。 たとえば、TSSはGDTにのみ保存でき、GDTの長さは8192を超えることはできないことを考慮すると、ハードウェアの観点からは8kを超えるタスクを持つことはできません。

トラップゲート

トラップゲートはIDTにのみ保存され、「INT」命令によって呼び出されます。 ゲートの基本的なタイプと考えることができます。 それは、より特権のあるセグメントのトラップゲート記述子で指定された特定のアドレスに制御を渡すだけで、それ以上のことはしません。 さまざまな目的でアクティブに使用されるトラップゲートには、次のものが含まれます。

  • システムコールの実装(たとえば、Linuxは `INT 0x80`を使用し、 Windowsはこの目的のために `INT 0x2E`を使用します)

  • 例外処理の実装(無効にする理由はありません 例外の場合の割り込み)。

  • APICを搭載したマシンでの割り込み処理の実装( カーネルスタックをより適切に制御します)。

割り込みゲート

割り込みゲートはIDTにのみ保存され、「INT」命令によって呼び出されます。 トラップゲートと同じですが、さらに割り込みゲートコールは、EFLAGSレジスタのIFフラグを自動的にクリアすることにより、将来の割り込み受け入れを禁止します。

特にPICベースのマシンで、割り込み処理の実装に積極的に使用される割り込みゲート。 その理由は、スタックの深さを制御するための要件です。 PICには割り込みソースの優先順位機能はありません。 このため、デフォルトでは、PICはプロセッサで既に処理中の割り込みのみを無効にします。 ただし、別の割り込みがまだ途中で到着し、割り込み処理を横取りする可能性があります。 そのため、カーネルスタックには同時に15個の割り込みハンドラーが存在できます。 その結果、カーネル開発者は、メモリのペナルティにつながるカーネルスタックサイズを大幅に増やすか、散発的なカーネルスタックオーバーフローに直面する準備をしなければなりませんでした。 割り込みゲートは、同時に1つのハンドラーのみがカーネルスタックに存在できることを保証できます。

コールゲート

コールゲートはGDLとLDTに保存され、「CALL」と「JMP」命令によって呼び出されます。 トラップゲートに似ていますが、さらに、ユーザーモードのタスクスタックからカーネルモードのタスクスタックに多数のパラメーターを渡すことができます。 渡されるパラメーターの数は、コールゲート記述子で指定されます。

コールゲートは決して一般的ではありませんでした。 その理由はいくつかあります。

  • トラップゲート(Occam’s Razor)に置き換えることができます。

  • 彼らは多くのポータブルではありません。 他のプロセッサには、そのような機能はありません。 オペレーティングシステムを移植する場合、システムコールに対するコールゲートのサポートは、それらのコールを書き換える必要があるため、負担になることを意味します。

  • 柔軟性に欠けるのは、その量が スタック間で渡すことができるパラメーターは制限されています。

  • パフォーマンスの観点からは最適ではありません。

1990年代の終わりに、IntelとAMDはシステムコールに関する追加の指示を導入しました: SYSENTER /` SYSEXIT`(Intel)および SYSCALL /` SYSRET`(AMD)。 コールゲートとは対照的に、新しい命令はパフォーマンス上の利点を提供し、採用されています。

概要

私はマイケル・フカラキスに同意しません。 申し訳ありませんが、「IF」フラグに影響を与えることを除いて、割り込みとトラップに違いはありません。

  • 理論的には、各タイプのゲートは、 任意のレベルの特権を持つセグメント。 実際には、システムコール、割り込み、および例外処理のためにIDTで使用される割り込みおよびトラップゲートのみを使用する最新のオペレーティングシステムでは、これらすべてがカーネルエントリポイントとして機能します。

  • あらゆるタイプのゲート(割り込み、トラップ、タスクを含む)を呼び出すことができます ソフトウェアで「INT」命令を使用します。 特定のゲートへのユーザーモードコードアクセスを禁止できる唯一の機能はDPLです。 たとえば、オペレーティングシステムが特定のゲートのタイプに関係なくIDTを構築する場合、ハードウェアイベント処理に使用されるゲートのカーネルセットアップDPLは0になり、このゲートへのこのアクセスによると、カーネルスペースからのみ許可されます(ほとんどの特権ドメインで実行されます)が、システムコールのゲートを設定するとき、DPLを3に設定して、任意のコードからそのゲートへのアクセスを許可します。 その結果、ユーザーモードタスクは、DPL = 3のゲートを使用してシステムコールを行うことができますが、たとえば、キーボード割り込みハンドラーを呼び出そうとすると、一般保護違反をキャッチします。

  • IDTの任意のタイプのゲートは、ハードウェアによって呼び出すことができます。 人々が使用する このハードウェアイベントの割り込みゲートは、何らかの同期を実現したい場合にのみ処理します。 たとえば、カーネルスタックのオーバーフローが不可能であることを確認します。 たとえば、APICベースのシステムでハードウェア割り込みを処理するためのトラップゲートの使用に成功した経験があります。

  • 同様に、IDTのどのタイプのゲートもソフトウェアで呼び出すことができます。 The システムコールと例外にトラップゲートを使用する理由は簡単です。 割り込みを無効にする理由はありません。 割り込みを無効にすることは悪いことです。なぜなら、割り込み処理の待ち時間が長くなり、割り込みが失われる可能性が高くなるからです。 このため、深刻な理由がない限り、誰もそれらを無効にできません。

  • 割り込みハンドラは通常、厳密な再入可能スタイルで記述されています。 これで ウェイ割り込みハンドラは通常、データを共有せず、透過的に相互に先取りできます。 割り込みハンドラーでデータへの同時アクセスを相互に除外する必要がある場合でも、cliおよびsti命令を使用して、共有データへのアクセスのみを保護できます。 割り込みハンドラー全体をクリティカルセクションと見なす理由はありません。 PICベースのシステムでカーネルスタックオーバーフローが発生する可能性を防止すること以外は、割り込みゲートを使用する理由はありません。

トラップゲートは、カーネルインターフェイスのデフォルトのソリューションです。 何らかの重大な理由がある場合は、トラップゲートの代わりに割り込みゲートを使用できます。


8


IFフラグが自動的にクリアされるため、割り込みゲートは特別です。 コールゲートは、割り込みベクターを介してアクティブにされないため、特別です。 タスクゲートは、プロセッサの状態を自動的に保存するため、特別です。 4つの異なる動作を持ち、それらに4つの名前を付けると便利です。