GPU Passthrough: Linux et Windows ensemble, sans redémarrage

Linux et Windows en même temps, sans soucis de performance, possible, mais à quel prix?

MAJ 23/06 : Merci au sémillant Jaazyl du canal Discord Linux café pour le signalement d’une coquille dans un fichier de conf, qui est maintenant corrigée 🙂

C’est un peu la greffe contre-nature. Les deux anciens ennemis, fonctionnant de concert, avec un passage de l’un à l’autre quasi transparent. Ce qui s’apparente à créer informatiquement parlant un Frankenstein est possible, et fonctionne même très bien ! Les champs d’applications sont multiples. Tout ce qui foire ou boite sur Linux est dorénavant possible.

Il faudra malgré tout respecter quelques contraintes concernant l’équipement matériel. En effet, nous utiliserons pour cela la technologie bien connue des Machines Virtuelles, saupoudrée de quelques customisations possibles grâce à la souplesse de Linux. Après divers tests, recherches sur le net, plantages et litres de café, j’ai pu isoler une solution pour créer le Monstre, assez rapidement.

Prérequis :

  • Un ensemble processeur (assez costaud) + carte mère proposant les extensions de virtualisation et VT-D, ou équivalent pour AMD.
  • Minimum 16 Go de ram (8 pour Linux, 8 pour Windows, s’il est destiné pour le jeu, à adapter suivant les besoins, mais 16 Go permet d’être confortable).
  • 2 écrans, ou plus. C’est possible de le faire avec un seul à condition qu’il propose plusieurs sorties, mais c’est moins pratique.
  • 2 GPU. Dans l’idéal, un combo GPU intégré + “gros” GPU. Avoir 2 GPU non intégrés est possible aussi. Note que le GPU doit supporter l’UEFI (la grosse majorité de GPU sortis il y a moins de 5 ans le font).
  • Un 2e ensemble clavier-souris (au cas où, normalement pas nécessaire), afin de faciliter le paramétrage. Notez qu’un passthrough avec un laptop équipé d’optimus a l’air d’être possible, mais ce ne sera pas montré ici.
  • Une ISO de Windows.
  • L’ISO des drivers vfio de chez Red Hat

Observations :

  • Linux et Windows ne se serviront pas de la même source audio. En revanche, il est possible d’attribuer une source par système. Dans mon cas, le son venant de Windows sort par les haut parleurs, Linux dans le casque ou les HP des écrans. Il est possible de customiser un peu tout ça en faisant passer le périphérique de sortie audio voulu pour Windows en passthrough.
  • Le copier/coller entre systèmes est fonctionnel, en revanche, un des logiciels utilisés propose le partage de fichiers en “drag and drop”, mais je n’ai pas réussi à le faire fonctionner. Le souci peut aisément être contourné en copiant d’abord les fichiers voulus dans une clé ou un autre disque, que l’on attachera à la VM Windows, ou par des partages Samba.
  • Dans la catégorie trucs importants, l’interface chaise-clavier (toi qui lis cet article). Il faut savoir un peu manier de la ligne de commande et connaitre suffisamment pour adapter les commandes si nécessaire.
  • Bien que cette manip’ soit possible avec n’importe quelle distro Linux, ce tuto se concentre sur la distribution Ubuntu, et ses dérivés proches, simplement parce que les manips ont été faites sur ce système. Si t’as déjà rien compris à ce que je raconte précédemment, il faudra aller réviser quelques bases du shell 🙂
  • Il serait également possible de récupérer l’usage du GPU utilisé par Windows une fois la VM éteinte moyennant des manips supplémentaires et une déconnexion de session, mais je n’ai pas expérimenté, et par conséquent, ce ne sera pas décrit ici.
  • Il sera ici traité de la configuration pour Ubuntu sur une plateforme Intel + nVidia. Il est tout à fait possible de faire de même sur des plateformes AMD (CPU) + nVidia, et AMD + AMD, moyennant quelques adaptations pour la configuration aisément trouvables sur le net.

Bon on y va, non?

Doucement mon p’tit. Avant de briller en société virtuellement parlant, il faudra mettre les mains dans le cambouis, et peut être aller chercher deux trois conneries chez ton marchand de pièces favori.

Hardware

