Passthrough Intel GPU to QEMU/KVM VM on Linux host.
本文Ivon紀錄將Linux宿主機的Intel顯示卡,直通給QEMU/KVM虛擬機的過程。
我的這台Linux桌電,Intel CPU有附Intel UHD內顯(iGPU),然而桌電常常是插在Nvidia獨顯上,這時內顯就晾在那邊沒事幹。雖說Intel UHD內顯性能不怎麼樣,但還是想做有效利用,為此我決定將其直通給虛擬機使用,如下圖:
這樣直通的顯示卡接上螢幕之後,讓虛擬機裡面系統動畫順一點,能利用3D硬體加速播放影片,玩點小遊戲。

順帶一提,如果有Intel Arc獨立顯示卡也是可以進行GPU直通的,它使用的驅動核心模組跟Intel UHD內顯幾乎是一樣的。使用起來就會變這樣:
1. 環境說明#
如果要讓虛擬機使用宿主機的GPU,搜尋資料常常會提及使用Intel GVT-g的虛擬GPU技術,不過我們有更簡單的作法:像直通Nvidia獨顯那樣隔離PCI再直通就好了。
硬體:
- Host OS:Ubuntu 24.04
- 主機板:ASUS K31CD-K
- CPU:Intel i5-7400
- GPU:Intel UHD 630 ← 要直通的GPU
- GPU:Nvidia GTX1050Ti ← 顯示Linux和虛擬機視窗的GPU
接著是要直通的虛擬機系統,為什麼還要直通給另一個Linux?Intel的Linux驅動是開源的,直通後成功機率較大…
- Guest OS 1:Ubuntu 24.04
- Guest OS 2:Windows 11 25H2
2. 安裝虛擬機#
首先要安裝Libvirt + QEMU/KVM,設定好VFIO
並裝好Windows 11虛擬機。Ubuntu 24.04的安裝過程我不贅述。
3. 啟用IOMMU#
- 編輯GRUB設定檔
sudo vim /etc/default/grub- 在GRUB_CMDLINE_LINUX_DEFAULT這行後面加入核心參數,啟用Intel CPU的
iommu。
GRUB_CMDLINE_LINUX_DEFAULT="intel_iommu=on"- 重新產生設定檔,重開機
sudo grub-mkconfig -o /boot/grub/grub.cfg
sudo reboot- 終端機貼上以下指令稿查找顯示卡的IOMMU群組:
#!/bin/bash
shopt -s nullglob
for g in /sys/kernel/iommu_groups/*; do
echo "IOMMU Group ${g##*/}:"sudo update-initramfs -u -k all
sudo update-grub
for d in $g/devices/*; do
echo -e "\t$(lspci -nns ${d##*/})"
done;
done;- 應會看到Intel顯示卡的分組,後面的四位數組合
8086:5912就是硬體ID了。
IOMMU Group 0:
00:02.0 Display controller [0380]: Intel Corporation HD Graphics 630 [8086:5912] (rev 04)4. 啟用VFIO#
VFIO核心模組負責將PCI-E裝置暴露給虛擬機使用。接下來要將Intel的硬體ID綁給VFIO,然後要防止Linux開機的時候搶走Intel顯示卡的控制權。這有很多種作法,比如將Intel依賴的核心模組加入黑名單(blacklist)禁止載入。或者調整核心模組載入順序,確保VFIO可以搶先Intel需要的核心模組載入。這樣做的好處是如果你有Intel UHD + Intel Arc顯示卡的配置,兩個都需要i915驅動,不會因為將i915這個核心模組黑名單而導致兩張卡都沒畫面。這裡我們是透過vfio-pci綁定特定的硬體,再交給Libvirt控制的,因此不需要將i195核心模組黑名單完全禁止載入。
- 修改Linux的initramfs設定檔:
sudo vim /etc/initramfs-tools/modules- 設定開機儘早載入VFIO,這也可以防止接著Nvidia顯示卡的副螢幕開機時被意外喚醒。最後面
ids=將Intel顯示卡綁定給VFIO。
vfio vfio_iommu_type1 vfio_virqfd vfio_pci ids=8086:5912- 設定開機載入VFIO核心模組
sudo vim /etc/modprobe.d/vfio.conf- 加入以下選項
options vfio-pci ids=8086:5912- 設定VFIO先於Intel驅動載入
sudo vim /etc/modprobe.d/intel.conf- 填入以下內容,Intel顯示卡使用的多半是
i915這個核心模組,因此設定為在vfio-pci模組之後載入:
softdep i195 pre: vfio-pci- 防止KVM錯誤更正導致Windows虛擬機進入BSOD。
sudo vim /etc/modprobe.d/kvm.conf- 填入以下內容:
options kvm ignore_msrs=1- 更新initramfs和GRUB,重開機
sudo update-initramfs -u -k all
sudo update-grub5. 設定優先用獨顯開機#
以我這個ASUS主機板來說,需要特別的設定,讓系統優先以獨顯開機,也防止Linux佔用i1915核心模組。
重開機進入BIOS,到Advanced → System Agent (SA)Configuration,設定以PCI獨顯優先開機,並勾選Enable iGPU Multi-Monitor。
6. 將Intel顯示卡分配給虛擬機#
開啟Virt Manager,對虛擬機按二下。
點選編輯硬體,新增硬體 → PCI裝置,將Intel UHD 630顯示卡分配給虛擬機。

7. 在Ubuntu虛擬機內安裝Intel驅動#
Linux的Intel顯示卡驅動是含在核心裡面的,透過Mesa提供,不用裝。
用指令sudo losmod | grep i915確認i915核心模組有載入
接著,不論Intel顯示卡主機上的HDMI孔有無接實體螢幕,系統都能使用Intel顯示卡運算了。
安裝intel-gpu-tools,再執行sudo intel_gpu_top可監控Intel顯示卡有沒有真的跑起來。
8. 在Windows虛擬機內安裝Intel驅動#
正版的受害者?Winbdows 22H2測試時跳出錯誤。
理論上直通Intel顯示卡之後,Windows更新應該就會自動安裝Intel UHD 630驅動。然而有時裝好後裝置管理員顯示驚嘆號,出現代碼43錯誤 (Code 43),似乎是bug。UNRAID論壇和CSDN也有人也發現此問題。
經過搜尋之後,發現這可能是複合性問題,要讓Intel UHD 630驅動正常運作,必須裝30.*版本的驅動,且QEMU機器類型必須是i440fx
由於我已經有Windows虛擬機了,之前測試過Nvidia顯示卡直通沒問題,Intel卻有bug。故在該問題解決之前,我只能保持原本的虛擬機不變,另外創一個空的Windows的虛擬機,讀取舊的虛擬機的硬碟開機。這樣做的話Windows的PIN會噴掉,需要重設。
開啟Virt Manager,點選左上角新增機器,跳過新增儲存。作業系統選擇
Microsoft Windows NT Server 3.1,機器類型選擇i440fx,點選開機前自訂配置。在機器的頁面選取i440fx,韌體選UEFI (OVMF_CODE.secboot)

點選左下角新增硬體,選儲存,選取現有虛擬機的硬碟

別忘了新增虛擬TPM 2.0硬體裝置

開機,按照畫面指示重設Windows的PIN。
暫停Windows更新,防止下載新版驅動,或是把虛擬網卡移除,將虛擬機斷網。
開啟裝置管理員,對Intel UHD 630 點右鍵 → 解除安裝裝置 → 裝置(依驅動程式),右鍵強制移除
iigd_dch.inf驅動程式。重開機。
至Intel官網下載
30.0.101.1340驅動,選取zip版的。將其解壓縮。回到裝置管理員,點選「其他裝置」下的「視訊控制卡」,右鍵 → 更新驅動程式 → 瀏覽電腦上的驅動程式,填入剛剛解壓縮的資料夾,讓Windows自動安裝驅動程式。

重開機一切應該就正常了。
接著指定應用程式使用Intel顯示卡運算
開啟系統 → 顯示器 → 圖形,選取應用程式exe,指定使用Intel顯示卡運算。

再用工作管理員監控Intel顯示卡有沒有動起來。

順帶一提,遠端存取啟用硬體加速:內網穿透+RDP的方案無法使用硬體加速。於虛擬機內安裝Looking Glass即可使用硬體加速的遠端桌面。
9. 如何讓一切回歸原狀#
將/etc/initramfs-tools/modules和/etc/modprobe.d/vfio.conf內容全部註解掉。
重新生成initramfs和GRUB設定檔。


