首页/新闻资讯/正文详情

Linux Kernel 如何使用 PCIe ACS

发布时间:2026/9/23 22:04:34 来源:云帆数科 栏目:资讯中心
Linux Kernel 如何使用 PCIe ACS
本文基于Linux kernel v6.18 源码重点说明 Linux 如何配置 PCIe ACS、ACS 和 IOMMU Group以及 P2P Direct 场景下 kernel 如何处理 ACS redirect。1. 概述1.1 问题背景PCIe ACS 解决的是“设备间 P2P TLP 是否必须回到上游路径”的问题。IOMMU 解决的是“DMA 地址如何翻译和保护”的问题。两者配合时ACS 决定设备之间是否存在绕过 IOMMU 的 P2P 路径IOMMU 据此决定哪些设备能被拆成独立的 IOMMU Group。PCI Core 在枚举 PCIe Topology 时发现并配置 ACS ControlIOMMU Core 不直接配置 ACS而是读取 ACS path 的隔离结果来决定 IOMMU Group 边界P2P Direct 路径也会读取 ACS redirect 状态如果 redirect 打开就不能按直接 bus address 路径处理。图中的 Policy input 表示内核默认策略和pci参数会共同影响 ACS Control 的最终值。在 Linux 中ACS 不是由 IOMMU driver 直接写寄存器完成的而是由 PCI Core 在 PCI 设备初始化时发现 ACS Extended Capability 并配置PCI_ACS_CTRL。IOMMU Core 后续通过pci_acs_path_enabled()查询路径隔离能力。1.2 代码范围主要代码路径如下模块文件作用PCI Coredrivers/pci/pci.cACS 能力发现、默认启用、内核参数配置、路径检查PCI Quirkdrivers/pci/quirks.c设备特定 ACS 能力判断和 workaroundIOMMU Coredrivers/iommu/iommu.cPCI 设备 IOMMU Group 构建P2PDMAdrivers/pci/p2pdma.cP2P 距离计算、ACS redirect 检查DMA-IOMMUdrivers/iommu/dma-iommu.cP2P page 在 IOMMU DMA API 中的映射处理1.3 关键路径Linux ACS 的关键路径可以简化为IOMMU 被检测到后调用pci_request_acs()要求 PCI Core 尽量启用 ACS。PCI 设备初始化时调用pci_acs_init()发现 ACS Capability 并配置 ACS Control。IOMMU 建组时调用pci_device_group()用pci_acs_path_enabled()判断 P2P 隔离边界。P2PDMA 选择 Direct 路径时调用pci_p2pdma_distance_many()检查路径上是否存在 ACS redirect。2. ACS 初始化Linux 中 ACS 的最终配置由三类输入共同决定IOMMU 是否请求 ACS、设备或平台 quirk、管理员通过pci指定的内核参数。2.1 使能来源ACS 使能的入口不是某个单独的 IOMMU driver 写 ACS 寄存器而是 IOMMU 检测路径先调用pci_request_acs()设置 PCI Core 的全局变量pci_acs_enable。之后每个 PCI 设备初始化时pci_enable_acs()根据这个全局请求决定是否应用 kernel 默认 ACS 策略。需要注意的是pci_acs_enable只是“请求启用 ACS”的软件开关真正能不能启用还取决于设备是否有标准 ACS Capability或者是否存在设备特定 quirk。2.2 默认策略ACS 默认策略由pci_std_enable_acs()决定。Linux 在标准 ACS Capability 存在且系统请求启用 ACS 时会在PCI_ACS_CTRL中尝试打开PCI_ACS_SVSource ValidationPCI_ACS_RRP2P Request RedirectPCI_ACS_CRP2P Completion RedirectPCI_ACS_UFUpstream ForwardingPCI_ACS_TBTranslation Blocking仅在 ATS disabled、external facing、untrusted 设备上启用这里的目标是优先保证 DMA 隔离P2P Request/Completion 被 redirect 到上游路径IOMMU 才有机会参与地址翻译和权限检查。2.3 Quirk 处理drivers/pci/quirks.c中有两类 ACS quirkpci_dev_specific_acs_enabled()设备没有标准 ACS Capability或者标准能力不足时用设备特定知识判断它是否具备等价隔离能力。pci_dev_specific_enable_acs()对部分平台写厂商寄存器启用等价 ACS 行为。典型例子是 Intel PCH Root Port。部分设备通过 LPC RCBA、UPDCR、MPC 等寄存器禁用 peer decode 或启用 requester ID 检查从而提供SV/RR/CR/UF等价能力。因此quirk 有两个作用一是让没有标准 ACS Capability 的硬件表达“等价隔离能力”二是在初始化阶段通过厂商寄存器补上标准 ACS Control 无法覆盖的控制。2.4 内核参数Linux 主线支持两个直接影响 ACS 控制位的pci参数参数作用风险pcidisable_acs_redirpci_dev[;...]强制关闭匹配设备上的RR/CR/EC允许 P2P traffic 不被强制上游转发会降低设备间隔离可能让更多设备进入同一个 IOMMU Grouppciconfig_acsflagspci_dev[;...]按 bit 配置 ACS flags0表示关闭1表示开启x表示保持不变管理员需要理解拓扑和安全影响config_acs的 bit 定义来自Documentation/admin-guide/kernel-parameters.txtbitACS 控制位0Source Validation1Translation Blocking2P2P Request Redirect3P2P Completion Redirect4Upstream Forwarding5P2P Egress Control6Direct Translated P2P这两个参数是在pci_setup()中解析的但真正应用发生在pci_enable_acs()里。disable_acs_redir会先清除RR/CR/EC然后config_acs再按管理员指定 bit 覆盖 ACS Control所以最终结果以最后写入PCI_ACS_CTRL的值为准。2.5 初始化流程PCI Core 的 ACS 初始化入口是pci_acs_init()。pci_acs_init()会把 ACS Extended Capability 的 offset 保存在dev-acs_cap。即使设备没有标准 ACS CapabilityLinux 仍会调用pci_enable_acs()因为部分 Root Port 可能通过 quirk 实现等价 ACS 行为。更完整的初始化流程如下IOMMU 检测路径调用pci_request_acs()设置全局pci_acs_enable表示后续 PCI 设备初始化时应尽量启用 ACS 默认隔离策略。PCI 设备初始化进入pci_acs_init()先通过pci_find_ext_capability()查找标准 ACS Extended Capability并把 offset 保存到dev-acs_cap。pci_acs_init()继续调用pci_enable_acs()这是 ACS Control 的主要配置入口。pci_enable_acs()先调用pci_dev_specific_enable_acs()让设备特定 quirk 有机会通过厂商寄存器完成等价 ACS 配置。如果 quirk 没有接管且设备存在标准 ACS CapabilityPCI Core 读取PCI_ACS_CAP和当前PCI_ACS_CTRL并保存 firmware 原始配置。默认策略由pci_std_enable_acs()应用通常会尝试设置SV/RR/CR/UF并在条件满足时设置TB。管理员参数随后生效pcidisable_acs_redir可清除RR/CR/ECpciconfig_acs可按 bit 覆盖指定 ACS 控制位。最终配置通过pci_write_config_word()写回PCI_ACS_CTRL后续 IOMMU Group 和 P2P 判断会读取这个有效 ACS 状态。3. ACS 与 IOMMU3.1 隔离边界IOMMU 只能保护经过 IOMMU 的 DMA。如果两个 PCIe 设备可以通过 Switch 直接 P2P不经过 Root Complex/IOMMU那么 IOMMU 页表无法阻止这种访问。ACS 的意义就是把这种 P2P 路径 redirect 到上游或者报告 violation从而让 IOMMU Group 的隔离假设成立。在 Linux 中IOMMU Group 是隔离粒度。能互相绕过 IOMMU 的设备必须在同一个 group 中不能单独分配给不同安全域。3.2 IOMMU GroupPCI 设备的 group 构建逻辑在drivers/iommu/iommu.c::pci_device_group()。其中核心判断是REQ_ACS_FLAGS PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UFpci_device_group()从设备向上遍历 PCI 层级先处理 DMA alias。如果设备存在上游 DMA alias需要使用 alias 所在的最小 IOMMU 粒度。从该位置继续向上查找直到遇到满足REQ_ACS_FLAGS的 ACS 隔离路径。如果路径上缺少 ACS 隔离能力就继续向上合并到桥或上游设备所在的 group。如果没有找到共享 group才新建一个 IOMMU Group。3.3 DMA 重映射IOMMU Group 建好后IOMMU Core 为 group 分配 default domain。普通 DMA API 最终会使用这个 domain 完成 IOVA 分配和 IOMMU 映射。关键点是ACS 不做地址翻译IOMMU 也不做 PCIe 路由控制。ACS 负责保证不可信 P2P 不绕开上游路径IOMMU 负责对经过自己的 DMA 请求做地址翻译和权限控制。3.4 VFIO 直通VFIO 依赖 IOMMU Group 作为用户态直通的安全边界。vfio获取设备 group 后会通过 IOMMU API 管理 DMA ownership 和 domain attach。如果 ACS 不足导致多个设备处于同一个 group那么这些设备必须一起作为安全边界看待。用户态不能只安全地直通其中一个设备因为同组设备可能通过 P2P 或 DMA alias 互相影响。3.5 ACS 缺失当某段 PCIe 路径缺少 Linux 需要的SV/RR/CR/UF时pci_acs_path_enabled()返回 false。IOMMU Core 会把隔离边界继续向上扩大表现为更多设备被放入同一个 IOMMU Group。4. P2P Direct4.1 P2PDMA 模型Linux P2PDMA 把参与方分为角色含义Provider提供 P2P memory例如 PCI BAR 中的一段内存Client发起 DMA 到 P2P memory 的设备Orchestrator选择 provider/client 并组织数据路径的驱动Provider 通过pci_p2pdma_add_resource()注册 P2P memory。Client 仍然使用普通dma_map_sg()P2PDMA 和 DMA-IOMMU 层会根据 page 类型选择合适映射方式。4.2 距离计算P2P Direct 距离计算入口是pci_p2pdma_distance_many()。它对每个 client 调用calc_map_type_and_dist()从 provider 和 client 各自向上找公共上游桥。统计路径距离。检查路径上的桥是否设置 ACS redirect。根据结果返回PCI_P2PDMA_MAP_BUS_ADDR、PCI_P2PDMA_MAP_THRU_HOST_BRIDGE或PCI_P2PDMA_MAP_NOT_SUPPORTED。pci_p2pdma_map_type表示 P2PDMA page 最终应该按哪种 DMA 地址路径处理定义在include/linux/pci-p2pdma.henumpci_p2pdma_map_type{PCI_P2PDMA_MAP_UNKNOWN0,PCI_P2PDMA_MAP_NONE,PCI_P2PDMA_MAP_NOT_SUPPORTED,PCI_P2PDMA_MAP_BUS_ADDR,PCI_P2PDMA_MAP_THRU_HOST_BRIDGE,};枚举值含义PCI_P2PDMA_MAP_UNKNOWN内部初始状态表示还没有计算 map type正常 API 不应返回给调用者PCI_P2PDMA_MAP_NONE当前 page 不是 PCI P2PDMA page后续按普通 DMA page 处理PCI_P2PDMA_MAP_NOT_SUPPORTEDP2P 路径不可用或者必须经过不在 allowlist 中的 host bridgeDMA 映射应返回错误PCI_P2PDMA_MAP_BUS_ADDRprovider 和 client 可通过 PCI Switch 直接通信不经过 host bridgeDMA engine 使用 PCI bus address是真正的 P2P DirectPCI_P2PDMA_MAP_THRU_HOST_BRIDGEprovider 和 client 可以通信但路径经过 allowlist 中的 host bridge使用普通物理地址或 IOVA 映射不是 Direct P2P在 DMA-IOMMU 路径中PCI_P2PDMA_MAP_BUS_ADDR会把 scatterlist segment 标记成 bus addressiommu_map_sg()跳过该 segmentPCI_P2PDMA_MAP_THRU_HOST_BRIDGE和PCI_P2PDMA_MAP_NONE则继续走普通 IOVA 映射流程。4.3 ACS 影响calc_map_type_and_dist()中的关键判断是pci_bridge_has_acs_redir()。如果路径上任何桥打开了 ACS redirectLinux 就认为 provider 和 client 之间的 traffic 会被强制走 host bridge而不是 Direct P2P。因此没有 ACS redirect可以返回PCI_P2PDMA_MAP_BUS_ADDRDMA engine 使用 PCI bus address形成 Direct P2P。有 ACS redirect返回PCI_P2PDMA_MAP_THRU_HOST_BRIDGE或PCI_P2PDMA_MAP_NOT_SUPPORTED取决于 host bridge 是否可用或在 allowlist 中。verbose 模式下kernel 会打印提示建议使用pcidisable_acs_redirpath关闭该路径上的 redirect。驱动不能直接调用一个通用的pci_disable_acs_redir()来关闭 ACS redirect。Linux 中没有导出的此类 PCI Driver APIdisable_acs_redir是 PCI Core 解析的内核命令行参数最终在pci_enable_acs()中通过__pci_config_acs()清除匹配设备的RR/CR/EC。设备特定的pci_dev_specific_disable_acs_redir()也属于 PCI Core 内部 quirk 路径不是普通驱动可直接依赖的接口。因此驱动侧通常只通过pci_p2pdma_distance_many()、pci_p2pdma_map_type()等 P2PDMA 路径判断是否可 Direct P2P如果 ACS redirect 阻断了 Direct P2P只能回退到 host bridge 路径或失败并由管理员通过pcidisable_acs_redirpath这类参数承担关闭隔离的决策。P2PDMA 调用流程如下4.4 Direct 条件P2P Direct 成立时通常需要满足provider 和 client 都能归约到 PCI 设备。两者在同一可路由层级内或 host bridge 支持对应路径。路径上没有会强制 redirect 的 ACS 控制位。provider 的 P2P resource 已注册并可用于 DMA。这也是为什么 ACS 和 P2P Direct 存在天然冲突安全隔离希望打开RR/CRDirect P2P 性能路径希望关闭 redirect。4.5 回退路径DMA-IOMMU 映射时会调用pci_p2pdma_state()PCI_P2PDMA_MAP_BUS_ADDR把 segment 标记为 bus addressiommu_map_sg()跳过该 segmentDMA 地址来自pci_p2pdma_bus_addr_map()。PCI_P2PDMA_MAP_THRU_HOST_BRIDGE按普通 IOVA 流程映射。PCI_P2PDMA_MAP_NOT_SUPPORTED返回错误。PCI_P2PDMA_MAP_NONE不是 P2P page走普通 DMA 映射。所以P2P Direct 不是绕过整个 DMA API而是在 DMA API 内部根据 P2P map type 选择 bus address 或普通 IOVA。5. 典型流程5.1 设备枚举PCI 枚举过程中设备 capability 被解析pci_acs_init()保存dev-acs_cap并尝试配置 ACS。这个阶段决定硬件 ACS Control 的初始状态。5.2 ACS 启用如果系统检测到 IOMMU相关初始化路径会调用pci_request_acs()。之后 PCI Core 按默认策略启用 ACS 隔离位并叠加设备 quirk 和管理员参数。5.3 IOMMU 建组IOMMU driver probe 设备时通过ops-device_group()获取 group。对 PCI 设备常见路径会走pci_device_group()并用pci_acs_path_enabled()判断从设备到上游的隔离边界。如果 ACS path 满足SV/RR/CR/UF设备可以在更细粒度上分组如果不满足group 会向上合并。5.4 VFIO 使用VFIO 只信任 IOMMU Group而不是单个 PCI Function。用户态直通时group 内所有设备都属于同一个隔离单元。ACS 缺失或被关闭 redirect 可能导致 group 变大这是安全边界变化不只是显示上的变化。5.5 P2P 判定P2PDMA 不会为了 Direct 自动关闭 ACS redirect。它会检测路径发现 redirect 后不能作为 Direct bus address 路径使用。在 verbose 模式打印pcidisable_acs_redir...建议。由管理员决定是否牺牲隔离来换取 Direct P2P。6. 总结6.1 核心关系ACS 与 IOMMU 的关系可以概括为ACS 保证 P2P traffic 不绕过上游路径。IOMMU 对经过自身的 DMA 做地址翻译和权限控制。IOMMU Group 使用 ACS 判断设备之间是否可被安全拆分。6.2 配置原则默认配置偏向隔离Linux 在 IOMMU 存在时会请求启用 ACS并打开SV/RR/CR/UF等关键位。管理员可以用config_acs或disable_acs_redir覆盖配置但这会改变安全边界。6.3 注意点disable_acs_redir有助于 P2P Direct但会降低隔离。config_acs可以精细控制 ACS bit但错误配置可能导致 IOMMU Group 变化。Linux 的 P2PDMA 只检测和提示不自动为 Direct P2P 关闭 redirect。7. 参考资料Linux kernel V6.18 Source Codedrivers/pci/pci.cpci_request_acs()、pci_enable_acs()、pci_acs_enabled()、pci_acs_path_enabled()、pci_acs_init()drivers/pci/quirks.cpci_dev_specific_acs_enabled()、pci_dev_specific_enable_acs()、Intel PCH ACS workarounddrivers/iommu/iommu.cpci_device_group()、REQ_ACS_FLAGS、IOMMU default domain 和 DMA ownershipdrivers/pci/p2pdma.cpci_p2pdma_distance_many()、calc_map_type_and_dist()、pci_bridge_has_acs_redir()drivers/iommu/dma-iommu.cP2PDMA page 在dma_map_sg()路径中的处理Documentation/admin-guide/kernel-parameters.txtpcidisable_acs_redir、pciconfig_acsDocumentation/driver-api/pci/p2pdma.rstLinux P2PDMA provider/client/orchestrator 模型

