IOMMU简述-上篇

IOMMU的全称是Input/Output Memory Management Unit,即输入/输出内存管理单元,其主要功能链接DMA-capable I/O总线和系统内存。传统的内存管理单元MMU,是将CPU-visible的虚拟地址转换成物理地址,而IOMMU则是将Device-visible的虚拟地址转换成物理地址。例如:GARTGraphics Address RemappingTable)就是一种IOMMUPCIE的显卡就是利用GART,将GPU的虚拟地址转换成系统内存的物理地址。但是,需要注意一点,GART不支持保护模式,而现代的IOMMU是支持保护模式的。

1.IOMMU的基本功能

1.1 IOMMU能做什么?

  • 转译Device的Request;
  • Device必须授权访问系统地址空间,包括:页保护,每个Device都有各自的读/写权限;
  • 维护转译表的高速缓存器;

1.2 IOMMU不能做什么?

  • 不是MMU的替代品,CPU访问物理内存,依然使用MMU;
  • 不能支持直接请求Paged I/O,比如:1)Device和Driver无法处理任意的延迟;2)Device和Driver无法识别“I/O Page Fault”之类的错误;3)支持利用远程地址转译的方法间接地请求Page;

2. 系统拓扑结构


 通常情况下,IOMMU会被部署成HT(HyperTransport)或者PCI Bridge的一部分。在高端系统中,CPU和I/O Hub之间可能会有多个HT链接,此时就需要多个IOMMU。

3. IOMMU的优点

3.1虚拟化技术

  • Guest OS直接被分配到实际的Device;
  • 用户空间的应用程序可以直接访问Device;

  • 增强了安全性:1)增加了Device对地址空间的访问控制;2)创建I/O保护域;
  • 增强了可靠性:1)Device之间是独立,互不干扰;2) 保护系统内存不被不明的Device读/写;

  • 支持可信任的输入/输出:在Device和Driver之间创建了保护通道

  • 让传统32位PCI设备能够访问可寻址范围之外的系统内存区域,并且避免使用Bounce Buffer


### PCIe IOMMU 映射配置与理解 #### 背景介绍 I/O Memory Management Unit (IOMMU) 是一种硬件组件,用于管理设备访问内存的权限和地址转换。在 PCI Express (PCIe) 系统中,IOMMU 提供了虚拟化支持、安全性以及 DMA 地址重映射的功能。 Linux 内核提供了多种机制来管理和配置 IOMMU 的行为。以下是关于如何理解和配置 PCIe IOMMU 映射的相关信息: --- #### 配置 PCIe IOMMU 映射的方法 1. **设置固件节点** 在 Linux 中,`iommu_device_set_fwnode` 函数被用来为 IOMMU 设备分配固件节点(Firmware Node)。这是一个简单的赋值操作[^1]: ```c static inline void iommu_device_set_fwnode(struct iommu_device *iommu, struct fwnode_handle *fwnode) { iommu->fwnode = fwnode; } ``` 2. **启用 SR-IOV 功能** 对于支持 Single Root I/O Virtualization (SR-IOV) 的驱动程序,需要实现特定的接口函数 `sriov_configure` 来控制 VF(Virtual Function)的数量。例如,在 Intel Gigabit Ethernet 驱动中实现了如下逻辑[^2]: ```c static int igb_pci_sriov_configure(struct pci_dev *dev, int num_vfs) { #ifdef CONFIG_PCI_IOV if (num_vfs == 0) return igb_pci_disable_sriov(dev); else return igb_pci_enable_sriov(dev, num_vfs); #endif return 0; } ``` 这里的核心在于通过调用 `pci_enable_sriov()` 和 `pci_disable_sriov()` 来动态调整 VF 数量。 3. **创建 IOVA 到物理地址的映射** ARM 架构下的 LPAE(Large Physical Address Extension)模式下,IOMMU 使用 STE 表(Stream Table Entry)、CD 表(Context Descriptor)等结构完成地址翻译。其原理类似于传统页表的多级索引方式[^3]。具体实现在 `__arm_lpae_map` 函数中进行了封装。 4. **内核启动参数** 启用 IOMMU 可以通过传递适当的引导参数给内核。常见的选项包括: - `intel_iommu=on`: 开启 Intel VT-d 技术- `amd_iommu=on`: 开启 AMD-Vi 技术- `iommu.passthrough=1`: 设置直通模式,允许设备直接访问主机内存而不经过翻译。 5. **工具辅助调试** 使用命令行工具可以查看当前系统的 IOMMU 组成情况及其映射关系: ```bash dmesg | grep -i iommu ls /sys/kernel/iommu_groups/ cat /proc/cmdline ``` --- #### 示例代码片段 以下是一个简单的例子展示如何枚举所有的 IOMMU 组并打印相关信息: ```python import os def list_iommu_groups(): groups_path = "/sys/kernel/iommu_groups" if not os.path.exists(groups_path): print("No IOMMU groups found.") return for group_dir in os.listdir(groups_path): devices_path = os.path.join(groups_path, group_dir, "devices") try: with open(devices_path, 'r') as file: devices = file.read().strip() print(f"IOMMU Group {group_dir}: Devices={devices}") except Exception as e: print(f"Error reading group {group_dir}: {str(e)}") list_iommu_groups() ``` --- #### 总结 为了正确配置 PCIe IOMMU 映射,开发者需熟悉以下几个方面: - 如何初始化和关联 IOMMU 设备到对应的固件节点; - 实现 SR-IOV 接口以便灵活管理 VFs; - 创建有效的 IOVA 至物理地址映射规则; - 应用合适的内核参数激活所需特性; - 借助实用工具验证最终效果。 这些知识点共同构成了深入掌握 PCIe IOMMU 工作流程的基础。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值