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 卡在设备和内存中间,像个交通警察。

SMMU 在 SoC 中的位置 CPU Cluster Core 0 | Core 1 | Core 2 | Core 3 Memory Controller DDR4 / LPDDR5 系统总线 / 互联 (NoC / AXI Crossbar) ACE / CHI / AXI 协议 SMMU 地址翻译 + 权限检查 PCIe EP 网卡 / GPU / NVMe 加速器 NPU / DSP / VPU 显示控制器 DPU / MIPI DSI 其他外设 USB / SDIO / I2C SMMU 位于设备与系统总线之间,所有 DMA 事务都必须经过它翻译和检查

从图上你能看到:所有 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 里干四件事:

  1. 地址翻译:把设备发出的 IOVA 转成系统物理地址 PA。支持 4K/16K/64K 页粒度。
  2. 访问权限控制:每个 Stream(可以理解为一个设备或一个设备上的一个功能)都有独立的权限配置。读、写、可执行,逐页控制。
  3. 隔离保护:不同 VM、不同安全域之间的 DMA 流量完全隔离。非安全世界的设备不能访问安全世界的内存。
  4. 缓存一致性管理:这是咱们课程的核心。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,解决地址翻译、权限控制、隔离保护和缓存一致性问题。