ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

ACS与IOMMU分组:超微华硕BIOS中PCIe直通开关排查指南

ACS与IOMMU分组:超微华硕BIOS中PCIe直通开关排查指南 最近后台收到好几条类似的问题给超微、华硕主板刷好系统、准备上 PCIe 直通的时候lspci 一看 IOMMU 分组设备全挤在一个组里想单独透传一张网卡出去要么透传不成功要么一启动虚拟机宿主机直接死机。折腾一圈回来所有人都会卡在同一个地方BIOS 里翻来覆去找不到 ACS 选项。这个事我前前后后帮人排查过很多次也踩过不少坑。ACS 这个开关在不同厂商、不同 BIOS 版本里的藏身位置极其反直觉超微和华硕还各有各的脾气。这篇就把我在超微、华硕板子上找 ACS、关 ACS 重定向的完整思路和实操记录整理出来包括 BIOS 里到底怎么搜、搜不到还能走哪些替代方案以及验证分组是否生效的方法希望能帮你少走弯路。1. 先说清楚ACS 到底是什么为什么一定要动它1.1 用几分钟理解 ACS 和 IOMMU 分组ACS 的全称是 Access Control Services这是 PCIe 规范里一个可选的扩展能力。它的作用是让 PCIe 交换机Switch或 Root Port 能够对上下游设备之间的 DMA 访问做隔离。说得直白一点如果没有 ACS连接在同一个 PCIe Switch 下面的两个设备理论上可以互相发起 DMA 请求而有了 ACS 之后交换机会对这些请求做检查按规则决定放行还是阻断。这个能力和虚拟化里的设备直通VFIO passthrough关系非常大。现代平台做直通时IOMMU 会按照系统的拓扑关系把设备划分成一个个 IOMMU group。同一个 group 里的设备在 DMA 层面没有被隔离所以宿主机必须把它们看成一个整体。你要是想把其中一张卡透传给虚拟机内核出于安全考虑会拒绝单独透传或者即便强行绕过限制也会因为设备间互相访问的问题产生奇怪故障。所以你会看到很多人说“ACS 影响直通”。本质上是这样有 ACS 的 Switch 和 Root Port 会向软件报告“我这级别能隔离”IOMMU 据此把设备一个个拆到独立的分组里。如果没有 ACS设备全部堆在一起分组就特别粗直通自然困难。1.2 哪些场景会碰到“找不到 ACS 选项”这个坑不是所有人 BIOS 里都要去动 ACS。但如果你属于下面几类情况大概率会在某个环节卡住第一类是家庭实验室和 NAS 折腾党。搞 PVE 或者 ESXi想直通 SATA 控制器给黑群晖直通万兆网卡给软路由结果设备分组不隔离一张卡都透传不出去。第二类是工作站用户。超微的 X11、X12、H11 这些板子华硕的 WS 系列、Z 系列搭配独立显卡、计算卡想通过 GPU 直通给虚拟机做 AI 推理或图形加速发现 BIOS 里没有可用的 ACS 开关默认分组不支持。第三类是跑 SR-IOV 的同学。想把一张支持 SR-IOV 的网卡拆成多个 VF 发给不同虚机但宿主机用的是 ACS 隔离逻辑来管理分组分不出来就会导致 VF 分配异常。第四类比较特殊是 PCIe 扩展卡场景。买了 PCIe 转 M.2 转接卡、PCIe 拆分卡插上多块 NVMe 之后因为 Switch 没有 ACS所有盘被绑进同一个 IOMMU group不仅直通麻烦某些平台上还会影响设备热插拔。当你确认自己确实需要处理 ACS 之后回到 BIOS 里找来找去却找不到那个开关这才是最让人抓狂的部分。下面我会按平台分别讲超微和华硕的实际排查顺序和操作路径。2. 动手前先确认你的主板和平台到底缺不缺 ACS2.1 在系统里先看清楚当前 PCIe 拓扑先别急着重启进 BIOS 瞎翻。第一步应该是进系统里把当前 PCIe 拓扑和 IOMMU 分组状态导出来确认问题到底是不是 ACS 引起的。否则你在 BIOS 里折腾半天结果发现只是内核参数没给对那才是浪费时间。Linux 下首先要确认 IOMMU 有没有开dmesg | grep -i -e DMAR -e IOMMU看到“DMAR: IOMMU enabled”这类字样才说明 IOMMU 正常工作。如果是 Intel 平台没开 VT-dAMD 平台没开 SVM那跟 ACS 一点关系都没有先把这两个开关在 BIOS 里打开。接下来看设备分组#!/bin/bash for g in /sys/kernel/iommu_groups/*; do echo IOMMU Group $(basename $g); for d in $g/devices/*; do lspci -nns ${d##*/}; done; done把这个脚本存成iommu_groups.shroot 权限跑一遍。你会看到每个分组下面挂着哪些设备。如果某个 group 里同时出现了两个非桥接类设备而且它们是通过 Switch 连上来的那大概率就是 ACS 缺失导致的粗分组。注意很多平台上多功能设备同一个物理设备的不同 Function本来就会被分到同一个组这未必是 ACS 的问题需要结合拓扑判断。再看一下完整的 PCIe 拓扑树lspci -tv这个命令会画出树状结构能看到设备是直接挂在 Root Port 下还是中间隔着一层 PCIe Switch。如果中间有 Switch那就特别值得关注 ACS 设置。2.2 快速判断 BIOS 是否真的没提供 ACS在进入 BIOS 之前还有一个办法可以判断这台机器的 BIOS 到底支不支持 ACS 开关就是去查 ACPI 表里暴露的信息。Linux 下可以看ls /sys/kernel/iommu_groups/*/devices/ | wc -l以及通过dmesg搜索 ACS 相关输出dmesg | grep -i acs如果内核启动日志里出现了类似ACS: ... enabled的消息说明平台的相关端口向软件声明了 ACS 能力如果什么都没打出来只能说明固件或者设备没有正确报告 ACS 支持。但注意内核里有没有打日志和 BIOS 里有没有开关并不完全等价很多 OEM 固件默认就是把 ACS 写死在初始化代码里不在任何菜单暴露。所以这里我建议大家用一个更务实的判断标准进 BIOS 后找三到五个常见位置如果全部翻完都没有任何 ACS 字样再去考虑打补丁或者硬件拓扑调整的方案。不要只翻一遍主菜单就下结论这个选项藏得很深。3. 超微主板 BIOS 实战逐级索引 ACS 选项的路径3.1 超微常见 BIOS 结构的排查顺序超微的服务器、工作站主板 BIOS 大多是 AMI 核心但菜单结构和消费级主板区别很大。常见的 X11 系列、X12 系列开机按 Del 进 BIOS 之后默认会停在 “Main” 标签页。我遇到的大部分超微板子ACS 相关选项优先去这几个地方找第一个是Advanced菜单下的PCIe/PCI/PnP Configuration。这是超微 BIOS 里最常放 PCIe 相关开关的地方进去之后逐个子项往下翻重点看带ACS、PCIe ACS、ACS Control字样的项。不少 X11 系列板子在这里会有一个叫ACS Enable或者PCIe ACS的开关默认是Auto或者Disabled你想要更强的隔离就改成Enabled。第二个是Advanced下的Chipset Configuration。进去之后找North Bridge或IIO Configuration在 Intel 平台上IIOIntegrated IO模块控制着所有 PCIe Root Port 和拆分选项。ACS 相关的开关偶尔会出现在这里的某个 PCIe Port 的子菜单里名字不一定带 ACS可能是PCIe Port里的某个可选设置。如果你看到PCIe Port x这样的条目进去把每个端口的状态和高级选项都过一遍。第三个位置是Advanced下的PCIe AER或PCIe Error Reporting附近。有些 BIOS 把 ACS 和高级错误报告混在一个组里管理虽然这俩在规范里是独立的但 BIOS 开发人员做菜单的时候为了方便经常把它们挂在同一个页面。第四个需要留意的位置比较隐蔽部分超微板子在Advanced→ACPI Settings里藏了PCIe ACS相关的 ACPI 参数特别是在一些面向虚拟化场景定制过的固件里会出现。如果你前面的位置都翻了没结果ACPI Settings 里也要花几分钟过一遍。3.2 特定型号选项的命名差异超微板子即便是同一个世代不同型号的 BIOS 菜单也可能有出入。我经手的板子里遇到过好几种不同的命名方式整理成表格方便对照实际出现过的菜单名称出现位置备注ACS EnableAdvanced PCIe/PCI/PnP Configuration直接开关Enabled 后打开所有 Root Port 的 ACSPCIe ACSAdvanced Chipset Configuration North Bridge部分 X11 单路板ACS ControlAdvanced PCIe/PCI/PnP Configuration有 Auto/Enabled/Disabled 三态Source ValidationAdvanced PCIe/PCI/PnP Configuration代工厂固件里常见属于 ACS 的一个子功能PCIe IsolationAdvanced Chipset Configuration部分定制 OEM 固件才出现警告一下不同 BIOS 版本之间同名选项的含义也可能有微调。如果你刷过其他版本的固件或者买的是整机厂商定制过的超微板选项名对不上是很正常的事。最保险的办法是记住这几个关键词然后在 BIOS 的搜索功能里搜。AMI 的 BIOS 在高级页面通常会提供搜索操作路径是按下F9或者通过右上角的搜索框取决于具体版本。搜ACS把所有命中的条目过一遍比逐级菜单翻效率高很多。我在超微 X11SPA-TF 上就是这么找到的直接搜 ACS搜出来三个条目其中一个藏在 Bios 的PCIe/PCI/PnP Configuration底层子菜单里肉眼翻几乎不可能注意到。还要提醒一点超微很多服务器板是 BMC 集成的BIOS 里还有一个PCIe Slot Configuration或Onboard LOM相关的设置项。如果你发现某个跟 LAN 或者 BMC 共享带宽的 PCIe 插槽选项有开关先不要急着改那可能是 BIOS 在做插槽带宽拆分比如 x16 拆成 x8x8和 ACS 隔离不是一回事。动错了反而影响带宽。4. 华硕主板 BIOS 实战消费级与工作站级的选项位置差异4.1 消费级如 Prime、TUF、ROG 的路径与搜索技巧华硕消费级主板用的也是 AMI BIOS但 UI 风格偏图形化选项层级更琐碎。找 ACS 之前先确认你的 BIOS 是不是新版图形界面。如果是 2021 年之后的 EZ Mode 图形 BIOS直接按F7进入高级模式。消费级华硕板子ACS 选项最常在以下几个地方第一个是Advanced→PCI Subsystem Settings。这个菜单在多数华硕主板上都有进去之后能看到Above 4G Decoding、Re-Size BAR Support这些热门选项ACS 有时就在这个页面最下面。如果你看到ACS Enable或者PCIe ACS直接开。不过说实话消费级板子这里出现 ACS 的概率不高。第二个尝试的地方是Advanced→PCH Configuration。部分 Intel 平台主板的 PCIe 端口由 PCH 引出ACS 相关的控制项会放在PCI Express Configuration下面。每个 PCIe 端口的子菜单里可能有独立的 ACS 开关也可能整页只有一个全局开关。第三个是Advanced→North Bridge或CPU Configuration里的PCIe Configuration。这里主要负责 CPU 直连的那几条 PCIe 通道。如果板子上 M.2_1 插槽直连 CPU很可能相关设置就在这里。ACS 开关同样可能伪装成端口级选项出现。第四个是Advanced→Thunderbolt Configuration。如果你板子上有雷电接口这个菜单下面经常能看到PCIe ACS相关的东西。这是因为雷电控制器本质上是 PCIe SwitchACS 对它的工作方式影响很大。还有一个很多华硕玩家不知道的渠道华硕部分 BIOS 的功能页面里有一个Search功能通常在高级模式里按F9可以呼出或者直接在Main页面右下角有搜索图标。搜索时输入ACS有结果就是有没结果基本就是这版 BIOS 没暴露这个选项不用再花时间逐级翻。我在华硕 Z97 这类老平台上折腾过 M.2 转接卡直通当时 BIOS 里完全搜不到 ACS后来发现是主板 PCH 引出的 PCIe 通道本身不支持 ACS硬件层面就没有这个能力再怎么翻 BIOS 也没用。所以如果你搜索之后一无所获先别急着下结论说“华硕垃圾”很可能是 PCH 或 CPU 对应 Root Port 不支持。4.2 工作站/服务器系列WS、Pro、Z 系列的部分型号的差异华硕的工作站主板比如 Pro WS X570-ACE、Pro WS W680-ACE 这些BIOS 结构比消费级板子更接近服务器风格也更可能出现 ACS 选项。常见的路径有几个Advanced→PCI Subsystem Settings这个在 WS 板子上几乎一定有而且菜单项比消费级多很多不要只看前几个要往下滚动到底。Advanced→PCIe Configuration这个页面在 WS 板上通常包含多个 PCIe 插槽的子页面每个子页里可能有独立的ACS或PCIe Access Control设置。实测在 Pro WS X570-ACE 上PCIe Slot x的 BIOS 设置里确实有 ACS 相关项但默认是隐藏的需要在页面里按某个键展开所有选项不同版本按键不同可以留意屏幕右下角的提示。Advanced→AMD CBSAMD 平台或Advanced→System Agent (SA) ConfigurationIntel 平台。AMD 平台的 CBS 菜单里有很多隐藏的系统级选项ACS 就藏在某个子菜单里Intel 平台的 SA 配置中也有 PCIe 相关的高级控制。工作站板子和消费级板子在 ACS 选项上的差异本质上是因为目标客户不同。工作站用户多数是拿来做专业软件和虚拟化的BIOS 开发时会更重视直通相关选项所以出现概率高、命名也更接近服务器规范。真遇到华硕 WS 板上也没有的情况记得先更新 BIOS 再找一遍。我遇到过好几块 Pro WS 板子出厂 BIOS 版本比较老ACS 选项完全消失升级到新版本之后同一个位置就多出了 ACS Enable。而且华硕 WS 板子的 BIOS 更新往往不止修 bug还会补全一些虚拟化相关特性。还有个小技巧华硕部分板子在Boot→Secure Boot相关的配置页里如果开启某些复杂设置会影响 PCIe 选项的显示。有些隐藏项只有在“专家模式”下才能看到。进高级模式之前确认当前在最完整的模式别用简化视图。5. BIOS 里真没有 ACS 时的替代方案与取舍5.1 硬件拓扑优先避免经过 Switch 或换插槽如果 BIOS 里确实翻不到 ACS先别急着打内核补丁。第一步要考虑的是硬件拓扑能不能调整。ACS 相关的粗分组问题本质上都出在“多个设备共享一个上游端口”这个结构上。如果你现在的设备是通过一张 PCIe Switch 转接卡出来的试着把它换到直连 CPU 的插槽或者换到 PCH 直连的插槽再跑一遍 IOMMU 分组脚本。很多时候问题直接消失。举个例子我帮一位老哥排查 PVE 直通问题他的两张 NVMe 盘插在同一个 PCIe 转 M.2 卡上四块盘全部挂在同一个 IOMMU group。后来把系统盘单独插到主板直连 CPU 的 M.2 插槽剩下的盘继续留在扩展卡上虚拟机的透传目标变成一张独立插槽上的 SATA 扩展卡分组直接完美拆分。这个方法虽然听起来很傻但真的是最稳定、最安全、最没有副作用的选择。ACS 补丁和 BIOS 开关都只能在软件层面改变内核的分组策略物理拓扑限制永远在那里。所以在动软件方案之前把下面的检查做完整主板上有几组直连 CPU 的 PCIe 插槽都是 x16 还是 x8你的设备能不能用直连插槽插槽物理尺寸是否匹配芯片组PCH/FCH提供的 PCIe 通道有哪些那些通道的 Root Port 是否支持 ACS当前这张卡插在哪个槽位上通过lspci -tv确认上游设备是什么。5.2 内核参数和系统层面的 ACS 绕过方案如果硬件拓扑没法调整那就只能在系统层想办法。社区最常用的方案是 Linux 内核的acs override参数补丁。这个补丁的原理是让内核忽略设备或 Switch 端口没有声明 ACS 能力这一事实强制把每个设备从这个端口后面拆成独立 IOMMU group。注意这里有个容易混淆的点acs override 并不是在 BIOS 里“开启 ACS”的替代品它只是让内核在分组时不考虑 ACS 硬件是否真的存在。也就是说它不会增强硬件隔离能力只是改变了软件的信任边界。常见的用法是给内核加这样的引导参数pcie_acs_overridedownstream或者更激进一点的pcie_acs_overridemultifunction这两种参数的含义分别是downstream对所有 downstream ports 启用 ACS override强制拆分所有挂在 Switch 或 Root Port 下游的设备multifunction对多功能设备启用 ACS override把同一设备的不同功能拆到不同分组两者一起用pcie_acs_overridedownstream,multifunction。在 GRUB 里配置的时候编辑/etc/default/grub找到GRUB_CMDLINE_LINUX_DEFAULT把参数加进去然后运行update-grub或者有些发行版用grub2-mkconfig -o /boot/grub2/grub.cfg重启之后再跑 IOMMU 分组脚本你会看到分组数量明显变多。这是目前绕过 BIOS 缺失 ACS 选项最常用的方案。但我必须把丑话说在前面acs override 补丁从安全角度讲是有代价的。它本质上是在告诉内核“不需要验证硬件隔离能力你就信我一次”。如果你的某个 PCIe 设备不可信或者系统里有多个租户共用物理设备这个方案会降低隔离强度。不少人都是这么用的我没有资格拦着但至少要说清楚生产环境要慎重。5.3 换主板之前先看 PCH 和 Root Port 数量还有一些情况无论你用什么方案都优化不了分组那就是硬件本身支持的 Root Port 数量太少或者 PCH 的 PCIe 通道数量不够。比如某些消费级 B 系列主板芯片组只提供有限数量的 PCIe Root Port所有 PCH 引出的设备可能共享有限几个端口ACS 能力又弱IOMMU 分组天然就是一大坨。这种时候与其在 BIOS 和内核参数上死磕不如先算清楚平台硬件账。Intel 平台看 CPU 的 PCIe Root Port 数量和 PCH 的 PCIe 通道数量AMD 平台看 CPU 通道和芯片组通道。如果你的需求是直通多张卡构建机器的时候就应该选工作站或服务器平台。我个人的建议是如果 ACS 是为了做正规虚拟化直通尤其是生产环境超微和华硕的 WS 系列是比消费级板子更合适的选择。这些板子的 BIOS 里 ACS 选项出现概率高很多IOMMU 分组天然更细体验完全不是一个层级。6. 实操验证与问题排查记录6.1 验证 IOMMU 分组是否真的按预期隔离不管你是通过 BIOS 开关还是内核参数处理完最后都要回到系统里验证结果。只看 lspci 信息不够最直观的方法是重新跑一遍 IOMMU 分组脚本确认你要直通的那张卡现在是否独占一个 group。以直通一张 Intel I210 网卡为例期望的结果是类似下面这样的输出IOMMU Group 17 01:00.0 Ethernet controller [0200]: Intel Corporation I210 Gigabit Network Connection [8086:1533]如果你看到同一 group 里还有其他设备就需要确认这些设备是否与目标卡存在物理从属关系。正常情况下一张标准 PCIe 网卡应该独占一个组如果它非要和别的东西绑在一起多半是它上游的 Root Port 或 Switch 没有正确触发 ACS。还有一种常见情况分组拆开了但直通虚拟机时仍然报Error: Device is busy。这可能是因为网卡的一部分功能比如管理网卡所用的端口仍然被宿主机驱动占用。对于 I350 这类多口网卡排查时需要把整个物理设备都释放干净。验证完软硬件状态之后最后一步是实际建一个测试虚拟机把设备挂载上去确认 guest 内的设备驱动能正常加载、队列能起来、数据通路没异常。这个步骤虽然耗时但省了之后生产环境出问题再回头排查的大麻烦。6.2 我踩过的几个坑与排查思路第一个坑是过分依赖补丁。内核参数打完重启分组确实变细了但运行一段时间后发现某些设备不稳定偶尔报 AER 错误。后来才想明白acs override 会让内核越过硬件隔离能力做分组但 PCIe 层面的访问控制错误还是会由硬件报告。如果你设备本身 DMA 行为有问题覆盖 ACS 检查只会推迟问题暴露不会消除问题。第二个坑是搞混 ACS 和 AER。Asynchronous Error Reporting 和 Access Control Services 在 BIOS 菜单里位置接近名字也都有点像。有些人看到 BIOS 里有PCIe AER就直接当 ACS 打开结果分组一点变化都没有。实际上这两个是完全不同的功能AER 管错误上报ACS 管访问隔离。看选项的时候务必看全名。第三个坑是超微板子的 BMC 占位设备。有些超微服务器板BMC 的虚拟网卡对应一个 PCIe 功能它和你实际想直通的其他设备共享 Root Port。你不把 BMC/KVM 相关功能在 BIOS 里关掉分组就永远拆不干净。这个坑在普通家用板子上遇不到但在超微板子上相当常见。第四个坑是插槽带宽拆分导致的分组变化。有些主板支持把 x16 拆成 x8x8 或者 x4x4但拆分之后设备分组逻辑会变化。我在华硕某些板上就碰到过同一张卡插在默认 x8 模式的槽位上分到一个组切换成拆分模式之后分组反而变粗了。M.2 转接卡尤其明显因为它本身可能带一个 Switch 或 PCIe bridge。6.3 排查速查表现象可能原因排查方向设备全部挤在一个 IOMMU group上游 Switch/Root Port 未启用 ACSBIOS 找 ACS 开关或使用内核 acs overrideBIOS 搜不到 ACS固件未暴露该选项或硬件不支持尝试 BIOS 搜索功能更换插槽升级 BIOS分组拆开了但直通报 busy设备被内核驱动占用或有子功能未释放lspci -k查看驱动绑定检查vfio-pci绑定状态直通后 guest 内设备频繁报错硬件本身不支持隔离或 acs override 掩盖了硬件缺陷回退方案改用直连 CPU 插槽超微板 BMC 干扰分组BMC 虚拟设备占用同一 Root PortBIOS 里关闭 BMC LAN 相关功能华硕板找不到 ACS 但分组很细板载固件默认启用了某种高级隔离直接验证直通效果不需要纠结开关7. 后续还能怎么扩展这个内容这个话题如果再往下挖其实还有很多值得展开的方向。比如 SR-IOV 网卡在 ACS 不可用平台上的表现PCIe 直通对 NUMA 拓扑的依赖以及 VFIO 在最新内核里对安全性、隔离能力的新要求。我建议先把这次讲的四个核心动作做一遍确认拓扑、翻 BIOS、补内核参数、验证分组。做完之后再根据你的业务需求去研究更深层的东西。
返回列表