外观
读懂 IOMMU 分组
开完 IOMMU 之后,能不能直通某个设备,还要看它所在的分组。这篇教你怎么看分组、怎么判断能不能直通,以及分组不干净时有哪些(有代价的)选项。
为什么需要它
IOMMU 分组 (IOMMU group) 是硬件按 PCIe 拓扑划分出的最小隔离单位。同一个分组里的所有设备,只能整组一起直通给同一台虚拟机,不能把组里一个给 VM A、另一个留给宿主机或给 VM B。
这不是 PVE 的软件限制,而是主板 PCIe 拓扑和 CPU/芯片组对 ACS (Access Control Services) 支持程度决定的硬件事实。看懂分组,才知道你那张显卡到底能不能"干净地"拿出来,还是会捎带上你不想放弃的其他设备。
开始之前
已经完成开启 IOMMU 并且 dmesg 里确认 IOMMU 已启用,再来看分组才有意义——IOMMU 没开的情况下,所有设备实际上都挤在一个大分组里,看不出真实的隔离情况。
操作步骤
1. 列出所有分组和组内设备
sh
# 宿主机 shell
for d in /sys/kernel/iommu_groups/*/devices/*; do
n=${d#*/iommu_groups/}; n=${n%%/*}
printf 'Group %s: ' "$n"
lspci -nns "${d##*/}"
done | sort -V输出类似:
text
Group 14: 01:00.0 VGA compatible controller [0300]: NVIDIA Corporation ... [10de:2504]
Group 14: 01:00.1 Audio device [0403]: NVIDIA Corporation ... [10de:228e]
Group 15: 02:00.0 Non-Volatile memory controller [0108]: ...上面这个例子里,显卡(01:00.0)和它自带的 HDMI 音频设备(01:00.1)在同一组——这是正常且没有问题的,它们本来就属于同一张物理卡,直通时会一起给出去。
PVE 也提供了一个自带命令,效果类似,输出里带着分组信息,可以互相印证:
sh
# 宿主机 shell,<节点名> 替换成 Web UI 左侧看到的节点名
pvesh get /nodes/<节点名>/hardware/pci --pci-class-blacklist ""2. 判断分组"干不干净"
| 同组情况 | 能不能直通 |
|---|---|
| 同一张卡的不同功能(显卡 + 它的音频、网卡的多个端口) | 可以,一起给出去就行 |
| 设备所在的 PCIe 根端口 (root port) 或上联的 PCIe 桥 | 通常没问题,这些是拓扑结构本身,一起直通不影响功能 |
| 你想保留给宿主机的设备(系统盘控制器、唯一的网卡) | 不能整组直通,除非把这些设备也一起放弃 |
| 好几个互不相关的设备(比如显卡和网卡)挤在一组 | 不能只挑一个,除非能把分组拆开 |
分组由主板决定,换插槽可能有用
IOMMU 分组的划分由主板的 PCIe 拓扑和 CPU/芯片组的 ACS 支持程度决定,不是显卡或系统的问题。消费级主板经常把好几条 PCIe 插槽挂在同一个分组下。把目标设备换到另一条物理插槽(尤其是直连 CPU 的那几条,通常分组更干净),有时能把它和其他设备分开。具体哪条插槽效果更好,因主板而异,需要实测。
分组不干净时的选项
按代价从低到高:
- 换插槽实测:最简单也最推荐的第一步,见上文提示。
- 检查主板厂商是否有开启更完整 ACS 支持的固件更新:部分主板出厂固件对 ACS 的支持不完整,更新 BIOS 可能改善分组划分。
- 放弃这台机器上的直通方案,或者换一块分组更干净的显卡/网卡插到直连 CPU 的插槽。
pcie_acs_override 不是常规解法,有明确的安全代价
PVE 内核编译时带了一个 ACS override 补丁,可以通过内核参数 pcie_acs_override=downstream(或 multifunction)强制让内核认为设备之间是隔离的,从而把本来挤在一起的分组拆开。
这个参数绕过的是硬件本该提供的 DMA 隔离保证:拆开之后,同一物理拓扑下的设备理论上仍然可以通过总线互相访问对方的内存,如果被直通设备本身或使用它的虚拟机被攻破,攻击面会扩大到"同一分组里原本应该被隔离的其他设备"。
本站不把它作为推荐步骤,只在你已经充分理解这个代价、没有换插槽或换硬件的空间、且直通的虚拟机和使用场景本身可信度较高时,才把它当作最后手段。如果决定使用,改法和开启 IOMMU 里编辑内核参数的方法一致,同样需要遵守那篇里关于物理控制台和回退方式的前提条件。
检查结果
对照第 1 步的输出,确认目标设备所在的分组里,除了它自己的多功能设备、根端口和 PCIe 桥之外,没有其他你还需要留给宿主机或留给别的虚拟机的设备。满足这一条,才能进入具体的直通操作,比如显卡直通或硬盘与 HBA 直通。
常见问题
同一张显卡在不同电脑上分组表现不一样。 正常,分组取决于主板和 CPU 型号,不是显卡本身的属性。
笔记本电脑能不能做直通。 大多数笔记本的 PCIe 拓扑高度集成,分组普遍很差,而且核显往往和其他关键设备挤在一起,实际可行性远低于台式机和服务器主板,动手前先按上文方法确认清楚。
Group 0 或很小的编号里塞了一堆设备。 常见于主板的芯片组下挂了很多设备(USB 控制器、SATA 控制器等)又缺乏 ACS 支持,这类分组通常没法细分,只能整体放弃或者整体直通(如果里面没有必须保留的设备)。