On Tue, Nov 20, 2018 at 07:56:31PM -0800, Carlos Cardenas wrote:
> 
> I've been running the updated patch and so far so good...
> 
> If y'all don't mind, I want to keep pounding on it for the next day or
> two before giving a thumbs up.
> 
> Thanks.
> 
> +--+
> Carlos
> 

I had a look into the IRQ controller drivers used on arm64 and armv7
and it seems like the following diff would fix the panic and also
modify mvmpic(4) similarly.  I haven't touched omgpio(4) since we
do no use IRQs there.

diff --git a/sys/arch/arm/cortex/ampintc.c b/sys/arch/arm/cortex/ampintc.c
index bdfc14b621d..19d6eebdd2a 100644
--- a/sys/arch/arm/cortex/ampintc.c
+++ b/sys/arch/arm/cortex/ampintc.c
@@ -161,8 +161,8 @@ struct intrhand {
 
 struct intrq {
        TAILQ_HEAD(, intrhand) iq_list; /* handler list */
-       int iq_irq;                     /* IRQ to mask while handling */
-       int iq_levels;                  /* IPL_*'s this IRQ has */
+       int iq_irq_max;                 /* IRQ to mask while handling */
+       int iq_irq_min;                 /* lowest IRQ when shared */
        int iq_ist;                     /* share type */
 };
 
@@ -402,10 +402,12 @@ ampintc_calc_mask(void)
                                min = ih->ih_ipl;
                }
 
-               if (sc->sc_ampintc_handler[irq].iq_irq == max) {
+               if (sc->sc_ampintc_handler[irq].iq_irq_max == max &&
+                   sc->sc_ampintc_handler[irq].iq_irq_min == min)
                        continue;
-               }
-               sc->sc_ampintc_handler[irq].iq_irq = max;
+
+               sc->sc_ampintc_handler[irq].iq_irq_max = max;
+               sc->sc_ampintc_handler[irq].iq_irq_min = min;
 
                if (max == IPL_NONE)
                        min = IPL_NONE;
@@ -538,7 +540,7 @@ ampintc_irq_handler(void *frame)
        if (irq >= sc->sc_nintr)
                return;
 
-       pri = sc->sc_ampintc_handler[irq].iq_irq;
+       pri = sc->sc_ampintc_handler[irq].iq_irq_max;
        s = ampintc_splraise(pri);
        TAILQ_FOREACH(ih, &sc->sc_ampintc_handler[irq].iq_list, ih_list) {
 #ifdef MULTIPROCESSOR
diff --git a/sys/arch/arm64/dev/agintc.c b/sys/arch/arm64/dev/agintc.c
index 2d9afa9016d..d39530e85a0 100644
--- a/sys/arch/arm64/dev/agintc.c
+++ b/sys/arch/arm64/dev/agintc.c
@@ -171,8 +171,8 @@ struct intrhand {
 
 struct intrq {
        TAILQ_HEAD(, intrhand)  iq_list;        /* handler list */
-       int                     iq_irq;         /* IRQ to mask while handling */
-       int                     iq_levels;      /* IPL_*'s this IRQ has */
+       int                     iq_irq_max;     /* IRQ to mask while handling */
+       int                     iq_irq_min;     /* lowest IRQ when shared */
        int                     iq_ist;         /* share type */
        int                     iq_route;
 };
@@ -746,13 +746,16 @@ agintc_calc_irq(struct agintc_softc *sc, int irq)
                        min = ih->ih_ipl;
        }
 
-       if (sc->sc_handler[irq].iq_irq == max)
-               return;
-       sc->sc_handler[irq].iq_irq = max;
-
        if (max == IPL_NONE)
                min = IPL_NONE;
 
+       if (sc->sc_handler[irq].iq_irq_max == max &&
+           sc->sc_handler[irq].iq_irq_min == min)
+               return;
+
+       sc->sc_handler[irq].iq_irq_max = max;
+       sc->sc_handler[irq].iq_irq_min = min;
+
 #ifdef DEBUG_AGINTC
        if (min != IPL_NONE)
                printf("irq %d to block at %d %d \n", irq, max, min );
@@ -828,7 +831,7 @@ agintc_route_irq(void *v, int enable, struct cpu_info *ci)
 
        if (enable) {
                agintc_set_priority(sc, ih->ih_irq,
-                   sc->sc_handler[ih->ih_irq].iq_irq);
+                   sc->sc_handler[ih->ih_irq].iq_irq_min);
                agintc_route(sc, ih->ih_irq, IRQ_ENABLE, ci);
                agintc_intr_enable(sc, ih->ih_irq);
        }
