KVM, passthrough PCI, Looking Glass et tout-tout

Après une transition réussie vers les développeurs de logiciels Linux, le moment est venu de travailler un peu et a également changé le système d'exploitation principal. Des inquiétudes ont été causées par les logiciels de nécro-plateforme pour soutenir les projets existants. Une partie du logiciel fonctionnait à travers le vin. Cependant, il s'est avéré que certains logiciels refusent de travailler sous le vin. Il a été décidé d'exécuter le logiciel sur la machine virtuelle QEMU + KVM. Le logiciel a commencé à fonctionner, mais y travailler était plutôt gênant. Les performances des cartes vidéo virtuelles logicielles ne diffèrent pas et la prise en charge des graphiques 3D est très modeste. J'ai dû découvrir le tambourin et chercher une issue.

Allouez une carte vidéo distincte au système invité!


Il n'a pas fallu longtemps pour trouver une issue, mais l'idée de frapper un tambourin avec un projecteur s'est avérée très étrange. En ce qui concerne le transfert de cartes vidéo vers une machine virtuelle, Internet regorge d'instructions de différentes époques et pour différents matériels. Qu'est-ce qu'un énorme article sur le site Arch Linux [0] . Je vais vous donner une version abrégée des instructions pour transférer une carte vidéo.

0. Vérifiez que le matériel prend en charge IOMMU


Par exemple, ici [1] .

1. Nous incluons le support de IOMMU dans un noyau.


chat / etc / default / grub
GRUB_CMDLINE_LINUX_DEFAULT = "splash silencieux amd_iommu = on"
ou
GRUB_CMDLINE_LINUX_DEFAULT = "splash silencieux intel_iommu = on"


N'oubliez pas sudo update-grub .

2. Nous sélectionnons la carte vidéo du pilote


Nous recherchons les périphériques nécessaires et voyons quels pilotes les utilisent.

lspci -nnk
04: 00.0 Contrôleur compatible VGA [0300]: NVIDIA Corporation GT218 [GeForce 210] [ 10de: 0a65 ] (rev a2)
Pilote du noyau en cours d'utilisation: nouveau
Modules du noyau: nvidiafb, nouveau
04: 00.1 Périphérique audio [0403]: Contrôleur audio haute définition NVIDIA Corporation [ 10de: 0be3 ] (rev a1)
Pilote du noyau en cours d'utilisation: snd_hda_intel
Modules du noyau: snd_hda_intel


Ajoutez des modules VFIO afin qu'ils soient chargés au démarrage.

cat / etc / modules | grep vfio
vfio
vfio_iommu_type1
vfio_pci
vfio_virqfd


Nous configurons le module VFIO pour qu'il intercepte les périphériques, empêchant le chargement des pilotes principaux. Si nécessaire, ajoutez à la liste noire le pilote principal.

cat /etc/modprobe.d/vfio.conf
options vfio-pci ids = 10de: 0a65,10de: 0be3
liste noire nouveau


3. Redémarrez et vérifiez que tout a fonctionné


IOMMU s'est allumé.

dmesg | grep -e DMAR -e IOMMU -e AMD-Vi
DMAR: technologie de virtualisation Intel® pour les E / S dirigées
ou
AMD-Vi: IOMMU trouvé à 0000: 00: 00.2 cap 0x40
AMD-Vi: remappage d'interruption activé
AMD-Vi: rinçage paresseux IO / TLB activé


Les appareils composites faisaient partie d'un groupe.

pour un fichier dans / sys / kernel / iommu_groups / *; trouver $ a -type l; fait | sort --version-sort
/sys/kernel/iommu_groups/15/devices/0000:01:00.0
/sys/kernel/iommu_groups/15/devices/0000:01:00.1
/sys/kernel/iommu_groups/16/devices/0000:02:00.0
/sys/kernel/iommu_groups/17/devices/0000:03:00.0
/sys/kernel/iommu_groups/18/devices/0000:04:00.0
/sys/kernel/iommu_groups/18/devices/0000:04:00.1


Pilotes KVM et VFIO chargés.

lsmod | grep -e kvm -e vfio
 kvm_amd 94208 0
 ccp 90112 1 kvm_amd
 kvm 622592 1 kvm_amd
 vfio_pci 45056 0
 vfio_virqfd 16384 1 vfio_pci
 irqbypass 16384 2 vfio_pci, kvm
 vfio_iommu_type1 24576 0
 vfio 28672 2 vfio_iommu_type1, vfio_pci


