仮想割り込みコントローラー

ハイパーバイザーは、仮想プロセッサへの割り込み配信を仮想化します。 これは、仮想化されたローカル APIC の拡張機能である合成割り込みコントローラー (SynIC) を使用して行われます。つまり、各仮想プロセッサには、SynIC 拡張機能を含むローカル APIC インスタンスがあります。 これらの拡張機能は、次の章で説明する単純なパーティション間通信メカニズムを提供します。 パーティションに配信される割り込みは、外部と内部の 2 つのカテゴリに分類されます。 外部割り込みは他のパーティションまたはデバイスから発生し、内部割り込みはパーティション自体内から発生します。

外部割り込みは、次の状況で生成されます。

  • 物理ハードウェア デバイスによってハードウェア割り込みが生成されます。
  • 親パーティションは仮想割り込みをアサートします (通常はハードウェア デバイスをエミュレートする処理中)。
  • ハイパーバイザーは、メッセージ (インターセプトなど) をパーティションに配信します。
  • 別のパーティションがメッセージを投稿します。
  • 別のパーティションがイベントを通知します。

内部割り込みは、次の状況で生成されます。

  • 仮想プロセッサは、APIC 割り込みコマンド レジスタ (ICR) にアクセスします。
  • 合成タイマーの有効期限が切れます。

ローカル APIC

SynIC は、ローカル APIC のスーパーセットです。 この APIC へのインターフェイスは、32 ビット メモリ マップト レジスタのセットによって提供されます。 このローカル APIC (メモリ マップレジスタの動作を含む) は、通常、Intel と AMD のドキュメントで説明されているように、P4/Xeon システム上のローカル APIC と互換性があります。

ハイパーバイザーのローカル APIC 仮想化は、次のマイナーな方法で物理 APIC 操作から逸脱する可能性があります。

  • 物理システムでは、IA32_APIC_BASE MSR はシステム内のプロセッサごとに異なる場合があります。 ハイパーバイザーでは、この MSR にパーティション内のすべての仮想プロセッサに対して同じ値が含まれている必要がある場合があります。 そのため、この MSR はパーティション全体の値として扱われる場合があります。 仮想プロセッサがこのレジスタを変更すると、その値は実質的にパーティション内のすべての仮想プロセッサに伝達される可能性があります。
  • IA32_APIC_BASE MSR は、APIC を有効または無効にするための "グローバル有効化" ビットを定義します。 仮想化された APIC は常に有効にすることができます。 その場合、このビットは常に 1 に設定されます。
  • ハイパーバイザーのローカル APIC が仮想 SPI (システム管理割り込み) を生成できない場合があります。
  • パーティション内の複数の仮想プロセッサに同一の APIC ID が割り当てられている場合、ターゲット割り込み配信の動作は未定義になります。 つまり、ハイパーバイザーは、1 つの仮想プロセッサ、指定された APIC ID を持つすべての仮想プロセッサ、または仮想プロセッサに割り込みを無料で配信できます。 この状況は、ゲスト プログラミング エラーと見なされます。
  • メモリ マップされた APIC レジスタの一部は、仮想 MSR を使用してアクセスできます。
  • ハイパーバイザーでは、ゲストが APIC ID を変更できない場合があります。

このセクションの残りの部分では、ローカル APIC の拡張機能である SynIC 機能の側面のみを説明します。

ローカル APIC MSR アクセス

ハイパーバイザーは、使用率の高いメモリ マップされた APIC レジスタへの高速 MSR アクセスを提供します。 これらは TPR、EOI、および ICR レジスタです。 ICR ロー レジスタと ICR ハイ レジスタは、1 つの MSR に組み合わされます。 パフォーマンス上の理由から、ゲスト オペレーティング システムは、APIC MSR の使用に関するハイパーバイザーの推奨事項に従う必要があります。

MSR アドレス レジスタ名 説明
0x40000070 HV_X64_MSR_EOI APIC EOI にアクセスする
0x40000071 HV_X64_MSR_ICR APIC ICR-high および ICR-low にアクセスする
0x40000072 HV_X64_MSR_TPR APIC TPR にアクセスする