Dans la pratique, il faudra brancher l’écran voulu pour Linux sur la prise vidéo de la carte mère, et l’écran dédié a Windows sur le GPU voulu pour Windows. Note qu’une variante que j’utilise est possible : Si la carte mère (ou le GPU pour linux) et l’écran possèdent plusieurs sources vidéo, il est possible d’utiliser la permutation des sources vidéo pour garder un 2e écran pour Linux, et passer à Windows en switchant de sortie. Dans mon cas on est sur du :
-Linux: Ecran1-HDMI + Ecran2-DP (les 2 branchés aux ports de la carte mère
-Windows: Ecran2-HDMI GPU (je passe de Linux a Windows en changeant la source vidéo avec les boutons physiques de mon écran 2)

Pour ceux qui n’ont rien compris au précédent paragraphe, un schéma fait vite fait avec GIMP permettra d’y voir plus clair.

Pense également à régler correctement dans le bios, si ce n’est pas déjà fait, l’activation des options de virtualisation et le GPU par défaut (devant être celui “branché” sur linux).

Software

Une fois l’enchevêtrement de câbles (et de nœuds) réalisé, il est temps de passer aux choses sérieuses. Démarre donc ce fringant Linux, et on commence à ouvrir un terminal.

sudo apt install qemu-kvm libvirt-clients libvirt-daemon-system virt-manager ovmf

On installe donc le logiciel de virtualisation et quelques utilitaires.
Ensuite, on, le cas échéant, blackliste certains drivers qui peuvent parasiter. Dans mon cas, et celui d’une carte nVidia pour windows :

sudo nano /etc/modprobe.d/blacklist-nouveau.conf

---On y entre ceci

blacklist nouveau
options nouveau modeset=0

Ensuite, il faudra modifier la configuration du gestionnaire de démarrage

sudo nano /etc/default/grub

On ajoute "intel_iommu=on" à la ligne GRUB_CMDLINE_LINUX_DEFAULT="quiet splash ..."
Ce qui donne : 

GRUB_CMDLINE_LINUX_DEFAULT="quiet splash intel_iommu=on"

Pour rendre les changements effectifs : un p’tit “sudo update-grub” fera le travail.

Il va falloir maintenant identifier la carte graphique dédiée à Windows. Pour cela, entre dans le terminal :

lspci -nn | grep -i nvidia 

Note bien précieusement quelque part les caractères entre crochets ( le [10de:xxxx]) des deux lignes, on en aura besoin par la suite.

On crée maintenant un nouveau fichier :

sudo nano /etc/modprobe.d/vfio.conf

et on y ajoute ceci :

options vfio-pci ids=abcd:1234,efgh:5678 (a adapter avec les deux suites de caractères notées précédemment)
Voici ce que ça donne dans mon cas : le 1er ID est celui de la carte graphique, l’autre celui de la partie audio controller : les 2 sont nécessaires, séparés par la virgule

Un p’tit one liner dans le terminal afin de charger le module au démarrage :

sudo echo 'vfio-pci' > /etc/modules-load.d/vfio-pci.conf

Et on régénère l’initramfs. Pour ubuntu, cela donne

sudo update-initramfs -u

Et on redémarre. Un souci peut se poser ici :

Au redémarrage, il n’y a pas d’affichage : Ceci est souvent dû à une mauvaise configuration de la source vidéo dans l’UEFI. Pensez a régler la source vidéo principale sur celle définie pour linux (dans mon cas : onboard graphics, un équivalent est peut être proposé suivant les cartes mère.

Une fois redémarré, on va faire quelques vérifications :

dmesg | grep iommu
et
dmesg | grep vfio

doit retourner quelques lignes

Pour valider le fonctionnement, le résultat de l’incantation précédente doit ressembler à ça

On stoppe avec le terminal pour le moment ! Il est temps de lancer virt-manager (Gestionnaire de machines virtuelles dans ton Desktop Environment chéri) et de créer la machine virtuelle.

Exemple pour mon cas : I7 8700K, 32Go de RAM et GTX 1070Ti

  • Etape 1: Média d’installation local
  • Etape 2: On coche “Utiliser une image ISO” et on sélectionne l’ISO de windows
  • Etape 3: Personnellement, j’alloue la moitié de la RAM totale disponible. Laisse le nombre de CPU comme il l’est pour le moment, on customisera ça comme il faut tout à l’heure
  • Etape 4: On peut définir la taille du disque virtuel pour windows, ou créer des volumes de stockages personnalisés (aussi utiliser des disques entiers)
  • Etape 5: Baptise ton FranckenDows comme tu veux. J’ai pas donné un nom trop compliqué afin de faciliter la configuration par la suite.
    Avant de valider, on branche le 2e ensemble clavier/souris et on coche la case “personnaliser la configuration avant l’installation”
La configuration des volumes de stockage. Ici, un SSD entier est dédié à Windows
Voici à quoi ressemble la dernière étape. Il n’y a que 2 Go d’attribué car c’est une VM temporaire pour le tutorial.

Courage, la pause café arrive bientôt ! Maintenant, on va configurer plus en détail la machine virtuelle.

Champs textuels au choix.
Microprogramme sur l’entrée avec UEFI
Chipset : Q35

Réglages CPU pour mon cas (6 cœurs/12 threads)
Allocation actuelle : 10 (correspondant à 5 cœurs ayant chacun 2 threads (dénommé Chaînes plus bas). Ce réglage permet de garder 1 cœur pour l’hôte Linux.
Modèle : host-passthrough. Afin de profiter de profiter du maximum des instructions de son CPU
Topologie : A adapter en fonction du matériel

Il faudra également reconfigurer le disque 1, en sélectionnant virtio comme bus, SATA pour le bus CDROM, et aller chercher l’iso de windows 10.

Il faudra également créer un 2e lecteur virtuel, en cliquant sur ajouter un matériel. Prendre stockage, sélectionner l’iso des drivers téléchargée plus tôt, type de périphérique CDROM

On peut cliquer ensuite sur commencer l’installation.
Ça ouvrira la VM dans une fenêtre, c’est voulu afin de procéder à quelques étapes avant d’effectuer le passthrough à proprement parler.
Il sera sûrement nécessaire de charger le pilote viostor (dans l’ISO des drivers) lors de l’arrivée sur l’écran de partitionnement afin que le volume de stockage pour l’installation soit reconnu.

Il est enfin temps de prendre un petit café en attendant que l’installation de Windows se fasse.

Une fois l’installation finie, on coupe la VM, et on retourne dans l’écran principal de virt-manager, édition, puis détail de la connexion.
Il s’agit ensuite de virer le réseau par défaut, et de configurer un nouveau réseau, avec les IP adaptées à sa configuration. Personnellement, j’ai opté pour : hôte en 192.168.x.x, Windows dans 192.168.x+1.x, NAT vers mon interface réseau ethernet. Il est possible de créer un pont, mais chez moi, cela ralentit voire coupe la connexion au moment de la connexion du pont.

On retourne dans les réglages de la VM et dans la partie NIC on sélectionne le réseau nouvellement créé.

Il faudra ensuite installer Barrier, pour la gestion clavier/souris sur Windows et Linux.
Pour Windows, cela se fera directement dans la VM, avec l’exécutable fourni.
Pour Linux, il existe un flatpak….qui ne fonctionne pas. Pas de panique, on va compiler mais ce sera pas douloureux.

sudo apt install git cmake make xorg-dev g++ libcurl4-openssl-dev \
                 libavahi-compat-libdnssd-dev libssl-dev libx11-dev \
                 libqt4-dev qtbase5-dev

git clone https://github.com/debauchee/barrier.git (on récupère les sources du logiciel)

cd barrier

./clean_build.sh

sudo make install (installation directe) ou sudo checkinstall (étapes supplémentaires pour créer un paquet .deb)

Une fois installé des deux côtés, paramétrons le serveur, côté Linux :

Dans Windows, Barrier est en mode client. Spécifie l’adresse IP de l’hôte Linux. Lance le serveur, et le client, et si dans les logs côté Linux (menu barrier, logs) quelque chose comme “client “votre écran win” has connected” apparaît, c’est tout bon. Suivant la topologie configurée sur le serveur, faire “sortir” le curseur du côté de l’écran Windows fera apparaître le curseur sur windows.

Après s’être assuré que tout soit OK, éteins la VM, double clic dessus pour ouvrir la configuration, on ajoute la carte graphique ainsi que la partie audio de celle-ci, ainsi que tout périphérique USB utile (manettes pour le cas de jeux), et autres périphériques, selon l’envie.

On est reparti en ligne de commande, pour que le son soit correctement géré :

sudo nano /etc/libvirt/qemu.conf
Décommenter user = "example" et remplacer example par son utilisateur Linux
Décommenter vnc_allow_host_audio et le passer de 0 à 1
Décommenter nographics_allow_host_audio et le passer de 0 à 1

sudo nano /etc/pulse/daemon.conf
Décommenter default-sample-rate = 44100 et alternate-sample-rate = 48000

sudo virsh edit TaVM
Au début du fichier, remplacer <domain type='kvm'> par <domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
Ajouter à la fin du fichier; entre </devices> et </domain>
<qemu:commandline>
  <qemu:env name='QEMU_AUDIO_DRV' value='pa'/>
  <qemu:env name='QEMU_PA_SAMPLES' value='8192'/>
  <qemu:env name='QEMU_AUDIO_TIMER_PERIOD' value='99'/>
  <qemu:env name='QEMU_PA_SERVER' value='/run/user/1000/pulse/native'/>
</qemu:commandline>

Pour les possesseurs de cartes nVidia, petit bonus, afin de ne pas se manger un écran bleu au démarrage :

sudo virsh edit TaVM
Ajouter en dessous de <features>
    <hyperv>
      <vendor_id state='on' value='cequetuveux'/>
    </hyperv>
    <kvm>
      <hidden state='on'/>
    </kvm>

Car nVidia bloque l’utilisation de ses cartes grand public pour ce genre de manip. Il n’y a aucune contre-indication, c’est juste pour faire acheter des Quadro, carte professionnelles…

Il est temps maintenant de prier si t’es croyant, de croiser tout ce que t’as en doigts. Si tout s’est bien goupillé, un Windows démarrera sur son écran dédié, et il sera possible d’installer les drivers de sa carte graphique. La souris sera également gérée, et on passera d’un système à l’autre en baladant le curseur vers l’autre écran. Le clavier sera actif sur le système dans lequel se trouve la souris. Pour les adeptes de ma variante proposée plus haut, ce sera la même chose, sauf qu’il faudra changer de source vidéo sur l’écran Linux2/Windows (et dans le cas ou Windows n’a pas son écran dédié uniquement à lui)

Le résultat final : Un Linux et un Windows, les deux exploitant pleinement leur matériel dédié.

Point particulier : Il est nécéssaire de stopper et redémarrer le serveur Barrier sous Linux entre 2 lancements de VM Windows. Cela peut se faire facilement avec l’interface graphique ou l’icône dans la barre de notifications.

Pour les jeux, afin que la souris ne soit pas prise de mouvements convulsifs: En étant dans Windows, appuies sur la touche “Arrêt défil” ou “Scroll Lock” du clavier pour verrouiller le curseur dans Windows. Pour déverrouiller, c’est la même touche.

Il est possible maintenant de profiter d’un Windows sans redémarrer le PC, et sans compromis côté 3D ou traitements lourds. A toi maintenant les fières parties de jeu jusque tard le soir! (ou toute autre activité bloquante sur Linux).

J'aime
error0

4 réflexions au sujet de « GPU Passthrough: Linux et Windows ensemble, sans redémarrage »

  1. Merci pour cet article très interessant, j’envisage justement de changer de configuration pour profiter du Passthrough.

    Petite question, est-il vraiment nécessaire de diposer d’un cpu très performance. Linux ne consommant pas beacoups de ressources je me demande s’il est possible de réaliser cette configuraiton à partir d’un Ryzen-3 2300X, voir Ryzen 5-2600.

    Autre interrogation, pour relier les cartes graphiques aux écrans, est-il possible d’utiliser un hub hdmi pour réaliser le branchement suivant:
    Ecran1 -> HUB HDMI -> GPU INTEGRE
    -> GPU DEDIE

    En appuyant sur le bouton de l’hub hdmi, on passe de Linux à Windows sur Ecran1.

    Merci d’avance,

    1. C’est quand même mieux d’avoir un cpu costaud. Faut quand même gérer 2 systèmes. Je serais toi, je partirais sur un ryzen 5 histoire d’être sûr d’avoir ce qu’il faut en terme de patate.

      Tu peux utiliser un hub HDMI,il n’y a aucun souci

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Anti-Robots *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.