「設定 - KVMのGPUパススルー」の版間の差分

提供:MochiuWiki : SUSE, EC, PCB
ナビゲーションに移動 検索に移動
551行目: 551行目:
*# 次に、C:\Program Files\BarrierフォルダおよびC:\ProgramData\Barrierフォルダを削除する。
*# 次に、C:\Program Files\BarrierフォルダおよびC:\ProgramData\Barrierフォルダを削除する。
*# %LocalAppData%\Barrierフォルダ(レジストリ設定、Barrierの設定ファイル、証明書、フィンガープリント)の削除は、任意で行う。
*# %LocalAppData%\Barrierフォルダ(レジストリ設定、Barrierの設定ファイル、証明書、フィンガープリント)の削除は、任意で行う。
*: <br>
* Linux
*# まず、Barrierのインストールディレクトリを削除する。
*#: <code>rm -rf <Barrierのインストールディレクトリ></code>
*# 次に、Barrierの設定ファイルが存在するディレクトリを削除する。
*#: <code>rm -rf ~/.local/share/barrier</code>
*#: <code>rm -rf ~/.config/Debauchee</code>
<br>
<br>



2021年11月26日 (金) 02:12時点における版

概要

ここでは、Linuxホスト上にWindows10の仮想マシンを構築して、グラフィックボードやUSBポートを物理PCと同様に使用できるように設定する。

Linuxの欠点の1つは、利用できるゲームがそれほど多くないことである。
最近では、多くのゲームがLinuxに移植されたのは事実であるが、一般的には、ゲームはほぼWindows専用に開発されている。
Linuxユーザとして、これらのWindowsゲームをプレイするために、4つの方法がある。

  • Wineを使用してプレイする(Wineは、通常、古いゲームで機能する)
  • デュアルブートセットアップを使用して、ゲームをプレイするたびにWindowsをブートする。(手間が掛かる)
  • Windowsの仮想マシンでプレイする。(グラフィック性能が活かせない)
  • GPUパススルーを備えたWindowsの仮想マシンを使用する。(ハードウェアの前提条件がいくつかあり、特定のCPUとGPUでのみ機能するが、適切なハードウェアがあれば可能である)


基本的な設定の流れは、以下のようになる。

  1. CPUの仮想化支援機能(Intel VT-xまたはAMD-Vi)を有効にする
  2. グラフィックボードのパススルー設定
    1. IOMMUの有効化
    2. Linuxホストのグラフィックボード無効化
  3. kvm / qemuのインストール
  4. ゲストOS作成
    1. チューニング -> インストール
  5. グラフィックボードのパススルー
  6. USBポートのパススルー設定



ここでは、実際に設定を行うPCの環境は、以下の通りである。

  • CPU : Ryzen 3900X
  • マザーボード : GIGABYTE X570 UD(BIOS F12e)
  • GPU1 : 玄人志向 Radeon RX550 LP
  • GPU2 : GIGABYTE GeForce GT1030
  • OS : SUSE(カーネル : 4.12.14-lp151.28.52-default)



前提条件

  1. 2枚以上のグラフィックボード(マザーボード内蔵でも可)が必要である
    1つはLinuxホストで使用され、もう1つはWindowsを実行している仮想マシン(以降、VMという)で使用される。
    また、VMにIntel統合GPU(Intel UHD等)を使用することはできない。ATI製またはnVidia製のみ使用できる。
    ただし、LinuxホストにIntel統合GPUを使用することはできる。
  2. グラフィックボードがUEFIに対応していること。
    こちらのWebサイトに記載されているグラフィックボードであればよい。
  3. CPUの機能において、Intel VT-DまたはAMD-Viをサポートするマザーボードが必要である。
    リストの一部はこのWebサイトにある。BIOS上で有効にする必要がある。
  4. PCIのルートポートは、VMで使用するGPUと同じIOMMUグループの一部であってはならない。(詳細は後述)
  5. VMが使用するプライマリディスプレイの空き入力ポートまたはセカンダリディスプレイの空き入力ポートがあること。



BIOSの設定

まず最初に、BIOSの設定画面を表示して、以下の項目の設定を変更する。
なお、以下の項目はマザーボードがGIGABYTE X570UDのものである。

F12までのBIOS

  • AMD-Viの有効化
    [M.I.T.] - [高度な周波数設定] - [Advanced CPU Settings] - [SVM Mode]を[Enable]に変更する。
  • IOMMUの有効化
    [チップセット] - [IOMMU]を[Enable]に変更する。
  • ACSの有効化
    [周辺機器] - [AMD CBS] - [ACS Enable]を[Enable]に変更する。
  • AER Capの有効化
    [周辺機器] - [AMD CBS] - [Enable AER Cap]を[Enable]に変更する。


