hiroの長い冒険日記

主にコンピュータ周辺の興味を持った内容を綴ります

qemu whpx & haxm option が機能しない理由 (もしかして Virtualbox も?)

qemu の whpx option と haxm option が使用できない件について、以下の記事に記載した。
hiro20180901.hatenablog.com
hiro20180901.hatenablog.com
hiro20180901.hatenablog.com
最後の haxm の error message「UG mode is not supported by the hardware.」が気になり、詳細について調べてみた。

使用している CPU

私の使用している PC の CPU は Core i7-870 である。

$ cat /proc/cpuinfo 
processor	: 0
vendor_id	: GenuineIntel
cpu family	: 6
model		: 30
model name	: Intel(R) Core(TM) i7 CPU         870  @ 2.93GHz
stepping	: 5
microcode	: 0x4
cpu MHz		: 1200.000
cache size	: 8192 KB
physical id	: 0
siblings	: 8
core id		: 0
cpu cores	: 4
apicid		: 0
initial apicid	: 0
fpu		: yes
fpu_exception	: yes
cpuid level	: 11
wp		: yes
flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm sse4_1 sse4_2 popcnt lahf_lm kaiser tpr_shadow vnmi flexpriority ept vpid dtherm ida
bugs		: cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf
bogomips	: 5887.17
clflush size	: 64
cache_alignment	: 64
address sizes	: 36 bits physical, 48 bits virtual
power management:

ark.intel.com
Intel VT-x、VT-d、EPT (拡張ページテーブル) に対応していると Intel のページからは読み取れる。

Sandy Bridgeおじさん」なんて言葉もあるが、それより前の「Nehalem」世代。開発コード Lynnfield 、4コア8スレッドである。
ark.intel.com

Intel CPU の仮想化技術は VT-x、VT-d だけではない

Intel CPU の仮想化技術は、一般的に Intel VT (Intel Virtualization Technology) と呼ばれている。
ja.wikipedia.org
Wikipedia にもあるように、Intel VT は

  • Intel IA-64 用の VT-i
  • Intel 64 用の VT-x
  • I/O 処理の仮想化の為の VT-d

の3種類が存在している、というのが私の認識だった。VT-x に対応していれば仮想化ソフトウェアは高速で動作できる、と考えていた。だが、実際には違う。

Intel CPU の仮想化技術は、より効率的な仮想化を行うために、CPU の世代毎に機能が追加されている。EPT もそう。Intel VT に対応、と書かれていても、追加された機能に対応しているか、していないか、によって、仮想化ソフトウェアが機能するか、しないか、高速に動作するか、しないかが決まってしまう。今回、qemu haxm option が「UG mode is not supported by the hardware.」の error で有効に出来なかった事も、この「追加された機能」に Core i7-870 が対応していなかった事が原因である。この追加された機能は細かく分けられているのにも関わらず、Intel のページには記載がない。

UG = Unrestricted Guest で、これを keyword にググると色々と見つかった。

Intel VT Unrestricted Guest feature

Unrestricted Guest をググって多く見つかったのは、VMware に関する記事だった。
ips.nekotype.com
abhp.net
communities.vmware.com
2017年に VMware 12 から 14 に update された際に、Intel VT-x の新しい機能を使うように変更になり、古い CPU のサポートが削除された模様。その機能が Unrestricted Guest mode で、

Intel 「Nahalem」 以前の CPU はこのリリースではサポートされていません

と書かれている。なので、(試してはいないが) VMware 14 は私の PC では使用できないはずである。

Unrestricted Guest の他に、どのような追加機能があるのか、どのようにして調べることが出来るのかを、上記3番目の記事を keyword に調べてみた。

Intel VT 追加機能をどうやって調べるか

上記3番目の記事には、次のように書かれている。

If you have an old vmware.log file, you can see bit 5 of MSR 485. If bit 5 is zero it means the Unrestricted Guest feature is not available.

どうにかして、CPU が対応している仮想化技術を調べられないかと考えた。
MSR:
en.wikipedia.org
MSR (Model-specific register) を読み込む事によって、仮想化技術の対応状況が調べられそうな気配がある。

MSR からIntel VT 追加機能の有無を取得する

