仮想マシンでの x86-64 レベル
仮想マシンに見えるのは、自分が動いているプロセッサーではなく、ハイパーバイザーが記述するプロセッサーです。そしてデフォルトの記述は、多くの場合ハードウェアより古いものです。
VM が低いレベルを報告する理由
オペレーティングシステムは、プロセッサーに何ができるかを CPUID 命令から知ります。仮想マシンでは CPUID に答えるのはハイパーバイザーで、ホストのプロセッサーではなく、その VM に設定された CPU モデルに基づいて答えます。
ハイパーバイザーは、VM が異なるプロセッサーを持つホスト間を移動できるように、デフォルトで控えめなモデルを使います。つまり、すべてのホストが備えていると想定される機能だけを提示します。ゲストの x86-64 レベルはそのモデルから決まるので、x86-64-v4 のサーバー上の VM が x86-64-v1 になることがあります。
エラーメッセージ
| メッセージ | 意味 |
|---|---|
Fatal glibc error: CPU does not support x86-64-v2 | システムの C ライブラリが x86-64-v2 向けにビルドされており (たとえば RHEL 9 とその派生ディストリビューション)、ゲストに見えるプロセッサーに v2 の機能が欠けています。 |
Fatal glibc error: CPU does not support x86-64-v3 | RHEL 10、Rocky Linux 10、AlmaLinux 10 など、x86-64-v3 向けにビルドされたシステムでの同じ状況です。 |
The current CPU is missing one or more of the following instruction sets: SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT | x86-64-v2 に満たないプロセッサー上の .NET 11 以降です。 |
glibc はこのチェックを動的ローダーの中で、どのプログラムコードよりも先に実行するので、動的リンクされたすべてのプログラムが同じメッセージで失敗します。
SLES 16 と openSUSE Leap 16 も x86-64-v2 向けにビルドされていて、そのローダーには同じチェックがありますが、チェックの前に SSE4.1 の命令である PINSRQ を実行します。QEMU 10.0 のユーザーモードで記録した実行では、それらの 16.0 イメージの ls と bash は、SSE4.1 のない CPU モデル (qemu64、kvm64、Conroe) ではその PINSRQ で SIGILL (「Illegal instruction」) により異常終了し、上のメッセージを表示したのは、SSE4.1 はあるものの SSE4.2 と POPCNT がない Penryn のときだけでした。これらのディストリビューションからビルドしたコンテナーイメージも、そうしたマシンでは同じように失敗します。コンテナーは自分が動いているマシンのプロセッサーを使うからです。どのシステムがどのレベルを必要とするかに最小要件の一覧があり、エラーメッセージでは、これらのメッセージや「Illegal instruction」などのほかのメッセージをより詳しく説明しています。
QEMU と KVM
-cpu オプションを指定しないと、QEMU は x86-64 のゲストに qemu64 モデルを与えます。このモデルには SSE3、CMPXCHG16B、LAHF/SAHF はありますが、SSSE3、SSE4.1、SSE4.2、POPCNT はないので、ゲストは x86-64-v1 です。それより古い kvm64 モデルには LAHF/SAHF もなく、やはり x86-64-v1 です。
VM がライブマイグレーションを必要としない場合、QEMU が推奨するのはホストのプロセッサーをパススルーすることです。
qemu-system-x86_64 -enable-kvm -cpu host ...
ホスト間をマイグレーションする VM では、代わりに最も古いホストに合う名前付きのモデルを選び (qemu-system-x86_64 -cpu help で一覧を表示できます)、ゲストの中でレベルを確認してください。
libvirt
<cpu> 要素のないドメインには qemu64 モデルが割り当てられます。代わりにドメイン XML で次のどちらかを使ってください。
<cpu mode='host-passthrough'/>
<cpu mode='host-model'/>
host-passthrough はホストのプロセッサーをそのまま公開します。host-model は、libvirt が表現できる範囲でホストのプロセッサーに最も近い記述を libvirt に求めます。これにより、似たホスト間でのライブマイグレーションが可能なままになります。
Proxmox VE
CPU タイプは VM ごとに Hardware > Processors > Type で設定するか、qm set <vmid> --cpu <type> で設定します。Proxmox はレベルにちなんだ名前のタイプを定義しています。
| CPU タイプ | レベル | 備考 |
|---|---|---|
kvm64 | x86-64-v1 | タイプを設定しないときのデフォルトです。 |
x86-64-v2 | x86-64-v2 | |
x86-64-v2-AES | x86-64-v2 | AES-NI を追加します。Web インターフェイスで作成した VM のデフォルトです。 |
x86-64-v3 | x86-64-v3 | |
x86-64-v4 | x86-64-v4 | |
host | ホストと同じ | ホストのプロセッサーをパススルーします。 |
Web インターフェイスのデフォルトである x86-64-v2-AES は、RHEL 9 とその派生ディストリビューションには十分ですが、RHEL 10、Rocky Linux 10、AlmaLinux 10 には足りません。これらには x86-64-v3 か host が必要です。
VMware vSphere
Enhanced vMotion Compatibility (EVC) は、クラスターのプロセッサー機能を 1 つのプロセッサー世代の機能までマスクし、ゲストにはその世代の機能だけが見えます。Broadcom は、x86-64-v2 を必要とするゲストには Nehalem 以上の EVC モードを勧めています。x86-64-v3 には、そのレベルに達している世代の EVC モードを選んでください。どの世代が達しているかは CPU のページに載っています。
Hyper-V
プロセッサー互換モードを有効にすると、Hyper-V は、VM がより古いプロセッサーを持つホストへ移動できるように、新しい命令セットを VM から隠します (Microsoft はそれらを、通常は過去 10 年以内に導入されたものと説明しています)。Microsoft は、これをマイグレーションのときだけ有効にし、その後は無効にすることを推奨しています。Windows Server 2025 では、クラスターのすべてのノードに共通する機能を提示する動的モードが追加されています。
結果の確認
CPU モデルを変更したら、VM を再起動し、ゲストの中でレベルを確認してください。
出典
- glibc: sysdeps/x86/dl-get-cpu-features.c (the start-up level check)
- QEMU documentation: Recommendations for KVM CPU model configuration on x86 hosts
- QEMU: target/i386/cpu.c (qemu64 and kvm64 models)
- Proxmox VE documentation: QEMU/KVM Virtual Machines, CPU Type
- Broadcom: "Fatal glibc error: CPU does not support x86-64-v2" (EVC mode)
- Microsoft: Processor compatibility for Hyper-V virtual machines
- SUSE Linux Enterprise Server 16.0 release notes
- .NET 11 breaking change: minimum hardware requirements (Microsoft)
- .NET 11.0.0-rc.1: src/coreclr/vm/codeman.cpp (the start-up instruction set check)