F12より新しいBIOS

  • Settings -> IO Ports -> Initial Display Output -> PCIe 2 Slot
  • AMD-Viの有効化
    [M.I.T.] - [高度な周波数設定] - [Advanced CPU Settings] - [SVM Mode]を[Enable]に変更する。
  • IOMMUの有効化
    [チップセット] - [IOMMU]を[Enable]に変更する。
  • IOMMUの有効化
    [周辺機器] - [AMD CBS] - [NBIO Common Options] - [IOMMU]を[Enable]に変更する。
  • ACSの有効化
    [周辺機器] - [AMD CBS] - [NBIO Common Options] - [ACS Enable]を[Enable]に変更する。
  • AER Capの有効化
    [周辺機器] - [AMD CBS] - [NBIO Common Options] - [Enable AER Cap]を[Enable]に変更する。



GPUパススルーの自動設定

もし、下記のセクションの手動設定が面倒と考える場合、以下の自動設定を行うシェルスクリプトをダウンロードする。
ファイル:GPU-PassThrough.zip
まず、gpu-passthrough.shをスーパーユーザ権限で実行する。
これは、必要なソフトウェアをインストールして、GPUパススルーに必要な設定を行った後、initrdを再構築するシェルスクリプトである。

sudo ./gpu-passthrough.sh


SUSEを再起動する。

次に、分離するGPU(VMで使用するGPU)を確認する。
Kernel driver in use:と記載されいている箇所を探す。正常に分離されていれば、vfio-pciと記載される。

sudo lspci -nnk


KVMを起動して、[QEMU/KVM]にフォーカスを当てて[編集]メニュー - [接続の詳細]を選択する。
[接続の詳細]画面が起動するので、[仮想ネットワーク]タブを選択して、[Autostart:]項目の[On Boot]チェックボックスにチェックを入力する。

後は、下記の[ゲストOSの作成]セクションに移動して、VMの作成および設定を行う。

なお、この方法は、https://www.youtube.com/watch?v=Nu2bHV8mA6c を参考にしている。


KVM / QEMUのインストール

KVM / QEMUおよび依存関係のライブラリをインストールする。


こちらのWebサイトから、VirtIOドライバをダウンロードする。


IOMMUの有効化

Intel VT-xとAMD-Viは、一般的にIOMMUと呼ばれる。
IOMMUを有効にするには、/etc/default/grubファイル(ブートローダファイル)にあるGRUB_CMDLINE_LINUX_DEFAULTセクションに以下の設定を追記する。
iommu=ptは、カーネルにDMA変換をメモリにバイパスするように指示する。これにより、パフォーマンスが向上する場合がある。

# Intel CPU
intel_iommu=on iommu=pt 

# AMD CPU
amd_iommu=on iommu=pt


grubを再構築するために、以下のコマンドを実行する。

sudo grub2-mkconfig -o /boot/grub2/grub.cfg


Linuxを再起動する。
再起動後、IOMMUが有効になっているか確認するため、以下のコマンドを実行する。

# Intel CPU
dmesg | grep -e DMAR -e IOMMU

# AMD CPU
dmesg | grep AMD-Vi


有効化されている場合は、以下のようなメッセージが出力される。

# Intel CPU
DMAR: IOMMU enabled
・
・
・

# AMD CPU
[    1.643621] pci 0000:00:00.2: AMD-Vi: IOMMU performance counters supported
[    1.645069] pci 0000:00:00.2: AMD-Vi: Found IOMMU cap 0x40
[    1.645069] pci 0000:00:00.2: AMD-Vi: Extended features (0x58f77ef22294ade):
[    1.645071] AMD-Vi: Interrupt remapping enabled
[    1.645072] AMD-Vi: Virtual APIC enabled
[    1.645072] AMD-Vi: X2APIC enabled
[    1.645153] AMD-Vi: Lazy IO/TLB flushing enabled
[    2.486602] AMD-Vi: AMD IOMMUv2 driver by Joerg Roedel <jroedel@suse.de>


次に、IOMMUグループが有効であることを確認する。
以下のシェルスクリプトを作成して実行する。(ここでは、シェルスクリプトのファイル名をlsIOMMU.shとする)

 #!/bin/bash
 
 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;


# 実行
chmod u+x lsIOMMU.sh
sudo ./lsIOMMU.sh


出力結果は下図のようになる。この図から、2つのことが分かる。
VMで使用するデバイスがどのIOMMUグループであるか(下図の場合は、グループ11)およびそのベンダー/モデルID(下図の場合は、1002:683fおよび1002:aab0)である。
この出力結果は、IOMMUグループ内で(関連付けられているオーディオデバイスを無視して)単独のデバイスに対してのみ機能する。

GPU PassThrough 1.jpg



複数のGPUの分離

