Virtio Devices

src/devices/src/virtio/ — MMIO bus, transport layer, queue mechanics, and device drivers

MMIO bus hierarchy bus.rs:81

Guest vCPU (MMIO exit)
↓ KVM_EXIT_MMIO → MMIODeviceManager.dispatch(gpa) → Bus.get_device(addr) bus.rs:103
MMIO Bus — BTreeMap<(GPA range), Arc<Mutex<dyn BusDevice>>> bus.rs:81
↓ O(log n) range lookup → MmioTransport.read/write() mmio.rs:377
Block
dev 2
Net
dev 1
Vsock
dev 19
GPU
dev 16
Console
dev 3
Entropy
dev 4

MmioTransport — virtio MMIO wrapper mmio.rs:61

MmioTransport mmio.rs:61 ├─ device: Arc<Mutex<dyn VirtioDevice>> // the actual device ├─ queues: Vec<Queue> // RX, TX, event queues queue.rs:324 ├─ interrupt_status: AtomicUsize // virtio interrupt flags ├─ interrupt_evt: EventFd // signals host→guest IRQ ├─ queue_evts: Vec<EventFd> // guest→host queue kicks └─ device_status: u32 // feature negotiation state MMIO register map (4 KiB window per device): read:377 write:441 0x000: MagicValue 0x74726976 ("virt") 0x004: Version 2 0x008: DeviceID (block=2, net=1, vsock=19, …) 0x010: HostFeatures → device.features() 0x020: GuestFeatures← driver writes accepted features 0x030: QueueSel select active queue 0x038: QueueMax → max descriptors 0x044: QueueReady ← driver signals queue is configured 0x050: QueueNotify ← driver kicks queue (triggers EventFd) 0x060: InterruptStatus → interrupt_status 0x064: InterruptAck ← driver clears interrupt 0x070: Status ← driver writes DRIVER_OK etc.

Virtqueue mechanics queue.rs:324

Descriptor Table :197

Guest-allocated array of descriptors (addr, len, flags, next)

Available Ring

Guest writes head descriptor indices here to submit requests

Used Ring add_used:502

Host writes completed descriptor indices + byte count here

① Guest builds chain
② Write avail.idx
③ Kick QUEUE_NOTIFY
④ Host dequeues pop:452
⑤ Host writes used
⑥ Interrupt guest

Descriptors can be chained (NEXT flag) for scatter-gather I/O. WRITE flag marks host-writable descriptors (response buffers). The host uses DescriptorChain / DescIter queue.rs:197 to walk chains and distinguish readable from writable descriptors.


Device catalogue

💽

Block (virtio-blk) block.rs

device ID 2 · feature: blk

Provides a virtual disk backed by a host file or block device. The guest sees it as /dev/vda, vdb, …

  • Request queue: one virtqueue
  • Op codes: IN, OUT, FLUSH, GET_ID
  • Worker thread for async I/O
  • Supports raw and qcow2 images
  • Read-only and writable modes
🌐

Network (virtio-net) net.rs

device ID 1 · feature: net

Ethernet device bridging guest and host networking.

  • RX queue + TX queue (+ ctrl queue optional)
  • Linux: TAP fd backend
  • macOS: gvproxy / unix socket backend
  • TSO/UFO offload negotiation
  • MAC address from config
🔌

Vsock (virtio-vsock) device.rs:38

device ID 19 · always on

Guest↔host socket communication with transparent impersonation (TSI). See the Vsock page for deep-dive.

  • RX :26 + TX + event queue
  • TSI hijacks AF_INET and AF_UNIX
  • Muxer thread handles packet routing muxer.rs:99
  • Flow control via credit packets
🎮

GPU (virtio-gpu)

device ID 16 · feature: gpu

3D-accelerated GPU using the virgl protocol and shared memory for framebuffers.

  • CMD queue + CURSOR queue
  • Virgl renderer on host side
  • SHM manager for resource buffers shm.rs:19
  • Display backends: X11, Wayland, offscreen
  • OpenGL ES pass-through
📟

Console (virtio-console)

device ID 3

Multiplexed serial console with multiple ports. Maps guest stdout/stderr/stdin to host file descriptors.

  • One RX + TX queue pair per port
  • Control queue for port add/remove
  • Port 0: main console (ttyHVC0)
  • Additional ports for logging
🎲

Entropy (virtio-rng)

device ID 4

Seeds the guest kernel's CSPRNG from the host's /dev/urandom. Essential for fast guest boot (avoids entropy starvation).

  • Single request queue
  • Guest requests N bytes of entropy
  • Host reads from /dev/urandom
  • No backend thread needed
flows into → Vsock / TSI