Sometimes it can be hard to choose a CPU model for VMs. There are many factors that can limit our options, like security or performance restrictions, or even the hardware you are using in your data center.
In this post I’d like to share my approach for selecting a CPU model for KVM x86 hosts, and some tips on how to deal with the possible restrictions you might face during that process.
Selecting a base CPU model
The first step is always to find the closest QEMU CPU model that fits our hardware. To do so, we can use the
virsh -c qemu:///system capabilities command. You can see below the output when executed in a laptop:
<counter name='tsc' frequency='1799996000' scaling='no'/>
<topology sockets='1' cores='4' threads='2'/>
/host/cpu/model we can get the closest QEMU CPU model that fits the hardware of our host, in this case
Broadwell-noTSX-IBRS. If all your hosts have the same CPU, you can use this CPU model straightaway.
Note that from OpenNebula 5.10 “Boomerang” onwards, the CPU model is retrieved automatically during the host monitoring process and stored in
You may want to group servers by CPU model in different OpenNebula clusters and then use the virtual CPU model closest to the hypervisor model. However, this might not always be an option. In that case, just repeat the process described above to find out which QEMU CPU models fits your hardware specs.
Once you have your server specs, follow QEMU docs to select the best QEMU model supported by all your hosts. This way you’ll make sure you are using the optimum model compatible with all of them while—and this is important—preserving the ability to live migrate VMs.
For example, imagine you have these three different CPU models:
Haswell-IBRS. According to the official documentation, the best QEMU model we’d have to choose in order to fit the specs of this heterogeneous datacenter would be
More info about how to obtain information about the capabilities of the virtualization host via the libvirt toolkit can be found here:
- Driver capabilities XML format: Host capabilities
- Application Development Guide: Capability information
Security and performance restrictions
Once you have selected a base QEMU CPU model, you need to check if it satisfies your restrictions. Here you can find out which features are exposed by each QEMU CPU model.
At this poing, it is also quite sensible to check which security mitigations are enabled and which are left vulnerable inside the guest OS. For example, let’s check the content of
$ cd /sys/devices/system/cpu/vulnerabilities
$ grep . *
l1tf:Mitigation: PTE Inversion
mds:Vulnerable: Clear CPU buffers attempted, no microcode; SMT Host state unknown
spectre_v1:Mitigation: usercopy/swapgs barriers and __user pointer sanitization
spectre_v2:Mitigation: Full generic retpoline, STIBP: disabled, RSB filling
We can see here that the CPU of this example is actually vulnerable to
Another interesting way of examining the guest OS in search of CPU vulnerabilities is by running some Spectre checkers like https://github.com/speed47/spectre-meltdown-checker.
If you find out that you need to incorporate some security or performance feature to the CPU model you are using for your VMs, you can always add them by using the RAW section inside the VM template and leaving the field
For example, if we want to use the
pcid feature and our CPU model does not enable it by default, we could use the following RAW section inside the VM template:
RAW = [
DATA = "<cpu mode='custom'><model
TYPE = "kvm"
We can set this configuration as the one by default by modifying
You can find more information about important features at Intel x86 CPUs, like Spectre mitigations, right here.
Remember that a very convenient way to prevent cross-VM attacks based on the speculative nature of the processors is the use of the CPU pinning feature introduced in OpenNebula 5.10, which isolates a VM in a whole core using the core policy.
As always, don’t hesitate to send us your comments or questions!