Carte vidéo pour OS invité capturée par VFIO.

lspci -nnk
04: 00.0 Contrôleur compatible VGA [0300]: NVIDIA Corporation GT218 [GeForce 210] [ 10de: 0a65 ] (rev a2)
Pilote du noyau en cours d'utilisation: vfio-pci
Modules du noyau: nvidiafb, nouveau
04: 00.1 Périphérique audio [0403]: Contrôleur audio haute définition NVIDIA Corporation [ 10de: 0be3 ] (rev a1)
Pilote du noyau en cours d'utilisation: vfio-pci
Modules du noyau: snd_hda_intel


4. Configurez QEMU et lancez le système d'exploitation invité


Installer, s'il n'est pas déjà installé
sudo apt install qemu-kvm qemu-utils seabios ovmf virt-viewer

Créer un disque sur lequel le système d'exploitation invité sera installé
qemu-img create -f raw -o preallocation = full guest.img 50G
ou
fallocate -l 50G guest.img

Nous démarrons la machine virtuelle sans transférer la carte vidéo pour installer le système d'exploitation invité. Puisqu'il y a une vue sur Looking Glass, pour l'invité, il vaut la peine de choisir Windows 10. Windows 8 / 8.1 selon les dernières données est également pris en charge.

vga_qxl.sh
#! / bin / bash
épice pour téléspectateur: //127.0.0.1: 5900 &
sudo qemu-system-x86_64 \
-machine q35, accel = kvm \
-enable-kvm \
-cpu host, kvm = off, check \
-smp cpus = 2, sockets = 1, cores = 2, threads = 1 \
-m 6G \
-rtc base = heure locale, horloge = hôte \
-device piix3-usb-uhci \
-device usb-tablet \
-drive if = pflash, format = raw, readonly, file = / usr / share / OVMF / OVMF_CODE.fd \
-drive file = 'w10.iso', if = ide, format = raw, index = 2, media = cdrom, cache = none \
-drive file = 'virtio-win-0.1.141_st.iso', if = ide, format = raw, index = 3, media = cdrom, cache = none \
-drive file = 'guest.img', if = ide, format = raw, index = 4, media = disk, cache = writeback \
-vga qxl \
-pice port = 5900, addr = 127.0.0.1, disable-ticketing \
-monitor stdio \
-netdev user, id = n1, ipv6 = off, smb = "/ media / user / data" \
-device e1000, netdev = n1, mac = 67: 77: 78: 88: 89: 99 \
"$ @"

5. Nous transmettons la carte vidéo à l'OS invité


Pour commencer, démarrez avec deux cartes vidéo. Nous vérifions que la carte transmise est apparue dans le système, y avons placé les pilotes et nous nous assurons qu'ils fonctionnent.

vga_qxl_pass.sh
#! / bin / bash
épice pour téléspectateur: //127.0.0.1: 5900 &
sudo qemu-system-x86_64 \
-machine q35, accel = kvm \
-enable-kvm \
-cpu host, kvm = off, check \
-smp cpus = 2, sockets = 1, cores = 2, threads = 1 \
-m 6G \
-rtc base = heure locale, horloge = hôte \
-device piix3-usb-uhci \
-device usb-tablet \
-drive if = pflash, format = raw, readonly, file = / usr / share / OVMF / OVMF_CODE.fd \
-drive file = 'virtio-win-0.1.141_st.iso', if = ide, format = raw, index = 3, media = cdrom, cache = none \
-drive file = 'guest.img', if = ide, format = raw, index = 4, media = disk, cache = writeback \
-vga qxl \
-pice port = 5900, addr = 127.0.0.1, disable-ticketing \
-device ioh3420, bus = pcie.0, addr = 1c.0, multifonction = on, port = 1, chassis = 1, id = root \
-device vfio-pci, host = 04: 00.0, bus = root, addr = 00.0, multifunction = on \
-device vfio-pci, host = 04: 00.1, bus = root, addr = 00.1 \
-monitor stdio \
-netdev user, id = n1, ipv6 = off, smb = "/ media / user / data" \
-device e1000, netdev = n1, mac = 67: 77: 78: 88: 89: 99 \
"$ @"

Après le fonctionnement de la carte vidéo transférée et dans le gestionnaire de périphériques écrit «Le périphérique fonctionne correctement», nous démarrons la machine virtuelle uniquement avec la carte vidéo transférée.

