- CPU是如何支持安全中断的?
- GIC是如何支持安全中断的?
- 外设如何支持安全中断
- TF-A2.6.0 源码分析
前几篇博文主要梳理了GIC V3架构基础,中断全生命周期,以及中断IRQ、FIQ基础概念。那在ARM TrustZone是如何支持安全中断的呢?
ARM TrustZone一个非常大的优势就是很容易管理外设,管理外设包含了:外设访问权限,外设作为Master时怎么发出安全访问或非安全访问,以及外设如何产生安全中断,以及CPU如何响应这个中断等。我们今天主要介绍如何产生安全中断,由三个部分来参与:安全外设,GIC,以及CPU。
CPU是如何支持安全中断的?对于CPU本身来说对中断是安全还是非安全是无感知的,CPU只区分到底是IRQ,还是FIQ。当CPU收到中断时会根据状态寄存器来检查这个中断是否被屏蔽了,例如PSTATE.DAIF,其中I bit标识IRQ是否被Mask,F bit标识FIQ是否被Mask。如果没有被Mask的话,CPU可能会处理这个中断。
那这个中断到底在哪里处理呢?例如Armv8-A CPU分为EL0,EL1,EL2,EL3,EL0是不处理中断的,EL1,EL2,EL3都可以处理中断,具体在哪些EL处理中断,是有系统寄存器来决定的,例如SCR_EL3.FIQ和SCR_EL3.IRQ来标志来了对应的中断后,CPU是否直接进入到EL3所对应的exception handler。但是exception handler具体怎么处理这个中断,那是软件的事情,例如直接处理中断,还是作为一个event来做其他的事情,都是软件来控制的。 可见对于CPU来说是不知道中断是安全还是非安全,只是根据收到的中断类型来做两件事:屏蔽了吗?如果没屏蔽,在哪里处理?目前在Armv7-A的架构中,FIQ当安全中断,在Armv8-A和GICv3架构中FIQ不表示安全中断,表示来了中断,当前EL可能处理不了,需要换个地方处理。
GIC是如何支持安全中断的?GIC也在不断向前演进,现在最新的应该GICv4,从GICv1就开始支持TrustZone,GICv2相对GICv1来说主要是支持虚拟化,GICv3相对GICv2改动较大,支持Message base interrupt,支持的CPU更多,在安全方面也做了一些增强,GICv4在虚拟化上做了增强。
GICv1和GICv2主要是配合Armv7-A的CPU,是怎么支持TrustZone的呢?结合Armv7-A的架构,因为想把FIQ预留给安全中断,那么GIC主要由两点来实现,第一个是把安全分Group,Group 0给安全中断可以产生IRQ或者FIQ,Group 1给非安全中断只能产生IRQ。第二个把跟FIQ相关的registers都需要安全来配置,例如Group 0相关的配置,只有CPU在安全状态进行配置,这样做来达到安全的目的。
GICv3主要是配合Armv8-A的CPU,但是Armv8-A相对Armv7-A的TrustZone进行了优化,Secure World分为S-EL1(Trusted OS)和EL3(Secure Monitor)是不同的特权级,如果再像GICv2那样分为Group 0 和Group 1,Group 0如果同时给S-EL1和EL3使用,其实是不够的。所以在GICv3时分成了三个Group,Group0,Secure Group 1和non-secure Group 1,这样就很容易区分,例如Group 0 给EL3使用,Secure Group 1给S-EL1用,Non-secure Group 1给EL1来用,这样划分就很合理,但是也存在另外一个问题,如果三个Group,而CPU侧只有两个信号线IRQ和FIQ,怎么区分这三个Group呢?这样也是很多开发者容易误解的地方,在GICv3的GIC CPU interface是跟CPU做在一起的,也是说GIC Distributor把中断发送到GIC CPU interface后,CPU interface是知道CPU在哪个EL,以及安全状态还是非安全状态,CPU根据中断所在的Group,以及CPU的状态来决定到底是发IRQ,还是FIQ,这样用两个中断信号很好解决区分三个Group的问题。
不过这里要注意的FIQ不在表示安全中断,例如对于Non-secure Group 1的中断,如果CPU在Secure world,CPU interface就给CPU发送一个FIQ,如果CPU在Non-secure world就发一个IRQ。CPU收到这个IRQ或者IFQ,是否被屏蔽,以及在哪处理,是由上文提到的CPU系统寄存器来决定的,跟GIC没关系。
外设如何支持安全中断在GICv3中,中断分为SGI,PPI,SPI,LPI。其中LPI只有Non-secure Group 1,也就是说只能产生非安全中断,其他三个可以配置成Group 0,Non-secure Group 1或Secure Group 1。SGI是software generated interrupts,一般是做核间通讯来用的,PPI是private peripheral interrupt主要是给CPU的私有外设来用的,一般是安全外设是做成SPI,shared peripheral interrupt。
TF-A2.6.0 源码分析void __init gicv3_distif_init(void) { unsigned int bitmap; assert(gicv3_driver_data != NULL); assert(gicv3_driver_data->gicd_base != 0U); assert(IS_IN_EL3()); gicd_clr_ctlr(gicv3_driver_data->gicd_base, CTLR_ENABLE_G0_BIT | CTLR_ENABLE_G1S_BIT | CTLR_ENABLE_G1NS_BIT, RWP_TRUE); // 当前中断被disabled,清除分组信息,当前函数做重新配置 gicd_set_ctlr(gicv3_driver_data->gicd_base, CTLR_ARE_S_BIT | CTLR_ARE_NS_BIT, RWP_TRUE); // 亲和路由是能 gicv3_spis_config_defaults(gicv3_driver_data->gicd_base); bitmap = gicv3_secure_spis_config_props( gicv3_driver_data->gicd_base, gicv3_driver_data->interrupt_props, gicv3_driver_data->interrupt_props_num); gicd_set_ctlr(gicv3_driver_data->gicd_base, bitmap, RWP_TRUE); //使能上述配置的SPIs }
unsigned int gicv3_secure_spis_config_props(uintptr_t gicd_base, const interrupt_prop_t *interrupt_props, unsigned int interrupt_props_num) { unsigned int i; const interrupt_prop_t *current_prop; unsigned long long gic_affinity_val; unsigned int ctlr_enable = 0U; if (interrupt_props_num > 0U) { assert(interrupt_props != NULL); } for (i = 0U; i < interrupt_props_num; i++) { current_prop = &interrupt_props[i]; unsigned int intr_num = current_prop->intr_num; if (!IS_SPI(intr_num)) { continue; } gicd_clr_igroupr(gicd_base, intr_num); assert((current_prop->intr_grp == INTR_GROUP0) || (current_prop->intr_grp == INTR_GROUP1S)); if (current_prop->intr_grp == INTR_GROUP1S) { gicd_set_igrpmodr(gicd_base, intr_num); ctlr_enable |= CTLR_ENABLE_G1S_BIT; } else { gicd_clr_igrpmodr(gicd_base, intr_num); ctlr_enable |= CTLR_ENABLE_G0_BIT; } gicd_set_icfgr(gicd_base, intr_num, current_prop->intr_cfg); gicd_set_ipriorityr(gicd_base, intr_num, current_prop->intr_pri); gic_affinity_val = gicd_irouter_val_from_mpidr(read_mpidr(), 0U); gicd_write_irouter(gicd_base, intr_num, gic_affinity_val); gicd_set_isenabler(gicd_base, intr_num); } return ctlr_enable; }
1.《ARM GIC ARM TrustZone如何支持安全中断 分析笔记。》援引自互联网,旨在传递更多网络信息知识,仅代表作者本人观点,与本网站无关,侵删请联系页脚下方联系方式。
2.《ARM GIC ARM TrustZone如何支持安全中断 分析笔记。》仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证。
3.文章转载时请保留本站内容来源地址,https://www.lu-xu.com/jiaoyu/2372144.html