nkjmkzk.net

powered by Kazuki Nakajima

VT-dを使ってXenでPCI-Passthroughを設定する手順

システム環境

  • CPU: Intel Core-i7 860
  • チップセット: Intel P55 Express
  • マザーボード: MSI P55M-SD40
  • Xen: 3.4.0
  • dom0: Oracle VM Server (Oracle Enterprise Linux 5.3ベース)
  • Passthrough対象のdomU: OpenSolaris b134 PVHVM

Xenは既にインストールされているという前提で始めます。/etc/grub.confのkernel行に「iommu=pv」と追記してI/O Virtualizationを有効化します。*これはBIOSでの有効とは異なります。BIOSでI/O Virtualizationを有効にした上でこの設定を行います。参考までにgrub.conf全体を。

default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title Oracle VM server (2.6.18-128.2.1.4.25.el5xen)
	root (hd0,0)
	kernel /xen-64bit.gz dom0_mem=564M iommu=pv
	module /vmlinuz-2.6.18-128.2.1.4.25.el5xen ro root=UUID=d060bc44-d5d2-49ec-8312-222c761a3746
	module /initrd-2.6.18-128.2.1.4.25.el5xen.img

*より一般的にはiommu=1と設定しますが、これではPVM(準仮想化マシン)に対してのPassthroughが有効にならないのでiommu=pvとしています。iommu=pvとすればHVM, PVM双方でPassthroughが有効になります。

ここで一度OSを再起動します。再起動後、xm dmesgコマンドを発行してI/O Virtualizationが有効になったことを確認します。

[root@vmserver]# xm dmesg | grep "I/O virtualisation"
(XEN) I/O virtualisation enabled
(XEN) I/O virtualisation for PV guests enabled

*ちなみにgrepする場合はvirtualizationではなく上記のようにvirtualisationで引っ掛けてください。

次にdomUにPassthroughしたいPCIデバイスをdom0から隠します。作業の流れとしては、まず対象となるPCIデバイスのBDFを求めます(BDFについて詳しくはこちら)。次にPCIデバイスをdom0から隠すためのカーネルモジュール「pciback」をロードします。そしてsysファイルシステムを使うか、modprobe.confに適当な記述を行うことでPCIデバイスをdom0から隠しdomUにPassthrough可能な状態にします。

BDFはlspciコマンドでPCIデバイスの一覧を表示させ、それっぽいモノを判別します。

[root@vmserver]# lspci
00:00.0 Host bridge: Intel Corporation Clarksfield/Lynnfield DMI (rev 11)
00:03.0 PCI bridge: Intel Corporation Clarksfield/Lynnfield PCI Express Root Port 1 (rev 11)
00:08.0 System peripheral: Intel Corporation Clarksfield/Lynnfield System Management Registers (rev 11)
00:08.1 System peripheral: Intel Corporation Clarksfield/Lynnfield Semaphore and Scratchpad Registers (rev 11)
00:08.2 System peripheral: Intel Corporation Clarksfield/Lynnfield System Control and Status Registers (rev 11)
00:08.3 System peripheral: Intel Corporation Clarksfield/Lynnfield Miscellaneous Registers (rev 11)
00:10.0 System peripheral: Intel Corporation QPI Link (rev 11)
00:10.1 System peripheral: Intel Corporation QPI Routing and Protocol Registers (rev 11)
00:1a.0 USB Controller: Intel Corporation Ibex Peak USB2 Enhanced Host Controller (rev 05)
00:1b.0 Audio device: Intel Corporation Ibex Peak High Definition Audio (rev 05)
00:1c.0 PCI bridge: Intel Corporation Ibex Peak PCI Express Root Port 1 (rev 05)
00:1c.4 PCI bridge: Intel Corporation Ibex Peak PCI Express Root Port 5 (rev 05)
00:1c.5 PCI bridge: Intel Corporation Ibex Peak PCI Express Root Port 6 (rev 05)
00:1d.0 USB Controller: Intel Corporation Ibex Peak USB2 Enhanced Host Controller (rev 05)
00:1e.0 PCI bridge: Intel Corporation 82801 PCI Bridge (rev a5)
00:1f.0 ISA bridge: Intel Corporation Ibex Peak LPC Interface Controller (rev 05)
00:1f.2 IDE interface: Intel Corporation Ibex Peak 4 port SATA IDE Controller (rev 05)
00:1f.3 SMBus: Intel Corporation Ibex Peak SMBus Controller (rev 05)
00:1f.5 IDE interface: Intel Corporation Ibex Peak 2 port SATA IDE Controller (rev 05)
01:00.0 VGA compatible controller: nVidia Corporation Unknown device 0a65 (rev a2)
01:00.1 Audio device: nVidia Corporation Unknown device 0be3 (rev a1)
03:00.0 SATA controller: 1b4b:9123 (rev 11)
04:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168B PCI Express Gigabit Ethernet controller (rev 03)

手元の環境では増設したSATAコントローラ(赤字)がPassthroughしたいPCIデバイスです。したがって対象のBDFは03:00.0です。が、実際にはこの番号の頭に0000:をくっつけて、『0000:03:00.0」が正式なBDFで、この後もこちらの正式なBDFを使用します。

*ちなみに00:1f.0, 00:1f.2, 00:1f.3, 00:1f.5のように下一桁だけが異なるものはマルチファンクションのPCIデバイスです。この例ではこのPCIデバイスはオンボードのSATAコントローラ・ブリッジで、6ポートのSATAポートを装備しています。そしてこの内4ポートが00:1f.2に属しており、2ポートが00:1f.5に属しています。一度00:1f.2にSSDを一枚差し、00:1f.5にSSDを一枚差して後者だけをdomUにPassthroughできるか試してみましたが、結果はNGでした。Xen 3.4.0とXen 4.0.0両方でトライしましたが、前者は一見うまくいったように見えるのですがその内I/Oエラーやファイルシステムのジャーナルエラーが報告され、domo, domUともフリーズしました。後者は割り当てた瞬間にフリーズが発生しました。DMAのマップがめちゃくちゃになってそうな雰囲気です。