vga_pass.sh
#! / bin / bash
sudo qemu-system-x86_64 \
-machine q35, accel = kvm \
-enable-kvm \
-cpu host, kvm = off, check \
-smp cpus = 2, sockets = 1, cores = 2, threads = 1 \
-m 6G \
-rtc base = heure locale, horloge = hôte \
-device piix3-usb-uhci \
-device usb-tablet \
-drive if = pflash, format = raw, readonly, file = / usr / share / OVMF / OVMF_CODE.fd \
-drive file = 'virtio-win-0.1.141_st.iso', if = ide, format = raw, index = 3, media = cdrom, cache = none \
-drive file = 'guest.img', if = ide, format = raw, index = 4, media = disk, cache = writeback \
-vga aucun \
-device ioh3420, bus = pcie.0, addr = 1c.0, multifonction = on, port = 1, chassis = 1, id = root \
-device vfio-pci, host = 04: 00.0, bus = root, addr = 00.0, multifunction = on \
-device vfio-pci, host = 04: 00.1, bus = root, addr = 00.1 \
-monitor stdio \
-netdev user, id = n1, ipv6 = off, smb = "/ media / user / data" \
-device e1000, netdev = n1, mac = 67: 77: 78: 88: 89: 99 \
"$ @"

Nous y connectons un moniteur et admirons l'image de bureau de l'OS invité.

L'endroit où les décisions simples se terminent


Et puis le plaisir commence. Quelqu'un, tout va bien, l'image est partie et tout est simple. Mon expérience a trébuché deux fois au stade du manque d'image. La première fois a été la transmission de la carte graphique intégrée du processeur Intel 6700T HD 530, les sorties vidéo étaient vides et l'échec était dû au fait que les plug-ins ne fonctionnaient pas bien. La deuxième fois, le Nvidia GF210 externe a été renversé, qui avait déjà été spécialement acheté pour les expériences. Le résultat était encore plus intéressant. En mode non EFI, la carte vidéo a été transférée avec succès et a même montré une image, mais la désactivation du système d'exploitation invité a échoué .

Le transfert ultérieur pourrait simplement bloquer l'hôte. Quelques heures de recherche facile sur Google mènent au fait que le problème du gel d'une carte vidéo est assez courant. Cela entraîne un arrêt incorrect de la machine virtuelle et, avec une certaine chance, même un arrêt correct. En sortie, il est recommandé de transmettre en mode EFI. Mais VBIOS Nvidia GF210 ne prend pas en charge EFI ...

Coudre ou ne pas coudre, telle est la question


Ne cousez pas. QEMU prend en charge l'usurpation d'identité VBIOS lors du transfert d'une carte vidéo. Mais VBIOS doit encore apprendre à prendre en charge le mode EFI. Il est généralement recommandé de vérifier cela avant de commencer le transfert de la carte vidéo, par exemple ici [2] . Mais il faut faire face à ce qui est, et ne voulait pas chercher une nouvelle carte vidéo avec support EFI. Vous devez donc patcher VBIOS. Toutes les opérations effectuées avec VBIOS se font à vos propres risques. J'ai utilisé un progiciel et des instructions à partir d'ici [3] . Après avoir lu VBIOS, nous obtenons le fichier gt210.rom , patch et à la sortie, nous avons gt210_uefi.rom . C'est là que vous devez glisser la carte vidéo lors du chargement de la machine virtuelle.

vga_pass_rom.sh
#! / bin / bash
sudo qemu-system-x86_64 \
-machine q35, accel = kvm \
-enable-kvm \
-cpu host, kvm = off, check \
-smp cpus = 2, sockets = 1, cores = 2, threads = 1 \
-m 6G \
-rtc base = heure locale, horloge = hôte \
-device piix3-usb-uhci \
-device usb-tablet \
-drive if = pflash, format = raw, readonly, file = / usr / share / OVMF / OVMF_CODE.fd \
-drive file = 'virtio-win-0.1.141_st.iso', if = ide, format = raw, index = 3, media = cdrom, cache = none \
-drive file = 'guest.img', if = ide, format = raw, index = 4, media = disk, cache = writeback \
-vga aucun \
-device ioh3420, bus = pcie.0, addr = 1c.0, multifonction = on, port = 1, chassis = 1, id = root \
-device vfio-pci, host = 04: 00.0, bus = root, addr = 00.0, multifunction = on, romfile = gt210_uefi.rom \
-device vfio-pci, host = 04: 00.1, bus = root, addr = 00.1 \
-monitor stdio \
-netdev user, id = n1, ipv6 = off, smb = "/ media / user / data" \
-device e1000, netdev = n1, mac = 67: 77: 78: 88: 89: 99 \
"$ @"

