Checklist Proxmox PCI Passthrough : 12 vérifications avant d’accuser VFIO

Cet article vous a aidé ?

Les échecs de passthrough PCI ne se présentent que rarement de manière élégante. Ils se manifestent par une VM qui démarre sur un écran noir, une carte réseau qui disparaît sous charge, ou un hôte qui gèle net pendant une démo. Ensuite, tout le monde pointe du doigt VFIO comme si c’était le méchant d’un dessin animé du samedi matin.

La plupart du temps, VFIO fait simplement son travail : refuser d’exécuter quelque chose d’insecure ou d’impossible. Votre véritable ennemi est généralement l’un des douze prérequis ennuyeux — réglages du firmware, groupement IOMMU, comportement des resets, routage des interruptions, ou ce paramètre kernel « temporaire » que vous avez oublié d’enlever il y a trois mois.

Mode opératoire de diagnostic rapide

Si vous êtes en astreinte, vous ne commencez pas par de la philosophie. Vous commencez par une boucle de triage qui répond à trois questions : (1) l’IOMMU s’est-il réellement activé, (2) le périphérique est-il isolé, et (3) peut-il être réinitialisé proprement entre les démarrages de VM ?

Première étape : confirmer que la plateforme est capable et que l’IOMMU est activé

  • Bascules BIOS/UEFI : Intel VT-d ou AMD-Vi, et idéalement « Above 4G decoding » pour les GPU modernes et les HBA.
  • Le kernel voit l’IOMMU : vérifiez dmesg pour des lignes DMAR/AMD-Vi.

Deuxième étape : confirmer que le groupement IOMMU est sensé

  • Listez les groupes IOMMU et assurez-vous que le périphérique n’est pas collé à votre contrôleur SATA, contrôleur USB ou port racine du chipset que vous ne pouvez pas sacrifier.
  • Si vous comptez sur ACS override, considérez-le comme un dernier recours et un compromis de sécurité, pas comme un « correctif ».

Troisième étape : confirmer le binding VFIO et le comportement de reset

  • Assurez-vous que le périphérique est lié à vfio-pci sur l’hôte et non à un pilote constructeur.
  • Vérifiez le support FLR et les quirks de reset (particulièrement pour les GPU).

Puis : vérifiez le côté VM (type de machine, UEFI/OVMF, quirks ROM)

  • Choisissez un type de machine QEMU stable, et ne mélangez pas les habitudes SeaBIOS avec des périphériques de l’ère OVMF.
  • Si c’est un GPU, décidez rapidement si vous avez besoin d’un VBIOS dumpé et si vous devez passer la fonction audio aussi.

Cet ordre paraît évident jusqu’à ce que vous ayez vu quelqu’un passer deux heures à bricoler des arguments QEMU alors que le BIOS avait VT-d désactivé. Ce qui m’amène à la seule loi du passthrough : il punit les hypothèses avec intérêts.

Faits et contexte rapides (pour arrêter de deviner)

  • Fait 1 : Le nom marketing d’Intel pour l’IOMMU est VT-d ; celui d’AMD est AMD-Vi. Ils résolvent la même classe de problèmes : isolation et remappage DMA.
  • Fait 2 : VFIO n’a pas toujours été l’approche par défaut. L’ancienne méthode pci-stub existait, mais VFIO a apporté un cadre plus propre et plus sûr pour l’assignation de périphériques sous Linux.
  • Fait 3 : Les groupes IOMMU ne sont pas « une chose Linux ». Ce sont une réalité matérielle/topologique exposée par l’ACPI et les capacités PCIe. Linux n’est que le messager.
  • Fait 4 : ACS (Access Control Services) est une fonctionnalité PCIe qui peut améliorer l’isolation. Beaucoup de cartes grand public l’implémentent partiellement ou de manière créative — souvent la forme de « créatif » que vous ne voulez pas en production.
  • Fait 5 : « Above 4G decoding » compte parce que les BAR larges (Base Address Registers) des GPU et des périphériques modernes ne tiennent pas proprement dans l’espace d’adressage 32 bits hérité.
  • Fait 6 : Les problèmes de reset GPU ne sont pas du folklore. Certains GPU ne se réinitialisent pas complètement sans Function Level Reset (FLR) ou sans comportement spécifique du constructeur, et l’hôte peut ne pas être capable de les réinitialiser après l’arrêt d’une VM.
  • Fait 7 : SR-IOV n’est pas venu pour vous faciliter la vie. Il existe pour diviser une fonction PCIe physique en fonctions virtuelles, mais il multiplie les façons de mal configurer firmware, pilotes et isolation.
  • Fait 8 : MSI/MSI-X ont été une amélioration majeure pour les performances et la stabilité par rapport aux interruptions ligne-legacy — et une source de douleur quand le remappage des interruptions n’est pas activé correctement.
  • Fait 9 : Proxmox est « juste Debian avec des opinions », ce qui est une bonne nouvelle : la plupart du débogage est du débogage Linux standard une fois que vous arrêtez de traiter l’interface graphique comme de la magie.

