2.3 EL0_IRQ 中断改造之中断处理
2.3.1 概要

在原生irq_handler中,通过ldr_l加载函数handle_arch_irq的地址到通用寄存器X1。其中,ldr_l并不是ARM64指令,而是内核引入宏定义,定义在arch/arm64/include/asm/assembler.h,通过adrp和ldr指令的组合,加载当前PC值一定范围[-4GB~4GB]内的符号地址到寄存器。
如果打开了CONFIG_IPIPE配置项,那么通过ldr伪指令,加载函数handle_arch_irq_pipelined到通用寄存器X1中。
通过mov x0, sp指令,把当前的栈指针存入通用寄存器X0,作为函数的入参。之前已经调用kernel_entry 0,将进程运行的用户态现场按照struct pt_regs的格式存入进程内核栈。所以函数的入参就是struct pt_regs *regs。
调用irq_stack_entry,切换到内核中断栈;通过blr x1执行handle_arch_irq_pipelined函数,函数返回后,返回值存在W0;然后调用irq_stack_exit退出内核中断栈。
2.3.2 irq_stack_entry/irq_stack_exit
ARM64的Linux内核在2015年之前中断没有自己独立的栈,都是借用线程的内核栈。独立的中断栈是在 commit 8e23dacd12 arm64: Add do_softirq_own_stack() and enable irq_stacks 中引入的。
如果打开了CONFIG_IPIPE配置项,实时内核co-kernel(Xenomai)允许在中断栈上进行上下文切换,并且允许更多的中断发生在sibling栈上下文中。那么原先判断当前是否在中断栈的汇编代码将不可用,所以I-pipe实现了一套新的方法,如果per cpu变量irq_nesting为0,则说明此时不在中断栈中,否则已经在中断栈中。
1. irq_stack_entry
1 .macro irq_stack_entry
2 mov x19, sp // preserve the original sp
3
4 #ifdef CONFIG_IPIPE
5 /*
6 * When the pipeline is enabled, context switches over the irq
7 * stack are allowed (for the co-kernel), and more interrupts
8 * can be taken over sibling stack

最低0.47元/天 解锁文章
415

被折叠的 条评论
为什么被折叠?



