PIB - Linux - PCI-PassThrough

参考になるページ等

環境

  • Ubuntu 13.10 Desktop
  • CPU: Intel Core i7-3770
  • M/B: ASRock Z77 EXTREME6/TB4

Intel VT-d の有効化

Debian 系で package 提供されているコンパイル済みの kernel について、コンパイル時の設定を確認してみると以下のようになっている
$ grep IOMMU /boot/config-`uname -r`
...
CONFIG_INTEL_IOMMU=y
# CONFIG_INTEL_IOMMU_DEFAULT_ON is not set
...
このため、デフォルトだと IOMMU が無効な状態で kernel が起動する。
この状態で IOMMU を有効するには boot 時に kernel パラメータとして intel_iommu=on を渡す必要がある。
Bootloader に grub2 を用いているなら、
/etc/default/grub
に以下の設定をしておけば良い。
GRUB_CMDLINE_LINUX="intel_iommu=on"
起動後 IOMMU の状態は dmesg を用いると以下のようにして確認できる。
無効な場合
$ dmesg|grep IOMMU
[    0.000000] Please enable the IOMMU option in the BIOS setup
...
有効な場合
$ dmesg|grep IOMMU
[    0.000000] Intel-IOMMU: enabled
...

VGA BIOS のファイル化

出来れば VGA を 2 デバイス用意して BIOS を保存したい方のデバイスを未使用の状態にして作業したほうが良いらしい。

まず、目的のデバイスの確認
$ lspci -nn
...
00:02.0 VGA compatible controller [0300]: Intel Corporation Xeon E3-1200 v2/3rd Gen Core processor Graphics Controller [8086:0162] (rev 09)
...

以下のようにすれば /tmp/vgabios.rom に、VGA BIOS を取得出来るとのこと。
$ sudo bash -c 'cd /sys/bus/pci/devices/0000:00:02.0 && echo 1 > enable && echo 1 > rom && cat rom > /tmp/vgabios.rom && echo 0 > rom && echo 0 > enable'

VGA の解放

通常は X や console に使われているはずなので Device or resource busy と言われて VGA PassThrough に用いる事が出来ない。
そこで、/etc/modules に以下の行を追加しておくと起動時に pci-stub の管理下に入るため X に食われなくなる。
pci_stub ids=8086:0162
更に /etc/modprobe.d/blacklist.conf へ以下の行を追加すると console にも食われなくなる。
blacklist vesafb

VGA-PassThrough

Intel HD Graphics 4000 については以下のような感じで何とか動作に漕ぎ着けたが、かなり不安定。
sudo modprobe vfio_iommu_type1 allow_unsafe_interrupts=1
sudo modprobe vfio-pci
echo 0000:00:02.0 | sudo tee /sys/bus/pci/devices/0000\:00\:02.0/driver/unbind
echo 0x8086 0x0162 | sudo tee /sys/bus/pci/drivers/vfio-pci/new_id

sudo qemu-system-x86_64 \
-m 4096 \
-boot c \
-vga none \
-enable-kvm \
-device vfio-pci,host=00:02.0,bus=pcie.0,addr=02.0,multifunction=on,x-vga=on,rombar=0,romfile=/home/kou/Intel_HD_Graphics_4000.rom \
-device piix4-ide,bus=pcie.0,id=piix4-ide \
-drive file=/var/lib/libvirt/images/Windows.img,id=disk,format=raw -device ide-hd,bus=piix4-ide.0,drive=disk \
-usb -usbdevice host:0b39:0001 \
-nographic \
-M q35 \
-localtime \
-balloon virtio \
-cpu host \
-netdev type=user,id=guest0 \
-device virtio-net-pci,netdev=guest0 \
-bios /usr/share/qemu/bios.bin
負荷(?)がかかると落ちて再起動するため、VGAドライバーのインストールさえ出来ない状況。

仕方ないので GeForce 750Ti を接続してみた。
vfio: error, group 1 is not viable, please ensure all devices within the iommu_group are bound to their vfio bus driver
と言われてしまった。
どうも以下の post に該当している模様。 Linux 3.11, qemu 1.5 なのだが、
Linux 3.12, qemu 1.7 を使うことを考えなさいって。
仕方ないので、まだ公式リリースされてないが Ubuntu 14.04 に upgrade するために以下のコマンドを実行した。
sudo do-release-upgrade -d
以下のような感じで VGA-PassThrough 状態で起動出来た。
echo 0000:00:01.0 | sudo tee /sys/bus/pci/devices/0000\:00\:01.0/driver/unbind
echo 0x8086 0x0151 | sudo tee /sys/bus/pci/drivers/vfio-pci/new_id
echo 0000:01:00.0 | sudo tee /sys/bus/pci/devices/0000\:01\:00.0/driver/unbind
echo 0x10de 0x1380 | sudo tee /sys/bus/pci/drivers/vfio-pci/new_id
echo 0000:01:00.1 | sudo tee /sys/bus/pci/devices/0000\:01\:00.1/driver/unbind
echo 0x10de 0x0fbc | sudo tee /sys/bus/pci/drivers/vfio-pci/new_id

