1. juze9

    No comment

    juze9
Changes in body
Source | HTML | Preview
@@ -1,209 +1,207 @@
## はじめに
Proxmox VEでビデオカードをKVMゲストにパススルーします。UEFI環境に絞って説明するため、UEFIに対応したビデオカードの必要があります。この投稿は下記のページを下敷きにしています。あわせてご覧ください。
- [Pci passthrough \- Proxmox VE](https://pve.proxmox.com/wiki/Pci_passthrough)
- [OVMF による PCI パススルー \- ArchWiki](https://wiki.archlinuxjp.org/index.php/OVMF_%E3%81%AB%E3%82%88%E3%82%8B_PCI_%E3%83%91%E3%82%B9%E3%82%B9%E3%83%AB%E3%83%BC)
- [Windows VirtIO Drivers \- Proxmox VE](https://pve.proxmox.com/wiki/Windows_VirtIO_Drivers)
- [Category:HOWTO \- Proxmox VE](https://pve.proxmox.com/wiki/Category:HOWTO)
-環境はCPUがSkylake、GPUがGeForce GT 710およびRADEON HD 5450です。RADEON HD 5450は玄人志向のRH5450-LE1GB/D3/HSで、UEFIに対応しています。
-
-CPUがHaswellだと、RADEON HD 5450でWindowsゲストのとき、AMDのドライバーを入れた瞬間にゲストOSの画面が乱れ、最終的に落ちました。
+CPUがSkylakeおよびHaswell、GPUがGeForce GT 710およびRadeon HD 5450の環境でテストしましたが、結局Windows 10ではRadeonのドライバーを入れるとクラッシュ。UbuntuではRadeon、GeForceともに10分ほど操作していると画面が乱れるようになるなど、安定させることができませんでした。
## VMの準備
OVMF(UEFI)の場合、VirtIOの仮想HDDからブートできません。そのため仮想HDDはSCSIとし、SCSI Controller TypeにWindowsではVirtIO SCSIを、LinuxではVirtIO SCSI singleを選んでください。WindowsでVirtIO SCSI singleは、VirtIOドライバーが対応していないようです。
仮想HDDのキャッシュはWrite backとし、Discardをオンにします。DiscardによってVMでTrimを行うと、仮想HDDのサイズを縮小することができます(LVM-Thinで確認)。
Windowsでは仮想CPUにCore 2 Duoを選ばないと、再起動時にブートできない問題があります。Core 2 Duoを選んでいるわけにもいかないので、再起動はしないで、シャットダウン・起動してください。インストールだけCore 2 Duoで行ってもよいかもしれません。
### インストール(Windows・ドライバー先)
#### VirtIOドライバーをダウンロード
```
cd /var/lib/vz/template/iso &&
wget https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/latest-virtio/virtio-win.iso
```
ダウンロードできたらVMに追加してください。
#### VMの設定
- ハードウェア
- ハードディスク (scsi0): local-lvm:vm-100-disk-1,cache=writeback,discard=on,size=64G
- ネットワークデバイス (net0): virtio=00:00:00:00:00:00,bridge=vmbr0
- オプション
- SCSI Controller Type: VirtIO SCSI
- BIOS: OVMF(UEFI)
#### OSのインストール
- インストールの種類を選んでください→カスタム
- Windowsのインストール場所を選んでください→ドライバーの読み込み→インストールするドライバーの選択→参照→Balloon\w8.1\amd64\balloon.inf→次へ
- Windowsのインストール場所を選んでください→ドライバーの読み込み→インストールするドライバーの選択→参照→NetKVM\w10\amd64\netkvm.inf→次へ
- Windowsのインストール場所を選んでください→ドライバーの読み込み→インストールするドライバーの選択→参照→vioscsi\w10\amd64\vioscsi.inf→次へ
動的なメモリーが働いていない場合は、Balloon\w8.1をProgram Filesにコピーして、BLNSVR.exe -iを実行してください。
### インストール(Windows・ドライバー後)
#### VMの設定
- ハードウェア
- ハードディスク (ide0): local-lvm:vm-100-disk-1,cache=writeback,discard=on,size=64G
- ネットワークデバイス (net0): e1000=00:00:00:00:00:00,bridge=vmbr0
- オプション
- SCSI Controller Type: デフォルト (LSI 53C895A)
- BIOS: OVMF(UEFI)
#### ドライバーのインストール(OSインストール後)
VirtIOドライバーをダウンロード。VMに追加します。そしてVMを起動して、Balloon\w8.1\amd64\balloon.inf、NetKVM\w10\amd64\netkvm.inf、およびvioscsi\w10\amd64\vioscsi.infをそれぞれ右クリックしてインストールします。
動的なメモリーが働いていない場合は、Balloon\w8.1をProgram Filesにコピーして、BLNSVR.exe -iを実行してください。
### インストール(Linux)
#### VMの設定
- ハードウェア
- ハードディスク (scsi0): local-lvm:vm-100-disk-1,cache=writeback,discard=on,size=64G
- ネットワークデバイス (net0): virtio=00:00:00:00:00:00,bridge=vmbr0
- オプション
- SCSI Controller Type: VirtIO SCSI single
- BIOS: OVMF(UEFI)
#### OSのインストール
Linuxではドライバーは最初から入っていますが、UEFIでのブートに苦労します。以下Ubuntuの場合について記します。おおむね[Ubuntu 15\.10 インストール(UEFI)その1 \- UEFIのPCにUbuntu 15\.10をインストールする(ライブメディアから起動 〜 EFIシステムパーティションの作成) \- kledgeb](http://kledgeb.blogspot.jp/2015/10/ubuntu-1510-uefi1-uefipcubuntu-1510-efi.html)の手順通りです。
- ライブメディアから起動し、GPartedで仮想HDDにGPTパーティションテーブルを作成する。
- FAT32で512MiBのパーティションを作成し、仮想HDDへ実際に反映させる。
- ネイティブEFIシステムパーティションのサイズは[EFI システムパーティション \- ArchWiki](https://wiki.archlinuxjp.org/index.php/EFI_%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%83%91%E3%83%BC%E3%83%86%E3%82%A3%E3%82%B7%E3%83%A7%E3%83%B3)で512MiBが推奨されています。
- 作成したパーティションにbootおよびespフラグを立てる。
- デスクトップ上にあるインストーラーを起動する。
- 「インストールの種類」画面で「それ以外」を選び、パーティションをカスタマイズできるルートに入る。
- さきほど作成したパーティションに、タイプ欄でEFIが指定されていることを確認する。
- 1MiBのダミーパーティションを作る。
- 1024MiB程度のスワップパーティションを終点方に作る。
- ダミーパーティションを削除する。
- 残りの領域に、ext4のパーティションを作る。マウントポイントにはルートを指定。
インストールが終わったら再起動せずに、ライブOS上で作業します。端末を立ち上げ次のコマンドを実行します。
```
sudo mount /dev/sda1 /mnt
sudo ls -la /mnt/EFI/ubuntu # grubx64.efiを確認
sudo mkdir /mnt/EFI/BOOT
sudo cp /mnt/EFI/ubuntu/grubx64.efi
/mnt/EFI/BOOT/BOOTX64.EFI
```
これはOVMFがgrubx64.efiからブートしてくれないため、grubx64.efiをBOOTX64.EFIにコピーするコマンドです。コピーが完了したら再起動します。仮想HDDにインストールしたUbuntuからブートするはずです。
## IOMMUを有効にする
### 準備
BIOSでVT-dを有効にしてください。
### 設定
```
# nano /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="quiet"
GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on"
# update-grub
```
AMDのCPUの場合intel_iommuに代えてamd_iommuとします。update-grubを忘れないでください。
### 確認(要再起動)
```
# dmesg | grep -e DMAR -e IOMMU
[ 0.000000] DMAR: IOMMU enabled
```
## x2APICを有効にする
### 準備
BIOSでx2APICを有効にしてください。
### 確認
```
# dmesg | grep -e DMAR -e IOMMU
[ 0.061698] DMAR-IR: x2apic is disabled because BIOS sets x2apic opt out bit.
[ 0.061699] DMAR-IR: Use 'intremap=no_x2apic_optout' to override the BIOS setting.
[ 0.063089] DMAR-IR: Enabled IRQ remapping in xapic mode
```
BIOSで有効にできなかった場合、このように「x2apic is disabled」と表示されます。その場合、以下の設定を行います。
### 設定
```
# nano /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on"
GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on intremap=no_x2apic_optout"
# update-grub
```
update-grubを忘れないでください。
### 確認(要再起動)
```
[ 0.060882] DMAR-IR: Queued invalidation will be enabled to support x2apic and Intr-remapping.
[ 0.062304] DMAR-IR: Enabled IRQ remapping in x2apic mode
```
## カーネルモジュールを組み込む
```
# echo -e "vfio\nvfio_iommu_type1\nvfio_pci\nvfio_virqfd" >> /etc/modules
```
## ビデオカードのPCIアドレスを確認する
```
# for iommu_group in $(find /sys/kernel/iommu_groups/ -maxdepth 1 -mindepth 1 -type d); do echo "IOMMU group $(basename "$iommu_group")"; for device in $(ls -1 "$iommu_group"/devices/); do echo -n $'\t'; lspci -nns "$device"; done; done
IOMMU group 1
00:01.0 PCI bridge [0604]: Intel Corporation Sky Lake PCIe Controller (x16) [8086:1901] (rev 07)
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation Device [10de:128b] (rev a1)
01:00.1 Audio device [0403]: NVIDIA Corporation GK208 HDMI/DP Audio Controller [10de:0e0f] (rev a1)
```
## ビデオカードをvfio-pciに渡す
### 設定
```
# echo options vfio-pci ids=10de:128b,10de:0e0f > /etc/modprobe.d/vfio.conf
```
### 確認(要再起動)
```
# dmesg | grep -i vfio
[ 2.013295] VFIO - User Level meta-driver version: 0.3
[ 2.039844] vfio_pci: add [10de:128b[ffff:ffff]] class 0x000000/00000000
[ 2.055799] vfio_pci: add [10de:0e0f[ffff:ffff]] class 0x000000/00000000
```
## ビデオカードのドライバーを無効にする
```
# echo -e "blacklist radeon\nblacklist nouveau\nblacklist nvidia" >> /etc/modprobe.d/blacklist.conf
```
## VMにパススルーを設定する
```
# nano /etc/pve/nodes/hostname/qemu-server/100.conf
cpu: host
hostpci0: 01:00.0,x-vga=on
hostpci1: 01:00.1
usb0: host=1-3
usb1: host=1-4
```
最近はマシンをq35にし、pcie=1を設定する必要はないようです。
USBのパススルーは[USB physical port mapping \- Proxmox VE](https://pve.proxmox.com/wiki/USB_physical_port_mapping)を参照。
## VMの起動コマンドを確認する
```
# qm showcmd 100
/usr/bin/kvm -id 100 -chardev socket,id=qmp,path=/var/run/qemu-server/100.qmp,server,nowait -mon chardev=qmp,mode=control -pidfile /var/run/qemu-server/100.pid -daemonize -smbios type=1,uuid=a925fcc5-0805-44ad-8b69-c6981816109a -drive if=pflash,format=raw,readonly,file=/usr/share/kvm/OVMF-pure-efi.fd -drive if=pflash,format=raw,file=/tmp/100-OVMF_VARS-pure-efi.fd -name win10 -smp 2,sockets=1,cores=2,maxcpus=2 -nodefaults -boot menu=on,strict=on,reboot-timeout=1000 -vga none -nographic -no-hpet -cpu host,hv_vendor_id=proxmox,hv_spinlocks=0x1fff,hv_vapic,hv_time,hv_reset,hv_vpindex,hv_runtime,hv_relaxed,+kvm_pv_unhalt,+kvm_pv_eoi,kvm=off -m 16384 -k ja -device pci-bridge,id=pci.2,chassis_nr=2,bus=pci.0,addr=0x1f -device pci-bridge,id=pci.1,chassis_nr=1,bus=pci.0,addr=0x1e -device piix3-usb-uhci,id=uhci,bus=pci.0,addr=0x1.0x2 -readconfig /usr/share/qemu-server/pve-usb.cfg -device usb-tablet,id=tablet,bus=uhci.0,port=1 -device vfio-pci,host=01:00.0,id=hostpci0,bus=pci.0,addr=0x10 -device vfio-pci,host=01:00.1,id=hostpci1,bus=pci.0,addr=0x11 -device usb-host,hostbus=1,hostport=3,id=usb0 -device usb-host,hostbus=1,hostport=4,id=usb1 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 -iscsi initiator-name=iqn.1993-08.org.debian:01:cad28f461da5 -drive file=/dev/pve/vm-100-disk-1,if=none,id=drive-ide0,format=raw,cache=none,aio=native,detect-zeroes=on -device ide-hd,bus=ide.0,unit=0,drive=drive-ide0,id=ide0,bootindex=100 -drive file=/var/lib/vz/template/iso/Windows10.iso,if=none,id=drive-ide2,media=cdrom,aio=threads -device ide-cd,bus=ide.1,unit=0,drive=drive-ide2,id=ide2 -netdev type=tap,id=net0,ifname=tap100i0,script=/var/lib/qemu-server/pve-bridge,downscript=/var/lib/qemu-server/pve-bridgedown -device e1000,mac=1A:01:70:2D:27:49,netdev=net0,bus=pci.0,addr=0x12,id=net0 -rtc driftfix=slew,base=localtime -global kvm-pit.lost_tick_policy=discard
```
hv_vendor_id=proxmoxはNVIDIAのコード43対策。NVIDIAのWindows用ドライバーは、仮想マシン上であることを検知すると停止するため、それへの対策です。しかし、手元の環境ではこの対策をしていてもコード43を回避できませんでした。
## VMを起動・停止する
```
# qm start 100
# qm stop 100
```
WebUIから行っても構いません。めでたくビデオカードをパススルーできるはずです。
## RadeonでVMを再起動できない問題
RadeonにはVMを再起動できない問題があるようです。手元の環境では確認できませんでしたがご注意ください。
参考: [ESXi 6\.0u1 GPUパススルーでVM再起動できない問題の解決|HaioH:変遷備忘録](http://silver0480.blog80.fc2.com/blog-entry-411.html)