割り込みが発生すると、Xenは、前述した割り込み種別ごとに異なる処理(ハンドラ)を実行します。またこのとき、実行すべきハンドラだけでなく、割り込みコントローラーの制御方法も、割り込み種別ごとに異なることがあります。x86用のXenハイパーバイザーは、これを管理するためのテーブル(irq_desc配列)を用意し、割り込みを管理しています。
ただし、x86用のXenハイパーバイザーでは、CPUローカル割り込み、プロセッサ間割り込みのハンドラは直接IDT(Interrupt Descriptor Table)に登録する実装になっており*、irq_descテーブルには登録されていないので注意してください。
なお、Linuxカーネルでは、1つの割り込み番号を複数のデバイスで共有することを許しており、複数デバイスの割り込みハンドラを登録できるようになっていますが、Xenハイパーバイザーはそれを許していません。1つの割り込み要因に対し、登録できる割り込みハンドラは基本的に1つだけで、ドメインに転送する指定になっている割り込みに対しては、個別のハンドラが登録されておらず、専用の関数を呼び出すようになっています(図4)。
ハイパーバイザー呼び出し処理(もしくはソフトウェア割り込みハンドラ)が利用しているデータ構造は、ハードウェア割り込みハンドラからも参照したり更新したりするかもしれません。ハードウェア割り込みとのやり取りがある以上、必ずそのようなデータ構造は存在するからです。
ハイパーバイザー呼び出し処理やソフトウェア割り込みハンドラがこれらのデータ構造を利用しているときに、ハードウェア割り込みハンドラからデータを変更されると、矛盾が生じます。この問題に対応するため、Xenハイパーバイザーは、ハードウェア割り込みを明示的に禁止する仕組みを提供しています。
ハードウェア割り込みを禁止することによって、データの排他アクセスを保証するわけです。ただし、この仕組みを使ってもほかのCPUからのアクセスは禁止できないため、多くの場合スピンロックと組み合わせて使うことになります(表1)。
関数名 | 説明 |
---|---|
local_irq_disable() | 割り込みを禁止する |
local_irq_enable() | 割り込みを許可する |
local_irq_save() | 現在の割り込み禁止/許可状態を保存し、割り込みを禁止する |
local_irq_restore() | 指定した割り込み禁止/許可状態に戻す |
spin_lock_irq() | 割り込みを禁止し、スピンロックを行う |
spin_unlock_irq() | スピンロックを解除し、割り込みを許可する |
spin_lock_irqsave() | 現在の割り込み禁止/許可状態を保存し、割り込みを禁止する。その上でスピンロックを行う |
spin_unlock_irqrestore() | スピンロックを解除し、指定した割り込み禁止/許可状態に戻す |
この辺りの仕組みは、CPUアーキテクチャによって少し異なる。
Copyright © ITmedia, Inc. All Rights Reserved.