Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 #include <linux/kdebug.h>
0003 #include <linux/kprobes.h>
0004 #include <linux/export.h>
0005 #include <linux/notifier.h>
0006 #include <linux/rcupdate.h>
0007 #include <linux/vmalloc.h>
0008 #include <linux/reboot.h>
0009 
0010 /*
0011  *  Notifier list for kernel code which wants to be called
0012  *  at shutdown. This is used to stop any idling DMA operations
0013  *  and the like.
0014  */
0015 BLOCKING_NOTIFIER_HEAD(reboot_notifier_list);
0016 
0017 /*
0018  *  Notifier chain core routines.  The exported routines below
0019  *  are layered on top of these, with appropriate locking added.
0020  */
0021 
0022 static int notifier_chain_register(struct notifier_block **nl,
0023                    struct notifier_block *n,
0024                    bool unique_priority)
0025 {
0026     while ((*nl) != NULL) {
0027         if (unlikely((*nl) == n)) {
0028             WARN(1, "notifier callback %ps already registered",
0029                  n->notifier_call);
0030             return -EEXIST;
0031         }
0032         if (n->priority > (*nl)->priority)
0033             break;
0034         if (n->priority == (*nl)->priority && unique_priority)
0035             return -EBUSY;
0036         nl = &((*nl)->next);
0037     }
0038     n->next = *nl;
0039     rcu_assign_pointer(*nl, n);
0040     return 0;
0041 }
0042 
0043 static int notifier_chain_unregister(struct notifier_block **nl,
0044         struct notifier_block *n)
0045 {
0046     while ((*nl) != NULL) {
0047         if ((*nl) == n) {
0048             rcu_assign_pointer(*nl, n->next);
0049             return 0;
0050         }
0051         nl = &((*nl)->next);
0052     }
0053     return -ENOENT;
0054 }
0055 
0056 /**
0057  * notifier_call_chain - Informs the registered notifiers about an event.
0058  *  @nl:        Pointer to head of the blocking notifier chain
0059  *  @val:       Value passed unmodified to notifier function
0060  *  @v:     Pointer passed unmodified to notifier function
0061  *  @nr_to_call:    Number of notifier functions to be called. Don't care
0062  *          value of this parameter is -1.
0063  *  @nr_calls:  Records the number of notifications sent. Don't care
0064  *          value of this field is NULL.
0065  *  @returns:   notifier_call_chain returns the value returned by the
0066  *          last notifier function called.
0067  */
0068 static int notifier_call_chain(struct notifier_block **nl,
0069                    unsigned long val, void *v,
0070                    int nr_to_call, int *nr_calls)
0071 {
0072     int ret = NOTIFY_DONE;
0073     struct notifier_block *nb, *next_nb;
0074 
0075     nb = rcu_dereference_raw(*nl);
0076 
0077     while (nb && nr_to_call) {
0078         next_nb = rcu_dereference_raw(nb->next);
0079 
0080 #ifdef CONFIG_DEBUG_NOTIFIERS
0081         if (unlikely(!func_ptr_is_kernel_text(nb->notifier_call))) {
0082             WARN(1, "Invalid notifier called!");
0083             nb = next_nb;
0084             continue;
0085         }
0086 #endif
0087         ret = nb->notifier_call(nb, val, v);
0088 
0089         if (nr_calls)
0090             (*nr_calls)++;
0091 
0092         if (ret & NOTIFY_STOP_MASK)
0093             break;
0094         nb = next_nb;
0095         nr_to_call--;
0096     }
0097     return ret;
0098 }
0099 NOKPROBE_SYMBOL(notifier_call_chain);
0100 
0101 /**
0102  * notifier_call_chain_robust - Inform the registered notifiers about an event
0103  *                              and rollback on error.
0104  * @nl:     Pointer to head of the blocking notifier chain
0105  * @val_up: Value passed unmodified to the notifier function
0106  * @val_down:   Value passed unmodified to the notifier function when recovering
0107  *              from an error on @val_up
0108  * @v       Pointer passed unmodified to the notifier function
0109  *
0110  * NOTE:    It is important the @nl chain doesn't change between the two
0111  *      invocations of notifier_call_chain() such that we visit the
0112  *      exact same notifier callbacks; this rules out any RCU usage.
0113  *
0114  * Returns: the return value of the @val_up call.
0115  */
0116 static int notifier_call_chain_robust(struct notifier_block **nl,
0117                      unsigned long val_up, unsigned long val_down,
0118                      void *v)
0119 {
0120     int ret, nr = 0;
0121 
0122     ret = notifier_call_chain(nl, val_up, v, -1, &nr);
0123     if (ret & NOTIFY_STOP_MASK)
0124         notifier_call_chain(nl, val_down, v, nr-1, NULL);
0125 
0126     return ret;
0127 }
0128 
0129 /*
0130  *  Atomic notifier chain routines.  Registration and unregistration
0131  *  use a spinlock, and call_chain is synchronized by RCU (no locks).
0132  */
0133 
0134 /**
0135  *  atomic_notifier_chain_register - Add notifier to an atomic notifier chain
0136  *  @nh: Pointer to head of the atomic notifier chain
0137  *  @n: New entry in notifier chain
0138  *
0139  *  Adds a notifier to an atomic notifier chain.
0140  *
0141  *  Returns 0 on success, %-EEXIST on error.
0142  */
0143 int atomic_notifier_chain_register(struct atomic_notifier_head *nh,
0144         struct notifier_block *n)
0145 {
0146     unsigned long flags;
0147     int ret;
0148 
0149     spin_lock_irqsave(&nh->lock, flags);
0150     ret = notifier_chain_register(&nh->head, n, false);
0151     spin_unlock_irqrestore(&nh->lock, flags);
0152     return ret;
0153 }
0154 EXPORT_SYMBOL_GPL(atomic_notifier_chain_register);
0155 
0156 /**
0157  *  atomic_notifier_chain_register_unique_prio - Add notifier to an atomic notifier chain
0158  *  @nh: Pointer to head of the atomic notifier chain
0159  *  @n: New entry in notifier chain
0160  *
0161  *  Adds a notifier to an atomic notifier chain if there is no other
0162  *  notifier registered using the same priority.
0163  *
0164  *  Returns 0 on success, %-EEXIST or %-EBUSY on error.
0165  */
0166 int atomic_notifier_chain_register_unique_prio(struct atomic_notifier_head *nh,
0167                            struct notifier_block *n)
0168 {
0169     unsigned long flags;
0170     int ret;
0171 
0172     spin_lock_irqsave(&nh->lock, flags);
0173     ret = notifier_chain_register(&nh->head, n, true);
0174     spin_unlock_irqrestore(&nh->lock, flags);
0175     return ret;
0176 }
0177 EXPORT_SYMBOL_GPL(atomic_notifier_chain_register_unique_prio);
0178 
0179 /**
0180  *  atomic_notifier_chain_unregister - Remove notifier from an atomic notifier chain
0181  *  @nh: Pointer to head of the atomic notifier chain
0182  *  @n: Entry to remove from notifier chain
0183  *
0184  *  Removes a notifier from an atomic notifier chain.
0185  *
0186  *  Returns zero on success or %-ENOENT on failure.
0187  */
0188 int atomic_notifier_chain_unregister(struct atomic_notifier_head *nh,
0189         struct notifier_block *n)
0190 {
0191     unsigned long flags;
0192     int ret;
0193 
0194     spin_lock_irqsave(&nh->lock, flags);
0195     ret = notifier_chain_unregister(&nh->head, n);
0196     spin_unlock_irqrestore(&nh->lock, flags);
0197     synchronize_rcu();
0198     return ret;
0199 }
0200 EXPORT_SYMBOL_GPL(atomic_notifier_chain_unregister);
0201 
0202 /**
0203  *  atomic_notifier_call_chain - Call functions in an atomic notifier chain
0204  *  @nh: Pointer to head of the atomic notifier chain
0205  *  @val: Value passed unmodified to notifier function
0206  *  @v: Pointer passed unmodified to notifier function
0207  *
0208  *  Calls each function in a notifier chain in turn.  The functions
0209  *  run in an atomic context, so they must not block.
0210  *  This routine uses RCU to synchronize with changes to the chain.
0211  *
0212  *  If the return value of the notifier can be and'ed
0213  *  with %NOTIFY_STOP_MASK then atomic_notifier_call_chain()
0214  *  will return immediately, with the return value of
0215  *  the notifier function which halted execution.
0216  *  Otherwise the return value is the return value
0217  *  of the last notifier function called.
0218  */
0219 int atomic_notifier_call_chain(struct atomic_notifier_head *nh,
0220                    unsigned long val, void *v)
0221 {
0222     int ret;
0223 
0224     rcu_read_lock();
0225     ret = notifier_call_chain(&nh->head, val, v, -1, NULL);
0226     rcu_read_unlock();
0227 
0228     return ret;
0229 }
0230 EXPORT_SYMBOL_GPL(atomic_notifier_call_chain);
0231 NOKPROBE_SYMBOL(atomic_notifier_call_chain);
0232 
0233 /**
0234  *  atomic_notifier_call_chain_is_empty - Check whether notifier chain is empty
0235  *  @nh: Pointer to head of the atomic notifier chain
0236  *
0237  *  Checks whether notifier chain is empty.
0238  *
0239  *  Returns true is notifier chain is empty, false otherwise.
0240  */
0241 bool atomic_notifier_call_chain_is_empty(struct atomic_notifier_head *nh)
0242 {
0243     return !rcu_access_pointer(nh->head);
0244 }
0245 
0246 /*
0247  *  Blocking notifier chain routines.  All access to the chain is
0248  *  synchronized by an rwsem.
0249  */
0250 
0251 static int __blocking_notifier_chain_register(struct blocking_notifier_head *nh,
0252                           struct notifier_block *n,
0253                           bool unique_priority)
0254 {
0255     int ret;
0256 
0257     /*
0258      * This code gets used during boot-up, when task switching is
0259      * not yet working and interrupts must remain disabled.  At
0260      * such times we must not call down_write().
0261      */
0262     if (unlikely(system_state == SYSTEM_BOOTING))
0263         return notifier_chain_register(&nh->head, n, unique_priority);
0264 
0265     down_write(&nh->rwsem);
0266     ret = notifier_chain_register(&nh->head, n, unique_priority);
0267     up_write(&nh->rwsem);
0268     return ret;
0269 }
0270 
0271 /**
0272  *  blocking_notifier_chain_register - Add notifier to a blocking notifier chain
0273  *  @nh: Pointer to head of the blocking notifier chain
0274  *  @n: New entry in notifier chain
0275  *
0276  *  Adds a notifier to a blocking notifier chain.
0277  *  Must be called in process context.
0278  *
0279  *  Returns 0 on success, %-EEXIST on error.
0280  */
0281 int blocking_notifier_chain_register(struct blocking_notifier_head *nh,
0282         struct notifier_block *n)
0283 {
0284     return __blocking_notifier_chain_register(nh, n, false);
0285 }
0286 EXPORT_SYMBOL_GPL(blocking_notifier_chain_register);
0287 
0288 /**
0289  *  blocking_notifier_chain_register_unique_prio - Add notifier to a blocking notifier chain
0290  *  @nh: Pointer to head of the blocking notifier chain
0291  *  @n: New entry in notifier chain
0292  *
0293  *  Adds a notifier to an blocking notifier chain if there is no other
0294  *  notifier registered using the same priority.
0295  *
0296  *  Returns 0 on success, %-EEXIST or %-EBUSY on error.
0297  */
0298 int blocking_notifier_chain_register_unique_prio(struct blocking_notifier_head *nh,
0299                          struct notifier_block *n)
0300 {
0301     return __blocking_notifier_chain_register(nh, n, true);
0302 }
0303 EXPORT_SYMBOL_GPL(blocking_notifier_chain_register_unique_prio);
0304 
0305 /**
0306  *  blocking_notifier_chain_unregister - Remove notifier from a blocking notifier chain
0307  *  @nh: Pointer to head of the blocking notifier chain
0308  *  @n: Entry to remove from notifier chain
0309  *
0310  *  Removes a notifier from a blocking notifier chain.
0311  *  Must be called from process context.
0312  *
0313  *  Returns zero on success or %-ENOENT on failure.
0314  */
0315 int blocking_notifier_chain_unregister(struct blocking_notifier_head *nh,
0316         struct notifier_block *n)
0317 {
0318     int ret;
0319 
0320     /*
0321      * This code gets used during boot-up, when task switching is
0322      * not yet working and interrupts must remain disabled.  At
0323      * such times we must not call down_write().
0324      */
0325     if (unlikely(system_state == SYSTEM_BOOTING))
0326         return notifier_chain_unregister(&nh->head, n);
0327 
0328     down_write(&nh->rwsem);
0329     ret = notifier_chain_unregister(&nh->head, n);
0330     up_write(&nh->rwsem);
0331     return ret;
0332 }
0333 EXPORT_SYMBOL_GPL(blocking_notifier_chain_unregister);
0334 
0335 int blocking_notifier_call_chain_robust(struct blocking_notifier_head *nh,
0336         unsigned long val_up, unsigned long val_down, void *v)
0337 {
0338     int ret = NOTIFY_DONE;
0339 
0340     /*
0341      * We check the head outside the lock, but if this access is
0342      * racy then it does not matter what the result of the test
0343      * is, we re-check the list after having taken the lock anyway:
0344      */
0345     if (rcu_access_pointer(nh->head)) {
0346         down_read(&nh->rwsem);
0347         ret = notifier_call_chain_robust(&nh->head, val_up, val_down, v);
0348         up_read(&nh->rwsem);
0349     }
0350     return ret;
0351 }
0352 EXPORT_SYMBOL_GPL(blocking_notifier_call_chain_robust);
0353 
0354 /**
0355  *  blocking_notifier_call_chain - Call functions in a blocking notifier chain
0356  *  @nh: Pointer to head of the blocking notifier chain
0357  *  @val: Value passed unmodified to notifier function
0358  *  @v: Pointer passed unmodified to notifier function
0359  *
0360  *  Calls each function in a notifier chain in turn.  The functions
0361  *  run in a process context, so they are allowed to block.
0362  *
0363  *  If the return value of the notifier can be and'ed
0364  *  with %NOTIFY_STOP_MASK then blocking_notifier_call_chain()
0365  *  will return immediately, with the return value of
0366  *  the notifier function which halted execution.
0367  *  Otherwise the return value is the return value
0368  *  of the last notifier function called.
0369  */
0370 int blocking_notifier_call_chain(struct blocking_notifier_head *nh,
0371         unsigned long val, void *v)
0372 {
0373     int ret = NOTIFY_DONE;
0374 
0375     /*
0376      * We check the head outside the lock, but if this access is
0377      * racy then it does not matter what the result of the test
0378      * is, we re-check the list after having taken the lock anyway:
0379      */
0380     if (rcu_access_pointer(nh->head)) {
0381         down_read(&nh->rwsem);
0382         ret = notifier_call_chain(&nh->head, val, v, -1, NULL);
0383         up_read(&nh->rwsem);
0384     }
0385     return ret;
0386 }
0387 EXPORT_SYMBOL_GPL(blocking_notifier_call_chain);
0388 
0389 /*
0390  *  Raw notifier chain routines.  There is no protection;
0391  *  the caller must provide it.  Use at your own risk!
0392  */
0393 
0394 /**
0395  *  raw_notifier_chain_register - Add notifier to a raw notifier chain
0396  *  @nh: Pointer to head of the raw notifier chain
0397  *  @n: New entry in notifier chain
0398  *
0399  *  Adds a notifier to a raw notifier chain.
0400  *  All locking must be provided by the caller.
0401  *
0402  *  Returns 0 on success, %-EEXIST on error.
0403  */
0404 int raw_notifier_chain_register(struct raw_notifier_head *nh,
0405         struct notifier_block *n)
0406 {
0407     return notifier_chain_register(&nh->head, n, false);
0408 }
0409 EXPORT_SYMBOL_GPL(raw_notifier_chain_register);
0410 
0411 /**
0412  *  raw_notifier_chain_unregister - Remove notifier from a raw notifier chain
0413  *  @nh: Pointer to head of the raw notifier chain
0414  *  @n: Entry to remove from notifier chain
0415  *
0416  *  Removes a notifier from a raw notifier chain.
0417  *  All locking must be provided by the caller.
0418  *
0419  *  Returns zero on success or %-ENOENT on failure.
0420  */
0421 int raw_notifier_chain_unregister(struct raw_notifier_head *nh,
0422         struct notifier_block *n)
0423 {
0424     return notifier_chain_unregister(&nh->head, n);
0425 }
0426 EXPORT_SYMBOL_GPL(raw_notifier_chain_unregister);
0427 
0428 int raw_notifier_call_chain_robust(struct raw_notifier_head *nh,
0429         unsigned long val_up, unsigned long val_down, void *v)
0430 {
0431     return notifier_call_chain_robust(&nh->head, val_up, val_down, v);
0432 }
0433 EXPORT_SYMBOL_GPL(raw_notifier_call_chain_robust);
0434 
0435 /**
0436  *  raw_notifier_call_chain - Call functions in a raw notifier chain
0437  *  @nh: Pointer to head of the raw notifier chain
0438  *  @val: Value passed unmodified to notifier function
0439  *  @v: Pointer passed unmodified to notifier function
0440  *
0441  *  Calls each function in a notifier chain in turn.  The functions
0442  *  run in an undefined context.
0443  *  All locking must be provided by the caller.
0444  *
0445  *  If the return value of the notifier can be and'ed
0446  *  with %NOTIFY_STOP_MASK then raw_notifier_call_chain()
0447  *  will return immediately, with the return value of
0448  *  the notifier function which halted execution.
0449  *  Otherwise the return value is the return value
0450  *  of the last notifier function called.
0451  */
0452 int raw_notifier_call_chain(struct raw_notifier_head *nh,
0453         unsigned long val, void *v)
0454 {
0455     return notifier_call_chain(&nh->head, val, v, -1, NULL);
0456 }
0457 EXPORT_SYMBOL_GPL(raw_notifier_call_chain);
0458 
0459 #ifdef CONFIG_SRCU
0460 /*
0461  *  SRCU notifier chain routines.    Registration and unregistration
0462  *  use a mutex, and call_chain is synchronized by SRCU (no locks).
0463  */
0464 
0465 /**
0466  *  srcu_notifier_chain_register - Add notifier to an SRCU notifier chain
0467  *  @nh: Pointer to head of the SRCU notifier chain
0468  *  @n: New entry in notifier chain
0469  *
0470  *  Adds a notifier to an SRCU notifier chain.
0471  *  Must be called in process context.
0472  *
0473  *  Returns 0 on success, %-EEXIST on error.
0474  */
0475 int srcu_notifier_chain_register(struct srcu_notifier_head *nh,
0476         struct notifier_block *n)
0477 {
0478     int ret;
0479 
0480     /*
0481      * This code gets used during boot-up, when task switching is
0482      * not yet working and interrupts must remain disabled.  At
0483      * such times we must not call mutex_lock().
0484      */
0485     if (unlikely(system_state == SYSTEM_BOOTING))
0486         return notifier_chain_register(&nh->head, n, false);
0487 
0488     mutex_lock(&nh->mutex);
0489     ret = notifier_chain_register(&nh->head, n, false);
0490     mutex_unlock(&nh->mutex);
0491     return ret;
0492 }
0493 EXPORT_SYMBOL_GPL(srcu_notifier_chain_register);
0494 
0495 /**
0496  *  srcu_notifier_chain_unregister - Remove notifier from an SRCU notifier chain
0497  *  @nh: Pointer to head of the SRCU notifier chain
0498  *  @n: Entry to remove from notifier chain
0499  *
0500  *  Removes a notifier from an SRCU notifier chain.
0501  *  Must be called from process context.
0502  *
0503  *  Returns zero on success or %-ENOENT on failure.
0504  */
0505 int srcu_notifier_chain_unregister(struct srcu_notifier_head *nh,
0506         struct notifier_block *n)
0507 {
0508     int ret;
0509 
0510     /*
0511      * This code gets used during boot-up, when task switching is
0512      * not yet working and interrupts must remain disabled.  At
0513      * such times we must not call mutex_lock().
0514      */
0515     if (unlikely(system_state == SYSTEM_BOOTING))
0516         return notifier_chain_unregister(&nh->head, n);
0517 
0518     mutex_lock(&nh->mutex);
0519     ret = notifier_chain_unregister(&nh->head, n);
0520     mutex_unlock(&nh->mutex);
0521     synchronize_srcu(&nh->srcu);
0522     return ret;
0523 }
0524 EXPORT_SYMBOL_GPL(srcu_notifier_chain_unregister);
0525 
0526 /**
0527  *  srcu_notifier_call_chain - Call functions in an SRCU notifier chain
0528  *  @nh: Pointer to head of the SRCU notifier chain
0529  *  @val: Value passed unmodified to notifier function
0530  *  @v: Pointer passed unmodified to notifier function
0531  *
0532  *  Calls each function in a notifier chain in turn.  The functions
0533  *  run in a process context, so they are allowed to block.
0534  *
0535  *  If the return value of the notifier can be and'ed
0536  *  with %NOTIFY_STOP_MASK then srcu_notifier_call_chain()
0537  *  will return immediately, with the return value of
0538  *  the notifier function which halted execution.
0539  *  Otherwise the return value is the return value
0540  *  of the last notifier function called.
0541  */
0542 int srcu_notifier_call_chain(struct srcu_notifier_head *nh,
0543         unsigned long val, void *v)
0544 {
0545     int ret;
0546     int idx;
0547 
0548     idx = srcu_read_lock(&nh->srcu);
0549     ret = notifier_call_chain(&nh->head, val, v, -1, NULL);
0550     srcu_read_unlock(&nh->srcu, idx);
0551     return ret;
0552 }
0553 EXPORT_SYMBOL_GPL(srcu_notifier_call_chain);
0554 
0555 /**
0556  *  srcu_init_notifier_head - Initialize an SRCU notifier head
0557  *  @nh: Pointer to head of the srcu notifier chain
0558  *
0559  *  Unlike other sorts of notifier heads, SRCU notifier heads require
0560  *  dynamic initialization.  Be sure to call this routine before
0561  *  calling any of the other SRCU notifier routines for this head.
0562  *
0563  *  If an SRCU notifier head is deallocated, it must first be cleaned
0564  *  up by calling srcu_cleanup_notifier_head().  Otherwise the head's
0565  *  per-cpu data (used by the SRCU mechanism) will leak.
0566  */
0567 void srcu_init_notifier_head(struct srcu_notifier_head *nh)
0568 {
0569     mutex_init(&nh->mutex);
0570     if (init_srcu_struct(&nh->srcu) < 0)
0571         BUG();
0572     nh->head = NULL;
0573 }
0574 EXPORT_SYMBOL_GPL(srcu_init_notifier_head);
0575 
0576 #endif /* CONFIG_SRCU */
0577 
0578 static ATOMIC_NOTIFIER_HEAD(die_chain);
0579 
0580 int notrace notify_die(enum die_val val, const char *str,
0581            struct pt_regs *regs, long err, int trap, int sig)
0582 {
0583     struct die_args args = {
0584         .regs   = regs,
0585         .str    = str,
0586         .err    = err,
0587         .trapnr = trap,
0588         .signr  = sig,
0589 
0590     };
0591     RCU_LOCKDEP_WARN(!rcu_is_watching(),
0592                "notify_die called but RCU thinks we're quiescent");
0593     return atomic_notifier_call_chain(&die_chain, val, &args);
0594 }
0595 NOKPROBE_SYMBOL(notify_die);
0596 
0597 int register_die_notifier(struct notifier_block *nb)
0598 {
0599     return atomic_notifier_chain_register(&die_chain, nb);
0600 }
0601 EXPORT_SYMBOL_GPL(register_die_notifier);
0602 
0603 int unregister_die_notifier(struct notifier_block *nb)
0604 {
0605     return atomic_notifier_chain_unregister(&die_chain, nb);
0606 }
0607 EXPORT_SYMBOL_GPL(unregister_die_notifier);