4章 Linuxカーネル - 割り込み・例外 3

33
4 章 Linux カーネル – 割り込み・例外 3 ・ APIC mao Web >https://www.pridact.com Twitter >https://twitter.com/rivarten Mail >[email protected]

Transcript of 4章 Linuxカーネル - 割り込み・例外 3

4 章 Linux カーネル – 割り込み・例外 3・ APIC

maoWeb >https://www.pridact.comTwitter >https://twitter.com/rivartenMail   >[email protected]

はじめに

割り込み・例外の話

視点・概要・ハードウェアの動作・データ構造・データ構造の操作の仕方・ソースコード

ソースコードの情報が載っている場合は ,実際にソースコードに目を通しながら資料を見ていったほうがいいかもしれません。

今回はハードウェアの話が多いかもしれません

この資料について

・間違っていたらご指摘をお願い致します。・ Linux Kernel のバージョンは 4.9.16 です。・ページタイトルに * 印が付いているページは、 少し踏み込んだ内容になっています。 ざっと全体に目を通したければ、読み飛ばして もらっても構いません。

カーネル参考文献

< 参考書 > 〜基本的に古い情報だが、基本は学べる〜

・詳解 LINUX カーネル 第 3 版 (O’REILLY・ Linux カーネル 2.6 解読室 (Softbank Creative・ Linux カーネル解析入門 ( 工学社・ Modern Operating Systems 3e International

(Pearson, Andrew S. Tanenbaum) 〜初期化部分を知りたいなら〜

・新装改訂版 Linux のブートプロセスを見る( アスキー・メディアワークス )

< 参考 Web>・ Linux Cross Reference[http://lxr.free-electrons.com]・ Wikipedia

APIC (1)

・概要 (1)・ Intel Advanced Programmable Interrupt Controller・ 8259PIC の拡張バージョン・ Pentium Ⅲ 以降・ I/O APIC, ローカル APIC の 2 種類を組合わせて使用 .・ IOAPIC は , サウスブリッジ – I/O コントローラハブに内蔵・ローカル APIC は CPU に内蔵・ IOAPIC とローカル APIC の接続は ,  APIC バス ( 割り込みコントローラバス

Interrupt Controller Communication:ICC) で接続  Pentium 4 以降は FSB(Front Side Bus) を利用

https://ja.wikipedia.org/wiki/フロントサイドバス

・システム起動時は PIC 互換モード ( 仮想ワイヤモード ) で動作 .  APIC 機能を利用するには APIC モードに移行する .

・ IA-64 プロセッサ環境 (Itanium) では ,  SAPIC(Streamlined Advanced Programmable Interrupt Controller) が使われる .

APIC (1) ピンアサイン

・概要 (2) IOAPIC

データシートより

APIC (1) ブロック図

・概要 (2) IOAPIC

データシートより

APIC (1) 接続図

・概要 (2) IOAPIC - LocalAPIC 間の接続

データシートより

APIC (2)

・概要 (2)・ I/O APIC

・データシート http://www.intel.com/design/chipsets/datashts/290566.htm

・ IRQライン 24個・ 24エントリの割り込み転送テーブル (Interrupt Redirection Table)  I/O デバイスから受け取った割り込みを CPUへ通知する為の表 . エッジ /レベルトリガの種別 , 割り込みベクタ , 割り込み先 CPU等 . テーブルの各エントリを RTE(Redirection Table Entry) と呼ぶ .・プログラマブルレジスタ・メッセージ回路  APIC バスを通じて他の APIC と通信する為の回路・割り込み優先度がピン番号に依存しない .・全ての割り込みは一旦 IOAPIC で受信する .・ IOAPIC はシステムで複数存在していても構わない .・ APIC での IRQはGSI(Global System Interrupt) と呼ぶ .・複数のプロセッサからアクセスできる必要がある為 , メモリ・マップド・レジスタ形式で ,レジスタにアクセスする .  (I/Oポートは 64KB(0x0000~0xFFFF) までしか無い為 ,  レジスタアクセスの為に貴重な I/Oポートを割けず ,代わりにメモリ空間を使う )

APIC (3)

・概要 (3)・ Local APIC

・各 CPU 内に存在・外部からの割り込みを全て管理する .・マルチプロセッサによる割り込み IPI(Inter-Processor Interrupt) を 使用した CPU 間通信にも使用される .・ 32bitレジスタ

・割り込みコマンドレジスタ ICR(Interrupt Command Register)・タスク調停レジスタ TPR(Task Priority Register)・調停優先度レジスタ APR(Arbitration Priority Register)

・内部クロック・ローカルタイマデバイス・割り込み元

・ LINT0,LINT1 ローカル APIC 割り込みの為の追加の IRQライン・ IOAPIC  ・ APIC タイマ・他の CPU・性能モニタリングカウンタ・温度センサ・ APICエラー

APIC (4)

・ APIC の一般的な実装

・ PCI バスには ,最大 4 本の I/O 割り込み線 (INT_A,B,C,D) が存在し , それぞれ IOAPIC に接続される .・ IOAPIC には ,それぞれの割り込み線に対する割り込み転送テーブル が割り当てられている .・ I/O デバイスの数が多い場合 ,1 本の割り込み線を複数のデバイスで 共有することがある .共有の管理は IOAPIC が行う .・ PCI の I/O デバイスによっては MSI(Message Signaled Interrupt) を サポートするものがあり , このデバイスは割り込み線を使用しないが , チップセットにより MSI メッセージは一旦 IOAPIC にルーティングされ , リダイレクションテーブルを通して CPUへ割り込み通知される .

※PCI を I/O デバイスに持つ一般的な IA-32 アーキテクチャを仮定

APIC (5)

・ APIC の動作概要 (1)

基本的な機能は PIC と同じ .

1.IOAPIC が割り込み信号の変化を検知すると , 割り込み転送テーブルに従い ,CPU に割り込みメッセージを発行 .2.CPU の Local APIC がこれを受信すると , 自 CPU の割り込み処理を始める .3. 割り込み処理が完了すると ,CPU は EOI を IOAPIC に発行する .

APIC (6)

・ APIC の動作概要 (2)

マルチプロセッサにおける割り込み信号の分配

・静的分配 (Static distribution) 割り込み転送テーブルの対応するエントリに書かれている ローカル APICへ割り込みを発行 .

・動的分配 (Dynamic distribution) もっとも優先度が低いプロセスを実行しているプロセッサの ローカル APICへ割り込みを発行 .

APIC (7)

・ APIC の動作概要 (3)

・動的分配 (Dynamic distribution) もっとも優先度が低いプロセスを実行しているプロセッサの ローカル APICへ割り込みを発行 . ローカル APIC のタスク優先度レジスタを利用して , 現在実行中のプロセスの優先度を計算し , プロセス切り替え毎にこのレジスタを更新 .

・動的分配における調停 (arbitration)  2 つ以上の CPU が最も低い優先度を持つ場合 , 調停をして割り込み要求をラウンドロビン方式で発行 . ・調停優先度レジスタ APR に 0(最低 )~ 15(最高 ) の優先度を割当て . ・割り込みを受取った CPU の APR は自動的に 0になる .  それ以外の CPU は自動的に +1される . ・ APR > 15 ⇒ 割り込みを受取った CPU が以前に持っていた APR+1

APIC (8)

・ APIC の動作概要 (4)

シングルプロセッサにおける I/O APIC

・ローカル APIC を無効にし , ローカル IRQラインの  LINT0と INTR ピンを接続 ,  LINT1 と NMI ピンを接続することで , 従来の 8259A型の外部 PIC として利用可 .

・ローカル APIC を有効にすると ,標準の外部 I/O APIC としても利用可 .

APIC (9)

・ IOAPIC のレジスタ

・レジスタにはメモリマップドレジスタ形式でアクセスする .・コンパイラの最適化によってメモリの操作順が変わる可能性がある為 , メモリマップドレジスタを扱う場合は ,最適化抑止の措置をとる . ※ Linux の場合 , 「 volatile 指定」「 gcc のメモリバリア機能を使う」等 .

・ IOREGSEL(I/O Register Select) どのレジスタを操作したいか選択するレジスタ . アクセス権 :RW メモリアドレス :0xFEC0[x][y]00h

・ IOWIN(I/O Window) 目的のレジスタにアクセスするレジスタ . アクセス権 :RW メモリアドレス :0xFEC0[x][y]10h

・メモリアドレスは ,ACPI の AML から取得する .x = 0 - Fh y = 0, 4, 8, Ch

APIC (10)

・ IOAPIC のレジスタ

・ IOREGSEL(I/O Register Select) どのレジスタを操作したいか選択するレジスタ . メモリアドレス :0xFEC0[x][y]00h (x = 0 - Fh y = 0, 4, 8, Ch) アドレスオフセット値をレジスタに書き込む事で ,レジスタを指定 .

オフセット レジスタ名 アクセス権

00h IOAPICID(IOAPIC ID) RW

01h IOAPICVER(IOAPIC Version) RO(Read Only)

02h IOAPICARB(IOAPIC Arbitration ID) RO(Read Only)

10 - 3Fh IOREDTBL[0-23](Redirection Table) RW

APIC (11)

・ IOAPIC のレジスタ

・ IOAPICIDレジスタ  4bit の APICIDを格納 . 全ての IOAPIC においてユニークな値が割り振られる . デフォルト値 :00h, アクセス権 :RW

・ IOAPICVERレジスタ  IOAPIC のバージョンや最大 RTEエントリ値を格納 . デフォルト値 :0x00170011h, アクセス権 RO  

bit 意味

31-28 Reserved

27-24 IOAPIC ID

23-0 Reserved

bit 意味

31-24 Reserved

23-16 最大 RTEエントリ値 .0~239.0オリジン .0x17h(23) で固定 .

15-8 Reserved

7-0 APIC バージョン .0x11h で固定 .

APIC (12)

・ IOAPIC のレジスタ

・ IOAPICARBレジスタ  IOAPIC複数搭載の場合に , バス調停を行う時の優先度を格納する .  APIC バス / フロントサイドバス等の占有権決定の為に利用 . 決定アルゴリズムは単純 . デフォルト値 :0x00000000h, アクセス権 :RO

 決定アルゴリズム :IOAPICARBレジスタに 0~15 までの調停 ID(Arbitration ID) を設定しておき ,その IDを 1ずつ増やしていき ,最初に 15 に到達した IOAPIC がバスの使用権を得る .

  

bit 意味

31-28 Reserved

27-24 IOAPIC Arbitration ID

23-0 Reserved

APIC (13)

・ IOAPIC のレジスタ

・ IOREDTBLレジスタ  RTEエントリを格納 .  24エントリ .RTE1エントリ 64bit( アドレスオフセット 2 つ分 ).

  

オフセットh

エントリ オフセットh

エントリ

10-11 IOREDTBL0 28-29 IOREDTBL0

12-13 IOREDTBL1 2A-2B IOREDTBL1

14-15 IOREDTBL2 2C-2D IOREDTBL2

16-17 IOREDTBL3 2E-2F IOREDTBL3

18-19 IOREDTBL4 30-31 IOREDTBL4

1A-1B IOREDTBL5 32-33 IOREDTBL5

1C-1D IOREDTBL6 34-35 IOREDTBL6

1E-1F IOREDTBL7 36-37 IOREDTBL7

20-21 IOREDTBL8 38-39 IOREDTBL8

22-23 IOREDTBL9 3A-3B IOREDTBL9

24-25 IOREDTBL10 3C-3D IOREDTBL10

26-27 IOREDTBL11 3E-3F IOREDTBL11

APIC (14)

・ IOAPIC のレジスタ

・ IOREDTBLレジスタ 各エントリのオフセット値の低位側が bit31-0,高位側が bit63-32.

  

bit 意味

63-56

[RW]転送先フィールド (DesticationField).転送先のプロセッサを指定 .bit11 の転送先モードによって ,bit の意味が変わる .bit11=0(PhysicalMode) -> bit[59-56] = APICIDbit11=1(LogicalMode) -> bit[63-56] = プロセッサ ID

55-17 予約

16 [RW] 割り込みマスク . 1:マスク 0:マスク解除

15 [RW] トリガーモード . 1:レベルトリガ 0:エッジトリガ

14[RO] リモート IRR.レベルトリガ時のみ .ローカル APIC が IOAPIC から割り込み受信した時に 1,EOI発行をうけると 0.

13 [RW] 割り込み入力ピンの極性 (INTPOL:Interrupt Input Pin Polarity). 1:負論理 0:正論理

12 [RO] 配送ステータス (DELIVS:Delivery Status). 0: アイドル状態 1: 割り込み送信中断

11 [RW] 転送先モード (DESTMOD:Destination Mode). 0:PhysicalMode 1:LogicalMode

10-8 [RW] 配送モード (DELMOD:DeliveryMode) 別表参照

7-0 [RW] 割り込みベクタ (INTVEC:Interrupt Vector). 0x10~0xFE. これがプロセッサに送られる .

APIC (15)

・ IOAPIC のレジスタ

・ IOREDTBLレジスタ bit10-8 の DELMODの表

  

bit モード 意味

000 Fixed指定された全プロセッサに対して INTR シグナルを配送 .指定によっては , ブロードキャストモードにもなる .

001Lowest Priority

指定された全プロセッサのうち , もっとも負荷が低い 1 つのプロセッサにINTR シグナルを送る .

010 SMISMI(System Management Interrupt) として割り込みを配送する .SMI は , 割り込み処理を BIOS 内で行うレガシー手法 .エッジトリガ .現在は SMI の代わりに ,SCI(System Control Interrupt) 割り込みが使われている .

011 Reserved

100 NMI指定された全プロセッサに対して ,NMI として割り込みを配送する .ベクタ情報は無視される .エッジトリガ .

110 Reserved

111 ExtINT指定された全プロセッサに対して ,8259A 互換割り込みとして割り込みを配送する .エッジトリガ .

APIC (16)

・ローカル APIC のレジスタ

・レジスタにはメモリマップドレジスタ形式でアクセスする .・ APICレジスタ ・物理アドレス空間に 4KB領域として割り当てられている . ・開始アドレス (APICBASE):0xFEE00000( デフォルト値 ) ・ APICBASE は IA32_APIC_BASE MSR(Machine Specific Register)  で変更可能

APIC (17)

・ローカル APIC のレジスタ

・ IA32_APIC_BASE MSRレジスタ  64bit. ・ APICグローバルフラグ :0 -> ローカル APIC無効化 ・ BSP(BootStrap Processor) フラグ  プロセッサが BSP かどうかを表す .

   BSP:マルチプロセッサの場合 ,       PC に電源が入った直後は CPU は 1 つしか動いていない .      ある程度初期化が進んだ後に残りの CPU が動き出す .      最初に動く CPU を BSP という

 bit 意味

63-36 Reserved

35-12 APICBASE(物理アドレス )

11 APICグローバルフラグ

10-9 Reserved

8 BSP フラグ

7-0 Reserved

APIC (18)

・ローカル APIC のレジスタ

・ APICレジスタのアドレスマップ

  

アドレスFEE0 ~~~~h

レジスタ名 アクセス

0000 Reserved

0010 Reserved

0020 Local APIC ID RW

0030 Local APIC Version RO

0040 Reserved

0050 Reserved

0060 Reserved

0070 Reserved

0080 タスク優先度レジスタ TPR RW

0090 調停優先度レジスタ APR RO

00A0 プロセッサ優先度レジスタ PPR RO

00B0 EOI W

00C0 Reserved

APIC (19)

・ローカル APIC のレジスタ

・ APICレジスタのアドレスマップ

  

アドレスFEE0 ~~~~h

レジスタ名 アクセス

00D0 論理デスティネーション RW

00E0 デスティネーション形式bit31-28:RWbit27-0:RO

00F0 スプリアス割り込みベクタbit31-9:RObit8-0:RW

0100~0170 ISR RO

0180~01F0 トリガモードレジスタ TMR RO

0200~0270 IRR RO

0280 エラーステータス RO

0290~02F0 Reserved

0300 割り込みコマンド ICR[0-31] RW

0310 割り込みコマンド ICR[32-63] RW

APIC (20)

・ローカル APIC のレジスタ

・ APICレジスタのアドレスマップ

  

アドレスFEE0 ~~~~h

レジスタ名 アクセス

0320 LVT タイマ RW

0330 LVT温度センサ RW

0340 LVT性能モニタリングカウンタ RW

0350 LVT LINT0 RW

0360 LVT LINT1 RW

0370 LVTエラー RW

0380 初期カウント ( タイマ用 ) RW

0390 現行カウント ( タイマ用 ) RO

03A0~03D0 Reserved

03E0 除算設定 ( タイマ用 ) RW

03F0 Reserved

APIC (21)

・ローカル APIC のレジスタ

・ローカル APICIDレジスタ :0xFEE00020 ローカル APIC をバス上で識別する為に割り振る . プロセッサ IDとしても利用 .

・ローカル APIC バージョンレジスタ :0xFEE00030 ローカル APIC のバージョンや最大 LVTエントリ値を格納 .

 ※ i486 以前には APIC は無い .

  

bit 意味

31-24 APIC ID

23-0 Reserved

bit 意味

31-24 Reserved

23-16 最大 LVTエントリ値 .0オリジン .

15-8 Reserved

7-0 バージョン

プロセッサ 最大 LVTエントリ値

Pentium4,Xeon

6

P6系(Pentium 2,3)

5

Pentium 4

APIC (22)

・ローカル APIC のレジスタ・ LVT タイマレジスタ

・ LVT温度モニタレジスタ /LVT性能カウンタレジスタ

bit 意味

31-18 Reserved

17 タイマモード . 0: ワンショット 1:周期

16 マスクビット . 0:マスク無し 1:マスクあり

15-13 Reserved

12 伝達ステータス . 0: アイドル 1:送信保留

11-8 Reserved

7-0 ベクタ

bit 意味

31-17 Reserved

16 マスクビット . 0:マスク無し 1:マスクあり

15-13 Reserved

12 伝達ステータス . 0: アイドル 1:送信保留

11 Reserved

10-8 伝達モード .000:固定 ,010:SMI, 100:NMI, 111:ExtINT, 101:INIT

7-0 ベクタ

APIC (23)

・ローカル APIC のレジスタ

・ LVT LINT0レジスタ /LVT LINT1レジスタbit 意味

31-18 Reserved

17 タイマモード . 0: ワンショット 1:周期

16 マスクビット . 0:マスク無し 1:マスクあり

15 トリガモード . 0:エッジ 1:レベル

14リモート IRR フラグ .0:EOI を受信した 1: 割り込み処理中

13割り込み入力ピンの極性0:正論理 1:負論理

12 伝達ステータス . 0: アイドル 1:送信保留

11 Reserved

10-8 伝達モード .000:固定 ,010:SMI, 100:NMI, 111:ExtINT, 101:INIT

7-0 ベクタ

APIC (24)

・ローカル APIC のレジスタ

・ LVTエラーレジスタbit 意味

31-17 Reserved

16 マスクビット . 0:マスク無し 1:マスクあり

15-13 Reserved

12 伝達ステータス . 0: アイドル 1:送信保留

11-8 Reserved

7-0 ベクタ

APIC (25)

・初期化  start_kernel() -> init_IRQ() -> x86_init.irqs.intr_init() -> native_init_IRQ()  -> x86_init.irqs.pre_vector_init() = init_ISA_irqs() -> init_bsp_APIC()

[ver4.9.16 arch/x86/kernel/apic/apic.c:1157] 1157 void __init init_bsp_APIC(void) 1158 { 1159 unsigned int value; 1165 if (smp_found_config || !boot_cpu_has(X86_FEATURE_APIC)) 1166 return; 1171 clear_local_APIC(); #Do not trust the local APIC being empty at bootup

/* Enable APIC. */ #スプリアス割り込みベクタレジスタを利用して LocalAPIC を有効化 .#IA32_APIC_BASE_MSR を操作しても LocalAPIC を有効化できる .

1176 value = apic_read(APIC_SPIV); 1177 value &= ~APIC_VECTOR_MASK; 1178 value |= APIC_SPIV_APIC_ENABLED; 1180 #ifdef CONFIG_X86_32 1181 /* This bit is reserved on P4/Xeon and should be cleared */ 1182 if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && 1183 (boot_cpu_data.x86 == 15)) 1184 value &= ~APIC_SPIV_FOCUS_DISABLED; 1185 else 1186 #endif 1187 value |= APIC_SPIV_FOCUS_DISABLED; 1188 value |= SPURIOUS_APIC_VECTOR; 1189 apic_write(APIC_SPIV, value);

APIC (26)

・初期化

arch/x86/kernel/apic/apic.c:1157 1157 void __init init_bsp_APIC(void) 1158 {

…/* Set up the virtual wire mode. */

1194 apic_write(APIC_LVT0, APIC_DM_EXTINT); #LINT0を伝達モード ExtINT で設定 1195 value = APIC_DM_NMI; #NMI 1196 if (!lapic_is_integrated()) /* 82489DX */ #82489DX は Pentium4 以前の旧式の LocalAPIC 1197 value |= APIC_LVT_LEVEL_TRIGGER; # レベルトリガ 1198 if (apic_extnmi == APIC_EXTNMI_NONE) 1199 value |= APIC_LVT_MASKED; 1200 apic_write(APIC_LVT1, value); #LINT1 を伝達モード NMI で設定 1201 }