web-dev-qa-db-ja.com

GPUパススルーを備えたQEMUが起動しない

Ubuntuを実行していて、GPUパススルーを使用してQEMUを構成しようとしています。私はそれらのガイドに従っていました:

https://www.youtube.com/watch?v=w-hOr44oBAI

https://www.pugetsystems.com/labs/articles/Multiheaded-NVIDIA-Gaming-using-Ubuntu-14-04-KVM-585/#Step5Createascripttoruneachvirtualmachine

http://www.howtogeek.com/117635/how-to-install-kvm-and-create-virtual-machines-on-ubuntu/

私の/etc/modules

lp
rtc
pci_stub
vfio
vfio_iommu_type1
vfio_pci
kvm
kvm_intel 

私の/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=""

私の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)

私の/etc/initramfs-tools/modules

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

pci_stubは機能しているようです:

$ 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

私の/etc/vfio-pci1.cfg

0000:01:00.0
0000:01:00.1

私の~/windows_start.bashhttp://Pastebin.com/F7fq2Szt

Bashスクリプトを実行した後、vfio-pciがドライバーとして使用されています。

$ 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)

ソフトウェアバージョン:

$ 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

問題は、windows_start.bashを実行すると、QEMUターミナルが起動しますが、何も起こらないことです。 NVIDIA GPUに接続されているモニターは黒で、QEMUによってオンになっているはずですが、そうではありません。私は何が間違っているのですか?どうすればデバッグできますか? GPUパススルーを実現するために他に何を試みることができますか?

このガイド を使用して確認しましたが、GPUがUEFIをサポートしていないようですが、それが失敗の理由でしょうか?それはまだ奇妙です、 多くの人が成功しました さらに古いGPUを使用しているので、方法が必要です。

編集:@Deltikが提案したように、virt-managerを使用してlibvirtでvmを実行しようとしました。私の設定は次のようになります: http://Pastebin.com/W46kNcrh

結果は以前とほとんど同じでした。開始され、virt-managerのウィンドウに黒い画面が表示され、他に何も起こりませんでした。デバッグコンソールにエラーはありませんでした(virt-manager --debugを実行して開始しました)。 Arch Linuxと新しいバージョンのUbuntuでも同じアプローチを試しましたが、まったく違いはありませんでした。

@Deltikが私にいくつかの良いアドバイスをくれたので、私はその恩恵を与えましたが、それでも私はそれを機能させることができませんでした。少なくとも私の現在のハードウェアでは、このタスクを完了することは不可能のようです。

4
Victor Marchuk

あなたは近くにいます。

_pci-stub_と_vfio-pci_の両方を使用する

グラフィックスドライバー(nouveaufglrxなど)は取得しないため、_pci-stub_を使用してPCIデバイス(GPUなど)を予約し、グラフィックスドライバーがそれを取得しないようにすることは問題ありません。デバイスを手放します。

実際、私のテストでは、最初に_pci-stub_でPCIグラフィックカードを要求する必要がありました。これは、_vfio-pci_が起動時に要求しないためです。これは、発生した問題の1つです。 1つのドライバー(_pci-stub_)をアンロードし、その場所に別の(_vfio-pci_)をロードしている間、 一部には醜いようです 、_pci-stub_および_vfio-pci_はGPUパススルーを備えた仮想マシンを成功させる信頼性の高いタグチーム。私のテストでは、どちらか一方だけを使用しても成功しませんでした。

ここで、PCIデバイスを_pci-stub_から解放し、_vfio-pci_に渡す必要があります。スクリプトのこの部分は、すでにそれを実行しているはずです。

_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
_

警告:「vfiobind」は1回だけ必要です

このコメント に記載されているように、_pci-stub_から_vfio-pci_への切り替えは、起動後に1回だけ実行する必要があるのは事実です。これは真実ですが、仮想マシンが現在影響を受けるものを使用している場合を除いて、「vfiobind」関数を複数回実行しても実際には無害です PCIデバイス。

仮想マシンがデバイスを使用している場合、バインド解除操作はブロックされます( "D状態"プロセス )。これは、仮想マシンをシャットダウンまたは強制終了することで修正できます。その後、バインド解除はおそらく成功します。

vfiobind()関数を次のように変更することで、この不要な余分なバインド解除と再バインドを回避できます。

_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"
}
_

_lspci -k_ドライバーの接続が成功したかどうかを_vfio-pci_で確認してください

_vfio-pci_が_lspci -k_を使用して引き継いだことを確認します。この例は、同等の設定からのものです。

_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
_

_Kernel driver in use: vfio-pci_が表示されない場合は、上に貼り付けたスクリプトの一部に問題があります。

QEMUパススルー構成

私は黒いディスプレイで少し苦労しました。

スクリプトの以前のリビジョンでは、次のように指定しました。

_-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 \
_

使用する仮想バスとアドレスをQEMUに決定させてみてください。

_-device vfio-pci,Host=01:00.0,multifunction=on,x-vga=on \
-device vfio-pci,Host=01:00.1 \
_

また、_-nographic_フラグと_-vga none_フラグを_qemu-system-x86_64_に渡す必要があります。デフォルトでは、QEMUはエミュレートされたグラフィックカードを仮想マシンに公開し、仮想マシンは、意図した物理NVIDIAカードの代わりに、この他のビデオデバイスを使用して表示する場合があります。

それでも空白の表示が表示される場合は、_-nodefaults_フラグも追加してみてください。これには、デフォルトのシリアルポート、パラレルポート、仮想コンソール、モニターデバイス、VGAアダプター、フロッピーデバイス、およびCD-ROMデバイスが含まれません。

これで、_qemu-system-x86_64_コマンドがPCIデバイス_01:00.0_と_01:00.1_を通過させて仮想マシンを起動できるようになり、_01:00.0_に接続されたディスプレイに何かが表示されるはずです。

リファレンス/サンプル構成

私のテストはあなたのテストと同じではありませんが、_qemu-system-x86_64_から_pci-stub_で関連するすべてのPCIデバイスを要求した後、この_vfio-pci_コマンドでグラフィックパススルーとUSBパススルーを機能させることができました。

_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
_

_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
_

観測結果:

Photograph of the observed result

3
Deltik