V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
ins0mn1a
V2EX  ›  Linux

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

  •  
  •   ins0mn1a · 2022-05-10 15:01:56 +08:00 · 2025 次点击
    这是一个创建于 923 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

    • 硬件层面是否支持 DMA ,例如设备有没有 DMA controller ,或者挂接的总线是什么之类的;
    • 软件层面设备 match 的驱动是否有做 DMA 相关的 configure ,即调用对应 bus_type->dma_configure();

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

    7 条回复    2022-05-11 15:25:44 +08:00
    ins0mn1a
        1
    ins0mn1a  
    OP
       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
        2
    yuguorui96  
       2022-05-10 23:58:15 +08:00
    设备支持不支持 DMA 和驱动没有必然联系。

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

    如果你的假设是设备都是诚实的,倒是可以翻翻驱动,看看驱动分配时有没有用 DMA 相关的内存分配 API ,但是这个都只是启发式的。
    ins0mn1a
        4
    ins0mn1a  
    OP
       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
        5
    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
        6
    ins0mn1a  
    OP
       2022-05-11 15:09:37 +08:00
    @yuguorui96 也就是说,在 IOMMU 被配置的 OS 上,普通的 DMA 请求会被禁止,只有使用 IOMMU 的 DMA 设备能够发起 DMA 访问是吗?非常感谢,会去读一下启动时关于 IOMMU 的配置代码以及阅读一下这篇文章的。
    ins0mn1a
        7
    ins0mn1a  
    OP
       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 。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3892 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 10:25 · PVG 18:25 · LAX 02:25 · JFK 05:25
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.