Une citation que je garde sur mon tableau de bord mental : paraphrased idea — W. Edwards Deming, sur l’amélioration des systèmes en améliorant le processus, pas en criant sur les résultats. En matière de passthrough, votre « processus » est la boucle de vérification ci-dessous.

Checklist / plan étape par étape (12+ vérifications avec commandes)

C’est la partie où vous arrêtez de « tester des trucs » et commencez à collecter des preuves. Chaque tâche inclut : une commande, ce que la sortie signifie, et la décision que vous prenez.

1) Identifiez les périphériques et fonctions PCI exacts que vous voulez passer

cr0x@server:~$ lspci -nn
00:00.0 Host bridge [0600]: Intel Corporation Device [8086:3e0f]
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation TU104 [GeForce RTX 2080] [10de:1e87]
01:00.1 Audio device [0403]: NVIDIA Corporation TU104 HD Audio Controller [10de:10f8]
03:00.0 Ethernet controller [0200]: Intel Corporation I350 Gigabit Network Connection [8086:1521]

Ce que cela signifie : Vous avez besoin du BDF (bus:device.function) et des IDs vendor:device. Les GPU ont souvent plusieurs fonctions (VGA + audio). Les NIC peuvent avoir plusieurs ports/fonctions aussi.

Décision : Notez l’ensemble complet des fonctions que vous devez passer ensemble. Si vous passez 01:00.0 mais oubliez 01:00.1, vous aurez des comportements bizarres plus tard et accuserez QEMU pour votre gestion des identifiants.

2) Vérifiez les flags de virtualisation CPU (ne zappez pas ça parce que « c’est un serveur »)

cr0x@server:~$ lscpu | egrep -i 'Virtualization|Flags'
Virtualization:                  VT-x
Flags:                           fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid

Ce que cela signifie : VT-x/AMD-V sert à exécuter des VM ; ce n’est pas VT-d/AMD-Vi. Néanmoins, si cela manque, vous déboguez le mauvais ensemble de fonctionnalités.

Décision : Si la virtualisation manque, arrêtez. Corrigez le BIOS/UEFI d’abord. Si c’est une machine louée, confirmez que vous n’êtes pas sur une SKU hostile à la virtualisation.

3) Confirmez que l’IOMMU est activé dans le firmware et réellement actif dans Linux

cr0x@server:~$ dmesg | egrep -i 'DMAR|IOMMU|AMD-Vi' | head -n 30
[    0.000000] DMAR: IOMMU enabled
[    0.000000] DMAR: Host address width 39
[    0.084123] DMAR: DRHD base: 0x000000fed90000 flags: 0x0
[    0.084129] DMAR: dmar0: reg_base_addr fed90000 ver 1:0 cap c90780106f0462 ecap f020de
[    0.251990] DMAR: Intel(R) Virtualization Technology for Directed I/O

Ce que cela signifie : Vous voulez voir « IOMMU enabled » et de préférence tôt dans le boot. Si vous voyez des erreurs sur le remappage des interruptions ou « no IOMMU found », pas de passthrough aujourd’hui.

Décision : Si l’IOMMU n’est pas activé, vérifiez les réglages du BIOS (VT-d/AMD-Vi) et les paramètres de la ligne de commande du kernel ensuite.

4) Vérifiez que les paramètres de la ligne de commande du kernel sont corrects (et ne se sabordent pas)

cr0x@server:~$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-6.8.12-5-pve root=ZFS=rpool/ROOT/pve-1 ro quiet intel_iommu=on iommu=pt pcie_acs_override=downstream,multifunction

Ce que cela signifie : intel_iommu=on (ou amd_iommu=on) active l’IOMMU. iommu=pt utilise le mode passthrough pour les périphériques de l’hôte pour la performance ; c’est courant et généralement acceptable.

Décision : Si vous voyez intel_iommu=off ou aucune option IOMMU et que dmesg est muet, corrigez la configuration GRUB/systemd-boot et redémarrez. Si vous voyez pcie_acs_override, considérez-le comme « nous contournons les règles ».

5) Confirmez que le remappage des interruptions est activé (la stabilité sous charge se joue ici)

