Intel Arc B580をQEMU/KVM上のWindows11で安定して動作させるに至るまでの苦心惨憺と凡ミス(長

# 前提

**これは大前提として, *"トラブルの原因はQEMU/KVMの設定にはなかった"* 話です.**
**この記事は, 飽く迄も筆者のやらかしを忘れず記憶に留めておくための備忘録です.**
**Intel Arc B580やQEMU/KVMの適切な動作設定等々については全く参考にならない話です.**
**以上を念頭に置いた上で読み進めてください.**
**結論だけを知りたい方は項目欄から "これはwwwwww重大なミスwwwwwwwwwwwww" という見出しまで飛んでください.**

## 前環境

+ ホスト
:::note info
+ OS:Debian12
+ CPU:AMD Ryzen9 7945HX(16C32T)
+ MEM:DDR5-5200 64GB
+ SSD:DRAM Cache付 NVMe1.4 SSD 4TB
+ iGPU:AMD Radeon 610M
+ dGPU:Intel Arc A380(6GB)
:::

+ ゲスト
:::note info
+ OS:Windows11 22H2
+ CPU:AMD EPYC(8C16T)
+ MEM:16GB
+ HDD:2TB
+ GPU0:VirtIO GPU DOD
+ GPU1:Intel Arc A380(6GB)
:::

## 新環境

+ ホスト
:::note info
+ OS:Debian12
+ CPU:AMD Ryzen9 7945HX(16C32T)
+ MEM:DDR5-5200 64GB
+ SSD:DRAM Cache付 NVMe1.4 SSD 4TB
+ iGPU:AMD Radeon 610M
+ **dGPU:Intel Arc B580(12GB)**
:::

+ ゲスト
:::note info
+ OS:Windows11 24H2
+ CPU:AMD EPYC-Milan(8C16T)
+ MEM:16GB
+ HDD:2TB
+ GPU0:VirtIO GPU DOD
+ **GPU1:Intel Arc B580(12GB)**
:::

### 更新後の症状
:::note warn
+ **何もしていなくてもBSoD**
+ **何かしても不明なタイミングでBSoD**
+ **Stop codeは"VIDEO TDR FAILURE"だが何も表示されずにVMがクラッシュすることもある**
+ **クラッシュするのは必ず"igdkmdnd64.sys"**
+ **ホストサーバーを巻き込んでのクラッシュはしない(他のVMに接続されている拡張カードのデータが多少ドロップする程度)**
:::

### 試したこと

:::note warn
+ **ホストサーバーのUEFI/BIOSのアップデート -> 既に元々最新**
+ **ホストサーバーのOS(Debian12)のアップデート -> 他の拡張デバイスのデバイスIDが不可逆的に狂った(ダメージ・中)**
+ **Windows11のアップデート -> 24H2にアップデートしたが効果なし**
+ **B580 -> A380に切り戻し -> 効果なし**
+ **最小構成にしてみる -> 効果なし**
+ **vfio.confのデバイスIDの変更漏れをやらかしてないかチェックする -> 問題なし**
+ **vfio.confのデバイスID変更後にアップデートしてないかチェックする -> 問題なし(というか、更新してもBSoDになる)**
:::

# 試行錯誤

:::note info
## 効果:小
+ **GRUBの起動パラメーターに"pcie_aspm=off"を入れる.**
+ **GRUBの起動パラメーターに"pci=realloc"を入れる.**
+ **/etc/modules-load.d/modules.conf に以下のパラメーターを追加する.**
```/etc/modules-load.d/modules.conf
vfio
vfio_iommu_type1
options kvm_amd avic=1
```
*※"vfio_virqfd"はdmesgを見ているとどうも他のパラメーターにマージされているようなので, 先人の例ではよく記載するパターンがあるが, 省いてもきちんと動作するので問題はありません.*


+ **/etc/modprobe.d/kvm.conf に以下のパラメーターを追加する.**
```/etc/modprobe.d/kvm.conf
options kvm ignore_msrs=1
options kvm allow_unsage_assigned_interrupts=1
options kvm report_ignored_msrs=0
```

+ **/etc/modprobe.d/qemu-system-x86.conf に以下のパラメーターを追加する.**
```/etc/modprobe.d/qemu-system-x86.conf
options kvm_intel nested=1
options kvm_amd avic=1
```

+ **/etc/modprobe.d/vfio_iommu_type1.conf に以下のパラメーターを追加する.**
```/etc/modprobe.d/vfio_iommu_type1.conf
options vfio_iommu_type1 allow_unsage_interrupts=1
```

+ **仮想マシンのlibvirtで使用可能なhyperv関連の設定を全部載せする**

```xml
    <hyperv mode="custom">
      <relaxed state="on"/>
      <vapic state="on"/>
      <spinlocks state="on" retries="8191"/>
      <vpindex state="on"/>
      <runtime state="on"/>
      <synic state="on"/>
      <stimer state="on">
        <direct state="on"/>
      </stimer>
      <frequencies state="on"/>
      <tlbflush state="on"/>
      <ipi state="on"/>
      <avic state="on"/>
    </hyperv>
```

***結果: テスト用ベンチマークの実行可能時間が僅かに伸びた(15秒前後->30秒前後).***
:::

:::note info
## 効果:中(1)
+ **仮想マシンのGPUの接続トポロジをvirt-managerでパススルーデバイスを作成した場合のデフォルト設定である「PCI-to-PCIブリッジ配下」から(一番番号が若い)「PCIeルートポート直下」に変更する(virt-managerからxmlを編集).**

**ソース: https://wiki.gentoo.org/wiki/GPU_passthrough_with_virt-manager,_QEMU,_and_KVM**
***Troubleshooting*** と ***Adjusting PCI Address of GPU inside Guest*** を参照

### 変更前
```plantuml
object CPU
object Q35PCIeルートポート
object PCItoPCIブリッジ
object IntelArcB580

CPU --> Q35PCIeルートポート
Q35PCIeルートポート --> PCItoPCIブリッジ
PCItoPCIブリッジ --> IntelArcB580
```
```xml
  <devices>
    <hostdev mode="subsystem" type="pci" managed="yes">
      <source>
        <address domain="0x0000" bus="0x03" slot="0x00" function="0x0"/>
      </source>
      <address type="pci" domain="0x0000" bus="0x04" slot="0x00" function="0x0"/>
    </hostdev>
    <hostdev mode="subsystem" type="pci" managed="yes">
      <source>
        <address domain="0x0000" bus="0x04" slot="0x00" function="0x0"/>
      </source>
      <address type="pci" domain="0x0000" bus="0x05" slot="0x00" function="0x0"/>
    </hostdev>
  </devices>
```

### 変更後
```plantuml
object CPU
object Q35PCIeルートポート
object IntelArcB580
object PCItoPCIブリッジ

CPU --> Q35PCIeルートポート
Q35PCIeルートポート --> IntelArcB580
Q35PCIeルートポート --> PCItoPCIブリッジ
```

```xml
  <devices>
    <hostdev mode="subsystem" type="pci" managed="yes">
      <driver name="vfio"/>
      <source>
        <address domain="0x0000" bus="0x03" slot="0x00" function="0x0"/>
      </source>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x05" function="0x0"/>
    </hostdev>
    <hostdev mode="subsystem" type="pci" managed="yes">
      <driver name="vfio"/>
      <source>
        <address domain="0x0000" bus="0x04" slot="0x00" function="0x0"/>
      </source>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x06" function="0x0"/>
    </hostdev>
  </devices>
```

***結果: テスト用ベンチマークの実行可能時間が大抵の場合で大幅に伸びた(30秒前後->6分弱)***
:::

:::note info
## 効果:中(2)~~病~~

VMのXMLファイルに次のようなパラメーターを追加

```xml
<domain type="kvm" xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0">
  (中略)
  <qemu:commandline>
    <qemu:arg value="-cpu"/>
    <qemu:arg value="host,host-phys-bits=on,migratable=off,topoext=on,hv-time=on,hv-relaxed=on,hv-vapic=on,hv-spinlocks=0x1fff,kvm=off"/>
    <qemu:arg value="-fw_cfg"/>
    <qemu:arg value="name=opt/ovmf/X-PciMmio64Mb,string=65536"/>
    <qemu:arg value="-fw_cfg"/>
    <qemu:arg value="name=opt/ovmf/PciParseBar[0x05].BarType,string='PciBarTypePMem64'"/>
    <qemu:arg value="-global"/>
    <qemu:arg value="q35-pcihost.below-4g-mem-size=4294967296"/>
    <qemu:arg value="-global"/>
    <qemu:arg value="q35-pcihost.above-4g-mem-size=17179869184"/>
    <qemu:arg value="-global"/>
    <qemu:arg value="q35-pcihost.pci-hole64-size=2199023255552"/>
    <qemu:arg value="-global"/>
    <qemu:arg value="q35-pcihost.x-pci-hole64-fix=true"/>
    <qemu:env name="BAR" value="2"/>
</domain>
```

**結果: ベンチマークを大分良いところまで走らせることは出来るが, 完走まで至らず.**

:::

:::note alert
## 効果:なし

次のようなスクリプトを作成して、libvirtの起動より前(パススルーデバイスがVMにバインドされる前)で実行

```/usr/local/etc/rebar.sh
#!/bin/bash
echo -n "0000:03:00.0" > /sys/bus/pci/drivers/vfio-pci/unbind
echo 13 > /sys/bus/pci/devices/0000\:03\:00.0/resource2_resize
echo -n "8086 e20b" > /sys/bus/pci/drivers/vfio-pci/new_id
echo -n "0000:03:00.0" > /sys/bus/pci/drivers/vfio-pci/bind
```

**結果: BARサイズが8GBに下がるとVMのWindowsにインストールされたIntelドライバはResizableBARが外れたと認識するためNG**

:::

:::note info
## 効果:大

**上述した"-fw_cfg"と"global"属性のqemuコマンドを削除し, pcie-root controllerに"pcihole64"ユニットを追加します.**

```diff_xml
<domain type="kvm" xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0">
  (中略)
  <devices>
  (中略)
-   <controller type="pci" index="0" model="pcie-root">
+   <controller type="pci" index="0" model="pcie-root">
+     <pcihole64 unit="KiB">2147483648</pcihole64>
+   </controller>
  (中略)
  </devices>
  <qemu:commandline>
    <qemu:arg value="-cpu"/>
    <qemu:arg value="host,host-phys-bits=on,migratable=off,topoext=on,hv-time=on,hv-relaxed=on,hv-vapic=on,hv-spinlocks=0x1fff,kvm=off"/>
  </qemu:commandline>
</domain>
```

***結果: ベンチマークは1本単独なら完走できるが, 2週目を走らせると早々に(GPUが)リタイアする. -> 従前は1本完走することすら出来なかったので大幅な進歩(進歩なのか?)***

:::

## ゴールを目指して

### 方向性

ここまでの(長時間のエンコード負荷をかけることでの)動作確認の傾向から, どうやら **"pcihole64"** と **それに関わりのありそうな何かの設定** が **安定稼働の鍵** のようです.

:::note warn
**しかし"pcihole64"に纏わる言及資料は少なく, ~~そもそも論としてDebian12のQEMU/KVMにIntel dGPUでパススルー(しかもCPUがAMD)という変態環境なのがアカンのではないかという疑問も頭を過りますが,~~ 後はlibvirtやQEMUに設定可能なパラメーターと睨めっこしつつ, トライアンドエラーの積み重ねです.**
:::

:::note info
### 設定1

**QEMUのUEFIのパラメーターを強制的に書き換えると言われている "Above 4G Decode" に関連するパラメーター "X-PciMmio" を再び追加してみます.** 

```diff_xml
<domain type="kvm" xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0">
  (中略)
  <devices>
  (中略)
    <controller type="pci" index="0" model="pcie-root">
      <pcihole64 unit="KiB">2147483648</pcihole64>
    </controller>
  (中略)
  </devices>
  <qemu:commandline>
    <qemu:arg value="-cpu"/>
    <qemu:arg value="host,host-phys-bits=on,migratable=off,topoext=on,hv-time=on,hv-relaxed=on,hv-vapic=on,hv-spinlocks=0x1fff,kvm=off"/>
+   <qemu:arg value="-fw_cfg"/>
+   <qemu:arg value="name=opt/ovmf/X-PciMmio64Mb,string=65536"/>
  </qemu:commandline>
</domain>
```

***結果: ベンチマーク1本単独は完走できるが, 2本目を走らせると早々にGPUがリタイア.***

**これは効果の有無の判定が難しいですね. 可もなく不可でもない感じ.**
:::

:::note alert
### 設定2

**QEMUのUEFIのパラメーターを強制的に書き換えると言われている "Above 4G Decode" に関連するパラメーター "X-PciMmio" の値を変更してみます. ~~そもそもこの値は本当に反映されているのか? ゲストOSからは確認することが出来ないのだが.~~** 

```diff_xml
<domain type="kvm" xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0">
  (中略)
  <qemu:commandline>
    <qemu:arg value="-cpu"/>
    <qemu:arg value="host,host-phys-bits=on,migratable=off,topoext=on,hv-time=on,hv-relaxed=on,hv-vapic=on,hv-spinlocks=0x1fff,kvm=off"/>
    <qemu:arg value="-fw_cfg"/>
+   <qemu:arg value="name=opt/ovmf/X-PciMmio16384Mb,string=2097152"/>
  </qemu:commandline>
</domain>
```

***結果: ベンチマーク1本目を走らせると早々にGPUがリタイア.***

**予想に反してあっさりとダウンしてしまいました. どうやらこの値はあまり弄ってはいけないようです.**
:::

:::note warn
### 設定3

**"X-PciMmio" の値を(B580のBAR 0のサイズである)16MBに縮小変更してみます.** 

```diff_xml
<domain type="kvm" xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0">
  (中略)
  <qemu:commandline>
    <qemu:arg value="-cpu"/>
    <qemu:arg value="host,host-phys-bits=on,migratable=off,topoext=on,hv-time=on,hv-relaxed=on,hv-vapic=on,hv-spinlocks=0x1fff,kvm=off"/>
    <qemu:arg value="-fw_cfg"/>
+   <qemu:arg value="name=opt/ovmf/X-PciMmio16Mb,string=2097152"/>
  </qemu:commandline>
</domain>
```

***結果: ベンチマーク1本目を走らせると40%を越える直前でGPUがリタイア(フォールト).***

**予想よりは持ち堪えましたがダメでした. デフォルトの64Mbに戻してみましょう(stringの方はpcihole64と同じ2048GB(2097152Mb)のままにします).**
:::

:::note warn
### 設定4

**"X-PciMmio" の値を元の64Mbに戻してみます.** 

```diff_xml
<domain type="kvm" xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0">
  (中略)
  <qemu:commandline>
    <qemu:arg value="-cpu"/>
    <qemu:arg value="host,host-phys-bits=on,migratable=off,topoext=on,hv-time=on,hv-relaxed=on,hv-vapic=on,hv-spinlocks=0x1fff,kvm=off"/>
    <qemu:arg value="-fw_cfg"/>
+   <qemu:arg value="name=opt/ovmf/X-PciMmio64Mb,string=2097152"/>
  </qemu:commandline>
</domain>
```

***結果: ベンチマーク1本目を走らせると73%を越える直前でGPUがリタイア(フォールト).***

**予想よりは持ち堪えましたがダメでした.** 
**設定1に戻してもエンコードの長さ次第ではダメなので, どうやら "X-PciMmio" は "64Mb" と "65536" の組み合わせが最も良いようですが, 特に影響は無いか, あっても些少もしくは悪化する可能性があります.**
**取り敢えず"X-PciMmio"は省くことにしました(省いたら安定して1本目は通る).**
:::

:::note alert
### 設定5

**"pcihole64" のサイズを16GiBに減らし, "-global" パラメーターへ "Above 4G Decode" に関する値を放り込みます.
閾値は2GBと6GBに設定しました.**

```diff_xml
<domain type="kvm" xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0">
  (中略)
  <devices>
  (中略)
    <controller type="pci" index="0" model="pcie-root">
+     <pcihole64 unit="KiB">16777216</pcihole64>
    </controller>
  (中略)
  </devices>
  <qemu:commandline>
    <qemu:arg value="-cpu"/>
    <qemu:arg value="host,host-phys-bits=on,migratable=off,topoext=on,hv-time=on,hv-relaxed=on,hv-vapic=on,hv-spinlocks=0x1fff,kvm=off"/>
+   <qemu:arg value="-global"/>
+   <qemu:arg value="q35-pcihost.below-4g-mem-size=2147483648"/>
+   <qemu:arg value="-global"/>
+   <qemu:arg value="q35-pcihost.above-4g-mem-size=6442450944"/>
  </qemu:commandline>
</domain>
```

***結果: ベンチマーク1本目で30秒以内にGPUがリタイア(フォールト).***

**~~一気に3つも設定変更をしてしまったのでどれが悪かったのか正直不明です.~~
(良いエンジニアの皆さんはそんなこと絶対にしてはいけません)**
:::

:::note alert
### 設定6

**"pcihole64" のサイズを128GiBに増やします.
"Above 4G Decode" に関する値の閾値は前の設定と同じ2GBと6GBで続行します.**

```diff_xml
<domain type="kvm" xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0">
  (中略)
  <devices>
  (中略)
    <controller type="pci" index="0" model="pcie-root">
+     <pcihole64 unit="KiB">134217728</pcihole64>
    </controller>
  (中略)
  </devices>
  <qemu:commandline>
    <qemu:arg value="-cpu"/>
    <qemu:arg value="host,host-phys-bits=on,migratable=off,topoext=on,hv-time=on,hv-relaxed=on,hv-vapic=on,hv-spinlocks=0x1fff,kvm=off"/>
    <qemu:arg value="-global"/>
    <qemu:arg value="q35-pcihost.below-4g-mem-size=2147483648"/>
    <qemu:arg value="-global"/>
    <qemu:arg value="q35-pcihost.above-4g-mem-size=6442450944"/>
  </qemu:commandline>
</domain>
```

***結果: なんと今まで(比較的)安定していたのに, エンコードを走らせる前の静止状態から突然のBSoDを起こしたためボッシュートです.***
:::

:::note warn
### 設定7

**"pcihole64" のサイズを256GiBに増やします.
"-cpu" に関する値は取り去ってしまいます.
"Above 4G Decode" に関する値の閾値は前の設定と同じ2GBと6GBで続行します.
Grokくんのアドバイスで, featuresセクションに "ioapic driver="kvm"" を生やしました.
devicesセクションに "iommu" ユニットを生やしました.**

```diff_xml
<domain type="kvm" xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0">
  (中略)
  <features>
  (中略)
+   <ioapic driver="kvm"/>
  </features>
  <devices>
  (中略)
    <controller type="pci" index="0" model="pcie-root">
+     <pcihole64 unit="KiB">268435456</pcihole64>
    </controller>
+   <iommu model="intel">
+     <driver caching_mode="on" iotlb="on" aw_bits="48"/>
+   </iommu>
  (中略)
  </devices>
  <qemu:commandline>
    <qemu:arg value="-global"/>
    <qemu:arg value="q35-pcihost.below-4g-mem-size=2147483648"/>
    <qemu:arg value="-global"/>
    <qemu:arg value="q35-pcihost.above-4g-mem-size=6442450944"/>
  </qemu:commandline>
</domain>
```

***結果: エンコード速度が半分になり, かつ突然のBSoD.***
:::

:::note warn
### 設定8

**featuresセクションにWindows向けの設定を再度盛り込んでみます.**

```diff_xml
<domain xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0" type="kvm">
  (中略)
  <features>
    <acpi/>
    <apic/>
+   <hyperv mode="custom">
+     <relaxed state="on"/>
+     <vapic state="on"/>
+     <spinlocks state="on" retries="8191"/>
+     <vpindex state="on"/>
+     <runtime state="on"/>
+     <synic state="on"/>
+     <stimer state="on">
+       <direct state="on"/>
+     </stimer>
+     <reset state="on"/>
+     <frequencies state="on"/>
+     <tlbflush state="on"/>
+     <ipi state="on"/>
+   </hyperv>
    <kvm>
      <hidden state="on"/>
    </kvm>
    <vmport state="off"/>
    <ioapic driver="kvm"/>
  </features>
  <deivices>
  (中略)
    <controller type="pci" index="0" model="pcie-root">
      <pcihole64 unit="KiB">268435456</pcihole64>
    </controller>
  (中略)
    <hostdev mode="subsystem" type="pci" managed="yes">
      <driver name="vfio"/>
      <source>
        <address domain="0x0000" bus="0x03" slot="0x00" function="0x0"/>
      </source>
      <rom bar="on"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x05" function="0x0"/>
    </hostdev>
    <memballoon model="virtio">
      <address type="pci" domain="0x0000" bus="0x06" slot="0x00" function="0x0"/>
+     <driver iommu="on" ats="on"/>
    </memballoon>
    <iommu model="intel">
      <driver caching_mode="on" iotlb="on" aw_bits="48"/>
    </iommu>
  </devices>
  <qemu:commandline>
    <qemu:arg value="-global"/>
    <qemu:arg value="q35-pcihost.below-4g-mem-size=2147483648"/>
    <qemu:arg value="-global"/>
    <qemu:arg value="q35-pcihost.above-4g-mem-size=6442450944"/>
  </qemu:commandline>
</domain>
```

***結果: エンコード性能も振るわず, 割と早々に途中でGPUがリタイア(フォールト).***

**iommuセクションとhypervユニットを追加してからというもの, 性能も振るわず途中でGPUがリタイア(フォールト)するまでの時間も短くなってしまいました.**

:::

:::note warn
### 設定9

**"pcihole64" の設定を2048GiBに戻し, "iommu" セクションのdriverユニットを必要最小限にしてみます.**

```diff_xml
<domain xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0" type="kvm">
  (中略)
  <features>
    <acpi/>
    <apic/>
    <hyperv mode="custom">
      <relaxed state="on"/>
      <vapic state="on"/>
      <spinlocks state="on" retries="8191"/>
     <vpindex state="on"/>
      <runtime state="on"/>
      <synic state="on"/>
      <stimer state="on">
        <direct state="on"/>
      </stimer>
      <reset state="on"/>
      <frequencies state="on"/>
      <tlbflush state="on"/>
      <ipi state="on"/>
    </hyperv>
    <kvm>
      <hidden state="on"/>
    </kvm>
    <vmport state="off"/>
    <ioapic driver="kvm"/>
  </features>
  <deivices>
  (中略)
    <controller type="pci" index="0" model="pcie-root">
+     <pcihole64 unit="KiB">214783648</pcihole64>
    </controller>
  (中略)
    <hostdev mode="subsystem" type="pci" managed="yes">
      <driver name="vfio"/>
      <source>
        <address domain="0x0000" bus="0x03" slot="0x00" function="0x0"/>
      </source>
      <rom bar="on"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x05" function="0x0"/>
    </hostdev>
    <memballoon model="virtio">
      <address type="pci" domain="0x0000" bus="0x06" slot="0x00" function="0x0"/>
      <driver iommu="on" ats="on"/>
    </memballoon>
    <iommu model="intel">
+     <driver caching_mode="on"/>
    </iommu>
  </devices>
  <qemu:commandline>
    <qemu:arg value="-global"/>
    <qemu:arg value="q35-pcihost.below-4g-mem-size=2147483648"/>
    <qemu:arg value="-global"/>
    <qemu:arg value="q35-pcihost.above-4g-mem-size=6442450944"/>
  </qemu:commandline>
</domain>
```
***結果: 途中でGPUがリタイア(フォールト). 尚且つキャンセル直後にBSoD.***

:::

:::note alert
### 設定10

**"iommu" セクションのdriverユニットを調整してみます.**

```diff_xml
<domain xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0" type="kvm">
  (中略)
  <features>
  (中略)
+   <ioapic driver="qemu"/>
  </features>
  <deivices>
  (中略)
    <iommu model="intel">
+     <driver intremap="on" caching_mode="on" iotlb="on"/>
    </iommu>
  </devices>
  (中略)
</domain>
```
***結果: Windows自体が起動せず(延々とOSロード画面のままになる).***

:::

:::note alert
### 設定11

**"iommu" セクションのdriverユニットを元に戻して, smmとmsrsを設定します. 取り敢えずリファレンス通りの48MiBを指定してみましょう(デフォルトは1,2,4,16MiBが設定されています).**

```diff_xml
<domain xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0" type="kvm">
  (中略)
  <features>
  (中略)
+   <smm state="on">
+     <tseg unit="MiB">48</tseg>
+   </smm>
+   <ioapic driver="kvm"/>
+   <msrs unknown="ignore"/>
  </features>
  <deivices>
  (中略)
    <iommu model="intel">
+     <driver caching_mode="on" iotlb="on"/>
    </iommu>
  </devices>
  (中略)
</domain>
```
***結果: ベンチマークを10%も進まずGPUがリタイア(フォールト).***

:::

:::note alert
### 設定12

**smmを64MiBに設定します.**

```diff_xml
<domain xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0" type="kvm">
  (中略)
  <features>
  (中略)
    <smm state="on">
+     <tseg unit="MiB">64</tseg>
    </smm>
    <ioapic driver="kvm"/>
    <msrs unknown="ignore"/>
  </features>
  <deivices>
  (中略)
    <iommu model="intel">
      <driver caching_mode="on" iotlb="on"/>
    </iommu>
  </devices>
  (中略)
</domain>
```
***結果: ベンチマークを13%まで走らせたところでGPUがリタイア(フォールト).***

:::

:::note alert
### 設定13

**smmを1024MiBに設定します.**

```diff_xml
<domain xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0" type="kvm">
  (中略)
  <features>
  (中略)
    <smm state="on">
+     <tseg unit="MiB">1024</tseg>
    </smm>
    <ioapic driver="kvm"/>
    <msrs unknown="ignore"/>
  </features>
  <deivices>
  (中略)
    <iommu model="intel">
      <driver caching_mode="on" iotlb="on"/>
    </iommu>
  </devices>
  (中略)
</domain>
```
***結果: ベンチマークを13%まで走らせたところでGPUがリタイア(フォールト).***

**これ以上smmのサイズを大きくする方向性にはあまり意味がないので, 小さくする(デフォルトサイズより少し大きいサイズから)方向で考えてみます.**

:::

:::note alert
### 設定14

**smmを32MiBに設定します.**

```diff_xml
<domain xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0" type="kvm">
  (中略)
  <features>
  (中略)
    <smm state="on">
+     <tseg unit="MiB">32</tseg>
    </smm>
    <ioapic driver="kvm"/>
    <msrs unknown="ignore"/>
  </features>
  <deivices>
  (中略)
    <iommu model="intel">
      <driver caching_mode="on" iotlb="on"/>
    </iommu>
  </devices>
  (中略)
</domain>
```
***結果: ベンチマークを65%超えたところでGPUがリタイア(フォールト).***

**~~あまりsmmの値を弄っても良くならない気がします.~~**

:::

:::note warn
### 設定15

**smmをonのみ(ゲストに通知されるサイズは1,2,4,16MiBのみ)に設定してみます.**

```diff_xml
<domain xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0" type="kvm">
  (中略)
  <features>
  (中略)
-   <smm state="on">
-     <tseg unit="MiB">32</tseg>
-   </smm>
+   <smm state="on"/>
    <ioapic driver="kvm"/>
    <msrs unknown="ignore"/>
  </features>
  <deivices>
  (中略)
    <iommu model="intel">
      <driver caching_mode="on" iotlb="on"/>
    </iommu>
  </devices>
  (中略)
</domain>
```
***結果: ベンチマークを59%超えたところでエンコーダーとGPU間の疎通がなくなりエンコード失敗.***

:::

:::note warn
### 設定16

+ **何故か消失していたOS情報の"metadata"記載を復活.**
+ **CPUの世代がこれより前になることは有り得ない(予定)なので"feature"を全部載せ.**

```diff_xml
<domain xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0" type="kvm">
  (中略)
+ <metadata>
+   <libosinfo:libosinfo xmlns:libosinfo="http://libosinfo.org/xmlns/libvirt/domain/1.0">
+     <libosinfo:os id="http://microsoft.com/win/11"/>
+   </libosinfo:libosinfo>
+ </metadata>
  (中略)
+ <cpu mode="host-passthrough" check="none" migratable="off">
+   <topology sockets="1" dies="1" cores="16" threads="1"/>
+   <cache mode="passthrough"/>
+   <feature policy="require" name="x2apic"/>
+   <feature policy="require" name="tsc-deadline"/>
+   <feature policy="require" name="hypervisor"/>
+   <feature policy="require" name="tsc_adjust"/>
+   <feature policy="require" name="avx512f"/>
+   <feature policy="require" name="avx512dq"/>
+   <feature policy="require" name="avx512ifma"/>
+   <feature policy="require" name="avx512cd"/>
+   <feature policy="require" name="avx512bw"/>
+   <feature policy="require" name="avx512vl"/>
+   <feature policy="require" name="avx512vbmi"/>
+   <feature policy="require" name="avx512vbmi2"/>
+   <feature policy="require" name="gfni"/>
+   <feature policy="require" name="vaes"/>
+   <feature policy="require" name="vpclmulqdq"/>
+   <feature policy="require" name="avx512vnni"/>
+   <feature policy="require" name="avx512bitalg"/>
+   <feature policy="require" name="avx512-vpopcntdq"/>
+   <feature policy="require" name="spec-ctrl"/>
+   <feature policy="require" name="stibp"/>
+   <feature policy="require" name="arch-capabilities"/>
+   <feature policy="require" name="ssbd"/>
+   <feature policy="require" name="avx512-bf16"/>
+   <feature policy="require" name="cmp_legacy"/>
+   <feature policy="require" name="invtsc"/>
+   <feature policy="require" name="virt-ssbd"/>
+   <feature policy="require" name="lbrv"/>
+   <feature policy="require" name="tsc-scale"/>
+   <feature policy="require" name="vmcb-clean"/>
+   <feature policy="require" name="flushbyasid"/>
+   <feature policy="require" name="pause-filter"/>
+   <feature policy="require" name="pfthreshold"/>
+   <feature policy="require" name="vgif"/>
+   <feature policy="require" name="rdctl-no"/>
+   <feature policy="require" name="skip-l1dfl-vmentry"/>
+   <feature policy="require" name="mds-no"/>
+   <feature policy="require" name="pschange-mc-no"/>
+   <feature policy="disable" name="pcid"/>
+ </cpu>
  <deivices>
  (中略)
    <memballoon model="virtio">
      <address type="pci" domain="0x0000" bus="0x01" slot="0x00" function="0x0"/>
+     <driver iommu="on" ats="on"/>
    </memballoon>
+   <iommu model="intel">
+     <driver caching_mode="on" iotlb="on"/>
+   </iommu>
  </devices>
  (中略)
</domain>
```

***結果: 2本目でBSoD***

:::

## これはwwwwww重大なミスwwwwwwwwwwwww

### ところで……

ここで筆者, 改めて足回り(ハードウェア)をチェックしていて, **ある重大なやらかしに気付く.**

:::note warn

**このPC唯一のPCIe x16スロットは, 物理的には下図のように接続されている.**

```plantuml
object PCIe_x16スロット
object PCIe_x16_to_PCIe_x8_and_M2_x2ライザーカード
object PCIe_x16スロット_to_SFF8654ライザーカード
object M2_to_SFF8611ライザーカード
object NVMe_SSD
object SFF8611ケーブル
object 9211_8i_HBA
object SFF8654toSFF8654ケーブル
object SFF8654toPCIe_x16ライザーカード
object Intel_Arc_B580

PCIe_x16スロット --> PCIe_x16_to_PCIe_x8_and_M2_x2ライザーカード
PCIe_x16_to_PCIe_x8_and_M2_x2ライザーカード --> PCIe_x16スロット_to_SFF8654ライザーカード
PCIe_x16_to_PCIe_x8_and_M2_x2ライザーカード --> M2_to_SFF8611ライザーカード
PCIe_x16_to_PCIe_x8_and_M2_x2ライザーカード --> NVMe_SSD
PCIe_x16スロット_to_SFF8654ライザーカード --> SFF8654toSFF8654ケーブル
M2_to_SFF8611ライザーカード --> SFF8611ケーブル
SFF8611ケーブル --> 9211_8i_HBA
SFF8654toSFF8654ケーブル --> SFF8654toPCIe_x16ライザーカード
SFF8654toPCIe_x16ライザーカード --> Intel_Arc_B580
```

**これらの内, Intel Arc B580と接続しているパーツだけPCIeリビジョンを書き出すと以下のようになる.**

+ PCIe_x16スロット: **PCIe5.0**
+ PCIe_x16_to_PCIe_x8_and_M2_x2ライザーカード: **PCIe4.0**
+ PCIe_x16スロット_to_SFF8654ライザーカード: **PCIe4.0**
+ ***SFF8654toSFF8654ケーブル: PCIe3.0 <--!?!?!?!?!?!!?!?!!?!?!?!?!?!?***
+ SFF8654toPCIe_x16ライザーカード: **PCIe4.0**
+ Intel_Arc_B580: **PCIe4.0**
:::

**お分かり頂けただろうか.**

:::note alert
***途中区間のケーブルだけ, PCIe3.0までの対応なのである.***
:::

:::note alert
***詰まり, PCIe3.0(8GT/s x8)のSFF-8654ケーブルにPCIe4.0(16GT/s x8)の信号を流していたのである.***
:::

:::note alert
***そりゃ通信エラーが起きてIntel Arc B580がフォールトするわけである.***
:::

:::note alert
***そりゃ前の仮想化基盤サーバーでは上手く動いていたはずである(だってその仮想化基盤サーバーはPCIe3.0だったもの……).***
:::

### というわけでUEFI/BIOSでPCIeの動作速度を3.0に落とします

UEFI/BIOSにPCIeの動作速度を設定する項目がありますので, **一律にPCIe3.0(設定出来る最低値)** まで落とします.
**(※SFF-8654ケーブルで「PCIe4.0に対応している」「入手性の良いもの」に行き当たらなかったため)**

### 最終回答:

:::note info

***リンク速度をPCIe3.0にダウングレードする設定をしたら, どんなコマンドよりも有意に全てが安定しましたorz***
:::

~~***何ならベンチマークを3スレッド同時に流しても快調に完走して次のベンチマークを走らせられます.***~~

## 総括

:::note alert
+ **そもそも論として, 相手(ハードウェアやドライバやソフトウェア)を疑うより, 自分で自分が作った環境の構成が本当に適切なのか疑え.**
:::

:::note warn
+ **自分の手元足元に先ず原因を求め, 1つ1つ虱潰しに可能性を消していった後に, 相手(ハードウェアやドライバやソフトウェア)を疑え.**
:::

:::note info
+ **トラブルの原因を最初に自分以外の他者に求めるのは甘え.**
:::