LWN:UIO驱动的DMA地址!

关注了就能看到更多这么棒的文章哦~

DMA addresses for UIO

By Jonathan Corbet
April 22, 2025
Gemini-1.5-flash translation
https://lwn.net/Articles/1017449/

用户空间 I/O (UIO) 子系统最初由 Hans J. Koch 在 2007 年 添加到内核,用于 2.6.23 版本。它的(主要)目的是方便在用户空间编写驱动程序;为此,它提供了对用户空间代码通常无法触及的许多资源的访问。不过,缺少的一个部分是 DMA 地址。来自 Bastien Curutchet 的填补该空白的提案 遇到了阻力。

虽然 UIO 驱动程序主要驻留在用户空间,但它们仍然需要一个小的内核组件;它本质上是一小段胶水代码,可以探测设备并处理中断,并通知内核应该向用户空间提供哪些内存映射 I/O (MMIO) 区域。UIO 也暴露出它的年代久远,它有一种使 x86 I/O 端口可用的机制。一旦加载了该模块,用户空间驱动程序就可以打开相应的 /dev/uioX 设备,将内存区域映射到其地址空间中,使用该映射来编程设备,并从设备文件描述符中读取以等待中断。映射的 MMIO 区域通常是操作设备所需的全部。

请参阅这篇 2007 年的文章,了解当时 UIO 接口的概况以及围绕将其添加到内核的一些讨论。

UIO 驱动程序通常相对简单;随着设备复杂性的增加,完全在内核中驱动它的优势也随之增加。除其他事项外,UIO 驱动程序通常仅限于简单的编程 I/O,其中所有传输的数据都通过 CPU。但是,编程 I/O 传输的性能受到限制,因此即使是相对低端的设备现在也支持 DMA 传输。访问 MMIO 区域通常足以将 DMA 操作编程到设备中,但缺少一个小细节:要提供给设备的 I/O 缓冲区地址。

想出 DMA 地址并不像听起来那么容易。在用户空间中运行的驱动程序将看到其虚拟地址空间;它可以在那里创建一个缓冲区,但是驱动程序的该缓冲区的虚拟地址对于设备而言没有任何意义。即使在最简单的系统上,也需要将该地址转换为设备可以访问的物理地址;所涉及的用户空间页面也需要在传输期间锁定到内存中。在更复杂的系统上,“物理地址”将位于设备所在的总线的单独地址空间中,并且很可能通过 I/O 内存管理单元 (IOMMU) 进行转换,必须对其进行适当的编程。所有这些工作都无法从用户空间完成。

根据 Curutchet 的说法,有许多 UIO 驱动程序包含 hacks,以使用户空间驱动程序能够创建和导出 DMA 地址。已发布的补丁系列试图提供一种标准的、经过良好测试的机制,以相对安全的方式执行此任务。内核/确实/具有一些用于从用户空间管理 DMA 缓冲区的基础架构:dma-buf 层,最初创建该层是为了在设备之间共享 DMA 缓冲区。该层几乎可以完成 UIO 驱动程序所需的一切,但是它不会使用户空间可以使用其缓冲区的 DMA 地址。

Curutchet 的补丁集向 dma-buf 层添加了一个新的 ioctl() 操作,该操作可以为调用者提供 dma-buf 的 DMA 地址。该系列还添加了一个新的 dma-buf 堆模块,用于创建简单的、缓存一致的 DMA 缓冲区。使用此模块,用户空间驱动程序可以创建 DMA 缓冲区,但是它们无法访问大多数更复杂的 dma-buf 机制,包括其所有同步支持。

Christian König 反复要求使用此新功能的开源驱动程序。但是,正如 Thomas Petazzoni 指出的那样,任何其他 UIO 功能都从未要求过开源用户。对于新接口,开源消费者的存在在审查过程中可能会有所帮助,但是在这里添加该要求似乎有点晚了,因为以前从未提出过该要求。

Christoph Hellwig 表示,解决此问题的正确方法是使用 VFIO 和 IOMMUFD 子系统。他后来补充说,该提案“从根本上说是错误的且不安全的”,并且,如果他建议的方法不起作用,则唯一的选择是编写完整的内核驱动程序。Petazzoni 回答说,VFIO 和 IOMMUFD 不适用于此用例,并且指出,使 DMA 地址可用不会增加已经存在的安全隐患:

UIO 允许将 MMIO 寄存器重新映射到用户空间应用程序中,然后该应用程序可以对这些 MMIO 寄存器后面的 IP 块执行其想要的任何操作。如果此 IP 块支持 DMA,则已经意味着_今天_在当前 UIO 子系统(目前的状态)下,用户空间应用程序可以对 DMA 传输进行编程,以读取/写入内存中的任何位置。

他建议,为 DMA 缓冲区的管理创建一个干净的接口,可能会使 UIO 驱动程序比现在更安全。但是,Andrew Davis 没有被说服,他将 Petazzoni 的论点描述为:“UIO 是一个损坏的遗留混乱,因此让我们向其中添加更多损坏的东西,因为损坏 + 损坏 => 仍然损坏,因此没有造成任何危害”。他后来说,改进 UIO 接口“给人的印象是仍然应该如何编写驱动程序”,他说,正确的解决方案是编写内核驱动程序。

正如最后引用的内容所示,这里真正的争论点不是提供 DMA 地址是否会以某种方式使 UIO 更加危险;UIO 驱动程序已经可以破坏系统。问题是 UIO 在 2025 年是否应该存在。自从 UIO 合并以来,内核中对许多驱动程序类的支持已得到显着改善,并且一些开发人员无疑对其在开发专有驱动程序中的潜在用途感到不满。在这一点上,对某些人来说,UIO 提供的价值可能看起来是负面的。

当然,如果不破坏未知数量的现有驱动程序,就无法删除 UIO,但是可以将其冻结,目的是减少将来编写的使用 UIO 接口的驱动程序的数量。但是,拒绝新的 UIO 功能的真正结果似乎很可能是将这些功能推入到一组(可能更危险的)特定于驱动程序的 hacks 中,正如 DMA 地址显然已经在发生的那样。

全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。

欢迎分享、转载及基于现有协议再创作~

长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值