2. IOMMU/SMMU 概述:定义、功能对比与系统内存管理角色
在 DMA 驱动开发中,IOMMU(I/O Memory Management Unit)与 SMMU(System Memory Management Unit)是保障设备内存访问安全、实现地址空间隔离与虚拟化的核心硬件单元。本章从定义出发,对比两者功能差异,并阐明它们在系统内存管理中的关键角色。
2.1 IOMMU 与 SMMU 的定义
IOMMU 最初源于 x86 平台(Intel VT-d / AMD-Vi),用于将支持 DMA 的外设(如网卡、GPU、NVMe 控制器)的 I/O 地址空间映射到系统物理内存。它提供设备视角的“虚拟地址”到物理地址的转换,并实施访问权限检查。
SMMU 是 ARM 架构下的 IOMMU 实现(ARM MMU-600/700 系列),功能与 IOMMU 类似,但深度集成于 ARM 系统总线(ACE/CHI)中,支持更复杂的共享虚拟内存(SVM)和多级页表。
核心要点:IOMMU 是通用术语,SMMU 是 ARM 生态下的具体实现。在嵌入式 ARM Linux 驱动开发中,两者常被混用,但配置接口(如 Linux 内核的 IOMMU API)是统一的。
关键定义速查:
- IOMMU:I/O 内存管理单元,为 DMA 设备提供地址翻译与保护。
- SMMU:系统内存管理单元,ARM 架构下的 IOMMU,支持 Stage-1/Stage-2 转换。
- DMA:直接内存访问,设备绕过 CPU 直接读写内存。
- IPA:中间物理地址,SMMU Stage-2 转换后的地址。
2.2 功能对比:IOMMU vs SMMU
下表从架构、转换能力、虚拟化支持、页表格式等维度对比 IOMMU 与 SMMU 的核心差异:
| 对比维度 | IOMMU(x86 VT-d/AMD-Vi) | SMMU(ARM MMU-600/700) |
|---|---|---|
| 架构平台 | x86(Intel/AMD) | ARM(Cortex-A/R 系列) |
| 地址转换级数 | 单级(GPA→HPA)或两级(GVA→GPA→HPA) | 两级(Stage-1: VA→IPA, Stage-2: IPA→PA) |
| 页表格式 | Intel VT-d 上下文表 + 根表 | ARM 长描述符(LPAE)/ 短描述符 |
| 虚拟化支持 | 通过 VT-d 的 DMA 重映射(DMAR) | 原生支持 Stage-2 转换,适配 KVM/虚拟化 |
| 共享虚拟内存(SVM) | 需 PASID 支持(PCIe ATS/PRI) | 原生支持 SVM,通过 PCIe ATS/PRI 或 AMBA CHI |
| 中断重映射 | 支持(Intel VT-d Interrupt Remapping) | 通过 GICv3 ITS 实现 |
| 性能隔离 | 基于 PCIe 总线号/设备号 | 基于 StreamID/SubstreamID |
开发注意:在 ARM 平台上编写 DMA 驱动时,必须区分 SMMU 的 StreamID(标识主设备)和 SubstreamID(标识进程/VM)。错误配置会导致设备无法访问内存或触发 SMMU 同步异常(Sync Fault)。
2.3 在系统内存管理中的角色
IOMMU/SMMU 在系统内存管理中扮演三个核心角色:地址翻译、访问保护、虚拟化支持。下图展示了 SMMU 在 ARM SoC 中的典型位置与数据流:
2.4 核心角色详解
2.4.1 地址翻译与隔离
IOMMU/SMMU 为每个 DMA 设备维护独立的地址空间。设备看到的“设备虚拟地址”(DVA)经过 SMMU 转换为物理地址(PA)。这种隔离机制确保:
- 设备无法访问未映射的内存区域(如内核关键数据结构、其他进程的页面)。
- 支持非连续物理内存的 DMA:通过页表将连续的 IOVA 映射到分散的物理页框。
- 热插拔与动态映射:驱动可在运行时动态分配/释放 DMA 缓冲区,无需固定物理内存。
2.4.2 访问权限控制
SMMU 的每个 StreamID 关联的页表条目包含读写权限位(AP/XN 等)。典型权限模型如下:
| 权限位 | 含义 | 典型用途 |
|---|---|---|
| AP[2:1] | 数据访问权限(EL0/EL1 读写) | 限制用户态驱动直接访问 DMA 缓冲区 |
| XN | 禁止执行 | 防止设备将 DMA 缓冲区当作代码执行 |
| PXN | 特权级禁止执行 | 防止内核态利用设备缓冲区提权 |
| SH | 可共享属性(非共享/内部共享/外部共享) | 控制缓存一致性协议行为 |
2.4.3 虚拟化支持
在虚拟化场景中,SMMU 的 Stage-2 转换将客户机物理地址(IPA)映射到宿主机物理地址(PA)。这使得:
- 直通设备(PCIe Passthrough):虚拟机直接控制物理设备,SMMU 保证设备 DMA 不会污染其他 VM 或宿主机内存。
- 嵌套虚拟化:支持多级 SMMU 转换,适配 KVM 的嵌套页表(NPT/EPT)。
- 共享虚拟内存(SVM):设备与 CPU 共享同一页表,实现零拷贝数据交换。
实战要点:在编写支持虚拟化的 DMA 驱动时,必须通过 Linux 内核的
iommu_domain_alloc() 分配 IOMMU 域,并调用 iommu_map() 建立 Stage-1 映射。对于直通设备,QEMU/KVM 会通过 VFIO 框架自动配置 Stage-2 转换。
2.5 IOMMU/SMMU 在 DMA 驱动中的典型工作流
以下流程图展示了一个标准 DMA 传输中 IOMMU/SMMU 的参与步骤:
2.6 本章小结
- IOMMU/SMMU 是 DMA 驱动开发中不可绕过的硬件单元,提供地址翻译、隔离与保护。
- SMMU 是 ARM 生态下的 IOMMU 实现,支持两级转换(Stage-1/Stage-2),适配虚拟化与 SVM。
- 在系统内存管理中,SMMU 确保设备 DMA 操作安全、高效,并支持非连续物理内存与动态映射。
- 驱动开发者需掌握
iommu_map()/iommu_unmap()等内核 API,并理解 StreamID/SubstreamID 的配置规则。