I have Rocket Chat in VM hosted in Cloudmin that relies on qemu. When I tried to update Rocket Chat to the latest version I got the following error:
Your cpu does not support avx or avx2 instructions, which is required to run mongo 5.x, shipped with the next version of this snap.
I logged in to the virtual machine and ran:
1 |
cat /proc/cpuinfo |
to get CPU details:
or to just get the list of flags:
1 |
grep ‘flags’ -m1 /proc/cpuinfo |
So VM has “generic” CPU with some default set of CPU flags among which “avx
” or “avx2
” flag are absent.
The VM possesses much less flags than its parent. The question is, if the cpu flags are beneficial, why arent they enabled for virtual machines?
The answer is simple: compatibility. By default, KVM sets the cpu mode to custom with generic model— to ensure that a persistent guest sees the same hardware no matter what host the guest is booted on. For that, many flags would be removed because that model doesn’t support them. Sometimes, however, the flags are truly necessary.
CPU flags or CPU features are attributes of CPU, denoted which features it supports. The features can be simple as calculating floating point unit, hyperthreading technology, or ability to extend physical memory to 64-bit address…
Examples of notable CPU flags can be:
ht
: Hyper-Threading — improves parallelism of computations
lm
: Long mode — supports 64-bit architecture
vmx
: Virtual Machine Extention — which must be enable for software virtualization services (KVM, VMWare, VirtualBox…) to work
fpu
: Floating Point Unit — supports floating point operations
aes-ni
(or simply aes): Advanced Encryption Standard new instructions — improves the speed of encryption / decryption operations using AES
pae
: Physical Address Extension — ability to use more than 4G memory for 32bit CPU
avx
: Advanced Vector Extensions — allows a (quite drastic) speed up in certain floating point operations.
In my hypervisor host I have AMD EPYC 7302P 16-Core Processor installed that supports avx
and avx2
flags so the question I got is to how to let VM know about capabilities of real processor.
Set Cloudmin’s VM CPU type in VM’s properties
You can pass CPU type to virtual machine by specifing it in virtual machine’s properties:
Now launch the virtual machine, log in to the VM and check CPU now:
1 |
cat /proc/cpuinfo |
And now VM has EPYC CPU on board with needed avx and avx2 flags:
And Rocket Chat’s update to the latest version ran without any issue.
That’s it!
The rest of the article explains more on Cloudmin and QEMU virtualization options.
Cloudmin leverages QEMU virtualization systems to run VMs and QEMU has options to configure CPU model for virtual machine:
QEMU Syntax for configuring CPU models in virtual machine
The examples below illustrate the approach to configuring the various CPU models / features in QEMU and libvirt
.
QEMU command line
Host passthrough:
1 |
qemu-system-x86_64 -cpu host |
Host passthrough with feature customization:
1 |
qemu-system-x86_64 -cpu host,vmx=off,... |
Named CPU models:
1 |
qemu-system-x86_64 -cpu Westmere |
Named CPU models with feature customization:
1 |
qemu-system-x86_64 -cpu Westmere,pcid=on,... |
The full list of supported options:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# qemu-system-x86_64 -cpu help (process:17585): GLib-WARNING **: 15:13:55.080: gmem.c:489: custom memory allocation vtable not supported x86 qemu64 QEMU Virtual CPU version 2.0.0 x86 phenom AMD Phenom(tm) 9550 Quad-Core Processor x86 core2duo Intel(R) Core(TM)2 Duo CPU T7700 @ 2.40GHz x86 kvm64 Common KVM processor x86 qemu32 QEMU Virtual CPU version 2.0.0 x86 kvm32 Common 32-bit KVM processor x86 coreduo Genuine Intel(R) CPU T2600 @ 2.16GHz x86 486 x86 pentium x86 pentium2 x86 pentium3 x86 athlon QEMU Virtual CPU version 2.0.0 x86 n270 Intel(R) Atom(TM) CPU N270 @ 1.60GHz x86 Conroe Intel Celeron_4x0 (Conroe/Merom Class Core 2) x86 Penryn Intel Core 2 Duo P9xxx (Penryn Class Core 2) x86 Nehalem Intel Core i7 9xx (Nehalem Class Core i7) x86 Westmere Westmere E56xx/L56xx/X56xx (Nehalem-C) x86 SandyBridge Intel Xeon E312xx (Sandy Bridge) x86 Haswell Intel Core Processor (Haswell) x86 Opteron_G1 AMD Opteron 240 (Gen 1 Class Opteron) x86 Opteron_G2 AMD Opteron 22xx (Gen 2 Class Opteron) x86 Opteron_G3 AMD Opteron 23xx (Gen 3 Class Opteron) x86 Opteron_G4 AMD Opteron 62xx class CPU x86 Opteron_G5 AMD Opteron 63xx class CPU x86 host KVM processor with all supported host features (only available in KVM mode) Recognized CPUID flags: pbe ia64 tm ht ss sse2 sse fxsr mmx acpi ds clflush pn pse36 pat cmov mca pge mtrr sep apic cx8 mce pae msr tsc pse de vme fpu hypervisor rdrand f16c avx osxsave xsave aes tsc-deadline popcnt movbe x2apic sse4.2|sse4_2 sse4.1|sse4_1 dca pcid pdcm xtpr cx16 fma cid ssse3 tm2 est smx vmx ds_cpl monitor dtes64 pclmulqdq|pclmuldq pni|sse3 smap adx rdseed rtm invpcid erms bmi2 smep avx2 hle bmi1 fsgsbase 3dnow 3dnowext lm|i64 rdtscp pdpe1gb fxsr_opt|ffxsr mmxext nx|xd syscall perfctr_nb perfctr_core topoext tbm nodeid_msr tce fma4 lwp wdt skinit xop ibs osvw 3dnowprefetch misalignsse sse4a abm cr8legacy extapic svm cmp_legacy lahf_lm pmm-en pmm phe-en phe ace2-en ace2 xcrypt-en xcrypt xstore-en xstore kvm_pv_unhalt kvm_pv_eoi kvm_steal_time kvm_asyncpf kvmclock kvm_mmu kvm_nopiodelay kvmclock pfthreshold pause_filter decodeassists flushbyasid vmcb_clean tsc_scale nrip_save svm_lock lbrv npt |
And now I had to find where this options can be specified.
There are two ways to configure CPU models with QEMU / KVM:
1. Host passthrough
This passes the host CPU model features, model, stepping, exactly to the guest. Note
that KVM may filter out some host CPU model features if they cannot be supported with
virtualization. Live migration is unsafe when this mode is used as libvirt / QEMU
cannot guarantee a stable CPU is exposed to the guest across hosts. This is the
recommended CPU to use, provided live migration is not required.
2. Named model
QEMU comes with a number of predefined named CPU models, that typically refer to
specific generations of hardware released by Intel and AMD. These allow the guest VMs
to have a degree of isolation from the host CPU, allowing greater flexibility in live
migrating between hosts with differing hardware.
In Cloudmin management script that run virtual machines are located in /etc/init.d
and named cloudmin-kvm
There Cloudmin uses qemu-kvm to run VMs:
I noticed, that qemu-kvm has wider CPU options available:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
[root@admin init.d]# /usr/libexec/qemu-kvm -cpu help x86 qemu64 QEMU Virtual CPU version 1.5.3 x86 phenom AMD Phenom(tm) 9550 Quad-Core Processor x86 core2duo Intel(R) Core(TM)2 Duo CPU T7700 @ 2.40GHz x86 kvm64 Common KVM processor x86 qemu32 QEMU Virtual CPU version 1.5.3 x86 kvm32 Common 32-bit KVM processor x86 coreduo Genuine Intel(R) CPU T2600 @ 2.16GHz x86 486 x86 pentium x86 pentium2 x86 pentium3 x86 athlon QEMU Virtual CPU version 1.5.3 x86 n270 Intel(R) Atom(TM) CPU N270 @ 1.60GHz x86 cpu64-rhel6 QEMU Virtual CPU version (cpu64-rhel6) x86 Conroe Intel Celeron_4x0 (Conroe/Merom Class Core 2) x86 Penryn Intel Core 2 Duo P9xxx (Penryn Class Core 2) x86 Nehalem Intel Core i7 9xx (Nehalem Class Core i7) x86 Nehalem-IBRS Intel Core i7 9xx (Nehalem Core i7, IBRS update)[7E▒V x86 Westmere Westmere E56xx/L56xx/X56xx (Nehalem-C) x86 Westmere-IBRS Westmere E56xx/L56xx/X56xx (IBRS update) x86 SandyBridge Intel Xeon E312xx (Sandy Bridge) x86 SandyBridge-IBRS Intel Xeon E312xx (Sandy Bridge, IBRS update) x86 IvyBridge Intel Xeon E3-12xx v2 (Ivy Bridge) x86 IvyBridge-IBRS Intel Xeon E3-12xx v2 (Ivy Bridge, IBRS) x86 Haswell Intel Core Processor (Haswell) x86 Haswell-IBRS Intel Core Processor (Haswell, IBRS) x86 Broadwell Intel Core Processor (Broadwell) x86 Broadwell-IBRS Intel Core Processor (Broadwell, IBRS) x86 Skylake-Client Intel Core Processor (Skylake) x86 Skylake-Client-IBRS Intel Core Processor (Skylake, IBRS) x86 Skylake-Server Intel Xeon Processor (Skylake) x86 Skylake-Server-IBRS Intel Xeon Processor (Skylake, IBRS) x86 Cascadelake-Server Intel Xeon Processor (Cascadelake) x86 Opteron_G1 AMD Opteron 240 (Gen 1 Class Opteron) x86 Opteron_G2 AMD Opteron 22xx (Gen 2 Class Opteron) x86 Opteron_G3 AMD Opteron 23xx (Gen 3 Class Opteron) x86 Opteron_G4 AMD Opteron 62xx class CPU x86 Opteron_G5 AMD Opteron 63xx class CPU x86 EPYC AMD EPYC Processor x86 EPYC-IBPB AMD EPYC Processor (with IBPB) x86 host KVM processor with all supported host features (only available in KVM mode) Recognized CPUID flags: pbe ia64 tm ht ss sse2 sse fxsr mmx acpi ds clflush pn pse36 pat cmov mca pge mtrr sep apic cx8 mce pae msr tsc pse de vme fpu hypervisor rdrand f16c avx osxsave xsave aes tsc-deadline popcnt movbe x2apic sse4.2|sse4_2 sse4.1|sse4_1 dca pcid pdcm xtpr cx16 fma cid ssse3 tm2 est smx vmx ds_cpl monitor dtes64 pclmulqdq|pclmuldq pni|sse3 avx512vl avx512bw sha-ni avx512cd avx512er avx512pf clwb clflushopt pcommit avx512ifma smap adx rdseed avx512dq avx512f mpx rtm invpcid erms bmi2 smep avx2 hle bmi1 fsgsbase cldemote rdpid avx512-vpopcntdq avx512bitalg avx512vnni vpclmulqdq vaes gfni avx512vbmi2 ospke pku umip avx512vbmi ssbd arch-facilities|arch-capabilities stibp spec-ctrl md-clear avx512-4fmaps avx512-4vnniw 3dnow 3dnowext lm|i64 rdtscp pdpe1gb fxsr_opt|ffxsr mmxext nx|xd syscall perfctr_nb perfctr_core topoext tbm nodeid_msr tce fma4 lwp wdt skinit xop ibs osvw 3dnowprefetch misalignsse sse4a abm cr8legacy extapic svm cmp_legacy lahf_lm invtsc virt-ssbd ibpb pmm-en pmm phe-en phe ace2-en ace2 xcrypt-en xcrypt xstore-en xstore kvm_pv_unhalt kvm_pv_eoi kvm_steal_time kvm_asyncpf kvmclock kvm_mmu kvm_nopiodelay kvmclock pfthreshold pause_filter decodeassists flushbyasid vmcb_clean tsc_scale nrip_save svm_lock lbrv npt xsaves xgetbv1 xsavec xsaveopt taa-no tsx-ctrl mds-no ssb-no skip-l1dfl-vmentry rsba ibrs-all rdctl-no |
And EPYC is what I needed.
Make a backup of this file in a safe place and open it in a text editor.
Next, find the needed virtual machine and add -cpu
flag with a proper parameter.
In my case I used Named model of configuration as Host passthrough is available in KVM mode only:
after smp
I added -cpu EPYC
directive and saved the file.
Now go to Cloudmin menu, choose your VM, shutdown it, and after a while start it.
Good luck!