Windows Server 2022+Windows 11(Hyper-V)+GPUパススルーで仮想ゲーミングマシン構築

# はじめに
Windows Server 2022上のHyper-VでWindows11をインストールし、さらにGPUパススルーでゲーミングマシンとして動かすことができたので備忘録として残しておきます。

# マシンスペック
今回使用したマシンの詳細は下記の通りです（主要パーツのみ）。

パーツ|名前
:--:|:--:
CPU | Intel Core i7 11700
メモリ | 32GB
マザーボード | ASUS PRIME H570-PLUS
GPU | GeForce GTX 1060
拡張USBボード | オウルテック OWL-PCEXU3E4S

今回はGPUだけでなくUSBのパススルーも行いました。
追加したUSBボードにマウスやキーボードを接続することで、仮想マシン内から直接デバイスを使用することができます。

# セットアップ手順
## BIOSの設定
Hyper-VおよびPCIeデバイスのパススルーを行うDiscrete Device Assignment(DDA)の機能を使用するため、BIOSで以下の設定を行います。

- Intel (VMX) Virtualization Technology の有効化
- VT-d の有効化
- SR-IOV Support の有効化

## Windows Server 2022のセットアップ
画面に従ってインストールを進めます。
以降の作業はGPUではなくマザーボード側の出力端子にモニタを接続して行ってください。

今回使用したマザーボード搭載NIC「Intel I219-V」のドライバがWindows Server 2022に対応していなかったため、以下の方法で対応しました。

1. Windows 10 64-bit版のドライバをダウンロード
2. `Wired_driver_26.4_x64.exe`を実行し、`ドライバーをインストールできません。このコンピューターにはインテル(R)アダプターがありません。`のエラーが出るのを確認する
3. 生成された`%LOCALAPPDATA%\Temp\PRO1000`を適当な場所にコピーする
4. デバイスマネージャーから認識しないNICのDEV IDを確認する。今回の場合は`15FA`であった。
5. `PRO1000\Winx64\NDIS68\e1d68x64.inf`を開く
6. `15FA`で検索し、`[Intel.NTamd64.10.0.1]`セクション内の以下の2行をコピー

```
%E15FANC.DeviceDesc%            = E15FA.10.0.1,       PCI\VEN_8086&DEV_15FA
%E15FANC.DeviceDesc%            = E15FA.10.0.1,       PCI\VEN_8086&DEV_15FA&SUBSYS_00008086
```

7. `[Intel.NTamd64.10.0]`、`[Intel.NTamd64.10.0...18362]`のセクションの最後に6.でコピーした2行を貼り付けて保存
8. 未署名のドライバをインストールするため、管理者権限のコマンドプロンプトで以下のコマンドを実行し、再起動

```
bcdedit /set LOADOPTIONS DISABLE_INTEGRITY_CHECKS
bcdedit /set TESTSIGNING ON
bcdedit /set NOINTEGRITYCHECKS ON
```

9. 編集した`e1d68x64.inf`を右クリックし、インストール
10. 8.の設定を戻すため以下のコマンドを実行

```
bcdedit /set LOADOPTIONS ENABLE_INTEGRITY_CHECKS
bcdedit /set TESTSIGNING OFF
bcdedit /set NOINTEGRITYCHECKS OFF
```

## 仮想マシンのセットアップ
ご存じの通り、Windows 11のシステム要件は厳しめに設定されています。

- CPU：1GHz以上、2コア以上、64bit
- メモリ：4GB以上
- ストレージ：64GB以上
- TPM 2.0の搭載

以上の要件を満たすように仮想マシンを設定する必要があります。

仮想マシン作成時に以下の設定を行います。仮想スイッチや仮想ハードディスクはいい感じに設定してください。
- 世代の指定：第2世代
- 起動メモリ：4096 MB以上（動的メモリは任意）

作成できたら、作成した仮想マシンを右クリック>設定から以下の項目を変更します。

- セキュリティ
    - 「セキュアブートを有効にする」にチェック
    - 「トラステッド プラットフォーム モジュールを有効にする」にチェック
- メモリ
    - RAMと最小RAMを一致させる
- プロセッサ
    - 「仮想プロセッサの数」に2以上を指定
- 自動停止アクション
    - 「ゲスト オペレーティング システムをシャットダウンする」を選択

以降はISOイメージを使用し、通常と同じようにWindows 11のインストール作業を進めます。

### 「Press any key to boot from CD or DVD…」の画面から進まない場合
仮想マシンの起動直後に任意のキーを押す必要があります。
しばらく押さないで放置していると、入力を一切受け付けなくなるようです。

### Windows 11のシステム要件を満たさない場合
以下のような画面が出てインストールが中断されます。

![このPCではWindows11を実行できません](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2198726/4473fbdb-a790-88e9-0fbc-3c6fafd6a689.png)

この場合、仮想マシンの設定が正しく行われていない可能性があります。
インストール画面でレジストリを編集することで強制的にインストールを行う方法もありますが、公式では非推奨となっています。

## GPUパススルーの設定
Windows 11のセットアップが一通り終わったら、一度マシンをシャットダウンさせます。

PCIeデバイスに仮想マシンから直接アクセスするためにHyper-Vの機能であるDiscrete Device Assignment (DDA)を利用します。
パススルーを行ったデバイスはホストマシンからは認識されなくなるため注意してください。（今回追加でUSB拡張ボードを購入したのはこのためです。）

グラフィックボードが接続されていることを確認し、以下の手順を実行します。

### 1. 管理者権限でPowerShellを起動し、以下のコマンドでGPUのハードウェアIDを確認する
```
> Get-PnpDevice -PresentOnly | where {$_.InstanceID -like 'PCI*'} | select InstanceID,FriendlyName | sort FriendlyName
```

