QEMU com passagem de GPU não inicia

4

Estou executando o Ubuntu e tentando configurar o QEMU com uma passagem da GPU. Eu estava seguindo esses guias:

link

link

link

Meu /etc/modules :

lp
rtc
pci_stub
vfio
vfio_iommu_type1
vfio_pci
kvm
kvm_intel 

Meu /etc/default/grub :

GRUB_DEFAULT=0
GRUB_HIDDEN_TIMEOUT=0
GRUB_HIDDEN_TIMEOUT_QUIET=true
GRUB_TIMEOUT=10
GRUB_DISTRIBUTOR='lsb_release -i -s 2> /dev/null || echo Debian'
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash intel_iommu=on vfio_iommu_type1.allow_unsafe_interrupts=1"
GRUB_CMDLINE_LINUX=""

Minha GPU:

$ lspci -nn | grep NVIDIA
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GK106 [GeForce GTX 650 Ti] [10de:11c6] (rev a1)
01:00.1 Audio device [0403]: NVIDIA Corporation GK106 HDMI Audio Controller [10de:0e0b] (rev a1)
$ lspci -nn | grep -i graphic
00:02.0 VGA compatible controller [0300]: Intel Corporation Xeon E3-1200 v2/3rd Gen Core processor Graphics Controller [8086:0152] (rev 09)

Meu /etc/initramfs-tools/modules :

pci_stub ids=10de:11c6,10de:0e0b

pci_stub parece estar funcionando:

$ dmesg | grep pci-stub
[    0.541737] pci-stub: add 10DE:11C6 sub=FFFFFFFF:FFFFFFFF cls=00000000/00000000
[    0.541750] pci-stub 0000:01:00.0: claimed by stub
[    0.541755] pci-stub: add 10DE:0E0B sub=FFFFFFFF:FFFFFFFF cls=00000000/00000000
[    0.541760] pci-stub 0000:01:00.1: claimed by stub

Meu /etc/vfio-pci1.cfg :

0000:01:00.0
0000:01:00.1

Meu ~/windows_start.bash : link

Depois de executar o script, vfio-pci está sendo usado como um driver:

$ lspci -k | grep -C 3 -i nvidia
    Kernel driver in use: ahci
00:1f.3 SMBus: Intel Corporation 7 Series/C210 Series Chipset Family SMBus Controller (rev 04)
    Subsystem: ASRock Incorporation Motherboard
01:00.0 VGA compatible controller: NVIDIA Corporation GK106 [GeForce GTX 650 Ti] (rev a1)
    Subsystem: Gigabyte Technology Co., Ltd Device 3557
    Kernel driver in use: vfio-pci
01:00.1 Audio device: NVIDIA Corporation GK106 HDMI Audio Controller (rev a1)
    Subsystem: Gigabyte Technology Co., Ltd Device 3557
    Kernel driver in use: vfio-pci
03:00.0 PCI bridge: ASMedia Technology Inc. ASM1083/1085 PCIe to PCI Bridge (rev 03)

Versões de software:

$ kvm --version
QEMU emulator version 2.5.0, Copyright (c) 2003-2008 Fabrice Bellard

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 14.04.3 LTS
Release:    14.04
Codename:   trusty

O problema é que quando eu executo windows_start.bash , o terminal QEMU é iniciado, mas nada está acontecendo. O monitor que está conectado à GPU NVIDIA é preto, ele deve estar ligado pelo QEMU, mas não. O que eu estou fazendo errado? Como posso depurar isso? O que mais eu posso tentar conseguir passar pela GPU?

Eu verifiquei usando este guia e parece que minha GPU não é compatível UEFI, então talvez essa seja a razão pela qual ele falha? Ainda é estranho, muitas pessoas tiveram sucesso usando GPUs ainda mais antigas, por isso deve ser um caminho.

EDIT: Acabei de tentar executar o vm com libvirt usando virt-manager , como sugerido por @Deltik. Aqui está o que minha configuração parece: link

O resultado foi praticamente o mesmo de antes - começou, mostrou uma tela preta na janela virt-manager e nada mais aconteceu. Não houve erros no console de depuração (que comecei executando virt-manager --debug ). Eu também tentei a mesma abordagem no Arch Linux e em uma versão mais recente do Ubuntu, não fazia diferença alguma.

Eu dei a recompensa para @Deltik, porque ele me deu alguns bons conselhos, mas eu ainda não consegui fazer funcionar. Parece que esta tarefa é impossível de concluir, pelo menos com o meu hardware atual.

    
por Victor Marchuk 13.02.2016 / 10:04

1 resposta

3

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:

    
por 26.02.2016 / 15:15