QEMU
BitVisor

QEMU上でBitVisorは動作するか? SMP編

以下の記事ではQEMU上でのBitVisorの実行に成功していましたが、SMPは使用していませんでした。果たしてどうなるでしょうか。

QEMU上でBitVisorは動作するか? リベンジ編

https://qiita.com/hdk_2/items/dab49edf80975f4cc7d0

面倒なのでKVMありの場合だけ紹介します。


  • Debian GNU/Linux 9

  • Linux 4.9.0-8-amd64

  • QEMU 2.8.1(Debian 1:2.8+dfsg-6+deb9u5)

  • AMD Ryzen 7 2700


起動パラメーター

qemu-system-x86_64 -bios OVMF.fd -cpu host -enable-kvm -m 2048 -snapshot -cdrom ../data/iso/ubuntu-18.04-desktop-amd64.iso -hda fat:bitvisor/_ -M q35 -vga qxl -smp 2


結果

z1.png

2個目のプロセッサを開始したログも出ていますし、一見大丈夫そうに見えますね? 実はこれ、ダメなんです...

z2.png

このように、taskset 1ならdbgshが動くのに、taskset 2だと動きません。


Intel環境の場合は?

Intel環境では、2個目のプロセッサを開始したところで、VM entry failed. panicが発生するそうです。その理由は、BitVisorがVMCSのguest activity stateにwait-for-SIPIをセットしたためみたいです。実は、IA32_VMX_MISC MSRに、guest activity stateにactive以外のステートをセットできるかどうかを示す情報があるのですが、BitVisorはこれをチェックしないで使用してしまっています。QEMU KVMはwait-for-SIPI未対応と返しているみたいです。

なお、問題はそれだけではないようです。


何が起きているのか?

推測ですが、どうやら、QEMUかKVMのいずれかあるいは両方のINIT信号の処理には問題があるようです。BitVisorでは以下の機能を使用していますが、いずれもQEMU KVM上では正しく動作しません。


  • AMDの場合: VM_CR MSRのR_INITビットをセットすることにより、INIT信号は#SX例外に変換される

  • Intelの場合: INIT信号は、VMX root operationであればブロックされ、VMX non-root operationであればVM exitになる

BitVisorのSMP対応はこの機能をあてにしていて、AMD環境では常にlocal APICのIPI送信をフックしていますが、それで見ているのはUEFI環境での最初のINIT信号送信と、startup IPI送信だけです。しかも、裏から見ているだけで、実際にINIT信号もstartup IPIも送信されます。AMD環境ではwait-for-SIPIを受け取る特別な機能はないので、INIT信号を受けたらwait-for-SIPI待ちのポーリング処理に移る仕掛けになっています。

それで、QEMU KVM上ではどうやら、INIT信号を受けたプロセッサは、本当にリセットしてwait-for-SIPIステートに移ってしまうようです。それで2個目のプロセッサではBitVisorがいなくなってしまい、QEMU KVM上で直接動作していたのでdbgshが動作しないのです。Intelの場合も同じような問題を抱えているっぽいです。

Intelでwait-for-SIPIステートが使えないプロセッサに対応できていないのはBitVisorの問題ですが、INIT信号を正しく扱えないのはQEMUあるいはKVMのバグということになりそうです。