Domain Topology

Life as a Xen hypervisorintermediate · standard · comprehensive | model: claude-opus-4-8 | 2026-06-21
Quick ref
xl list show running domains
xl create cfg boot a domU
xl console N attach guest console
xl info host + hypervisor facts
xl migrate D host live migrate
xenstore-ls dump the config tree
xl top per-domain resource view

Domain Topology

Xen is a thin Type-1 hypervisor that owns CPU, memory, and interrupts; everything else runs in domains. There is no monolithic kernel doing device work — privilege is split across cooperating guests.

xen.gz
The hypervisor itself: scheduler, MMU/p2m, event channels, grant tables, hypercall ABI — no device drivers.
dom0
First, privileged guest; hosts the toolstack (xl/libxl), xenstored, and backend drivers for the real hardware.
domU
Unprivileged guest VM. Its frontend drivers talk to backends in dom0 or a driver domain.
driver domain
A dedicated domU granted PCI devices that serves I/O backends, shrinking dom0's attack surface.
stub domain
Per-HVM-guest mini-domain running its own QEMU device model, isolating emulation from dom0.
Note Disaggregating dom0 into driver and stub domains is the canonical security-hardening move: a compromised backend no longer means a compromised control plane.

Execution Modes: PV / HVM / PVH

ModeCPU virtI/O pathNotes
PVParavirtual, ring deprivilegingPV split drivers onlyNo HW virt needed; modern x86-64 PV largely retired post-Meltdown.
HVMVT-x/AMD-V hardwareEmulated (QEMU) + optional PVBoots unmodified OSes; uses a device model.
PVHHardware virt, no emulationPV split drivers, virtual interruptsLightweight default for Linux/*BSD; no QEMU, fast boot.
Tip Prefer type="pvh" for Linux guests: you get hardware page tables and interrupts without the emulated-platform overhead and attack surface of HVM.

CPU Scheduling

xl sched-credit2
Default scheduler: weight + cap fair-share across pCPUs, scalable to many cores.
xl vcpu-list
Show vCPU-to-pCPU mapping and run state per domain.
xl vcpu-pin D v cpu
Pin a vCPU to physical CPUs for NUMA locality or latency.
xl sched-credit2 -d D -w 512
Set relative CPU weight for a domain.
xl cpupool-list
CPU pools partition pCPUs with independent schedulers for hard isolation.
dom0_max_vcpus= dom0_vcpus_pin
Boot args to dedicate and pin dom0 CPUs away from guest contention.

Memory: Translation & Ballooning

Address translation

Guests see pseudo-physical frames; Xen maps these to machine frames via the p2m table. HVM/PVH use hardware-assisted nested paging (EPT/NPT); legacy PV used direct-but-validated page tables.

Reclamation

The balloon driver inflates inside a guest to hand pages back to Xen, enabling overcommit. Combine with maxmem headroom so a guest can grow later.

xl mem-set D 2048
Balloon a domain's current target to 2 GiB (≤ its maxmem).
xl mem-max D 4096
Raise the static upper bound for the guest.
xl sharing
Report memory deduplicated via page sharing (CoW).
Warning Over-ballooning a guest below its working set causes thrashing or OOM kills; never set a target the guest can't tolerate, and watch dom0's own floor.

Split I/O: Rings, Grants, Events, XenStore

Paravirtual I/O is a frontend/backend pair sharing a ring buffer. The plumbing rests on three primitives that also serve interrupts and inter-domain signalling generally.

grant references
A domain authorizes another to map/copy specific pages — the controlled basis for all shared-memory I/O.
event channels
Lightweight virtual IRQs: notify a peer that a ring has data, deliver virtual interrupts, or signal VIRQs.
xenstore
Hierarchical config/status database used to negotiate device setup (grant refs, evtchn ports) and watch for state changes.
vif / vbd / vfb
Standard frontends: network, block, framebuffer — each pairs with a dom0/driver-domain backend.
xenstore-ls /local/domain/N
Inspect a domain's device tree and negotiated parameters.
xenstore-read path
Read a single key (e.g. backend/frontend connection state).

PCI Passthrough & IOMMU

xl pci-assignable-add 00:1f.2
Detach a device from dom0 and mark it available for guests (via pciback).
pci=['00:1f.2']
Config-file