KVM, PCI-Passthrough, Spiegel und alles in allem

Nach einem erfolgreichen Übergang zu Linux-Softwareentwicklern kam der Moment, als ein wenig gearbeitet wurde und auch das Hauptbetriebssystem geändert wurde. Bedenken wurden durch Necro-Plattform-Software zur Unterstützung bestehender Projekte verursacht. Ein Teil der Software arbeitete mit Wein. Es stellte sich jedoch heraus, dass bestimmte Software sich weigert, unter Wein zu arbeiten. Es wurde beschlossen, Software auf der virtuellen Maschine QEMU + KVM auszuführen. Die Software begann zu laufen, aber die Arbeit darin war ziemlich unpraktisch. Virtuelle Software-Grafikkarten unterscheiden sich nicht in der Leistung, und die Unterstützung für 3D-Grafiken ist sehr bescheiden. Ich musste das Tamburin aufdecken und nach einem Ausweg suchen.

Ordnen Sie dem Gastsystem eine separate Grafikkarte zu!


Es dauerte nicht lange, einen Ausweg zu finden, aber die Idee, ein Tamburin mit einem Suchscheinwerfer zu treffen, erwies sich als sehr seltsam. Beim Thema Weiterleiten von Grafikkarten an eine virtuelle Maschine enthält das Internet Anweisungen zu verschiedenen Zeiten und für verschiedene Hardware. Was ist ein riesiger Artikel auf der Arch Linux Site [0] . Ich werde eine gekürzte Version der Anweisungen zum Weiterleiten einer Grafikkarte geben.

0. Überprüfen Sie, ob die Hardware IOMMU unterstützt


Zum Beispiel hier [1] .

1. Wir bieten Unterstützung für IOMMU in einem Kernel.


cat / etc / default / grub
GRUB_CMDLINE_LINUX_DEFAULT = "leises Spritzen amd_iommu = on"
oder
GRUB_CMDLINE_LINUX_DEFAULT = "leiser Splash intel_iommu = on"


Vergessen Sie nicht sudo update-grub .

2. Wir wählen die Grafikkarte aus dem Treiber


Wir suchen nach den notwendigen Geräten und sehen, welche Treiber sie verwenden.

lspci -nnk
04: 00.0 VGA-kompatibler Controller: NVIDIA Corporation GT218 [GeForce 210] [ 10de: 0a65 ] (Rev. a2)
Verwendeter Kerneltreiber: Nouveau
Kernelmodule: nvidiafb, nouveau
04: 00.1 Audiogerät: High Definition Audio Controller der NVIDIA Corporation [ 10de: 0be3 ] (rev a1)
Verwendeter Kerneltreiber : snd_hda_intel
Kernelmodule: snd_hda_intel


Fügen Sie VFIO-Module hinzu, damit sie beim Booten geladen werden.

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


Wir konfigurieren das VFIO-Modul so, dass es Geräte abfängt und verhindert, dass die Haupttreiber geladen werden. Fügen Sie bei Bedarf den Haupttreiber zur Blacklist hinzu.

cat /etc/modprobe.d/vfio.conf
Optionen vfio-pci ids = 10de: 0a65,10de: 0be3
Blacklist Nouveau


3. Starten Sie neu und überprüfen Sie, ob alles geklappt hat


IOMMU eingeschaltet.

dmesg | grep -e DMAR -e IOMMU -e AMD-Vi
DMAR: Intel® Virtualisierungstechnologie für gerichtete E / A.
oder
AMD-Vi: IOMMU um 0000: 00: 00.2 cap 0x40 gefunden
AMD-Vi: Interrupt-Neuzuordnung aktiviert
AMD-Vi: Lazy IO / TLB-Spülung aktiviert


Verbundgeräte fielen in eine Gruppe.

für ein in / sys / kernel / iommu_groups / *; finde $ a-Typ l; erledigt | 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


KVM- und VFIO-Treiber geladen.

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


Grafikkarte für das von VFIO erfasste Gastbetriebssystem.

lspci -nnk
04: 00.0 VGA-kompatibler Controller: NVIDIA Corporation GT218 [GeForce 210] [ 10de: 0a65 ] (Rev. a2)
Verwendeter Kerneltreiber : vfio-pci
Kernelmodule: nvidiafb, nouveau
04: 00.1 Audiogerät: High Definition Audio Controller der NVIDIA Corporation [ 10de: 0be3 ] (rev a1)
Verwendeter Kerneltreiber : vfio-pci
Kernelmodule: snd_hda_intel


4. Konfigurieren Sie QEMU und starten Sie das Gastbetriebssystem


Installieren, falls noch nicht installiert
sudo apt installiere qemu-kvm qemu-utils seabios ovmf virt-viewer

