1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Ubuntu+KVM+GVT-gで仮想GPUを仮想環境に割り当てる

Last updated at Posted at 2024-12-12

概要

お久しぶりです。えぢぢーんです。
適当な気持ちでandroidアプリを作ろうとしたら、
すごく難しかったので、息抜きでUbuntuをいじってました。

dj_neko.gif

本日やるとことはUbuntuのKVMで仮想環境を作り、そこにIntel GVT-gを使ってiGPU(仮想GPU)を割り当てることです。

ユースケースとしてはどうしても仮想環境にgpuを割り当てたいけど、GPUパススルーは嫌だ(そんな人いる?)そんな人に向けた記事です。

ちょっと説明

おそらくこういうことをやるならほんとはNVIDIAのGPUを仮想化することがゴールになると思いますが、現状NVIDIAのGPU仮想化はサーバー用のGPUに限られており、基本的にはコンシューマ版のGPUの仮想化は対応していません。(なんか有志が作ったパッチを当てると動くとかなんとか)

じゃぁしょうがないからIntel GVT-gを使って仮想上でGPUを有効にするか!ただ3D アクセラレーションとかは有効にできるから3Dゲームとかやれるよ!という記事

環境

  • ホストOS : Ubuntu 24.04 LTS Desktop
  • ホストCPU : Intel(R) Core(TM) i7-8700 CPU @ 3.20GHz
  • ゲストOS : Windows 7 Pro
  • 仮想環境 : kvm + qemu + virtio

今回はintel GVT-gを使うのでそれに対応したCPU
第6世代以降(Skylake以降)が必要になります

KVMインストール

まずはkvmと必要パッケージをインストール

sudo apt-get install qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virtinst libosinfo-bin virt-manager

以下を打つと仮想マシンマネージャが立ち上がる

sudo virt-manager

Screenshot from 2024-12-12 16-08-30.png

カーネル設定(IOMMU・GVT有効化)

まずカーネルってなんやってなったんですけど
以下検索AIくんより

Linuxカーネルとは、Linuxオペレーティングシステム(OS)の中核部分で、コンピューターのハードウェアとプロセスの間で通信しながらリソースを管理するソフトウェアです

だそうです。
なんとなくOSの大事な処理をするところだなぁくらいにしか理解してません。

で、今からカーネルをいじるのはIOMMUを有効化するためで
IOMMUはInput-Output Memory Management Unitの略で、メモリを管理する機能です

仮想環境を建てるときはホストと仮想のメモリ領域を完全に分離する必要があります(仮想からの不正アクセスを防ぐため)
この機能にIOMMUが使われていて、更にGPUは物理アドレスを参照する設計になっているのでIOMMUを使わないとそいつらがわからんとなるわけです
(自分の理解なので間違ってたらごめんなさい)

で今回はintelのcpuに内蔵されたgpu仮想化をしたいので

  • i915.eneble_gvt=1(intelのgvt機能の有効化)
  • i915.enable_guc=0(なんかgvt機能と競合する?)
  • intel_iommu=on(intelのiommu機能の有効化)
    3つを行う必要がありますんで以下行をgrubの設定ファイルの以下部分を
/etc/default/grub
GRUB_CMDLINE_LINUX=""

こんな感じに追記

/etc/default/grub
GRUB_CMDLINE_LINUX="i915.enable_gvt=1 i915.enable_guc=0 intel_iommu=on"

grubはブート時にカーネルロードとかを担当する機能です
ここに上記コマンドを書いとくと反映されます

もう一個kvmgt, vfio-iommu-type1, mdevを有効にする?
(ここは理解できてないです)

/etc/modules-load.d/kvmgt.conf
kvmgt

このファイルを作らないとうまく行かなかったので作っときましょ

以上終わったら再起動

update-grub
reboot

再起動完了したらカーネル設定がうまく行ったか以下で確認

dmesg | grep iommu

うまく行ってなかったら
BIOSの設定でVt-dの設定とか見直すと良い

