QEMU vs QEMU-KVM: Understanding the Differences Between qemu-system-x86_64 and qemu-x86_64 Binaries


2 views

Historically, QEMU-KVM was a specialized fork of QEMU that focused specifically on KVM acceleration support. As mentioned in the QEMU documentation, this fork has been deprecated since 2012 when KVM support was fully merged into mainline QEMU. Today, you should always use the upstream QEMU (qemu-system-x86_64) rather than the old qemu-kvm package.

When you install modern QEMU, you'll typically find these binaries:

/usr/local/bin/qemu-system-x86_64  # Full system emulator
/usr/local/bin/qemu-x86_64        # User-mode emulator

This is the main QEMU binary that libvirt and other management tools use. It provides complete system virtualization, including:

  • Full hardware emulation (CPU, memory, devices)
  • KVM acceleration support when available
  • Support for various machine types and architectures

Example usage with KVM:

qemu-system-x86_64 -enable-kvm -m 2048 -hda vm.img

This binary serves a completely different purpose - it allows running individual Linux programs compiled for one architecture (x86_64 in this case) on a different host architecture. Key characteristics:

  • Doesn't virtualize a complete system
  • Translates individual process system calls
  • Useful for cross-architecture development/testing

Example usage:

qemu-x86_64 ./arm64_program

Yes, the modern qemu-system-x86_64 still uses KVM acceleration when available. The performance is identical to the old qemu-kvm fork because:

  • The KVM kernel module provides the same hardware acceleration
  • QEMU's KVM integration is now more mature than in the old fork
  • You can verify KVM is active with:
cat /proc/cpuinfo | grep hypervisor
dmesg | grep -i kvm

When upgrading from qemu-kvm to mainline QEMU:

  • Update libvirt configurations to point to qemu-system-x86_64
  • Check that the KVM module is loaded (lsmod | grep kvm)
  • Verify performance with benchmarks if needed

Example libvirt domain XML configuration:

<domain type='kvm'>
  <name>example-vm</name>
  <emulator>/usr/local/bin/qemu-system-x86_64</emulator>
  ...
</domain>

When working with QEMU 2.5.0+, you'll encounter several binaries:

/usr/local/bin/qemu-system-x86_64  # Full system emulator
/usr/local/bin/qemu-x86_64         # User-mode emulator
/usr/bin/qemu-kvm                  # Legacy KVM-optimized version (deprecated)

qemu-system-x86_64 is what you want for virtualization - it handles complete system emulation including CPU, memory, and devices. This is what libvirt interacts with.

qemu-x86_64 serves a completely different purpose - it's for user-mode emulation, allowing you to run individual x86_64 Linux binaries on different architectures (like ARM). Example usage:

# Run x86_64 binary on ARM host
qemu-x86_64 -L /path/to/x86_64/libs my_x86_program

The standalone qemu-kvm fork has been deprecated since 2012. Modern QEMU incorporates all KVM optimizations directly. When using qemu-system-x86_64, KVM acceleration is automatically enabled if:

  1. KVM kernel modules are loaded
  2. Your CPU supports virtualization extensions
  3. You have appropriate permissions (/dev/kvm access)

Verify KVM activation with:

ps aux | grep qemu | grep -- -enable-kvm

With modern QEMU (2.0+), there's no performance difference between the old qemu-kvm and current qemu-system-x86_64 when using KVM. Both utilize the same hardware acceleration.

However, if KVM isn't available, QEMU falls back to software emulation (TCG), which is significantly slower. Always check dmesg for KVM initialization:

dmesg | grep kvm
# Should see "kvm: disabled by bios" or similar if not working

Here's a sample libvirt domain XML snippet showing proper QEMU/KVM usage:

<domain type='kvm'>
  <name>vm1</name>
  <memory unit='KiB'>2097152</memory>
  <vcpu placement='static'>2</vcpu>
  <os>
    <type arch='x86_64' machine='pc-i440fx-2.5'>hvm</type>
    <boot dev='hd'/>
  </os>
  <devices>
    <emulator>/usr/bin/qemu-system-x86_64</emulator>
    <!-- other devices -->
  </devices>
</domain>