1. SMMU 基础概念:什么是 SMMU?为什么需要 SMMU?SMMU 与 MMU 的区别
各位同学好,我是你们的讲师。咱们这门课叫《SMMU 多级缓存与固件配置调试实战》,第一讲,先把地基打牢。说白了,SMMU 这玩意儿,你要是没搞懂它到底解决什么问题,后面看代码、调 bug 就会一头雾水。
我刚开始接触 SMMU 的时候,也觉得它就是 MMU 的“马甲”。后来被一个 DMA 踩内存的 bug 折磨了三天,才真正明白——它俩压根不是一回事。今天咱们就把这个事儿彻底说清楚。
1.1 什么是 SMMU?
SMMU,全称 System Memory Management Unit,系统内存管理单元。你可以把它理解成:专门给“设备”用的 MMU。
CPU 有 MMU,管理进程的虚拟地址。那 DMA、GPU、网卡这些设备呢?它们直接访问物理内存,没有虚拟化保护。SMMU 就是给这些设备加的一道“虚拟地址翻译 + 权限检查”的关卡。
一句话总结:SMMU 让设备也能用虚拟地址访问内存,同时提供隔离和保护。
我习惯把 SMMU 比作“设备界的门卫”。CPU 那边的门卫是 MMU,管进程;SMMU 这个门卫,管的是所有想闯进内存的外设。
1.2 为什么需要 SMMU?
你可能会问:没有 SMMU 的时候,设备不也跑得好好的吗?嗯,那是你没见过“裸奔”的后果。
咱们看几个场景:
- 场景一:DMA 写飞了 —— 一个 buggy 的驱动程序,让 DMA 往错误地址写数据,直接把内核踩死。没有 SMMU,这就是“物理内存裸奔”,谁都能写。
- 场景二:虚拟化 —— 宿主机上跑多个虚拟机,每个 VM 有自己的物理地址空间。但设备 DMA 用的是“机器物理地址”,如果没有 SMMU 做二次翻译,设备根本不知道数据该往哪个 VM 送。
- 场景三:安全隔离 —— 安全世界和普通世界共享内存?没有 SMMU 做访问控制,恶意设备可以直接偷读安全内存。
我的经验:有一次调试一个 PCIe 网卡驱动,发现 DMA 缓冲区总是被莫名其妙地覆盖。查了三天,最后发现是 SMMU 配置没开,设备直接写到了物理地址冲突的区域。开了 SMMU 并正确配置 stream ID 映射后,问题立刻消失。从那以后,我所有涉及 DMA 的项目,第一件事就是检查 SMMU 有没有使能。
所以,SMMU 的核心价值就三个词:翻译、隔离、保护。
1.3 SMMU 与 MMU 的区别
很多初学者会把 SMMU 和 MMU 搞混。我列个表,一目了然:
| 对比维度 | MMU | SMMU |
|---|---|---|
| 服务对象 | CPU 核心(进程/线程) | 外设(DMA、GPU、网卡等) |
| 地址空间 | 进程虚拟地址 → 物理地址 | 设备 IOVA → 物理地址 |
| 页表格式 | 通常与架构绑定(如 x86 的 4 级页表) | 可配置,支持多种页表格式(与 MMU 兼容或自定义) |
| 触发方式 | CPU 指令访问内存时自动触发 | 设备发起 DMA 请求时触发 |
| 上下文切换 | 进程切换时由 OS 刷新 TLB | 设备切换时由驱动/固件刷新 SMMU TLB |
| 缺页处理 | 由 OS 缺页异常处理程序完成 | 通常不支持缺页(或需要特殊机制) |
| 典型应用 | 进程隔离、虚拟内存 | 设备隔离、IO 虚拟化(IOMMU) |
你看,MMU 和 SMMU 本质都是“地址翻译器”,但服务的对象完全不同。MMU 是 CPU 的“私人翻译”,SMMU 是所有外设的“公共翻译”。
1.4 SMMU 的核心工作流程
为了让你更直观地理解,我画了一张 SMMU 的工作流程图:
流程其实不复杂:设备发起 DMA 请求时,带上一个 IOVA(设备虚拟地址)和 Stream ID。SMMU 根据 Stream ID 找到对应的 STE,再从 STE 里拿到 CD,然后开始页表遍历,把 IOVA 翻译成物理地址。翻译过程中还会检查权限——读、写、执行,一个都不能少。
注意:我曾经遇到过一个坑——Stream ID 配置错了,导致两个不同的设备用了同一个 STE。结果设备 A 的 DMA 数据被设备 B 的翻译路径给“劫持”了,数据全乱套。所以,Stream ID 的分配和映射,一定要在固件层面严格管理,不能有重叠。
1.5 SMMU 的典型应用场景
咱们再聊聊实际项目中 SMMU 都在哪儿用:
- 虚拟化环境 (IOMMU) —— 给每个 VM 分配独立的 IOVA 空间,设备直通时自动翻译。KVM 和 Xen 都依赖这个。
- 安全隔离 —— 比如 ARM 的 TrustZone,安全世界和普通世界共享 SMMU,通过配置不同 STE 实现访问隔离。
- 大页支持 —— 有些设备需要连续大块内存,但物理内存是碎片化的。SMMU 可以通过大页映射,让设备看到连续的 IOVA 空间。
- 错误隔离 —— 某个设备 DMA 出错时,SMMU 可以截获并上报,不会直接崩掉整个系统。
嗯,说到错误隔离,我记得有一次调试一个 GPU 驱动,GPU 发了一个非法的 DMA 请求,SMMU 直接报了 F_TRANSLATION_FAULT。如果没有 SMMU,这个非法访问可能直接写坏文件系统缓存,后果不堪设想。
1.6 本章小结
咱们这一章把 SMMU 的“根”刨清楚了:
- SMMU 是给设备用的 MMU,解决设备 DMA 的地址翻译和隔离问题。
- 没有 SMMU,设备就是“裸奔”,虚拟化和安全隔离都无从谈起。
- SMMU 和 MMU 的核心区别在于服务对象和触发方式,但底层原理相通。
- Stream ID、STE、CD、TLB 是 SMMU 的四大核心概念,后面每一章都会用到。