@@ -937,7 +940,7 @@ agintc_irq_handler(void *frame)
                return;
        }
 
-       pri = sc->sc_handler[irq].iq_irq;
+       pri = sc->sc_handler[irq].iq_irq_max;
        s = agintc_splraise(pri);
        TAILQ_FOREACH(ih, &sc->sc_handler[irq].iq_list, ih_list) {
                agintc_run_handler(ih, frame, s);
diff --git a/sys/arch/arm64/dev/ampintc.c b/sys/arch/arm64/dev/ampintc.c
index 2c4ce63a150..de6ed057f95 100644
--- a/sys/arch/arm64/dev/ampintc.c
+++ b/sys/arch/arm64/dev/ampintc.c
@@ -160,8 +160,8 @@ struct intrhand {
 
 struct intrq {
        TAILQ_HEAD(, intrhand) iq_list; /* handler list */
-       int iq_irq;                     /* IRQ to mask while handling */
-       int iq_levels;                  /* IPL_*'s this IRQ has */
+       int iq_irq_max;                 /* IRQ to mask while handling */
+       int iq_irq_min;                 /* lowest IRQ when shared */
        int iq_ist;                     /* share type */
 };
 
@@ -469,14 +469,16 @@ ampintc_calc_mask(void)
                                min = ih->ih_ipl;
                }
 
-               if (sc->sc_handler[irq].iq_irq == max) {
-                       continue;
-               }
-               sc->sc_handler[irq].iq_irq = max;
-
                if (max == IPL_NONE)
                        min = IPL_NONE;
 
+               if (sc->sc_handler[irq].iq_irq_max == max &&
+                   sc->sc_handler[irq].iq_irq_min == min)
+                       continue;
+
+               sc->sc_handler[irq].iq_irq_max = max;
+               sc->sc_handler[irq].iq_irq_min = min;
+
                /* Enable interrupts at lower levels, clear -> enable */
                /* Set interrupt priority/enable */
                if (min != IPL_NONE) {
@@ -604,7 +606,7 @@ ampintc_route_irq(void *v, int enable, struct cpu_info *ci)
        bus_space_write_4(sc->sc_iot, sc->sc_d_ioh, ICD_ICRn(ih->ih_irq), 0);
        if (enable) {
                ampintc_set_priority(ih->ih_irq,
-                   sc->sc_handler[ih->ih_irq].iq_irq);
+                   sc->sc_handler[ih->ih_irq].iq_irq_min);
                ampintc_intr_enable(ih->ih_irq);
        }
 
@@ -646,7 +648,7 @@ ampintc_irq_handler(void *frame)
        if (irq >= sc->sc_nintr)
                return;
 
-       pri = sc->sc_handler[irq].iq_irq;
+       pri = sc->sc_handler[irq].iq_irq_max;
        s = ampintc_splraise(pri);
        TAILQ_FOREACH(ih, &sc->sc_handler[irq].iq_list, ih_list) {
 #ifdef MULTIPROCESSOR
diff --git a/sys/arch/armv7/marvell/mvmpic.c b/sys/arch/armv7/marvell/mvmpic.c
index 5d3b162c6bb..8c7c93d3f1f 100644
--- a/sys/arch/armv7/marvell/mvmpic.c
+++ b/sys/arch/armv7/marvell/mvmpic.c
@@ -195,8 +195,8 @@ mpic_calc_mask(struct mpic_softc *sc)
        if (max == IPL_NONE)
                min = IPL_NONE;
 
-       if (sc->sc_ipl != max) {
-               sc->sc_ipl = max;
+       if (sc->sc_ipl != min) {
+               sc->sc_ipl = min;
 
                if (sc->sc_ih != NULL)
                        arm_intr_disestablish_fdt(sc->sc_ih);

Reply via email to