Debian Squeeze環境のKVMでPCIパススルーしてみた〜pt2をゲストOSから使いたい!〜

我が家にvt-d搭載マシンがやってきた。つまり、これはパススルーを試してみて可能ならば実運用してあげないと、僕はきっとpciパススルーがしたくても出来ない子らに殺されてしまう。衝動が走る。僕は、これで、PT2のパススルー環境を、試さなければならない。
というわけで、PCIパススルーを用いて、Linux KVM(on Debian Squeeze)でゲストOSからpt2を使えるようにした。環境再構築して記事の検証を行うのが非常に手間であるため、今回も記憶を頼りに書いてゆく。この記事の内容を参考にするのは自由だが、その結果について、私は一切関知しない。心の準備はオーケー?

追記(2011/08/09)

二番組同時に録画すると、片方が録画してくれない現象発生……。もうホストで動かすお……。

環境

目的は、ゲストOS上にpt2のテスト環境を気軽に作ること。
mythTVやdvb版ドライバの挙動テスト等を行えるように。
使った環境は以下のとおり。

  • Host
    • ML110 G6 with Xeon3340
    • RAM 8GB
    • Debian Squeeze 64bit
  • Guest
    • Debian Squeeze 64bit
    • RAM 2GB割り当て

ゲストOSの管理にはlibvirtを使うとする。

やること

  1. ホストOSのvt-d有効設定
  2. USBパススルー(B-CASリーダ)、PCIパススルー(PT2)
  3. libvirtに定義を書く(上で行ったパススルー設定をlibvirtに反映させる)
  4. ゲストOSにドライバをインストール and 録画環境構築

ここでは、「ホストOSのvt-dの有効設定」と「libvirtに定義を書く」方法を紹介する。

ホストOSのvt-dの有効設定

BIOSの設定

ゲストOSにPCIバイスを見せるためには、intel vt-d(iommu)*1の設定を有効にしてやる必要がある*2。これは、チップセットの機能であるため、まずはBIOSで有効にしてやる必要が有る。これは、機種によって違うため説明を割愛する。ただし、マザーボードによってはvt-dの有効設定の「有効:無効」が逆転しているという話を耳にした*3。設定の際には注意されたい。

kernelオプションの設定

次に、起動時のカーネルオプションを有効にする。起動時のカーネルオプションはブートローダーの設定を変更する必要がある。Debian Squeezeのブートローダはgrub2になっているため、grub2の設定ファイルを書き換える。Debian Squeezeの場合は、/etc/default/grubにその設定ファイルがある。Ubuntuの場合も同様である。

...(省略)...
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT="quiet"
GRUB_CMDLINE_LINUX=""
...(省略)...

起動時オプションは、GRUB_CMDLINE_LINUXにて指定できる。ここを編集し、"intel_iommu=on"という引数を追加する。なお、amdの場合は、"amd_iommu=on"のようである*4

...(省略)...
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT="quiet"
#GRUB_CMDLINE_LINUX=""
GRUB_CMDLINE_LINUX="intel_iommu=on"
...(省略)...

さて、設定が終わったらこれを反映してやる必要が有る。これには、update-grubコマンドを用いる。

$ sudo update-grub
[sudo] password for m-bird: 
Generating grub.cfg ...
Found linux image: /boot/vmlinuz-2.6.32-5-amd64
Found initrd image: /boot/initrd.img-2.6.32-5-amd64
done

initramfsなどが自動で再構築され、設定が反映される。

libvirtの設定

次に、libvirtの設定を変更し、パススルー設定を固定化する。これには、virt-managerを使う方法が一番楽であるが、ここでは仮想マシン定義ファイルを編集する場合を解説する。

USBパススルー

B-CASカードリーダのパススルー設定を行う。ホストOSでのデバイスドライバアンロードなど詳細な解説は、上記参考サイトに譲り、ここでは最低限の作業手順のみ解説する。
まず、lsusbでUSBデバイスの確認を行う。

$lsusb
Bus 002 Device 004: ID 04e6:511a SCM Microsystems, Inc.
Bus 002 Device 003: ID 0000:0000  
Bus 002 Device 002: ID 8087:0020 Intel Corp. Integrated Rate Matching Hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 8087:0020 Intel Corp. Integrated Rate Matching Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

SCM Microsystems, Inc.が目的のデバイス。"04e6:511a"とあるのが、これは"vendor id : product id"となる。
libvirtd公式サイトの情報とおり、USBのパススルー設定を行う。"virsh edit マシン名"コマンドを使って、定義ファイルを編集する。

