xtensa: Don't call ISRs for disabled interrupts

Xtensa interrupts are handled generically, by testing a set of flagged
interrupts in the INTERRUPT register.  It's not possible to know
exactly which device "caused" an interrupt.

The entry code was dispatching correctly, but it was failing to test
the enable state in INTENABLE.  Such an interrupt will never "fire",
but it might still be flagged, and if we happen to end up handling an
interrupt of the same priority (due to some other device) the entry
handler would incorrectly invoke the disabled interrupt.

Found by dumb luck and a comedy of errors: the recent timer driver
change swapped the counter in use, which changed the interrupt number
to one shared with the I2C driver, whose early interrupts (odd that
this device is interrupting on boot when not in use, but whatever)
would then discover the OTHER timer counter had been flagged and try
to invoke an ISR for that other counter, which was the _irq_spurious()
spurious interrupt handler.

Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This commit is contained in:
Andy Ross 2018-11-14 11:49:53 -08:00 committed by Anas Nashif
commit d411514a5f

View file

@ -135,9 +135,10 @@ static void dump_stack(int *stack)
#define DEF_INT_C_HANDLER(l) \
void *xtensa_int##l##_c(void *interrupted_stack) \
{ \
int irqs, m; \
u32_t irqs, intenable, m; \
__asm__ volatile("rsr.interrupt %0" : "=r"(irqs)); \
\
__asm__ volatile("rsr.intenable %0" : "=r"(intenable)); \
irqs &= intenable; \
while ((m = _xtensa_handle_one_int##l(irqs))) { \
irqs ^= m; \
__asm__ volatile("wsr.intclear %0" : : "r"(m)); \