Erstellen Sie eine Festplatte, auf der das Gastbetriebssystem installiert wird
qemu-img create -f raw -o preallocation = full guest.img 50G
oder
fallocate -l 50G guest.img

Wir starten die virtuelle Maschine, ohne die Grafikkarte weiterzuleiten, um das Gastbetriebssystem zu installieren. Da es einen Blick auf Looking Glass gibt, lohnt es sich für den Gast, Windows 10 zu wählen. Windows 8 / 8.1 nach den neuesten Daten wird ebenfalls unterstützt.

vga_qxl.sh
#! / bin / bash
Remote-Viewer-Gewürz: //127.0.0.1: 5900 &
sudo qemu-system-x86_64 \
-Maschine q35, accel = kvm \
-enable-kvm \
-cpu host, kvm = off, check \
-smp cpus = 2, Sockets = 1, Cores = 2, Threads = 1 \
-m 6G \
-rtc base = Ortszeit, clock = host \
-device piix3-usb-uhci \
-Gerät USB-Tablet \
-drive if = pflash, format = raw, schreibgeschützt, 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 \
-spice port = 5900, addr = 127.0.0.1, disable-ticketing \
-monitor stdio \
-netdev user, id = n1, ipv6 = off, smb = "/ media / user / data" \
-Gerät e1000, netdev = n1, mac = 67: 77: 78: 88: 89: 99 \
"$ @"

5. Wir leiten die Grafikkarte an das Gastbetriebssystem weiter


Booten Sie zunächst mit zwei Grafikkarten. Wir sehen, dass die weitergeleitete Karte im System angezeigt wird, setzen die Treiber darauf und stellen sicher, dass sie funktionieren.

vga_qxl_pass.sh
#! / bin / bash
Remote-Viewer-Gewürz: //127.0.0.1: 5900 &
sudo qemu-system-x86_64 \
-Maschine q35, accel = kvm \
-enable-kvm \
-cpu host, kvm = off, check \
-smp cpus = 2, Sockets = 1, Cores = 2, Threads = 1 \
-m 6G \
-rtc base = Ortszeit, clock = host \
-device piix3-usb-uhci \
-Gerät USB-Tablet \
-drive if = pflash, format = raw, schreibgeschützt, 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 \
-spice port = 5900, addr = 127.0.0.1, disable-ticketing \
-Gerät ioh3420, Bus = PCIE.0, Adr = 1c.0, Multifunktion = Ein, 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" \
-Gerät e1000, netdev = n1, mac = 67: 77: 78: 88: 89: 99 \
"$ @"

Nachdem die weitergeleitete Grafikkarte funktioniert hat und im Geräte-Manager "Das Gerät funktioniert einwandfrei" geschrieben ist, starten wir die virtuelle Maschine nur mit der weitergeleiteten Grafikkarte.

vga_pass.sh
#! / bin / bash
sudo qemu-system-x86_64 \
-Maschine q35, accel = kvm \
-enable-kvm \
-cpu host, kvm = off, check \
-smp cpus = 2, Sockets = 1, Cores = 2, Threads = 1 \
-m 6G \
-rtc base = Ortszeit, clock = host \
-device piix3-usb-uhci \
-Gerät USB-Tablet \
-drive if = pflash, format = raw, schreibgeschützt, 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 keine \
-Gerät ioh3420, Bus = PCIE.0, Adr = 1c.0, Multifunktion = Ein, 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" \
-Gerät e1000, netdev = n1, mac = 67: 77: 78: 88: 89: 99 \
"$ @"

Wir schließen einen Monitor daran an und bewundern das Desktop-Image des Gastbetriebssystems.

Der Ort, an dem einfache Entscheidungen enden


Und dann beginnt der Spaß. Jemand, alles ist in Ordnung, das Bild ist weg und alles ist einfach. Meine Erfahrung stolperte zweimal über das Stadium des Imagemangels. Das erste Mal war die Weiterleitung der integrierten Grafikkarte des Intel 6700T HD 530-Prozessors, die Videoausgänge waren leer und der Fehler wurde auf die Tatsache zurückgeführt, dass die Plug-Ins nicht gut funktionieren. Das zweite Mal wurde das externe Nvidia GF210 umgeworfen, das bereits speziell für Experimente gekauft wurde. Das Ergebnis war noch interessanter. Im Nicht-EFI-Modus wurde die Grafikkarte erfolgreich weitergeleitet und zeigte sogar ein Bild, schaltete jedoch das fehlgeschlagene Gastbetriebssystem aus.