...(省略)...
    <devices>
    ...(省略)...
    <hostdev mode='subsystem' type='usb'>
      <source>
        <vendor id='0x04e6'/>
        <product id='0x511a'/>
      </source>
    </hostdev>
  </devices>
...(省略)...
PCIパススルー

同様にして、PCIバイスのパススルーを行う。まずは確認。

$lspci
...(省略)...
00:1f.2 IDE interface: Intel Corporation 5 Series/3400 Series Chipset 4 port SATA IDE Controller (rev 05)
00:1f.3 SMBus: Intel Corporation 5 Series/3400 Series Chipset SMBus Controller (rev 05)
00:1f.5 IDE interface: Intel Corporation 5 Series/3400 Series Chipset 2 port SATA IDE Controller (rev 05)
01:00.0 Ethernet controller: Intel Corporation 82574L Gigabit Network Connection
1c:00.0 VGA compatible controller: Matrox Graphics, Inc. MGA G200e [Pilot] ServerEngines (SEP1) (rev 02)
1e:00.0 Ethernet controller: Broadcom Corporation NetXtreme BCM5723 Gigabit Ethernet PCIe (rev 10)
30:00.0 Multimedia controller: Xilinx Corporation Device 222a (rev 01)

「Multimedia controller: Xilinx Corporation Device 222a」が目的のデバイス。"30:00.0"あるが、これは"bus:slot.funtion"となっている。
USBパススルーと同様、PCIパススルー設定をマシン定義ファイルに記述する。

  <devices>
    ...(省略)...
    <hostdev mode='subsystem' type='pci' managed='yes'>
      <source>
        <address domain='0x0000' bus='0x30' slot='0x00' function='0x0'/>
      </source>
    </hostdev>
  </devices>

以上で、libvirtの設定は完了。

ゲストOS上で確認する
$ lsusb
Bus 001 Device 002: ID 04e6:511a SCM Microsystems, Inc. 
Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
$ lspci
...(省略)...
00:03.0 Ethernet controller: Red Hat, Inc Virtio network device
00:04.0 SCSI storage controller: Red Hat, Inc Virtio block device
00:05.0 Multimedia controller: Xilinx Corporation Device 222a (rev 01)
00:06.0 RAM memory: Red Hat, Inc Virtio memory balloon

確かに、pt2とICカードリーダーがパススルーできていることを確認できた。

最後に

気をつける点を二点。

ゲストOSのメモリをケチるな

しょっぱい構成でも録画だけならスペック要らん要らんって言っている人が多いけれど、chardev版のドライバを使う場合は、メモリを積もう。「何故かrecpt1が動かない」「セグ落ちする」「意中の女の子が、恋に落ちない」等と言った不具合は、これが原因の場合がある。

実運用に投入するのには、注意

一度、PCIパススルー環境を作ったとき、ゲストOSがホストOSごと刺す、通称「親殺し」という事件が発生した。とても胸くそ悪い事件だったが、以下に環境を書き留めておく。

デバイスドライバやkernelの組み合わせなどによっては、ホストOSにまで影響を与える場合があるようだ。

追記 8/7
  • ホスト:Debian Squeeze 2.6.32(64bit)
  • ゲスト:Debain Squeeze 2.6.32(32bit)

という環境において、PT2が使用されると同時に

などの現象が確認された。
「Linuxカーネルの再構築方法@Debian Squeez」のエントリの手順を踏み、ホストOSのkernelのバージョンを2.6.39-RC4にあげたところ、PT2については安定して動作している。

ホストOSのカーネルのバージョンと、ゲストOSのデバイスドライバの組み合わせによって、動作が怪しかったりするようだ(@oracchaさん情報)。

なお、USBパススルーでゲストOSに提供しているICカードリーダーが、安定しない。いつの間にかパススルーされなくなっている時がある(ゲストでlsusbを行ってもデバイスが見えない)。どうやら、qemu-kvmでのUSBパススルー機能は不安定のようだ(ソースは某巨大掲示板)。
安定動作している方は、qemu-kvmのバージョンを教えてくれると有り難いです。なお、Debian Squeezeのqemu-kvmのバージョンは0.12.5。

参考リンク:「Plan 9 on KVMでもパススルーしてみる」- Plan9日記

*1:ハードウェアの仮想化支援機構の一つ:http://ja.wikipedia.org/wiki/IOMMU

*2:AMDのIOMMUでの動作報告は、まだみていない。恐らく、現状iommuの搭載マザーボードが非常に高価であるためだろう。

*3:BIOSTAR製との噂

*4:iommu=onという引数もあるようだが、これは前者二つを自動で認識して切り替えてくれるものなのだろうか?