继续上一节中断处理流程,对中断向量表中对应的handler进一步作介绍。
由EL0和EL1产生的中断分别由函数el0_64_irq_handler()和el1_64_irq_handler()处理。

(1)函数el0_64_irq_handler()由用户态进入内核态,通过irq_enter_rcu()进入中断上下文,进行中断处理函数do_interrupt_handler(),然后调用irq_exit_rcu()退出中断上下文并同时执行处理软中断,最后返回到用户态;
(2)函数el1_64_irq_handler()由EL1直接产生中断,通过irq_enter_rcu()进入中断上下文,进行中断处理函数do_interrupt_handler(),然后调用irq_exit_rcu()退出中断上下文并同时执行处理软中断,返回内核模式;
(3)GIC初始化过程中通过set_handle_irq(gic_handle_irq)设置中断的统一处理函数,因此中断处理函数do_interrupt_handler()最终调用gic_handle_irq();
(4)GIC中断处理函数gic_handle_irq()首先读取IAR寄存器获取acknowledge该中断,此时中断状态从pending到activate状态,且获取中断号,然后根据中断号进行不同中断的处理,最后进行EOI(end of interrupt)。
其中EOI的不同模式由EOImode决定。EOI由priority drop和deactivate两个操作。EOImode=0表示写ICC_EOIR0_EL1/EL0寄存器会同时发出上述两个操作。EOImode=1表示写ICC_EOIR0_EL1/EL0寄存器仅做priority drop操作,需要写ICC_DIR_EL1做deactivate操作。
(5)对NMI中断,中断处理函数为gic_handle_nmi();对于SGI/PPI中断,中断处理函数为handle_percpu_devid_irq();对于SPI/LPI中断,中断处理函数为handle_fastoi_irq();
对于handle_percpu_devid_irq(),处理过程如下:

对于handle_fasteoi_irq(),设置中断进行中标志,然后执行中断handler函数,若支持中断线程化,唤醒中断线程,最后清除中断进行中标志,处理过程如下:

后面章节将对各种中断作使用实例讲解,以便对不同的中断分配/映射/处理过程有更深的理解。