2つ以上のGPUを分離する必要がある。
これは、異なるメーカーのGPUが2つある場合(ここでは、VMで使用するGPUをブラックリストに登録するだけ)は非常に簡単であるが、
両方のGPUが同じベンダーのものである場合は少し複雑になる。
また、両方のGPUが同じモデルの場合、さらに複雑になる。
GPUが同じベンダーのものであったとしても、両方のGPUが完全に同じモデルでない限り、この設定に従うことができる。
また、グラフィックカードのHDMIオーディオデバイスもパススルーすること。

ただし、この設定では、2つの全く同一のGPUでは機能しないので注意すること。(Radeon RX550が2枚など)

2つのグラフィックボードがそれぞれ異なる場合(nVidia製とATI製)
/etc/modprobe.d/50-blacklist.confファイルを編集して、以下の内容を追記する。

# LinuxホストにATI製グラフィックボード、VMにnVidia製グラフィックボードを使用する場合
blacklist nouveau
blacklist nvidia

# LinuxホストにnVidia製グラフィックボード、VMにATI製グラフィックボードを使用する場合
blacklist amdgpu
blacklist radeon


2つのグラフィックボードが同じ場合(両方ともnVidia製または両方ともATI製)
まず、/etc/modprobe.d/gpu-passthrough.confファイルを作成して、以下のように編集する。
ここで、<VMで使用するGPUのベンダー>と<VMで使用するGPUのモデルID>は、上記セクションで実行したlsIOMMU.shの出力結果に記載されている。

# /etc/modprobe.d/gpu-passthrough.confファイル
options vfio-pci ids=<VMで使用するGPUのベンダー>,<VMで使用するGPUのモデルID>


例えば、上記セクションの結果から、以下のように記述する。
また、options vfio-pcidisable_vga=1は、ホストPCが4.1以降のカーネルかつゲストOSがUEFIの場合のみ有効である。
VGAアービトレーションがホストデバイスに干渉するのを防ぐのに役立つ。

# /etc/modprobe.d/gpu-passthrough.confファイル
options vfio-pci ids=10de:1d01,10de:0fb8
options vfio-pcidisable_vga=1


また、Windows10 1803以降をインストールする場合は、以下の設定も追記する。

# /etc/modprobe.d/gpu-passthrough.confファイル
options kvm ignore_msrs=1


次に、/etc/default/grubファイルのGRUB_CMDLINE_LINUX_DEFAULTセクションに以下を追記する。
vfio-pciをパススルーするGPUにバインドするには、rd.driver.pre=vfio-pciをGRUB_CMDLINE_LINUX_DEFAULTに追記する必要がある。

# /etc/default/grubファイル
rd.driver.pre=vfio-pci 



initrdの再構築

必要な全てのモジュールを含めるには、initrdを再構築する必要がある。
/etc/dracut.conf.d/gpu-passthrough.confファイルを作成して、以下のように編集する。
(先頭と末尾にスペースが必要なので注意すること)

※調査中
pci_stubオプションは不要の可能性がある。

# Intel CPU
add_drivers+=" pci_stub vfio vfio_iommu_type1 vfio_pci vfio_virqfd kvm kvm_intel "

# AMD CPU
add_drivers+=" pci_stub vfio vfio_iommu_type1 vfio_pci vfio_virqfd kvm kvm_amd "


initrdを再構築するために、以下のコマンドを実行する。

sudo dracut -f /boot/initrd $(uname -r)


initrdの再構築の完了後、Linuxホストを再起動する。
設定ミスで失敗すると、Linuxホストが起動できなくなる可能性があるので注意すること。


GPUが分離されていることを確認

GPUが分離されているか確認する。
以下のコマンドを実行して、使用中のカーネルドライバーを探す。

sudo lspci -nnv


分離するGPU(VMで使用するGPU)を確認するには、Kernel driver in use:と記載されいている箇所を探す。 正常に分離されていれば、vfio-pciと記載される。

03:00.0 VGA compatible controller [0300]: NVIDIA Corporation GP108 [GeForce GT 1030] [10de:1d01] (rev a1)
       Subsystem: Gigabyte Technology Co., Ltd Device [1458:375d]
       Kernel driver in use: vfio-pci
       Kernel modules: nouveau
03:00.1 Audio device [0403]: NVIDIA Corporation GP108 High Definition Audio Controller [10de:0fb8] (rev a1)
       Subsystem: Gigabyte Technology Co., Ltd Device [1458:375d]
       Kernel driver in use: vfio-pci
       Kernel modules: snd_hda_intel



QEMUのアクセス権限の付与

別のHDD / SSDに仮想マシンを配置する場合、初期設定ではアクセス権限エラーになる。
そこで、/etc/libvirt/qemu.confファイルに以下の設定を追記する。

# /etc/libvirt/qemu.confファイル
・
・
・
user = "root"
group = "root"


また、別のHDD / SSDに仮想マシンを配置する時は、配置先のディレクトリで以下のコマンドを実行する。
以下では、<仮想マシン名>.qcow2ファイルを最大100[GB]の領域で仮想マシンを作成している。

qemu-img create -f qcow2 <仮想マシン名>.qcow2 100G