相关推荐

SSTImap实战指南:自动化检测与利用服务器端模板注入漏洞
SSTImap实战指南:自动化检测与利用服务器端模板注入漏洞

1. 项目概述:为什么我们需要SSTImap?在Web应用安全测试的日常工作中,我经常遇到一种情况:面对一个可能存在模板注入的端点,手动构造Payload去探测、验证、利用,整个过程繁琐且容易遗漏。尤其是在时间紧迫的… · 2026/9/23 22:04:30

新手开抖店需要全部工具功能吗?从AI选品到一键下单 自动拍单 自动售后+违规检测优先掌握核心功能即可
新手开抖店需要全部工具功能吗?从AI选品到一键下单 自动拍单 自动售后+违规检测优先掌握核心功能即可

抖店工具完整指南:创业副业小白只需要掌握这些功能,少花钱不踩坑 很多零基础新手、上班族副业创业者、宝妈想做抖店,一开店就被后台繁杂功能、五花八门第三方工具绕晕,要么盲目开通全部功能浪费时间,要么一次性采购多… · 2026/9/20 7:13:37

Android随笔-Launcher是什么?
Android随笔-Launcher是什么?

Launcher 是 Android 系统中的桌面应用(Home Screen App),是用户与手机交互的第一界面。 一、Launcher 的本质定位 1.1 它就是一个普通应用 属性 说明 进程类型 普通 Android 应用进程(非系统进程) UID 与普通应用一样,有自己的 Linux UID 沙箱 运行在独立的 Dalvik/AR… · 2026/9/19 5:31:50