sudo qemu-system-x86_64 \
-m 4096 \
-boot c \
-vga none \
-enable-kvm \
-device vfio-pci,host=01:00.0,bus=pcie.0,addr=01.0,multifunction=on,x-vga=on,rombar=3,romfile=/home/kou/GV-N75TOC-2GI.rom \
-device vfio-pci,host=01:00.1,bus=pcie.0,addr=01.1 \
-device piix4-ide,bus=pcie.0,id=piix4-ide \
-drive file=/var/lib/libvirt/images/Windows.img,id=disk,format=raw -device ide-hd,bus=piix4-ide.0,drive=disk \
-usb -usbdevice host:0b39:0001 \
-nographic \
-M q35 \
-localtime \
-balloon virtio \
-cpu host \
-netdev type=user,id=guest0 \
-device e1000,netdev=guest0 \
-bios /usr/share/qemu/bios.bin
ファイルのダウンロード時に落ちて再起動する現象も発生しない。
これは実用になるかも。
と思ったのもつかの間、ダウンロードしてきた NVIDIA のドライバー入れたら、Windows 8.1 が起動しなくなった。

追記: 2014-04-24
dist-upgrade してみたら以下の設定でかなり安定して動作するようになった。
GeForce のドライバーインストールも Windows 8.1 Update への Windows Update も無事完了。
Ubuntu 14.04 が正式 release されたせいだろうか?
sudo \
qemu-system-x86_64 \
    -nodefconfig \
    -nodefaults \
    -nographic \
    -vnc none \
    -vga none \
    -enable-kvm \
    -M q35 \
    -cpu host \
    -smp 4,sockets=1,cores=2,threads=2 \
    -m 4096 \
    -boot menu=on \
    -display none \
    -monitor telnet::1381,server,nowait \
    -localtime \
    -device ioh3420,bus=pcie.0,addr=1c.0,multifunction=on,port=1,chassis=1,id=root.1 \
    -device vfio-pci,host=01:00.0,bus=root.1,addr=00.0,x-vga=on,multifunction=on,rombar=3,romfile=/home/kou/GV-N75TOC-2GI.rom \
    -device vfio-pci,host=01:00.1,bus=root.1,addr=00.1 \
    -device piix4-ide,id=ide,bus=pcie.0,addr=2.0 \
    -drive file=/home/kou/host.raw,format=raw,id=bootdisk \
      -device ide-hd,bus=ide.0,drive=bootdisk \
    -drive file=/home/kou/9600.16384.WINBLUE_RTM.130821-1623_X64FRE_ENTERPRISE_EVAL_JA-JP-IRM_CENA_X64FREE_JA-JP_DV5.ISO,id=isocd \
      -device ide-cd,bus=ide.1,drive=isocd \
    -drive file=/home/kou/virtio-win-0.1-74.iso,id=virtiocd \
      -device ide-cd,bus=ide.2,drive=virtiocd \
    -netdev type=user,id=guest0 \
    -device virtio-net-pci,netdev=guest0 \
    -soundhw ac97 \
    -usb \
    -usbdevice host:0b39:0001 \
    -serial none \
    -parallel none \

これなら実用になるかも。
Ubuntu をベースにストレージは ZFS で組んで Windows 8.1 Update 他、仮想マシンをいくつか乗っけて運用とか行けそう。
でも VM が suspend すると monitor から system_wakeup しても resume 出来ない。
環境は以下
  • Ubuntu 14.01. LTS Desktop 64bit 版
  • CPU: Intel Core i7-43770
  • M/B: ASRock H87 Pro4
  • GPU: RADEON7770
HD Graphics 4600 の ROM を抜こうとしたのだが
BIOS の設定が
  • Primary Graphics Adapter: PCI-Express
  • I-GPU Multimonitor: enabled
の状態だと
$ lspci -nn | grep -i graphics
00:02.0 Display controller [0380]: Intel Corporation Xeon E3-1200 v3/4th Gen Core Processor Integrated Graphics Controller [8086:0412] (rev 06)
となり、/sys/bus/pci/devices/0000:00:02.0/ 以下に rom が出て来ない。

BIOS の設定を
  • Primary Graphics Adapter: onboard
  • I-GPU Multi monitor: enabled
の状態にすると
$ lspci -nn | grep -i graphics
00:02.0 VGA compatible controller [0300]: Intel Corporation Xeon E3-1200 v3/4th Gen Core Processor Integrated Graphics Controller [8086:0412] (rev 06)
のようになり /sys/bus/pci/devices/0000:00:02.0/ 以下に rom が出て来た。

どうも、この M/B は firmware の動作が怪しいんだけど I-GPU Multimonitor の設定、ちゃんと反映されてるんだろうか?





関連