仮想GPUの確保

先程のgrubの設定を確認するために
まずはPCIデバイスを確認する

sudo lspci | grep VGA

VGAがついてるPCIデバイスを確認すると
以下が出てきた(自分の環境では2つ)

00:02.0 VGA compatible controller: Intel Corporation CoffeeLake-S GT2 [UHD Graphics 630]
01:00.0 VGA compatible controller: NVIDIA Corporation TU106 [GeForce RTX 2070] (rev a1)

片方はNVIDIAのGPUなので、今回はIntelの00:02.0が欲しかったID

このIDはこのあとも使うので変数化して
(0000:を頭につけてね)

PCI_ID="0000:00:02.0"

以下で対応するGVTの種類を確かめます

ls /sys/devices/pci0000\:00/$PCI_ID/mdev_supported_types/

なんか出力がでてきたら成功

i915-GVTg_V5_4  i915-GVTg_V5_8

これの内訳は以下のようになっていて

プロファイル VRAM容量 最大解像度
i915-GVTg_V5_1 最大512MB 1920x1200
i915-GVTg_V5_2 最大256MB 1920x1200
i915-GVTg_V5_4 最大128MB 1920x1200
i915-GVTg_V5_8 最大64MB 1024x768

数字をが小さければよい性能を引き出せるけど
CPUによってメモリの最大値が決められてるので
並列数は減るらしいのでトレードオフの関係

で、以下を叩くと仮想GPUを確保できる

GVT_ID=$(uuidgen)
GVT_TYPE=i915-GVTg_V5_4
echo $GVT_ID >  /sys/devices/pci0000\:00/$PCI_ID/mdev_supported_types/$GVT_TYPE/create

GVT_IDは仮想GPUのuuidを作成していて
このIDを使って仮想マネージャなどに登録する
あとでも使うので以下で確認

echo $GVT_ID

念の為GPUが確保できたかも以下で確認

ls /sys/devices/pci0000\:00/$PCI_ID/

フォルダの中にGVT_IDが名前になったフォルダができていれば問題ない

で、取得したGPUは電源ON/OFFで消えちゃうので
サービス化して自動で取得するようにしたほうが勝手が良い
(QEMUのhook機能を使っても良いです)

自分はわかりやすいのでサービス化する手順をやってます

/usr/lib/systemd/system/getvgpu.service
[Unit]
Description=Create intel vGPU

[Service]
Type=oneshot
ExecStart=/bin/sh -c "echo '<GVT_IDの値>' > /sys/devices/pci0000:00/<PCI_IDの値>/mdev_supported_types/i915-GVTg_V5_4/create"
ExecStop=/bin/sh -c "echo '1' > /sys/devices/pci0000:00/<PCI_IDの値>/<GVT_IDの値>/remove"
RemainAfterExit=yes

[Install]
WantedBy=graphical.target

これを作ってsystem起動しておけば
ubuntuを起動するたび特定のuuidで仮想GPUを確保してくれます
(getvgpu.serviceの名前はなんでもいいです)

sudo systemctl enable getvgpu

これで自動確保まで完了です
うまくサービス化できてるか確認するために
再起動して以下で自動的にvgpuが取られているか確認しましょう

ls /sys/devices/pci0000\:00/<PCI_ID>/

自動でvgpuが生成されていれば成功です

仮想GPUの確保

ここまできたらあと少し
次はKVMで実際に仮想PCを立ち上げますが
virtioという準仮想環境を使います

以下からstable版のvirtio-win ISOをダウンロードします

WindowsのISOは各自調達してください

  • virtio-winのISO
  • windowsのISO

両方用意できたら新しい仮想マシンから

image.png

ISOを選択

Screenshot from 2024-12-12 17-28-43.png

メモリ指定(値はご自由に)

image.png

ディスク容量(ご自由に)

image.png

インストールのカスタマイズをONに!!

image.png

ディスクをSATAからSCSIへ変更

image.png

