Proxmox VEI · FoundationsConcepts
Hardware virtualisation, IOMMU, and CPU features
What you'll learn
- Verify Intel VT-x / AMD-V is enabled in firmware and exposed to the kernel
- Explain what IOMMU does and why PCI passthrough requires it
- Read an IOMMU group listing and say what it implies for passthrough
- Choose appropriate CPU models for portable vs performant VMs
- Know what "virtualisation extensions disabled" looks like at boot time
Prerequisites
Verified against Proxmox VE 9.2.4 · Proxmox Backup Server 4.2.5 · Ceph Squid / Tentacle · Debian 13 (Trixie) · Linux kernel 7.0 (PVE 9.2 default) · 2026-08-12
Why this matters in production
A surprising fraction of “Proxmox won’t install” and “PCI passthrough doesn’t work” tickets trace back to firmware settings that were never enabled. This lesson shows how to verify the features Proxmox depends on, and what the symptoms of their absence look like.
Mental model
Proxmox needs three classes of hardware feature:
- CPU virtualisation extensions — Intel VT-x (also called
vmx) or AMD-V (svm). Without these, KVM cannot run a guest at full speed; QEMU falls back to TCG (pure emulation) and is dramatically slower. - IOMMU — Intel VT-d (
intel-iommu) or AMD-Vi (amd-iommu). Without this, the host cannot safely give a guest direct access to a PCI device (GPU, NVMe controller, NIC). - Optional but recommended — SR-IOV (for NIC virtual functions), APICv, Posted Interrupts. These affect throughput and latency for high-performance networking and passthrough.
How to verify in the kernel
The firmware menu records what you asked for. The kernel records what you got, and they disagree often enough that only the second is worth trusting.
grep -c -E 'vmx|svm' /proc/cpuinfo
ls -l /dev/kvm
dmesg | grep -iE 'DMAR|IOMMU|AMD-Vi' | head
cat /proc/cmdline# dmesg | grep -iE 'DMAR|IOMMU'[ 0.008431] ACPI: DMAR 0x000000006C7E4000 0000A8 (v01 INTEL EDK2 )
[ 0.291204] DMAR: IOMMU enabled
[ 0.412887] DMAR: Host address width 46
[ 0.412889] DMAR: DRHD base: 0x000000fbffc000 flags: 0x0
[ 0.412901] DMAR: dmar0: reg_base_addr fbffc000 ver 1:0 cap 8d2078c106f0466
[ 1.884012] DMAR: Intel(R) Virtualization Technology for Directed I/OIllustrative output
If /dev/kvm is missing, the most common causes are:
- Hardware virtualisation disabled in firmware.
- Kernel booted with
kvm.enable_virt_at_load=0(uncommon). - The kernel does not have the KVM module loaded (
modprobe kvm). - Running inside a guest without nested virtualisation enabled.
IOMMU groups: the check that actually predicts passthrough
Enabling VT-d is necessary and not sufficient. What decides whether you can pass a particular device to a guest is which IOMMU group it lands in — and that is determined by the motherboard’s PCIe topology, not by any setting.
ls /sys/kernel/iommu_groups/ | wc -l
for G in /sys/kernel/iommu_groups/*/devices/*; do
N=${G#*/iommu_groups/}; N=${N%%/*}
printf 'group %s: ' "$N"
lspci -nns "${G##*/}"
done | sort -V# (the loop above)group 13: 00:1f.3 Audio device [0403]: Intel Corporation HD Audio [8086:a348]
group 14: 01:00.0 VGA compatible controller [0300]: NVIDIA Corporation [10de:2484]
group 14: 01:00.1 Audio device [0403]: NVIDIA Corporation [10de:228b]
group 14: 02:00.0 Ethernet controller [0200]: Realtek RTL8125 [10ec:8125]
group 15: 03:00.0 Non-Volatile memory controller [0108]: Samsung [144d:a80a]Illustrative output
Firmware checklist
Every server-class motherboard Proxmox runs on should have these settings:
| Setting | Where | Required for |
|---|---|---|
| Intel VT-x / AMD-V | CPU configuration | All KVM VMs |
| Intel VT-d / AMD-Vi | Chipset / Northbridge | PCI/GPU passthrough |
| SR-IOV | PCIe configuration | NIC virtual functions |
| Above 4G Decoding | PCIe configuration | Large-memory GPUs |
| ACS | PCIe configuration | Finer-grained IOMMU groups |
The exact wording varies between vendors (Dell iDRAC, HPE iLO, Supermicro IPMI, Lenovo
XClarity). Searching the firmware manual for “virtualisation” or “IOMMU” usually surfaces the
right option. ii-planning-firmware-bios treats these as pre-install decisions, which is
where they belong.
Kernel command line
For PCI passthrough, the kernel command line on each Proxmox node should include:
intel_iommu=on iommu=pt
or for AMD:
amd_iommu=on iommu=pt
iommu=pt enables pass-through mode, in which the IOMMU only translates for devices
assigned to guests and leaves host-owned devices on a direct mapping — lower overhead than
translating everything.
Where you put that line depends on the bootloader, and Proxmox nodes differ. Editing the wrong file produces a change that looks applied and is not, which is why the first step is always to ask the node.
proxmox-boot-tool status
[ -d /sys/firmware/efi ] && echo "UEFI" || echo "legacy BIOS"
cat /proc/cmdline# GRUB installs: edit GRUB_CMDLINE_LINUX_DEFAULT in /etc/default/grub, then
update-grub
# systemd-boot installs: append to the single line in /etc/kernel/cmdline, then
proxmox-boot-tool refresh
# after the reboot, on either:
cat /proc/cmdline
dmesg | grep -iE 'DMAR|AMD-Vi' | head -3CPU models for VMs
| Model | What it exposes | When to use |
|---|---|---|
host | All host CPU features verbatim | Maximum performance; migration only between identical hosts |
x86-64-v2-AES | Westmere-era baseline plus AES | The UI default for new VMs. Good portability and performance |
x86-64-v2 / v3 / v4 | Specified x86-64 micro-architecture levels | Raise the level when the workload benefits and the fleet supports it |
kvm64 | The x86-64-v1 baseline | Maximum compatibility, lowest performance. Legacy |
| Named Intel/AMD models | Specific CPU vendor lines | Rarely needed |
The documentation is explicit about the cost of host: “If you want to do a live migration
of VMs between different hosts, your VM might end up on a new system with a different CPU
type or a different microcode version. If the CPU flags passed to the guest are missing, the
QEMU process will stop.”
That is a stop, not a degradation. It is the reason host belongs only on guests that will
never migrate, or on clusters whose nodes are genuinely identical — including their
microcode revision, which a firmware update can change on one node and not another.
pvesh get /nodes/localhost/capabilities/qemu/cpu --output-format json | jq -r '.[].name'
cat /etc/pve/virtual-guest/cpu-models.conf 2>/dev/null || echo "no custom CPU models defined"
for VMID in $(qm list | awk 'NR>1 {print $1}'); do
printf '%s ' "$VMID"; qm config "$VMID" | grep -E '^cpu:' || echo "cpu: (default)"
doneProduction considerations
Common mistakes
- Verifying from the firmware menu rather than the kernel. The menu is a request;
/proc/cpuinfo,/dev/kvmanddmesgare the result. - Checking
intel_iommu=onis set and stopping there. An empty/sys/kernel/iommu_groupsmeans it did not take, and a group containing several devices means passthrough is blocked for a different reason entirely. - Editing
/etc/default/grubon a systemd-boot node. Nothing reads it.proxmox-boot-tool statussays which applies. - Using
cpu: hoston a heterogeneous cluster. Migration to a node with fewer features stops the QEMU process rather than degrading it. - Assuming identical hardware means identical CPU features. A rolling microcode update makes a uniform cluster temporarily mixed.
- Buying consumer motherboards for passthrough. Many lack VT-d, and many that have it lack ACS, which puts unrelated devices in one IOMMU group.
- Forgetting “Above 4G Decoding”, which causes large GPUs to fall back to legacy addressing and lose performance.
- Looking for custom CPU models in
/etc/pve/cpu-models.conf. The path is/etc/pve/virtual-guest/cpu-models.conf, and it does not exist unless you created it.
Key takeaways
- Proxmox needs VT-x/AMD-V (always) and VT-d/AMD-Vi (for passthrough).
- Verify from the kernel:
/proc/cpuinfoflags,/dev/kvm,dmesg | grep -iE 'DMAR|AMD-Vi', and/proc/cmdline. - A non-empty
/sys/kernel/iommu_groupsis the real test that IOMMU is active. - The IOMMU group is the unit of isolation. Everything in a group goes to the same guest, and the grouping comes from PCIe topology and ACS support, not from configuration.
- The kernel command line lives in
/etc/default/grubplusupdate-grub, or/etc/kernel/cmdlineplusproxmox-boot-tool refresh. Askproxmox-boot-tool statuswhich. x86-64-v2-AESis the UI default for new VMs.hostgives maximum performance and stops the QEMU process on migration to a node with fewer features.- Custom CPU models live in
/etc/pve/virtual-guest/cpu-models.confand are referenced ascustom-<name>. - Keep the CPU model uniform across a cluster so migration either always works or never does.
Knowledge check
Knowledge check · 5 questions
Q1. Which kernel parameter enables Intel IOMMU?
Q2. PCI passthrough needs VT-d or AMD-Vi enabled in firmware and in the kernel, whatever CPU model the VM is given.
Q3. IOMMU is confirmed active, but assigning a GPU to a VM also requires assigning an onboard NIC. Why?
Q4. Which statements about the cpu: host setting are correct? Select all that apply.
Q5. Which command tells you whether a Proxmox node boots via GRUB or systemd-boot, and therefore where kernel parameters go?
Passing score: 75%. Answers are checked in this browser.