És hogy miért fél? Mert csak a feléig jutottam, de ez a fele legalább működik (vagy nem). Ezt is huszonhat leírásból és fórumból kellett összelapátolni. Egyszerűen nincs step-by-step leírás, és valószínűleg azért, mert nincs univerzális eljárás erre...
Szükség volt egy olyan megoldásra, ahol egy virtuális Windowson futnak dVGA igényes programok, ehhez pedig GPU-t kell adni a virtuális gépnek. A fizikai gép egy workstation laptop, amin Ubuntu fut, a hipervizor KVM.
Elméletben ez nem olyan rettenetes dolog, hiszen workstation gép, IOMMU SR-IOV, VT-D, ilyesmi van. Erre lett kitalálva. Bekattintod a Virt-managerben a PCIE eszközt, hogy azt adja át és... na, így nem fog menni.
Az itthoni hostban van mondjuk egy PCIE-s párhuzamos kártya (videokátya nincs, minek), azt tényleg ennyi, simán megy. Egy GPU nem
Ahogyan sikerült eljutni az alapvető GPU átadásig :
- Megnézni, hogy az IOMMU csoportok rendben vannak-e, azaz hogy nem-e egy csoportban van a két GPU-nk, mert ha igen, akkor neki se kell állni. Erre jó ez a script, ami kiírja, hogy melyik PCIE eszköz melyik csoportban van. Elvileg asztali gépeken a használt PCIE slot sem mindegy.
Hirdetés
- Nvidia driver feltelepít a host gépre. Ezt az Ubuntu (KDE-vel) simán megoldotta.
- Beállítani a kernelnek pár paramétert. A /etc/default/grub
-ban a GRUB_CMDLINE_LINUX_DEFAULT
sor valahogy így :GRUB_CMDLINE_LINUX_DEFAULT="iommu=pt nvidia-drm nomodeset=0 mitigations=auto intel_iommu=on rd.driver.pre=vfio-pci modprobe.blacklist=nouveau xdg.force_integrated=1 vfio_pci.ids=10de:13b0,10de:0fbc"
elmenteni, sudo update-grub
, reboot.
A "vfio_pci.ids=10de:13b0,10de:0fbc
" az érdekes itt. A PCIE ID-k a GPU-é, és a GPU hangkártyájáé, ezt később kiderül, hogyan lehet kinyerni A lényeg, hogy VFIO driver fogja kezelni a GPU-t, ami csak annyit csinál, hogy lehetővé teszi a direkt hozzáférést ahhoz az eszközhöz. Másnak nem szabad használnia a dVGA-t, mert vagy nem fog menni, vagy érdekes dolgok fognak történni, amikor elveszi a VFIO a kártyát a hosttól
A nouveau driver helyből blacklistes, a host OS-en csak az integrált videokártya dolgozik.
- A VFIO PCI ID-k a lspci -nnk
parancs kimenetében lesznek, az eszközre vonatkozó első sor végén. A sor elején található PCI címre is szükség lesz. A kernelparaméterek között vesszővel kell felsorolni.
Nekem ugye ez volt:
$ lspci -nnk
.
.
.
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GM107GLM [Quadro M2000M] [10de:13b0] (rev a2)
Kernel driver in use: vfio-pci
Kernel modules: nvidiafb, nouveau, nvidia_drm, nvidia
01:00.1 Audio device [0403]: NVIDIA Corporation GM107 High Definition Audio Controller [GeForce 940MX] [10de:0fbc] (rev a1)
Kernel driver in use: vfio-pci
Kernel modules: snd_hda_intel
- A virtuális gép indításakor, leállításakor le kell kezelni a kártya átadását, visszavételét (a későbbiekben kiderült, hogy ez nem is biztos, hogy kell). Ehhez az alábbi könyvtárszerkezetben lesz szükség némi scriptre :$ tree /etc/libvirt/
/etc/libvirt/
├── hooks
│ ├── kvm.conf
│ └── qemu.d
│ └── win11
│ ├── prepare
│ │ └── begin
│ │ └── bind_vfio.sh
│ └── release
│ └── end
│ └── unbind_vfio.sh
kvm.conf :VIRSH_GPU_VIDEO=pci_0000_01_00_0
VIRSH_GPU_VIDEO=pci_0000_01_00_1
(A PCI id-k a lspci -nnk
kimenetében a sorok elején levő címből állnak elő.)
bind_vfio.sh :#!/bin/bash
systemctl stop nvidia-presistenced.service
## Load the config file
source "/etc/libvirt/hooks/kvm.conf"
## Load vfio
modprobe vfio
modprobe vfio_iommu_type1
modprobe vfio_pci
## Unbind gpu from nvidia and bind to vfio
virsh nodedev-detach $VIRSH_GPU_VIDEO
virsh nodedev-detach $VIRSH_GPU_AUDIO
unbind_vfio.sh :#!/bin/bash
## Load the config file
source "/etc/libvirt/hooks/kvm.conf"
## Unbind gpu from vfio and bind to nvidia
virsh nodedev-reattach $VIRSH_GPU_VIDEO
virsh nodedev-reattach $VIRSH_GPU_AUDIO
## Unload vfio
modprobe -r vfio_pci
modprobe -r vfio_iommu_type1
modprobe -r vfio
- És már tényleg csak a Virt-managerben kell összekattintani egy gépet, aminek win11 lesz a neve (mert ez alapján találja meg a scripteket hozzá a KVM), és elindítani. Ha minden jó, akkor elindul, van kép, és nem áll meg a host UI-ja
Itt olyan gondba futottam, hogy ugyan az átadott hardver látszik, de a Windows Microsoft Basic video adapterként ismeri fel (az Everest, GPU-Z által kiolvasott azonosító rendben van, 10de:13b0 ahogy kell), és nem jövök rá, miért. A Nvidia driver nem települ fel, mert szerinte nincs nVidia kártya. Vagy a video BIOS kell neki (ezt be kell szerezni, vagy kidumpolni egy updaterből - szerencsém volt, simán fent volt a TechPowerUp-on), vagy a ROM BAR-nak kellene működnie, és azzal meg is lenne?????? ), vagy mivel ez mobil GPU, be kéne neki kamuzni, hogy laptopon fut. Nézzük, ez okozza-e...
És lőn. A laptop kamuzásához akku kell; a virtuálgép XML-jében lett egy Qemu-s bejegyzés :<qemu:commandline>
<qemu:arg value='-acpitable'/>
<qemu:arg value='file=/opt/qemu/SDDT1.dat' />
</qemu:commandline>
Ezt közvetlenül a </domain>
elé kell betenni.
A file= az, ahol a SDDT1.dat van (a linken le is lehet tölteni). Az se mindegy, hogy hol van, mert az Apparmor megfogja, ha nem jó helyre kerül. Tehát a /usr/share/libvirt/seabios/
-ba kell tenni, különben file not found-dal el sem indul a guest.
Valamint az XML elején az XML definíció nézzen ki így :<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
Mert különben nem fogja a libvirt érteni, hogy a Qemu parancssorba tegye be a megadott paramétereket.
Így már lesz egy akku is a virtuális gépben, de nekem a nVidia driver így se m ment fel.
Persze ha nem laptopon kerül előadásra a dolog, akkor nem kell akkut csinálni.
A video BIOS hasonlóképpen a /usr/share/vgabios/ könyvtárba kerüljön (Apparmor-os disztrókon, mint a Debian, és származékai.). Az XML-ben a <hostdev>...</hostdev> sorok közöt lesz a rom bar='on' bejegyzés, ezt kell módosítani ilyenre :
<rom bar='on' file='/path/to/your/gpu/bios.bin' />
Ekkor már meg kell lennie a VGA BIOS-nak is. Már ha olyan a cucc, hogy a letöltött BIOS megfelel neki.
Nekem nem felelt, ezért a VGA BIOS-t a kártyáról kellett lementeni. Elvileg ezen a mobil Quadro-n is patchelni (valójában strippelni) kellett volna a BIOS-t, ez jelen esetben azt jelenti, hogy az elejét levágni; na most ez ezen Arch-os single GPU-s leírás alapján már jól lett kinyerve a kártyáról.
Fontos, hogy egyes nVidia (amit biztosan tudok) kártyák és driver verziók (pl. a GeForce-ok) nem támogatják csak úgy a GPU passthrough-t, illetve a 465-ös drivertől van támogatás elvileg GeForce-okra - előtte trükközni kellett (na most ezt nem tudom, hogy host vagy guest oldalon kell ez a driver, de majd kiderítem). Megint más driverek a virtuális géptől hisztiznek be (de pl. ebben a gépben mobil Quadro volt, ennek mennie kellett volna)...
Olyan hibák jönnek, hogy 13, 31, 43 a 'dózer eszközkezelőjében. Ezek ilyen "nem tudom elindítani a drivert" "más az eszközazonosító mint a POST alatt volt" meg ilyesmik.
(Utóbbira talán a<kvm>
<hidden state='on'/>
</kvm>
megoldás lehet a XML <features>
részében. Egyszer sikerült úgy beletenni, hogy nem tűnt el az egész gép a Virt-manager-ből, de nem működött az sem )
- Érdekes lehet, hogy a nVidia driver nagyon kukacos; pl. a KVM beállítja az átadott PCIE eszközt 0x05-nek, ezt észreveszi, és beduzzog. Tehát a bus=0x01... ( pl. ez volt a VGA eszköznél az XML-ben : <address domain='0x0000' bus='0x05' slot='0x00' function='0x0'/>
)
- A fel nem települő driverre lett egy olyan megoldás, hogy esetleg a PCI Vendor ID? Subsystem ID? nem jó. Na jó, az eszközazonosító rendben volt, de a subsystem ID-t meg lehet adni qemu:commandline paraméterek között :<qemu:arg value='device.hostdev0.romfile=/usr/share/vgabios/vbios.rom'/>
<qemu:arg value='-set'/>
<qemu:arg value='device.hostdev0.x-pci-vendor-id=0x10de'/>
<qemu:arg value='-set'/>
<qemu:arg value='device.hostdev0.x-pci-device-id=0x13b0'/>
<qemu:arg value='-set'/>
<qemu:arg value='device.hostdev0.x-pci-sub-vendor-id=0x17aa'/>
<qemu:arg value='-set'/>
<qemu:arg value='device.hostdev0.x-pci-sub-device-id=0x222e'/>
...és ezzel a VGA BIOS átadása is megvan. (A linkelt Reddit subon van egy utalás a Gvt-g-re is, ami elég meredeken hangzik, de működhet.) A hexa értékeket úgy lehet kinyerni, ha telepítesz egy Windowst, és megnézed, mit ad az Eszközkezelő, tulajdonságok között. (Esetleg a driverben az .inf file-ból.) Ha ez nincs meg, akkor nem ismerhető fel a kártya nVidia-nak, amint megkapja a guest, azonnal megvan a Quadro kártya, ...és a Code 43
Így már feltelepült a driver (azaz : talált neki megfelelő eszközt), de természetesen "device has problems" (és én is ), sárga felkiáltójel.
- Voltak olyan megoldások is, hogy a Proxmox (ami alatt szintén KVM dolgozik, és amin működik a GPU passthrough) OVMF BIOS-aival sikerült működésre bírni az egyéb KVM-es passthrough-t; megoldottam, a Proxmox OVMF-ével sem ment (Saját OVMF-et buildelni nem tudtam, nem működött egyik megoldás sem.)
Code 31, de amúgy 43-at is tud dobni
Legalább felteepül, de a VGA BIOS még mindig sehol
Jött az ötlet, hogy mit kezdene próbaképpen egy Linux guest-tel ugyanez a cucc? nVidia driver arra is van...
És működött. Legalábbis olyan szintig, hogy egy friss Ubuntu telepítés virtuálgépre azonnal húzta be a Nouveau drivert. Viszont a zárt driver inicializációs hibákat dobál.
A gond csak az, hogy ezen a gépen semmilyen hókuszpókusz nem volt, a két PCIE eszköz bekattint, hogy az megy a guestnek (nyilván itt ugye lényeges, hogy a host Ubuntun a VFIO driver sem változott), se a start/stop scriptek, se semmi nem volt... Mondjuk nem tudom, ez a helyes működés volt-e, de a dmesg
alapján nem volt baja, és gondolom a nouveau modul sem működne, ha nincs video BIOS. Képet nem tudtam kinyerni belőle a gép HDMI-jén, de nem is biztos, hogy annak ott kellett volna jönnie (a host OS sem látta azt a kimenetet, mivel a VFIO driver nem működik videoeszközként).