Você está perto.
Usando os dois pci-stub
e vfio-pci
Não há problema em usar pci-stub
para reservar um dispositivo PCI (como sua GPU) para evitar que o driver gráfico o capture, pois o driver de gráficos (como nouveau
ou fglrx
) não soltará o dispositivo .
Na verdade, no meu teste, eu precisava reivindicar a placa de vídeo PCI com pci-stub
primeiro porque vfio-pci
não faria isso na inicialização, que é um dos problemas que você teve. Enquanto o descarregamento de um driver ( pci-stub
) e o carregamento de outro ( vfio-pci
) em seu lugar pode feio para alguns , pci-stub
e vfio-pci
são uma equipe de tags confiável que resulta em uma máquina virtual de sucesso com passagem de GPU. Meu teste não encontrou sucesso usando apenas um ou outro.
Agora, você precisa liberar o dispositivo PCI de pci-stub
e entregá-lo a vfio-pci
. Esta parte do seu script já deveria estar fazendo isso:
configfile=/etc/vfio-pci1.cfg
vfiobind() {
dev="$1"
vendor=$(cat /sys/bus/pci/devices/$dev/vendor)
device=$(cat /sys/bus/pci/devices/$dev/device)
if [ -e /sys/bus/pci/devices/$dev/driver ]; then
echo $dev > /sys/bus/pci/devices/$dev/driver/unbind
fi
echo $vendor $device > /sys/bus/pci/drivers/vfio-pci/new_id
}
modprobe vfio-pci
cat $configfile | while read line;do
echo $line | grep ^# >/dev/null 2>&1 && continue
vfiobind $line
done
Ressalva: " vfiobind
" é necessário apenas uma vez
Como observado em este comentário , É verdade que a transição de pci-stub
para vfio-pci
só precisa ser feita uma vez após a inicialização. Isso é verdade, mas na verdade é inofensivo executar a função " vfiobind
" várias vezes a menos que uma máquina virtual esteja atualmente usando o dispositivo PCI afetado.
Se a máquina virtual estiver usando o dispositivo, a operação de desvinculação será bloqueada ( processo "D state" ). Isso pode ser corrigido ao encerrar ou eliminar a máquina virtual, após o qual a desvinculação provavelmente terá êxito.
Você pode evitar essa desvinculação e religação extra desnecessária alterando sua função vfiobind()
para a seguinte forma:
vfiobind() {
dev="$1"
vendor=$(cat /sys/bus/pci/devices/$dev/vendor)
device=$(cat /sys/bus/pci/devices/$dev/device)
if [ -e /sys/bus/pci/devices/$dev/driver/module/drivers/pci\:vfio-pci ]; then
echo "Skipping $dev because it is already using the vfio-pci driver"
continue;
fi
if [ -e /sys/bus/pci/devices/$dev/driver ]; then
echo "Unbinding $dev"
echo $dev > /sys/bus/pci/devices/$dev/driver/unbind
echo "Unbound $dev"
fi
echo "Plugging $dev into vfio-pci"
echo $vendor $device > /sys/bus/pci/drivers/vfio-pci/new_id
echo "Plugged $dev into vfio-pci"
}
Verifique lspci -k
para o anexo do driver vfio-pci
bem-sucedido
Verifique se vfio-pci
assumiu o uso de lspci -k
. Este exemplo é da minha configuração equivalente:
01:00.0 VGA compatible controller: NVIDIA Corporation GK104 [GeForce GTX 760] (rev a1)
Subsystem: eVga.com. Corp. Device 3768
Kernel driver in use: vfio-pci
01:00.1 Audio device: NVIDIA Corporation GK104 HDMI Audio Controller (rev a1)
Subsystem: eVga.com. Corp. Device 3768
Kernel driver in use: vfio-pci
Se você não vir Kernel driver in use: vfio-pci
, algo deu errado com a parte do seu script que colei acima.
Configuração de passagem do QEMU
Eu lutei um pouco com a tela preta.
Em uma revisão anterior do seu script, você especificou:
-device vfio-pci,host=01:00.0,bus=root.1,addr=00.0,multifunction=on,x-vga=on \
-device vfio-pci,host=01:00.1,bus=root.1,addr=00.1 \
Tente deixar o QEMU decidir qual barramento virtual e endereço usar:
-device vfio-pci,host=01:00.0,multifunction=on,x-vga=on \
-device vfio-pci,host=01:00.1 \
Você também deve passar as bandeiras -nographic
e -vga none
para qemu-system-x86_64
. Por padrão, o QEMU revela uma placa gráfica emulada para a máquina virtual e a máquina virtual pode usar esse outro dispositivo de vídeo para exibir em vez da sua placa NVIDIA física pretendida.
Se você ainda estiver recebendo uma exibição em branco, tente adicionar também o sinal -nodefaults
, que exclui a porta serial padrão, porta paralela, console virtual, dispositivo de monitor, adaptador VGA, dispositivo de disquete e dispositivo de CD-ROM .
Agora, o comando qemu-system-x86_64
deve poder iniciar sua máquina virtual com dispositivos PCI 01:00.0
e 01:00.1
transmitidos e a exibição conectada a 01:00.0
deve mostrar algo.
Referência / Configuração de Amostra
Meu teste não é idêntico ao seu, mas consegui passar repasse de gráficos de trabalho e passagem USB com esse comando qemu-system-x86_64
, depois de reivindicar todos os dispositivos PCI relevantes de pci-stub
com vfio-pci
:
qemu-system-x86_64 \
-enable-kvm \
-name node51-Win10 \
-S \
-machine pc-i440fx-2.1,accel=kvm,usb=off \
-cpu host,kvm=off \
-m 16384 \
-realtime mlock=off \
-smp 8,sockets=8,cores=1,threads=1 \
-uuid 5c4a3e8a-6e8e-449f-9361-29fcdc35358d \
-nographic \
-no-user-config \
-nodefaults \
-chardev socket,id=charmonitor,path=/var/lib/libvirt/qemu/node51-Win10.monitor,server,nowait \
-mon chardev=charmonitor,id=monitor,mode=control \
-rtc base=localtime,driftfix=slew \
-global kvm-pit.lost_tick_policy=discard \
-no-hpet \
-no-shutdown \
-global PIIX4_PM.disable_s3=0 \
-global PIIX4_PM.disable_s4=0 \
-boot strict=on \
-device ich9-usb-ehci1,id=usb,bus=pci.0,addr=0x5.0x7 \
-device ich9-usb-uhci1,masterbus=usb.0,firstport=0,bus=pci.0,multifunction=on,addr=0x5 \
-device ich9-usb-uhci2,masterbus=usb.0,firstport=2,bus=pci.0,addr=0x5.0x1 \
-device ich9-usb-uhci3,masterbus=usb.0,firstport=4,bus=pci.0,addr=0x5.0x2 \
-device virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x6 \
-drive file=/dev/zd16,if=none,id=drive-virtio-disk0,format=raw,cache=none,aio=native \
-device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x2,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1 \
-drive file=/media/isos/Win10_English_x64.iso,if=none,id=drive-ide0-1-0,readonly=on,format=raw \
-device ide-cd,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0 \
-device ide-cd,bus=ide.1,unit=1,drive=drive-ide0-1-1,id=ide0-1-1 \
-netdev tap,fd=24,id=hostnet0,vhost=on,vhostfd=25 \
-device virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:11:bf:dd,bus=pci.0,addr=0x3 \
-chardev pty,id=charserial0 \
-device isa-serial,chardev=charserial0,id=serial0 \
-device usb-tablet,id=input0 \
-device intel-hda,id=sound0,bus=pci.0,addr=0x4 \
-device hda-duplex,id=sound0-codec0,bus=sound0.0,cad=0 \
-device vfio-pci,host=01:00.1,id=hostdev0,bus=pci.0,addr=0x9 \
-device vfio-pci,host=00:12.0,id=hostdev1,bus=pci.0,addr=0x8 \
-device vfio-pci,host=00:12.2,id=hostdev2,bus=pci.0,addr=0xa \
-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x7 \
-device vfio-pci,host=01:00.0,x-vga=on \
-vga none \
-msg timestamp=on
Itens relevantes de lspci -k
:
00:12.0 USB controller: Advanced Micro Devices, Inc. [AMD/ATI] SB7x0/SB8x0/SB9x0 USB OHCI0 Controller
Subsystem: Gigabyte Technology Co., Ltd Device 5004
Kernel driver in use: vfio-pci
00:12.2 USB controller: Advanced Micro Devices, Inc. [AMD/ATI] SB7x0/SB8x0/SB9x0 USB EHCI Controller
Subsystem: Gigabyte Technology Co., Ltd Device 5004
Kernel driver in use: vfio-pci
01:00.0 VGA compatible controller: NVIDIA Corporation GK104 [GeForce GTX 760] (rev a1)
Subsystem: eVga.com. Corp. Device 3768
Kernel driver in use: vfio-pci
01:00.1 Audio device: NVIDIA Corporation GK104 HDMI Audio Controller (rev a1)
Subsystem: eVga.com. Corp. Device 3768
Kernel driver in use: vfio-pci
Resultado observado: