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);