X11の設定

上記の設定の状態では、PC起動時においてパススルーしたGPUを先に読み込むため、ホストOSの画面が表示されない。
ホストOS向けのGPUを先に読む込む必要があるため、/etc/X11/xorg.conf.installファイルに以下の設定を追記する。

sudo vi /etc/X11/xorg.conf.install


# /etc/X11/xorg.conf.installファイル

# ...略

# 以下の設定を追記
Section "Device"
  Identifier "amdgpu"
  Driver  "amdgpu"
EndSection

# 以下の設定を追記
Section "Screen"
  Identifier "amdgpu"
  Device "amdgpu"
EndSection

# Screen  "amdgpu"を追記
Section "ServerLayout"
  # ...略
  Screen  "amdgpu"  # 追加
EndSection



ゲストOSの作成

予め、Microsoftの公式Webサイトで、Windows10のisoファイルをダウンロードする。

  1. まず、SUSE 15.1を使用している場合は、/etc/libvirt/qemu.confファイルを開いて、nvramセクションを以下のように編集する。
    nvram = ["/usr/share/qemu/ovmf-x86_64.bin:/usr/share/qemu/ovmf-x86_64-code.bin"]
  2. libvirtデーモンを再起動する。
    sudo systemctl restart libvirtd

    必要であれば、以下のように、libvirtdを自動起動するように設定する。
    sudo systemctl enable libvirtd

  3. Virtual Machine Managerを起動して、新しいVMを作成する。
    [Architecture Option]画面では、[Local Install Media]と[x86_64]を選択する。
  4. [Use ISO Imege]項目を選択して、Windows10のISOファイルを選択する。
  5. VMに割り当てるメモリ容量とCPUのコア数を選択する。
  6. VMのディスクイメージを作成する。(既に定義されている場合は選択する。また、ディスク全体でも構わない。パスをそこに配置して、ホストにマウントされていないことを確認する)
  7. VMに名前を付けて、[Customize configuration before install]チェックボックスにチェックが入力されていることを確認して、[Finish]ボタンを押下する。
  8. VM構成画面(以降、メイン画面という)に移動する。
    メイン画面左の[Overview]を選択して、[Chipset:]プルダウンおよび[Firmware:]プルダウンを以下の値に設定する。

    SUSE 15.1
    [Chipset:] : i440FX
    [Firmware:] : BIOS(またはUEFI)

    SUSE 15.2
    [Chipset:] : Q35
    [Firmware:] : ovmf-x86_64-smm-ms-code.bin

  9. メイン画面左の[CPUs]で、[Configuration]項目の[Model: ]プルダウンから、[host-passthrough]を選択する。(プルダウンに存在しない場合は、host-passthroughと入力する)
  10. メイン画面左下の[Add Hardware]ボタンを押下すると、[Add New Virtual Hardware]画面が表示される。
    この画面左の[Controller]を選択して、[Type: ]項目にSCSI、[Model: ]項目にVirtIO SCSIと入力する。
    (パフォーマンスを向上させるために、タイプを必ずVirtIO SCSIに変更する)
  11. メイン画面左の[SCSI Disk 1]を選択して、[Advanced Options]項目の[Disk bus]項目にSCSIを選択する。
  12. [Add New Virtual Hardware]画面左の[Storage]を選択して、[管理]ボタンを押下して、
    "KVM / QEMUのインストール"セクションでダウンロードしたvirtio-win-<バージョン名>.isoファイルを選択する。
    [デバイスの種類]項目には、[CD-ROMデバイス]を選択する。
  13. [Add New Virtual Hardware]画面左の[PCI Host Device]を選択して、分離されたGPUとサウンドカード(ここでは、PCIデバイス02:00.0とPCIデバイス02:00.1)を追加する。
  14. [Add New Virtual Hardware]画面左の[USB Host Device]を選択して、キーボードとマウスを追加する。
  15. 同様に、不要なデバイス(タブレット、ディスプレイスパイス、コンソール、チャンネルスパイス、ビデオQXL等)を全て削除する。
    ディスプレイにサウンド出力がない場合またはVGA経由で接続する場合は、サウンドカードが必要である。
    1000円程度の安価なUSBサウンドカードを購入してPCに取り付けた場合、キーボードとマウスを追加した際と同様にして追加する。
  16. VMに割り当てたばかりのグラフィックボードをディスプレイに接続し、[Begin Installation]ボタンを押下する。
    全て正しく設定されていれば、そのディスプレイにVMが起動していることがわかる。
  17. Windows10をインストール画面の手順に従ってインストールする。
    インストール完了後、Windows10のデバイスマネージャーを起動して、マウントされているvirtio-win-<バージョン名>.isoファイルから各種ドライバをインストールする。



SynergyまたはBarrierのインストール

