x2APICとinterrupt remapping
以前IOAPICやMSI/MSI-Xを利用するデバイスでx2apicを利用するにはinterrupt remapingを利用すると書きました.
今回実際のマッピングを調べることがあったので,ここに要点をまとめます. 図はVT-dのドキュメントからの引用です.
前提
Interrupt RemappingのサポートはVT-dレジスタのExtended Capability Registerの3bit目(IR: Interrupt Remapping support)で示されます.
VT-dレジスタのアドレスはACPIのDMARのDRHDに記載されています.
またVT-dレジスタのGlobal Command Register (18h)のIRE: Interrupt Remapping Enableを利用してInterupt remapingを有効化します.
Interrupt Remappingの設定
Interrupt Remappingを利用するには,以下の設定が必要です.
デバイス側
MSI/MSI-Xを利用するデバイスは,割り込みを生成するときに,以下に示す"Remappable Format Interrut Request"でMSIを設定します.
通常のMSIと異なり,割り込みアドレスに割り込みベクタ番号やdestination IDはエンコードされていません.Interrupt indexで次に説明するInterrupt remapping table entryのインデックスを指定します.
(ここから分かるように,Interrupt Remappingを利用する場合には,デバイスの方の割り込み設定も適切に設定する必要があります.デバイス設定に透過でinterrupt remappingを利用することはできません.)
IRTE (Interrupt Remapping Table Entry)
IRTEで実際の変換の内容を設定します.IRTEにはinterrupt remapping用と,posted interrupts用の二種類存在します.
interrupt remappingを利用する場合は,以下のようなエントリになります.
IRTEのベースアドレスはVT-dレジスタのInterrupt Remapping Table Address Register (0B8h)に格納されています.
Invalidation
IRTEエントリのキャッシュの無効化はInvalidation Queueを用いておこないます.
確認
x2APICを有効にしたLinuxマシンでMSIの設定とRITEエントリを確認しました.
% sudo lspci -vvv -s 05:00.0 05:00.0 Non-Volatile memory controller: OCZ Technology Group, Inc. RD400/400A SSD (rev 01) (prog-if 02 [NVM Express]) ... Capabilities: [b0] MSI-X: Enable+ Count=8 Masked- Vector table: BAR=0 offset=00002000 PBA: BAR=0 offset=00003000
MSI-X ベクタテーブル
% for j in `seq 0 1 64`; do; for i in `seq $((($j+1)*16-4+8192)) -4 $(($j*16+8192))`; sudo ./pcimem /sys/devices/pci0000:00/0000:00:1d.0/0000:05:00.0/resource0 $i w | tail -n1 | cut -d':' -f 2 | tr '\n' ' '; echo ; done 0x0 0x0 0x0 0xFEE00258 0x0 0x0 0x0 0xFEE00378 0x0 0x0 0x0 0xFEE00398 0x0 0x0 0x0 0xFEE003B8 ...
左がMessage data, 一番右がMessage Addressです. 上からそれぞれ利用するIRTEのインデックスは18, 27, 28, 29です.
IRTE
適当なカーネルモジュール書いて確認したら以下のようになりました.
[ 2459.161111] vtd: irta = 0x0000000460500000, eime = 1, s = 2^15 [ 2459.161112] vtd: 0 000000010083002d, 0000000000040500 [ 2459.161112] vtd: P: 1 [ 2459.161113] vtd: FPD: 0 [ 2459.161113] vtd: Destination mode: 1 [ 2459.161113] vtd: Redirection Hint: 1 [ 2459.161114] vtd: Trigger Mode: 0 [ 2459.161114] vtd: Delivery Mode: 1 [ 2459.161114] vtd: AVAIL: 0 [ 2459.161115] vtd: VECTOR: 131 [ 2459.161115] vtd: Destination ID: 1 [ 2459.161115] vtd: SID: 0x500
ここで,最初の行がInterrupt Remapping Table Address Registerの値で,eime=1なのでx2APICモードです. その下がIRTEの中身です.