制造业数字化转型案例集:16行业32案例,从云化到数据驱动
制造业数字化转型案例集:16行业32案例,从云化到数据驱动

简介:阿里云研究中心发布的《制造业数字化转型案例集》PDF,面向制造业企业管理者、数字化转型负责人及行业研究人员,系统梳理了制造业数字化转型的路径与最佳实践。案例集涵盖IT基础设施云化、数字工厂、区域工业互联网平台、C2M模式、工业智… · 2026/9/23 22:04:32

企业AI智能体测评:提升效率与决策精度的关键
企业AI智能体测评:提升效率与决策精度的关键

1. 项目概述:企业AI智能体测评的价值与挑战去年我参与了一个制造业客户的数字化转型项目,他们的IT主管给我看了一份令人震惊的数据:公司内部每天有超过37%的员工时间消耗在重复性流程审批、跨部门数据核对和基础文档处理上。这正是当下企业普… · 2026/9/23 22:04:32

RK3576-Android15-实现开机脚本静默安装功能
RK3576-Android15-实现开机脚本静默安装功能

RK3576-Android15-实现开机脚本静默安装功能 文章目录前言一、涉及到知识点二、参考资料三、修改文件四、实现方案1、拷贝apk 到指定目录/system/preloadapp 下配置系统编译环境(框架)-便于管理-确认 fise_preloadapp 的目录结构创建 fise_preloadapp/Android.mk创建 fise_prel… · 2026/9/23 22:04:32