Windows10のインストール完了後、Synergy(有償ソフトウェア)またはBarrierをインストールできる。
これらは、物理的なKVM(Keyboard-Video-Mouse)スイッチなしで、複数のPCで同じキーボードとマウスを使用できる。

以下に、SynergyとBarrierのインストール手順を記載する。

Synergy

Synergyは有償ソフトウェアであるが、一部の機能(通信の暗号化機能)を除いて、無償でも使用することができる。

まず、以下のコマンドを実行して、LinuxにSynergyをインストールする。

  • パッケージ管理システムからインストール (非推奨 : Synergyのパッケージが古いため)
    sudo zypper install libdns_sd qsynergy synergy

  • ソースコードからインストール
    まず、Synergyのビルドに必要な依存関係のライブラリをインストールする。
    sudo zypper install glib2-devel gdk-pixbuf-devel avahi-compat-mDNSResponder-devel dbus-1-devel libnotify-devel fixesproto-devel \
    libXrandr-devel libXext-devel libXfixes-devel libXinerama-devel libXi-devel libXtst-devel xextproto-devel libavahi-devel \
    inputproto-devel recordproto-devel libSM-devel libcurl-devel libopenssl-1_1-devel libopenssl-devel \
    libQt5Core-devel libQt5Gui-devel libQt5Network-devel libqt5-qtbase-common-devel libQt5Widgets-devel

    次に、Synergyのソースコードをダウンロードする。
    git clone https://github.com/symless/synergy-core.git

    Synergyのビルドディレクトリを作成して、ビルドおよびインストールする。
    cd synergy-core && mkdir build && cd build
    cmake -DCMAKE_INSTALL_PREFIX=<Synergyのインストールディレクトリ> ..
    make -j $(nproc)
    make install


Synergyの実行ファイルが存在するディレクトリに、以下のようなシェルスクリプトを作成する。

vi /<Synergyの実行ファイルがあるディレクトリ>/bin/synergy.sh


 # /<Synergyの実行ファイルがあるディレクトリ>/bin/synergy.shファイル
 
 #!/usr/bin/env sh
 
 appname="synergy"
 
 # use -f to make the readlink path absolute
 dirname="$(dirname -- "$(readlink -f -- "${0}")" )"
 
 if [ "$dirname" = "." ]; then
    dirname="${PWD}/${dirname}"
 fi
 
 cd ${dirname}
 
 # Initialize interpreter path
 export PATH="${dirname}:${PATH}"
 export LD_LIBRARY_PATH="/<Qtのインストールディレクトリ>/<Qtのバージョン>/gcc_64/lib:${LD_LIBRARY_PATH}"
 
 # Run Synergy binary
 "${dirname}/${appname}" "$@"


次に、Windows用のSynergyをダウンロードしてインストールする。
インストール後、Synergyの設定を行う。

  • Synergyのアンインストール
    • Windowsの場合
      1. [プログラムの追加と削除](または[アプリと機能])で、Synergyをアンインストールする。
        この時、"アプリとその関連情報がアンインストールされます"というメッセージが表示されるので、再度、[アンインストール]ボタンを押下する。
      2. [アプリを終了する必要があります]メッセージ、および、アプリを自動的に終了させるかどうかを尋ねられるので、これを選択する。
      3. 次に、regeditを実行して、以下に示すレジストリキーを削除する。(存在する場合)
        • HKEY_CURRENT_USER\Software\Symless
        • HKEY_CURRENT_USER\Software\Synergy
        • HKEY_LOCAL_MACHINE\SOFTWARE\Synergy

      4. 以下のディレクトリが存在する場合は、削除する。
        • C:\ProgramData\Symless
        • C:\ProgramData\Synergy
        • C:\ProgramData\Synergy v2
        • %USERPROFILE%\AppData\Local\Synergy
        • %USERPROFILE%\AppData\Local\Symless

      5. 次に、SystemConfig.iniファイルを削除する。
        この時、以前に保存した設定は失われる。
        C:\Program Files\Synergy\SystemConfig.ini

      6. 最後に、Windowsを再起動する。

    • Linuxの場合
      1. パッケージ管理システムを使用して、Synergyを削除する。
      2. 次に、以下のコマンドを実行して、Synergyの設定を削除する。
        • rm -rf ~/.config/Symless/
        • rm -rf ~/.config/Synergy/
        • rm -rf ~/.synergy/
        • rm -rf ~/.symless/

      3. 次に、SystemConfig.iniファイルを削除する。
        この時、以前に保存した設定は失われる。
        sudo rm -rf /usr/local/etc/Symless/SystemConfig.ini


Barrier (推奨)

パッケージ管理システムからインストール

まず、以下のコマンドを実行して、LinuxにBarrierをインストールする。

sudo zypper install barrier


次に、BarrierのGiHubにアクセスして、Windows向けのBarrierの実行ファイルをダウンロードしてインストールする。
インストール後、Barrierの設定を行う。

ソースコードからインストール