cr0x@server:~$ dmesg | egrep -i 'remapping|x2apic|irq' | head -n 50
[    0.000000] DMAR-IR: Enabled IRQ remapping in x2apic mode
[    0.000000] x2apic enabled

Ce que cela signifie : Le remappage IRQ est une fonctionnalité de sécurité et de correction. Sans lui, certains périphériques et interruptions MSI peuvent se comporter comme une maison hantée sous charge.

Décision : Si le remappage IRQ n’est pas activé, revérifiez le BIOS pour « Interrupt Remapping » ou des fonctionnalités de virtualisation similaires. Sur certaines plateformes, un BIOS obsolète est la cause.

6) Inspectez les groupes IOMMU (cela décide ce que vous pouvez passer en sécurité)

cr0x@server:~$ for d in /sys/kernel/iommu_groups/*/devices/*; do echo "IOMMU Group ${d#*/iommu_groups/*}: $(lspci -nns ${d##*/})"; done | sort -V | sed -n '1,30p'
IOMMU Group 0: 00:00.0 Host bridge [0600]: Intel Corporation Device [8086:3e0f]
IOMMU Group 1: 00:01.0 PCI bridge [0604]: Intel Corporation Device [8086:1901]
IOMMU Group 12: 01:00.0 VGA compatible controller [0300]: NVIDIA Corporation TU104 [GeForce RTX 2080] [10de:1e87]
IOMMU Group 12: 01:00.1 Audio device [0403]: NVIDIA Corporation TU104 HD Audio Controller [10de:10f8]
IOMMU Group 13: 03:00.0 Ethernet controller [0200]: Intel Corporation I350 Gigabit Network Connection [8086:1521]

Ce que cela signifie : Les périphériques du même groupe peuvent DMA entre eux sauf si la plateforme offre une isolation adéquate. Si votre GPU partage un groupe avec un contrôleur USB dont l’hôte a besoin, vous êtes coincé ou sur le point de faire quelque chose de risqué.

Décision : Si le groupement est propre, poursuivez. Si le groupement est désordonné, envisagez de déplacer le périphérique vers un autre slot, modifier les réglages de bifurcation, mettre à jour le BIOS, ou — seulement si vous acceptez le compromis — utiliser ACS override.

7) Vérifiez que le périphérique supporte le reset (FLR) ou notez qu’il ne le fait pas

cr0x@server:~$ lspci -s 01:00.0 -vv | egrep -i 'Capabilities:.*Express|FLR|Reset' -n
12:Capabilities: [60] Express (v2) Endpoint, MSI 00
55:    DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis- FLR+

Ce que cela signifie : FLR+ suggère le support de Function Level Reset. Ce n’est pas une garantie de bonheur, mais c’est un bon signe. Certains périphériques (surtout des GPU plus anciens) passent une fois et se bloquent jusqu’au reboot de l’hôte.

Décision : S’il n’y a pas de FLR et que vous voyez des problèmes récurrents « device is in use » ou « failed to reset », planifiez opérationnellement : reboot d’hôte entre les assignations, ou choisissez un autre matériel.

Blague n°1 : Le passthrough PCI, c’est comme sortir avec une imprimante — tout semble bien jusqu’à ce que vous ayez réellement besoin que ça fonctionne.

8) Assurez-vous que l’hôte lie le périphérique à vfio-pci (et non à nouveau/nvidia/amdgpu)

cr0x@server:~$ lspci -k -s 01:00.0
01:00.0 VGA compatible controller: NVIDIA Corporation TU104 [GeForce RTX 2080]
Subsystem: Micro-Star International Co., Ltd. [MSI] TU104 [GeForce RTX 2080]
Kernel driver in use: vfio-pci
Kernel modules: nvidiafb, nouveau

Ce que cela signifie : « Kernel driver in use » doit être vfio-pci. « Kernel modules » peut lister des modules possibles ; c’est acceptable.

Décision : Si un pilote constructeur est en cours d’utilisation, corrigez le binding : ajoutez les IDs de périphérique à vfio-pci, blacklistez les pilotes conflictuels, régénérez initramfs, redémarrez, et revérifiez.

9) Confirmez que les modules vfio sont chargés et présents dans l’initramfs

cr0x@server:~$ lsmod | egrep 'vfio|kvm'
vfio_pci               16384  0
vfio_pci_core          73728  1 vfio_pci
vfio_iommu_type1       45056  0
vfio                   45056  2 vfio_pci_core,vfio_iommu_type1
kvm_intel             401408  0
kvm                  1343488  1 kvm_intel

