« Ça marche sur mon poste » est mignon jusqu’à ce que vous tentiez d’exécuter Windows dans une VM avec un vrai GPU, une vraie charge et de vrais utilisateurs qui ouvrent des tickets quand la souris saccade.
Le passthrough GPU est un de ces projets qui ressemble à une case à cocher (« activer IOMMU ») et qui se transforme en une semaine à courir après un seul interrupteur BIOS manquant, une réinitialisation PCIe défaillante ou un pilote Windows qui refuse de coopérer. Ce guide sert à y parvenir sans transformer l’hôte en foire scientifique.
Ce que vous construisez (et ce que vous ne construisez pas)
Vous construisez une VM Windows sur un hôte Linux (pile KVM/QEMU) qui utilise un GPU physique directement via VFIO/IOMMU. La VM possède ce GPU. Pas « en partie ». Pas « partagé poliment ». L’hôte doit traiter ce GPU comme s’il était débranché.
Ceci n’est pas la même chose que :
- Accélération via bureau distant (RDP, VNC, SPICE). Utile, mais généralement pas « quasi‑native » pour la 3D ou le travail interactif à faible latence.
- vGPU / dispositifs médiés (style SR‑IOV pour GPU). Parfait quand disponible, mais le matériel et les licences peuvent être restrictifs.
- Accélération GUI WSL2 (sympa, problème différent).
« Quasi‑native » signifie que vous avez éliminé les goulets d’étranglement typiques de la virtualisation : périphériques émulés, mauvais routage des interruptions, pénalités de synchronisation du stockage et chaos d’ordonnancement CPU. Le GPU est la vedette, mais la distribution d’appui (firmware, isolation du chipset, stockage, timers) fait ou défait votre journée.
Faits et contexte historique (pour que les bizarreries aient du sens)
- IOMMU n’a pas été créé pour les gamers. AMD‑Vi et Intel VT‑d ont été fortement poussés pour la consolidation serveur et l’isolation DMA — empêcher les périphériques d’écrire dans une mémoire qui ne leur appartient pas.
- VFIO est du « Linux moderne ». Avant VFIO, l’assignation de périphériques était possible mais plus fragile et moins sûre ; VFIO a standardisé une interface utilisateur‑espace plus sûre pour le passthrough.
- PCIe ACS est le méchant/héros méconnu. Access Control Services déterminent si un switch peut isoler le trafic peer‑to‑peer. Beaucoup de cartes grand public économisent là-dessus, et vos groupes IOMMU le montrent.
- UEFI (OVMF) a changé la donne. Les comportements des ROM des BIOS legacy et la gestion des option ROM des GPU étaient un casse‑tête. OVMF a rendu les installations Windows modernes et l’initialisation GPU beaucoup plus prévisibles.
- L’époque du « Code 43 » de NVIDIA a existé. Les comportements des pilotes consommateur punissaient historiquement les signaux de virtualisation. Beaucoup de ces douleurs sont réduites aujourd’hui, mais le folklore persiste pour une raison.
- Le comportement de reset est du matériel, pas de l’ambiance. Certains GPU ne peuvent pas être réinitialisés proprement sans un reset du bus complet ; voilà pourquoi « ça marche une fois après le boot » revient souvent.
- VirtIO n’était pas un hack de performance ; c’est une philosophie. Les périphériques paravirtualisés réduisent le surcoût d’émulation en proposant une interface explicitement conçue pour les VM.
- Les interruptions MSI/MSI‑X comptent plus que vous ne voulez l’admettre. Elles réduisent le partage d’interruptions et peuvent améliorer la latence. Mais elles peuvent aussi révéler des tables firmware cassées et des hypothèses erronées des pilotes.
Choix matériels qui font ou défont le passthrough
Choisissez un CPU/plateforme qui gère correctement l’IOMMU
La plupart des plateformes AMD Ryzen et Intel Core récentes supportent IOMMU/VT‑d, mais l’implémentation sur la carte mère est ce que vous achetez réellement. Si vous avez le choix, privilégiez des cartes connues pour avoir des groupements IOMMU raisonnables et des mises à jour de firmware stables. Une carte avec trois mises à jour BIOS en six mois est soit une excellente équipe… soit une étiquette d’avertissement.
Deux GPU rendent la vie plus simple
Oui, vous pouvez faire le passthrough du seul GPU et exécuter l’hôte en headless. Mais c’est plus difficile à diagnostiquer et plus pénible à récupérer quand vous cassez l’affichage. Utilisez un iGPU (Intel) ou un second GPU bon marché pour la console de l’hôte. Ça transforme « J’ai briqué mon boot » en « Je peux encore SSH et corriger. »
Câblage des slots PCIe : lisez la documentation
Le slot x16 supérieur n’est pas toujours « lignes CPU directes ». Certaines cartes routent via le chipset ou partagent la bande passante avec des slots M.2. Pour le passthrough, vous voulez :
- GPU dans un slot avec un entraînement de lien stable (Gen4/Gen5 peut être délicat).
- Partage minimal avec d’autres périphériques à large bande.
- Groupement IOMMU qui n’englobe pas la moitié du chipset avec votre GPU.
Stratégie USB et audio
Décidez tôt : faîtes‑vous le passthrough d’un contrôleur USB complet, ou forwardez‑vous des périphériques individuellement ? Passer un contrôleur complet est plus propre et plus stable pour claviers, souris, casques VR et interfaces audio. Mais il faut un contrôleur dans son propre groupe IOMMU.
Blague #1 : Le passthrough USB, c’est comme la politique de bureau : tout va bien jusqu’à ce qu’un casque arrive et que soudain rien ne fonctionne.
Réseau : restez simple
Une carte virtio‑net sur un bridge Linux saturera facilement du 10GbE dans beaucoup de cas. Ne passez pas le NIC en passthrough à moins d’avoir une raison impérative (pilotes spéciaux, isolation stricte). Chaque périphérique en passthrough ajoute des modes de panne et des dépendances de reboot.
Paramètres BIOS/UEFI : les commutateurs ennuyeux qui décident de votre sort
La plupart des fils « le passthrough GPU ne fonctionne pas » se réduisent à « IOMMU n’était pas réellement activé ». Les libellés BIOS varient, les valeurs par défaut varient, et les mises à jour de firmware peuvent les réinitialiser silencieusement. Notez vos réglages. Sérieusement.
Paramètres à activer
- Intel : VT‑d (IOMMU), VT‑x (virtualisation). Parfois « DMA remapping ».
- AMD : SVM (virtualisation), IOMMU (AMD‑Vi). Parfois « IOMMU Controller ».
- Mode de démarrage UEFI (préférez UEFI, pas CSM/legacy).
- Above 4G decoding (souvent requis pour les GPU modernes, le sizing des BAR et un mappage propre).
- Resizable BAR (optionnel ; tester soigneusement — peut aider ou compliquer).
Paramètres à envisager de désactiver (si vous traquez des gremlins)
- CSM (compatibility support module). Il peut créer des chemins ROM/init étranges.
- Fast boot (cache les infos POST et saute parfois des étapes d’init périphérique utiles pour le comportement de reset).
- PCIe ASPM (gestion d’énergie qui peut induire latence ou instabilité sur certaines plateformes).
Mises à jour du firmware : traitez‑les comme des changements en production
Mettez à jour le BIOS si vous avez besoin d’un meilleur groupement ACS ou de stabilité. Mais faites‑le comme vous patcheriez un routeur core : fenêtre de maintenance, plan de rollback et moyen de revenir si l’hôte ne démarre plus. Vous changez la plateforme dont dépend votre frontière de sécurité (IOMMU).
Configuration du host Linux : IOMMU, VFIO et isolation
Paramètres du noyau au boot : IOMMU activé, et réellement utilisé
Sur Intel, vous voulez typiquement intel_iommu=on. Sur AMD, amd_iommu=on. Beaucoup de configurations ajoutent aussi iommu=pt pour réduire l’overhead pour les périphériques de l’hôte en utilisant des mappings pass‑through là où c’est sûr.
Si vous chassez la performance : pinnez les CPU, isolez le bruit de l’hôte et évitez les périphériques émulés. Si vous chassez la stabilité : gardez la configuration simple et reproductible avant d’affiner.
Liez le GPU à VFIO tôt
Vous voulez que l’hôte ne charge jamais le pilote GPU normal pour le périphérique passé. Cela signifie le binder à vfio-pci au démarrage, en utilisant les identifiants de périphérique (vendor:device). Liez aussi la fonction audio HDMI/DP du GPU — la plupart des GPU discrets exposent au moins deux fonctions PCI.
N’oubliez pas l’initramfs
Beaucoup de distributions ont besoin que les modules VFIO soient disponibles dans l’initramfs afin que le noyau puisse binder les périphériques avant que les pilotes GPU « normaux » ne les saisissent. Si vous manquez ça, vous passerez une journée à vous demander pourquoi votre GPU est « en cours d’utilisation » même quand vous avez blacklisté les pilotes.
Sécurité et rayon d’action
IOMMU est une isolation, pas de la magie. Les attaques DMA sont la raison de son existence, et une mauvaise configuration peut compromettre l’hôte. Si ce système compte, gardez l’hôte minimal, réduisez les modules noyau tiers et traitez le passthrough comme donner à une VM une voie directe vers le matériel.
Voici une citation à garder en mémoire. Elle est courte, et elle frappe au‑delà de son poids :
« L’espoir n’est pas une stratégie. » — Gen. Gordon R. Sullivan
Groupes IOMMU : interprétez-les comme une scène de crime
Les groupes IOMMU déterminent ce qui peut être isolé en toute sécurité. Si votre GPU est dans un groupe avec votre contrôleur SATA, vous n’avez pas une « configuration passthrough cool ». Vous avez un futur rapport d’incident.
À quoi ressemble du « bon »
- Le GPU et sa fonction audio sont dans le même groupe (acceptable), mais pas avec des périphériques non liés.
- Votre contrôleur USB destiné au passthrough est dans son propre groupe.
- Les NVMe que vous voulez passer sont isolés proprement (ou vous ne les passez pas et gardez le stockage virtualisé).
À quoi ressemble du « mauvais »
- Le GPU partage un groupe avec des périphériques ponts du chipset et plusieurs contrôleurs.
- Tout derrière un switch PCIe s’effondre en un seul groupe (commun sur le matériel grand public sans ACS).
ACS override : un outil, pas une solution
Le noyau dispose d’un patch/paramètre d’ACS override dans certains environnements. Il peut séparer artificiellement les groupes IOMMU. Il peut aussi créer un faux sentiment de sécurité en disant à la pile logicielle « c’est isolé » alors que le matériel peut toujours faire du peer‑to‑peer DMA. Utilisez‑le uniquement si vous comprenez le risque et l’acceptez. En production : évitez d’en dépendre.
Construction de la VM Windows : OVMF, Q35, VirtIO et bon sens
Type de machine et firmware
Utilisez Q35 (émulation de chipset moderne) et OVMF (UEFI). Cela s’aligne sur les attentes de Windows modernes, la topologie PCIe et l’initialisation GPU.
Périphériques disque et réseau
Utilisez VirtIO pour le disque et le réseau. Installez les pilotes VirtIO pendant l’installation de Windows (ou injectez‑les). Le SATA/IDE émulé fonctionne pour le bootstrap mais coûte en performance et parfois en stabilité sous charge.
Modèle CPU et fonctionnalités
Exposez un modèle CPU sensé. host-passthrough est courant car il donne à Windows le même jeu d’instructions que l’hôte, réduisant l’overhead de traduction. Mais cela peut réduire la portabilité de la VM. Pour une machine unique, c’est généralement acceptable.
TPM et Secure Boot
Windows 11 veut TPM 2.0 et Secure Boot. Utilisez un TPM virtuel (swtpm) et OVMF Secure Boot si votre plateforme le supporte. Si vous faites ça pour un environnement contrôlé, répondez aux exigences au lieu de bidouiller. Les hacks deviennent des politiques. Ensuite arrivent les audits.
Passer le GPU (et sa fonction audio)
Passez les deux fonctions, ou profitez d’un audio HDMI à moitié fonctionnel
Les GPU discrets présentent couramment :
- Fonction VGA/contrôleur 3D
- Fonction audio HDMI/DP
- Parfois un contrôleur USB‑C (sur certaines cartes)
Passez l’ensemble des fonctions qui appartiennent ensemble. Mélanger la propriété host/guest crée de la confusion côté pilote et des réinitialisations de périphérique qui échouent de façons créatives.
Bugs de reset et syndrome « marche une fois »
Si la VM peut démarrer une fois après le boot de l’hôte, mais échoue au second démarrage, vous rencontrez probablement un problème de reset. Certains GPU AMD avaient historiquement besoin d’un vendor‑reset ; certains GPU NVIDIA peuvent être récalcitrants aussi. La correction peut être un module noyau, un autre slot PCIe, désactiver ASPM, ou changer la façon dont QEMU réinitialise le périphérique. Parfois la solution est « utilisez un GPU différent », ce qui n’est pas satisfaisant émotionnellement mais est opérationnellement correct.
Blague #2 : Les bugs de reset GPU sont la façon dont la nature nous rappelle que « éteindre et rallumer » est une fonctionnalité matérielle, pas une philosophie de vie.
Ordre d’installation des pilotes Windows
Installez d’abord VirtIO (stockage/réseau), puis les pilotes GPU une fois la VM stable. Si vous installez les pilotes GPU tôt et que la VM est instable, vous passerez du temps à déboguer Windows alors que la cause racine est souvent le binding VFIO ou le groupement PCIe.
Stockage et performance : ne vous sabotez pas
Les configurations de passthrough GPU échouent souvent à la promesse « quasi‑native » parce que le stockage est configuré comme une VM de démo de 2009.
Décidez : disque virtuel vs passthrough de périphérique
- Disque virtuel (qcow2/raw sur NVMe, VirtIO‑blk/scsi) : le plus simple pour snapshots, migration, sauvegarde et monitoring. Généralement assez rapide.
- Passthrough NVMe : très haute performance, mais réduit la gérabilité et augmente la complexité de récupération. Nécessite aussi une isolation IOMMU propre.
ZFS sur l’hôte : puissant, mais respectez sync
Si votre disque VM est sur ZFS, vous rencontrerez les sémantiques de sync. Un invité Windows avec cache d’écriture et flushs peut déclencher des écritures sync. Si votre pool ZFS n’a pas de SLOG ou en a un faible, des pics de latence apparaissent sous forme de « stutter » VM.
Règle : ne désactivez pas sync sauf si vous pouvez tolérer la corruption. Si vous construisez une VM uniquement pour le jeu et que perdre une session est acceptable, vous pouvez prendre ce risque. Pour tout ce qui sent le travail : gardez sync et investissez dans un vrai SLOG ou acceptez la latence.
Trim/Discard
Activez discard quand approprié pour que l’espace SSD soit récupéré. Mais validez‑le. Un discard mal configuré peut provoquer des pics de latence périodiques selon la pile de stockage et le firmware.
Latence et « quasi‑native » : où se cache les derniers 10%
Pinning CPU et bruit de l’ordonnanceur
Pignez les vCPU sur des cœurs physiques. Gardez les threads d’émulation hors de vos cœurs pinés. Si vous exécutez les tâches de fond de l’hôte sur les mêmes cœurs que le thread de rendu de la VM, vous obtiendrez des micro‑saccades presque impossibles à expliquer à quelqu’un qui veut une réponse simple.
Hugepages : parfois un gain, parfois un piège
Les hugepages peuvent réduire les misses TLB et améliorer les performances mémoire. Elles peuvent aussi rendre l’allocation de mémoire fragile. Si vous exécutez plusieurs services, réservez les hugepages avec soin et surveillez la fragmentation. Si c’est une machine à usage unique, les hugepages valent plus souvent le coup.
Interruptions : MSI/MSI‑X et isolation
Quand la performance est « proche mais pas fluide », vérifiez le routage des interruptions et si les périphériques utilisent MSI. Les interruptions partagées peuvent générer de la latence sous charge. La solution n’est pas toujours de forcer MSI ; parfois il faut réparer la topologie, mettre à jour le firmware ou déplacer le périphérique dans un autre slot.
Capture d’image vs affichage direct
Si vous voulez garder l’écran connecté à l’hôte mais voir la sortie de la VM, des outils comme Looking Glass peuvent aider en utilisant la mémoire partagée (ivshmem). C’est élégant. C’est aussi un autre composant à gérer. Stabilisez d’abord le passthrough de base ; ajoutez la commodité ensuite.
Trois mini‑histoires d’entreprise tirées du terrain
Incident : une mauvaise hypothèse sur des « serveurs identiques »
Une société a décidé de standardiser une petite flotte de stations « identiques » pour des contractuels CAO : même CPU, même RAM, même modèle de GPU, même image Linux. Le plan était d’héberger des VM Windows avec passthrough GPU pour que les contractuels puissent se connecter à leur VM assignée depuis n’importe où.
La semaine de déploiement s’est bien passée. Puis la moitié des machines a commencé à échouer au boot des VM après un reboot de routine. Les symptômes étaient incohérents : certains hôtes démarraient la VM une fois, puis échouaient aux démarrages suivants ; d’autres montraient le GPU manquant complètement. L’équipe a supposé une régression du noyau et a rollbacké. Pas de changement.
Le vrai problème était embarrassant et physique. Les machines « identiques » avaient été achetées en deux lots. Le second lot avait une autre révision de carte mère avec un switch PCIe différent. Les groupes IOMMU ont changé, et le GPU s’est retrouvé à partager un groupe avec un contrôleur USB dont l’hôte avait besoin pour son média de boot et un dongle KVM distant. Les scripts de passthrough liaient bêtement tout le groupe à VFIO.
Correction : inventorier les révisions matérielles, pinner les périphériques critiques par adresse PCI avec soin, et refuser de binder automatiquement un groupe entier lorsqu’il inclut des périphériques critiques de l’hôte. Ils ont aussi commencé à valider la disposition des groupes IOMMU comme partie des tests d’acceptation, comme on validerait le firmware d’une NIC.
Optimisation qui a mal tourné : courir après des chiffres de bench avec des réglages de stockage
Un autre service exécutait des VM Windows pour du traitement vidéo accéléré GPU. Les VM vivaient sur un pool ZFS. Quelqu’un a remarqué que le pipeline d’ingestion s’arrêtait parfois, et ils voulaient des écritures plus rapides. Ils ont basculé une propriété de dataset pour réduire l’overhead sync (et se sont félicités parce que le graphique de benchmark montait).
Quelques semaines ont semblé correctes. Puis un incident d’alimentation est survenu. Pas dramatique — juste une courte coupure qui a fait basculer un onduleur d’une façon qui a forcé un arrêt brutal. Au retour, plusieurs VM ont démarré avec des volumes NTFS corrompus. Certains projets ont dû être réimportés depuis les sources ; certains travaux en cours étaient perdus.
Le postmortem a été gênant parce que « l’optimisation » n’était pas malveillante ; c’était un conseil commun trouvé sur Internet. Le problème est que l’ordre d’écriture et les sémantiques de durabilité comptent plus en virtualisation, car les invités supposent souvent que l’hyperviseur respecte les flushes.
Correction : restaurer un comportement sync sûr, ajouter un vrai SLOG pour la latence, et documenter une règle : les changements de performance affectant la durabilité du stockage suivent le même processus d’approbation que les changements de sécurité. Les benchmarks ne signent pas les rapports d’incident ; les personnes le font.
Pratique ennuyeuse mais correcte qui a sauvé la mise : pinning déterministe et contrôle de version
Une équipe gérant une petite « ferme GPU » interne pour du rendu Windows avait une habitude presque comiquement bureaucratique : chaque hôte avait sa configuration complète de passthrough en contrôle de version, incluant les IDs PCI, les arguments QEMU et les paramètres noyau. Les changements passaient en revue. Ils avaient aussi un runbook d’une page pour identifier le GPU et sa fonction audio et confirmer le binding VFIO.
Puis est arrivée une fenêtre de maintenance : mises à jour noyau, microcode, un BIOS mis à jour sur deux machines, et un remplacement GPU car un ventilateur rendait l’âme. Exactement le genre de journée où « je me souviendrai de ce que j’ai fait la dernière fois » vire au théâtre improvisé.
Une des machines mise à jour est revenue avec le GPU à une adresse PCI différente (changement de slot). La VM a échoué au démarrage car la config pointait l’ancienne adresse. Pas de panique. L’ingénieur on‑call a suivi le runbook : lister les périphériques, cartographier les groupes IOMMU, mettre à jour la config, rebind VFIO, régénérer l’initramfs, reboot. Trente minutes plus tard la VM tournait. Personne n’a eu à redécouvrir comment le setup fonctionnait sous pression.
La pratique ennuyeuse n’était pas de l’héroïsme. C’était juste traiter les configs de passthrough comme une infrastructure de production : déterministe, révisable et testable. Voilà l’astuce entière.
Méthode de diagnostic rapide
Quand la performance n’est pas quasi‑native ou que la VM ne démarre pas, ne vous promenez pas. Faites une triage façon SRE : confirmez d’abord les conditions limites, puis rétrécissez.
Première étape : confirmer les fondamentaux (10 minutes)
- IOMMU activé et actif (les logs noyau montrent DMAR/AMD‑Vi, et les groupes IOMMU existent).
- GPU lié à vfio-pci sur l’hôte avant de démarrer la VM.
- VM utilise OVMF + Q35 (firmware moderne et modèle de chipset).
- Windows voit le GPU sans erreurs de pilote (Gestionnaire de périphériques, pas de Code 12/43).
Deuxième étape : identifiez la classe de goulot
- Saccades sous charge → ordonnancement CPU / interruptions / latence stockage.
- La VM ne démarre pas → groupes IOMMU, binding VFIO, ROM/reset.
- Démarre une fois, échoue ensuite → comportement de reset GPU, gestion d’alimentation, état du pilote.
- Faible FPS mais stable → mauvais chemin d’affichage (utilisation d’un GPU virtuel), pilote incorrect, largeur/vitesse PCIe.
Troisième étape : mesurez les signaux évidents
- État du lien PCIe (le GPU est‑il en x16 Gen4, ou s’est‑il entraîné en x4 Gen1 ?).
- Latence stockage (les écritures sync sont‑elles throttlées ?).
- Steal CPU et charge de l’hôte (êtes‑vous en lutte avec l’ordonnanceur ?).
- Distribution des interruptions (un cœur reçoit‑il toutes les interruptions ?).
Si vous ne pouvez pas dire dans quelle catégorie vous êtes, vous ne diagnostiquez pas encore — vous êtes en visite touristique.
Erreurs fréquentes : symptômes → cause racine → correction
La VM ne démarre pas ; QEMU dit « device is in use »
Symptômes : La VM échoue immédiatement ; les logs mentionnent que le périphérique GPU est occupé.
Cause racine : Le pilote GPU de l’hôte (nouveau/amdgpu/nvidia) a revendiqué le périphérique avant vfio-pci.
Correction : Binder par vendor/device ID avec vfio-pci au boot ; assurez‑vous que les modules VFIO sont dans l’initramfs ; blacklister les pilotes conflictuels n’est qu’une mesure secondaire.
Windows affiche Code 12 (« not enough resources ») pour le GPU
Symptômes : Le GPU apparaît mais ne démarre pas ; erreur d’allocation de ressources.
Cause racine : Mappage BAR/contraintes de ressources ; souvent Above 4G decoding manquant ou mauvaise topologie PCIe dans la VM.
Correction : Activez Above 4G decoding dans le BIOS ; utilisez Q35 ; envisagez Resizable BAR désactivé initialement ; assurez‑vous de passer toutes les fonctions du GPU.
Marche une fois après le boot de l’hôte, puis le GPU disparaît au redémarrage VM
Symptômes : Premier démarrage de VM OK ; démarrages suivants échouent jusqu’au reboot de l’hôte.
Cause racine : Le GPU ne supporte pas une réinitialisation propre au niveau fonctionnel ; le pilote le laisse dans un état incorrect.
Correction : Essayez différentes versions noyau/QEMU ; désactivez la gestion d’alimentation PCIe ; utilisez vendor‑reset si disponible ; si critique, choisissez un GPU connu pour sa stabilité de reset.
Faible FPS et forte utilisation CPU dans l’invité
Symptômes : Windows ressemble à un rendu logiciel ; CPU en pics.
Cause racine : Vous n’utilisez pas réellement le GPU passé (Windows utilise Microsoft Basic Display Adapter ou un GPU virtuel), ou l’affichage passe par un chemin de remoting lent.
Correction : Confirmez que le Gestionnaire de périphériques montre le bon GPU ; installez les pilotes GPU adéquats ; branchez un écran sur le GPU passé ou utilisez une méthode de capture faible latence comme ivshmem.
Craquements audio sous charge
Symptômes : Pops/crackles, surtout lors de compilations ou copies de fichiers.
Cause racine : Latence DPC due à l’ordonnancement CPU, aux interruptions ou à la gestion d’énergie ; parfois causée par le passthrough partiel de la chaîne audio.
Correction : Pinnez les vCPU ; réduisez la charge d’arrière‑plan de l’hôte ; assurez‑vous de MSI/MSI‑X où il faut ; passez un contrôleur USB dédié pour les périphériques audio si nécessaire.
Performance disque VM terrible sur un pool « rapide »
Symptômes : FPS qui chute lors du chargement d’actifs ; rendus vidéo qui s’arrêtent ; pics IO wait.
Cause racine : Pénalités d’écritures sync, fragmentation thin provisioning, overhead qcow2, ou manque de cache/SLOG adapté.
Correction : Préférez raw sur SSD/NVMe rapide pour la performance ; utilisez VirtIO avec queueing approprié ; sur ZFS, gardez sync=standard et fournissez un SLOG adapté si nécessaire.
Périphériques USB qui se déconnectent de façon aléatoire
Symptômes : Clavier/souris qui se déconnectent ; périphériques VR qui disparaissent ; sons Windows « device removed ».
Cause racine : Flapping de passthrough USB ; gestion d’énergie de l’hôte ; forwarding d’appareils individuels au lieu d’un contrôleur ; mauvais groupement IOMMU forçant des compromis.
Correction : Passez un contrôleur USB complet dans un groupe isolé ; désactivez l’autosuspend USB sur l’hôte si besoin ; évitez les hubs quand c’est possible.
Tâches pratiques avec commandes, sorties et décisions
Voici les vérifications que j’exécute quand je veux des réponses rapides. Chaque tâche inclut : une commande, ce que la sortie signifie et la décision suivante.
Task 1: Confirm virtualization extensions are present
cr0x@server:~$ lscpu | egrep -i 'Virtualization|Flags'
Virtualization: AMD-V
Flags: fpu vme de pse tsc ... svm ...
Meaning: You have CPU virtualization (SVM on AMD, VT-x on Intel). This is necessary but not sufficient for IOMMU.
Decision: If virtualization is missing, fix BIOS settings first (SVM/VT-x). Don’t touch VFIO yet.
Task 2: Confirm IOMMU/DMAR is actually enabled in the kernel
cr0x@server:~$ dmesg | egrep -i 'DMAR|IOMMU|AMD-Vi' | head -n 12
[ 0.812345] AMD-Vi: IOMMU performance counters supported
[ 0.812678] AMD-Vi: Found IOMMU at 0000:00:00.2 cap 0x40
[ 0.813210] AMD-Vi: Interrupt remapping enabled
Meaning: The IOMMU is initialized and interrupt remapping is on (good sign for stability).
Decision: If you see nothing relevant, add amd_iommu=on or intel_iommu=on to GRUB/systemd-boot and reboot.
Task 3: Confirm VFIO modules are loaded
cr0x@server:~$ lsmod | egrep 'vfio|kvm' | head
vfio_pci 65536 0
vfio_pci_core 90112 1 vfio_pci
vfio_iommu_type1 40960 0
vfio 45056 2 vfio_pci_core,vfio_iommu_type1
kvm_amd 139264 0
kvm 1105920 1 kvm_amd
Meaning: VFIO core is present. If this is missing, passthrough won’t happen.
Decision: If missing, install appropriate packages and ensure initramfs includes VFIO modules.
Task 4: Identify the GPU and its functions (VGA + audio)
cr0x@server:~$ lspci -nn | egrep -i 'vga|3d|audio'
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GA104 [GeForce RTX 3070] [10de:2484] (rev a1)
01:00.1 Audio device [0403]: NVIDIA Corporation GA104 High Definition Audio Controller [10de:228b] (rev a1)
Meaning: Two functions: GPU (01:00.0) and GPU audio (01:00.1). You almost always pass both.
Decision: Record the PCI addresses and device IDs. These drive vfio-pci binding.
Task 5: Check IOMMU group membership for the GPU
cr0x@server:~$ for d in /sys/kernel/iommu_groups/*/devices/*; do echo "$d" | sed 's/.*iommu_groups\/\([0-9]*\).*/Group \1/'; lspci -nns "${d##*/}"; done | egrep -A2 '01:00\.'
Group 12
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GA104 [GeForce RTX 3070] [10de:2484] (rev a1)
Group 12
01:00.1 Audio device [0403]: NVIDIA Corporation GA104 High Definition Audio Controller [10de:228b] (rev a1)
Meaning: The GPU and its audio are in Group 12 and nothing else is shown in this filtered output. You still need to confirm the full group contents.
Decision: If Group 12 contains unrelated devices, you cannot safely passthrough just the GPU without addressing isolation (different slot/board, or accept risk).
Task 6: Print the full IOMMU group (no cheating)
cr0x@server:~$ find /sys/kernel/iommu_groups/12/devices -maxdepth 1 -type l -printf '%f\n' | sort
0000:01:00.0
0000:01:00.1
Meaning: Clean, minimal group. This is what you want.
Decision: Proceed with VFIO binding. If the group is crowded, stop and reconsider hardware/topology.
Task 7: Bind GPU to vfio-pci using vendor:device IDs
cr0x@server:~$ sudo tee /etc/modprobe.d/vfio.conf >/dev/null <<'EOF'
options vfio-pci ids=10de:2484,10de:228b disable_vga=1
EOF
Meaning: This tells vfio-pci which devices to claim. disable_vga=1 can help with legacy VGA decoding quirks.
Decision: After setting this, you must rebuild initramfs (next task) and reboot to ensure early binding.
Task 8: Ensure VFIO modules load early (initramfs) and regenerate
cr0x@server:~$ echo -e "vfio\nvfio_pci\nvfio_iommu_type1\nvfio_pci_core" | sudo tee /etc/initramfs-tools/modules
vfio
vfio_pci
vfio_iommu_type1
vfio_pci_core
cr0x@server:~$ sudo update-initramfs -u
update-initramfs: Generating /boot/initrd.img-6.8.0-41-generic
Meaning: The initramfs now includes VFIO modules so they can bind devices before GPU drivers load.
Decision: Reboot. If you skip reboot here, you’re mostly testing your luck.
Task 9: After reboot, verify the GPU is using vfio-pci
cr0x@server:~$ lspci -k -s 01:00.0
01:00.0 VGA compatible controller: NVIDIA Corporation GA104 [GeForce RTX 3070] (rev a1)
Subsystem: Micro-Star International Co., Ltd. [MSI] Device 3901
Kernel driver in use: vfio-pci
Kernel modules: nvidiafb, nouveau, nvidia_drm, nvidia
Meaning: “Kernel driver in use: vfio-pci” is the money line. The presence of other modules under “Kernel modules” is fine; it lists possible modules, not active binding.
Decision: If the driver in use is nouveau/amdgpu/nvidia, go back: initramfs order, vfio IDs, and blacklists.
Task 10: Confirm the host didn’t grab the GPU for display
cr0x@server:~$ loginctl seat-status seat0 | head -n 20
seat0
Devices:
/sys/devices/pci0000:00/0000:00:02.0/drm/card0
cr0x@server:~$ ls -l /dev/dri/by-path | head
total 0
lrwxrwxrwx 1 root root 8 Feb 4 10:12 pci-0000:00:02.0-card -> ../card0
Meaning: The active DRM device is the iGPU at 00:02.0, not the passthrough GPU at 01:00.0.
Decision: If the host is using the passthrough GPU for DRM, you need a secondary GPU/iGPU for the host or a headless setup with careful binding.
Task 11: Validate PCIe link width/speed (performance sanity)
cr0x@server:~$ sudo lspci -vv -s 01:00.0 | egrep -i 'LnkCap|LnkSta'
LnkCap: Port #0, Speed 16GT/s, Width x16, ASPM L1, Exit Latency L1 <64us
LnkSta: Speed 16GT/s (ok), Width x16 (ok)
Meaning: The GPU trained correctly (Gen4 x16 here). If you see x4 or Gen1, expect bandwidth bottlenecks and weird stutter.
Decision: If link is degraded, reseat the card, change slot, update BIOS, or force PCIe generation in BIOS for stability testing.
Task 12: Check KVM acceleration is available
cr0x@server:~$ sudo kvm-ok
INFO: /dev/kvm exists
KVM acceleration can be used
Meaning: You have hardware virtualization acceleration exposed to QEMU.
Decision: If this fails, fix BIOS virtualization or kernel module loading before you troubleshoot passthrough.
Task 13: Confirm QEMU sees the VFIO device node
cr0x@server:~$ ls -l /dev/vfio
total 0
crw-rw---- 1 root root 10, 196 Feb 4 10:15 vfio
crw-rw---- 1 root root 10, 140 Feb 4 10:15 12
Meaning: Group 12 has a VFIO device node. That’s what QEMU opens to access the group.
Decision: If the group node is missing, IOMMU grouping isn’t active or permissions/udev rules are off.
Task 14: Watch for IOMMU faults during VM boot
cr0x@server:~$ sudo dmesg -w | egrep -i 'vfio|iommu|fault|DMAR|AMD-Vi'
[ 312.123456] vfio-pci 0000:01:00.0: enabling device (0000 -> 0003)
[ 312.456789] vfio-pci 0000:01:00.1: enabling device (0000 -> 0002)
Meaning: Normal device enable lines are fine. Actual IOMMU faults would show “fault” and an address.
Decision: If you see faults, suspect buggy firmware, unsafe ACS overrides, or a device doing DMA outside its assigned ranges.
Task 15: Check host CPU scheduling pressure and steal-like symptoms
cr0x@server:~$ top -b -n 1 | head -n 12
top - 10:22:01 up 12 days, 3:11, 2 users, load average: 7.82, 6.11, 5.44
Tasks: 382 total, 2 running, 380 sleeping, 0 stopped, 0 zombie
%Cpu(s): 62.1 us, 3.4 sy, 0.0 ni, 33.9 id, 0.4 wa, 0.0 hi, 0.2 si, 0.0 st
MiB Mem : 64239.0 total, 812.5 free, 28410.2 used, 35016.3 buff/cache
Meaning: Load is high but CPU idle is still ~34%. That suggests runnable pressure but not total saturation. If wa spikes, suspect storage latency.
Decision: If you see sustained high wa, go straight to storage checks. If sy is high, suspect interrupt storms or heavy networking.
Task 16: Measure storage latency signals on ZFS (if applicable)
cr0x@server:~$ sudo zpool iostat -v 1 3
capacity operations bandwidth
pool alloc free read write read write
rpool 1.20T 2.40T 220 980 28.0M 96.5M
nvme0n1 1.20T 2.40T 220 980 28.0M 96.5M
Meaning: High write ops could include sync-heavy guest workloads. This output doesn’t show latency directly, but it shows pressure patterns.
Decision: If write ops jump when stutter happens, investigate ZFS sync behavior, SLOG, and guest flush patterns.
Checklists / plan étape par étape
Phase 1 : Matériel et firmware (faites‑le avant de toucher les configs Linux)
- Installez un second GPU ou activez l’iGPU pour l’affichage de l’hôte.
- Mettez le BIOS/UEFI à une version stable (pas nécessairement la plus récente en bêta).
- Activez VT‑d/AMD‑Vi (IOMMU), VT‑x/SVM, Above 4G decoding.
- Désactivez CSM ; démarrez en mode UEFI pur.
- Placez le GPU dans un slot susceptible d’être direct CPU‑lanes ; évitez le partage avec des contrôleurs critiques.
Phase 2 : Base OS host
- Installez un noyau LTS récent connu pour être stable avec VFIO pour votre distro.
- Activez les paramètres noyau IOMMU (
intel_iommu=onouamd_iommu=on; éventuellementiommu=pt). - Installez KVM/QEMU, libvirt (ou votre pile hyperviseur) et assurez‑vous que
/dev/kvmexiste. - Identifiez les fonctions GPU avec
lspci -nn. - Vérifiez les groupes IOMMU. Si les groupes sont mauvais, corrigez la topologie maintenant (slot/carte), pas plus tard.
Phase 3 : Binding VFIO
- Créez la config ids vfio‑pci (
/etc/modprobe.d/vfio.conf). - Ajoutez les modules VFIO à l’initramfs, régénérez l’initramfs, reboot.
- Vérifiez « Kernel driver in use: vfio-pci » pour le GPU et la fonction audio.
- Confirmez que l’affichage de l’hôte n’utilise pas le GPU passé.
Phase 4 : Création de la VM
- Créez la VM avec Q35 + OVMF.
- Utilisez VirtIO disque + VirtIO réseau ; joignez l’ISO des pilotes VirtIO.
- Installez Windows ; installez les pilotes VirtIO ; puis installez les pilotes GPU.
- Passez le GPU + audio, et éventuellement un contrôleur USB.
- Redémarrez la VM plusieurs fois. Si ça ne marche qu’une fois, vous n’avez pas fini.
Phase 5 : Tuning performance (après la stabilité)
- Pignez les vCPU ; isolez les CPU de l’hôte si nécessaire.
- Évaluez les hugepages si la charge en bénéficie.
- Vérifiez la vitesse/largeur du lien PCIe.
- Mesurez le comportement du stockage sous charge ; corrigez la latence sync correctement.
FAQ
1) Ai‑je besoin de deux GPU ?
Besoin ? Non. Vouloir ? Oui. Deux GPU (ou un iGPU pour l’hôte) rend la récupération et le débogage beaucoup plus faciles. Le mode headless est viable mais moins indulgent.
2) Puis‑je obtenir des performances de jeu quasi‑natives ?
Souvent, oui. La partie GPU peut être quasi‑native ; l’écart restant vient généralement de l’ordonnancement CPU, de la latence stockage et du chemin d’affichage/USB. Si vous ajustez ces éléments, vous pouvez vous rapprocher beaucoup.
3) Dois‑je passer le NVMe en passthrough pour la vitesse maximale ?
Seulement si vous avez une raison qui compense le coût opérationnel. Un disque virtuel raw sur NVMe rapide avec VirtIO est déjà excellent. Le passthrough NVMe complique sauvegardes, snapshots et récupération.
4) Pourquoi Windows affiche Code 12 ou Code 43 ?
Code 12 est typiquement un problème d’allocation de ressources/BAR — souvent corrigé par Above 4G decoding et le bon chipset/firmware VM. Code 43 impliquait historiquement la détection de virtualisation par le pilote, mais aujourd’hui les causes incluent la mauvaise configuration et un état instable du périphérique.
5) Resizable BAR aide‑t‑il ?
Ça peut, selon le jeu/la charge et la plateforme. Ça peut aussi introduire de la complexité de mappage. Obtenez d’abord une base stable avec ça désactivé, puis testez intentionnellement.
6) ACS override est‑il sûr ?
Il peut faire croire au noyau que vous avez une meilleure isolation que le matériel ne le fournit. Pour un poste personnel, vous pouvez accepter le risque. Pour tout ce qui compte, traitez‑le comme dernier recours et préférez une isolation matérielle réelle.
7) Quelle est la façon la plus propre de gérer clavier/souris et périphériques USB ?
Passez un contrôleur USB entier dans son propre groupe IOMMU. Le forwarding d’appareils individuels fonctionne, mais il est plus sujet à des réinitialisations et des comportements étranges avec des périphériques à forte variation.
8) Comment savoir si le goulot est stockage vs CPU vs GPU ?
Vérifiez l’état du lien PCIe et confirmez que le GPU est réellement utilisé. Ensuite regardez le wa CPU de l’hôte et les stats de stockage pendant les saccades. Si IO wait grimpe en même temps que les saccades, c’est le stockage. Si le CPU est saturé ou les interruptions s’amoncellent sur un cœur, c’est l’ordonnancement/les interruptions.
9) Puis‑je exécuter plusieurs VM Windows avec plusieurs GPU ?
Oui, si vous avez les lignes PCIe, l’alimentation, le refroidissement et des groupes IOMMU propres. Opérationnellement, c’est plus proche d’un petit cluster : des configs déterministes et le contrôle des changements paient.
10) Dois‑je utiliser libvirt, Proxmox ou QEMU brut ?
Utilisez ce que vous pouvez opérer. Libvirt donne de la structure et une gestion plus simple ; QEMU brut donne un contrôle total. Proxmox est pratique mais repose toujours sur la même réalité noyau/VFIO en dessous.
Prochaines étapes à entreprendre réellement
- Inventoriez votre matériel : révision de la carte mère, version BIOS, modèle GPU et agencement PCIe. N’assumez pas que « même modèle » signifie « même comportement ».
- Validez les groupes IOMMU avant d’acheter des pièces supplémentaires ou de commencer à toucher les flags noyau. Si les groupes sont moches, changez de slot ou de carte maintenant.
- Rendez le binding VFIO déterministe : IDs de périphériques, initramfs et vérification post‑reboot que l’hôte ne pilote pas le GPU.
- Construisez la VM avec des valeurs modernes : Q35 + OVMF + VirtIO. Évitez le chemin nostalgique.
- Stabilisez d’abord, optimisez ensuite : cycles de reboot, démarrages/arrêts de VM, et suspend/reprise (si cela vous intéresse) avant de chasser les microsecondes.
- Écrivez un runbook : les 10 commandes que vous avez utilisées aujourd’hui seront les mêmes à 2 h du matin plus tard.
Si vous faites ces six choses, vous passerez votre temps sur le vrai tuning de performance au lieu de vous disputer avec une case BIOS qui s’est éteinte toute seule.