From 15fba9d3bea8b1284434e78b8df0723458ddc22a Mon Sep 17 00:00:00 2001 From: Justin Hibbits Date: Sat, 19 Jan 2019 04:47:19 +0000 Subject: [PATCH] powerpc: Fix opaque irq data initialization The powerpc_intr structure is not zero-initialized, so on an invariants build would panic in the xics driver with an invalid pointer. Also fix the xics driver to share the private data setup code between xics_enable() and xics_bind(). Reported by: Leonardo Bianconi --- sys/powerpc/powerpc/intr_machdep.c | 1 + sys/powerpc/pseries/xics.c | 28 ++++++++++++++++------------ 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/sys/powerpc/powerpc/intr_machdep.c b/sys/powerpc/powerpc/intr_machdep.c index 851b4265a168..adfd573dd940 100644 --- a/sys/powerpc/powerpc/intr_machdep.c +++ b/sys/powerpc/powerpc/intr_machdep.c @@ -209,6 +209,7 @@ intr_lookup(u_int irq) i->event = NULL; i->cntp = NULL; + i->priv = NULL; i->trig = INTR_TRIGGER_CONFORM; i->pol = INTR_POLARITY_CONFORM; i->irq = irq; diff --git a/sys/powerpc/pseries/xics.c b/sys/powerpc/pseries/xics.c index e2a6d71d7c48..4dbfcfbd30cb 100644 --- a/sys/powerpc/pseries/xics.c +++ b/sys/powerpc/pseries/xics.c @@ -295,6 +295,20 @@ xics_attach(device_t dev) return (0); } +static __inline struct xicp_intvec * +xicp_setup_priv(struct xicp_softc *sc, u_int irq, void **priv) +{ + if (*priv == NULL) { + KASSERT(sc->nintvecs + 1 < nitems(sc->intvecs), + ("Too many XICP interrupts")); + mtx_lock(&sc->sc_mtx); + *priv = &sc->intvecs[sc->nintvecs++]; + mtx_unlock(&sc->sc_mtx); + } + + return (*priv); +} + /* * PIC I/F methods. */ @@ -311,10 +325,7 @@ xicp_bind(device_t dev, u_int irq, cpuset_t cpumask, void **priv) if (irq == MAX_XICP_IRQS) return; - if (*priv == NULL) - *priv = &sc->intvecs[sc->nintvecs++]; - - iv = *priv; + iv = xicp_setup_priv(sc, irq, priv); /* * This doesn't appear to actually support affinity groups, so pick a @@ -426,14 +437,7 @@ xicp_enable(device_t dev, u_int irq, u_int vector, void **priv) /* Bind to this CPU to start: distrib. ID is last entry in gserver# */ cpu = PCPU_GET(hwref); - if (*priv == NULL) { - KASSERT(sc->nintvecs + 1 < nitems(sc->intvecs), - ("Too many XICP interrupts")); - mtx_lock(&sc->sc_mtx); - *priv = &sc->intvecs[sc->nintvecs++]; - mtx_unlock(&sc->sc_mtx); - } - intr = *priv; + intr = xicp_setup_priv(sc, irq, priv); intr->irq = irq; intr->vector = vector;