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

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

Linux Mint 20.3 (Una)
whiptail 0.52.21
libglib2.0-bin 2.64.6

スクリプトを作成する。

#!/bin/bash
directories=("共有1" "共有2" "共有3")
radioList=()
listIndex=0
for index in "${!directories[@]}"
do
    radioList[${listIndex}]=$index
    radioList[${listIndex}+1]=${directories[${index}]}
    radioList[${listIndex}+2]=OFF
    listIndex+=3
done
selectedIndex=$(whiptail --title "共有ディレクトリ" --radiolist "アクセスするディレクトリを選択してください。" 20 80 15 "${radioList[@]}" --notags 3>&1 1>&2 2>&3)
if [ ${#selectedIndex} == 0 ]; then
    exit 0
fi
directory=${directories[${selectedIndex}]}
if [ ! -d /run/user/$UID/gvfs/smb-share:server=samba-server,share=$directory/ ]; then
    echo -e "user\nWORKGROUP\nPassword\n" | gio mount smb://samba-server/$directory 1>/dev/null 2>/dev/null
fi
xdg-open smb://samba-server/$directory/

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

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

lightdmのログイン画面に解像度を設定する

環境

・ OS: Linux Mint 20.2
・ LightDM: 1.30.0

下記のコマンドでディスプレイ名と使用できる解像度を確認する。

$ xrandr

解像度をセットするスクリプトをディスプレイ名と解像度を確認した値に置き換えて作成する。

#!/bin/bash
xrandr --output DisplayPort-1 --mode 1920x1080

スクリプトに実行権限を付与する。

# chmod +x /etc/lightdm/resolution.sh

スクリプトを実行するlightdmの設定ファイルを作成する。

[SeatDefaults]
display-setup-script=/etc/lightdm/resolution.sh

ドスパラのVF-AD4でplymouth後のOEMロゴを非表示にする

LinuxMint20.1をインストールしたが、plymouthが表示される前と表示された後にOEMロゴが出て、なんか格好悪いので、plymouth後のロゴは非表示にしたい。

…
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash fbcon=nodefer"
…

OEMロゴは出なくなったけど、「drm:intel_cpu_fifo_underrun_irq_handler [i915]] *ERROR* CPU pipe A FIFO underrun」とか出るようになった。よく分からないし、普通に動くので下記のように追記して非表示にする。

…
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash fbcon=nodefer loglevel=0"
…

LinuxMint18.3でL2TP/IPSecを使用したVPN接続

※UbuntuGnome16.04でも同じ手順で接続可能なのを確認済み

VPN設定画面にL2TP/IPSecを追加

Mintはリポジトリを追加してインストールする必要がある。

$ sudo -s
# add-apt-repository ppa:nm-l2tp/network-manager-l2tp
# apt update
# apt install network-manager-l2tp
# apt install network-manager-l2tp-gnome

GUIでVPN設定

「設定」の「ネットワーク接続」から追加ボタンでl2tpのVPN接続を追加する。

・接続名を入力
・ゲートウェイを入力
・ユーザー名・パスワードを入力
・IPSecを有効にしてPre-shared keyを入力
・IPSecのAdvancedからAlgorithmsを下記の通り入力
  [Phase1] aes256-sha1-modp2048,aes256-sha1-modp1536
  [Phase2] 3des-sha1-modp3072,3des-sha1-modp2048
  ※この値の調べ方は後述
・PPPのMPPE暗号を使用するをチェック
・MSCHAPv2のみ残してあとはチェック外す

Algorithmを調べる

下記のサイトを参考にike-scan.shを作成し、ike-scanをインストールしてからスクリプトを実行する。結果を解析して適宜Algorithmを入力する。
https://github.com/nm-l2tp/network-manager-l2tp/wiki/Known-Issues#querying-vpn-server-for-its-ikev1-algorithm-proposals
作成したike-scan.shはこちら

一時ファイルの削除

設定は合っているのに何故か接続できない場合は下記のコマンドで一時ファイルを削除すると接続できる場合がある。

# rm -f /etc/ipsec.d/nm-l2tp-ipsec-*.secrets