顯示卡直通(GPU Passthrough) 讓Windows虛擬機能以接近原生效能玩大型3D遊戲。本文說明如何在Ubuntu安裝Windows虛擬機,並將獨立顯示卡直通給虛擬機的作法。
為什麼要這麼做?Linux的QEMU/KVM的虛擬機的3D性能十分低落,跑不動3D應用程式,為此將顯示卡直通給虛擬機使用。
顯示卡直通(GPU Passthrough)搭配VFIO核心模組,即可讓虛擬機存取宿主機的硬體資源,,Proxmox VE系統有採用此技術,現在我們要在一般的Ubuntu桌面系統搞GPU直通。
要做到這點,電腦需要二張顯示卡(一個CPU內顯,一個獨立顯示卡),再準備二台螢幕。
原理是這樣的:將獨顯直通給虛擬機後,宿主機便無法存取獨顯,故需要內顯用於顯示畫面。
我的電腦主機後方有內顯和獨顯的HDMI連接埠,通常主螢幕是插在Nvidia獨顯的連接埠
而獨顯在直通給虛擬機後,等同與系統隔離,Linux便無法存取Nvidia顯示卡,主螢幕就要改插Intel內顯的連接埠才有畫面,Nvidia獨顯則插上副螢幕。也就是讓Linux畫面輸出到CPU;Windows畫面由獨立顯示卡輸出。
如果你沒有二個螢幕也沒關係!請使用文末提及的「Looking Glass」存取Windows桌面。讓你能夠在使用Linux的時候,透過Looking Glass的視窗與Windows桌面互動。
影片設定過程參考
1. 環境#
- 主機板:ASUS K31CD-K
- CPU: Intel® Core™ i5-7400
- GPU:Intel® UHD Graphics 630 (內顯)
- GPU:NVIDIA GTX 1050 Ti(獨顯),已安裝閉源驅動
- 主螢幕x1
- 副螢幕x1
- 宿主機Host OS:Ubuntu 22.04 LTS
- Linux核心版本:6.5.0
- 虛擬機Guest OS:Windows 11 23H2
- QEMU版本:6.2
- Libvirt版本:8.0.0
2. 安裝Windows 11虛擬機#
參見 Linux安裝Windows 11虛擬機 (QEMU KVM)
建議不要安裝SPICE Tools。
安裝後將Windows虛擬機關機。
3. 啟用IOMMU#
使用VFIO前必須先啟用IOMMU。
- 編輯
/etc/default/grub
sudo vim /etc/default/grub
- 針對Intel CPU,在
GRUB_CMDLINE_LINUX_DEFAULT
後面加入以下內容,啟用IOMMU
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash intel_iommu=on iommu=pt"
- 更新GRUB後重開機。
sudo update-grub
sudo reboot
4. 將Nvidia顯示卡綁定給VFIO#
- 解除安裝Nvidia閉源驅動,這樣系統才不會有多餘行程嘗試載入Nvidia驅動
sudo apt purge nvidia-driver-535
sudo apt install xserver-xorg-video-nouveau
- 貼上以下指令,查找獨顯和HDMI裝置的ID
#!/bin/bash
shopt -s nullglob
for g in /sys/kernel/iommu_groups/*; do
echo "IOMMU Group ${g##*/}:"
for d in $g/devices/*; do
echo -e "\t$(lspci -nns ${d##*/})"
done;
done;
- 找到GTX 1050Ti和顯示卡的HDMI音訊裝置,像這裡是Group 2
IOMMU Group 2:
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GP107 [GeForce GTX 1050 Ti] [10de:1c82] (rev a1)
01:00.1 Audio device [0403]: NVIDIA Corporation GP107GL High Definition Audio Controller [10de:0fb9] (rev a1)
將後面的二個硬體ID記起來,例如
10de:1c82
和10de:0fb9
。將Nvidia顯示卡綁定給VFIO,再次修改
/etc/default/grub
sudo vim /etc/default/grub
- 將
GRUB_CMDLINE_LINUX_DEFAULT
增添為以下內容,video=efifb:off
防止系統搶走顯示卡,vfio-pci.ids
指定要綁定的硬體ID,modprobe.blacklist
禁止載入Nvidia核心模組。kvm.ignore_msrs=1
防止KVM錯誤更正導致Windows進入BSOD。
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash intel_iommu=on iommu=pt video=efifb:off modprobe.blacklist=nouveau,nvidia vfio-pci.ids=10de:1c82,10de:0fb9 kvm.ignore_msrs=1 kvm.report_ignored_msrs=0"
- 編輯
/etc/modules-load.d/vfio-pci.conf
,啟用開機自動載入vfio-pci核心模組
echo "vfio-pci" | sudo tee -a /etc/modules-load.d/vfio-pci.conf
- 更新initramfs和GRUB,重開機
sudo update-initramfs -u
sudo update-grub
sudo reboot
重開機一直按著delete,進到UEFI,開啟內顯優先模式。我的是在Advanced → System Agent (SA) Configuration,設定「內顯(IGFX)」優先開機,並開啟「混合螢幕輸出」。
主螢幕改插到內顯的孔,副螢幕插到獨顯的孔(如果你沒有二個螢幕就讓Nvidia顯示卡的孔空著)
重開機進入Linux系統,理論上此時副螢幕應該不會有任何畫面輸出。
執行
sudo lspci -nnk
指令,應該會看到Nvidia顯示卡Kernel driver in use:
是為vfio-pci
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GP107 [GeForce GTX 1050 Ti] [10de:1c82] (rev a1)
Subsystem: ASUSTeK Computer Inc. GP107 [GeForce GTX 1050 Ti] [1043:85d6]
Kernel driver in use: vfio-pci
Kernel modules: nvidiafb, nouveau
01:00.1 Audio device [0403]: NVIDIA Corporation GP107GL High Definition Audio Controller [10de:0fb9] (rev a1)
Subsystem: ASUSTeK Computer Inc. GP107GL High Definition Audio Controller [1043:85d6]
Kernel driver in use: vfio-pci
Kernel modules: snd_hda_intel
5. 將獨顯加入到虛擬機#
開啟Virt Manager,按二下開啟Windows虛擬機,點左上角i編輯硬體
點選左下角添加硬體 → 新增PCI主機裝置,將獨顯和獨顯音訊HDMI都加進去
現在虛擬機有二個螢幕了,一個是虛擬機的QXL顯示卡,一個是Nvidia顯示卡
虛擬機開機後,主螢幕會看到Windows畫面,副螢幕會暫時黑畫面。
在虛擬機安裝 GeForce Experience更新顯示卡驅動之後,副螢幕應該就會跳出畫面了。
接著在系統設定 → 顯示器 → 圖形,選取應用程式exe,指定使用Nvidia顯示卡彩現,而非QXL。
程式只要指定使用Nvidia顯示卡渲染,就會吃到GPU加速。儘管如此,程式的視窗在副螢幕上時效能最好。你可以編輯虛擬機硬體,將QXL顯示卡設定為None,讓虛擬機只有一個螢幕。
如果副螢幕有喇叭,則Windows的音效會透過HDMI從副螢幕輸出。
6. 安裝Looking Glass#
Looking Glass是為只有一個螢幕的用戶準備的,讓你可以在同一個畫面同時操作Linux和Windows虛擬機。
注意Looking Glass Host與Client的版本需一致。Ubuntu 22.04已收錄looking-glass-client
套件,不需要手動編譯了。