LinuxMint21のQEMU+KVMで動くWindowsにGPUパススルー

AdobeCreativeCloudをGPUで快適に使用したく、設定対象の機種がAPUとGPUを両方使える機種だったので、APUはホスト用、GPUを仮想マシンのWindows用に設定することにした。

ASUS ROG Flow x13 GV301QH
AMD Ryzen 9 5900HS
NVIDIA GeForce GTX 1650 Mobile / Max-Q
Linux Mint 21 Vanessa
virt-manager 4.0.0
QEMU 6.2.0

GPUのデバイスIDを確認する。

01:00.0 3D controller [0302]: NVIDIA Corporation TU117M [GeForce GTX 1650 Mobile / Max-Q] [10de:1f9d] (rev a1)

ArchWikiを参考にカーネルパラメーターに「amd_iommu=on」「iommu=pt」「vfio-pci.ids=[デバイスID]」を追加する。

…
GRUB_CMDLINE_LINUX="amd_iommu=on iommu=pt vfio-pci.ids=10de:1f9d"
…

GRUBの設定を更新してホストを再起動する。

# update-grub

Windowsの仮想マシンはvirt-managerを使用して作成した。

仮想マシンを作成してインストール前に設定変更
ファームウェアをUEFIに
ハードウェアの追加でPCIホストデバイスのGPUを選択して追加
WindowsをインストールしてGPUが認識されていることを確認
ドライバなどをインストール
Windowsのリモートデスクトップを有効化
LinuxからRDPクライアントで接続できることを確認
Windowsをシャットダウン
仮想マシンの詳細設定で「ディスプレイ Spice」を削除
Windowsを起動してRDPで接続し動作確認

利便性を考えてこんなスクリプトも作ってみた。起動中画面のアイコンを変えたかったらzenityに--class付けてデスクトップエントリファイル(*.desktop)と関連付けて。

#!/bin/bash
virsh start windows 1>/dev/null 2>/dev/null
result=1
(
while [ ! "$result" = "0" ]
do
    nc -v -w 1 windows-vm.local -z 3389 1>/dev/null 2>/dev/null
    result=$?
    sleep 1
done
) | zenity --progress --title="Windows起動中" --text="仮想マシンを起動中です…\n" --width=300 --height=50 --percentage=99 --auto-close --no-cancel
remmina --connect=$HOME/.local/share/remmina/windows-vm-local.remmina 1>/dev/null 2>/dev/null

LinuxMint21でLaptopのACアダプターを抜き差しした際にスクリプトを実行する

ThinkBook 14 G3
Linux Mint 21 Vanessa

下記のコマンドを実行したまま、ACアダプタを抜き差ししてイベントを調べる。

$ acpi_listen

下記のような感じに出力された。

ac_adapter ACPI0003:00 00000080 00000000
battery PNP0C0A:00 00000080 00000001
ac_adapter ACPI0003:00 00000080 00000001
battery PNP0C0A:00 00000080 00000001

ACアダプタを抜いた際のイベントについて書く。

event=ac_adapter ACPI0003:00 00000080 00000000
action=/etc/acpi/switch-to-battery.sh

さっき指定したACアダプタを抜いた際のスクリプトを書く。これは画面の明るさを40%にする処理。
※先に/sys/class/backlight/amdgpu_bl0/max_brightnessで最大は確認した方が良い

#!/bin/bash
echo 102 | tee /sys/class/backlight/amdgpu_bl0/brightness

実行可能にする。

# chmod +x /etc/acpi/switch-to-battery.sh

ACアダプタを接続した際のイベントについて書く。

event=ac_adapter ACPI0003:00 00000080 00000001
action=/etc/acpi/switch-to-ac.sh

さっき指定したACアダプタを接続した際のスクリプトを書く。これは画面の明るさを60%にする処理。

#!/bin/bash
echo 153 | tee /sys/class/backlight/amdgpu_bl0/brightness

実行可能にする。

# chmod +x /etc/acpi/switch-to-ac.sh

サービスを再起動する。

# systemctl restart acpid

virt-managerでQEMUを通常アカウントで管理・実行する

自分のノートパソコンにインストールしているLinuxで、開発・検証・テストを目的に仮想マシンを利用するため、通常アカウントで管理できるよう設定する。

