マクスのメモ帳

ブログではキレイなマクスでありたい。Twitterは知らん。

PCIパススルー(失敗)

下記の公式ドキュメントに従ってパススルーを設定していく。

docs.opennebula.org

KVMホストでIOMMU機能を有効化。

# vi /etc/default/grub
GRUB_CMDLINE_LINUX="intel_iommu=on"
# update-grub 

再起動。 次にパススルーするデバイスを確認。

# lspci -nn
00:00.0 Host bridge [0600]: Intel Corporation Celeron N3350/Pentium N4200/Atom E3900 Series Host Bridge [8086:5af0] (rev 0b)
00:02.0 VGA compatible controller [0300]: Intel Corporation Celeron N3350/Pentium N4200/Atom E3900 Series Integrated Graphics Controller [8086:5a84] (rev 0b)
00:0e.0 Audio device [0403]: Intel Corporation Celeron N3350/Pentium N4200/Atom E3900 Series Audio Cluster [8086:5a98] (rev 0b)
00:0f.0 Communication controller [0780]: Intel Corporation Celeron N3350/Pentium N4200/Atom E3900 Series Trusted Execution Engine [8086:5a9a] (rev 0b)
00:12.0 SATA controller [0106]: Intel Corporation Celeron N3350/Pentium N4200/Atom E3900 Series SATA AHCI Controller [8086:5ae3] (rev 0b)
00:13.0 PCI bridge [0604]: Intel Corporation Celeron N3350/Pentium N4200/Atom E3900 Series PCI Express Port A #1 [8086:5ad8] (rev fb)
00:13.1 PCI bridge [0604]: Intel Corporation Celeron N3350/Pentium N4200/Atom E3900 Series PCI Express Port A #2 [8086:5ad9] (rev fb)
00:13.2 PCI bridge [0604]: Intel Corporation Celeron N3350/Pentium N4200/Atom E3900 Series PCI Express Port A #3 [8086:5ada] (rev fb)
00:13.3 PCI bridge [0604]: Intel Corporation Celeron N3350/Pentium N4200/Atom E3900 Series PCI Express Port A #4 [8086:5adb] (rev fb)
00:15.0 USB controller [0c03]: Intel Corporation Celeron N3350/Pentium N4200/Atom E3900 Series USB xHCI [8086:5aa8] (rev 0b)
00:1f.0 ISA bridge [0601]: Intel Corporation Celeron N3350/Pentium N4200/Atom E3900 Series Low Pin Count Interface [8086:5ae8] (rev 0b)
00:1f.1 SMBus [0c05]: Intel Corporation Celeron N3350/Pentium N4200/Atom E3900 Series SMBus Controller [8086:5ad4] (rev 0b)
01:00.0 Ethernet controller [0200]: Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller [10ec:8168] (rev 11)
03:00.0 SATA controller [0106]: ASMedia Technology Inc. ASM1062 Serial ATA Controller [1b21:0612] (rev 02)
04:00.0 PCI bridge [0604]: Pericom Semiconductor PI7C9X111SL PCIe-to-PCI Reversible Bridge [12d8:e111] (rev 02)
05:04.0 Multimedia controller [0480]: Xilinx Corporation Device [10ee:211a] (rev 01)

Intel VGA

# lspci -nnk -d 8086:5a84
00:02.0 VGA compatible controller [0300]: Intel Corporation Celeron N3350/Pentium N4200/Atom E3900 Series Integrated Graphics Controller [8086:5a84] (rev 0b)
        Subsystem: ASRock Incorporation Celeron N3350/Pentium N4200/Atom E3900 Series Integrated Graphics Controller [1849:5a84]
        Kernel driver in use: i915
        Kernel modules: i915

PT2。

# lspci -nnk -d 10ee:211a
05:04.0 Multimedia controller [0480]: Xilinx Corporation Device [10ee:211a] (rev 01)
        Subsystem: Device [ef11:dee5]
        Kernel driver in use: earth-pt1
        Kernel modules: earth_pt1

カードリーダー。

# lsusb -d 08e6:3437
Bus 001 Device 002: ID 08e6:3437 Gemalto (was Gemplus) GemPC Twin SmartCard Reader

vfioモジュールを読み込むように設定。

# vi /etc/modules
vfio
vfio_iommu_type1
vfio_pci 
vfio_virqfd

PCIバイスのモジュールをブラックリストに登録。

# vi /etc/modprobe.d/blacklist.conf
blacklist earth_pt1
blacklist i915
# vi /etc/modprobe.d/vfio.conf
options vfio-pci ids=8086:5a84,10ee:211a

再起動して確認。

# lspci -v -d 10ee:211a | grep Kernel
        Kernel driver in use: vfio-pci
        Kernel modules: earth_pt1
# lspci -v -d 8086:5a84 | grep Kernel
        Kernel driver in use: i915
        Kernel modules: i915

VGAだけ変わらない・・・下記のようにしてみた。

# vi /etc/default/grub
GRUB_CMDLINE_LINUX="intel_iommu=on modprobe.blacklist=i915"
# update-grub

当然だけど、画面出力は止まる。

# lspci -v -d 8086:5a84 | grep Kernel
        Kernel driver in use: vfio-pci
        Kernel modules: i915

下記を修正して再起動。設定内容は公式参照で。

# vi /var/lib/one/remotes/etc/im/kvm-probes.d/pci.conf

それでもPCIタブが表示されない。
下記を実行したら出るようになった。

# rm -r /var/tmp/one/*
# onehost sync --force <ID>

vifoデバイスバインディング設定。

# vi /usr/local/bin/vfio-bind
#!/bin/sh
modprobe vfio-pci
for dev in "$@"; do
        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
done

# chmod +x /usr/local/bin/vfio-bind

設定ファイル。

# /etc/vfio-bind.conf
DEVICES="0000:00:02.0 0000:05:04.0"

サービス設定。

# vi /etc/systemd/system/vfio-bind.service
[Unit]
Description=Binds devices to vfio-pci
After=syslog.target

[Service]
EnvironmentFile=-/etc/vfio-bind.conf
Type=oneshot
RemainAfterExit=yes
ExecStart=-/usr/local/bin/vfio-bind $DEVICES

[Install]
WantedBy=multi-user.target

シンボリックリンク作成。

# ln -s /lib/systemd/system/vfio-bind.service /etc/systemd/system/vfio-bind.service

と、ここまで設定したのはいいのだが、
下記のコマンドでiommuグループを調べるとPCIeのグループが全て同じ・・・

# find /sys/kernel/iommu_groups/ -type l

qemuの仕様上、同グループの一部だけパススルーするということはできないらしい。
Ethernetも同じグループなので参った。。。
Kernelにパッチ当ててACSなるものでグループを分けることも試みてみたがダメそう。(Xenならできる?)
USB-LANを接続してうまいこと出来る気もするけどそこまでやるか悩む。