web-dev-qa-db-ja.com

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

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

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

これらの3つのゲートにはすべて、権限の境界を越えた呼び出しに必要な情報が含まれているので、不思議に思っています。なぜ3種類必要なのですか? 1で十分ではないですか?

あなたの時間と応答をありがとう。

アップデート1

関連質問: 割り込みゲートまたはトラップゲートを使用する場合?

アップデート2

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

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

40
smwikipedia

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

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

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

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

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

更新

コメントに答えるには:

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

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

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

今日もほとんど関係ありません。今日、 高速と低速の割り込みハンドラー (「高速および低速ハンドラー」を検索)の間に実質的な区別はありません。割り込みハンドラーはネストされた方法で実行できます。SMPプロセッサーローカル割り込みの無効化とスピンロックなどを組み合わせることを必須にします。

現在、トラップゲートは実際にソフトウェアの割り込みや例外などを処理するために使用されています。ページフォールトまたはプロセッサのゼロ除算例外は、おそらくトラップゲートを通じて処理されます。トラップゲートを使用してプログラムの実行を制御する最も簡単な例は、デバッガーにブレークポイントを実装するために使用されるINT 3命令です。仮想化を行うと、ハイパーバイザーはリング0で実行され、ゲストカーネルは通常リング1で実行されます。この場合、特権コードは一般的な例外エラーで失敗します。 WitchelとRosenblumは バイナリ変換 を開発しました。重要な指示が発見され、トラップに置き換えられます。次に、トラップが実行されると、制御はVMM /ハイパーバイザーに渡されます。VMM/ハイパーバイザーは、リング0の重要な命令をエミュレートする役割を果たします。

ハードウェア支援の仮想化では、トラップアンドエミュレート手法の使用はある程度制限されています(特に動的な場合は非常に高価であるため)が、バイナリ変換の手法は 今でも広く使用されています

詳細については、以下を確認することをお勧めします。

  • Linuxデバイスドライバー、第3版(利用可能 オンライン
  • バイナリ変換の場合、 [〜#〜] qemu [〜#〜] が優れた出発点です。
  • トラップアンドエミュレートについては、ソフトウェア/ハードウェアテクニックの比較 比較 を確認してください。

お役に立てれば!

61

建築とデザイン

保護の観点から見ると、x86アーキテクチャは階層リングに基づいており、プロセッサによって提供されるすべての実行スペースは4つの 階層保護ドメイン に分割され、それぞれに独自のレベルの特権があります割り当てられた。この設計では、ほとんどの場合、コードは最も権限の少ないドメインで実行され、より権限の高いセキュリティドメインのサービスが要求され、このサービスは権限の低いアクティビティをスタックにプリエンプトし、それを次のように復元します。特権の低いコードでは、プリエンプション全体が見えなくなります。

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

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

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

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

ゲートのタイプ

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

タスクゲート

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

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

実際には、誰もそれを使用せず、ハードウェアコンテキストの切り替えも行いません。実際には、この機能はパフォーマンスの観点からは最適ではなく、使い勝手もよくありません。たとえば、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に保存でき、CALLJMP命令によって呼び出されます。トラップゲートに似ていますが、さらに、ユーザーモードタスクスタックからカーネルモードタスクスタックに多数のパラメーターを渡すことができます。渡されるパラメーターの数は、コールゲート記述子で指定されます。

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

  • トラップゲート(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のどのタイプのゲートもソフトウェアで呼び出すことができます。システムコールと例外にトラップゲートを使用する理由は簡単です。割り込みを無効にする理由はありません。割り込みの無効化は、割り込み処理のレイテンシが増加し、割り込みが失われる可能性が高くなるため、悪いことです。このため、深刻な理由がない限り、誰もそれらを無効にすることはできません。

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

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

20
ZarathustrA

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

8
Hans Passant