先程ダウンロードしたvirtioをCD-ROMとして追加

image.png

NICをvirtioへ変更

image.png

ディスプレイのリッスンをなしへ変更
OpenGLにチェック

image.png

SCSIコントローラを追加

image.png

最後に作成した仮想GPUを割り当て

image.png

ここでmdevデバイスが見えない場合手順にミスがありますので見返してください

また適用ボタンを押さないと適用されないので
一度見返してみてください

それが終わったらインストール開始

image.png

インストール開始するとこのようにディスクが見えません
(ディスクをSCSIに指定したのでドライバがない)
ドライバを当てると見えるようになります

ドライバの読み込みからvirio isoが入ってるドライブを選択して以下のドライバを当ててください

  • vioscsi: scsiのvertioドライバ
  • NetKVM: networkのvertioドライバ
  • Balloon: メモリのvertioドライバ
  • qxl: ディスプレイのドライバ <*>

※windows8以上はqxlではなくqxldodを使う
※windows7はqxlを使い一回目インストールをミスするけど2回めで通るので根気よく頑張る

全部ドライバがあたったらインストールして放置
適当に寝て待ちましょう

sleep_neko.gif

立ち上がったらデバイスマネージャから謎のディスプレイデバイスが追加されてるはずなのでホスト側で使ってるcpuのドライバ(だいたいIntelのHD Graphics)を入れましょう

image.png

windows10用のドライバしかないって?
よくわからないけど皆さんこちらに行きますね(三店方式)
ttps://archive.org/download/inteluhd-win7

無事ドライバがあたったら一度仮想の電源を落とします
グラフィックドライバが2個存在していると
追加した仮想GPUが有効化できないので
いらないグラフィックドライバをぶちのめします

まず、仮想GPUのディスプレイを有効にします
image.png

mdev上のxmlから

display="off"

以下へ変更

display="on"

ビデオをnoneへ変更

image.png

最後

mdev(仮想GPU)の有効化をしたい
qemu(仮想化システム)でcommmadlineによる設定が必要

毎回commandlineを叩くのは面倒なので
xml上でqemuのcommandを直書きしたいが
何故か仮想マシンマネージャからは適用できない・・・・・

さまよっていたら以下の情報を発見

sudo virt-xml <仮想pcの名前> --edit --confirm --qemu-commandline="test"

このコマンドでとりあえず無理やりxmlドメインにqemuコマンドラインのパススルーを書き込むことに成功
(こんなことでええんか?)

wao_neko.gif

そしたらxmlの最後に以下のようなコマンドが追加されていると思うので

image.png

  <qemu:commandline>
    <qemu:arg value="test"/>
  </qemu:commandline>

これを消して以下を追加

  <qemu:override>
    <qemu:device alias="hostdev0">
      <qemu:frontend>
        <qemu:property name="x-igd-opregion" type="bool" value="true"/>
        <qemu:property name="driver" type="string" value="vfio-pci-nohotplug"/>
        <qemu:property name="ramfb" type="bool" value="true"/>
      </qemu:frontend>
    </qemu:device>
  </qemu:override>

色々探してみた結果、現在は他のブログで書かれてるようなcommandlineからの入力は廃止されてoverrideの書き方が有効らしい(詳しくはわからない・・・)

これで再度仮想マシンを起動します

image.png

割と長い時間この画面になりますが、
待つと立ち上がってくるので立ち上がったら
dxdiagでディスプレイ情報を確認

image.png

仮想のwindows7で3Dアクセラレータが使用可能であることを確認しました。

参考にした方々

めちゃくちゃわかりやすくお世話になりました

最小手順でやっている方

詳細に説明してくれている方

おわり

今回は先人の方々の情報を大分参考にしました
本当に文書化してくれる人たちに感謝です

ただ最新のバージョンだとフォルダ構成や使えない構文などもあり、最新版に翻訳したくらいの仕事はできたとおもいます

次こそは開発中androidアプリの話をします!!

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?