PCI-Device-Passthrough

Industrie-PCs mit IOMMU-Virtualisierungsfunktionen erlauben das explizite Zuweisen von physischen PCI-Geräten an eine virtuelle Maschine (siehe Tabelle: Geräteunterstützung für TwinCAT/BSD Hypervisor, Device- und GPU-Passthrough.). PCI-Geräte wie die GPU, Netzwerkschnittstellen oder USB-Controller können als passthru Geräte explizit einer virtuellen Maschine zugewiesen werden.

Um ein PCI-Gerät einer virtuellen Maschine zuzuweisen, wird zunächst dessen PCI-Adresse benötigt. Mit dem Kommando pciconf -l werden alle PCI-Geräte sowie ihre Adressen gelistet.

$ pciconf -l
...
vgapci0@pci0:0:2:0: class=0x030000 card=0x22128086 chip=0x3e928086 rev=0x00 hdr=0x00
...
igb2@pci0:3:0:0: class=0x020000 card=0x15338086 chip=0x15338086 rev=0x03 hdr=0x00
xhci1@pci0:4:0:0: class=0x0c0330 card=0x00000000 chip=0x8241104c rev=0x02 hdr=0x00
...

Im folgenden Beispiel sollen die drei gelisteten Geräte einer virtuellen Maschine zugewiesen werden.

Gerät

Beschreibung

Adresse

vgapci0@pci0:0:2:0

GPU

pci0:0:2:0

igb2@pci0:3:0:0

Ethernet Controller

pci0:3:0:0

xhci1@pci0:4:0:0

USB-Controller

pci0:4:0:0

Um die Geräte vom TwinCAT/BSD-Host zu isolieren, wird ihnen mit devctl der ppt (PCI PassThrough) Treiber zugewiesen.

doas devctl set driver -f pci0:0:2:0 ppt
doas devctl set driver -f pci0:3:0:0 ppt
doas devctl set driver -f pci0:4:0:0 ppt

Um die Treiber bereits beim Systemboot zu setzen können die PCI Adressen als pptdevs der /boot/loader.conf Datei hinzugefügt werden:

pptdevs="0/2/0 3/0/0 4/0/0"

Eine erneute Ausgabe von pciconf -l zeigt nun, dass die ppt Treiber den Geräten zugewiesen worden sind:

$ pciconf -l
...
ppt0@pci0:0:2:0: class=0x030000 card=0x22128086 chip=0x3e928086 rev=0x00 hdr=0x00
...
ppt1@pci0:3:0:0: class=0x020000 card=0x15338086 chip=0x15338086 rev=0x03 hdr=0x00
ppt2@pci0:4:0:0: class=0x0c0330 card=0x00000000 chip=0x8241104c rev=0x02 hdr=0x00
...

Die PCI-Geräte können nun bhyve mit dem Parameter -s [slot],passthru,[slot/bus/function] übergeben werden. Die Werte für [slot/bus/function] beziehen sich dabei auf die PCI-Adressen der pciconf -l Ausgabe. Da Passthrough-Geräte fixe Speicheradressen verwenden, muss byhve zusätzlich das Flag -S als Parameter übergeben werden, um Memory-Swapping für den Prozess zu deaktivieren.

Der bhyve Aufruf mit zugewiesener on-board GPU, Ethernet- und USB-Controller ergibt sich für das Beispiel wie folgt:

doas bhyve \
-c sockets=1,cores=1,threads=1 \
-m 2G \
-l bootrom,/usr/local/share/uefi-firmware/BHYVE_BHF_UEFI.fd,/vms/samplevm/EFI_VARS.fd,fwcfg=qemu \
-s 0:0,hostbridge
-s 2:0,passthru,0/2/0 \
-s 3:0,passthru,4/0/0 \
-s 10:0,virtio-blk,/dev/zvol/vm1_disk0 \
-s 20:0,virtio-net,tap0 \
-s 21:0,passthru,3/0/0 \
-s 31:0,lpc \
-A -H -P -S \
samplevm