Fri Aug 30 00:33:55 2019 UTC ()
Don't dereference pointer when we're about to panic because it's null.

Reported by Dr Silvio Cesare of InfoSect.


(riastradh)
diff -r1.6 -r1.7 src/sys/arch/arm/gemini/gemini_ipi.c

cvs diff -r1.6 -r1.7 src/sys/arch/arm/gemini/gemini_ipi.c (switch to unified diff)

--- src/sys/arch/arm/gemini/gemini_ipi.c 2012/10/27 17:17:38 1.6
+++ src/sys/arch/arm/gemini/gemini_ipi.c 2019/08/30 00:33:55 1.7
@@ -1,237 +1,237 @@ @@ -1,237 +1,237 @@
1#include "opt_gemini.h" 1#include "opt_gemini.h"
2#if !defined(GEMINI_MASTER) && !defined(GEMINI_SLAVE) 2#if !defined(GEMINI_MASTER) && !defined(GEMINI_SLAVE)
3# error IPI needs GEMINI_MASTER or GEMINI_SLAVE 3# error IPI needs GEMINI_MASTER or GEMINI_SLAVE
4#endif 4#endif
5#include "locators.h" 5#include "locators.h"
6#include "geminiipm.h" 6#include "geminiipm.h"
7 7
8#include <sys/cdefs.h> 8#include <sys/cdefs.h>
9 9
10__KERNEL_RCSID(0, "$NetBSD: gemini_ipi.c,v 1.6 2012/10/27 17:17:38 chs Exp $"); 10__KERNEL_RCSID(0, "$NetBSD: gemini_ipi.c,v 1.7 2019/08/30 00:33:55 riastradh Exp $");
11 11
12#include <sys/param.h> 12#include <sys/param.h>
13#include <sys/systm.h> 13#include <sys/systm.h>
14#include <sys/device.h> 14#include <sys/device.h>
15#include <sys/intr.h> 15#include <sys/intr.h>
16#include <sys/malloc.h> 16#include <sys/malloc.h>
17#include <arch/arm/gemini/gemini_obiovar.h> 17#include <arch/arm/gemini/gemini_obiovar.h>
18#include <arch/arm/gemini/gemini_ipivar.h> 18#include <arch/arm/gemini/gemini_ipivar.h>
19#include <arch/arm/gemini/gemini_reg.h> 19#include <arch/arm/gemini/gemini_reg.h>
20 20
21static int gemini_ipi_match(device_t, cfdata_t, void *); 21static int gemini_ipi_match(device_t, cfdata_t, void *);
22static void gemini_ipi_attach(device_t, device_t, void *); 22static void gemini_ipi_attach(device_t, device_t, void *);
23static int gemini_ipiintr(void *); 23static int gemini_ipiintr(void *);
24 24
25CFATTACH_DECL_NEW(geminiipi, sizeof(struct gemini_ipi_softc), 25CFATTACH_DECL_NEW(geminiipi, sizeof(struct gemini_ipi_softc),
26 gemini_ipi_match, gemini_ipi_attach, NULL, NULL); 26 gemini_ipi_match, gemini_ipi_attach, NULL, NULL);
27 27
28static gemini_ipi_softc_t *gemini_ipi_sc; 28static gemini_ipi_softc_t *gemini_ipi_sc;
29 29
30 30
31static int 31static int
32gemini_ipi_match(device_t parent, cfdata_t cf, void *aux) 32gemini_ipi_match(device_t parent, cfdata_t cf, void *aux)
33{ 33{
34 struct obio_attach_args *obio = aux; 34 struct obio_attach_args *obio = aux;
35 35
36 if (obio->obio_intr == LPCCF_INTR_DEFAULT) 36 if (obio->obio_intr == LPCCF_INTR_DEFAULT)
37 panic("ipi must specify intr in config."); 37 panic("ipi must specify intr in config.");
38 38
39 return 1; 39 return 1;
40} 40}
41 41
42static void 42static void
43gemini_ipi_attach(device_t parent, device_t self, void *aux) 43gemini_ipi_attach(device_t parent, device_t self, void *aux)
44{ 44{
45 gemini_ipi_softc_t *sc = device_private(self); 45 gemini_ipi_softc_t *sc = device_private(self);
46 struct obio_attach_args *obio = aux; 46 struct obio_attach_args *obio = aux;
47 bus_space_tag_t iot; 47 bus_space_tag_t iot;
48 bus_space_handle_t ioh; 48 bus_space_handle_t ioh;
49 bus_size_t size; 49 bus_size_t size;
50 bus_addr_t addr; 50 bus_addr_t addr;
51 void *ih; 51 void *ih;
52 52
53 iot = obio->obio_iot; 53 iot = obio->obio_iot;
54 addr = GEMINI_GLOBAL_BASE; 54 addr = GEMINI_GLOBAL_BASE;
55 size = 4096; /* XXX */ 55 size = 4096; /* XXX */
56 56
57 if (bus_space_map(iot, addr, size, 0, &ioh)) 57 if (bus_space_map(iot, addr, size, 0, &ioh))
58 panic("%s: Cannot map registers", device_xname(self)); 58 panic("%s: Cannot map registers", device_xname(self));
59 59
60 /* 60 /*
61 * NOTE: we are using IPL_NET, not IPL_HIGH use of IPI on this system 61 * NOTE: we are using IPL_NET, not IPL_HIGH use of IPI on this system
62 * is (mainly) networking keep simple (for now) and force all IPIs 62 * is (mainly) networking keep simple (for now) and force all IPIs
63 * to same level so splnet() can block them as any other NIC. 63 * to same level so splnet() can block them as any other NIC.
64 */ 64 */
65#if 0 65#if 0
66 ih = intr_establish(obio->obio_intr, IPL_NET, IST_LEVEL_HIGH, 66 ih = intr_establish(obio->obio_intr, IPL_NET, IST_LEVEL_HIGH,
67 gemini_ipiintr, sc); 67 gemini_ipiintr, sc);
68#else 68#else
69 ih = intr_establish(obio->obio_intr, IPL_NET, IST_EDGE_RISING, 69 ih = intr_establish(obio->obio_intr, IPL_NET, IST_EDGE_RISING,
70 gemini_ipiintr, sc); 70 gemini_ipiintr, sc);
71#endif 71#endif
72 if (ih == NULL) 72 if (ih == NULL)
73 panic("%s: Cannot establish interrupt %d\n", 73 panic("%s: Cannot establish interrupt %d\n",
74 device_xname(self), obio->obio_intr); 74 device_xname(self), obio->obio_intr);
75 75
76 SIMPLEQ_INIT(&sc->sc_intrq); 76 SIMPLEQ_INIT(&sc->sc_intrq);
77 77
78 sc->sc_iot = iot; 78 sc->sc_iot = iot;
79 sc->sc_ioh = ioh; 79 sc->sc_ioh = ioh;
80 sc->sc_addr = addr; 80 sc->sc_addr = addr;
81 sc->sc_size = size; 81 sc->sc_size = size;
82 sc->sc_intr = obio->obio_intr; 82 sc->sc_intr = obio->obio_intr;
83 sc->sc_ih = ih; 83 sc->sc_ih = ih;
84 84
85 gemini_ipi_sc = sc; 85 gemini_ipi_sc = sc;
86 86
87 aprint_normal("\n"); 87 aprint_normal("\n");
88 aprint_naive("\n"); 88 aprint_naive("\n");
89 89
90#if NGEMINIIPM > 0 90#if NGEMINIIPM > 0
91 config_found(self, __UNCONST("geminiipm"), NULL); 91 config_found(self, __UNCONST("geminiipm"), NULL);
92#endif 92#endif
93} 93}
94 94
95static inline int 95static inline int
96gemini_ipi_intrq_empty(gemini_ipi_softc_t *sc) 96gemini_ipi_intrq_empty(gemini_ipi_softc_t *sc)
97{ 97{
98 return SIMPLEQ_EMPTY(&sc->sc_intrq); 98 return SIMPLEQ_EMPTY(&sc->sc_intrq);
99} 99}
100 100
101static inline void * 101static inline void *
102gemini_ipi_intrq_insert(gemini_ipi_softc_t *sc, int (*func)(void *), void *arg) 102gemini_ipi_intrq_insert(gemini_ipi_softc_t *sc, int (*func)(void *), void *arg)
103{ 103{
104 gemini_ipi_intrq_t *iqp; 104 gemini_ipi_intrq_t *iqp;
105 105
106 iqp = malloc(sizeof(*iqp), M_DEVBUF, M_NOWAIT|M_ZERO); 106 iqp = malloc(sizeof(*iqp), M_DEVBUF, M_NOWAIT|M_ZERO);
107 if (iqp == NULL) { 107 if (iqp == NULL) {
108 printf("gemini_ipi_intrq_insert: malloc failed\n"); 108 printf("gemini_ipi_intrq_insert: malloc failed\n");
109 return NULL; 109 return NULL;
110 } 110 }
111 111
112 iqp->iq_func = func; 112 iqp->iq_func = func;
113 iqp->iq_arg = arg; 113 iqp->iq_arg = arg;
114 SIMPLEQ_INSERT_TAIL(&sc->sc_intrq, iqp, iq_q); 114 SIMPLEQ_INSERT_TAIL(&sc->sc_intrq, iqp, iq_q);
115 115
116 return (void *)iqp; 116 return (void *)iqp;
117} 117}
118 118
119static inline void 119static inline void
120gemini_ipi_intrq_remove(gemini_ipi_softc_t *sc, void *cookie) 120gemini_ipi_intrq_remove(gemini_ipi_softc_t *sc, void *cookie)
121{ 121{
122 gemini_ipi_intrq_t *iqp; 122 gemini_ipi_intrq_t *iqp;
123 123
124 SIMPLEQ_FOREACH(iqp, &sc->sc_intrq, iq_q) { 124 SIMPLEQ_FOREACH(iqp, &sc->sc_intrq, iq_q) {
125 if ((void *)iqp == cookie) { 125 if ((void *)iqp == cookie) {
126 SIMPLEQ_REMOVE(&sc->sc_intrq, 126 SIMPLEQ_REMOVE(&sc->sc_intrq,
127 iqp, gemini_ipi_intrq, iq_q); 127 iqp, gemini_ipi_intrq, iq_q);
128 free(iqp, M_DEVBUF); 128 free(iqp, M_DEVBUF);
129 return; 129 return;
130 } 130 }
131 } 131 }
132} 132}
133 133
134static inline int 134static inline int
135gemini_ipi_intrq_dispatch(gemini_ipi_softc_t *sc) 135gemini_ipi_intrq_dispatch(gemini_ipi_softc_t *sc)
136{ 136{
137 gemini_ipi_intrq_t *iqp; 137 gemini_ipi_intrq_t *iqp;
138 int rv = 0; 138 int rv = 0;
139 139
140 SIMPLEQ_FOREACH(iqp, &sc->sc_intrq, iq_q) 140 SIMPLEQ_FOREACH(iqp, &sc->sc_intrq, iq_q)
141 rv |= (*iqp->iq_func)(iqp->iq_arg); 141 rv |= (*iqp->iq_func)(iqp->iq_arg);
142 142
143 return (rv != 0); 143 return (rv != 0);
144} 144}
145 145
146 146
147void * 147void *
148ipi_intr_establish(int (*func)(void *), void *arg) 148ipi_intr_establish(int (*func)(void *), void *arg)
149{ 149{
150 gemini_ipi_softc_t *sc = gemini_ipi_sc; 150 gemini_ipi_softc_t *sc = gemini_ipi_sc;
151 void *ih; 151 void *ih;
152 152
153 if (sc == NULL) 153 if (sc == NULL)
154 return NULL; 154 return NULL;
155 155
156 ih = gemini_ipi_intrq_insert(sc, func, arg); 156 ih = gemini_ipi_intrq_insert(sc, func, arg);
157#ifdef DEBUG 157#ifdef DEBUG
158 if (ih == NULL) 158 if (ih == NULL)
159 panic("%s: gemini_ipi_intrq_insert failed", 159 panic("%s: gemini_ipi_intrq_insert failed",
160 device_xname(sc->sc_dev)); 160 device_xname(sc->sc_dev));
161#endif 161#endif
162 162
163 return ih; 163 return ih;
164} 164}
165 165
166void 166void
167ipi_intr_disestablish(void *ih) 167ipi_intr_disestablish(void *ih)
168{ 168{
169 gemini_ipi_softc_t *sc = gemini_ipi_sc; 169 gemini_ipi_softc_t *sc = gemini_ipi_sc;
170 170
171 if (sc == NULL) 171 if (sc == NULL)
172 panic("%s: NULL gemini_ipi_sc", device_xname(sc->sc_dev)); 172 panic("NULL gemini_ipi_sc");
173 173
174 gemini_ipi_intrq_remove(sc, ih); 174 gemini_ipi_intrq_remove(sc, ih);
175} 175}
176 176
177int 177int
178ipi_send(void) 178ipi_send(void)
179{ 179{
180 gemini_ipi_softc_t *sc = gemini_ipi_sc; 180 gemini_ipi_softc_t *sc = gemini_ipi_sc;
181 uint32_t r; 181 uint32_t r;
182 uint32_t bit; 182 uint32_t bit;
183 bus_addr_t off; 183 bus_addr_t off;
184 184
185 if (sc == NULL) 185 if (sc == NULL)
186 return -1; 186 return -1;
187 187
188#if defined(GEMINI_MASTER) 188#if defined(GEMINI_MASTER)
189 off = GEMINI_GLOBAL_CPU0; 189 off = GEMINI_GLOBAL_CPU0;
190 bit = GLOBAL_CPU0_IPICPU1; 190 bit = GLOBAL_CPU0_IPICPU1;
191#elif defined(GEMINI_SLAVE) 191#elif defined(GEMINI_SLAVE)
192 off = GEMINI_GLOBAL_CPU1; 192 off = GEMINI_GLOBAL_CPU1;
193 bit = GLOBAL_CPU1_IPICPU0; 193 bit = GLOBAL_CPU1_IPICPU0;
194#endif 194#endif
195 195
196 r = bus_space_read_4(sc->sc_iot, sc->sc_ioh, off); 196 r = bus_space_read_4(sc->sc_iot, sc->sc_ioh, off);
197 r |= bit; 197 r |= bit;
198 bus_space_write_4(sc->sc_iot, sc->sc_ioh, off, r); 198 bus_space_write_4(sc->sc_iot, sc->sc_ioh, off, r);
199 199
200 return 0; 200 return 0;
201} 201}
202 202
203static inline void 203static inline void
204ipi_ack(gemini_ipi_softc_t *sc) 204ipi_ack(gemini_ipi_softc_t *sc)
205{ 205{
206 uint32_t r; 206 uint32_t r;
207 uint32_t bit; 207 uint32_t bit;
208 bus_addr_t off; 208 bus_addr_t off;
209 209
210#if defined(GEMINI_MASTER) 210#if defined(GEMINI_MASTER)
211 off = GEMINI_GLOBAL_CPU1; 211 off = GEMINI_GLOBAL_CPU1;
212 bit = GLOBAL_CPU1_IPICPU0; 212 bit = GLOBAL_CPU1_IPICPU0;
213#elif defined(GEMINI_SLAVE)  213#elif defined(GEMINI_SLAVE)
214 off = GEMINI_GLOBAL_CPU0; 214 off = GEMINI_GLOBAL_CPU0;
215 bit = GLOBAL_CPU0_IPICPU1; 215 bit = GLOBAL_CPU0_IPICPU1;
216#endif 216#endif
217 217
218 r = bus_space_read_4(sc->sc_iot, sc->sc_ioh, off); 218 r = bus_space_read_4(sc->sc_iot, sc->sc_ioh, off);
219 r &= ~bit; 219 r &= ~bit;
220 bus_space_write_4(sc->sc_iot, sc->sc_ioh, off, r); 220 bus_space_write_4(sc->sc_iot, sc->sc_ioh, off, r);
221} 221}
222 222
223static int 223static int
224gemini_ipiintr(void *arg) 224gemini_ipiintr(void *arg)
225{ 225{
226 gemini_ipi_softc_t *sc = arg; 226 gemini_ipi_softc_t *sc = arg;
227 int rv; 227 int rv;
228 228
229 if (sc == NULL) 229 if (sc == NULL)
230 return -1; 230 return -1;
231 231
232 ipi_ack(sc); 232 ipi_ack(sc);
233 233
234 rv = gemini_ipi_intrq_dispatch(sc); 234 rv = gemini_ipi_intrq_dispatch(sc);
235 235
236 return rv; 236 return rv;
237} 237}