• Will Deacon's avatar
    arm64: irq: fix walking from irq stack to task stack · 7596abf2
    Will Deacon authored
    Running with CONFIG_DEBUG_SPINLOCK=y can trigger a BUG with the new IRQ
    stack code:
    
      BUG: spinlock lockup suspected on CPU#1
    
    This is due to the IRQ_STACK_TO_TASK_STACK macro incorrectly retrieving
    the task stack pointer stashed at the top of the IRQ stack.
    
    Sayeth James:
    
    | Yup, this is what is happening. Its an off-by-one due to broken
    | thinking about how the stack works. My broken thinking was:
    |
    | >   top ------------
    | >       | dummy_lr | <- irq_stack_ptr
    | >       ------------
    | >       |   x29    |
    | >       ------------
    | >       |   x19    | <- irq_stack_ptr - 0x10
    | >       ------------
    | >       |   xzr    |
    | >       ------------
    |
    | But the stack-pointer is decreased before use. So it actually looks
    | like this:
    |
    | >       ------------
    | >       |          |  <- irq_stack_ptr
    | >   top ------------
    | >       | dummy_lr |
    | >       ------------
    | >       |   x29    | <- irq_stack_ptr - 0x10
    | >       ------------
    | >       |   x19    |
    | >       ------------
    | >       |   xzr    | <- irq_stack_ptr - 0x20
    | >       ------------
    |
    | The value being used as the original stack is x29, which in all the
    | tests is sp but without the current frames data, hence there are no
    | missing frames in the output.
    |
    | Jungseok Lee picked it up with a 32bit user space because aarch32
    | can't use x29, so it remains 0 forever. The fix he posted is correct.
    
    This patch fixes the macro and adds some of this wisdom to a comment,
    so that the layout of the IRQ stack is well understood.
    
    Cc: James Morse <james.morse@arm.com>
    Reported-by: default avatarJungseok Lee <jungseoklee85@gmail.com>
    Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
    7596abf2
irq.h 1.59 KB