更に調査を進めていくと、MSR を読み込むのは linux だと簡単に出来ることが分かった。linux では、msr.ko を modprobe で読み込むと /dev/cpu/[0-n]/msr が使えるようになる。ただし、読み込んでも分かりにくい情報なので、整理された状態で表示する事が出来るか調べると、uproc で可能だった。
github.com
build 方法や使い方は README.md に記載されている。cmake、flex、bison、chicken-bin が必要である。

実行結果は以下の通り。
updump:

$ sudo modprobe msr
$ sudo dump/updump 
==================== profile dump start ====================
date:     2019-02-21 19:53:44 UTC+0900
computer: PC (7952 MB)
OS:       unknown GNU/Linux
kernel:   Linux 4.9.0-8-amd64

CPUID dump:
      leaf   subleaf       eax       ebx       ecx       edx
         0                   b  756e6547  6c65746e  49656e69
         1               106e5   1100800    98e3fd  bfebfbff
         2            55035a01    f0b2e4         0   9ca212c
         3                   0         0         0         0
         4         0  1c004121   1c0003f        3f         0
         4         1  1c004122    c0003f        7f         0
         4         2  1c004143   1c0003f       1ff         0
         4         3  1c03c163   3c0003f      1fff         2
         5                  40        40         3      1120
         6                   3         2         1         0
         7                   0         0         0         0
         8                   0         0         0         0
         9                   0         0         0         0
         a             7300403        44         0       603
         b         0         1         2       100         1
         b         1         4         8       201         1
  80000000            80000008         0         0         0
  80000001                   0         0         1  28100800
  80000002            65746e49  2952286c  726f4320  4d542865
  80000003            37692029  55504320  20202020  20202020
  80000004            30373820  20402020  33392e32    7a4847
  80000005                   0         0         0         0
  80000006                   0         0   1006040         0
  80000007                   0         0         0       100
  80000008                3024         0         0         0

MSR dump:
  IA32_FEATURE_CONTROL                                     7
  IA32_MISC_ENABLE                                    850089
  IA32_APIC_BASE                                    fee00900
  IA32_EFER                                              d01
  IA32_VMX_BASIC                              da04000000000e
  IA32_VMX_PINBASED_CTLS                          7f00000016
  IA32_VMX_PROCBASED_CTLS                   fff9fffe0401e172
  IA32_VMX_PROCBASED_CTLS2                        7f00000000
  IA32_VMX_EXIT_CTLS                          7fffff00036dff
  IA32_VMX_ENTRY_CTLS                           ffff000011ff
  IA32_VMX_MISC                                        401c5
  IA32_VMX_VMCS_ENUM                                      2a
  IA32_VMX_EPT_VPID_CAP                          f0106114141
  IA32_VMX_TRUE_PINBASED_CTLS                     7f00000016
  IA32_VMX_TRUE_PROCBASED_CTLS              fff9fffe04006172
  IA32_VMX_TRUE_EXIT_CTLS                     7fffff00036dfb
  IA32_VMX_TRUE_ENTRY_CTLS                      ffff000011fb
  IA32_VM_CR                                             n/a
===================== profile dump end =====================

Intel の技術資料を見れば、各項目の意味が分かる...はず。理解できない部分が多いが、参考:
software.intel.com
24.6.2 Processor-Based VM-Execution Controls の Table 24-7. に IA32_VMX_PROCBASED_CTLS2 (index 48BH) についての中身が書いてあり、bit 7 が Unrestricted Guest feature 有効/無効の判定になっている。a.3.3 より上位32bits が有効と分かるので、32+7 = 39 bit 目が該当箇所になる。uproc の source 内でも同様な事を確認した(dump/x86msr.c, parse/parse.scm)。

parse すると人間が読みやすい形で表示してくれる。
upparse:

$ sudo dump/updump | convert/upconvert | parse/upparse 

Generic features:

 - Physical Address Extension: yes
 - Physical Attributes Table: yes
 - MONITOR/MWAIT: yes
 - x2APIC: no
 - x2APIC is active: no
 - XSAVE instruction: no
 - XSAVE is active: no
 - Long Mode: yes
 - Long Mode is active: yes
 - No-Execute Page Protection: yes
 - No-Execute Page Protection is active: yes
 - Process-Context Identifiers: no
 - RDRAND instruction: no
 - Bit Manipulation Instructions: no
 - Bit Manipulation Instructions 2: no
 - Supervisor-Mode Execution Prevention: no
 - Supervisor-Mode Access Prevention: no
 - Hardware Lock Elision: no
 - Restricted Transactional Memory: no
 - Feature Control Locked: yes