Ce que cela signifie : Si les modules core VFIO ne sont pas chargés, vous n’êtes pas prêt. S’ils ne se chargent qu’après que le pilote hôte a saisi le périphérique, vous pouvez toujours perdre la course.

Décision : Si l’ordre de chargement des modules est incorrect, ajoutez les modules à /etc/modules, assurez les bons IDs vfio-pci, et régénérez l’initramfs pour que vfio se lie tôt.

10) Vérifiez que Proxmox/QEMU utilise réellement l’IOMMU dans la configuration de la VM

cr0x@server:~$ qm config 101 | egrep -i 'hostpci|machine|bios|efidisk|args'
bios: ovmf
machine: q35
hostpci0: 01:00,pcie=1,x-vga=1
hostpci1: 01:00.1,pcie=1
efidisk0: local-lvm:vm-101-disk-0,efitype=4m,pre-enrolled-keys=1
args: -cpu host

Ce que cela signifie : Pour les GPU et beaucoup de périphériques PCIe, q35 + pcie=1 est le défaut sensé. Passer à la fois le GPU et sa fonction audio évite les périphériques à moitié attachés. OVMF est typique pour Windows moderne et les guests Linux UEFI.

Décision : Si vous voyez des types de machine legacy et des flags étranges copiés d’un vieil article de forum, simplifiez. Passez à q35 + OVMF sauf raison spécifique contraire.

11) Vérifiez la contention des ressources hôtes : latence I/O et CPU steal peuvent ressembler à de la « flakiness » de passthrough

cr0x@server:~$ pveperf
CPU BOGOMIPS:      71999.84
REGEX/SECOND:      6068330
HD SIZE:           76.80 GB (rpool/ROOT/pve-1)
FSYNCS/SECOND:     1098.55
DNS EXT:           55.76 ms

Ce que cela signifie : FSYNCS/SECOND est un test olfactif grossier mais utile pour la latence de stockage. Si c’est terrible, votre « stutter GPU passthrough » peut être le guest qui bloque sur le disque.

Décision : Si le stockage est lent, arrêtez d’optimiser VFIO et commencez par optimiser le stockage : vérifiez les réglages ZFS sync, la santé du SLOG, le firmware du contrôleur et la profondeur de file d’attente. Ou déplacez les disques VM hors du pool en difficulté.

12) Vérifiez la pression sur les hugepages / mappage IOMMU et la disponibilité mémoire

cr0x@server:~$ grep -E 'HugePages|AnonHugePages|MemAvailable' /proc/meminfo | head
MemAvailable:   58723452 kB
AnonHugePages:  10240000 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0

Ce que cela signifie : Si vous avez épinglé des hugepages ou affamé l’hôte, l’assignation de périphérique peut échouer de manière apparemment non liée. Certaines configurations utilisent volontairement des hugepages ; c’est acceptable, mais vous devez savoir que vous l’avez fait.

Décision : Si la mémoire est tendue, réduisez la mémoire des VM, arrêtez le sur-engagement, ou ajoutez de la RAM. Si vous avez besoin de hugepages, configurez-les intentionnellement et documentez cela comme un adulte.

13) Vérifiez l’utilisation d’ACS override et comprenez le rayon d’impact

cr0x@server:~$ grep -R "pcie_acs_override" -n /etc/default/grub /etc/kernel/cmdline 2>/dev/null
/etc/default/grub:6:GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on iommu=pt pcie_acs_override=downstream,multifunction"

Ce que cela signifie : ACS override peut séparer artificiellement les groupes. Il peut rendre du matériel grand public utilisable pour des homelabs qui autrement n’isoleront pas correctement les périphériques.

Décision : Si c’est un homelab, vous pouvez l’accepter. Si c’est de la production avec multi-tenant hostile ou conformité stricte, évitez-le. Un meilleur matériel coûte moins cher que d’expliquer un incident d’isolation DMA.

14) Validez les besoins de VBIOS GPU (particulièrement quand le GPU est principal)

cr0x@server:~$ dmesg | egrep -i 'vfio|rom|bar|vga' | tail -n 30
[   12.912345] vfio-pci 0000:01:00.0: enabling device (0000 -> 0003)
[   12.934567] vfio-pci 0000:01:00.0: BAR 0: assigned [mem 0xf6000000-0xf6ffffff 64bit]
[   12.945678] vfio-pci 0000:01:00.0: BAR 2: assigned [mem 0xd0000000-0xdfffffff 64bit pref]
[   13.012345] vfio-pci 0000:01:00.0: vfio_ecap_init: hiding ecap 0x19@0x900

