注意:根據 Intel官網資料,Intel GVT-g技術僅適用Intel 11代(Rocket Lake)以前的CPU。搭載Intel Xe的新型CPU請改用「SR-IOV」技術。
本文探討如何在Linux系統利用「Intel GVT-g」技術將Intel的GPU虛擬化,將資源分享給QEMU/KVM虛擬機使用,使雙方都可以有3D硬體加速。
Intel CPU很多型號都有附贈GPU,稱之為內顯,讓電腦開機有畫面,用於看影片沒有問題的。
如果要在Linux上的虛擬機達成硬體加速,之前我提過GPU Passthrough的方法: 直通Intel GPU給QEMU/KVM虛擬機,不使用GVT-g 但這是有雙顯示卡的前提下才能這麼做,因為一旦顯示卡給虛擬機獨佔,Linux宿主機就沒有畫面了。
故採用本文提及的GPU虛擬化技術,即可讓宿主機與虛擬機共享Intel GPU。如果你的電腦只有一個Intel GPU想必會非常有用。而且Intel GVT-g是可以一對多,分配GPU資源給多個虛擬機的。
1. 環境#
- Host OS:Arch Linux
- Guest OS:Windows 10 22H2
- 核心版本:6.6.11
- QEMU版本:8.2.0
- Libvirt版本:9.10.0
- CPU:Intel i5-7400
- GPU:Intel UHD 630
我是雙顯卡桌電的配置,螢幕線必須接在Intel顯卡的HDMI上,GVT-g才能發揮作用。
2. 啟用GVT-g#
- 在
/etc/default/grub
加入以下內容,啟用IOMMU、vfio-pci、GVT-g核心模組
GRUB_CMDLINE_LINUX_DEFAULT="loglevel=3 quiet intel_iommu=on iommu=pt enable_gvt=1 i915.enable_guc=0 i915.enable_gvt=1"
- 更新GRUB
sudo grub-mkconfig -o /boot/grub/grub.cfg
- 設定開機自動載入核心模組
echo "vfio-pci" | sudo tee -a /etc/modules-load.d/vfio-pci.conf
echo "kvmgt" | sudo tee -a /etc/modules-load.d/kvmgt.conf
echo "mdev" | sudo tee -a /etc/modules-load.d/mdev.conf
- 重開機。
3. 新增mdev裝置#
- 取得Intel內顯的PCI位址
lspci | grep Intel
- 查看可用設定檔,路徑為上一步的指令PCI位址轉寫,例如
00:02.0
就是0000:00:02.0
。這裡我選取了i915-GVTg_V5_4
設定檔。
ls /sys/bus/pci/devices/0000:00:02.0/mdev_supported_types/
cat /sys/bus/pci/devices/0000:00:02.0/mdev_supported_types/i915-GVTg_V5_4/description
- 賦予
i915-GVTg_V5_4
一個UUID
su
uuidgen
echo "9e7afbf1-3b1e-4699-8cc2-a050b4b60b11" > /sys/bus/pci/devices/0000:00:02.0/mdev_supported_types/i915-GVTg_V5_4/create
如果賦予多個UUID,等同建立多個虛擬GPU,讓不同的虛擬機使用。但是Intel GPU的VRAM不是很大,實務上分配2個就很吃緊了。
如果要移除虛擬GPU就傳入1
echo 1 > /sys/bus/pci/devices/0000:00:02.0/填入UUID/remove
- 查看目前mdev裝置的狀態
ls -l /sys/bus/mdev/devices/
4. 將Intel GPU掛載至Libvirt虛擬機#
經測試,用UEFI韌體的虛擬機會出現各種詭異錯誤,可能是OVMF的bug,掛載i915ovmf.rom也沒用。虛擬機必須使用傳統BIOS韌體才有畫面。
開啟Virt Manager,新增 Windows虛擬機,開機韌體選取Q35和BIOS
點選編輯硬體,新增mdev主機裝置
開機後Windows應該會自動裝好Intel驅動,若無,開啟裝置管理員,對顯卡按下右鍵,更新驅動。
虛擬機預設的QXL顯示卡加上Intel GPU,於是Windows會偵測到二個螢幕。在系統設定 → 顯示器 → 圖形的部份,可以指定應用程式exe使用Intel GPU運算。
Windows工作管理員可看到Intel GPU有在運作。Linux端只能透過
intel_gpu_top
指令間接得知。因為是共享資源,若Windows端做太多重度運算一定會影響到宿主機的流暢度的。