Ci-dessous, les différences entre deux révisions de la page.
| Les deux révisions précédentesRévision précédenteProchaine révision | Révision précédente | ||
| sysadmin:linux:virtualisation:kvm:configurer-gpu-passthrough [2025/12/17 09:44] – supprimée - modification externe (Date inconnue) 127.0.0.1 | sysadmin:linux:virtualisation:kvm:configurer-gpu-passthrough [2026/01/03 16:09] (Version actuelle) – yoann | ||
|---|---|---|---|
| Ligne 1: | Ligne 1: | ||
| + | {{tag> | ||
| + | |||
| + | : | ||
| + | |||
| + | |||
| + | ====== KVM : Activer le GPU passthrough ====== | ||
| + | |||
| + | L' | ||
| + | |||
| + | Le GPU et les contrôleurs intégrés à la carte graphique additionnelle de l' | ||
| + | |||
| + | < | ||
| + | Dans ce mode de fonctionnement, | ||
| + | </ | ||
| + | |||
| + | |||
| + | ===== Environnement ===== | ||
| + | |||
| + | * Ubuntu 25.10 (questing) | ||
| + | * Linux 6.17.0-8-generic | ||
| + | * libvirtd (libvirt) 11.6.0 | ||
| + | * AMD AMD Ryzen 7 7800X3D ; 32 GO RAM ; carte-mère Asus TUF GAMING X670E-PLUS WIFI | ||
| + | |||
| + | |||
| + | |||
| + | ===== Prérequis ===== | ||
| + | |||
| + | Pour que cela soit possible, le PCI passthrough doit être supporté matériellement : | ||
| + | * Côté processeur : avec les fonctionnalité **VT-d** pour Intel ou **AMD-IOV/ | ||
| + | * Côté carte mère : le **IOMMU**((**I**nput-**O**utput **M**emory **M**anagement **U**nit)) intégré au chipset permet aux périphériques qui en sont capables (GPU, contrôleur réseau, contrôleur de stockage) d' | ||
| + | |||
| + | C'est dans le BIOS de l’hôte qu'il faudra activer ces options. | ||
| + | |||
| + | |||
| + | Pour vérifier que les options de virtualisation nécessaires sont présentes sur le CPU de l’hôte : | ||
| + | |||
| + | Via la commande **lscpu** : | ||
| + | |||
| + | <code bash> | ||
| + | lscpu | grep " | ||
| + | </ | ||
| + | |||
| + | La commande doit retourner : | ||
| + | |||
| + | < | ||
| + | Virtualisation: | ||
| + | Virtualisation: | ||
| + | </ | ||
| + | |||
| + | Via le fichier **''/ | ||
| + | |||
| + | * Pour les processeurs Intel la fonctionnalité de vmx doit être listée ; | ||
| + | * Pour les processeurs AMD la fonctionnalité de virtualisation du processeur est désignée **SVM** ((**S**ecure **V**irtual **M**achine)). | ||
| + | |||
| + | <code bash> | ||
| + | # La commande doit retourner une valeur supérieure à 0 | ||
| + | egrep -c ' | ||
| + | </ | ||
| + | |||
| + | Vérifier que l' | ||
| + | |||
| + | <code bash> | ||
| + | journalctl -b 0 --grep " | ||
| + | </ | ||
| + | |||
| + | ===== Configuration de l’hôte ===== | ||
| + | |||
| + | |||
| + | |||
| + | ==== Rechercher l'ID matériel et le groupe IOMMU ==== | ||
| + | |||
| + | < | ||
| + | Afin qu'il puisse être correctement assigné et utilisé par la VM, le GPU et les périphériques partageant le même groupe IOMMU doivent avoir leur pilote remplacé par le pilote VFIO afin qu'il ne soient pas utilisés par l’hôte. | ||
| + | </ | ||
| + | |||
| + | On cherche d' | ||
| + | |||
| + | <code bash> | ||
| + | # Lister les périphérique PCI en affichant leurs IDs (ID Vendor:ID Device) et le groupe IOMMU | ||
| + | lspci -nn -vmm | ||
| + | </ | ||
| + | |||
| + | Dans l' | ||
| + | |||
| + | <file txt [highlight_lines_extra=" | ||
| + | ... | ||
| + | Slot: | ||
| + | Class: | ||
| + | Vendor: NVIDIA Corporation [10de] | ||
| + | Device: AD104 [GeForce RTX 4070] [2786] | ||
| + | SVendor: | ||
| + | SDevice: | ||
| + | Rev: a1 | ||
| + | ProgIf: 00 | ||
| + | IOMMUGroup: | ||
| + | |||
| + | Slot: | ||
| + | Class: | ||
| + | Vendor: NVIDIA Corporation [10de] | ||
| + | Device: AD104 High Definition Audio Controller [22bc] | ||
| + | SVendor: | ||
| + | SDevice: | ||
| + | Rev: a1 | ||
| + | ProgIf: 00 | ||
| + | IOMMUGroup: | ||
| + | ... | ||
| + | </ | ||
| + | |||
| + | |||
| + | Les identifiants des périphériques correctement déterminés, | ||
| + | |||
| + | Affiche les pilotes utilisés par l’hôte avant modification : | ||
| + | |||
| + | <code bash [highlight_lines_extra=" | ||
| + | lspci -kd 10de:2786 | ||
| + | 01:00.0 VGA compatible controller: NVIDIA Corporation AD104 [GeForce RTX 4070] (rev a1) | ||
| + | Subsystem: Gigabyte Technology Co., Ltd Device 40ed | ||
| + | Kernel driver in use: nvidia | ||
| + | Kernel modules: nvidiafb, nouveau, nvidia_drm, nvidia | ||
| + | </ | ||
| + | |||
| + | Ici on peut voir qu'on utilise le pilote propriétaire nvidia. | ||
| + | |||
| + | ==== Mise à jour du bootloader ==== | ||
| + | |||
| + | On met à jour grub via le fichier ''/ | ||
| + | |||
| + | |||
| + | < | ||
| + | # Mettre à jour la variable sans écraser le contenu existant | ||
| + | GRUB_CMDLINE_LINUX_DEFAULT=" | ||
| + | |||
| + | GRUB_CMDLINE_LINUX_DEFAULT=" | ||
| + | </ | ||
| + | |||
| + | < | ||
| + | Bien renseigner les valeurs des IDs retournés par la commande lspci. | ||
| + | </ | ||
| + | |||
| + | <code bash> | ||
| + | update-grub | ||
| + | </ | ||
| + | |||
| + | ==== Mise à jour de modprobe ==== | ||
| + | |||
| + | Modifier la configuration de modprobe en éditant le fichier ''/ | ||
| + | |||
| + | < | ||
| + | options vfio-pci ids=10de: | ||
| + | </ | ||
| + | |||
| + | Empêcher le chargement des pilotes nvidia en créant le fichier ''/ | ||
| + | |||
| + | < | ||
| + | blacklist nouveau | ||
| + | blacklist nvidia | ||
| + | blacklist nvidia_drm | ||
| + | </ | ||
| + | |||
| + | Redémarrer le système | ||
| + | <code bash> | ||
| + | systemctl reboot | ||
| + | </ | ||
| + | |||
| + | < | ||
| + | Si après redémarrage, | ||
| + | </ | ||
| + | |||
| + | |||
| + | Après redémarrage vérifier les pilotes chargés pour le GPU sur le système hôte | ||
| + | <code bash> | ||
| + | lspci -kd 10de:2786 | ||
| + | </ | ||
| + | |||
| + | On doit obtenir un retour de la forme : | ||
| + | <file conf [highlight_lines_extra=" | ||
| + | 01:00.0 VGA compatible controller: NVIDIA Corporation AD104 [GeForce RTX 4070] (rev a1) | ||
| + | Subsystem: Gigabyte Technology Co., Ltd Device 40ed | ||
| + | Kernel driver in use: vfio-pci | ||
| + | Kernel modules: nvidiafb, nouveau, nvidia_drm, nvidia | ||
| + | </ | ||
| + | |||
| + | < | ||
| + | Si après redémarrage l' | ||
| + | </ | ||
| + | |||
| + | |||
| + | ==== Vérifier les logs ==== | ||
| + | |||
| + | Une fois que l’affichage de l’hôte fonctionne avec la carte intégrée et que la carte additionnelle utilise les pilotes VFIO, le paramétrage coté l’hôte est terminé. | ||
| + | |||
| + | Vérifier cependant les **logs** et les **services** système. Dans le cas présent : | ||
| + | * La command '' | ||
| + | * De nombreux messages sont générés en permanence dans le journal système et son occupation disque croit rapidement. | ||
| + | |||
| + | Exemple de messages : | ||
| + | |||
| + | < | ||
| + | déc. 30 13:19:56 juggernaut kernel: NVRM: No NVIDIA devices probed. | ||
| + | déc. 30 13:19:56 juggernaut kernel: nvidia-nvlink: | ||
| + | déc. 30 13:19:56 juggernaut (udev-worker)[3044]: | ||
| + | déc. 30 13:19:56 juggernaut kernel: nvidia-nvlink: | ||
| + | déc. 30 13:19:56 juggernaut kernel: NVRM: GPU 0000: | ||
| + | déc. 30 13:19:56 juggernaut kernel: NVRM: The NVIDIA probe routine was not called for 1 device(s). | ||
| + | déc. 30 13:19:56 juggernaut kernel: NVRM: This can occur when another driver was loaded and | ||
| + | NVRM: obtained ownership of the NVIDIA device(s). | ||
| + | déc. 30 13:19:56 juggernaut kernel: NVRM: Try unloading the conflicting kernel module (and/or | ||
| + | NVRM: reconfigure your kernel without the conflicting | ||
| + | NVRM: driver(s)), then try loading the NVIDIA kernel module | ||
| + | NVRM: again. | ||
| + | </ | ||
| + | |||
| + | |||
| + | Comme la carte n'est plus utilisée directement par l’hôte, on désinstalle les pilotes propriétaire nvidia : | ||
| + | |||
| + | <code bash> | ||
| + | # Lister les paquets installés | ||
| + | apt list --installed | grep nvidia | ||
| + | |||
| + | # Suppression des paquets installés | ||
| + | apt remove --purge nvidia-* | ||
| + | apt autoremove --purge | ||
| + | </ | ||
| + | |||
| + | |||
| + | |||
| + | ===== Configuration de la VM ===== | ||
| + | |||
| + | : | ||
| + | |||
| + | < | ||
| + | virt-install --name=" | ||
| + | --metadata title=" | ||
| + | --vcpus=8 \ | ||
| + | --memory=16384 \ | ||
| + | --osinfo=debian13 \ | ||
| + | --features kvm_hidden=on \ | ||
| + | --machine q35 \ | ||
| + | --disk path=/ | ||
| + | --cdrom=/ | ||
| + | --graphics spice \ | ||
| + | --video virtio \ | ||
| + | --network network=default, | ||
| + | --console pty, | ||
| + | --hostdev pci_0000_01_00_0 \ | ||
| + | --hostdev pci_0000_01_00_1 \ | ||
| + | --wait -1 | ||
| + | </ | ||
| + | |||
| + | |||
| + | ===== Dépannage ===== | ||
| + | |||
| + | ==== GPU hôte non isolé ==== | ||
| + | |||
| + | |||
| + | Dans un premier temps, on essaie de modifier la configuration de modprobe en tentant de charger le pilote vfio au moment où udev charge les pilotes du GPU. C'est la méthode recommandée car ainsi on n’agrandit pas initramfs en y ajoutant des pilotes. | ||
| + | |||
| + | Dans le fichier ''/ | ||
| + | |||
| + | < | ||
| + | softdep drm pre: vfio-pci | ||
| + | </ | ||
| + | |||
| + | Pour les pilotes propriétaires nvidia : | ||
| + | < | ||
| + | softdep nvidia pre: vfio-pci | ||
| + | </ | ||
| + | |||
| + | Pour exemple le fichier après modification : | ||
| + | |||
| + | < | ||
| + | softdep nvidia pre: vfio-pci | ||
| + | options vfio-pci ids=10de: | ||
| + | </ | ||
| + | |||
| + | Si après redémarrage les pilotes vfio ne sont toujours pas chargés pour le GPU, il faudra modifier initramfs. | ||
| + | |||
| + | === Modification du initramfs via dracut === | ||
| + | |||
| + | Ubuntu utilise dracut pour générer/ | ||
| + | |||
| + | < | ||
| + | force_drivers+=" | ||
| + | </ | ||
| + | |||
| + | Mettre à jour initramfs : | ||
| + | |||
| + | <code bash> | ||
| + | update-initramfs -u | ||
| + | systemctl reboot | ||
| + | </ | ||
| + | |||
| + | < | ||
| + | C'est cette modification qui a fonctionné pour mon système hôte. | ||
| + | </ | ||
| + | |||
| + | |||
| + | ===== Références ===== | ||
| + | |||
| + | * [[https:// | ||
| + | * [[https:// | ||
| + | * [[https:// | ||
| + | * [[https:// | ||
| + | * [[https:// | ||
| + | * https:// | ||
| + | * [[https:// | ||