まず、Barrierをビルドするため、依存関係のライブラリをインストールする。

# CentOS (EPELリポジトリの追加が必要)
sudo yum groupinstall "Development Tools"

sudo yum install 'dnf-command(config-manager)'
sudo yum config-manager --set-enabled PowerTools

sudo yum install cmake3 libcurl-devel avahi-compat-libdns_sd-devel libX11-devel libXtst-devel desktop-file-utils openssl-devel \
                 qt5-qtbase-devel

# SUSE
sudo zypper install --type pattern devel_basis
sudo zypper install libdrm-devel libglvnd-devel libICE-devel \
                    libcurl-devel avahi-compat-mDNSResponder-devel libXtst-devel libopenssl-devel \
                    libSM-devel libXinerama-devel libXrandr-devel Mesa-devel \
                    libQt5Core-devel libQt5Gui-devel libQt5Network-devel libqt5-qtbase-common-devel libQt5Widgets-devel


次に、BarrierのGiHubにアクセスして、Barrierのソースコードをダウンロードする。
ダウンロードしたファイルを解凍して、ビルド向けディレクトリを作成する。

# Tarballからビルドする場合
tar xf barrier-<バージョン>-release.tar.gz
cd barrier-<バージョン>-release && mkdir build && cd build

# Gitからビルドする場合
git clone https://github.com/debauchee/barrier.git barrier && cd barrier
git submodule update --init --recursive 
./clean_build.sh
cd build


※注意
Tarballをダウンロードした時、Barrierディレクトリのext/gmockディレクトリ、ext/gtestディレクトリ、ext/gulrak-filesystemディレクトリが空の場合、
以下のモジュールのソースコードをダウンロードする必要がある。

# Tarballのモジュールをダウンロードする場合
wget https://github.com/google/googletest/archive/refs/tags/release-<バージョン>.tar.gz
wget https://github.com/gulrak/filesystem/archive/refs/tags/<バージョン>.tar.gz
tar xf googletest-release-<バージョン>.tar.gz
tar xf filesystem-<バージョン>.tar.gz

# Gitを使用してモジュールをダウンロードする場合
git clone https://github.com/google/googletest.git
git clone https://github.com/gulrak/filesystem


Barrierのビルドに必要なソースコードを、Barrierディレクトリのext/gmockディレクトリ、ext/gtestディレクトリ、ext/gulrak-filesystemディレクトリにコピーする。

