【入門編】 PCIパススルー(Intel VT-d / AMD-Vi)とIOMMU(Input-Output Memory Management Unit)の動作 – クラウドインフラと仮想化ネットワーク実践ガイド

こんにちは!SRE兼クラウドアーキテクトの私です。

日頃からAWSやGCPといった巨大なメガクラウドのインフラを触っていると、「仮想マシン(VM)って本当に便利だな〜」としみじみ感じますよね。ボタンをポチるだけで数秒のうちにコンピュータが立ち上がり、ネットワークが繋がる。この魔法のような世界の裏側では、CPUやメモリ、そしてネットワークなどのハードウェアを上手に分け合うための「仮想化技術」が日夜フル回転しています。

さて、そんな仮想化の世界ですが、今回は少しマニアック、けれどいざという時に「これを知らないと仕事が進まない!」という超重要テーマに直球で切り込みます。それが「PCIパススルー」と、それを下支えするハードウェアの守護神「IOMMU(Intel VT-d / AMD-Vi)」です。

「なんだか名前からして難しそう……」と思いましたか? 大丈夫です! 一歩ずつ、身近な例えを交えながら優しく紐解いていきましょう!

—

1. 仮想化の「居候問題」と、究極の解決策「パススルー」

普段私たちが使っている仮想マシンは、いわば「アパートの住人」のようなものです。大家さんであるハイパーバイザー(KVMやVMware ESXiなど)が全体の部屋割りや水道(メモリ)の管理をしていて、住人たちは仲良く資源をシェアしています。

一般的なネットワークカード(NIC)やディスクを使うときも、この大家さんを経由して「すみません、このデータを外に送ってください」とお願いする仕組み(エミュレーション)になっています。

なぜパススルーが必要なの?

しかし、世の中には「どうしても我慢できないほど超高速な処理がしたい!」というアパートの住人がいます。例えば、AIのディープラーニング学習を行うための超高価なGPUや、100Gbpsを超えるようなモンスター級のネットワークカードです。

これらを大家さん経由で使おうとすると、どうしても「お伺い」を立てるオーバーヘッド(手間)が発生し、本来の性能が発揮できません。

そこで登場するのが「PCIパススルー」です。これは、アパートの共用スペースを通すのではなく、「特定の部屋専用の専用通路を直接ドカンと作っちゃおう!」という荒業です。物理的なハードウェア(NICやGPUなど)を、特定の仮想マシンに丸ごと専有(アサイン)させることで、ベアメタル(物理サーバー)とほぼ変わらない極限のパフォーマンスを引き出すことができます。

—

2. 郵便配達員が大混乱? パススルーが抱える「安全性のジレンマ」

専用通路を作って物理デバイスを直結させるのはいいのですが、ここで一つ大きな問題が立ち塞がります。それが「DMA(Direct Memory Access)」という仕組みです。

少しイメージしてみてください。
ネットワークカードなどの賢いハードウェアは、CPUにお伺いを立てることなく、自分の判断でパソコン内のメモリ(机の上)に直接データを読み書き(配達)する能力を持っています。これがDMAです。

もし、仮想マシンに物理NICをそのまま渡してしまうと、何が起きるでしょうか?
悪意あるプログラムや、ちょっとおバカなプログラムが暴走したとき、NICが「他の仮想マシンや、ホストOS(大家さん)のプライベートなメモリ領域」に勝手にズカズカ入り込んで、データを書き換えたり盗み見たりできてしまうのです。これはセキュリティ上、大問題ですよね。

現実世界で例えるなら、宅配業者がマンションの各部屋の合鍵を勝手に持って歩き回り、宛先を確認せずにどの部屋の冷蔵庫にでも勝手に荷物を詰め込んでいるような状態です。危険すぎますよね。

—

3. 救世主「IOMMU」の登場:メモリの警備員さん

この「暴走するDMAの脅威」からシステム全体を守り抜くために生まれたのが、今回の主役であるIOMMU(Input-Output Memory Management Unit)です。Intelの世界では Intel VT-d、AMDの世界では AMD-Vi と呼ばれているハードウェア機能になります。

IOMMUは、いわば「メモリへの出入り口を厳重に監視する、超優秀な警備員兼カーナビゲーションシステム」です。

IOMMUがやっていることは大きく分けて2つあります。

1. DMAリマップ(宛先の監視と書き換え)

  • デバイスが「このメモリに書き込むぞ!」と言ってきたとき、IOMMUという警備員が「おいおい、お前がアクセスしていいのはあそこの部屋の机の上だけだ! こっちは立ち入り禁止だ!」とチェックし、安全なアドレスに交通整理(リマップ)します。

2. 割り込み再マッピング(Interrupt Remapping)

  • デバイスからの「助けて!(割り込み信号)」という叫び声を安全に宛先へ届けます。これも不正な割り込みでシステム全体がクラッシュするのを防ぐために不可欠です。

このIOMMUというハードウェア支援があるおかげで、私たちは「物理デバイスの爆速な性能を仮想マシンにそのまま使わせつつ、安全性はガッチリ担保する」という、いいとこ取りができるようになっているのです。

