Linux version: v6.0
Architecture: ARMv8
This post is the continuation of Linux Interrupt Subsystem Intro(1): Interrupt Handling Initialization.
Introduction
I’m surprised almost half a year had pasted since my last post… I got sidetracked by researching other things in between, so I’ve been leaving this gap unfilled. Now coming back to it I feel a bit rusty. Indeed, when there’s something I want to write about, it is better do it promptly.
The basic architecture of Linux’s interrupt handling and the preparation is introduced last time, including setting up interrupt handlers: handle_arch_irq
, irq_desc→handle_irq
, irqaction→handler
. Let’s see how they are invoked when an interrupt is serviced.
Interrupt Handling Process
PC jumps to the IRQ vector in the CPU’s exception vectors when and IPI comes:
1 | // arch/arm64/kernel/entry.S |
kernel_ventry
is an assembly macro:
1 | .macro kernel_ventry, el:req, ht:req, regsize:req, label:req |
the last instruction is a branch instruction, if we assume the CPU is in AArch64 EL0 when the interrupt arrives,
b el\el\ht\()_\regsize\()_\label
expands into
b el0t_64_irq
el0t_64_irq
is defined in the same file, and is also generated by macros:
1 | // arch/arm64/kernel/entry.S |
focus on entry_handler 0, t, 64, irq
it expands into
1 | SYM_CODE_START_LOCAL(el0t_64_irq) |
continue: see the comments added
1 | // arch/arm64/kernel/entry-common.c |
now let’s look at gic_handle_irq
:
1 | static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) |
as in the last post, desc→handle_irq
points to handle_percpu_devid_irq
1 | /** |
And that’s it! EZPZ, right?