建築とデザイン
保護の観点から、x86アーキテクチャは階層リングに基づいており、プロセッサによって提供されるすべての実行スペースが4つの階層保護ドメインに分割され、それぞれに独自のレベルの特権が割り当てられます。この設計では、ほとんどの場合、コードが最も特権の低いドメインで実行され、場合によってはより特権の高いセキュリティドメインからのサービスが要求され、このサービスがより特権の低いアクティビティをスタックにプリエンプトし、次のような方法で復元することを前提としています。特権の低いコードでは、プリエンプション全体が表示されなくなります。
階層的保護ドメインの設計では、異なるセキュリティドメイン間で制御を任意に渡すことはできないとされています。
ゲートは、特権の低いコードセグメントから特権の高いコードセグメントへの制御転送のためのx86アーキテクチャの機能ですが、その逆はありません。さらに、制御が渡される特権の低いセグメントのポイントは任意ですが、制御が渡される特権の高いセグメントのポイントは厳密に指定されます。特権の低いセグメントに渡される後方制御は、命令によってのみ許可されIRET
ます。これに関して、インテルソフトウェア開発者マニュアルは次のように主張しています。
低い特権セグメントのコードモジュールは、ゲートと呼ばれる厳密に制御および保護されたインターフェイスを使用して、高い特権セグメントで動作するモジュールにのみアクセスできます。保護ゲートを通過せず、十分なアクセス権を持たずに、より高い特権セグメントにアクセスしようとすると、一般保護例外(#GP
)が生成されます。
つまり、ゲートは、必要なアクセス権とターゲットアドレスを備えた特権ドメインエントリポイントです。このように、すべてのゲートは類似しており、ほぼ同じ目的で使用され、すべてのゲート記述子には、プロセッサがアクセス権を制御するために使用するDPLフィールドが含まれています。ただし、プロセッサは、呼び出しのソースがソフトウェア、、、または命令である場合にのみゲートのDPLをチェックし、CALL
呼び出しJMP
のINT
ソースがハードウェアである場合はこのチェックをバイパスすることに注意してください。
ゲートの種類
すべてのゲートが類似しているという事実にもかかわらず、元々Intelのエンジニアは異なるゲートが異なる目的に使用されると考えていたため、いくつかの違いがあります。
タスクゲート
タスクゲートはIDTとGDTにのみ保存でき、INT
命令によって呼び出されます。非常に特殊なタイプのゲートで、他のゲートとは大きく異なります。
当初、Intelのエンジニアは、タスク切り替え用のCPUベースの機能を提供することで、マルチタスクに革命を起こすと考えていました。彼らは、タスクのレジスタ状態を保持し、ハードウェアタスク切り替えに使用できるTSS(タスク状態セグメント)を導入しました。ハードウェアタスク切り替えをトリガーする方法は2つあります。TSS自体を使用する方法と、タスクゲートを使用する方法です。ハードウェアタスクを切り替えるには、CALL
またはJMP
命令を使用できます。JMP
私が正しく理解していれば、タスクゲートが導入された主な理由は、TSSセレクターへのaによってハードウェアタスクスイッチをトリガーできないため、割り込みの到着に応答してハードウェアタスクスイッチをトリガーできるようにすることでした。
実際には、誰もそれを使用せず、ハードウェアコンテキストスイッチングも使用しません。実際には、この機能はパフォーマンスの観点から最適ではなく、使用するのに便利ではありません。たとえば、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
命令によって呼び出されます。トラップゲートに似ていますが、さらに、ユーザーモードのタスクスタックからカーネルモードのタスクスタックに多数のパラメーターを渡すことができます。渡されるパラメーターの数は、コールゲート記述子で指定されます。
コールゲートは決して人気がありませんでした。その理由はいくつかあります。
- それらはトラップゲート(オッカムの剃刀)に置き換えることができます。
- 彼らはあまりポータブルではありません。他のプロセッサにはそのような機能がありません。つまり、システムコールのコールゲートのサポートは、オペレーティングシステムを移植するときに負担になります。これは、これらのコールを書き換える必要があるためです。
- スタック間で渡すことができるパラメーターの量が制限されているため、柔軟性はあまり高くありません。
- パフォーマンスの観点からは最適ではありません。
1990年代の終わりに、IntelとAMDは、システムコール用の追加の命令SYSENTER
/ SYSEXIT
(Intel)とSYSCALL
/ SYSRET
(AMD)を導入しました。コールゲートとは対照的に、新しい命令はパフォーマンス上の利点を提供し、採用されています。
概要
MichaelFoukarakisには同意しません。IF
申し訳ありませんが、フラグに影響を与えることを除いて、割り込みとトラップの間に違いはありません。
理論的には、各タイプのゲートは、任意のレベルの特権を持つセグメントを指すインターフェイスとして機能できます。実際には、使用中の最新のオペレーティングシステムでは、割り込みゲートとトラップゲートのみが使用されます。これは、IDTでシステムコール、割り込み、および例外処理に使用され、これらすべてがカーネルエントリポイントとして機能します。
命令を使用して、ソフトウェアで任意のタイプのゲート(割り込み、トラップ、タスクを含む)を呼び出すことができますINT
。特定のゲートへのユーザーモードコードアクセスを禁止できる唯一の機能はDPLです。たとえば、オペレーティングシステムがIDTを構築する場合、特定のゲートのタイプに関係なく、ハードウェアイベント処理に使用されるゲートのカーネルセットアップDPLは0になり、このゲートへのアクセスはカーネルスペースからのみ許可されます。 (ほとんどの特権ドメインで実行されます)が、システムコールのゲートを設定するときに、DPLを3に設定して、任意のコードからそのゲートにアクセスできるようにします。その結果、ユーザーモードタスクはDPL = 3のゲートを使用してシステムコールを行うことができますが、たとえば、キーボード割り込みハンドラーを呼び出そうとすると、一般保護違反が発生します。
IDTの任意のタイプのゲートは、ハードウェアによって呼び出すことができます。人々は、同期を実現したい場合にのみ、このハードウェアイベント処理に割り込みゲートを使用します。たとえば、カーネルスタックオーバーフローが不可能であることを確認します。たとえば、APICベースのシステムでのハードウェア割り込み処理のためのトラップゲートの使用に成功した経験があります。
同様に、IDTの任意のタイプのゲートをソフトウェアで呼び出すことができます。システムコールと例外にトラップゲートを使用する理由は単純です。割り込みを無効にする理由はありません。割り込みを無効にすると、割り込み処理の待ち時間が長くなり、割り込みが失われる可能性が高くなるため、悪いことです。このため、深刻な理由がない限り、誰もそれらを無効にすることはできません。
通常、厳密なリエントラントスタイルで記述された割り込みハンドラ。このように、割り込みハンドラーは通常、データを共有せず、相互に透過的にプリエンプトできます。割り込みハンドラー内のデータへの同時アクセスを相互に除外する必要がある場合でも、cliおよびsti命令を使用することにより、共有データへのアクセスのみを保護できます。割り込みハンドラ全体をクリティカルセクションと見なす理由はありません。PICベースのシステムでカーネルスタックオーバーフローが発生するのを防ぎたい場合を除いて、割り込みゲートを使用する理由はありません。
トラップゲートは、カーネルインターフェイスのデフォルトのソリューションです。重大な理由がある場合は、トラップゲートの代わりに割り込みゲートを使用できます。