Branch data Line data Source code
1 : : #include <linux/kdebug.h>
2 : : #include <linux/kprobes.h>
3 : : #include <linux/export.h>
4 : : #include <linux/notifier.h>
5 : : #include <linux/rcupdate.h>
6 : : #include <linux/vmalloc.h>
7 : : #include <linux/reboot.h>
8 : :
9 : : /*
10 : : * Notifier list for kernel code which wants to be called
11 : : * at shutdown. This is used to stop any idling DMA operations
12 : : * and the like.
13 : : */
14 : : BLOCKING_NOTIFIER_HEAD(reboot_notifier_list);
15 : :
16 : : /*
17 : : * Notifier chain core routines. The exported routines below
18 : : * are layered on top of these, with appropriate locking added.
19 : : */
20 : :
21 : : static int notifier_chain_register(struct notifier_block **nl,
22 : : struct notifier_block *n)
23 : : {
24 [ # # ][ # # ]: 0 : while ((*nl) != NULL) {
[ # # ][ # # ]
[ # # ][ # # ]
25 [ # # ][ # # ]: 0 : if (n->priority > (*nl)->priority)
[ # # ][ # # ]
[ # # ][ # # ]
26 : : break;
27 : 0 : nl = &((*nl)->next);
28 : : }
29 : 0 : n->next = *nl;
30 : 0 : rcu_assign_pointer(*nl, n);
31 : : return 0;
32 : : }
33 : :
34 : : static int notifier_chain_cond_register(struct notifier_block **nl,
35 : : struct notifier_block *n)
36 : : {
37 [ # # ]: 0 : while ((*nl) != NULL) {
38 [ # # ]: 0 : if ((*nl) == n)
39 : : return 0;
40 [ # # ]: 0 : if (n->priority > (*nl)->priority)
41 : : break;
42 : 0 : nl = &((*nl)->next);
43 : : }
44 : 0 : n->next = *nl;
45 : 0 : rcu_assign_pointer(*nl, n);
46 : : return 0;
47 : : }
48 : :
49 : : static int notifier_chain_unregister(struct notifier_block **nl,
50 : : struct notifier_block *n)
51 : : {
52 [ # # ][ # # ]: 0 : while ((*nl) != NULL) {
[ # # ][ # # ]
[ # # ][ # # ]
53 [ # # ][ # # ]: 0 : if ((*nl) == n) {
[ # # ][ # # ]
[ # # ][ # # ]
54 : 0 : rcu_assign_pointer(*nl, n->next);
55 : : return 0;
56 : : }
57 : 0 : nl = &((*nl)->next);
58 : : }
59 : : return -ENOENT;
60 : : }
61 : :
62 : : /**
63 : : * notifier_call_chain - Informs the registered notifiers about an event.
64 : : * @nl: Pointer to head of the blocking notifier chain
65 : : * @val: Value passed unmodified to notifier function
66 : : * @v: Pointer passed unmodified to notifier function
67 : : * @nr_to_call: Number of notifier functions to be called. Don't care
68 : : * value of this parameter is -1.
69 : : * @nr_calls: Records the number of notifications sent. Don't care
70 : : * value of this field is NULL.
71 : : * @returns: notifier_call_chain returns the value returned by the
72 : : * last notifier function called.
73 : : */
74 : 0 : static int __kprobes notifier_call_chain(struct notifier_block **nl,
75 : : unsigned long val, void *v,
76 : : int nr_to_call, int *nr_calls)
77 : : {
78 : : int ret = NOTIFY_DONE;
79 : : struct notifier_block *nb, *next_nb;
80 : :
81 : 46203168 : nb = rcu_dereference_raw(*nl);
82 : :
83 [ + + ]: 80710070 : while (nb && nr_to_call) {
84 : 34824074 : next_nb = rcu_dereference_raw(nb->next);
85 : :
86 : : #ifdef CONFIG_DEBUG_NOTIFIERS
87 : : if (unlikely(!func_ptr_is_kernel_text(nb->notifier_call))) {
88 : : WARN(1, "Invalid notifier called!");
89 : : nb = next_nb;
90 : : continue;
91 : : }
92 : : #endif
93 : 34824074 : ret = nb->notifier_call(nb, val, v);
94 : :
95 [ + + ]: 34595701 : if (nr_calls)
96 : 6000181 : (*nr_calls)++;
97 : :
98 [ + ]: 34595701 : if ((ret & NOTIFY_STOP_MASK) == NOTIFY_STOP_MASK)
99 : : break;
100 : : nb = next_nb;
101 : 34506902 : nr_to_call--;
102 : : }
103 : 0 : return ret;
104 : : }
105 : :
106 : : /*
107 : : * Atomic notifier chain routines. Registration and unregistration
108 : : * use a spinlock, and call_chain is synchronized by RCU (no locks).
109 : : */
110 : :
111 : : /**
112 : : * atomic_notifier_chain_register - Add notifier to an atomic notifier chain
113 : : * @nh: Pointer to head of the atomic notifier chain
114 : : * @n: New entry in notifier chain
115 : : *
116 : : * Adds a notifier to an atomic notifier chain.
117 : : *
118 : : * Currently always returns zero.
119 : : */
120 : 0 : int atomic_notifier_chain_register(struct atomic_notifier_head *nh,
121 : : struct notifier_block *n)
122 : : {
123 : : unsigned long flags;
124 : : int ret;
125 : :
126 : 0 : spin_lock_irqsave(&nh->lock, flags);
127 : 0 : ret = notifier_chain_register(&nh->head, n);
128 : : spin_unlock_irqrestore(&nh->lock, flags);
129 : 0 : return ret;
130 : : }
131 : : EXPORT_SYMBOL_GPL(atomic_notifier_chain_register);
132 : :
133 : : /**
134 : : * atomic_notifier_chain_unregister - Remove notifier from an atomic notifier chain
135 : : * @nh: Pointer to head of the atomic notifier chain
136 : : * @n: Entry to remove from notifier chain
137 : : *
138 : : * Removes a notifier from an atomic notifier chain.
139 : : *
140 : : * Returns zero on success or %-ENOENT on failure.
141 : : */
142 : 0 : int atomic_notifier_chain_unregister(struct atomic_notifier_head *nh,
143 : : struct notifier_block *n)
144 : : {
145 : : unsigned long flags;
146 : : int ret;
147 : :
148 : 0 : spin_lock_irqsave(&nh->lock, flags);
149 : 0 : ret = notifier_chain_unregister(&nh->head, n);
150 : : spin_unlock_irqrestore(&nh->lock, flags);
151 : : synchronize_rcu();
152 : 0 : return ret;
153 : : }
154 : : EXPORT_SYMBOL_GPL(atomic_notifier_chain_unregister);
155 : :
156 : : /**
157 : : * __atomic_notifier_call_chain - Call functions in an atomic notifier chain
158 : : * @nh: Pointer to head of the atomic notifier chain
159 : : * @val: Value passed unmodified to notifier function
160 : : * @v: Pointer passed unmodified to notifier function
161 : : * @nr_to_call: See the comment for notifier_call_chain.
162 : : * @nr_calls: See the comment for notifier_call_chain.
163 : : *
164 : : * Calls each function in a notifier chain in turn. The functions
165 : : * run in an atomic context, so they must not block.
166 : : * This routine uses RCU to synchronize with changes to the chain.
167 : : *
168 : : * If the return value of the notifier can be and'ed
169 : : * with %NOTIFY_STOP_MASK then atomic_notifier_call_chain()
170 : : * will return immediately, with the return value of
171 : : * the notifier function which halted execution.
172 : : * Otherwise the return value is the return value
173 : : * of the last notifier function called.
174 : : */
175 : 0 : int __kprobes __atomic_notifier_call_chain(struct atomic_notifier_head *nh,
176 : : unsigned long val, void *v,
177 : : int nr_to_call, int *nr_calls)
178 : : {
179 : : int ret;
180 : :
181 : : rcu_read_lock();
182 : 36519247 : ret = notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls);
183 : : rcu_read_unlock();
184 : 0 : return ret;
185 : : }
186 : : EXPORT_SYMBOL_GPL(__atomic_notifier_call_chain);
187 : :
188 : 0 : int __kprobes atomic_notifier_call_chain(struct atomic_notifier_head *nh,
189 : : unsigned long val, void *v)
190 : : {
191 : 36514303 : return __atomic_notifier_call_chain(nh, val, v, -1, NULL);
192 : : }
193 : : EXPORT_SYMBOL_GPL(atomic_notifier_call_chain);
194 : :
195 : : /*
196 : : * Blocking notifier chain routines. All access to the chain is
197 : : * synchronized by an rwsem.
198 : : */
199 : :
200 : : /**
201 : : * blocking_notifier_chain_register - Add notifier to a blocking notifier chain
202 : : * @nh: Pointer to head of the blocking notifier chain
203 : : * @n: New entry in notifier chain
204 : : *
205 : : * Adds a notifier to a blocking notifier chain.
206 : : * Must be called in process context.
207 : : *
208 : : * Currently always returns zero.
209 : : */
210 : 0 : int blocking_notifier_chain_register(struct blocking_notifier_head *nh,
211 : : struct notifier_block *n)
212 : : {
213 : : int ret;
214 : :
215 : : /*
216 : : * This code gets used during boot-up, when task switching is
217 : : * not yet working and interrupts must remain disabled. At
218 : : * such times we must not call down_write().
219 : : */
220 [ # # ]: 0 : if (unlikely(system_state == SYSTEM_BOOTING))
221 : 0 : return notifier_chain_register(&nh->head, n);
222 : :
223 : 0 : down_write(&nh->rwsem);
224 : 0 : ret = notifier_chain_register(&nh->head, n);
225 : 0 : up_write(&nh->rwsem);
226 : 0 : return ret;
227 : : }
228 : : EXPORT_SYMBOL_GPL(blocking_notifier_chain_register);
229 : :
230 : : /**
231 : : * blocking_notifier_chain_cond_register - Cond add notifier to a blocking notifier chain
232 : : * @nh: Pointer to head of the blocking notifier chain
233 : : * @n: New entry in notifier chain
234 : : *
235 : : * Adds a notifier to a blocking notifier chain, only if not already
236 : : * present in the chain.
237 : : * Must be called in process context.
238 : : *
239 : : * Currently always returns zero.
240 : : */
241 : 0 : int blocking_notifier_chain_cond_register(struct blocking_notifier_head *nh,
242 : : struct notifier_block *n)
243 : : {
244 : : int ret;
245 : :
246 : 0 : down_write(&nh->rwsem);
247 : 0 : ret = notifier_chain_cond_register(&nh->head, n);
248 : 0 : up_write(&nh->rwsem);
249 : 0 : return ret;
250 : : }
251 : : EXPORT_SYMBOL_GPL(blocking_notifier_chain_cond_register);
252 : :
253 : : /**
254 : : * blocking_notifier_chain_unregister - Remove notifier from a blocking notifier chain
255 : : * @nh: Pointer to head of the blocking notifier chain
256 : : * @n: Entry to remove from notifier chain
257 : : *
258 : : * Removes a notifier from a blocking notifier chain.
259 : : * Must be called from process context.
260 : : *
261 : : * Returns zero on success or %-ENOENT on failure.
262 : : */
263 : 0 : int blocking_notifier_chain_unregister(struct blocking_notifier_head *nh,
264 : : struct notifier_block *n)
265 : : {
266 : : int ret;
267 : :
268 : : /*
269 : : * This code gets used during boot-up, when task switching is
270 : : * not yet working and interrupts must remain disabled. At
271 : : * such times we must not call down_write().
272 : : */
273 [ # # ]: 0 : if (unlikely(system_state == SYSTEM_BOOTING))
274 : 0 : return notifier_chain_unregister(&nh->head, n);
275 : :
276 : 0 : down_write(&nh->rwsem);
277 : 0 : ret = notifier_chain_unregister(&nh->head, n);
278 : 0 : up_write(&nh->rwsem);
279 : 0 : return ret;
280 : : }
281 : : EXPORT_SYMBOL_GPL(blocking_notifier_chain_unregister);
282 : :
283 : : /**
284 : : * __blocking_notifier_call_chain - Call functions in a blocking notifier chain
285 : : * @nh: Pointer to head of the blocking notifier chain
286 : : * @val: Value passed unmodified to notifier function
287 : : * @v: Pointer passed unmodified to notifier function
288 : : * @nr_to_call: See comment for notifier_call_chain.
289 : : * @nr_calls: See comment for notifier_call_chain.
290 : : *
291 : : * Calls each function in a notifier chain in turn. The functions
292 : : * run in a process context, so they are allowed to block.
293 : : *
294 : : * If the return value of the notifier can be and'ed
295 : : * with %NOTIFY_STOP_MASK then blocking_notifier_call_chain()
296 : : * will return immediately, with the return value of
297 : : * the notifier function which halted execution.
298 : : * Otherwise the return value is the return value
299 : : * of the last notifier function called.
300 : : */
301 : 0 : int __blocking_notifier_call_chain(struct blocking_notifier_head *nh,
302 : : unsigned long val, void *v,
303 : : int nr_to_call, int *nr_calls)
304 : : {
305 : : int ret = NOTIFY_DONE;
306 : :
307 : : /*
308 : : * We check the head outside the lock, but if this access is
309 : : * racy then it does not matter what the result of the test
310 : : * is, we re-check the list after having taken the lock anyway:
311 : : */
312 [ - + ]: 1625808 : if (rcu_dereference_raw(nh->head)) {
313 : 0 : down_read(&nh->rwsem);
314 : 0 : ret = notifier_call_chain(&nh->head, val, v, nr_to_call,
315 : : nr_calls);
316 : 0 : up_read(&nh->rwsem);
317 : : }
318 : 0 : return ret;
319 : : }
320 : : EXPORT_SYMBOL_GPL(__blocking_notifier_call_chain);
321 : :
322 : 0 : int blocking_notifier_call_chain(struct blocking_notifier_head *nh,
323 : : unsigned long val, void *v)
324 : : {
325 : 1625803 : return __blocking_notifier_call_chain(nh, val, v, -1, NULL);
326 : : }
327 : : EXPORT_SYMBOL_GPL(blocking_notifier_call_chain);
328 : :
329 : : /*
330 : : * Raw notifier chain routines. There is no protection;
331 : : * the caller must provide it. Use at your own risk!
332 : : */
333 : :
334 : : /**
335 : : * raw_notifier_chain_register - Add notifier to a raw notifier chain
336 : : * @nh: Pointer to head of the raw notifier chain
337 : : * @n: New entry in notifier chain
338 : : *
339 : : * Adds a notifier to a raw notifier chain.
340 : : * All locking must be provided by the caller.
341 : : *
342 : : * Currently always returns zero.
343 : : */
344 : 0 : int raw_notifier_chain_register(struct raw_notifier_head *nh,
345 : : struct notifier_block *n)
346 : : {
347 : 0 : return notifier_chain_register(&nh->head, n);
348 : : }
349 : : EXPORT_SYMBOL_GPL(raw_notifier_chain_register);
350 : :
351 : : /**
352 : : * raw_notifier_chain_unregister - Remove notifier from a raw notifier chain
353 : : * @nh: Pointer to head of the raw notifier chain
354 : : * @n: Entry to remove from notifier chain
355 : : *
356 : : * Removes a notifier from a raw notifier chain.
357 : : * All locking must be provided by the caller.
358 : : *
359 : : * Returns zero on success or %-ENOENT on failure.
360 : : */
361 : 0 : int raw_notifier_chain_unregister(struct raw_notifier_head *nh,
362 : : struct notifier_block *n)
363 : : {
364 : 0 : return notifier_chain_unregister(&nh->head, n);
365 : : }
366 : : EXPORT_SYMBOL_GPL(raw_notifier_chain_unregister);
367 : :
368 : : /**
369 : : * __raw_notifier_call_chain - Call functions in a raw notifier chain
370 : : * @nh: Pointer to head of the raw notifier chain
371 : : * @val: Value passed unmodified to notifier function
372 : : * @v: Pointer passed unmodified to notifier function
373 : : * @nr_to_call: See comment for notifier_call_chain.
374 : : * @nr_calls: See comment for notifier_call_chain
375 : : *
376 : : * Calls each function in a notifier chain in turn. The functions
377 : : * run in an undefined context.
378 : : * All locking must be provided by the caller.
379 : : *
380 : : * If the return value of the notifier can be and'ed
381 : : * with %NOTIFY_STOP_MASK then raw_notifier_call_chain()
382 : : * will return immediately, with the return value of
383 : : * the notifier function which halted execution.
384 : : * Otherwise the return value is the return value
385 : : * of the last notifier function called.
386 : : */
387 : 0 : int __raw_notifier_call_chain(struct raw_notifier_head *nh,
388 : : unsigned long val, void *v,
389 : : int nr_to_call, int *nr_calls)
390 : : {
391 : 9661176 : return notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls);
392 : : }
393 : : EXPORT_SYMBOL_GPL(__raw_notifier_call_chain);
394 : :
395 : 0 : int raw_notifier_call_chain(struct raw_notifier_head *nh,
396 : : unsigned long val, void *v)
397 : : {
398 : 7261173 : return __raw_notifier_call_chain(nh, val, v, -1, NULL);
399 : : }
400 : : EXPORT_SYMBOL_GPL(raw_notifier_call_chain);
401 : :
402 : : /*
403 : : * SRCU notifier chain routines. Registration and unregistration
404 : : * use a mutex, and call_chain is synchronized by SRCU (no locks).
405 : : */
406 : :
407 : : /**
408 : : * srcu_notifier_chain_register - Add notifier to an SRCU notifier chain
409 : : * @nh: Pointer to head of the SRCU notifier chain
410 : : * @n: New entry in notifier chain
411 : : *
412 : : * Adds a notifier to an SRCU notifier chain.
413 : : * Must be called in process context.
414 : : *
415 : : * Currently always returns zero.
416 : : */
417 : 0 : int srcu_notifier_chain_register(struct srcu_notifier_head *nh,
418 : : struct notifier_block *n)
419 : : {
420 : : int ret;
421 : :
422 : : /*
423 : : * This code gets used during boot-up, when task switching is
424 : : * not yet working and interrupts must remain disabled. At
425 : : * such times we must not call mutex_lock().
426 : : */
427 [ # # ]: 0 : if (unlikely(system_state == SYSTEM_BOOTING))
428 : 0 : return notifier_chain_register(&nh->head, n);
429 : :
430 : 0 : mutex_lock(&nh->mutex);
431 : 0 : ret = notifier_chain_register(&nh->head, n);
432 : 0 : mutex_unlock(&nh->mutex);
433 : 0 : return ret;
434 : : }
435 : : EXPORT_SYMBOL_GPL(srcu_notifier_chain_register);
436 : :
437 : : /**
438 : : * srcu_notifier_chain_unregister - Remove notifier from an SRCU notifier chain
439 : : * @nh: Pointer to head of the SRCU notifier chain
440 : : * @n: Entry to remove from notifier chain
441 : : *
442 : : * Removes a notifier from an SRCU notifier chain.
443 : : * Must be called from process context.
444 : : *
445 : : * Returns zero on success or %-ENOENT on failure.
446 : : */
447 : 0 : int srcu_notifier_chain_unregister(struct srcu_notifier_head *nh,
448 : : struct notifier_block *n)
449 : : {
450 : : int ret;
451 : :
452 : : /*
453 : : * This code gets used during boot-up, when task switching is
454 : : * not yet working and interrupts must remain disabled. At
455 : : * such times we must not call mutex_lock().
456 : : */
457 [ # # ]: 0 : if (unlikely(system_state == SYSTEM_BOOTING))
458 : 0 : return notifier_chain_unregister(&nh->head, n);
459 : :
460 : 0 : mutex_lock(&nh->mutex);
461 : 0 : ret = notifier_chain_unregister(&nh->head, n);
462 : 0 : mutex_unlock(&nh->mutex);
463 : 0 : synchronize_srcu(&nh->srcu);
464 : 0 : return ret;
465 : : }
466 : : EXPORT_SYMBOL_GPL(srcu_notifier_chain_unregister);
467 : :
468 : : /**
469 : : * __srcu_notifier_call_chain - Call functions in an SRCU notifier chain
470 : : * @nh: Pointer to head of the SRCU notifier chain
471 : : * @val: Value passed unmodified to notifier function
472 : : * @v: Pointer passed unmodified to notifier function
473 : : * @nr_to_call: See comment for notifier_call_chain.
474 : : * @nr_calls: See comment for notifier_call_chain
475 : : *
476 : : * Calls each function in a notifier chain in turn. The functions
477 : : * run in a process context, so they are allowed to block.
478 : : *
479 : : * If the return value of the notifier can be and'ed
480 : : * with %NOTIFY_STOP_MASK then srcu_notifier_call_chain()
481 : : * will return immediately, with the return value of
482 : : * the notifier function which halted execution.
483 : : * Otherwise the return value is the return value
484 : : * of the last notifier function called.
485 : : */
486 : 0 : int __srcu_notifier_call_chain(struct srcu_notifier_head *nh,
487 : : unsigned long val, void *v,
488 : : int nr_to_call, int *nr_calls)
489 : : {
490 : : int ret;
491 : : int idx;
492 : :
493 : 25870 : idx = srcu_read_lock(&nh->srcu);
494 : 25874 : ret = notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls);
495 : : srcu_read_unlock(&nh->srcu, idx);
496 : 25870 : return ret;
497 : : }
498 : : EXPORT_SYMBOL_GPL(__srcu_notifier_call_chain);
499 : :
500 : 0 : int srcu_notifier_call_chain(struct srcu_notifier_head *nh,
501 : : unsigned long val, void *v)
502 : : {
503 : 25880 : return __srcu_notifier_call_chain(nh, val, v, -1, NULL);
504 : : }
505 : : EXPORT_SYMBOL_GPL(srcu_notifier_call_chain);
506 : :
507 : : /**
508 : : * srcu_init_notifier_head - Initialize an SRCU notifier head
509 : : * @nh: Pointer to head of the srcu notifier chain
510 : : *
511 : : * Unlike other sorts of notifier heads, SRCU notifier heads require
512 : : * dynamic initialization. Be sure to call this routine before
513 : : * calling any of the other SRCU notifier routines for this head.
514 : : *
515 : : * If an SRCU notifier head is deallocated, it must first be cleaned
516 : : * up by calling srcu_cleanup_notifier_head(). Otherwise the head's
517 : : * per-cpu data (used by the SRCU mechanism) will leak.
518 : : */
519 : 0 : void srcu_init_notifier_head(struct srcu_notifier_head *nh)
520 : : {
521 : 0 : mutex_init(&nh->mutex);
522 [ # # ]: 0 : if (init_srcu_struct(&nh->srcu) < 0)
523 : 0 : BUG();
524 : 0 : nh->head = NULL;
525 : 0 : }
526 : : EXPORT_SYMBOL_GPL(srcu_init_notifier_head);
527 : :
528 : : static ATOMIC_NOTIFIER_HEAD(die_chain);
529 : :
530 : 0 : int notrace __kprobes notify_die(enum die_val val, const char *str,
531 : : struct pt_regs *regs, long err, int trap, int sig)
532 : : {
533 : 0 : struct die_args args = {
534 : : .regs = regs,
535 : : .str = str,
536 : : .err = err,
537 : : .trapnr = trap,
538 : : .signr = sig,
539 : :
540 : : };
541 : 0 : return atomic_notifier_call_chain(&die_chain, val, &args);
542 : : }
543 : :
544 : 0 : int register_die_notifier(struct notifier_block *nb)
545 : : {
546 : 0 : vmalloc_sync_all();
547 : 0 : return atomic_notifier_chain_register(&die_chain, nb);
548 : : }
549 : : EXPORT_SYMBOL_GPL(register_die_notifier);
550 : :
551 : 0 : int unregister_die_notifier(struct notifier_block *nb)
552 : : {
553 : 0 : return atomic_notifier_chain_unregister(&die_chain, nb);
554 : : }
555 : : EXPORT_SYMBOL_GPL(unregister_die_notifier);
|