KVMに直接USBデバイスを認識させようと思いまして、はじめにUSBパススルーが思い浮かびました。が、調べてみるとフルスピードモード(12Mbps)なら簡単にできるけど、ハイスピードモード(480Mbps/USB2.0)を使うのは込み入った設定が必要っぽいです。だったらUSB2.0ホストコントローラごとPCIパススルーしてあげれば簡単でいいかなと思いました。やってみたところ、ちゃんと動いているので今日はその方法をまとめます。
- 環境
- BIOSの設定
- Grubの設定
- AMD
- Intel
- USBホストコントローラの確認
- VMの設定
- SE Linux
- VM起動
使用する VM Host の OS は Ubuntu 14.04 Server で、KVMの環境構築済み、ゲストOSが既に存在している前提です。
使ったマシンは HP ProLiant ML110 G7 ですが、汎用的な設定なので他のマシンでもできると思います。
AMDならAMD-Vi、IntelならVT-dをBIOSで有効にします。有効になっていないと、PCIパススルーができません。CPUが対応していてもBIOSが対応していないことがあります。対応していないとどうにもなりません。今回の最初のハードルにして最大のハードルです。
マシンを再起動してBIOSの設定画面を表示し、当該項目を確認しましょう。
OS起動時にハードウェア仮想化機能を有効にする設定を書きます。
CPUがAMDかIntelかによって設定するパラメータが違いますのでお気をつけて。
amd_iommu=on
intel_iommu=on
この設定を以下のファイルの2行に書き込みます。
$ sudo vi /etc/default/grub GRUB_CMDLINE_LINUX_DEFAULT="intel_iommu=on nomdmonddf nomdmonisw" GRUB_CMDLINE_LINUX="intel_iommu=on"
GRUBの設定を更新します。
$ sudo update-grub
そして再起動。
$ sudo reboot
マッピングされてそうなメッセージが出ていたらOK。
$ dmesg | grep IOMMU [ 0.000000] Intel-IOMMU: enabled ...
$ lspci -D | grep USB 0000:00:1a.0 USB controller: Intel Corporation 6 Series/C200 Series Chipset Family USB Enhanced Host Controller #2 (rev 05) 0000:00:1d.0 USB controller: Intel Corporation 6 Series/C200 Series Chipset Family USB Enhanced Host Controller #1 (rev 05)
この先頭の16進数の羅列、0000:00:1a.0が重要で、左から順に0000がdomain、00がbus、1aがslot、0がfunctionです。今回は、このUSB2.0ホストコントローラをPCIパススルーすることにします。USB3.0ホストコントローラでもできると思いますが、手元に試せるマシンがないのでやってません。Intel 7 Series、8 SeriesのEHCIとかxHCIもきっとできるんじゃないかな。
HP ML110 G7 では、0000:00:1a.0がフロントパネルUSBポートのコントローラで、0000:00:1d.0がバックパネルUSBポートのコントローラでした。設定するマシンのどのコントローラがどこのUSBポートを制御しているか確認しておきましょう。
deviceタグの下にこんな設定を追加してください。上で調べた domain、bus、slot、function はここで使います。
$ virsh edit YOUR_VM_NAME <device> ... <hostdev mode='subsystem' type='pci' managed='yes'> <source> <address domain='0x0000' bus='0x00' slot='0x1a' function='0x0'/> </source> </hostdev> ... </device>
SE Linux を使ってる場合にはこの設定が必要だそうです。僕は使ってないのでこれはしなくて大丈夫でした。
# setsebool -P virt_use_sysfs 1
ゲストOSが起動したらUSBポートに何か刺してみて、認識するかどうか確認してみましょう。
$ virsh start YOUR_VM_NAME
Enjoy!