GPUのドライバ等が入っていない場合は「Microsoft 基本ディスプレイ アダプター」と表示されます。自分の環境の場合、以下のような項目が見つかりました。
```
PCIP\VEN_10DE&DEV_1C03&SUBSYS_11D710DE&REV_A1\4&39FDDC03&0&0008 Microsoft 基本ディスプレイ アダプター
```

ドライバが入っている場合は「NVIDIA GeForce GTX 1060 6GB」や「PCI Express Graphics Processing Unit」のような表示がされている場合もあります。

「Microsoft 基本ディスプレイ アダプター」が複数存在し、どれがGPUかわからない場合は「VEN_XXXX」と「DEV_YYYY」の部分を検索することで特定できます。

### 2. GPUをホストマシンからをアンマウントする

```
> $deviceID = 'PCI\VEN_10DE&DEV_1C03&SUBSYS_11D710DE&REV_A1\4&39FDDC03&0&0008'
> $locationPath = (Get-PnpDeviceProperty -KeyName DEVPKEY_Device_LocationPaths -InstanceID $deviceID).Data[0]
> Disable-PnpDevice -InstanceId $deviceID
確認
この操作を実行しますか?
対象 "Win32_PnPEntity: Microsoft 基本ディスプレイ アダプター (DeviceID = "PCI\VEN_10DE&DEV_1C03&SUBSYS_11D710DE&R...)"  に対して操作
"Disable" を実行しています。
[Y] はい(Y)  [A] すべて続行(A)  [N] いいえ(N)  [L] すべて無視(L)  [S] 中断(S)  [?] ヘルプ (既定値は "Y"): Y
> Dismount-VMHostAssignableDevice -force -LocationPath $locationPath
```

1行目の`$deviceID = `以降のIDは各自の環境に置き換えてください。

### 3. GPUを仮想マシンに割り当てる
```
> Add-VMAssignableDevice -VMName "<仮想マシンの名前>" -LocationPath $locationPath -Verbose
詳細: Add-VMAssignableDevice は、割り当て可能デバイスを仮想マシン "<仮想マシンの名前>" に追加します。
```

エラーが出てアンマウントや割り当てが失敗する場合、
BIOSでVT-dやSR-IOV Supportを有効化に設定されていない可能性があります。

4. Hyper-V上から仮想マシンを起動し、接続する
5. デバイスマネージャーを開き、ディスプレイ アダプターに「基本ディスプレイ アダプター」が追加されていることを確認する
6. 対応するGPUのドライバをインストールし、再起動する

ここで再度デバイスバネージャーを確認すると、「NVIDIA GeForce GTX 1060 6GB」のように正しく名前が表示されています。

しかし、プロパティを開くとデバイスの状態に`問題が発生したためこのデバイスは停止しました。(コード43)`のようなエラーが表示されている場合があります。
私の場合、「デバイスを無効にする」→「デバイスを有効にする」を行ったり、GPU側の出力端子にモニタを接続した状態で起動することで正常に認識されるようになりました。

7. GPUの出力端子にモニタを接続し、モニタに画面が出力されることを確認
8. ディスプレイの設定を開き、「表示画面を拡張する」を「2のみに表示」に変更する

ここでディスプレイ1はHyper-V経由で画面を表示するための「HyperVMonitor」、ディスプレイ2は接続したモニタとなっているはずです。

私の環境では、ここで「画面の複製」を選択することができず、仕方なく「2のみに表示」としています。
この場合、以降はHyper-V経由での画面表示ができなくなるため注意してください。

## 拡張USBボードのパススルーの設定
GPUパススルーの場合と手段は全く同様です。
参考として、ハードウェアIDは以下のように表示されました。

```
PCI\VEN_1106&DEV_3483&SUBSYS_34831106&REV_01\4&199B923F&0&00D8 VIA USB 3.0 eXtensible Host Controller - 1.0 (Microsoft)
```

# 運用
以降はGPUの映像出力端子にモニタを接続し、キーボードやマウスを拡張USB
ボードに挿すことで物理マシンと全く同じように使用できます。
またPCケースのオーディオ端子等も使えないため、USB接続のヘッドセットやオーディオインターフェース等を買う必要があります。

Apexのような最近のゲームも普通に動きます。
ただしメモリは最低8GB、仮想プロセッサのコア数は4以上割り振らないとかなり動作がカクつきます。
またストレージへのアクセス速度は物理マシンよりも遅いため、
速度を求めるのであれば、Hyper-Vの仮想ハードディスクの設定で物理ハードデイスクを割り当てるのが有効です。

# 問題点
通常の使用に支障はありませんが、以下の問題点が残りました。

## GPUファンのコントロールができない
何故かGPU温度に関わらずGPUファンが常に最大速度で稼働してしまいます。
MSI Afterburnerなどのツールを使用してもコントロールできないため、
ファンコントローラーを使ったアナログな手段で対応する必要があります。

## 特定の条件下でWindows Serverを起動すると画面が正常に出力されない
- マザーボード側の映像出力端子に何も挿していない
- GPU側の映像出力端子にモニタを接続している

上記の2つの条件を満たした状態でWindows Serverを起動すると、GPUパススルーしているにも関わらずBIOS画面がGPUを通して表示されてしまい、以降画面の表示がおかしくなります。

# 参考
- [Windows Server 2019にIntel LAN Adapter I219-Vのドライバをインストールする](https://phst.hateblo.jp/entry/2021/01/11/150000)
- [Hyper-V仮想マシンでDDAを利用したGPUパススルー](https://nashippe.blog/hv/gpu-passthrough/)
- [Windows 11 の仕様とシステム要件](https://www.microsoft.com/ja-jp/windows/windows-11-specifications)