1 // SPDX-License-Identifier: GPL-2.0-only 2 #include <linux/device/devres.h> 3 #include <linux/kdebug.h> 4 #include <linux/kprobes.h> 5 #include <linux/export.h> 6 #include <linux/notifier.h> 7 #include <linux/rcupdate.h> 8 #include <linux/vmalloc.h> 9 10 #define CREATE_TRACE_POINTS 11 #include <trace/events/notifier.h> 12 13 /* 14 * Notifier chain core routines. The exported routines below 15 * are layered on top of these, with appropriate locking added. 16 */ 17 18 static int notifier_chain_register(struct notifier_block **nl, 19 struct notifier_block *n, 20 bool unique_priority) 21 { 22 while ((*nl) != NULL) { 23 if (unlikely((*nl) == n)) { 24 WARN(1, "notifier callback %ps already registered", 25 n->notifier_call); 26 return -EEXIST; 27 } 28 if (n->priority > (*nl)->priority) 29 break; 30 if (n->priority == (*nl)->priority && unique_priority) 31 return -EBUSY; 32 nl = &((*nl)->next); 33 } 34 n->next = *nl; 35 rcu_assign_pointer(*nl, n); 36 trace_notifier_register((void *)n->notifier_call); 37 return 0; 38 } 39 40 static int notifier_chain_unregister(struct notifier_block **nl, 41 struct notifier_block *n) 42 { 43 while ((*nl) != NULL) { 44 if ((*nl) == n) { 45 rcu_assign_pointer(*nl, n->next); 46 trace_notifier_unregister((void *)n->notifier_call); 47 return 0; 48 } 49 nl = &((*nl)->next); 50 } 51 return -ENOENT; 52 } 53 54 /** 55 * notifier_call_chain - Informs the registered notifiers about an event. 56 * @nl: Pointer to head of the blocking notifier chain 57 * @val: Value passed unmodified to notifier function 58 * @v: Pointer passed unmodified to notifier function 59 * @nr_to_call: Number of notifier functions to be called. Don't care 60 * value of this parameter is -1. 61 * @nr_calls: Records the number of notifications sent. Don't care 62 * value of this field is NULL. 63 * Return: notifier_call_chain returns the value returned by the 64 * last notifier function called. 65 */ 66 static int notifier_call_chain(struct notifier_block **nl, 67 unsigned long val, void *v, 68 int nr_to_call, int *nr_calls) 69 { 70 int ret = NOTIFY_DONE; 71 struct notifier_block *nb, *next_nb; 72 73 nb = rcu_dereference_raw(*nl); 74 75 while (nb && nr_to_call) { 76 next_nb = rcu_dereference_raw(nb->next); 77 78 #ifdef CONFIG_DEBUG_NOTIFIERS 79 if (unlikely(!func_ptr_is_kernel_text(nb->notifier_call))) { 80 WARN(1, "Invalid notifier called!"); 81 nb = next_nb; 82 continue; 83 } 84 #endif 85 trace_notifier_run((void *)nb->notifier_call); 86 ret = nb->notifier_call(nb, val, v); 87 88 if (nr_calls) 89 (*nr_calls)++; 90 91 if (ret & NOTIFY_STOP_MASK) 92 break; 93 nb = next_nb; 94 nr_to_call--; 95 } 96 return ret; 97 } 98 NOKPROBE_SYMBOL(notifier_call_chain); 99 100 /** 101 * notifier_call_chain_robust - Inform the registered notifiers about an event 102 * and rollback on error. 103 * @nl: Pointer to head of the blocking notifier chain 104 * @val_up: Value passed unmodified to the notifier function 105 * @val_down: Value passed unmodified to the notifier function when recovering 106 * from an error on @val_up 107 * @v: Pointer passed unmodified to the notifier function 108 * 109 * NOTE: It is important the @nl chain doesn't change between the two 110 * invocations of notifier_call_chain() such that we visit the 111 * exact same notifier callbacks; this rules out any RCU usage. 112 * 113 * Return: the return value of the @val_up call. 114 */ 115 static int notifier_call_chain_robust(struct notifier_block **nl, 116 unsigned long val_up, unsigned long val_down, 117 void *v) 118 { 119 int ret, nr = 0; 120 121 ret = notifier_call_chain(nl, val_up, v, -1, &nr); 122 if (ret & NOTIFY_STOP_MASK) 123 notifier_call_chain(nl, val_down, v, nr-1, NULL); 124 125 return ret; 126 } 127 128 /* 129 * Atomic notifier chain routines. Registration and unregistration 130 * use a spinlock, and call_chain is synchronized by RCU (no locks). 131 */ 132 133 /** 134 * atomic_notifier_chain_register - Add notifier to an atomic notifier chain 135 * @nh: Pointer to head of the atomic notifier chain 136 * @n: New entry in notifier chain 137 * 138 * Adds a notifier to an atomic notifier chain. 139 * 140 * Returns 0 on success, %-EEXIST on error. 141 */ 142 int atomic_notifier_chain_register(struct atomic_notifier_head *nh, 143 struct notifier_block *n) 144 { 145 unsigned long flags; 146 int ret; 147 148 spin_lock_irqsave(&nh->lock, flags); 149 ret = notifier_chain_register(&nh->head, n, false); 150 spin_unlock_irqrestore(&nh->lock, flags); 151 return ret; 152 } 153 EXPORT_SYMBOL_GPL(atomic_notifier_chain_register); 154 155 /** 156 * atomic_notifier_chain_register_unique_prio - Add notifier to an atomic notifier chain 157 * @nh: Pointer to head of the atomic notifier chain 158 * @n: New entry in notifier chain 159 * 160 * Adds a notifier to an atomic notifier chain if there is no other 161 * notifier registered using the same priority. 162 * 163 * Returns 0 on success, %-EEXIST or %-EBUSY on error. 164 */ 165 int atomic_notifier_chain_register_unique_prio(struct atomic_notifier_head *nh, 166 struct notifier_block *n) 167 { 168 unsigned long flags; 169 int ret; 170 171 spin_lock_irqsave(&nh->lock, flags); 172 ret = notifier_chain_register(&nh->head, n, true); 173 spin_unlock_irqrestore(&nh->lock, flags); 174 return ret; 175 } 176 EXPORT_SYMBOL_GPL(atomic_notifier_chain_register_unique_prio); 177 178 /** 179 * atomic_notifier_chain_unregister - Remove notifier from an atomic notifier chain 180 * @nh: Pointer to head of the atomic notifier chain 181 * @n: Entry to remove from notifier chain 182 * 183 * Removes a notifier from an atomic notifier chain. 184 * 185 * Returns zero on success or %-ENOENT on failure. 186 */ 187 int atomic_notifier_chain_unregister(struct atomic_notifier_head *nh, 188 struct notifier_block *n) 189 { 190 unsigned long flags; 191 int ret; 192 193 spin_lock_irqsave(&nh->lock, flags); 194 ret = notifier_chain_unregister(&nh->head, n); 195 spin_unlock_irqrestore(&nh->lock, flags); 196 synchronize_rcu(); 197 return ret; 198 } 199 EXPORT_SYMBOL_GPL(atomic_notifier_chain_unregister); 200 201 struct atomic_notifier_chain_devres { 202 struct atomic_notifier_head *nh; 203 struct notifier_block *nb; 204 }; 205 206 static void devm_atomic_notifier_chain_unregister(struct device *dev, void *res) 207 { 208 struct atomic_notifier_chain_devres *dr = res; 209 210 atomic_notifier_chain_unregister(dr->nh, dr->nb); 211 } 212 213 /** 214 * devm_atomic_notifier_chain_register - Device-managed atomic notifier registration 215 * @dev: Device to tie the notifier lifetime to 216 * @nh: Pointer to head of the atomic notifier chain 217 * @nb: New entry in notifier chain 218 * 219 * Adds a notifier to an atomic notifier chain and registers a cleanup 220 * action to automatically unregister it when @dev is unbound. 221 * 222 * Must be called in process context. 223 * 224 * Return: 225 * 0 on success, negative errno on error. 226 */ 227 int devm_atomic_notifier_chain_register(struct device *dev, 228 struct atomic_notifier_head *nh, 229 struct notifier_block *nb) 230 { 231 struct atomic_notifier_chain_devres *dr; 232 int ret; 233 234 dr = devres_alloc(devm_atomic_notifier_chain_unregister, 235 sizeof(*dr), GFP_KERNEL); 236 if (!dr) 237 return -ENOMEM; 238 239 ret = atomic_notifier_chain_register(nh, nb); 240 if (ret) { 241 devres_free(dr); 242 return ret; 243 } 244 245 dr->nh = nh; 246 dr->nb = nb; 247 devres_add(dev, dr); 248 249 return 0; 250 } 251 EXPORT_SYMBOL_GPL(devm_atomic_notifier_chain_register); 252 253 /** 254 * atomic_notifier_call_chain - Call functions in an atomic notifier chain 255 * @nh: Pointer to head of the atomic notifier chain 256 * @val: Value passed unmodified to notifier function 257 * @v: Pointer passed unmodified to notifier function 258 * 259 * Calls each function in a notifier chain in turn. The functions 260 * run in an atomic context, so they must not block. 261 * This routine uses RCU to synchronize with changes to the chain. 262 * 263 * If the return value of the notifier can be and'ed 264 * with %NOTIFY_STOP_MASK then atomic_notifier_call_chain() 265 * will return immediately, with the return value of 266 * the notifier function which halted execution. 267 * Otherwise the return value is the return value 268 * of the last notifier function called. 269 */ 270 int atomic_notifier_call_chain(struct atomic_notifier_head *nh, 271 unsigned long val, void *v) 272 { 273 int ret; 274 275 rcu_read_lock(); 276 ret = notifier_call_chain(&nh->head, val, v, -1, NULL); 277 rcu_read_unlock(); 278 279 return ret; 280 } 281 EXPORT_SYMBOL_GPL(atomic_notifier_call_chain); 282 NOKPROBE_SYMBOL(atomic_notifier_call_chain); 283 284 /** 285 * atomic_notifier_call_chain_is_empty - Check whether notifier chain is empty 286 * @nh: Pointer to head of the atomic notifier chain 287 * 288 * Checks whether notifier chain is empty. 289 * 290 * Returns true is notifier chain is empty, false otherwise. 291 */ 292 bool atomic_notifier_call_chain_is_empty(struct atomic_notifier_head *nh) 293 { 294 return !rcu_access_pointer(nh->head); 295 } 296 297 /* 298 * Blocking notifier chain routines. All access to the chain is 299 * synchronized by an rwsem. 300 */ 301 302 static int __blocking_notifier_chain_register(struct blocking_notifier_head *nh, 303 struct notifier_block *n, 304 bool unique_priority) 305 { 306 int ret; 307 308 /* 309 * This code gets used during boot-up, when task switching is 310 * not yet working and interrupts must remain disabled. At 311 * such times we must not call down_write(). 312 */ 313 if (unlikely(system_state == SYSTEM_BOOTING)) 314 return notifier_chain_register(&nh->head, n, unique_priority); 315 316 down_write(&nh->rwsem); 317 ret = notifier_chain_register(&nh->head, n, unique_priority); 318 up_write(&nh->rwsem); 319 return ret; 320 } 321 322 /** 323 * blocking_notifier_chain_register - Add notifier to a blocking notifier chain 324 * @nh: Pointer to head of the blocking notifier chain 325 * @n: New entry in notifier chain 326 * 327 * Adds a notifier to a blocking notifier chain. 328 * Must be called in process context. 329 * 330 * Returns 0 on success, %-EEXIST on error. 331 */ 332 int blocking_notifier_chain_register(struct blocking_notifier_head *nh, 333 struct notifier_block *n) 334 { 335 return __blocking_notifier_chain_register(nh, n, false); 336 } 337 EXPORT_SYMBOL_GPL(blocking_notifier_chain_register); 338 339 /** 340 * blocking_notifier_chain_register_unique_prio - Add notifier to a blocking notifier chain 341 * @nh: Pointer to head of the blocking notifier chain 342 * @n: New entry in notifier chain 343 * 344 * Adds a notifier to an blocking notifier chain if there is no other 345 * notifier registered using the same priority. 346 * 347 * Returns 0 on success, %-EEXIST or %-EBUSY on error. 348 */ 349 int blocking_notifier_chain_register_unique_prio(struct blocking_notifier_head *nh, 350 struct notifier_block *n) 351 { 352 return __blocking_notifier_chain_register(nh, n, true); 353 } 354 EXPORT_SYMBOL_GPL(blocking_notifier_chain_register_unique_prio); 355 356 /** 357 * blocking_notifier_chain_unregister - Remove notifier from a blocking notifier chain 358 * @nh: Pointer to head of the blocking notifier chain 359 * @n: Entry to remove from notifier chain 360 * 361 * Removes a notifier from a blocking notifier chain. 362 * Must be called from process context. 363 * 364 * Returns zero on success or %-ENOENT on failure. 365 */ 366 int blocking_notifier_chain_unregister(struct blocking_notifier_head *nh, 367 struct notifier_block *n) 368 { 369 int ret; 370 371 /* 372 * This code gets used during boot-up, when task switching is 373 * not yet working and interrupts must remain disabled. At 374 * such times we must not call down_write(). 375 */ 376 if (unlikely(system_state == SYSTEM_BOOTING)) 377 return notifier_chain_unregister(&nh->head, n); 378 379 down_write(&nh->rwsem); 380 ret = notifier_chain_unregister(&nh->head, n); 381 up_write(&nh->rwsem); 382 return ret; 383 } 384 EXPORT_SYMBOL_GPL(blocking_notifier_chain_unregister); 385 386 int blocking_notifier_call_chain_robust(struct blocking_notifier_head *nh, 387 unsigned long val_up, unsigned long val_down, void *v) 388 { 389 int ret = NOTIFY_DONE; 390 391 /* 392 * We check the head outside the lock, but if this access is 393 * racy then it does not matter what the result of the test 394 * is, we re-check the list after having taken the lock anyway: 395 */ 396 if (rcu_access_pointer(nh->head)) { 397 down_read(&nh->rwsem); 398 ret = notifier_call_chain_robust(&nh->head, val_up, val_down, v); 399 up_read(&nh->rwsem); 400 } 401 return ret; 402 } 403 EXPORT_SYMBOL_GPL(blocking_notifier_call_chain_robust); 404 405 struct blocking_notifier_chain_devres { 406 struct blocking_notifier_head *nh; 407 struct notifier_block *nb; 408 }; 409 410 static void devm_blocking_notifier_chain_unregister(struct device *dev, 411 void *res) 412 { 413 struct blocking_notifier_chain_devres *dr = res; 414 415 blocking_notifier_chain_unregister(dr->nh, dr->nb); 416 } 417 418 /** 419 * devm_blocking_notifier_chain_register - Device-managed blocking notifier registration 420 * @dev: Device to tie the notifier lifetime to 421 * @nh: Pointer to head of the blocking notifier chain 422 * @nb: New entry in notifier chain 423 * 424 * Adds a notifier to a blocking notifier chain and registers a cleanup 425 * action to automatically unregister it when @dev is unbound. 426 * Must be called in process context. 427 * 428 * Return: 429 * 0 on success, negative errno on error. 430 */ 431 int devm_blocking_notifier_chain_register(struct device *dev, 432 struct blocking_notifier_head *nh, 433 struct notifier_block *nb) 434 { 435 struct blocking_notifier_chain_devres *dr; 436 int ret; 437 438 dr = devres_alloc(devm_blocking_notifier_chain_unregister, 439 sizeof(*dr), GFP_KERNEL); 440 if (!dr) 441 return -ENOMEM; 442 443 ret = blocking_notifier_chain_register(nh, nb); 444 if (ret) { 445 devres_free(dr); 446 return ret; 447 } 448 449 dr->nh = nh; 450 dr->nb = nb; 451 devres_add(dev, dr); 452 453 return 0; 454 } 455 EXPORT_SYMBOL_GPL(devm_blocking_notifier_chain_register); 456 457 /** 458 * blocking_notifier_call_chain - Call functions in a blocking notifier chain 459 * @nh: Pointer to head of the blocking notifier chain 460 * @val: Value passed unmodified to notifier function 461 * @v: Pointer passed unmodified to notifier function 462 * 463 * Calls each function in a notifier chain in turn. The functions 464 * run in a process context, so they are allowed to block. 465 * 466 * If the return value of the notifier can be and'ed 467 * with %NOTIFY_STOP_MASK then blocking_notifier_call_chain() 468 * will return immediately, with the return value of 469 * the notifier function which halted execution. 470 * Otherwise the return value is the return value 471 * of the last notifier function called. 472 */ 473 int blocking_notifier_call_chain(struct blocking_notifier_head *nh, 474 unsigned long val, void *v) 475 { 476 int ret = NOTIFY_DONE; 477 478 /* 479 * We check the head outside the lock, but if this access is 480 * racy then it does not matter what the result of the test 481 * is, we re-check the list after having taken the lock anyway: 482 */ 483 if (rcu_access_pointer(nh->head)) { 484 down_read(&nh->rwsem); 485 ret = notifier_call_chain(&nh->head, val, v, -1, NULL); 486 up_read(&nh->rwsem); 487 } 488 return ret; 489 } 490 EXPORT_SYMBOL_GPL(blocking_notifier_call_chain); 491 492 /* 493 * Raw notifier chain routines. There is no protection; 494 * the caller must provide it. Use at your own risk! 495 */ 496 497 /** 498 * raw_notifier_chain_register - Add notifier to a raw notifier chain 499 * @nh: Pointer to head of the raw notifier chain 500 * @n: New entry in notifier chain 501 * 502 * Adds a notifier to a raw notifier chain. 503 * All locking must be provided by the caller. 504 * 505 * Returns 0 on success, %-EEXIST on error. 506 */ 507 int raw_notifier_chain_register(struct raw_notifier_head *nh, 508 struct notifier_block *n) 509 { 510 return notifier_chain_register(&nh->head, n, false); 511 } 512 EXPORT_SYMBOL_GPL(raw_notifier_chain_register); 513 514 /** 515 * raw_notifier_chain_unregister - Remove notifier from a raw notifier chain 516 * @nh: Pointer to head of the raw notifier chain 517 * @n: Entry to remove from notifier chain 518 * 519 * Removes a notifier from a raw notifier chain. 520 * All locking must be provided by the caller. 521 * 522 * Returns zero on success or %-ENOENT on failure. 523 */ 524 int raw_notifier_chain_unregister(struct raw_notifier_head *nh, 525 struct notifier_block *n) 526 { 527 return notifier_chain_unregister(&nh->head, n); 528 } 529 EXPORT_SYMBOL_GPL(raw_notifier_chain_unregister); 530 531 int raw_notifier_call_chain_robust(struct raw_notifier_head *nh, 532 unsigned long val_up, unsigned long val_down, void *v) 533 { 534 return notifier_call_chain_robust(&nh->head, val_up, val_down, v); 535 } 536 EXPORT_SYMBOL_GPL(raw_notifier_call_chain_robust); 537 538 /** 539 * raw_notifier_call_chain - Call functions in a raw notifier chain 540 * @nh: Pointer to head of the raw notifier chain 541 * @val: Value passed unmodified to notifier function 542 * @v: Pointer passed unmodified to notifier function 543 * 544 * Calls each function in a notifier chain in turn. The functions 545 * run in an undefined context. 546 * All locking must be provided by the caller. 547 * 548 * If the return value of the notifier can be and'ed 549 * with %NOTIFY_STOP_MASK then raw_notifier_call_chain() 550 * will return immediately, with the return value of 551 * the notifier function which halted execution. 552 * Otherwise the return value is the return value 553 * of the last notifier function called. 554 */ 555 int raw_notifier_call_chain(struct raw_notifier_head *nh, 556 unsigned long val, void *v) 557 { 558 return notifier_call_chain(&nh->head, val, v, -1, NULL); 559 } 560 EXPORT_SYMBOL_GPL(raw_notifier_call_chain); 561 562 /* 563 * SRCU notifier chain routines. Registration and unregistration 564 * use a mutex, and call_chain is synchronized by SRCU (no locks). 565 */ 566 567 /** 568 * srcu_notifier_chain_register - Add notifier to an SRCU notifier chain 569 * @nh: Pointer to head of the SRCU notifier chain 570 * @n: New entry in notifier chain 571 * 572 * Adds a notifier to an SRCU notifier chain. 573 * Must be called in process context. 574 * 575 * Returns 0 on success, %-EEXIST on error. 576 */ 577 int srcu_notifier_chain_register(struct srcu_notifier_head *nh, 578 struct notifier_block *n) 579 { 580 int ret; 581 582 /* 583 * This code gets used during boot-up, when task switching is 584 * not yet working and interrupts must remain disabled. At 585 * such times we must not call mutex_lock(). 586 */ 587 if (unlikely(system_state == SYSTEM_BOOTING)) 588 return notifier_chain_register(&nh->head, n, false); 589 590 mutex_lock(&nh->mutex); 591 ret = notifier_chain_register(&nh->head, n, false); 592 mutex_unlock(&nh->mutex); 593 return ret; 594 } 595 EXPORT_SYMBOL_GPL(srcu_notifier_chain_register); 596 597 /** 598 * srcu_notifier_chain_unregister - Remove notifier from an SRCU notifier chain 599 * @nh: Pointer to head of the SRCU notifier chain 600 * @n: Entry to remove from notifier chain 601 * 602 * Removes a notifier from an SRCU notifier chain. 603 * Must be called from process context. 604 * 605 * Returns zero on success or %-ENOENT on failure. 606 */ 607 int srcu_notifier_chain_unregister(struct srcu_notifier_head *nh, 608 struct notifier_block *n) 609 { 610 int ret; 611 612 /* 613 * This code gets used during boot-up, when task switching is 614 * not yet working and interrupts must remain disabled. At 615 * such times we must not call mutex_lock(). 616 */ 617 if (unlikely(system_state == SYSTEM_BOOTING)) 618 return notifier_chain_unregister(&nh->head, n); 619 620 mutex_lock(&nh->mutex); 621 ret = notifier_chain_unregister(&nh->head, n); 622 mutex_unlock(&nh->mutex); 623 synchronize_srcu(&nh->srcu); 624 return ret; 625 } 626 EXPORT_SYMBOL_GPL(srcu_notifier_chain_unregister); 627 628 /** 629 * srcu_notifier_call_chain - Call functions in an SRCU notifier chain 630 * @nh: Pointer to head of the SRCU notifier chain 631 * @val: Value passed unmodified to notifier function 632 * @v: Pointer passed unmodified to notifier function 633 * 634 * Calls each function in a notifier chain in turn. The functions 635 * run in a process context, so they are allowed to block. 636 * 637 * If the return value of the notifier can be and'ed 638 * with %NOTIFY_STOP_MASK then srcu_notifier_call_chain() 639 * will return immediately, with the return value of 640 * the notifier function which halted execution. 641 * Otherwise the return value is the return value 642 * of the last notifier function called. 643 */ 644 int srcu_notifier_call_chain(struct srcu_notifier_head *nh, 645 unsigned long val, void *v) 646 { 647 int ret; 648 int idx; 649 650 idx = srcu_read_lock(&nh->srcu); 651 ret = notifier_call_chain(&nh->head, val, v, -1, NULL); 652 srcu_read_unlock(&nh->srcu, idx); 653 return ret; 654 } 655 EXPORT_SYMBOL_GPL(srcu_notifier_call_chain); 656 657 /** 658 * srcu_init_notifier_head - Initialize an SRCU notifier head 659 * @nh: Pointer to head of the srcu notifier chain 660 * 661 * Unlike other sorts of notifier heads, SRCU notifier heads require 662 * dynamic initialization. Be sure to call this routine before 663 * calling any of the other SRCU notifier routines for this head. 664 * 665 * If an SRCU notifier head is deallocated, it must first be cleaned 666 * up by calling srcu_cleanup_notifier_head(). Otherwise the head's 667 * per-cpu data (used by the SRCU mechanism) will leak. 668 */ 669 void srcu_init_notifier_head(struct srcu_notifier_head *nh) 670 { 671 mutex_init(&nh->mutex); 672 if (init_srcu_struct(&nh->srcu) < 0) 673 BUG(); 674 nh->head = NULL; 675 } 676 EXPORT_SYMBOL_GPL(srcu_init_notifier_head); 677 678 static ATOMIC_NOTIFIER_HEAD(die_chain); 679 680 int notrace notify_die(enum die_val val, const char *str, 681 struct pt_regs *regs, long err, int trap, int sig) 682 { 683 struct die_args args = { 684 .regs = regs, 685 .str = str, 686 .err = err, 687 .trapnr = trap, 688 .signr = sig, 689 690 }; 691 RCU_LOCKDEP_WARN(!rcu_is_watching(), 692 "notify_die called but RCU thinks we're quiescent"); 693 return atomic_notifier_call_chain(&die_chain, val, &args); 694 } 695 NOKPROBE_SYMBOL(notify_die); 696 697 int register_die_notifier(struct notifier_block *nb) 698 { 699 return atomic_notifier_chain_register(&die_chain, nb); 700 } 701 EXPORT_SYMBOL_GPL(register_die_notifier); 702 703 int unregister_die_notifier(struct notifier_block *nb) 704 { 705 return atomic_notifier_chain_unregister(&die_chain, nb); 706 } 707 EXPORT_SYMBOL_GPL(unregister_die_notifier); 708