Server

virtio Drivers Explained

By Prabath Thalangama· October 24, 2026· 3 min read
#kvm#virtio#performance

Introduction

When a VM uses an emulated device (e1000 NIC, IDE disk), every I/O operation traps to the hypervisor, which mimics real hardware register by register — slow. virtio is a standardised paravirtual interface: the guest knows it's virtualised and talks to the host through efficient shared-memory ring buffers.

The virtio device families

Device Replaces Notes
virtio-net e1000 / rtl8139 paravirtual NIC; multi-queue capable
virtio-blk IDE / SATA simple fast block device (/dev/vda)
virtio-scsi LSI SAS SCSI stack: more LUNs, discard/TRIM, passthrough, hotplug
virtio-balloon — host reclaims guest RAM on demand
virtio-rng — feeds host entropy to the guest (avoids entropy starvation)
virtio-gpu Cirrus / QXL paravirtual graphics
virtio-fs / 9p — share a host directory into the guest
virtio-vsock — host↔guest socket channel

For disks, prefer virtio-scsi over virtio-blk on anything non-trivial — it supports TRIM/discard (thin reclaim), more devices, and online resize.

libvirt XML

<disk type='file' device='disk'>
  <driver name='qemu' type='qcow2' discard='unmap' queues='4'/>
  <source file='/var/lib/libvirt/images/vm.qcow2'/>
  <target dev='sda' bus='scsi'/>
</disk>
<controller type='scsi' model='virtio-scsi'/>

<interface type='network'>
  <source network='default'/>
  <model type='virtio'/>
  <driver name='vhost' queues='4'/>
</interface>

<memballoon model='virtio'/>
<rng model='virtio'>
  <backend model='random'>/dev/urandom</backend>
</rng>

<driver name='vhost'> moves the virtio-net datapath into the host kernel (vhost-net) — much faster than QEMU userspace handling it.

Guest drivers

  • Linux: virtio drivers are in the mainline kernel. Any modern distro just works — you'll see /dev/vda or virtio-scsi /dev/sda, and virtio_net. Make sure the initramfs includes them if the root disk is virtio (it is by default on distro cloud images).
  • Windows: not built in. Install the virtio-win driver package (Fedora/RHEL ships an ISO). Attach the ISO, install the NetKVM (network), viostor/vioscsi (storage), balloon, and vioserial drivers. For a fresh Windows install onto a virtio disk, load vioscsi during setup ("Load driver"), or the installer won't see the disk.

Multi-queue

One queue = one CPU handles all I/O for that device. Multi-queue spreads it:

<driver name='vhost' queues='4'/>        <!-- net: match vCPU count, up to 8-ish -->
<driver name='qemu' queues='4'/>          <!-- virtio-scsi/blk -->

In the Linux guest, enable the net queues: ethtool -L eth0 combined 4. Helps high-PPS or high-IOPS workloads; pointless for a mostly-idle VM.

Verification and troubleshooting

# In the guest
lspci | grep -i virtio
lsmod | grep virtio
ethtool -i eth0            # driver: virtio_net
lsblk -d -o NAME,TRAN      # TRAN = virtio
cat /sys/block/vda/queue/rotational   # 0
  • Windows VM: no network / no disk after migrating from another hypervisor — virtio-win drivers not installed. Boot with an e1000 NIC / SATA disk first, install virtio-win, then switch.
  • Windows install "no drives found" — load vioscsi/viostor from the virtio-win ISO during setup.
  • Guest slow disk despite virtio — cache mode (cache='none' + io='native' or io='threads' for best throughput/safety), backing storage is slow, or qcow2 on top of a network filesystem. Also check discard='unmap' for thin volumes.
  • TRIM/fstrim does nothing — virtio-blk without discard support, or missing discard='unmap'. Use virtio-scsi.
  • Entropy starvation in the guest (slow SSH/TLS on boot) — add virtio-rng.
  • Balloon deflating unexpectedly / guest OOM — the host reclaimed too much via the balloon. Set a floor, or disable auto-ballooning and manage memory explicitly.
  • Multi-queue set but only one CPU busy — guest side not enabled (ethtool -L), or the workload is single-threaded / single-flow.
PrabathStuck on something this site can't fix?Reach out to Prabath directly on LinkedIn.