QEMU Configuration & Usage

Here I collect some QEMU options I have found useful beyond the basics.

Machine Type (x86)

-M q35 configures a more modern chipset to be emulated. The Q35 chipset supports PCI-e and includes an AHCI controller [1].

UEFI
Get UEFI support by replacing the bios using -bios ./OVMF-pure-efi.fd or OVMF-with-csm.fd if legacy boot is desired.
OVMF can be downloaded from https://www.kraxel.org/repos/jenkins/edk2/ (pick edk2.git-ovmf-x64-...). bsdtar can extract the rpms.
Many distributions also offer a matching ovmf package in their repos.

If you need UEFI settings (such as display resolution) to be persisted, a copy of OVMF_VARS (one per VM) needs to be provided too:

-drive file=./OVMF_CODE-pure-efi.fd,format=raw,if=pflash,readonly=on \
-drive file=./OVMF_VARS-pure-efi.fd,format=raw,if=pflash
Attaching disk images using VirtIO

Use -drive file=disk.img,if=virtio for improved disk performance. Windows guests require additional drivers [2] to use this.

Disabling disk cache flush
If you are installing a VM to quickly test something, disabling flushing of write cache to disk can speed up the process immensely:
-drive file=foobar.qcow2,if=virtio,cache=unsafe (or cache.no-flush=on)

Caution: Never use this in a production environment or with any VMs or data you care about. The guest OS will be tricked into believing it has safely written data to disk, when in reality it could be lost at any moment.

Attaching raw disks
-drive file=/dev/sdb,if=virtio,format=raw,cache=none

When attaching entire disks, partitions or logical volumes cache=none is a good idea.

Share host directory to guest

-drive file=fat:/path/to/dir,snapshot=on creates a read-only virtual FAT-formatted disk image from the given directory.

Multiple CD-ROM images
-drive file=X.iso,index=0,media=cdrom -drive file=Y.iso,index=1,media=cdrom

The index=N parameter is optional but can be used to explicitly order drives.

Bridged Network Adapter
-netdev bridge,br=br0,id=mynet -device virtio-net-pci,netdev=mynet
short syntax: -nic bridge,br=br0,model=virtio
For virtio, Windows needs additional drivers [2].
Aside from virtio-net-pci QEMU also supports emulating real cards such as:

e1000e (Intel 82574L GbE) which is the default, e1000 (Intel 82540EM GbE) or rtl8139 (Realtek RTL-8139C 10/100M)

CPU type
The default is -cpu qemu64.
To get the full CPU feature set in the guest use -cpu host or the appropriate family, e.g. -cpu Haswell.
Alternatively, flags can also be enabled individually: -cpu qemu64,+ssse3,+sse4.2,+avx,+avx2

-cpu kvm64 is legacy and should not be used [3].

VNC

-display vnc=localhost:1,lossy=on starts VNC on port 5901 (no authentication, but localhost only) with JPEG compression enabled to save bandwidth.

io_uring

io_uring is supported by Linux 5.1 and newer (on the host) and can further raise disk performance: -drive file=disk.qcow2,aio=io_uring

USB Input Devices
-usb -device usb-tablet -device usb-kbd attaches attaches keyboard and tablet (as mouse) via USB instead of PS/2.

This improves mouse support especially when using VNC and will stop the GUI from grabbing the input devices.

Port forwarding with User networking
When using -nic user (default) the hostfwd=PROTO::HPORT-:PORT option can be used to forward connections to the guest.

e.g. -nic user,model=virtio,hostfwd=tcp::2222-:22

VGA driver
-vga qxl offers improved performance over the default (std). Windows needs drivers, again [2].

3D acceleration for Linux guests is possible with -vga virtio [4].

Serial console
-serial pty connects the serial port to a PTY, which can then be interacted with using screen.
Alternatively when -nographic is used, the QEMU monitor and serial get multiplexed to stdio.

Ctrl-A c can then be used to switch between the monitor/serial [5].

Monitor console
With either -nographic or -monitor stdio, QEMU will make its monitor console available in the terminal.
It can also be accessed when using the GUI via "View" > "compatmonitor0".

The monitor console provides access to lots of functionality including snapshots, migration, device hotplug and debugging.

  • stop pauses the VM, cont resumes execution again

  • info registers shows the current values of CPU registers

  • x/x ADDRESS prints the hexadecimal value at the given address in guest memory

  • x/20i ADDRESS disassembles 20 instructions at the given address

Detailed explanations can be found in the relevant documentation.

Emulated SCSI controller
(because it's possible, not because it's useful)

-device lsi,id=lsi -drive file=somewhere.img,if=none,id=disk0 -device scsi-hd,drive=disk0,bus=lsi.0

Emulated USB drive

This may not seem useful at first look but will help if some software refuses to operate on "system" disks and requires a removable drive to be presented to the VM.

-drive file=whatever.qcow2,if=none,id=disk1 -device usb-storage,drive=disk1

As a bonus here's how that looks from the monitor console (hotplug):
drive_add 0 file=whatever.qcow2,if=none,id=disk1
device_add usb-storage,drive=disk1

Further reading