求助:想知道一个 host 上有哪些设备支持 DMA 该怎么办啊...

2022-05-10 15:01:56 +08:00
 ins0mn1a

新手上路,希望得到一些指点!先谢谢各位大哥了

“设备支持 DMA”这句话,我从如下两个方面理解:

想知道以上理解是否有误?且也在探索该如何在一个 host 上以扫描的形式判断有哪些设备具有 DMA 能力...希望获取一些建议,或者能提供一些可以努力的方向!

2038 次点击
所在节点    Linux
7 条回复
ins0mn1a
2022-05-10 15:39:46 +08:00
补充一点更具体的信息:是在做移动端关于 DMA 的研究,所以设备初始化是基于设备树的。

通过临时的相关 kernel 源码阅读,目前我有如下认识:

认为设备树无法提供完整的 DMA 信息,部分设备树 dts 中不做 DMA 配置的节点,也会执行 dma 相关的 configure ,例如,在基于设备树的情况下,最终都是调用[of_dma_configure()]( https://elixir.bootlin.com/linux/v5.6.5/source/drivers/of/device.c#L75),该函数注释中说明,由于遗留问题,即便不在设备树中设置 dma 相关的信息,也会为其做一些默认的赋值;
且该函数的调用是由当前 dev 对应的 bus 决定的,即一个在设备树中没有设置 dma 相关选项的设备会因为其挂接的总线支持 DMA 而在 matching 阶段执行相关的 DMA 初始化,并被赋上默认值,而导致该设备在总线侧和驱动侧都是完成了对 DMA 支持的,那么此时这个设备是拥有 DMA 能力的吗?
yuguorui96
2022-05-10 23:58:15 +08:00
设备支持不支持 DMA 和驱动没有必然联系。

一个设备有 DMA 控制器,能朝系统总线上写 DMA 相关的消息就可以进行 DMA 了(假设我不关心会不会把系统写挂)。以 PIC 为例,DMA 的过程实际就是写 TLP 包的过程,然后就可以通过 PCI 的路由逻辑路由到 DIMM 里了,这个过程和任何驱动有关吗?
yuguorui96
2022-05-11 00:02:02 +08:00
说的更明白点,如果我是一个已经挂载在总线上的恶意设备,如果我不主动暴露 DMA 能力,没啥好方法探测。

如果你的假设是设备都是诚实的,倒是可以翻翻驱动,看看驱动分配时有没有用 DMA 相关的内存分配 API ,但是这个都只是启发式的。
ins0mn1a
2022-05-11 01:12:45 +08:00
@yuguorui96 谢谢你的回复!现阶段的想法也就只是看看 dma api 了...另外还想再探讨一下关于恶意设备的问题;
由这个恶意设备的例子展开去,现阶段对于类似的 DMA attack 的防护大多基于 IOMMU 机制,而一个设备与 IOMMU 进行绑定,即“使用 IOMMU”来限制 DMA 攻击的情景,kernel boot time 是在板上设备在与驱动进行绑定的 probe 阶段,为设备分配置 IOMMU 。据此我产生的理解就是,一个设备想接上 IOMMU 需要经过驱动绑定的 probe 阶段(?不一定对,源码是: https://elixir.bootlin.com/linux/v5.17.6/source/drivers/base/dd.c#L871
再说回你的例子,如果你说的恶意设备是一个热插拔的具有 DMA 能力的非板上的外部设备,成功挂载且无法匹配任何总线上的驱动,此时程序流不会走到 probe 分支,是否也就意味着该设备不会受到 IOMMU 的保护呢?
yuguorui96
2022-05-11 10:14:23 +08:00
@ins0mn1a 你这里 post 出来的代码我还没看,但是大体上的逻辑是:
1. firmware 需要在启动时默认启用 IOMMU remapping ,然后后续的 DMA 请求就被默认禁止了;
2. 后面 firmware/OS 就可以根据需求更新 IOMMU 的 second-level page table 以允许 /吊销设备的 DMA 访问能力。

是否也就意味着该设备不会受到 IOMMU 的保护呢?
====================================


这里的细节很多,可以参考: https://www.intel.com/content/dam/develop/external/us/en/documents/intel-whitepaper-using-iommu-for-dma-protection-in-uefi-820238.pdf
ins0mn1a
2022-05-11 15:09:37 +08:00
@yuguorui96 也就是说,在 IOMMU 被配置的 OS 上,普通的 DMA 请求会被禁止,只有使用 IOMMU 的 DMA 设备能够发起 DMA 访问是吗?非常感谢,会去读一下启动时关于 IOMMU 的配置代码以及阅读一下这篇文章的。
ins0mn1a
2022-05-11 15:25:44 +08:00
@yuguorui96 先介绍一篇 gp0 的文章: https://googleprojectzero.blogspot.com/2017/04/over-air-exploiting-broadcoms-wi-fi_4.html
其中一种 get root shell 的方式,是通过完全控制的 wifi SoC 使用 DMA 来完成攻击的,这个 wifi SoC 没有与 IOMMU 形成绑定,作者没有深究根本原因是主 SoC (骁龙 810 )没有硬件 IOMMU 还是当时的安卓系统没有默认启用 IOMMU ,又提到在该 wifi SoC 的 documentation 中,没有关于 iommu 的 dtbinding 相关的介绍;
查了下骁龙 810 ,其实是有 IOMMU 的,再结合设备树没有做 binding ,我就想当然的认为系统可能是支持 IOMMU 的,但是这个 DMA 设备由于缺少与 IOMMU 的绑定,而没有受到 IOMMU 的保护,这点逻辑在 kernel 中 dma api 的具体实现中也有体现,针对绑定了 iommu 的设备,会走一个 iommu 相关的 dma 分支,没有绑定则会走另一个分支。
因此我会去确认一下,这个案例中的系统版本究竟是否支持 IOMMU 。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/851980

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX