核显直通是 PVE 玩家绕不开的一道坎。网上教程大多只贴配置,不解释为什么这么配,一旦报错就只能从头翻。这篇按「能验证的顺序」重排了一遍,每一步都有检查手段。
一、先确认硬件真的支持
直通的前提是 CPU 和主板都允许把核显从宿主机隔离出去。
- Intel 平台需要 CPU 支持 VT-d,主板 BIOS 里有
VT-d或Intel Virtualization Technology for Directed I/O - AMD 平台对应
IOMMU,通常和SVM分开 - 部分品牌机 BIOS 锁死这些选项,那就只能作罢
在 PVE 宿主机上验证:
# 看到 IOMMU 相关的能力位就说明 CPU 支持
lscpu | grep -i -E 'vt-d|iommu'
# 打开内核参数后,这里会列出分组
dmesg | grep -i -E 'DMAR|IOMMU'
二、三处配置缺一不可
直通失败,九成是这三处漏了某一处。
1. GRUB 内核参数
nano /etc/default/grub
# Intel:
GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on iommu=pt i915.enable_gvt=0"
# AMD:
GRUB_CMDLINE_LINUX_DEFAULT="quiet amd_iommu=on iommu=pt"
update-grub
2. 加载 vfio 模块
echo -e "vfio\nvfio_iommu_type1\nvfio_pci\nvfio_virqfd" >> /etc/modules
update-initramfs -u -k all
3. 把设备 ID 绑给 vfio
# 查出核显的 vendor:device
lspci -nn | grep -i vga
# 写入绑定配置(示例 ID,按实际替换)
echo "options vfio-pci ids=8086:4690 disable_vga=1" > /etc/modprobe.d/vfio.conf
update-initramfs -u -k all
reboot
三、验证是否真的隔离成功
重启后不要急着建虚拟机,先看两件事:
# 核显应该显示 Kernel driver in use: vfio-pci
lspci -k | grep -A 3 -i vga
# 确认设备在独立的 IOMMU 组里
find /sys/kernel/iommu_groups/ -type l | sort -V
如果 Kernel driver in use 还是 i915,说明绑定没生效,回到第二步检查 modprobe.d 里的 ID 是否写错。
四、四个常见报错
| 报错现象 | 真实原因 | 处理 |
|---|---|---|
| 虚拟机启动后黑屏,控制台无输出 | 核显被宿主机占用,绑定未生效 | 检查 vfio-pci 是否在 lsmod 里 |
Cannot open /dev/vfio/xx | 权限或分组错误 | 确认设备在独立分组,必要时加 pcie_acs_override |
| Jellyfin 能识别但硬解失败 | 驱动版本与内核不匹配 | 容器内换 linuxserver/jellyfin 的 latest,或手动装 intel-media-va-driver |
| 直通后宿主机无法用 HDMI 输出 | 正常现象 | 直通就是把设备交出去,宿主机别再想用它 |
pcie_acs_override是一把双刃剑。它能让设备强行分组,但绕过的是硬件本身的隔离边界,安全性会下降。只有在你确认同组设备之间没有 DMA 风险时才用。
五、虚拟机侧的配置
在 PVE 的虚拟机硬件页里:
- 添加 PCI 设备,选中核显
- 勾选
All Functions(多 function 设备必须勾) - 勾选
Primary GPU只在你想用核显输出画面时需要 - 机器类型选
q35,BIOS 用OVMF
Jellyfin 容器里再补一条设备映射:
services:
jellyfin:
image: lscr.io/linuxserver/jellyfin:latest
devices:
- /dev/dri:/dev/dri
group_add:
- "989" # 容器内 render 组的 gid
六、我的最终结论
直通本身不复杂,复杂的是验证。把它拆成「硬件支持 → 内核参数 → 模块绑定 → 分组确认 → 虚拟机配置 → 容器映射」六步,每一步都能用一条命令验证,出问题时你就知道该往回退到哪一步。
如果你只是想跑 Jellyfin 硬解,其实还有个更省事的选择:不直通,直接把 /dev/dri 挂进 LXC 容器。少一层虚拟化,性能损耗也更小。
评论
评论功能默认关闭。想开启的话,去
src/lib/site.ts里把giscus.enabled改成true,填上你的repo和repoId即可——基于 GitHub Discussions, 不需要服务器,也不用数据库。