前言
最近看到了一个SMMU,以前只知道MMU,于是就找了几篇前辈的帖子来学习一下。
ARM® System Memory Management Unit Architecture Specification, SMMU architecture version 3.0 and version 3.1
1. 什么是SMMU?
SMMU(system mmu),是I/O device与总线之间的地址转换桥。
这里就可以很明显的看出这个MMU和SMMU的差别与相似。
2. 为什么需要SMMU?
了解SMMU出现的背景,需要知道系统中的两个概念:DMA和虚拟化。
1-DMA
DMA:((Direct Memory Access),直接内存存取, 是一种外部设备不通过CPU而直接与系统内存交换数据的接口技术 。外设可以通过DMA,将数据批量传输到内存,然后再发送一个中断通知CPU取,其传输过程并不经过CPU, 减轻了CPU的负担。但由于DMA不能像CPU一样通过MMU操作虚拟地址,所以DMA需要连续的物理地址。
2-虚拟化
虚拟化:在虚拟化场景, 所有的VM都运行在中间层hypervisor上,每一个VM独立运行自己的OS(guest OS),Hypervisor完成硬件资源的共享, 隔离和切换。
但对于Hypervisor + GuestOS的虚拟化系统来说, guest VM使用的物理地址是GPA, 看到的内存并非实际的物理地址(也就是HPA),因此Guest OS无法正常的将连续的物理地址分给硬件。(分给外设)
因此,为了支持I/O透传机制中的DMA设备传输**,而引入了IOMMU技术(ARM称作SMMU)。**
总而言之,SMMU可以为ARM架构下实现虚拟化扩展提供支持。它可以和MMU一样,提供
- stage1转换(VA->PA), 或者
- stage2转换(IPA->PA),或者
- stage1 + stage2转换(VA->IPA->PA)的灵活配置。
[VA:虚拟地址;IPA: 中间物理地址;PA:物理地址]
3. 作用?
1-SMMU在系统中位置和作用
SMMU功能与MMU功能类似,将IO设备的DMA地址请求(IOVA)转化为系统总线地址(PA),实现地址映射、属性转换、权限检查等功能,实现不同设备的DMA地址空间隔离。
2-SMMU软硬件交互过程
- SMMU处于IO设备和总线之间,负责将设备的输入IOVA转化为系统总线的物理地址PA;
- SMMU硬件包含configuration lookup/TLB/Page Table Walk以及cmdq/eventq等部分,其中configuration lookup部分查找stream id所对应的配置(ste/cd), 最终指向page table基地址等;
- SMMU通过configuration lookup找到设备的配置及页表基地址等,然后查询TLB中是否存在输入地址input的映射,如果TLB命中,直接返回输出PA;若TLB没有命中,PTW模块逐级查询页表,找到页表中的映射,输出PA;
- 软件/SMMU驱动通过CMDQ/EVENTQ进行交互,驱动通过CMDQ发送命令给SMMU硬件(如TLBI/SYNC等);SMMU硬件通过EVENTQ通知驱动有事件需要处理(如设备缺页等) 软件/驱动建立和维护内存中的配置和页表;
4. SMMU常用概念
- StreamID
一个平台上可以有多个SMMU设备,每个SMMU设备下面可能连接着多个Endpoint, 多个设备互相之间可能不会复用同一个页表,需要加以区分,SMMU用StreamID来做这个区分( SubstreamID的概念和PCIe PASID是等效的) - STE Stream Table Entry
STE里面包含一个指向stage2地址翻译表的指针,并且同时还包含一个指向CD(Context Descriptor)的指针. - CD Context Descriptor
是一个特定格式的数据结构,包含了指向stage1地址翻译表的基地址指针
关键点:
StreamID: device 通过物理线连接到SMMU ,这个StreamID就是用来标识SMMU上连接的设备。想象一个8 ports hub上连接了8个物理设备,这8个设备就可以通过portID来标识,比如port 0代表第一个设备,同理steamID
STE: stream Table Entry,可以理解为SMMU页表转换的第一级索引,每一个streamID代表着一个STE,通过这个STE指向的连接可以找到真正的虚地址==》物理地址转换的页表。假设SMMU上连接着8个具体设备,每个设备都有自己的StreamID,那就有至少8个STE表项。
CD: Context Descriptor, stage 1的页表配置项,它其中的TTB0指向了真正的页表信息,比如PGD, PMD, PTE等,完全和MMU的页表转换原理一样
查找过程:
假设stream ID为16的设备发起了DMA操作(如下动作完全自动完成,前提是之前配置好了SMMU中所有的表项):
- StreamID=16, 所以从寄存器strtab_base指向的地址中找到偏移为16的STE表项
- 该表项中的s1ContexPtr指向了下一级的stage 1转换地址CD(Context Descriptor)
- CD中的TTB0指向了一个页表转换的基地址PGD
- PGD-àPMD-àPTE 完成了虚拟地址到物理地址的转换(和MMU工作原理一样)
注:
- 其中引入的VMID, ASID的原因和MMU一样,都是为了在TLB中加于区别,防止cache bouncing
- Stage2 的转换原理基本和Stage 1一致,不过没有额外的CD
- 由于懒,文中有些图从网上直接扣的,抱歉。如有侵权,请告知