SIMD features:

 - MultiMedia eXtensions: yes
 - Steaming SIMD Extensions: yes
 - Steaming SIMD Extensions 2: yes
 - Steaming SIMD Extensions 3: yes
 - Supplemental Steaming SIMD Extensions 3: yes
 - Steaming SIMD Extensions 4.1: yes
 - Steaming SIMD Extensions 4.2: yes
 - AESNI instructions: no
 - Advanced Vector Extensions: no
 - Advanced Vector Extensions 2: no
 - Fused Multiply-Add: no

Intel VT-x features:

 - Virtual Machine eXtension: yes
 - VMX outside SMX: yes
 - MSR Bitmaps: yes
 - TPR Shadow: yes
 - Secondary Controls: yes
 - Virtual APIC: yes
 - Preemption Timer: yes
 - Posted Interrupts: no
 - Extended Page Tables: yes
 - Descriptor-table exiting: yes
 - Virtual Processor Identifiers: yes
 - Unrestricted Guest: no
 - PAUSE-Loop Exiting: no
 - VMCS Shadowing: no
 - EPT-Violation #VE: no

AMD SVM features:

 - Secure Virtual Machine: no
 - Nested Paging: no
 - Next RIP Save: no
 - VMCB Clean Bits: no
 - Flush By ASID: no
 - Decode Assists: no
 - Pause Filter: no
 - Pause Filter Threshold: no
 - Advanced Virtual Interrupt Controller: no

こちらをみると、Core i7-870 の VT-x features は
yes:

 - Virtual Machine eXtension: yes
 - VMX outside SMX: yes
 - MSR Bitmaps: yes
 - TPR Shadow: yes
 - Secondary Controls: yes
 - Virtual APIC: yes
 - Preemption Timer: yes
 - Extended Page Tables: yes
 - Descriptor-table exiting: yes
 - Virtual Processor Identifiers: yes

No:

 - Posted Interrupts: no
 - Unrestricted Guest: no
 - PAUSE-Loop Exiting: no
 - VMCS Shadowing: no
 - EPT-Violation #VE: no

という事で、Unrestricted Guest には対応していない。また、15 項目中の 5 項目は対応していない事が分かった。

推論

  • 少なくとも現在の最新版の qemu を haxm option 付で使用する為には Unrestricted Guest feature が必須。
  • android emulator が haxm で動作したのは、内部で使用している qemu が Unrestricted Guest feature の機能を software で行なっているのではないか。だから遅いのかも。qemu が新しくなれば、対応する CPU で高速化できる反面、古い CPU では動作しなくなるだろう。
  • Hyper-V (whpx) で Virtualboxqemu が動作しない (capability がない) のも、必要な Intel VT の機能がない為ではないだろうか。
  • Hyper-V 仮想マシンや Docker Desktop は、hypervisor platform で公開されていない Windows 内部の機能を使用して whpx 無効と判断される環境でも動作するのではないだろうか。
  • Hyper-V 無効で今の CPU Core i7-870 で Virtualbox が使えているのは、実は幸運な事かもしれない。仮想環境の速度を上げるのに、古い環境を切り捨てて hardware 処理を利用した方が効率良く simple にできるだろう。

結果

これまで、Hyper-V 有効、あるいは Intel HAXM 有効なのに使えない機能があってモヤモヤしていたが、CPU の仮想環境についての機能不足が分かり、残念な気持ちもあるが幾分スッキリした。

whpx も haxm も、install や実行段階で、動作しない明確な理由や error message を出してくれていたら、もっと早く原因が掴めたと思う。

これまで、Hyper-VIntel HAXM、Virtualboxqemu で仮想環境を使用して色々と遊んできた。今回の件を通して、昔の Z80/8086/80286/80386 で遊んでいた時を思い出した。昔と違い、今は一次情報に簡単に接する事ができる良い時代だと思った。Open Source だという事も大きい。

今の Nehalem (Lynnfield) を何処まで使えるか分からないが、新しい環境を入手するまで、色々と遊んでみたい。