Eine nachfolgende Weiterleitung könnte den Host einfach hängen lassen. Ein paar Stunden einfaches Googeln führen dazu, dass das Problem des Einfrierens einer Grafikkarte häufig auftritt. Dies führt zu einem fehlerhaften Herunterfahren der virtuellen Maschine und mit einiger Wahrscheinlichkeit sogar zu einem korrekten Herunterfahren. Als Ausgabe wird empfohlen, im EFI-Modus weiterzuleiten. VBIOS Nvidia GF210 unterstützt EFI jedoch nicht ...

Nähen oder nicht nähen, das ist die Frage


Nicht nähen. QEMU unterstützt VBIOS-Spoofing beim Weiterleiten einer Grafikkarte. VBIOS muss jedoch noch unterrichtet werden, um den EFI-Modus zu unterstützen. Es wird normalerweise empfohlen, dies zu überprüfen, bevor Sie mit der Weiterleitung der Grafikkarte beginnen, z. B. hier [2] . Aber man muss sich mit dem beschäftigen, was ist, und wollte nicht nach einer neuen Grafikkarte mit EFI-Unterstützung suchen. Sie müssen also VBIOS patchen. Alle mit VBIOS durchgeführten Operationen erfolgen auf eigenes Risiko. Ich habe hier ein Softwarepaket und Anweisungen dazu verwendet [3] . Nach dem Lesen von VBIOS erhalten wir die Datei gt210.rom , patch und am Ausgang haben wir gt210_uefi.rom . Hier müssen Sie die Grafikkarte ablegen, wenn Sie die virtuelle Maschine laden.

vga_pass_rom.sh
#! / bin / bash
sudo qemu-system-x86_64 \
-Maschine q35, accel = kvm \
-enable-kvm \
-cpu host, kvm = off, check \
-smp cpus = 2, Sockets = 1, Cores = 2, Threads = 1 \
-m 6G \
-rtc base = Ortszeit, clock = host \
-device piix3-usb-uhci \
-Gerät USB-Tablet \
-drive if = pflash, format = raw, schreibgeschützt, 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 keine \
-Gerät ioh3420, Bus = PCIE.0, Adr = 1c.0, Multifunktion = Ein, 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" \
-Gerät e1000, netdev = n1, mac = 67: 77: 78: 88: 89: 99 \
"$ @"

Wir starten die virtuelle Maschine und schauen.

Dunkelheit


Die Ausgänge der Grafikkarte leuchteten im Dunkeln. Wieder einmal bestand die Moral den Test des Scheiterns. Das erste, was mir einfällt, ist, dass das Gastbetriebssystem beim Start abstürzt. Protokolle, ich brauche ihre Protokolle. Führen Sie dazu vga_qxl.sh . Wir schauen uns den vorherigen Start an. Und dort ist alles in Ordnung, außer dass das Essen scharf gezogen wurde. Es stellt sich heraus, dass es funktioniert, obwohl es nicht funktioniert. Die erste Idee war, eine Verbindung über RDP herzustellen und zu sehen, was dort passiert, aber es ist immer noch besser, VNC zu verwenden, zum Beispiel tightvnc [4] . Wir installieren VNC, konfigurieren Port 5600 und leiten diesen Port für den Zugriff vom Host weiter.

vga_vnc_pass_rom.sh
#! / bin / bash
sudo qemu-system-x86_64 \
-Maschine q35, accel = kvm \
-enable-kvm \
-cpu host, kvm = off, check \
-smp cpus = 2, Sockets = 1, Cores = 2, Threads = 1 \
-m 6G \
-rtc base = Ortszeit, clock = host \
-device piix3-usb-uhci \
-Gerät USB-Tablet \
-drive if = pflash, format = raw, schreibgeschützt, 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 keine \
-Gerät ioh3420, Bus = PCIE.0, Adr = 1c.0, Multifunktion = Ein, 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, hostfwd = tcp: 127.0.0.1: 5600-: 5600, ipv6 = off, smb = "/ media / user / data" \
-Gerät e1000, netdev = n1, mac = 67: 77: 78: 88: 89: 99 \
"$ @"

Wir verbinden und sehen die Arbeitsmaschine, nur der Monitor hat einen seltsamen generischen Nicht-PnP-Monitor (Universal Monitor ist kein PnP). Es gibt ein Bild, sodass Sie versuchen können, Looking Glass auszuführen.

Spiegel


Obwohl diese Technologie OpenGL verwendet, wird nach gl kein Platz benötigt. Sie müssen jedoch die Anweisungen [5] auf der Projektwebsite lesen. Laden Sie für das Gastbetriebssystem den Bildschirm herunter - erfassen Sie die Anwendung Looking-Glass-Host.exe [6] , laden Sie Microsoft Visual C ++ 2015 Redistributable herunter und installieren Sie ihn [7] . Laden Sie den Treiber für das IVSHMEM-Gerät herunter [8] . Für den Host fügen wir Abhängigkeiten hinzu, laden die Clientanwendung herunter und erstellen sie.

