26

64 ビット カーネル (x86_64 プラットフォーム用) を作成する場合は、ユーザー空間 ABI が使用する 128 バイトのレッド ゾーンを使用しないようにコンパイラに指示することを強くお勧めします。(GCC の場合、コンパイラ フラグは です-mno-red-zone)。

カーネルが有効になっている場合、カーネルは割り込みに対して安全ではありません。

しかし、それはなぜですか?

4

3 に答える 3

16

AMD64 ABI からの引用:

%rsp が指す位置を超える 128 バイトの領域は、予約されていると見なされ、シグナルまたは割り込みハンドラによって変更されません。したがって、関数は、関数呼び出し間で必要のない一時データのためにこの領域を使用する場合があります。特に、リーフ関数は、プロローグとエピローグでスタック ポインターを調整するのではなく、スタック フレーム全体にこの領域を使用する場合があります。このエリアはレッドゾーンとして知られています。

基本的に、これは最適化です。ユーザーランド コンパイラは、特定の時点で使用されているレッド ゾーンの量 (最も単純な実装では、ローカル変数の全体のサイズ) を正確に認識しており%rsp、サブ関数を呼び出す前にそれに応じて調整できます。

%rsp特にリーフ関数では、これにより、関数内でなじみのないコードが実行されないことが確実になるため、調整する必要がないというパフォーマンス上の利点が得られます。(POSIX シグナル ハンドラーはコルーチンの形式と見なされる場合がありますが、シグナル ハンドラーでスタック変数を使用する前にレジスターを調整するようにコンパイラーに指示できます)。

カーネル空間では、割り込みについて考え始めると、それらの割り込みが%rsp. したがって、すべてがダーティであると想定し、不必要にスタック領域を浪費する (すべての関数で 128 バイトが保証されたローカル変数で効果的に実行されている) か、割り込みが想定を行わないことを保証します%rsp- これは注意が必要です。

ユーザー空間では、コンテキスト スイッチ + スタックの 128 バイトの過剰割り当てがそれを処理します。

于 2014-08-20T15:09:25.533 に答える