SMMU缓存一致性调试与TLB性能调优实战工程 - 第1节
1. 课程导入
先问大家一个问题:你想想看,一个 PCIe 网卡想要读写内存,它得经过谁?
在传统 PC 里,它直接通过 DMA 访问物理地址。但在现代 SoC 里,事情没那么简单。设备看到的地址空间和 CPU 看到的,往往是两套不同的东西。
SMMU,全称 System Memory Management Unit,说白了就是给 DMA 设备用的 MMU。CPU 有 MMU 做虚拟地址到物理地址的转换,那 DMA 设备呢?谁来管它的地址翻译?谁来保证它的访问权限?
嗯,这就是 SMMU 的活儿。
一句话总结:SMMU = 设备侧的 MMU。它让 DMA 设备也能用虚拟地址访问内存,同时提供隔离和保护。
1.1 为什么需要 SMMU?
我刚开始做 SoC 架构时,觉得 SMMU 就是个累赘。多一层硬件,多一堆延迟,何必呢?
后来在项目中踩了坑才明白——没有 SMMU,你根本没法做三件事:
- 虚拟化支持:虚拟机里的设备驱动直接操作物理地址?那宿主机怎么隔离?SMMU 提供第二级地址翻译(Stage-2 translation),让每个 VM 的设备 DMA 都限制在自己的地址空间里。
- 连续物理内存伪装:很多老设备要求 DMA 缓冲区物理连续。但系统跑久了,物理内存都是碎片。SMMU 可以把不连续的物理页映射成连续的 IOVA(I/O Virtual Address),骗过设备。
- 访问权限控制:哪个设备能读哪块内存,能写哪块内存,SMMU 的 Stream Table 里配得清清楚楚。我在项目中见过一次安全漏洞,就是某个加速器 DMA 越界写到了关键数据区——从那以后,我对 SMMU 的权限配置再也不敢马虎。
| 场景 | 没有 SMMU | 有 SMMU |
|---|---|---|
| 虚拟化 | 设备直通困难,性能损失大 | 安全直通,VM 隔离 |
| 内存碎片 | 必须预留大块连续内存 | IOVA 映射,碎片透明 |
| 安全隔离 | 设备可访问任意物理地址 | 细粒度权限控制 |
| 地址空间 | 32 位设备只能访问 4GB | IOVA 可扩展到 64 位 |
二、SMMU 在 SoC 中的位置
这张图我画了很多遍,每次给新同事讲 SoC 互联时都会拿出来。你看,SMMU 卡在设备和内存中间,像个交通警察。
从图上你能看到:所有 DMA 设备发出的访问请求,都要先经过 SMMU。SMMU 查 Stream Table,找到对应的配置上下文,做地址翻译,检查权限,然后才放行到系统总线上。
我习惯把 SMMU 比作一个「带安检的翻译官」。设备说「我要访问地址 0x1000」,SMMU 先查这个设备有没有权限,再把 0x1000 翻译成真正的物理地址,最后才让请求通过。
2.1 SMMU 和 MMU 的区别
很多人刚接触时容易搞混。我列个表,你一看就明白:
| 维度 | CPU MMU | SMMU |
|---|---|---|
| 服务对象 | CPU 核心(软件) | DMA 设备(硬件) |
| 触发方式 | 指令执行触发缺页 | DMA 请求触发翻译 |
| 页表格式 | 通常一套页表 | Stream Table + 多级页表 |
| 缓存 | TLB(CPU 侧) | TLB(SMMU 内部) |
| 虚拟化支持 | VT-x / SVM 扩展 | Stage-2 翻译内建 |
| 缺页处理 | CPU 触发 Page Fault | 返回 Abort 或触发中断 |
个人经验:调试 SMMU 和调试 MMU 最大的不同在于——MMU 出问题你还能打 printk 看日志,SMMU 出问题设备直接挂死或者数据错乱。我遇到过最头疼的一次,是某个加速器写数据时 SMMU 把地址翻译错了,结果写到别人的缓冲区里,查了三天才定位到是 Stream Table 配置项少写了一 bit。
三、SMMU 的核心作用
总结下来,SMMU 在 SoC 里干四件事:
- 地址翻译:把设备发出的 IOVA 转成系统物理地址 PA。支持 4K/16K/64K 页粒度。
- 访问权限控制:每个 Stream(可以理解为一个设备或一个设备上的一个功能)都有独立的权限配置。读、写、可执行,逐页控制。
- 隔离保护:不同 VM、不同安全域之间的 DMA 流量完全隔离。非安全世界的设备不能访问安全世界的内存。
- 缓存一致性管理:这是咱们课程的核心。SMMU 可以参与 ACE/CHI 协议的一致性事务,保证设备看到的数据和 CPU 看到的一致。
避坑指南:我曾经在一个项目中,SMMU 的缓存一致性没开,结果 GPU 渲染完一帧画面,显示控制器读到的还是旧数据。画面撕裂 + 花屏,折腾了两周才发现是 SMMU 的 Shareability 域配成了 Non-Shareable。嗯,从那以后我每次配 SMMU 都会再三检查一致性相关的寄存器。
3.1 SMMU 的两种工作模式
根据实际场景,SMMU 可以工作在两种模式下:
| 模式 | 说明 | 典型场景 |
|---|---|---|
| Bypass 模式 | SMMU 不翻译,直接透传 | 启动阶段、不需要地址翻译的简单设备 |
| 翻译模式 | 正常做地址翻译和权限检查 | 虚拟化、IOVA 映射、安全隔离 |
我个人建议:能开翻译模式就开,别图省事用 Bypass。Bypass 虽然延迟低,但等于把安全大门敞开了。你想想看,万一哪个设备驱动有 bug,直接 DMA 写到内核关键数据结构里,系统崩了都不知道怎么死的。
四、本章小结
这一章我们聊了 SMMU 是什么、为什么需要它、它在 SoC 里待在哪、以及它到底干哪些活。说白了,SMMU 就是给 DMA 设备配的 MMU,解决地址翻译、权限控制、隔离保护和缓存一致性问题。