次にpcibackのロードですが、Oracle VM Serverのdom0カーネルでは(恐らく多くの他の環境でも)、pcibackはカーネルに組み込まれてビルドされておらずモジュールとしてビルドされています。この状態ではpcibackはオンラインでmodprobeコマンドによってロードできますが、逆にブート時にカーネルパラメータを渡すことでロードすることはできません。自動的にロードさせたい場合はブートのもう少し後の段階でロードします。具体的にはrc.localかmodprobe.confを少々編集します。今回はrc.localに記載する手順で話を進めます。そしてロードに続けてPCIデバイスをdom0から隠しPassthrough可能にする設定を行います。これらをまとめてrc.localに下記のように記述します。

BDF=0000:03:00.0
# Load pciback
modprobe pciback
# Unbind a PCI function from its driver as necessary
[ ! -e /sys/bus/pci/devices/$BDF/driver/unbind ] || \
        echo -n $BDF > /sys/bus/pci/devices/$BDF/driver/unbind
# Add a new slot to the PCI Backend's list
echo -n $BDF > /sys/bus/pci/drivers/pciback/new_slot
# Now that the backend is watching for the slot, bind to it
echo -n $BDF > /sys/bus/pci/drivers/pciback/bind

*pcibackはpvops採用のdom0カーネルではxen-pcibackと名前が変更されています。

*環境によってはPCIデバイスをunbindした瞬間にOSがクラッシュするかもしれません。僕はahciドライバで認識しているデバイスをunbindしたときにこのクラッシュに遭遇しました。これを回避するためにはrc.localではなくmodprobe.confを利用する設定方法が有効でした。ahci等のドライバがデバイスを認識する前にpcibackをロードして該当デバイスを隠蔽することによって回避することができました。詳しくはこちらの2.の手法を参照してください。skgeは手元の環境に合わせて変える必要があります。

設定がうまくいっていれば、xm pci-list-assignable-deviceで確認できます。

[root@vmserver]# xm pci-list-assignable-device
0000:03:00.0

この出力が確認できれば対象のPCIデバイスはPassthroughされる準備が整っています。あとはdomUの設定ファイルにてpci = [ '0000:03:00.0' ]の記述を入れてdomUを起動すればPassthroughが実現できます。参考までに手元のOpenSolaris b134のPVHVMの設定ファイルを掲載しておきます。

acpi = 1
apic = 1
builder = 'hvm'
device_model = '/usr/lib/xen/bin/qemu-dm'
disk = ['file:/var/ovs/mount/4ED5C364C05246FE8AEE8C0E26D79ACF/running_pool/nas/System.img,hda,w',
',hdc:cdrom,r',
]
kernel = '/usr/lib/xen/boot/hvmloader'
keymap = 'en-us'
memory = '1024'
name = 'nas'
on_crash = 'restart'
on_reboot = 'restart'
pae = 1
pci = ['0000:03:00.0']
serial = 'pty'
timer_mode = '0'
uuid = '42d9bfd3-dd90-4b54-a8a0-af90bcc53028'
vcpus = 4
vif = ['bridge=xenbr0,mac=00:16:3E:15:01:3E,type=netfront']
vif_other_config = []
vnc = 1
vncconsole = 1
vnclisten = '0.0.0.0'
vncpasswd = 'secret'
vncunused = 1

正直PCI-Passthroughの設定はなかなかクセがあり、苦労しました。動いたように見えて半日くらいしてからI/Oエラーがでたり、サーバ全体がクラッシュしたり、デバイスによっては隠蔽設定はうまくいくもののxm pci-list-assignable-deviceには表示されなかったり、Xenのバージョンによってかなり挙動が違ったり。下記にPCI-Passthroughにおける教訓を掲載しておきます 。

  • マルチファンクションデバイスの一部だけPassthroughしようとしない。Passthroughするときは丸ごと。
  • Linuxで確実に動作する鉄板のPCIデバイスを使う。
  • Xenは出来る限り新しいバージョンを使う。
  • 動いたと思っても油断しない。最低1日はヒートランすべき。

*今回検証した機材の他に、下記の組み合わせでも動作を確認しています。ご参考まで。

  • CPU: Intel Core-i7 860
  • チップセット: Intel H55 Express
  • マザーボード: Intel DH55TC
  • Xen: 4.0.0
  • dom0: Fedora12 kernel 2.6.32
  • Passthrough対象のdomU: OpenSolaris b134 PVHVM

with 2 comments

Written by 中嶋 一樹

5月 4th, 2010 at 3:08 am

Posted in Uncategorized

Tagged with , ,

2 Responses to 'VT-dを使ってXenでPCI-Passthroughを設定する手順'

Subscribe to comments with RSS or TrackBack to 'VT-dを使ってXenでPCI-Passthroughを設定する手順'.

  1. [...] それでは別エントリでこのPCI-Passthroughの構成方法を解説しようと思います。 [...]

  2. はじめまして.
    非常に参考になりました.

    ひとつ疑問に思ったのですが,P55チップセットとH55チップセットは,
    VT-dに対応していないと思うのですが,この場合は必要ないとか
    あるのでしょうか?

    こっちん

    6 7月 10 at 4:51 AM

Leave a Reply