—

4. 【実務編】KVM/QEMU環境でIOMMUとパススルーを有効化する手順

「理屈は分かったけれど、現場ではどう設定するの?」という声にお応えして、ここからはLinux(KVM/QEMU)環境をベースにした具体的な設定の流れを見ていきましょう。

一歩ずつ、安全に進めていきますよ!

ステップ1: BIOS/UEFIでの有効化

大前提として、マザーボードのBIOS(UEFI)設定画面で、Intelなら Intel Virtualization Technology for Directed I/O (VT-d)、AMDなら AMD IOMMU を必ず Enabled にしてください。ここがオフだと、どれだけOS側で頑張ってもIOMMUは動きません。

ステップ2: カーネルパラメータの設定(GRUBの編集)

OSが起動するときに、IOMMUを有効化するよう指示を出します。/etc/default/grub を開き、Linuxカーネルの起動オプションに追記します。

# /etc/default/grub の該当箇所を編集します(root権限が必要です)
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash intel_iommu=on iommu=pt"

> ※ AMD製CPUの場合は、intel_iommu=on の代わりに amd_iommu=on を指定してください。
> ※ iommu=pt(Passthrough)を指定することで、パススルーしない通常のデバイスのパフォーマンス低下を防ぎつつ、必要なデバイスだけを効率よく保護できます。

設定を保存したら、GRUBの設定を更新してシステムを再起動します。

# UbuntuやDebianの場合のGRUB更新コマンド
sudo update-grub

# 再起動を実行
sudo reboot

ステップ3: IOMMUグループの確認

再起動後、IOMMUが正しく機能し、ターゲットのデバイスが独立したグループ(部屋)に分かれているかを確認します。以下のシェルスクリプトを実行してみてください。

#!/bin/bash
# IOMMUグループごとに割り当てられているデバイスを確認するスニペット
shopt -s nullglob
for d in /sys/kernel/iommu_groups/*/devices/*; do
    n=${d#*iommu_groups/}; n=${n%%/*}
    printf 'IOMMU Group %s: ' "$n"
    lspci -nns "${d##*/}"
done

このコマンドを実行すると、次のような出力が得られます。

IOMMU Group 12: 01:00.0 Ethernet controller [0200]: Intel Corporation I350 Gigabit Network Connection [8086:1521] (rev 01)

この「IOMMU Group」の切り分けが非常に重要です。もし、パススルーしたいNICが、他の重要なグラフィックボードやUSBコントローラーと同じグループに相乗りしている場合、そのグループ全体をまとめてパススルーしなければならず、ホストOS側の動作に支障が出る場合があります。現場のハードウェア選定では、「NICが独立したIOMMUグループを持っているか」を事前に確認するのがプロの技です。

ステップ4: VFIOドライバへのバインドとVMへのアタッチ

デバイスを仮想マシンに渡す準備として、ホストOSの通常のドライバから、仮想化用の安全なドライバ(vfio-pci)にバインドを切り替えます。

# 対象のデバイス(例: 01:00.0)をVFIOドライバに紐付ける設定例
# あらかじめホストの標準ドライバ(ixgbeやe1000eなど)からデタッチしておきます
sudo modprobe vfio-pci

# PCIアドレスを指定してVFIOにバインド(実際にはlibvirtやXML設定で自動化することが多いです)
echo "8086 1521" | sudo tee /sys/bus/pci/drivers/vfio-pci/new_id

Libvirt(KVMの管理ツール)を使う場合、仮想マシンの設定XMLファイルに以下のような <hostdev> タグを記述することで、無事に物理NICを仮想マシンへ直結させることができます。

<!-- 仮想マシン定義XMLファイルのデバイスセクションの例 -->
<hostdev mode='subpass' type='pci' managed='yes'>
  <source>
    <address domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
  </source>
  <!-- ホスト側のIOMMUが安全にDMAリマップを行います -->
</hostdev>

—

まとめ:仕組みを知れば、クラウドも怖くない!

今回は、仮想化ネットワークの裏側を支える「PCIパススルー」と「IOMMU」について、郵便配達やマンションの警備員という身近な例えを交えながら解説しました。

  • PCIパススルーは、物理デバイスの性能を限界まで引き出すための「専用の直結通路」。
  • IOMMU(VT-d / AMD-Vi)は、その直結通路で不正なメモリ書き込みが起きないように目を光らせる「優秀な警備員」。

一見すると難解なハードウェア機能も、「なぜそれが必要なのか(セキュリティとパフォーマンスの両立)」という文脈(ストーリー)さえ掴んでしまえば、インフラ設計やトラブルシューティングの心強い武器になります。

日々のインフラ運用で「なぜこの設定が必要なんだっけ?」と立ち止まったときは、ぜひ今回の郵便配達の例えを思い出してみてくださいね。それでは、また次回のディープな技術解説でお会いしましょう!SREチームより愛を込めて。

コメント

タイトルとURLをコピーしました