Ce que cela signifie : L’assignation des BAR est normale. Si vous manquez de sortie dans le guest, le GPU peut nécessiter un fichier ROM, surtout s’il a été utilisé comme affichage primaire de l’hôte (le firmware peut ne pas exposer une option ROM propre).

Décision : Si le guest n’initialise jamais le GPU et que tout le reste est confirmé, essayez de fournir un ROM VBIOS propre et assurez-vous de ne pas vous battre contre un pilote console hôte.

15) Recherchez Code 43 NVIDIA / motifs de refus du pilote (guests Windows)

cr0x@server:~$ qm showcmd 101 --pretty | egrep -i 'kvm=|hidden|vendor|cpu host' | head -n 50
-cpu host,hv_time,hv_relaxed,hv_vapic,hv_spinlocks=0x1fff
-machine type=q35,accel=kvm
-smbios type=1,uuid=2b4b9a2a-4a1a-4c3c-9f28-8ed0f843b2c1

Ce que cela signifie : Les pilotes consommateurs NVIDIA modernes détectaient autrefois la virtualisation et refusaient de fonctionner correctement dans certains cas. Le paysage a évolué, mais « le pilote refuse en VM » arrive encore selon le GPU, la branche du pilote et la configuration du guest.

Décision : Si vous rencontrez des symptômes type Code 43, confirmez que vous utilisez l’accélération KVM, le passthrough CPU host, et des enlightenments Hyper-V raisonnables. Ne commencez pas par des hacks aléatoires « cacher KVM » sauf si vous reproduisez une régression spécifique.

16) Vérifiez que le périphérique n’est pas utilisé par l’hôte (descripteurs ouverts, services ou bridges)

