Task state segment (TSS)は、x86ベースのCPUでタスクの情報を保存するための構造体である。
以下のような情報がTSSに保存される。
- レジスタ情報
- I/Oポート許可ビットマップ(80386以降)
- Tビット(80386以降)
- 割り込みリダイレクトビットマップ(Pentium以降)
- 特権レベル0, 1, 2のスタックポインタ
- TSSのバックリンクセレクタ
- LDTセレクタ
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でのTSS
x64ではハードウェアタスクスイッチ機能は廃止されたが、TSS自体は継承され、以下の情報が保存される。
- 特権レベル0, 1, 2でのスタックポインタ
- IST(Interrupt Stack Table)
- I/O許可ビットマップ
TR(タスクレジスタ)は、64ビットのアドレスを保存できるように拡張された。
TSSのフォーマット
15 - 0
|
タスクのLDTセレクタ
|
DS
|
SS
|
CS
|
ES
|
DI
|
SI
|
BP
|
SP
|
BX
|
DX
|
CX
|
AX
|
FLAGS
|
IP
|
SS(特権レベル2)
|
SP(特権レベル2)
|
SS(特権レベル1)
|
SP(特権レベル1)
|
SS(特権レベル0)
|
SP(特権レベル0)
|
バックリンクセレクタ
|
31 - 16
|
15 - 1
|
0
|
I/O許可ビットマップ領域
|
割り込みリダイレクトビットマップ
|
OS使用可能領域
|
I/O許可ビットマップオフセット
|
0
|
T
|
0
|
タスクのLDTセレクタ
|
0
|
GS
|
0
|
FS
|
0
|
DS
|
0
|
SS
|
0
|
CS
|
0
|
ES
|
EDI
|
ESI
|
EBP
|
ESP
|
EBX
|
EDX
|
ECX
|
EAX
|
EFLAGS
|
EIP
|
CR3
|
0
|
SS(特権レベル2)
|
ESP(特権レベル2)
|
0
|
SS(特権レベル1)
|
ESP(特権レベル1)
|
0
|
SS(特権レベル0)
|
ESP(特権レベル0)
|
0
|
バックリンクセレクタ
|
63 - 48
|
47 - 32
|
31 - 16
|
15 - 0
|
I/O許可ビットマップ領域
|
OS使用可能領域
|
I/O許可ビットマップオフセット
|
予約済み
|
予約済み
|
IST 7
|
IST 6
|
IST 5
|
IST 4
|
IST 3
|
IST 2
|
IST 1
|
予約済み
|
RSP(特権レベル2)
|
RSP(特権レベル1)
|
RSP(特権レベル0)
|
予約済み
|
脚注
外部リンク