# Tarballのモジュールをダウンロードした場合
cp -r googletest-release-<バージョン>/googlemock <Barrierディレクトリ>/ext/gmock
cp -r googletest-release-<バージョン>/googletest <Barrierディレクトリ>/ext/gtest
cp -r filesystem-<バージョン>/* <Barrierディレクトリ>/ext/gulrak-filesystem

# Gitを使用してモジュールをダウンロードした場合
cp -r googletest/googlemock/* <Barrierディレクトリ>/ext/gmock
cp -r googletest/googletest/* <Barrierディレクトリ>/ext/gtest
cp -r filesystem/* <Barrierディレクトリ>/ext/gulrak-filesystem


Barrierをビルドおよびインストールする。

# Tarballからインストールする場合
cmake  -DCMAKE_INSTALL_PREFIX=${HOME}/InstallSoftware/Barrier -DCMAKE_BUILD_TYPE=Release ..
make -j $(nproc)
make install

# Gitからインストールする場合
make DESTDIR=${HOME}/InstallSoftware/Barrier install 


Barrierの起動スクリプトを作成する。

vi ~/InstallSoftware/Barrier/barrier.sh


 # ~/InstallSoftware/Barrier/barrier.sh
 
 #!/usr/bin/env sh
 
 appname="barrier"
 
 # use -f to make the readlink path absolute
 dirname="$(dirname -- "$(readlink -f -- "${0}")" )"
 
 if [ "$dirname" = "." ]; then
    dirname="${PWD}/${dirname}"
 fi
 
 cd ${dirname}
 
 # Initialize interpreter path
 export PATH="${dirname}:${PATH}"
 export LD_LIBRARY_PATH="/<Qtのインストールディレクトリ>/<Qtのバージョン>/gcc_64/lib:${LD_LIBRARY_PATH}"
 
 # Run Barrier binary
 "${dirname}/${appname}" "$@"


Barrierの起動スクリプトに実行権限を付加する。

chmod u+x ~/InstallSoftware/Barrier/barrier.sh


Barrierのデスクトップエントリファイルを、~/.local/share/applicationsディレクトリに作成する。

# ~/.local/share/applications/Barrier.desktop

[Desktop Entry]
Type=Application
Name=Barrier <バージョン>
GenericName=Barrier
Comment=Keyboard and mouse sharing solution
Exec=/home/<ユーザ名>/InstallSoftware/Barrier/bin/barrier.sh
Icon=/home/<ユーザ名>/InstallSoftware/Barrier/barrier
Terminal=false
Categories=Utility;
Keywords=keyboard;mouse;sharing;network;share;


次に、BarrierのGiHubにアクセスして、Windows向けのBarrierの実行ファイルをダウンロードする。
KVMのゲストOSであるWindowsに、Barrierをインストールする。

Barrierのインストール完了後、Barrierの設定を行う。

Barrierのアンインストール
  • Windows
    1. Barrierをアンインストールする前に、Barrierを終了する。
      Barrierを起動したままでアンインストールした場合、ほとんどのBarrierに関するファイルが残ってしまうため注意すること。
    2. Barrierのサービスを停止するため、Powershellまたはコマンドプロンプトを起動して、net stopコマンドを実行する。
      これは、sc stopコマンドは非同期で実行されるため、sc deleteコマンドが失敗して、アンインストール後にbarrierd.exeが残るからである。
      net stopコマンドは、Barrierのサービスが停止するまで同期で実行するため、sc deleteコマンドが成功する。
    3. [設定] - [アプリ]画面または[コントロールパネル] - [プログラムと機能]画面から、Barrierをアンインストールする。
    4. 次に、C:\Program Files\BarrierフォルダおよびC:\ProgramData\Barrierフォルダを削除する。
    5. %LocalAppData%\Barrierフォルダ(レジストリ設定、Barrierの設定ファイル、証明書、フィンガープリント)の削除は、任意で行う。

  • Linux
    1. まず、Barrierのインストールディレクトリを削除する。
      rm -rf <Barrierのインストールディレクトリ>
    2. 次に、Barrierの設定ファイルが存在するディレクトリを削除する。
      rm -rf ~/.local/share/barrier
      rm -rf ~/.config/Debauchee


SynergyおよびBarrierが接続できない場合

SUSE以外の各ディストリビューションでは、以下のコマンドを実行することで接続できる可能性がある。

sudo firewall-cmd --permanent --add-port=24800/tcp
または
sudo firewall-cmd --permanent --zone=libvirt --add-port=24800/tcp

sudo firewall-cmd --reload


SUSEの場合および上記のコマンドで接続できない場合は、以下の設定を行う。

まず、/usr/lib/firewalld/services/barrier.xmlファイルを作成する。
(このファイルは不要の可能性があることに注意すること)

sudo vi /usr/lib/firewalld/services/barrier.xml


 <?xml version="1.0" encoding="utf-8"?>
    <service>
    <short>Synergy</short>
    <description>Share a mouse and keyboard on KVM.</description>
    <port protocol="tcp" port="24800"/>
 </service>


次に、/usr/lib/firewalld/zones/libvirt.xmlファイルにおいて、
</zone>タグの上部に<port port="24800" protocol="tcp"/>を追記する。

sudo nano /usr/lib/firewalld/zones/libvirt.xml


 <?xml version="1.0" encoding="utf-8"?>
 <zone target="ACCEPT">
 
    <!-- ...略 -->
 
    <port port="24800" protocol="tcp"/>
 </zone>


最後に、上記の設定を有効にするため、ファイアーウォールを再読み込みまたはPCを再起動する。
または、PCを再起動する。

sudo firewall-cmd --reload
sudo systemctl restart firewalld
または
sudo shutdown -r now



エラー時の対処方法

ゲストOSがopenSUSEの場合

ゲストOSがopenSUSEの場合、/etc/default/grubファイルのGRUB_CMDLINE_LINUX_DEFAULT項目に、pci=noaerオプションを追記する。

GRUB_CMDLINE_LINUX_DEFAULT="... pci=noaer"


AMD CPUのパフォーマンスの改善

以前、AMD CPUでは、Nested Page Tables(NPT)を無効化することでKVMのGPU性能を引き上げることができた。
これは、バグが原因で、トレードオフとしてCPUの性能が落ちて、がたつきが発生することがあった。

Linuxカーネル 4.9以降からこの問題を解決するカーネルパッチがマージされている。
LinuxカーネルまたはLinux-LTSカーネルを使用している場合、パッチは既に適用されている。

※注意
QEMU 3.1以降、TOPOEXTフラグは標準で無効化されており、
AMD CPUでハイパースレッディングを使用するには、以下のように、手動で有効にする必要がある。
cache passthroughの設定は、実際のCPUキャッシュ情報を仮想マシンに渡す。

 <!-- 各ゲストOS共通 -->
 <cpu mode="host-passthrough" check="none">
   <topology sockets="1" cores="4" threads="2"/>
   <cache mode="passthrough"/>
   <feature policy="require" name="topoext"/>
 </cpu>


更にパフォーマンスを向上させるため、以下のように、hypervエレメントを設定する。

 <!-- ゲストOSがWindows 10の場合 -->
 <hyperv>
   <relaxed state="on"/>
   <vapic state="on"/>
   <spinlocks state="on" retries="8191"/>
   <vendor_id state="on" value="0123456789ab"/>
   <vpindex state="on"/>
   <synic state="on"/>
   <stimer state="on"/>
   <frequencies state="on"/>
 </hyperv>
 
 <!-- ゲストOSがopenSUSEの場合 -->
 <hyperv>
   <relaxed state='on'/>
   <vapic state='on'/>
   <spinlocks state='on' retries='8191'/>
   <vendor_id state='on' value='0123456789ab'/>
 </hyperv>


仮想マシンのGPUパススルーに関するエラー(error code 43)

仮想マシンのデバイスマネージャでグラフィックボードを確認すると、"エラー43:ドライバーの読み込みに失敗しました"と表示されて、正常に機能しない場合がある。
この問題は、NVidia GeForceシリーズのみ起こり(QuadroやTeslaにはこの問題は無い)、ユーザが仮想マシンでそれらを使用しようとすると、機能を意図的に無効化する。
理由としては、仮想マシンでグラフィックカードを実行できるようになると、自社の製品の売上に悪影響を与える可能性があるからである。

GeforceのGPUパススルーを正常に動作させるには、ハイパーバイザがその存在を隠すことで出来る。
具体的な手順は以下の通りである。

手動での設定

  1. まず、仮想マシンを停止する。
  2. GPUパススルーを行う仮想マシンのxmlファイルを、以下のように編集する。
    sudo EDITOR=nano virsh edit <仮想マシン名>

    以下に示すように、vendor_id項目を<hyperv>セクション内に追記する。この時、value=の値はどんなものでもよい。
    <vendor_id state="on" value="123456789ab"/>

    次に、状態を非表示にするようにkvmに指示するため、<hyperv>セクション外の直下に次のコードを追記する。
    <kvm>
      <hidden state="on"/>
    </kvm>

    上記のvendor_idおよびhidden stateの2つの設定は、Quadro 2000以降のQuadroカードでは不要である。

  3. また、QEMU 4.0上において、仮想マシンにQ35チップセットを使用する場合、featuresセクション内に以下の設定を記述する。
    <ioapic driver="kvm"/>
  4. 最後に、libvirtdを再起動する。
    sudo systemctl restart libvirtd


自動での設定
GitHubにあるvirsh-patcherパッケージは、簡単に上記の方法を行うことができる。

git clone https://github.com/PassthroughPOST/virsh-patcher virsh-patcher


以下のコマンドを実行して修正を適用する。

sudo virshpatcher --error43 --vendor-id 123456789ab <仮想マシン名>



ネットワーク

VM起動時に下記のエラーが出力されて、VMが起動できないことがある。

ERROR    Requested operation is not valid: network 'default' is not active


まず、以下のコマンドを実行する。
この時、以下のメッセージが出力された場合は、sudo virsh net-start defaultを実行する。
今後、このネットワークを自動起動するには、sudo virsh net-autostart --network defaultを実行する。

# 実行
sudo virsh net-list --all

# 出力
名前      状態       自動起動      永続
------------------------------------------------
default   停止状態   いいえ (no)   はい (yes)


また、以下のようにネットワークが表示されない場合がある。

Name                 State      Autostart     Persistent
----------------------------------------------------------


その時は、/run/libvirt/network/default.xmlファイルを作成して、以下に示す内容を記述する。(デフォルトネットワークを作成する)

# /run/libvirt/network/default.xmlファイル

<networkstatus>
   <class_id bitmap='0-2'/>
   <floor sum='0'/>
   <network>
      <name>default</name>
      <uuid>e8a9f86b-1c3a-4fa5-ab03-1fb563b12b84</uuid>
      <forward mode='nat'>
         <nat>
            <port start='1024' end='65535'/>
         </nat>
      </forward>
      <bridge name='virbr0' stp='on' delay='0'/>
      <mac address='52:54:00:a3:0d:b0'/>
      <ip address='192.168.122.1' netmask='255.255.255.0'>
         <dhcp>
            <range start='192.168.122.2' end='192.168.122.254'/>
         </dhcp>
      </ip>
   </network>
</networkstatus>


次に、そのネットワークをKVMホストに永続的に追加するには、以下のコマンドを実行する。

sudo virsh net-define --file default.xml


ファイアーウォール

VM起動時に下記のエラーが出力されて、VMが起動できないことがある。

error: Failed to start network default
error: internal error: Failed to initialize a valid firewall backend


この時、ファイアーウォールサービスをインストールする。

sudo zypper install firewalld


サービスを有効にして、ネットワークを再び機能させるために、次のコマンドを実行する。

sudo systemctl enable --now firewalld
sudo systemctl restart libvirtd


DNSマスカレード

VM起動時に下記のエラーが出力されて、VMが起動できないことがある。

error: Failed to start network default
error: Cannot check dnsmasq binary /usr/sbin/dnsmasq: No such file or directory


この時、DNSマスカレードをインストールする。

sudo zypper install dnsmasq