Virtio is an open standard for paravirtualized devices that defines how a virtual machine and its hypervisor exchange data through shared-memory queues instead of imitating real hardware register by register. In Linux virtualization it is the default device model for KVM and QEMU guests, providing virtual network cards, disks, consoles, random number sources and file sharing with far less overhead than emulated legacy devices.
The guest knows it is virtualized and runs a virtio driver; the host runs a matching virtio device backend. Because both sides follow the same specification, maintained by the OASIS VIRTIO technical committee, a single Linux guest driver works on any hypervisor that implements the standard.
How virtio moves data through virtqueues
The central structure in virtio is the virtqueue, a ring of buffer descriptors placed in guest memory that both the guest driver and the host backend can read. The guest posts buffers, the host consumes or fills them, and each side signals the other only when necessary. This design replaces thousands of trapped register accesses with a few memory writes and occasional notifications.
A classic split virtqueue has three parts: a descriptor table that points to guest buffers, an available ring where the driver offers descriptors, and a used ring where the device returns completed ones. Version 1.1 of the specification added the packed virtqueue, which merges these into one ring to improve cache behavior. Notifications travel as a doorbell write (kick) from guest to host and as an interrupt, usually MSI-X, from host to guest.
| Component | Role | Detail |
|---|---|---|
| Feature bits | Negotiate capabilities at startup | Driver accepts a subset the device offers |
| Virtqueue | Carries requests and responses | Split or packed layout |
| Configuration space | Holds device parameters | For example MAC address or disk size |
| Notification | Signals new work | Kick to host, interrupt to guest |
| Transport | Attaches device to the guest | PCI, MMIO or channel I/O |
Feature negotiation keeps old and new components compatible. The device advertises bits such as multiqueue support or event index suppression, the driver acknowledges those it understands, and both then use only the agreed features. The bit VIRTIO_F_VERSION_1 distinguishes modern devices from legacy, pre-1.0 ones.
Virtio device types and transports
Virtio is a family of device types sharing one queue mechanism. Each type has a numeric ID and its own request format, and Linux ships drivers for all common ones in the mainline kernel. The table lists the devices administrators meet most often.
| Device | Function | Guest device name |
|---|---|---|
| virtio-net | Network interface with multiqueue support | eth0 or ens3 style names |
| virtio-blk | Simple, fast block device | /dev/vda, /dev/vdb |
| virtio-scsi | SCSI controller for many disks | /dev/sda, /dev/sdb |
| virtio-balloon | Returns unused guest memory to host | No device node |
| virtio-rng | Entropy from host to guest | /dev/hwrng |
| virtio-fs | Shares a host directory with the guest | Mounted as virtiofs |
| virtio-vsock | Host and guest sockets without networking | AF_VSOCK sockets |
The transport decides how the guest discovers the device. On x86 servers virtio devices appear as PCI devices with the vendor ID 1af4; small ARM and embedded virtual machines often use the simpler MMIO transport; IBM Z uses channel I/O. The queue logic stays identical across transports.
Virtio backends: QEMU, vhost and vDPA
The host side of a virtio device can run in several places, and the choice has a large effect on throughput and latency. In the basic arrangement QEMU processes the virtqueue in user space, which is flexible but requires a context switch for each batch of work. vhost moves the data path into a kernel thread or a separate process, while QEMU keeps only the control path.
| Backend | Data path location | Typical use |
|---|---|---|
| QEMU device model | QEMU user-space process | Defaults, less common devices |
| vhost-net | Host kernel thread | Standard fast networking for KVM |
| vhost-user | Separate user-space process | DPDK switches, SPDK storage |
| vDPA | Hardware that speaks virtio rings | SmartNICs with near line-rate I/O |
With vDPA (virtio data path acceleration), a network card processes virtio rings directly, so the guest keeps its standard virtio driver while gaining hardware speed. This preserves live migration compatibility, which direct device passthrough usually breaks.
Virtio compared with emulation and passthrough
A virtual machine can receive a device in three basic ways, and virtio occupies the practical middle ground between full emulation and direct hardware assignment. KVM, QEMU and libvirt all support each method, and the right one depends on the guest operating system, the required speed and the need to migrate.
| Approach | Example | Performance | Trade-off |
|---|---|---|---|
| Full emulation | e1000 NIC, IDE disk | Low | Works without special drivers |
| Paravirtualization | virtio-net, virtio-blk | High | Needs a virtio driver in the guest |
| Passthrough | VFIO, SR-IOV virtual function | Near native | Ties the VM to specific hardware |
Linux guests include virtio drivers out of the box, so virtio is the obvious choice for them. Windows guests need separately installed drivers, usually from the virtio-win package; installers often attach a temporary emulated disk or load the storage driver during setup so the system disk is visible.
Practical choices and common mistakes
- Choose virtio-blk for simple, high-speed disks and virtio-scsi when a guest needs many disks, SCSI commands such as UNMAP, or hot-plugging at scale.
- Enable multiqueue virtio-net with one queue pair per vCPU for busy network guests, otherwise one queue becomes the bottleneck.
- Keep vhost-net enabled; a missing
vhost_netmodule silently falls back to slower user-space processing. - Prefer virtio-fs over network file sharing for host directories in development VMs, because it avoids the network stack entirely.
- Remember that a memory balloon can starve a guest if the host reclaims too aggressively.
A frequent troubleshooting error is assuming that a slow virtual machine has a weak host, when the guest is actually using an emulated e1000 card or IDE disk. Checking lspci inside the guest for devices named “Virtio” quickly confirms which model is active.
In plain words
A virtual machine is a computer running inside another computer. Old-style virtualization makes the inner computer believe it has real network cards and disks, so the host must pretend to be hardware, step by tedious step. That pretending is slow.
Virtio drops the pretense. The guest knows it lives inside a host, and the two pass data through a shared mailbox in memory. It is like replacing a translator who repeats every word with two colleagues who simply hand each other folders. The result is faster, simpler virtual devices.
A real-world example
A hosting team migrates forty Linux servers from older virtual machines that used emulated e1000 network cards and IDE disks to KVM guests managed with libvirt. Each new guest gets virtio-net with four queue pairs, backed by vhost-net, and virtio-blk disks on local NVMe storage.
After the move, the same web workloads use noticeably less host CPU time per request, and disk-heavy nightly backups finish well inside their window. Three legacy Windows guests receive the virtio-win drivers before switching their disks, and every guest can still be live-migrated between hosts because no hardware is passed through directly.