HV_X64_MSR_EOI

Bits 説明 属性
63:32 RsvdZ (予約済み、ゼロにする必要があります) Write
31:0 EOI 値 Write

HV_X64_MSR_ICR

Bits 説明 属性
63:32 ICR の高い値 読み取り/書き込み
31:0 ICR の低い値 読み取り/書き込み

HV_X64_MSR_TPR

Bits 説明 属性
63:8 RsvdZ (予約済み、ゼロにする必要があります) 読み取り/書き込み
7:0 TPR 値 読み取り/書き込み

この MSR は、32 ビット モードのゲスト パーティションで TPR へのアクセスを高速化することを目的としています。 64 ビット モードのゲスト パーティションでは、CR8 を使用して TPR を設定する必要があります。

合成クラスター IPI

ハイパーバイザーでは、任意の仮想プロセッサ セットに仮想固定割り込みを送信できるハイパーコールがサポートされています。

Hypercall 説明
HvCallSendSyntheticClusterIpi 指定した仮想プロセッサ セットに仮想固定割り込みを送信します。
HvCallSendSyntheticClusterIpiEx HvCallSendSyntheticClusterIpi と同様に、スパース VP セットを入力として受け取ります。

EOI アシスト

[仮想プロセッサ アシスト] ページの 1 つのフィールドは、EOI Assist フィールドです。 EOI Assist フィールドはオーバーレイ ページのオフセット 0 にあり、サイズは 32 ビットです。 EOI アシスト フィールドの形式は次のとおりです。

Bits 説明 属性
31:1 RsvdZ 読み取り/書き込み
0 EOI は必要ありません 読み取り/書き込み

ゲスト OS は、仮想 VP アシスト ページの EOI Assist フィールドにアトミックにゼロを書き込み、"No EOI required" フィールドが以前に 0 であったかどうかを確認することで、EOI を実行します。 その場合、OS は HV_X64_APIC_EOI MSR に書き込む必要があるため、ハイパーバイザーへのインターセプトがトリガーされます。 EOI を実行するには、次のコードをお勧めします。

lea rcx, [VirtualApicAssistVa]
btr [rcx], 0
jc NoEoiRequired

mov ecx, HV_X64_APIC_EOI
wrmsr

NoEoiRequired:

ハイパーバイザーは、次の条件が満たされた場合に仮想割り込みを挿入するときに、"No EOI required" ビットを設定します。

  • 仮想割り込みはエッジによってトリガーされ、
  • 保留中の優先度の低い割り込みはありません

後で優先順位の低い割り込みが要求された場合、ハイパーバイザーは後続の EOI がインターセプトを引き起こすような "No EOI required" をクリアします。

入れ子になった割り込みの場合、EOI インターセプトは優先度が最も高い割り込みでのみ回避されます。 OS によって実行される EOI の数に対してカウントが維持されないので、これは必要です。 したがって、最初の EOI のみを回避でき、最初の EOI は "No EOI Required" ビットをクリアするため、次の EOI はインターセプトを生成します。 ただし、入れ子になった割り込みはまれであるため、これは一般的なケースでは問題になりません。

デバイスや I/O APIC (物理または合成) には、エッジによってトリガーされる割り込みについて EOI の通知を受け取る必要はありません。ハイパーバイザーは、仮想 APIC 状態を更新するためにのみ、このような EOI をインターセプトします。 場合によっては、仮想 APIC 状態を遅延更新できます。このような場合、"NoEoiRequired" ビットはハイパーバイザーによって設定され、EOI インターセプトが不要であることをゲストに示します。 後で、ハイパーバイザーは、"NoEoiRequired" ビットの現在の値に応じて、ローカル APIC の状態を派生させることができます。

このエンライトメントの有効化と無効化は、割り込みアクティビティとその時点の APIC 状態とは無関係にいつでも実行できます。 エンライトメントが有効になっている間、従来のEOIは"EOIは必要ありません"値に関係なく実行できますが、彼らは啓発のパフォーマンス上の利点を実現しません。