cr0x@server:~$ lsof /dev/vfio/* 2>/dev/null | head
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
qemu-sys 4212 root   25u   CHR  246,0      0t0  123 /dev/vfio/12

Ce que cela signifie : Si un précédent processus QEMU détient encore le groupe VFIO, votre prochain démarrage échouera. Cela capture aussi les moments « la VM tourne encore quelque part ».

Décision : Si vous voyez un processus obsolète, arrêtez-le proprement. S’il ne meurt pas, collectez d’abord les logs, puis terminez-le. Les reboots sont parfois le moindre mal face à des périphériques PCIe bloqués.

17) Confirmez l’état SR-IOV (si vous passez des VFs)

cr0x@server:~$ lspci -s 03:00.0 -vv | egrep -i 'SR-IOV|Virtual Function' -n
210:Capabilities: [160] Single Root I/O Virtualization (SR-IOV)
220:    Total VFs: 8, Initial VFs: 0, Number of VFs: 4, Function Dependency Link: 00

Ce que cela signifie : SR-IOV est présent et configuré pour 4 VFs. Si les VFs attendues n’apparaissent pas, le firmware, le pilote ou la configuration sysfs manque.

Décision : Si les VFs ne sont pas créées, activez SR-IOV dans le BIOS (si applicable), assurez-vous que le pilote hôte le supporte, et configurez explicitement la création des VFs. Si vous mélangez VFs et PF en passthrough, soyez absolument sûr de comprendre les contraintes du périphérique.

Trois mini-récits d’entreprise depuis le terrain

Mini-récit 1 : l’incident causé par une mauvaise hypothèse

L’équipe a hérité d’un cluster Proxmox qui « faisait déjà du GPU passthrough ». Le propriétaire précédent avait laissé une note : « fonctionne, ne touchez pas ». Cette note a tourné comme du lait.

Une petite mise à jour est passée : nouveau kernel, nouveau firmware, même matériel. Lundi matin : les VMs de rendu démarrent mais les GPU ne s’attachent plus. Le tableau de bord semblait normal. Les utilisateurs ont eu des écrans noirs et des avis véhéments.

Le premier ingénieur a pensé aux arguments QEMU. Le second a fouillé les pilotes Windows. Le troisième a fait la seule chose utile : a vérifié les groupes IOMMU et a remarqué qu’ils avaient changé. Le GPU était maintenant groupé avec un bridge PCIe qui incluait aussi un contrôleur USB dont l’hôte avait besoin. Ça « marchait » avant parce que l’ancien BIOS avait un comportement différent d’énumération et de groupement PCIe.

L’hypothèse erronée était subtile : « les groupes IOMMU sont stables après les mises à jour ». Ce n’est pas vrai. Les mises à jour firmware, les changements de kernel, et même le peuplement des slots peuvent remélanger la topologie. Ce n’est pas Linux qui fait des caprices ; c’est la plateforme qui expose de nouvelles informations ou de nouveaux routages.

La correction fut ennuyeuse : déplacer le GPU vers un autre slot, désactiver un contrôleur onboard inutilisé pour simplifier l’arbre, et mettre à jour le runbook pour revalider les groupes après les changements de firmware. L’incident ne s’est pas réglé par des exploits héroïques. Il s’est fini par une checklist.

Mini-récit 2 : l’optimisation qui a mal tourné

Une autre organisation voulait « des perfs maximales » pour une VM sensible à la latence utilisant des NICs en passthrough. Quelqu’un a activé tous les knobs de performance dont il se souvenait : hugepages, pinning CPU, isolcpus, tweaks irqbalance, réglages d’alimentation agressifs. Ça avait l’air impressionnant. C’était aussi fragile.

Ça a tourné parfaitement pendant une semaine. Puis un reboot d’hôte s’est produit pendant la maintenance, et la VM a commencé à perdre des paquets. Le passthrough NIC s’attachait toujours, mais le trafic avait du jitter et des stalls occasionnels. Sur l’hôte, la distribution des interruptions semblait inégale ; un cœur était noyé.

Le coupable n’était pas VFIO du tout. L’isolation CPU « optimisée » avait trop épinglé, et les interruptions se bloquaient sur un jeu de cœurs non optimal après le boot. L’hôte faisait un travail supplémentaire pour rééquilibrer les interruptions et gérer le bruit des timers dans un coin étrange de l’ordonnanceur.

Ils ont reverti la moitié des « tunings », gardé seulement ce qu’ils pouvaient mesurer, et réintroduit irqbalance avec des règles d’affinité explicites. Les perfs ont baissé légèrement dans le benchmark synthétique. La latence réelle s’est améliorée, et le système a cessé d’être une sculpture en verre.

Blague n°2 : À chaque fois que vous « optimisez » un système sans mesures, une interruption se pose sur le pire cœur possible par pure malice.

Mini-récit 3 : la pratique ennuyeuse mais correcte qui a sauvé la mise

Une équipe gérait une petite flotte de nœuds Proxmox pour des charges mixtes : VMs à stockage intensif et quelques desktops en passthrough GPU. Rien de tape-à-l’œil. Ce qu’ils avaient, c’était de la discipline.

Ils tenaient un artefact simple par hôte : un fichier texte avec les versions de firmware, la ligne de commande du kernel, la liste des groupes IOMMU et les périphériques destinés au passthrough. Après toute mise à jour BIOS ou modification matérielle, ils re-exécutaient la collecte d’artefacts. Ça prenait dix minutes. Les gens râlaient. Ils le faisaient quand même.

Un après-midi un nœud a redémarré inopinément après un incident d’alimentation. Au retour, une VM GPU n’a pas pu démarrer avec une erreur de groupe VFIO. L’ingénieur d’astreinte a comparé les groupes IOMMU du jour avec le dernier artefact connu bon. Le GPU partageait maintenant un groupe avec un contrôleur SATA parce qu’un réglage firmware avait été remis à sa valeur par défaut.

La correction a été immédiate : restaurer les réglages BIOS, valider les groupes IOMMU, et redémarrer la VM. Pas de supputations, pas de savoir tribal, pas de « essayez un autre kernel ». La pratique ennuyeuse n’a rendu personne célèbre, ce qui est le but.

Erreurs courantes : symptôme → cause racine → correctif

Cette section existe parce que nous répétons tous les mêmes échecs, juste avec des hostnames différents.

1) La VM ne démarre pas : « failed to set iommu for container » / « no IOMMU detected »

Symptôme : QEMU refuse de démarrer avec une erreur IOMMU/VFIO.

Cause racine : VT-d/AMD-Vi désactivé dans le BIOS, mauvaise ligne de commande kernel, ou boot sur un kernel sans activation IOMMU.

Correctif : Activez VT-d/AMD-Vi dans le firmware, ajoutez intel_iommu=on ou amd_iommu=on, redémarrez, confirmez avec dmesg.

2) La VM démarre mais le périphérique n’apparaît pas dans le guest

Symptôme : L’OS invité démarre, mais pas de GPU/NIC, ou il apparaît avec des erreurs.

Cause racine : Mauvais BDF, fonction multifonction manquante (audio GPU), périphérique non lié à vfio-pci, ou problème de pilote invité.

Correctif : Revérifiez lspci -nn, passez toutes les fonctions nécessaires, confirmez Kernel driver in use: vfio-pci, et validez les pilotes invités.

3) Ça marche une fois après le boot, puis échoue jusqu’au reboot de l’hôte

Symptôme : Le premier démarrage de VM après le boot de l’hôte fonctionne ; les démarrages suivants échouent ou le GPU reste noir.

Cause racine : Le périphérique n’a pas de reset fiable (pas de FLR), ou un quirk de reset du constructeur (commun sur certains GPU).

Correctif : Choisissez du matériel avec support FLR, essayez des modules de reset spécifiques au kernel/constructeur si disponibles, ou acceptez les reboots d’hôte comme contournement opérationnel.

4) Gel aléatoire de l’hôte sous charge

Symptôme : L’hôte se bloque pendant des I/O VM ou des charges GPU lourdes, nécessitant parfois un cycle d’alimentation.

Cause racine : Remappage d’interruptions cassé, BIOS buggué, overclocks instables, ou alimentation/entraînement PCIe marginal (oui, même sur des builds « server »).

Correctif : Confirmez DMAR-IR: Enabled IRQ remapping, mettez à jour le BIOS, désactivez l’overclock, vérifiez l’alimentation. Si la plateforme est grand public, traitez-la comme telle.

5) Les performances sont terribles même si le passthrough « fonctionne »

Symptôme : Faible FPS, stutter, pics de latence, perte de paquets, ou stalls intermittents.

Cause racine : Latence de stockage, contention CPU, mauvais modèle CPU, ou interruptions mal routées. Le passthrough ne vous immunise pas du reste de l’hôte.

Correctif : Mesurez : pveperf, iostat, top, distribution des interruptions. Corrigez les goulets d’étranglement avant de tripoter les flags VFIO.

6) Périphérique coincé dans un groupe IOMMU avec « tout »

Symptôme : Le GPU partage un groupe avec USB/SATA/chipset.

Cause racine : La topologie de la carte mère manque d’isolation ACS ; le périphérique est derrière le même root complex ; câblage du slot.

Correctif : Déplacez les slots, changez les réglages PCIe du BIOS, mettez à jour le firmware, ou acceptez le risque ACS override. Pour une isolation de production, choisissez une carte qui se comporte sérieusement.

Checklists / plan étape par étape

Si vous voulez quelque chose à coller dans un ticket, utilisez cette séquence. Elle est volontairement répétitive ; la répétition réduit la durée des interruptions.

Vérification de base de l’hôte (faites-le une fois par nœud, puis après chaque mise à jour BIOS)

  1. Confirmez les flags de virtualisation : lscpu et enregistrez la sortie.
  2. Confirmez l’IOMMU active : dmesg | egrep -i 'DMAR|AMD-Vi|IOMMU'.
  3. Confirmez le remappage IRQ : dmesg | egrep -i 'DMAR-IR|remapping'.
  4. Capturez la ligne de commande kernel : cat /proc/cmdline et stockez-la.
  5. Dump des groupes IOMMU et stockez-les comme artefact.

Vérification par périphérique (à faire chaque fois que vous ajoutez un périphérique en passthrough)

  1. Enregistrez les IDs et fonctions du périphérique : lspci -nn.
  2. Vérifiez l’appartenance au groupe : dump des groupes et confirmez l’isolation.
  3. Vérifiez la capacité de reset : lspci -vv et notez le FLR.
  4. Lie au vfio-pci et confirmez avec lspci -k.

Vérification par VM (à faire chaque fois que vous modifiez la config VM)

  1. Confirmez le type de machine et le BIOS : qm config VMID.
  2. Confirmez que les entrées hostpci incluent toutes les fonctions requises.
  3. Confirmez le mode CPU : préférez -cpu host sauf raison de compatibilité.
  4. En cas d’échec, vérifiez qui tient le groupe VFIO : lsof /dev/vfio/*.

Deux règles « stoppez creuser »

  • Si l’IOMMU n’est pas activé dans dmesg, arrêtez d’ajuster les arguments QEMU. Corrigez le firmware/la ligne de commande d’abord.
  • Si votre groupe IOMMU est « sale » et que vous envisagez ACS override, arrêtez-vous et décidez si vous acceptez le risque. Ne vous y engagez pas les yeux fermés.

FAQ

1) Ai-je besoin à la fois de VT-x et VT-d (ou AMD-V et AMD-Vi) ?

VT-x/AMD-V sert à la virtualisation CPU. VT-d/AMD-Vi sert à l’IOMMU (remappage DMA) et c’est celle dont dépend le passthrough PCI. Vous voulez typiquement les deux.

2) iommu=pt est-il sûr ?

Courant et généralement sûr pour la performance sur des hôtes où vous ne cherchez pas à imposer un surcoût de traduction sur les périphériques non-passthrough. Ça ne remplace pas une isolation correcte ; ça change juste la manière dont l’hôte utilise l’IOMMU.

3) Dois-je utiliser ACS override ?

Seulement si vous comprenez les implications de sécurité et de correction. Ça peut rendre du matériel grand public utilisable pour des homelabs. Ça peut aussi créer une isolation qui paraît réelle mais qui n’est pas aussi robuste qu’un comportement ACS natif matériel.

4) Pourquoi mon GPU a-t-il besoin que sa fonction audio soit passée ?

Beaucoup de GPU exposent un contrôleur audio HDMI/DP comme fonction PCI séparée. Les guests se comportent souvent mieux quand les deux fonctions sont assignées, et cela évite que l’hôte ne lie la fonction restante.

5) SeaBIOS ou OVMF ?

OVMF (UEFI) est le défaut moderne, en particulier pour Windows 11 et les GPU récents. SeaBIOS peut fonctionner pour des guests plus anciens, mais mélanger de vieilles habitudes avec des GPU modernes est la voie vers les écrans noirs.

6) Mon périphérique est dans le même groupe IOMMU qu’un bridge PCI. Est-ce toujours mauvais ?

Pas automatiquement. Les bridges font partie de la topologie. Ce qui compte, c’est si le groupe inclut des périphériques que vous ne pouvez pas ou ne devez pas passer ensemble. Si le groupe contient un contrôleur USB du chipset dont l’hôte a besoin, vous avez un problème pratique.

7) Pourquoi le passthrough casse-t-il après une mise à jour du kernel ?

Les mises à jour du kernel peuvent changer le comportement des pilotes, l’ordre d’initialisation, et comment les quirks sont appliqués. Les mises à jour firmware peuvent aussi changer l’énumération PCIe. C’est pourquoi vous conservez des artefacts (cmdline, groupes, bindings) et revalidez après les upgrades.

8) Les problèmes de performance ZFS peuvent-ils ressembler à des problèmes VFIO ?

Oui. Si le stockage invité se fige, vous verrez des accrochages, des latences d’entrée et des timeouts « aléatoires » que les gens attribuent à tort aux GPU ou aux NICs. Mesurez la latence stockage avant de réécrire les configs VM.

9) Dois-je dumper et passer un fichier ROM VBIOS ?

Parfois. C’est plus courant quand le GPU a été initialisé par le firmware hôte comme écran primaire, ou quand la plateforme n’expose pas une option ROM propre au guest. Si tout le reste est vérifié et que vous avez toujours un écran noir, c’est une expérience raisonnable suivante.

10) Pourquoi l’hôte a-t-il parfois besoin d’un reboot après l’arrêt d’une VM en passthrough ?

Parce que tous les périphériques ne se réinitialisent pas de manière fiable. Si le périphérique ne revient pas dans un état propre, la prochaine assignation échoue. Ce n’est pas Proxmox qui fait du cinéma ; c’est le matériel qui refuse d’oublier.

Conclusion : étapes suivantes qui fonctionnent réellement

Quand le passthrough casse, votre travail n’est pas de surclasser VFIO. Votre travail est de prouver que la plateforme fournit les prérequis que VFIO exige : IOMMU activé, isolation propre des groupes, binding pilote correct, et un périphérique qui se réinitialise comme s’il respectait des frontières.

Faites plutôt ceci :

  1. Capturez et enregistrez trois artefacts par hôte : /proc/cmdline, la liste des groupes IOMMU, et lspci -k pour les périphériques passthrough.
  2. Si vous utilisez ACS override, notez-le comme une décision de risque, pas comme un réglage. Décidez si le matériel doit être remplacé.
  3. Avant de changer les args VM, vérifiez IOMMU et le remappage IRQ dans dmesg. Si c’est mauvais, arrêtez et réparez le firmware/la ligne de commande.
  4. Pour les périphériques instables, testez explicitement le comportement de reset : démarrez la VM, arrêtez la VM, redémarrez sans rebooter l’hôte. Si ça échoue, considérez le reset comme la cause racine jusqu’à preuve du contraire.

Une fois que vous pouvez reproduire l’échec avec des preuves, VFIO cesse d’être un bouc émissaire et redevient ce qu’il est : un videur strict qui applique les règles que votre plateforme a promis de respecter.

← Précédent
Installation de Raspberry Pi OS : carte SD bien faite (et comment éviter la corruption)
Suivant →
IOMMU expliqué : l’interrupteur BIOS qui rend (ou casse) le passthrough GPU

Laisser un commentaire