1. 课程导入
各位同学,咱们今天正式开讲 SMMU。说实话,我第一次接触 SMMU 是在一个做虚拟化加速卡的 projects 里。当时系统老是莫名其妙地挂掉,排查了整整两周,最后发现是 DMA 访问越界,直接踩了操作系统的内存。嗯,从那以后,我就再也不敢轻视这个“躲在 PCIe 和内存之间的黑盒子”了。
1.1 什么是 SMMU?
SMMU,全称 System Memory Management Unit,系统内存管理单元。你把它理解成“给设备用的 MMU”就对了。
CPU 有 MMU,负责把虚拟地址翻译成物理地址,顺便做权限检查。那设备呢?设备发起 DMA 读写,用的是设备侧的地址(也叫 I/O 虚拟地址,IOVA)。如果没有 SMMU,设备直接拿 IOVA 去访问物理内存——这就像让一个陌生人直接进你家翻东西,太危险了。
SMMU 的作用,就是拦截设备的 DMA 请求,把 IOVA 翻译成物理地址,同时检查权限。说白了,它就是设备访问内存的“门卫”。
1.2 为什么需要 SMMU?
你可能会问:没有 SMMU 的年代,设备不也跑得好好的吗?
确实,早期嵌入式系统里,设备直接访问物理地址,简单粗暴。但到了现代 SoC,尤其是服务器和虚拟化场景,问题就来了:
- 安全问题:一个恶意的设备(或者被攻击的设备驱动)可以通过 DMA 读取整个物理内存,包括其他虚拟机的数据。
- 虚拟化困境:虚拟机里的设备驱动,它认为自己在访问连续的物理内存。但实际上,宿主机把物理内存分成了碎片。没有 SMMU,设备根本不知道这些碎片在哪。
- 地址空间限制:32 位设备只能访问 4GB 地址空间。有了 SMMU,你可以把 IOVA 映射到 64 位物理地址,轻松突破这个限制。
我在一个项目中遇到过这样的情况:一个 FPGA 加速卡,它内部的 DMA 引擎只支持 32 位地址。但服务器插了 256GB 内存。没有 SMMU,这卡就只能访问低 4GB,性能根本发挥不出来。加上 SMMU 之后,我们把 IOVA 映射到高地址区域,问题迎刃而解。
1.3 SMMU 在系统架构中的位置
我们来看一张典型的系统框图。这张图我画了很多遍,每次给新同事讲系统架构,我都会先画出它。
从这张图你可以看到:
- 设备发起 DMA:设备(比如网卡、GPU、FPGA)通过 PCIe 发起 DMA 读写,地址是 IOVA。
- 请求到达 SMMU:PCIe Root Complex 把请求转发给 SMMU。SMMU 查页表,把 IOVA 翻译成物理地址。
- 访问内存:翻译后的物理地址通过系统互连,最终到达内存控制器。
- CPU 路径独立:CPU 走自己的 MMU 和缓存,与 SMMU 路径并行。两者在互连层汇合。
1.4 SMMU 的核心能力一览
我把 SMMU 的主要能力整理成一个表格,方便你对照理解:
| 能力 | 说明 | 典型应用场景 |
|---|---|---|
| 地址翻译 | IOVA → PA,支持多级页表(2级/3级/4级) | 虚拟化、大内存设备 |
| 权限检查 | 读/写/执行权限,域隔离 | 多租户安全隔离 |
| 缓存 | TLB 缓存最近使用的翻译结果 | 降低翻译延迟 |
| 中断重映射 | 将设备 MSI/MSI-X 中断重映射到指定 CPU | 虚拟化中断投递 |
| PASID 支持 | 进程地址空间标识,让设备共享进程的虚拟地址空间 | SPDK、DPDK 等用户态驱动 |
| 安全与非安全域 | 支持 TrustZone 安全世界与非安全世界的隔离 | 安全支付、DRM 保护 |
1.5 小结
这一章我们搞清楚了 SMMU 的本质:它就是设备的 MMU。没有它,现代 SoC 的虚拟化、安全、大地址空间支持都无从谈起。
你记住三个关键点就行:
- SMMU 做 IOVA 到 PA 的翻译,同时检查权限。
- 它位于设备与内存之间,是 DMA 路径上的必经关卡。
- 它的页表缓存需要软件主动维护一致性,这是性能调优的重点。