On Fri, Dec 23, 2016 at 10:07:03AM +0100, Patrick Wildt wrote:
> Hi,
> 
> while looking at OpenBSD/arm64 I had interrupt storm issues.  Turns out
> the issue is in the interrupt controller code.  It's the same controller
> as on your typical OpenBSD/armv7 machine.
> 
> If the controller has for example 288 interrrupts, ((1 << 288) - 1) is
> a bit too much to handle.  In the end an iack_val of "33" will be stored
> as "0" in irq.  This means it will handle a different IRQ.
> 
> Instead we should split this "dynamic" mask into two parts.  First of
> all we need to grab only the IRQ bits relevant to us (ICPIAR_IRQ_M).
> The other bits contain the CPU ID.  When we have done this we can use
> the actual IRQ id to do additional checks (spurious and irq >= nintr).
> 
> ok?

ok jsg@ for this and the arm64 equivalent.

> 
> Patrick
> 
> diff --git a/sys/arch/arm/cortex/ampintc.c b/sys/arch/arm/cortex/ampintc.c
> index 693eb0d6d91..a26c45e848f 100644
> --- a/sys/arch/arm/cortex/ampintc.c
> +++ b/sys/arch/arm/cortex/ampintc.c
> @@ -488,11 +488,15 @@ ampintc_irq_handler(void *frame)
>       }
>  #endif
>  
> -     if (iack_val == 1023) {
> +     irq = iack_val & ICPIAR_IRQ_M;
> +
> +     if (irq == 1023) {
>               sc->sc_spur.ec_count++;
>               return;
>       }
> -     irq = iack_val & ((1 << sc->sc_nintr) - 1);
> +
> +     if (irq >= sc->sc_nintr)
> +             return;
>  
>       pri = sc->sc_ampintc_handler[irq].iq_irq;
>       s = ampintc_splraise(pri);
> 

Reply via email to