build_looking_glass_a12.sh
#! / bin / bash
sudo apt-get install cmake libsdl2-dev libsdl2-ttf-dev Brennnessel-dev libspice-Protokoll-dev libfontconfig1-dev libx11-dev Schriftarten-freefont-ttf libconfig-dev
wget github.com/gnif/LookingGlass/archive/a12.tar.gz
tar -xf a12.tar.gz
cd LookingGlass-a12
mkdir client / build
CD-Client / Build
cmake ../
machen

Wir starten die virtuelle Maschine mit dem IVSHMEM-Gerät. Die Speichergröße von 32 MB wird für eine Auflösung von 1920 x 1080 ausgewählt.

vga_vnc_lg_pass_rom.sh
#! / bin / bash
wenn [! -f / dev / shm / schauglas]; dann
touch / dev / shm / schauglas
chown `whoami`: kvm / dev / shm / schauglas
chmod 660 / dev / shm / schauglas
fi
sudo qemu-system-x86_64 \
-Maschine q35, accel = kvm \
-enable-kvm \
-cpu host, kvm = off, check \
-smp cpus = 2, Sockets = 1, Cores = 2, Threads = 1 \
-m 6G \
-rtc base = Ortszeit, clock = host \
-device piix3-usb-uhci \
-Gerät USB-Tablet \
-drive if = pflash, format = raw, schreibgeschützt, 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 keine \
-Gerät ioh3420, Bus = PCIE.0, Adr = 1c.0, Multifunktion = Ein, 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 \
-Objektspeicher-Backend-Datei, id = ivshmem, share = on, mem-path = / dev / shm / schauglas, size = 32M \
-monitor stdio \
-netdev user, id = n1, hostfwd = tcp: 127.0.0.1: 5600-: 5600, ipv6 = off, smb = "/ media / user / data" \
-Gerät e1000, netdev = n1, mac = 67: 77: 78: 88: 89: 99 \
"$ @"

Wir stellen eine Verbindung über VNC her, installieren den Treiber auf dem IVSHMEM-Gerät. Möglicherweise wird ein Standardtreiber darauf installiert, der sich in den "Systemgeräten" befindet. Wir beginnen mit der Suche nach der host.exe . Führen ./LookingGlass-a12/client/build/looking-glass-client auf dem Host ./LookingGlass-a12/client/build/looking-glass-client .

Auf diesem System funktionierte ein System mit NVidia GF210 für mich, und dann wurde Intel HD530 auf demselben Weg gestartet. Es gab ein kleines Problem mit der Bildschirmauflösung. Um zu einer seltenen Auflösung zu wechseln, z. B. 2048 x 1152, musste ich das Dienstprogramm für benutzerdefinierte Auflösung verwenden [9] .

Eine weitere Nuance: Wenn Sie die Anwendung look-glass-host.exe zum Start hinzufügen, müssen Sie die automatische Benutzeranmeldung konfigurieren. Aus Sicherheitsgründen können Sie den Anmeldebildschirm vom Gastbetriebssystem nicht erfassen.

Nachwort


Wenn Sie keine Aufgabe festlegen und ein Bild auf einem physischen Videoausgang abrufen, reicht dieses Ergebnis aus, um eine funktionierende virtuelle Maschine mit einer physischen Grafikkarte und einer reaktionsschnellen Steuerung zu erhalten. Die Verwaltung erfolgt vom Host in einem separaten Fenster oder im Vollbildmodus. Es gibt jedoch Nuancen.

Leistung . Overhead-Ressourcen für die Virtualisierung und nicht das effizienteste Gastbetriebssystem ermöglichen es Ihnen nicht, bequem mit schwacher und mittlerer bis niedriger Hardware zu arbeiten. Es erfordert einen leistungsstarken Prozessor mit mindestens 6-8 Kernen, eine gute Grafikkarte für ein Gastbetriebssystem, 16 GB + RAM und mindestens 8 GB für jedes Betriebssystem. Und mit einem Tamburin tanzen, um das Beste aus Eisen herauszuholen.
Geduld . Wenn es nicht sofort funktioniert, müssen Sie Zeit und Zeit anständig verbringen. Suchen, lesen, versuchen. Schauen Sie noch einmal, lesen Sie und versuchen Sie es erneut. Ich werde noch ein paar Links hinterlassen, auf die ich gestoßen bin. Vielleicht gibt es weitere nützliche Informationen. [10] [11] [12]

Referenzen

Achtung, in diesem Fenster öffnen sich Links.

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/de433878/


All Articles