Nous démarrons la machine virtuelle et regardons.

Obscurité


Les sorties de la carte vidéo brillaient dans le noir. Une fois de plus, la morale a passé l'épreuve de l'échec. La première chose qui me vient à l'esprit est que le système d'exploitation invité se bloque au démarrage. Journaux, j'ai besoin de ses journaux. Pour ce faire, exécutez vga_qxl.sh . Nous regardons le lancement précédent. Et là tout va bien, sauf que la nourriture a été fortement tirée. Il s'avère que cela fonctionne, bien que cela ne fonctionne pas. La première idée était de se connecter via RDP et de voir ce qui s'y passe, mais il est toujours préférable d'utiliser VNC, par exemple tightvnc [4] . Nous installons VNC, configurons le port 5600 et transmettons ce port pour l'accès à partir de l'hôte.

vga_vnc_pass_rom.sh
#! / bin / bash
sudo qemu-system-x86_64 \
-machine q35, accel = kvm \
-enable-kvm \
-cpu host, kvm = off, check \
-smp cpus = 2, sockets = 1, cores = 2, threads = 1 \
-m 6G \
-rtc base = heure locale, horloge = hôte \
-device piix3-usb-uhci \
-device usb-tablet \
-drive if = pflash, format = raw, readonly, file = / usr / share / OVMF / OVMF_CODE.fd \
-drive file = 'virtio-win-0.1.141_st.iso', if = ide, format = raw, index = 3, media = cdrom, cache = none \
-drive file = 'guest.img', if = ide, format = raw, index = 4, media = disk, cache = writeback \
-vga aucun \
-device ioh3420, bus = pcie.0, addr = 1c.0, multifonction = on, port = 1, chassis = 1, id = root \
-device vfio-pci, host = 04: 00.0, bus = root, addr = 00.0, multifunction = on, romfile = gt210_uefi.rom \
-device vfio-pci, host = 04: 00.1, bus = root, addr = 00.1 \
-monitor stdio \
-utilisateur netdev, id = n1, hostfwd = tcp: 127.0.0.1: 5600-: 5600, ipv6 = off, smb = "/ media / user / data" \
-device e1000, netdev = n1, mac = 67: 77: 78: 88: 89: 99 \
"$ @"