Linux Mint 21 Vanessa
virt-manager 4.0.0

virt-managerをインストールする。

# apt install virt-manager

対象の通常アカウントでqemu:///systemに接続できるよう設定する。

…
#user = "root"
user = "username"
…
#group = "root"
group = "libvirt"
…
#dynamic_ownership = 1
dynamic_ownership = 1
…

対象の通常アカウントをkvmとlibvirtグループに追加する。

# gpasswd -a username kvm
# gpasswd -a username libvirt

一度、ログアウトしてログインし直すと、virt-managerでqemu:///systemに接続できるようになる。接続の詳細でストレージのdefaultを通常アカウントで使用できる場所に変更しておいた方が良いかもしれない。

smbサーバーの共有ディレクトリをzenityで選択してgioでマウントする

Linux Mint 21 Vanessa
zenity 3.42.1
libglib2.0-bin 2.72.1

スクリプトを作成する。

#!/bin/bash
directory=$(zenity --list \
    --title="共有ディレクトリ" \
    --text="アクセスするディレクトリを選択してください。" \
    --width=400 --height=600 \
    --print-column=1 \
    --column="ディレクトリ名" \
        "共有1" \
        "共有2" \
        "共有3" \
2>/dev/null)
if [ $? -eq 1 ]; then
    exit 0;
fi
if [ ! -d "/run/user/$UID/gvfs/smb-share:server=samba-server.local,share=$directory/" ]; then
    echo -e "user\nWORKGROUP\nPassword\n" | gio mount smb://samba-server.local/$directory 1>/dev/null 2>/dev/null
fi
xdg-open smb://samba-server.local/$directory/

スクリプトを実行可能にする。

$ chmod +x ~/bin/gio-mount.sh

ディスプレイなしのXubuntu22.04にVNCでアクセスする

Xubuntu 22.04 TLS
TigerVNC Server 1.12.0
xserver-xorg-video-dummy 0.3.8

ここの手順でVNCサーバーとして設定されている前提です。この設定を行わない場合でもVNCビューワーで接続してもっさり操作は可能です。

必要なパッケージをインストールする。

apt install xserver-xorg-video-dummy

Xorgの設定ファイルにダミーディスプレイドライバを使用する設定を書き込む。内容はArchWikiのコピペっす。

Section "Monitor"
        Identifier "dummy_monitor"
        HorizSync 28.0-80.0
        VertRefresh 48.0-75.0
        Modeline "1920x1080" 172.80 1920 2040 2248 2576 1080 1081 1084 1118
EndSection

Section "Device"
        Identifier "dummy_card"
        VideoRam 256000
        Driver "dummy"
EndSection

Section "Screen"
        Identifier "dummy_screen"
        Device "dummy_card"
        Monitor "dummy_monitor"
        SubSection "Display"
        EndSubSection
EndSection

Xubuntu22.04でVNCサーバーを起動して画面共有する

Xubuntu 22.04 TLS
TigerVNC Server 1.12.0

Xubuntuに必要なパッケージをインストールする。

# apt install tigervnc-scraping-server

vncのパスワードファイルを作成する。

$ tigervncpasswd

Xubuntuにログインした状態でvncサーバーを起動する。
※-localhostオプションはデフォルトでyesなので明示的にnoを指定する

$ x0tigervncserver -localhost=no

Xubuntu22.04でVNCサーバーを起動してsshトンネル経由で画面共有する

Xubuntu 22.04 TLS
TigerVNC Server 1.12.0
OpenSSH 8.9

Xubuntuに必要なパッケージをインストールする。

# apt install ssh tigervnc-scraping-server

sshサーバーを有効化して開始する。

# systemctl enable --now ssh

Xubuntuにログインした状態でvncサーバーを起動する。

$ x0tigervncserver -localhost=yes -securitytypes=none

外部から接続するには下記のコマンドをリモート側で実行しsshポートフォワーディングを開始する。
※-Lオプションはリモート側のlocalhost:12345をホスト側のlocalhost:5900に転送するという意味らしい

$ ssh user@hostname.local.example.com -L 12345:localhost:5900

sshを接続したままの状態でvncビューワーでlocalhost:12345に接続する。

$ xtigervncviewer localhost:12345