大模型算法入门:从数学基础到中文处理实战
大模型算法入门:从数学基础到中文处理实战

1. 大模型算法入门全景解读2024年的大模型技术发展已经进入深水区,各类开源模型和商业应用呈现爆发式增长。作为中文社区的学习者,我们正面临一个关键转折点——大模型技术从实验室走向产业化的过程中,产生了大量需要本土化解决的实际问题。我… · 2026/9/23 22:04:32

网络鱼雷协同作战仿真:分布式交互平台选型与联邦架构落地实践
网络鱼雷协同作战仿真:分布式交互平台选型与联邦架构落地实践

简介:一份以分布式交互仿真平台为基础的学术论文PDF,聚焦网络鱼雷协同作战仿真系统,面向军事仿真、分布式开发及水下作战研究人员。论文从网络鱼雷的三种工作状态切入,分析了平台内待命、水面悬浮未入网与组网内巡航等场景的信息交… · 2026/9/23 22:04:32

C++实现三国杀核心规则引擎:零拷贝、状态机与类型安全设计
C++实现三国杀核心规则引擎:零拷贝、状态机与类型安全设计

简介:这是一份基于C实现的轻量级纸牌游戏《三国杀》完整开发资源,面向C初学者与课程设计实践者,聚焦面向过程与面向对象编程训练、基础数据结构应用及命令行交互系统开发。资源包含1个核心源码文件(game.cpp)与1份配套… · 2026/9/23 22:04:26

3招搞定手机怎么下载微信面试难题实战项目解析
3招搞定手机怎么下载微信面试难题实战项目解析

3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03

你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型

你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29

Win7无线热点配置工具源码解析:解决API失效的3个实战技巧
Win7无线热点配置工具源码解析:解决API失效的3个实战技巧

Win7无线热点配置工具源码解析:解决API失效的3个实战技巧 Win7无线热点配置工具在Win10/11上跑不动?不是你的问题,是版本升级后 API 全变了。很多老项目里的 netsh wlan… · 2026/9/23 0:00:36

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码