Nous connectons et voyons la machine qui fonctionne, seul le moniteur a un étrange moniteur générique non-PnP (le moniteur universel n'est pas PnP). Il y a une image, vous pouvez donc essayer de lancer Looking Glass.

Miroir


Bien que cette technologie utilise OpenGL, aucun espace n'est nécessaire après gl. Mais vous devez lire les instructions [5] sur le site Web du projet. Pour le système d'exploitation invité, téléchargez l'application de capture d'écran looking-glass-host.exe [6] , téléchargez et installez Microsoft Visual C ++ 2015 Redistributable [7] , téléchargez le pilote du périphérique IVSHMEM [8] . Pour l'hôte, nous ajoutons des dépendances, téléchargeons et construisons l'application cliente.

build_looking_glass_a12.sh
#! / bin / bash
sudo apt-get install cmake libsdl2-dev libsdl2-ttf-dev nettle-dev libspice-protocol-dev libfontconfig1-dev libx11-dev fonts-freefont-ttf libconfig-dev
wget github.com/gnif/LookingGlass/archive/a12.tar.gz
tar -xf a12.tar.gz
cd LookingGlass-a12
client / build mkdir
client / build cd
cmake ../
faire

Nous démarrons la machine virtuelle avec le périphérique IVSHMEM. La taille de mémoire de 32 Mo est sélectionnée pour une résolution de 1920 x 1080.

vga_vnc_lg_pass_rom.sh
#! / bin / bash
si [! -f / dev / shm / mirroir]; alors
tactile / dev / shm / miroir
chown `whoami`: kvm / dev / shm / miroir
chmod 660 / dev / shm / miroir
fi
sudo qemu-system-x86_64 \
-machine q35, accel = kvm \
-enable-kvm \
-cpu host, kvm = off, check \
-smp cpus = 2, sockets = 1, cores = 2, threads = 1 \
-m 6G \
-rtc base = heure locale, horloge = hôte \
-device piix3-usb-uhci \
-device usb-tablet \
-drive if = pflash, format = raw, readonly, file = / usr / share / OVMF / OVMF_CODE.fd \
-drive file = 'virtio-win-0.1.141_st.iso', if = ide, format = raw, index = 3, media = cdrom, cache = none \
-drive file = 'guest.img', if = ide, format = raw, index = 4, media = disk, cache = writeback \
-vga aucun \
-device ioh3420, bus = pcie.0, addr = 1c.0, multifonction = on, port = 1, chassis = 1, id = root \
-device vfio-pci, host = 04: 00.0, bus = root, addr = 00.0, multifunction = on, romfile = gt210_uefi.rom \
-device vfio-pci, host = 04: 00.1, bus = root, addr = 00.1 \
-device ivshmem-plain, memdev = ivshmem, bus = pcie.0 \
-object memory-backend-file, id = ivshmem, share = on, mem-path = / dev / shm / looking-glass, size = 32M \
-monitor stdio \
-utilisateur netdev, id = n1, hostfwd = tcp: 127.0.0.1: 5600-: 5600, ipv6 = off, smb = "/ media / user / data" \
-device e1000, netdev = n1, mac = 67: 77: 78: 88: 89: 99 \
"$ @"

Nous nous connectons via VNC, installons le pilote sur le périphérique IVSHMEM, peut-être qu'un pilote standard sera installé dessus, situé dans les "Périphériques système". Nous commençons à regarder-glass-host.exe . Sur l'hôte, exécutez ./LookingGlass-a12/client/build/looking-glass-client .

À ce sujet, un système avec NVidia GF210 a fonctionné pour moi, puis Intel HD530 a été lancé sur la même route. Il y avait un petit problème avec la résolution d'écran, pour passer à une résolution rare, par exemple 2048x1152, j'ai dû utiliser l'utilitaire de résolution personnalisée [9] .

Autre nuance, lors de l'ajout de l'application looking-glass-host.exe au chargement automatique, vous devez configurer la connexion utilisateur automatique, pour des raisons de sécurité, le système d'exploitation invité ne permet pas de capturer l'écran de connexion.

Postface


Si vous ne définissez pas de tâche, obtenir une image sur une sortie vidéo physique, ce résultat sera suffisant pour obtenir une machine virtuelle fonctionnelle avec une carte vidéo physique et un contrôle réactif. La gestion est effectuée à partir de l'hôte dans une fenêtre séparée ou en plein écran. Cependant, il y a des nuances.

Performance . Les ressources supplémentaires pour la virtualisation et non le système d'exploitation invité le plus efficace ne vous permettront pas de travailler confortablement sur du matériel faible et moyen-faible. Il faudra un processeur puissant d'au moins 6-8 cœurs, une bonne carte graphique pour un OS invité, 16 Go + RAM, au moins 8 Go pour chaque système d'exploitation. Et danser avec un tambourin pour tirer le meilleur parti du fer.
Patience . Si cela ne fonctionne pas tout de suite, vous devrez passer du temps et du temps décemment. Recherchez, lisez, essayez. Encore une fois, regardez, lisez et réessayez. Je vais laisser quelques liens supplémentaires que j'ai rencontrés, peut-être y aura-t-il des informations plus utiles. [10] [11] [12]

Les références

Attention, les liens s'ouvrent dans cette fenêtre.

0. https://wiki.archlinux.org/index.php/PCI_passthrough_via_OVMF
1. https://en.wikipedia.org/wiki/List_of_IOMMU-supporting_hardware
2. https://www.techpowerup.com/vgabios/
3. https://www.win-raid.com/t892f16-AMD-and-Nvidia-GOP-update-No-requests-DIY.html
4. https://www.tightvnc.com/download.php
5. https://looking-glass.hostfission.com/quickstart
6. https://github.com/gnif/LookingGlass/releases
7. https://www.microsoft.com/en-us/download/details.aspx?id=48145
8. https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/upstream-virtio/
9. https://www.monitortests.com/forum/Thread-Custom-Resolution-Utility-CRU
10. https://heiko-sieger.info/running-windows-10-on-linux-using-kvm-with-vga-passthrough
11. https://ycnrg.org/vga-passthrough-with-ovmf-vfio/
12. https://www.reddit.com/r/VFIO/comments/8h352p/guide_running_windows_via_qemukvm_and_intel_gvtg/

Source: https://habr.com/ru/post/fr433878/


All Articles