先月のBitVisor Summitにおいて,BitVisor上でAVX512命令を使うとillegal instructionになるという話をしたのですが1,改めて調べると原因が分かりました.
原因
extended control register(XCR)というレジスタがあり,この0番(XCR0)に浮動小数点機能の有効状態等の情報が格納されています.
XCRへはXGETBV/XSETBV命令でアクセスします.XSETBV命令はVMEXITが発生することになっており,この対応をBitVisorはcore/xsetbv_pass.c
でおこなっています.
BitVisorではXCR0の中のSSE及びAVX stateに関するbitに関してパススルーしていましたが,AVX512では新たに3つのstate bitが追加されました.ゲストがこの3つのstate bitを設定することができなかったため,AVX512命令を実行するとillegal instructionとなっていました.
対策
SSE, AVXの場合と同様にAVX512のstate bitもパスルルーするようにして対応してあげれば良いのではないかと思います.
問題発覚の経緯
そもそもの事の発端は,AVX512をサポートするCPUでUbuntu18.04をBitVisor上で起動した際に,起動時に読み込まれるraid6のカーネルモジュールがAVX512命令を使用しており,そこでパニックするという問題でした.
IntelのSDMでは,AVX512が利用可能かどうかの条件として,以下の3つを挙げています(SDM Vol1. 15.2).
- CPUID.1:ECX.OSXSAVE[bit 27] = 1
- XCR0のAVX512関連のstateが有効になっている (XCR[7:5] = 111b, XCR[2:1] = 11b)
- CPUID.7:EBX.AVX512F[bit 16] = 1
しかしながら,Linuxのraid6のモジュールはXCRを参照せず,CPUID.7の結果のみでAVX512が利用できるかどうかを判断しています.
XCR0のAVX512のstate bitが利用可能かどうかは,CPUID.7とは別に,CPUID.0xdに格納されています.そして,BitVisorはもともとAVX512のstate bitはマスクして利用不可能として通知するようにしていました(core/cpuid_pass.c
).
したがって,本来であればXCR0のAVX512 stateが利用できないこと,ひいてはAVX512命令が使用不可なことは分かるはずなので,AVX512命令を勝手に使うraid6のモジュールが悪いということになります.といっても現実的にCPUID.7でAVX512命令のサポートを示しておきながらXCR0のAVX512 stateが使えないプロセッサがバグ以外に存在するのかは分かりませんが..
逆に言うと,AVX512を隠蔽したいならCPUID.7もマスクしてあげたほうが親切かと思います.
ちなみに
BitVisorではVMENTRY/VMEXITに伴う浮動小数点関連のレジスタの退避/復元はしていません.もしBitVisor側から浮動小数点命令を実行したい場合は自分で退避/復元する必要があります.
以下が参考になるかもしれません.
- Yasushi Shinjo, [BitVisor-devel:91] 保護ドメインでの浮動小数点の利用, 2016.
-
正確にはVMWare上でBitVisorを動かした時,という話をしたのですが,VMWare関係ない話だと思います.環境の問題で実機での確認ができていませんが. ↩