このトピックでは、特定の最新カーネルバージョンを実行している Elastic Compute Service (ECS) インスタンスから virtio デバイスをホットアンプラグしたときに Oops 例外が発生する問題を解決する方法について説明します。
問題の説明
特定の最新カーネルバージョンを実行している ECS インスタンスから、ディスクやネットワークインターフェースコントローラー (NIC) などの virtio デバイスをホットアンプラグすると、次の Oops 例外が発生します。
kernel.panic_on_oopsパラメーターが 1 に設定されている場合、ECS インスタンスでカーネルパニックが発生します。kernel.panic_on_oopsパラメーターが 0 に設定されている場合、ECS インスタンスのカーネルが無応答になります。
kernel.panic_on_oops は、カーネルが Oops 例外に遭遇したときのカーネルの動作を制御するカーネルパラメーターです。
カーネルパニック: システムは進行中のタスクを停止し、デバッグ情報を保存してから、再起動またはシャットダウンして問題を解決し、潜在的な影響を軽減します。
カーネルの無応答: カーネルは操作の続行を試みる場合があります。データの破損やその他の重大な問題を防ぐため、この場合、本番環境ではカーネルの操作を続行しないでください。
原因
Linux アップストリームコミュニティは、virtio デバイスの admin virtqueue のサポートを追加しました。詳細については、「コミット」をご参照ください。
コミット内容:
admin virtqueue が存在するかどうかを判断するために、is_avq 関数ポインターが virtio_pci_device 定義に追加されます。
最新の virtio デバイスを初期化するために使用される virtio_pci_modern_probe 関数に、is_avq 関数ポインターの値が追加されます。

virtio デバイスをホットアンプラグすると、コードは現在のキューが admin virtqueue かどうかを確認します。

virtio デバイスがレガシー virtio デバイスであり、is_avq 関数ポインターに値が割り当てられていない場合、レガシー virtio デバイスの virtio_pci_device 構造体の is_avq 関数ポインターはヌルポインターです。 virtio デバイスをホットアンプラグし、コードが if (vp_dev->is_avq(vdev, vq->index)) を呼び出すと、ヌルポインター例外がスローされます。その結果、プログラムがクラッシュしたり、システムエラーが発生したりします。
影響範囲
Linux アップストリームコミュニティ
Linux アップストリームコミュニティはすでにこの問題を解決しています。詳細については、「コミット」をご参照ください。このコミットでは、is_avq 関数ポインターがヌルかどうかを確認するためのパッチが提供されています。
オペレーティングシステム
Ubuntu 24.
カーネルバージョンが 6.8 に近いオペレーティングシステムで、admin virtqueue 機能 (virtio-pci: Introduce admin virtqueue) を提供し、is_avq 関数ポインターの問題を解決するための virtio-pci: Check if is_avq is NULL パッチがインストールされていないもの。
説明uname -rコマンドを実行して、カーネルバージョンを表示できます。
Virtio デバイス
ECS インスタンスで使用され、ホットアンプラグされるレガシー virtio デバイス。
解決策
解決策 1: この問題を解消するには、ECS インスタンスのインスタンスファミリーを、最新の virtio デバイスが存在する第 8 世代以降のインスタンスファミリーに変更することをお勧めします。詳細については、「インスタンスタイプの変更」をご参照ください。インスタンスファミリーについては、「インスタンスファミリーの概要」をご参照ください。
解決策 2:
最新のカーネルソフトウェアパッケージにアップグレードし、virtio-pci: Check if is_avq is NULL パッチが最新のカーネルソフトウェアパッケージに含まれており、is_avq 関数ポインターがヌルかどうかを確認することを確認します。
(条件付きで必須) 前述のパッチが最新のカーネルソフトウェアパッケージに含まれていない場合は、パッチをインストールします。
付録: 用語
次の表に、このトピックで使用されている用語を示します。
用語 | 説明 |
virtio デバイス | Virtio は、仮想マシンがホスト上の仮想ハードウェアと効率的に通信できるようにする標準化されたフレームワークです。 virtio デバイスは、ディスクや NIC など、仮想化環境でエミュレートされるハードウェアデバイスです。 virtio デバイスは、レガシー virtio デバイスと最新の virtio デバイスに分類されます。レガシー virtio デバイスと最新の virtio デバイスは、異なる構成インターフェースを使用します。 |
admin virtqueue | デバイスのステータスの取得やデバイスの構成など、デバイスの管理と操作に使用される特別な virtio キュー。 admin virtqueue はすべての virtio デバイスでサポートされているわけではありません。 |
virtio_pci_device | カーネル内で virtio Peripheral Component Interconnect (PCI) デバイスを示すために使用されるデータ構造。このデータ構造には、特定の virtio キューが admin virtqueue かどうかを判断するために追加された is_avq 関数ポインターなど、さまざまな関数へのポインターが含まれています。 |
is_avq | 特定の virtio キューが admin virtqueue かどうかを判断するために使用される関数。 |
virtio_pci_modern_probe | virtio PCI デバイスを検出して初期化するために使用される関数。デバイスが検出されると、この関数が呼び出されて、構成空間の読み取り、デバイス機能の確認、必要なリソースの割り当てなど、デバイスが構成されます。 |
RIP | 次に実行される命令のアドレスを格納する x86 CPU のレジスタ。プログラムが例外に遭遇した場合 (たとえば、プログラムがヌルポインターが指すアドレスで命令を実行しようとした場合など)、RIP は例外の原因となった命令のアドレスを指します。 |