在上一篇文章中介绍了外设如何通过GIC产生安全中断,但是在实际的项目中有些Master也是要访问Secure Memory的,例如DPU,DMA等。TrustZone的基本原理是将系统资源划分成安全和非安全两部分,CPU本身支持TrustZone,可以发出安全访问和非安全访问。但是SoC的其他Master也需要访问memory,在有些场景下也需要访问安全memory和非安全memory,那该怎么去实现呢?
可以由几种不同的实现方式,有些Master本身就支持TrustZone,可以发出安全访问和非安全访问,例如Arm的DMA直接就可以发出安全访问或者非安全访问。但是第三方的Master可能不支持TrustZone,可以在IP前面加安全控制器来实现,例如这个控制器是Secure only的,可以通过TEE对安全控制器进行编程,Master发出的访问不Care安全或者非安全,通过控制器来扩展TrustZone功能,但是这种方式很大局限性;另外一种方法就是我们可以今天介绍的SMMU来实现。
SMMU是Arm的System IP,几乎是跟CPU演进结合最紧密的一个IP。我们知道CPU内部有个MMU,SMMU就是跟MMU非常相似,是System MMU,主要给其他Master来使用,连页表格式也是一样的,只是编程方式不同,理论上可以让CPU的MMU和SMMU可以使用同一套页表。增加SMMU后,其他Master也相当于有了MMU的功能,MMU是CPU的重要部分,主要是由两部分组成,一部分是TLB用来Cache VA<->PA的转换关系,一部分是Table Walk Unit,如果TLB里没有找到VA<->PA的转换关系,该Table Walk Unit就从页表里查询VA和PA的转换关系。对于TrustZone系统来说,MMU也是非常重要的,例如在Armv7-A的架构中很多MMU的寄存器都是banked,可以简单认为Secure world和Normal World都有一个MMU,在Armv8-A里是通过软件保存上下文来实现的,还有CPU在安全状态时发出的都是安全访问,当MMU enable后,可以通过页表里的NSbit来控制发出的是安全访问,还是非安全访问,同时也会把安全信息也会存储在TLB里。
CPU架构在不断的演进,增加了很多feature,这些feature的使能或者控制位都是存储在页表,如果其他Master也想使用这些feature,那么SMMU的架构也需要跟随者演进,例如SMMUv1主要是支持Armv7-A的页表格式,SMMUv2主要是支持Armv8.1-A的页表格式,SMMUv3相对SMMUv2更新很大,除了支持最新Armv8.x-A的特性,同时支持更多的context,支持PCIe,也支持Message based interrupt配合GICv3等。那其他Master通过SMMU可以支持下面的功能:
地址转换:SMMU跟MMU一样,支持两级转换Stage 1 Translation和Stage2 Translation,例如VA<->IPA<->PA,但是在现实使用中,也可以直接bypass,stage 1 only,stage2 only,或者Stage 1+Stage 2
内存保护:(S)MMU除了支持地址转换外,内存属性也是重要的部分,例如可以在页表内配置读写权限,执行权限,访问权限等
隔离:SMMU同时可以给多个Master使用,例如SMMUv2支持128个contexts,SMMUv3支持更多的Contexts,因为在SMMUv2中contexts的信息是保存在寄存器,在SMMUv3中context的信息是存储在内存里面,通过StreamID来查询,Stream ID是32位的。CPU可以和其他Master使用同一套页表,或者CPU可以SMMU单独建立页表,或者可以为每个Master建立一套或者多套页表,来控制不同的访问区域。
TrustZone:如果Master不支持TrustZone,可以通过SMMU来支持,例如在该Master发出访问时通过对应页表的属性来配置,尤其是到Armv8.4 Secure world virtulization,SMMU的作用会更大。
前面提到的都是支持的功能,我们也可以通过一些例子来解释哪些场景下需要SMMU,例如
- 访问非连续的地址:现在系统中很少再预留连续的memory,如果Master需要很多memory,可以通过SMMU把一些非连续的PA映射到连续的VA,例如给DMA,VPU,DPU使用。
- 32位转换成64位:现在很多系统是64位的,但是有些Master还是32位的,只能访问低4GB空间,如果访问更大的地址空间需要软硬件参与交换memory,实现起来比较复杂,也可以通过SMMU来解决,Master发出来的32位的地址,通过SMMU转换成64位,就很容易访问高地址空间。
- 限制Master的访问空间:Master理论上可以访问所有的地址空间,可以通过SMMU来对Master的访问进行过滤,只让Master访问受限的区域,那这个区域也可以通过CPU对SMMU建立页表时动态控制。
- 用户态驱动:现在我们也看到很多系统把设备驱动做在用户态,调用驱动时不需要在切换到内核态,但是存在一些安全隐患,就是用户态直接控制驱动,有可能访问到内核空间,这种情况下也可以用SMMU来实现限制设备的访问空间
- 设备虚拟化: 例如设备虚拟化有多种方式,Emulate,Para-virtualized,以及Pass-through,用SMMU可以实现Pass though,这样无论是性能,还是软件的改动都是比较小的。
- ......
SMMUv2和SMMUv3架构,编程方式,以及硬件实现差异都非常大,但是要实现的功能和基本原理都是相似,如果理解了SMMU的功能以及要解决的问题,再看Linux SMMU driver和SMMU Architecture Spec都会简单很多。
以上仅是个人理解,如果有任何问题,欢迎随时沟通。
相关文章
更多Arm Trustzone,PSA及安全相关的技术文章可以关注平台安全架构(PSA)专栏。如希望加入极术社区专业PSA技术交流群,欢迎联系极术小姐姐(微信:aijishu20, 备注PSA)加入。