2
votes

arm doc reads

This is because a fresh interrupt could occur at any time, which would cause the core to store the return address of the new interrupt and overwrite the original interrupt. When the original interrupt attempts to return to the main program, it will cause the system to fail. The nested handler must change into an alternative kernel mode before re-enabling interrupts in order to prevent this.

enter image description here

according to the context, the main reason is that new-coming irq would overwrite R14(LR), so that the first irq cannot return to main program.

In my understanding, to solve this problem, I just need to push R14(LR_irq), SPSR_irq to R13(SP_irq) before next irq raising.

enter image description here

There is no need for nested handler to switch to alternative mode before re-enabling interrupts.

Thank you!

1
Your title and text are somewhat confusing; the text is about re-entrant interrupts and your title is about a mode switch. The link above explains what is going on. Linux switches to SVC so it may have a common stack. All code use the stack as an 8k anchor to the thread_info/current PID. The LR_Irq is stored on the SVC stack and nested interrupts can happen after this is saved (if your linux is configured like this). IRQ can definitely interrupt kernel code. Only some configurations allow nested interrupts (aka real-time, desktop, server option can affect this).artless noise

1 Answers

0
votes

Consider this situation:

When you're in a IRQ handler and then perform a C function call, at this point the LR has been changed; so, if you then nest an IRQ right away, the LR will be corrupt.