Understanding Virtio: Architecture, Drivers, and Implementation in Linux Virtualization
Virtio, the Linux standard I/O virtualization framework, uses a semi‑virtualized front‑end driver and back‑end device linked by virtqueues, works across hypervisors (e.g., QEMU/KVM) via PCI or MMIO, enabling high‑performance, low‑overhead device emulation—as illustrated by the virtio‑snd driver—while supporting cloud and Android virtualization scenarios.
Virtio, originally created by Rusty Russell for the lguest virtualization solution, has become the standard I/O virtualization framework in Linux. This article introduces the background of virtualization, basic terminology, and the role of virtio as a semi‑virtualized device model.
Virtualization underpins cloud computing by abstracting physical hardware (CPU, memory, storage) into multiple independent virtual machines, improving resource utilization, deployment scalability, portability, flexibility, and security. It is now a standard practice in enterprise IT architectures.
Google’s Cuttlefish provides OS‑level virtualization for Android devices, enabling cloud‑based deployment of Android. This brings several engineering benefits:
1. Developers no longer depend on physical hardware for code development and verification. 2. High‑fidelity replication of real‑device behavior by staying closely aligned with the core framework. 3. Consistent API‑level functionality matching physical hardware. 4. Scalable parallel execution of multiple devices for concurrent testing with low entry cost. 5. Configurable devices (shape, RAM, CPU, I/O) to facilitate automated testing and tuning.
Hypervisors (VMMs) are classified into two types: Type 1 runs directly on physical hardware to host multiple guest OSes, while Type 2 runs as an application on a host OS, requiring explicit creation of virtual machines (e.g., Cuttlefish’s crosvm).
Virtualization can be implemented as full virtualization, where the guest OS is unaware of the virtual environment, or para‑virtualization, where the guest OS knows it runs on a hypervisor and includes optimized code for interaction.
The virtio architecture follows a semi‑virtualized model: a generic front‑end driver in the guest OS communicates with a back‑end device implemented by the hypervisor via a virtqueue. This separation of control and data planes enables flexibility and high‑performance data forwarding.
In QEMU/KVM (a Type 2 hypervisor), virtio provides device virtualization. The guest loads a virtio front‑end driver, while QEMU implements the back‑end device. Communication occurs through virtqueues.
The Virtio specification (v1.3) defines device states, features, notifications, reset, configuration space, shared memory, and other standard interfaces, ensuring that drivers built to the spec work across different hypervisors and operating systems.
Example analysis of a virtual sound‑card driver (virtio‑snd) in Android kernel 6.6:
• Registration uses module_virtio_driver , a macro that expands to register_virtio_driver and unregister_virtio_driver . • The driver’s probe function receives a virtio_device pointer (vdev) and allocates a virtio_snd structure, assigning snd->dev = vdev . • Spin locks are initialized for each virtqueue, and virtio_find_vqs obtains the virtqueues used for communication. • The virtqueue is defined by the virtio framework; it may have an optional callback invoked when the hypervisor supplies buffers.
The driver then calls virtio_device_ready to enable the virtqueues via the set_status operation, builds the sound devices, registers the sound card with snd_card_register , and presents a standard audio interface to user space.
Virtio’s virtual bus registers like any other Linux bus via bus_register . Its match function ( virtio_dev_match ) compares device IDs from the driver’s ID table with devices on the bus, invoking the bus’s probe and subsequently the driver’s probe for initialization.
From a PCI perspective, virtio devices appear as standard PCI devices (vendor ID 0x1AF4, device IDs 0x1000‑0x107F). The hypervisor creates a PCI device, the guest discovers it, matches it against virtio_pci_id_table , and the virtio_pci_driver registers the virtio_device with the virtio bus.
In summary, virtio implements the Virtio specification by exposing devices through mature transport mechanisms (PCI, MMIO, etc.), using a virtual bus to manage drivers and devices, and providing a simple, generic, and extensible solution that minimizes the need for new protocols or concepts while delivering high performance and low guest‑OS modification.
OPPO Kernel Craftsman
Sharing Linux kernel-related cutting-edge technology, technical articles, technical news, and curated tutorials
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.