Task state segmentTask state segment (TSS)は、x86ベースのCPUでタスクの情報を保存するための構造体である。 以下のような情報がTSSに保存される。
TSSの配置場所TSSはメモリ上のどこにでも配置することができる。オペレーティングシステムは、TSSディスクリプタを作成してTSSの配置された場所を指定し、TR(タスクレジスタ)にTSSディスクリプタのセグメントセレクタをロードする事により行われる。TSSディスクリプタは、GDT(Global Descriptor Table)に置かれる。 セキュリティ上の理由から、TSSはオペレーティングシステムのみからアクセスできる場所に置くべきである。 タスクレジスタTR(タスクレジスタ)は16ビットのレジスタでTSSディスクリプタのセグメントセレクタを保持する。これは特権命令であるLTR命令を使用して行われる。LTR命令を実行しても初期タスクのTSSを指定するだけで、ハードウェアタスクスイッチは起こらない。 レジスタ情報TSSにはx86のレジスタの値を保存することができる。これはタスクスイッチのときに使用される。CPUは、セグメントセレクタにTSSのセレクタかタスクゲートのセレクタを指定したFAR CALL/FAR JUMPの実行、あるいはNTフラグがセットされた状態でのIRET命令によるハードウェアタスクスイッチの実行時に、現在のタスクのレジスタ情報をTSSに保存し、新しいタスクのTSSからレジスタ情報をレジスタにロードする。 しかし、近代的なOSである Windows や Linux[1] はx86が持っているハードウェアタスクスイッチ機能は使用しておらず、レジスタ情報、TSSのバックリンクセレクタ、LDTセレクタフィールドは使用されていない。 x64では、ハードウェアタスクスイッチ機能は廃止され、レジスタ情報の場所にはIST(Interrupt Stack Table)の情報を設定する。 I/O許可ビットマップ80286以降のCPUでは、タスクがI/Oポートアクセス命令(IN, OUTなど)を実行したとき、CPUはフラグレジスタのIOPL(I/O privilege level)とタスクの特権レベルであるCPL(Current privilege level) を比較し、CPLのほうが特権が高いか同じであればすべてのI/Oポートアクセスが許可される。CPLがIOPLより特権が低い場合は、すべてのI/Oポートアクセスは許可されない。 80386以降ではTSSが拡張され、I/O許可ビットマップがTSSに追加された。このビットマップは、オペレーティングシステムにより設定され、どのI/Oポートがアクセス可能かを指定する。CPLのほうがIOPLより特権が高いか同じであればすべてのI/Oポートアクセスが許可される。CPLがIOPLより特権が低い場合、CPUはI/O許可ビットマップをチェックし、アクセスしようとしているI/Oポートのビットが0であればそのI/Oポートのアクセスは許可される。ビットが1であればそのポートへのアクセスはできず、一般保護例外が発生する。この機能により、オペレーティングシステムはタスクに対してI/Oポートごとにアクセス権を制限することができる。 TビットT(Trap)ビットがセットされているとハードウェアタスクスイッチ時にデバッグ例外(INT #1)が発生する。 割り込みリダイレクトビットマップVME(仮想86モード拡張)が有効になっている場合、割り込み番号に対応した割り込みリダイレクトビットがゼロの場合、その割り込みは例外を発生せず、仮想86マシン内で8086と同様に処理される。これにより仮想86モニタで捕捉する必要のない割り込みは、動作が速くなる。割り込みリダイレクトビットが1の場合は、従来通り例外が発生し仮想86モニタはその割り込みをエミュレートする必要がある。 特権レベル0, 1, 2のスタックポインタTSSには特権レベル0, 1, 2のスタックポインタの初期値を保存する。特権レベルの遷移があった場合、CPUはTSSからスタックポインタを自動的にロードし、特権レベルごとに違うスタックを使用する。 TSSのバックリンクセレクタIRET命令で以前のタスクにハードウェアタスクスイッチで戻るときに使用される。 LDTセレクタタスクごとに違うメモリ空間を割り当てるために使用される。 x64でのTSSx64ではハードウェアタスクスイッチ機能は廃止されたが、TSS自体は継承され、以下の情報が保存される。
TR(タスクレジスタ)は、64ビットのアドレスを保存できるように拡張された。 TSSのフォーマット
脚注
外部リンク |