Using a QEMU Accelerator
When virtualizing a guest operating system that has the same instruction set architecture as the host, it is possible to use hardware virtual machine extensions provided by the host CPU to increase the performance of the guest machine significantly. Modern CPUs tend to have these acceleration features, although it might be necessary to enable them in the system firmware.
Background
Effective virtualization of an instruction set architecture requires that the set of sensitive instructions is a subset of the privileged instructions for that architecture, per the theorem by Popek and Goldberg. The sensitive instructions that a CPU provides are those instructions that either depend on, or change, the state of the processor. Privileged instructions are those that the CPU will not execute in its less-privileged user mode (also known as ring 3 on x86_64); instead, the CPU will generate a trap that causes the operating system to switch into supervisor mode (also known as ring 0 on x86_64), which has the required privileges to run these instructions.1
The basic x86 and x86_64 instruction sets contain sensitive instructions that are not privileged, making efficient virtualization difficult. Both AMD and Intel have added extensions to their CPUs to add an additional mode above supervisor mode. This mode, hypervisor mode (or ring -1), makes virtualization efficient on x86_64 CPUs by allowing virtualization software to trap all the sensitive instructions in the instruction set. While Intel used to segment the CPU market based on the availability of virtual machine extensions, they have become standard on essentially all modern AMD and Intel CPUs. Intel refers to this technology at VT-x, while AMD uses the terms SVM and AMD-V. Armv8, with its AArch64 instruction set, also has virtualization extensions available.
Note that is still possible to run virtual machines without using hardware-accelerated virtualization. The guest machines will run more slowly, since the virtualization software has to do a lot more heavy lifting to process and dynamically recompile instructions on the fly. However, the guest machine will still run.
Firmware Settings
Some laptop and motherboard vendors ship their devices with virtualization technology disabled by default, while others enable them. It is a good idea to check to see that these capabilities are enabled, but the exact procedure to do so varies wildly between computer systems. The first step on most x86_64 systems is to boot into the UEFI firmware settings (also still sometimes called the BIOS setup). From there, it is necessary to look through all the pages of settings, looking for anything related to “virtualization,” “VT,” or “SVM” and ensuring that it is enabled. Unfortunately, there isn’t a standard location for this setting, so it is usually necessary to look through all the settings to find it.
To get into the UEFI firmware, there is normally a key that can be pressed immediately at boot time. On many systems, that key is Del, F1, or F2; however, it can be wildly different depending on the manufacturer. Windows users can hold down the Shift key while selecting Restart from the Power section of the Start Menu. A dialog will appear with an option to Troubleshoot. Under Advanced Options, choose UEFI firmware settings.
Host Operating System
Once you have the virtualization extensions enabled in the firmware settings, the next step is to ensure that the proper drivers are in place in the operating system. In practice, hardware-accelerated virtualization is easiest if you are running Linux as your host operating system. KVM “just works” as long as your hardware virtual machine extensions are turned on in the firmware and your user account has permissions to use it. The same cannot be said for the other host platforms, which require additional work.
Linux
If you are running Linux, then the KVM driver should be loaded automatically. Verify by running:
lsmod | grep kvm
and verify that the kvm_amd or kvm_intel module is loaded. The only other required step is to ensure that your regular user account is a member of the “kvm” group. Verify that the kvm group is used on your system by running:
ls -l /dev/kvm
You can verify that your account is a member of the kvm group by running:
groups | grep kvm
Adding your user account to the kvm group can be done on most systems by running:
gpasswd -a username kvm
(Replace username with your user name.)
Note that some distributions do not use the kvm group, while others make /dev/kvm world readable and writable by default. As long as your user account can read and write to /dev/kvm, you should be able to use virtualization extensions.
macOS
Mac systems enable virtualization extensions by default. The Hypervisor.Framework built into macOS provides an interface to these extensions. However, applications have to have an entitlement to use Hypervisor.Framework, which is a slightly annoying process.
See Installing QEMU on macOS for more information.
Windows
Windows has its own virtual machine interface called Hyper-V, which is available in Windows 10 Professional and Enterprise editions (it is not available in the Home edition). As of QEMU 7.1.0, my testing with Hyper-V as an accelerator on a Windows machine has not gone well. I am admittedly not a Windows user, and I might have missed a setting somewhere.
Intel used to have an accelerator available for Windows called HAXM. However, in early 2023, Intel discontinued development of this accelerator and recommended against its use due to outstanding security issues.2
Enabling the Accelerator in QEMU
Once hardware virtual machine extensions have been enabled in the firmware, and any required operating system changes have been made, using the extensions with QEMU is straightforward. The -accel argument specifies which accelerator to use.
My examples are designed to work with any system, so they do not use hardware acceleration. The QEMU argument:
-accel tcg
instructs QEMU to use its built-in dynamic recompiler (the Tiny Code Generator) instead of hardware-based virtualization. All we need to do is change “tcg” to the correct accelerator for the host system. On Linux, this is straightforward: just use “-accel kvm” to enable KVM. Mac users would use either “-accel hvf” to use Hypervisor.Framework.
Remember that hardware virtualization is only available if the guest operating system has the same instruction set architecture as the CPU. For example, you cannot enable a hardware-based accelerator when running AArch64 code on an x86_64 processor, or vice-versa. The guest and host architectures must match.
References and Further Reading
-
Gerald J. Popek and Robert P. Goldberg. “Formal requirements for virtualizable third generation architectures.” Communications of the ACM 17(7), 412-421. July 1974. Available from the ACM Digital Library ↩
-
Michael Larabel. Intel Discontinues Development Of Open-Source HAXM Software. Phoronix. January 7, 2023. ↩