将 Linux IOMMU API 与用户空间地址一起使用

Posted

技术标签:

【中文标题】将 Linux IOMMU API 与用户空间地址一起使用【英文标题】:Using the Linux IOMMU API with userspace addresses 【发布时间】:2016-10-31 10:37:15 【问题描述】:

我有一个 pci 设备驱动程序,当前使用 dma_map_page 将用户空间地址映射到 dma 地址。这工作正常,但我正在尝试将其移植到 iommu api 以获得使用组和域提供的一些好处。

当前代码:这很好用

ret = get_user_pages_fast(user_addr, one_page, flags, page);
dma_addr = dma_map_page(dev, off, size, *page, DMA_BIDIRECTIONAL);

IOMMU 代码:这不起作用

ret = get_user_pages_fast(...);
pfn = page_to_pfn(*page);
group = iommu_group_get(dev);
domain = iommu_domain_alloc(dev->bus);
iommu_attach_device(domain, dev);
iommu_attach_group(domain, group);
iommu_map(domain, iova, pfn << PAGE_SHIFT, size, IOMMU_READ|IOMMU_WRITE);

所有函数都成功返回,但是当我将 iova 传递给设备时,设备无法使用它。有没有人以前使用过 iommu 并且知道我的问题在哪里或者我可以在哪里查看?我无法在任何地方找到关于 Linux 的 iommu 实现的太多信息。

编辑: 我第一次错过了 dmesg 中的一些条目:

DEBUG: phys addr 0x7738de000
DEBUG: iova 0xdeadb000
DMAR: DRHD: handling fault status reg 2
DMAR: DMAR:[DMA Read] Request device [50:00.0] fault addr 1fdaee4000 
DMAR:[fault reason 06] PTE Read access is not set

【问题讨论】:

你的CPU和南桥型号是什么?你确定他们有 IOMMU 吗?是否为您的设备启用了 IOMMU(英特尔的 VT-d 可能仅对某些端口启用)? 设备在启动期间分配了一个 iommu 组。还有什么我需要检查以确保为设备启用 iommu 吗? 罗伯特,你的硬件是什么?启用drivers/iommu/iommu.c 文件的 pd_debug 怎么样?为什么不是PFN_PHYS,而是 CPU 是 Haswell Xeon,不确定南桥。你的意思是pr_debug?它已启用,我在 dmesg 中没有得到任何东西。而且我直到现在才知道 pfn_phys 您在 dmesg 中看到与 DMAR 相关的消息吗?您是否在内核命令行上传递了 intel_iommu=on? 【参考方案1】:

此类操作具有特权,因为它正在访问页表,或者可能是在任务结构中维护的数据结构。

请检查虚拟机管理程序如何执行此操作或虚拟机如何处理此类调用。可能有一些驱动程序接口通过管理程序从客户操作系统设置 IOMMU 分页单元。

Hypervisor 也以特权模式执行。

【讨论】:

以上是关于将 Linux IOMMU API 与用户空间地址一起使用的主要内容,如果未能解决你的问题,请参考以下文章

[架构之路-47]:目标系统 - 系统软件 - Linux OS硬件设备驱动 - CPU内存管理单元MMUDMA与IO内存管理单元IOMMU

[QNX Hypervisor 2.2用户手册]12.2 术语

[QNX Hypervisor 2.2用户手册]12.2 术语

Linux内存模型和Linux访问用户空间内存API详解

[转]iommu和vfio概念解构

随笔