1 // SPDX-License-Identifier: GPL-2.0 2 // Copyright (C) 2017 Arm Ltd. 3 #define pr_fmt(fmt) "sdei: " fmt 4 5 #include <acpi/ghes.h> 6 #include <linux/acpi.h> 7 #include <linux/arm_sdei.h> 8 #include <linux/arm-smccc.h> 9 #include <linux/atomic.h> 10 #include <linux/bitops.h> 11 #include <linux/compiler.h> 12 #include <linux/cpuhotplug.h> 13 #include <linux/cpu.h> 14 #include <linux/cpu_pm.h> 15 #include <linux/errno.h> 16 #include <linux/hardirq.h> 17 #include <linux/kernel.h> 18 #include <linux/kprobes.h> 19 #include <linux/kvm_host.h> 20 #include <linux/list.h> 21 #include <linux/mutex.h> 22 #include <linux/notifier.h> 23 #include <linux/of.h> 24 #include <linux/of_platform.h> 25 #include <linux/percpu.h> 26 #include <linux/platform_device.h> 27 #include <linux/pm.h> 28 #include <linux/ptrace.h> 29 #include <linux/preempt.h> 30 #include <linux/reboot.h> 31 #include <linux/slab.h> 32 #include <linux/smp.h> 33 #include <linux/spinlock.h> 34 35 /* 36 * The call to use to reach the firmware. 37 */ 38 static asmlinkage void (*sdei_firmware_call)(unsigned long function_id, 39 unsigned long arg0, unsigned long arg1, 40 unsigned long arg2, unsigned long arg3, 41 unsigned long arg4, struct arm_smccc_res *res); 42 43 /* entry point from firmware to arch asm code */ 44 static unsigned long sdei_entry_point; 45 46 static int sdei_hp_state; 47 48 struct sdei_event { 49 /* These three are protected by the sdei_list_lock */ 50 struct list_head list; 51 bool reregister; 52 bool reenable; 53 54 u32 event_num; 55 u8 type; 56 u8 priority; 57 58 /* This pointer is handed to firmware as the event argument. */ 59 union { 60 /* Shared events */ 61 struct sdei_registered_event *registered; 62 63 /* CPU private events */ 64 struct sdei_registered_event __percpu *private_registered; 65 }; 66 }; 67 68 /* Take the mutex for any API call or modification. Take the mutex first. */ 69 static DEFINE_MUTEX(sdei_events_lock); 70 71 /* and then hold this when modifying the list */ 72 static DEFINE_SPINLOCK(sdei_list_lock); 73 static LIST_HEAD(sdei_list); 74 75 /* Private events are registered/enabled via IPI passing one of these */ 76 struct sdei_crosscall_args { 77 struct sdei_event *event; 78 atomic_t errors; 79 int first_error; 80 }; 81 82 #define CROSSCALL_INIT(arg, event) \ 83 do { \ 84 arg.event = event; \ 85 arg.first_error = 0; \ 86 atomic_set(&arg.errors, 0); \ 87 } while (0) 88 89 static inline int sdei_do_local_call(smp_call_func_t fn, 90 struct sdei_event *event) 91 { 92 struct sdei_crosscall_args arg; 93 94 CROSSCALL_INIT(arg, event); 95 fn(&arg); 96 97 return arg.first_error; 98 } 99 100 static inline int sdei_do_cross_call(smp_call_func_t fn, 101 struct sdei_event *event) 102 { 103 struct sdei_crosscall_args arg; 104 105 CROSSCALL_INIT(arg, event); 106 on_each_cpu(fn, &arg, true); 107 108 return arg.first_error; 109 } 110 111 static inline void 112 sdei_cross_call_return(struct sdei_crosscall_args *arg, int err) 113 { 114 if (err && (atomic_inc_return(&arg->errors) == 1)) 115 arg->first_error = err; 116 } 117 118 static int sdei_to_linux_errno(unsigned long sdei_err) 119 { 120 switch (sdei_err) { 121 case SDEI_NOT_SUPPORTED: 122 return -EOPNOTSUPP; 123 case SDEI_INVALID_PARAMETERS: 124 return -EINVAL; 125 case SDEI_DENIED: 126 return -EPERM; 127 case SDEI_PENDING: 128 return -EINPROGRESS; 129 case SDEI_OUT_OF_RESOURCE: 130 return -ENOMEM; 131 } 132 133 return 0; 134 } 135 136 static int invoke_sdei_fn(unsigned long function_id, unsigned long arg0, 137 unsigned long arg1, unsigned long arg2, 138 unsigned long arg3, unsigned long arg4, 139 u64 *result) 140 { 141 int err; 142 struct arm_smccc_res res; 143 144 if (sdei_firmware_call) { 145 sdei_firmware_call(function_id, arg0, arg1, arg2, arg3, arg4, 146 &res); 147 err = sdei_to_linux_errno(res.a0); 148 } else { 149 /* 150 * !sdei_firmware_call means we failed to probe or called 151 * sdei_mark_interface_broken(). -EIO is not an error returned 152 * by sdei_to_linux_errno() and is used to suppress messages 153 * from this driver. 154 */ 155 err = -EIO; 156 res.a0 = SDEI_NOT_SUPPORTED; 157 } 158 159 if (result) 160 *result = res.a0; 161 162 return err; 163 } 164 NOKPROBE_SYMBOL(invoke_sdei_fn); 165 166 static struct sdei_event *sdei_event_find(u32 event_num) 167 { 168 struct sdei_event *e, *found = NULL; 169 170 lockdep_assert_held(&sdei_events_lock); 171 172 spin_lock(&sdei_list_lock); 173 list_for_each_entry(e, &sdei_list, list) { 174 if (e->event_num == event_num) { 175 found = e; 176 break; 177 } 178 } 179 spin_unlock(&sdei_list_lock); 180 181 return found; 182 } 183 184 int sdei_api_event_context(u32 query, u64 *result) 185 { 186 return invoke_sdei_fn(SDEI_1_0_FN_SDEI_EVENT_CONTEXT, query, 0, 0, 0, 0, 187 result); 188 } 189 NOKPROBE_SYMBOL(sdei_api_event_context); 190 191 static int sdei_api_event_get_info(u32 event, u32 info, u64 *result) 192 { 193 return invoke_sdei_fn(SDEI_1_0_FN_SDEI_EVENT_GET_INFO, event, info, 0, 194 0, 0, result); 195 } 196 197 static struct sdei_event *sdei_event_create(u32 event_num, 198 sdei_event_callback *cb, 199 void *cb_arg) 200 { 201 int err; 202 u64 result; 203 struct sdei_event *event; 204 struct sdei_registered_event *reg; 205 206 lockdep_assert_held(&sdei_events_lock); 207 208 event = kzalloc_obj(*event); 209 if (!event) { 210 err = -ENOMEM; 211 goto fail; 212 } 213 214 INIT_LIST_HEAD(&event->list); 215 event->event_num = event_num; 216 217 err = sdei_api_event_get_info(event_num, SDEI_EVENT_INFO_EV_PRIORITY, 218 &result); 219 if (err) 220 goto fail; 221 event->priority = result; 222 223 err = sdei_api_event_get_info(event_num, SDEI_EVENT_INFO_EV_TYPE, 224 &result); 225 if (err) 226 goto fail; 227 event->type = result; 228 229 if (event->type == SDEI_EVENT_TYPE_SHARED) { 230 reg = kzalloc_obj(*reg); 231 if (!reg) { 232 err = -ENOMEM; 233 goto fail; 234 } 235 236 reg->event_num = event->event_num; 237 reg->priority = event->priority; 238 239 reg->callback = cb; 240 reg->callback_arg = cb_arg; 241 event->registered = reg; 242 } else { 243 int cpu; 244 struct sdei_registered_event __percpu *regs; 245 246 regs = alloc_percpu(struct sdei_registered_event); 247 if (!regs) { 248 err = -ENOMEM; 249 goto fail; 250 } 251 252 for_each_possible_cpu(cpu) { 253 reg = per_cpu_ptr(regs, cpu); 254 255 reg->event_num = event->event_num; 256 reg->priority = event->priority; 257 reg->callback = cb; 258 reg->callback_arg = cb_arg; 259 } 260 261 event->private_registered = regs; 262 } 263 264 spin_lock(&sdei_list_lock); 265 list_add(&event->list, &sdei_list); 266 spin_unlock(&sdei_list_lock); 267 268 return event; 269 270 fail: 271 kfree(event); 272 return ERR_PTR(err); 273 } 274 275 static void sdei_event_destroy_llocked(struct sdei_event *event) 276 { 277 lockdep_assert_held(&sdei_events_lock); 278 lockdep_assert_held(&sdei_list_lock); 279 280 list_del(&event->list); 281 282 if (event->type == SDEI_EVENT_TYPE_SHARED) 283 kfree(event->registered); 284 else 285 free_percpu(event->private_registered); 286 287 kfree(event); 288 } 289 290 static void sdei_event_destroy(struct sdei_event *event) 291 { 292 spin_lock(&sdei_list_lock); 293 sdei_event_destroy_llocked(event); 294 spin_unlock(&sdei_list_lock); 295 } 296 297 static int sdei_api_get_version(u64 *version) 298 { 299 return invoke_sdei_fn(SDEI_1_0_FN_SDEI_VERSION, 0, 0, 0, 0, 0, version); 300 } 301 302 int sdei_mask_local_cpu(void) 303 { 304 int err; 305 306 err = invoke_sdei_fn(SDEI_1_0_FN_SDEI_PE_MASK, 0, 0, 0, 0, 0, NULL); 307 if (err && err != -EIO) { 308 pr_warn_once("failed to mask CPU[%u]: %d\n", 309 smp_processor_id(), err); 310 return err; 311 } 312 313 return 0; 314 } 315 316 static void _ipi_mask_cpu(void *ignored) 317 { 318 WARN_ON_ONCE(preemptible()); 319 sdei_mask_local_cpu(); 320 } 321 322 int sdei_unmask_local_cpu(void) 323 { 324 int err; 325 326 err = invoke_sdei_fn(SDEI_1_0_FN_SDEI_PE_UNMASK, 0, 0, 0, 0, 0, NULL); 327 if (err && err != -EIO) { 328 pr_warn_once("failed to unmask CPU[%u]: %d\n", 329 smp_processor_id(), err); 330 return err; 331 } 332 333 return 0; 334 } 335 336 static void _ipi_unmask_cpu(void *ignored) 337 { 338 WARN_ON_ONCE(preemptible()); 339 sdei_unmask_local_cpu(); 340 } 341 342 /* 343 * Signal the software-signalled event (event 0) to @mpidr. Does nothing 344 * but the SMC -- no locks, no event lookup -- so it is safe from NMI / 345 * crash context (e.g. the cross-CPU NMI service). 346 */ 347 int sdei_event_signal(u32 event_num, u64 mpidr) 348 { 349 return invoke_sdei_fn(SDEI_1_0_FN_SDEI_EVENT_SIGNAL, event_num, 350 mpidr, 0, 0, 0, NULL); 351 } 352 NOKPROBE_SYMBOL(sdei_event_signal); 353 354 /* 355 * Was SDEI firmware probed and is it usable? Lets optional consumers skip 356 * registering an event -- and the warning a failed registration emits -- on 357 * systems with no SDEI. 358 */ 359 bool sdei_is_present(void) 360 { 361 return sdei_firmware_call; 362 } 363 364 static void _ipi_private_reset(void *ignored) 365 { 366 int err; 367 368 WARN_ON_ONCE(preemptible()); 369 370 err = invoke_sdei_fn(SDEI_1_0_FN_SDEI_PRIVATE_RESET, 0, 0, 0, 0, 0, 371 NULL); 372 if (err && err != -EIO) 373 pr_warn_once("failed to reset CPU[%u]: %d\n", 374 smp_processor_id(), err); 375 } 376 377 static int sdei_api_shared_reset(void) 378 { 379 return invoke_sdei_fn(SDEI_1_0_FN_SDEI_SHARED_RESET, 0, 0, 0, 0, 0, 380 NULL); 381 } 382 383 static void sdei_mark_interface_broken(void) 384 { 385 pr_err("disabling SDEI firmware interface\n"); 386 on_each_cpu(&_ipi_mask_cpu, NULL, true); 387 sdei_firmware_call = NULL; 388 } 389 390 static int sdei_platform_reset(void) 391 { 392 int err; 393 394 on_each_cpu(&_ipi_private_reset, NULL, true); 395 err = sdei_api_shared_reset(); 396 if (err) { 397 pr_err("Failed to reset platform: %d\n", err); 398 sdei_mark_interface_broken(); 399 } 400 401 return err; 402 } 403 404 static int sdei_api_event_enable(u32 event_num) 405 { 406 return invoke_sdei_fn(SDEI_1_0_FN_SDEI_EVENT_ENABLE, event_num, 0, 0, 0, 407 0, NULL); 408 } 409 410 /* Called directly by the hotplug callbacks */ 411 static void _local_event_enable(void *data) 412 { 413 int err; 414 struct sdei_crosscall_args *arg = data; 415 416 err = sdei_api_event_enable(arg->event->event_num); 417 418 sdei_cross_call_return(arg, err); 419 } 420 421 int sdei_event_enable(u32 event_num) 422 { 423 int err = -EINVAL; 424 struct sdei_event *event; 425 426 mutex_lock(&sdei_events_lock); 427 event = sdei_event_find(event_num); 428 if (!event) { 429 mutex_unlock(&sdei_events_lock); 430 return -ENOENT; 431 } 432 433 434 cpus_read_lock(); 435 if (event->type == SDEI_EVENT_TYPE_SHARED) 436 err = sdei_api_event_enable(event->event_num); 437 else 438 err = sdei_do_cross_call(_local_event_enable, event); 439 440 if (!err) { 441 spin_lock(&sdei_list_lock); 442 event->reenable = true; 443 spin_unlock(&sdei_list_lock); 444 } 445 cpus_read_unlock(); 446 mutex_unlock(&sdei_events_lock); 447 448 return err; 449 } 450 451 static int sdei_api_event_disable(u32 event_num) 452 { 453 return invoke_sdei_fn(SDEI_1_0_FN_SDEI_EVENT_DISABLE, event_num, 0, 0, 454 0, 0, NULL); 455 } 456 457 static void _ipi_event_disable(void *data) 458 { 459 int err; 460 struct sdei_crosscall_args *arg = data; 461 462 err = sdei_api_event_disable(arg->event->event_num); 463 464 sdei_cross_call_return(arg, err); 465 } 466 467 int sdei_event_disable(u32 event_num) 468 { 469 int err = -EINVAL; 470 struct sdei_event *event; 471 472 mutex_lock(&sdei_events_lock); 473 event = sdei_event_find(event_num); 474 if (!event) { 475 mutex_unlock(&sdei_events_lock); 476 return -ENOENT; 477 } 478 479 spin_lock(&sdei_list_lock); 480 event->reenable = false; 481 spin_unlock(&sdei_list_lock); 482 483 if (event->type == SDEI_EVENT_TYPE_SHARED) 484 err = sdei_api_event_disable(event->event_num); 485 else 486 err = sdei_do_cross_call(_ipi_event_disable, event); 487 mutex_unlock(&sdei_events_lock); 488 489 return err; 490 } 491 492 static int sdei_api_event_unregister(u32 event_num) 493 { 494 return invoke_sdei_fn(SDEI_1_0_FN_SDEI_EVENT_UNREGISTER, event_num, 0, 495 0, 0, 0, NULL); 496 } 497 498 /* Called directly by the hotplug callbacks */ 499 static void _local_event_unregister(void *data) 500 { 501 int err; 502 struct sdei_crosscall_args *arg = data; 503 504 err = sdei_api_event_unregister(arg->event->event_num); 505 506 sdei_cross_call_return(arg, err); 507 } 508 509 int sdei_event_unregister(u32 event_num) 510 { 511 int err; 512 struct sdei_event *event; 513 514 WARN_ON(in_nmi()); 515 516 mutex_lock(&sdei_events_lock); 517 event = sdei_event_find(event_num); 518 if (!event) { 519 pr_warn("Event %u not registered\n", event_num); 520 err = -ENOENT; 521 goto unlock; 522 } 523 524 spin_lock(&sdei_list_lock); 525 event->reregister = false; 526 event->reenable = false; 527 spin_unlock(&sdei_list_lock); 528 529 if (event->type == SDEI_EVENT_TYPE_SHARED) 530 err = sdei_api_event_unregister(event->event_num); 531 else 532 err = sdei_do_cross_call(_local_event_unregister, event); 533 534 if (err) 535 goto unlock; 536 537 sdei_event_destroy(event); 538 unlock: 539 mutex_unlock(&sdei_events_lock); 540 541 return err; 542 } 543 544 /* 545 * unregister events, but don't destroy them as they are re-registered by 546 * sdei_reregister_shared(). 547 */ 548 static int sdei_unregister_shared(void) 549 { 550 int err = 0; 551 struct sdei_event *event; 552 553 mutex_lock(&sdei_events_lock); 554 spin_lock(&sdei_list_lock); 555 list_for_each_entry(event, &sdei_list, list) { 556 if (event->type != SDEI_EVENT_TYPE_SHARED) 557 continue; 558 559 err = sdei_api_event_unregister(event->event_num); 560 if (err) 561 break; 562 } 563 spin_unlock(&sdei_list_lock); 564 mutex_unlock(&sdei_events_lock); 565 566 return err; 567 } 568 569 static int sdei_api_event_register(u32 event_num, unsigned long entry_point, 570 void *arg, u64 flags, u64 affinity) 571 { 572 return invoke_sdei_fn(SDEI_1_0_FN_SDEI_EVENT_REGISTER, event_num, 573 (unsigned long)entry_point, (unsigned long)arg, 574 flags, affinity, NULL); 575 } 576 577 /* Called directly by the hotplug callbacks */ 578 static void _local_event_register(void *data) 579 { 580 int err; 581 struct sdei_registered_event *reg; 582 struct sdei_crosscall_args *arg = data; 583 584 reg = per_cpu_ptr(arg->event->private_registered, smp_processor_id()); 585 err = sdei_api_event_register(arg->event->event_num, sdei_entry_point, 586 reg, 0, 0); 587 588 sdei_cross_call_return(arg, err); 589 } 590 591 int sdei_event_register(u32 event_num, sdei_event_callback *cb, void *arg) 592 { 593 int err; 594 struct sdei_event *event; 595 596 WARN_ON(in_nmi()); 597 598 mutex_lock(&sdei_events_lock); 599 if (sdei_event_find(event_num)) { 600 pr_warn("Event %u already registered\n", event_num); 601 err = -EBUSY; 602 goto unlock; 603 } 604 605 event = sdei_event_create(event_num, cb, arg); 606 if (IS_ERR(event)) { 607 err = PTR_ERR(event); 608 pr_warn("Failed to create event %u: %d\n", event_num, err); 609 goto unlock; 610 } 611 612 cpus_read_lock(); 613 if (event->type == SDEI_EVENT_TYPE_SHARED) { 614 err = sdei_api_event_register(event->event_num, 615 sdei_entry_point, 616 event->registered, 617 SDEI_EVENT_REGISTER_RM_ANY, 0); 618 } else { 619 err = sdei_do_cross_call(_local_event_register, event); 620 if (err) 621 sdei_do_cross_call(_local_event_unregister, event); 622 } 623 624 if (err) { 625 sdei_event_destroy(event); 626 pr_warn("Failed to register event %u: %d\n", event_num, err); 627 goto cpu_unlock; 628 } 629 630 spin_lock(&sdei_list_lock); 631 event->reregister = true; 632 spin_unlock(&sdei_list_lock); 633 cpu_unlock: 634 cpus_read_unlock(); 635 unlock: 636 mutex_unlock(&sdei_events_lock); 637 return err; 638 } 639 640 static int sdei_reregister_shared(void) 641 { 642 int err = 0; 643 struct sdei_event *event; 644 645 mutex_lock(&sdei_events_lock); 646 spin_lock(&sdei_list_lock); 647 list_for_each_entry(event, &sdei_list, list) { 648 if (event->type != SDEI_EVENT_TYPE_SHARED) 649 continue; 650 651 if (event->reregister) { 652 err = sdei_api_event_register(event->event_num, 653 sdei_entry_point, event->registered, 654 SDEI_EVENT_REGISTER_RM_ANY, 0); 655 if (err) { 656 pr_err("Failed to re-register event %u\n", 657 event->event_num); 658 sdei_event_destroy_llocked(event); 659 break; 660 } 661 } 662 663 if (event->reenable) { 664 err = sdei_api_event_enable(event->event_num); 665 if (err) { 666 pr_err("Failed to re-enable event %u\n", 667 event->event_num); 668 break; 669 } 670 } 671 } 672 spin_unlock(&sdei_list_lock); 673 mutex_unlock(&sdei_events_lock); 674 675 return err; 676 } 677 678 static int sdei_cpuhp_down(unsigned int cpu) 679 { 680 struct sdei_event *event; 681 int err; 682 683 /* un-register private events */ 684 spin_lock(&sdei_list_lock); 685 list_for_each_entry(event, &sdei_list, list) { 686 if (event->type == SDEI_EVENT_TYPE_SHARED) 687 continue; 688 689 err = sdei_do_local_call(_local_event_unregister, event); 690 if (err) { 691 pr_err("Failed to unregister event %u: %d\n", 692 event->event_num, err); 693 } 694 } 695 spin_unlock(&sdei_list_lock); 696 697 return sdei_mask_local_cpu(); 698 } 699 700 static int sdei_cpuhp_up(unsigned int cpu) 701 { 702 struct sdei_event *event; 703 int err; 704 705 /* re-register/enable private events */ 706 spin_lock(&sdei_list_lock); 707 list_for_each_entry(event, &sdei_list, list) { 708 if (event->type == SDEI_EVENT_TYPE_SHARED) 709 continue; 710 711 if (event->reregister) { 712 err = sdei_do_local_call(_local_event_register, event); 713 if (err) { 714 pr_err("Failed to re-register event %u: %d\n", 715 event->event_num, err); 716 } 717 } 718 719 if (event->reenable) { 720 err = sdei_do_local_call(_local_event_enable, event); 721 if (err) { 722 pr_err("Failed to re-enable event %u: %d\n", 723 event->event_num, err); 724 } 725 } 726 } 727 spin_unlock(&sdei_list_lock); 728 729 return sdei_unmask_local_cpu(); 730 } 731 732 /* When entering idle, mask/unmask events for this cpu */ 733 static int sdei_pm_notifier(struct notifier_block *nb, unsigned long action, 734 void *data) 735 { 736 int rv; 737 738 WARN_ON_ONCE(preemptible()); 739 740 switch (action) { 741 case CPU_PM_ENTER: 742 rv = sdei_mask_local_cpu(); 743 break; 744 case CPU_PM_EXIT: 745 case CPU_PM_ENTER_FAILED: 746 rv = sdei_unmask_local_cpu(); 747 break; 748 default: 749 return NOTIFY_DONE; 750 } 751 752 if (rv) 753 return notifier_from_errno(rv); 754 755 return NOTIFY_OK; 756 } 757 758 static struct notifier_block sdei_pm_nb = { 759 .notifier_call = sdei_pm_notifier, 760 }; 761 762 static int sdei_device_suspend(struct device *dev) 763 { 764 on_each_cpu(_ipi_mask_cpu, NULL, true); 765 766 return 0; 767 } 768 769 static int sdei_device_resume(struct device *dev) 770 { 771 on_each_cpu(_ipi_unmask_cpu, NULL, true); 772 773 return 0; 774 } 775 776 /* 777 * We need all events to be reregistered when we resume from hibernate. 778 * 779 * The sequence is freeze->thaw. Reboot. freeze->restore. We unregister 780 * events during freeze, then re-register and re-enable them during thaw 781 * and restore. 782 */ 783 static int sdei_device_freeze(struct device *dev) 784 { 785 int err; 786 787 /* unregister private events */ 788 cpuhp_remove_state(sdei_hp_state); 789 790 err = sdei_unregister_shared(); 791 if (err) 792 return err; 793 794 return 0; 795 } 796 797 static int sdei_device_thaw(struct device *dev) 798 { 799 int err; 800 801 /* re-register shared events */ 802 err = sdei_reregister_shared(); 803 if (err) { 804 pr_warn("Failed to re-register shared events...\n"); 805 sdei_mark_interface_broken(); 806 return err; 807 } 808 809 err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "SDEI", 810 &sdei_cpuhp_up, &sdei_cpuhp_down); 811 if (err < 0) { 812 pr_warn("Failed to re-register CPU hotplug notifier...\n"); 813 return err; 814 } 815 816 sdei_hp_state = err; 817 return 0; 818 } 819 820 static int sdei_device_restore(struct device *dev) 821 { 822 int err; 823 824 err = sdei_platform_reset(); 825 if (err) 826 return err; 827 828 return sdei_device_thaw(dev); 829 } 830 831 static const struct dev_pm_ops sdei_pm_ops = { 832 .suspend = sdei_device_suspend, 833 .resume = sdei_device_resume, 834 .freeze = sdei_device_freeze, 835 .thaw = sdei_device_thaw, 836 .restore = sdei_device_restore, 837 }; 838 839 /* 840 * Mask all CPUs and unregister all events on panic, reboot or kexec. 841 */ 842 static int sdei_reboot_notifier(struct notifier_block *nb, unsigned long action, 843 void *data) 844 { 845 /* 846 * We are going to reset the interface, after this there is no point 847 * doing work when we take CPUs offline. 848 */ 849 cpuhp_remove_state(sdei_hp_state); 850 851 sdei_platform_reset(); 852 853 return NOTIFY_OK; 854 } 855 856 static struct notifier_block sdei_reboot_nb = { 857 .notifier_call = sdei_reboot_notifier, 858 }; 859 860 static void sdei_smccc_smc(unsigned long function_id, 861 unsigned long arg0, unsigned long arg1, 862 unsigned long arg2, unsigned long arg3, 863 unsigned long arg4, struct arm_smccc_res *res) 864 { 865 arm_smccc_smc(function_id, arg0, arg1, arg2, arg3, arg4, 0, 0, res); 866 } 867 NOKPROBE_SYMBOL(sdei_smccc_smc); 868 869 static void sdei_smccc_hvc(unsigned long function_id, 870 unsigned long arg0, unsigned long arg1, 871 unsigned long arg2, unsigned long arg3, 872 unsigned long arg4, struct arm_smccc_res *res) 873 { 874 arm_smccc_hvc(function_id, arg0, arg1, arg2, arg3, arg4, 0, 0, res); 875 } 876 NOKPROBE_SYMBOL(sdei_smccc_hvc); 877 878 int sdei_register_ghes(struct ghes *ghes, sdei_event_callback *normal_cb, 879 sdei_event_callback *critical_cb) 880 { 881 int err; 882 u64 result; 883 u32 event_num; 884 sdei_event_callback *cb; 885 886 if (!IS_ENABLED(CONFIG_ACPI_APEI_GHES)) 887 return -EOPNOTSUPP; 888 889 event_num = ghes->generic->notify.vector; 890 if (event_num == 0) { 891 /* 892 * Event 0 is reserved by the specification for 893 * SDEI_EVENT_SIGNAL. 894 */ 895 return -EINVAL; 896 } 897 898 err = sdei_api_event_get_info(event_num, SDEI_EVENT_INFO_EV_PRIORITY, 899 &result); 900 if (err) 901 return err; 902 903 if (result == SDEI_EVENT_PRIORITY_CRITICAL) 904 cb = critical_cb; 905 else 906 cb = normal_cb; 907 908 err = sdei_event_register(event_num, cb, ghes); 909 if (!err) 910 err = sdei_event_enable(event_num); 911 912 return err; 913 } 914 915 int sdei_unregister_ghes(struct ghes *ghes) 916 { 917 int i; 918 int err; 919 u32 event_num = ghes->generic->notify.vector; 920 921 might_sleep(); 922 923 if (!IS_ENABLED(CONFIG_ACPI_APEI_GHES)) 924 return -EOPNOTSUPP; 925 926 /* 927 * The event may be running on another CPU. Disable it 928 * to stop new events, then try to unregister a few times. 929 */ 930 err = sdei_event_disable(event_num); 931 if (err) 932 return err; 933 934 for (i = 0; i < 3; i++) { 935 err = sdei_event_unregister(event_num); 936 if (err != -EINPROGRESS) 937 break; 938 939 schedule(); 940 } 941 942 return err; 943 } 944 945 static int sdei_get_conduit(struct platform_device *pdev) 946 { 947 const char *method; 948 struct device_node *np = pdev->dev.of_node; 949 950 sdei_firmware_call = NULL; 951 if (np) { 952 if (of_property_read_string(np, "method", &method)) { 953 pr_warn("missing \"method\" property\n"); 954 return SMCCC_CONDUIT_NONE; 955 } 956 957 if (!strcmp("hvc", method)) { 958 sdei_firmware_call = &sdei_smccc_hvc; 959 return SMCCC_CONDUIT_HVC; 960 } else if (!strcmp("smc", method)) { 961 sdei_firmware_call = &sdei_smccc_smc; 962 return SMCCC_CONDUIT_SMC; 963 } 964 965 pr_warn("invalid \"method\" property: %s\n", method); 966 } else if (!acpi_disabled) { 967 if (acpi_psci_use_hvc()) { 968 sdei_firmware_call = &sdei_smccc_hvc; 969 return SMCCC_CONDUIT_HVC; 970 } else { 971 sdei_firmware_call = &sdei_smccc_smc; 972 return SMCCC_CONDUIT_SMC; 973 } 974 } 975 976 return SMCCC_CONDUIT_NONE; 977 } 978 979 static int sdei_probe(struct platform_device *pdev) 980 { 981 int err; 982 u64 ver = 0; 983 int conduit; 984 985 conduit = sdei_get_conduit(pdev); 986 if (!sdei_firmware_call) 987 return 0; 988 989 err = sdei_api_get_version(&ver); 990 if (err) { 991 pr_err("Failed to get SDEI version: %d\n", err); 992 sdei_mark_interface_broken(); 993 return err; 994 } 995 996 pr_info("SDEIv%d.%d (0x%x) detected in firmware.\n", 997 (int)SDEI_VERSION_MAJOR(ver), (int)SDEI_VERSION_MINOR(ver), 998 (int)SDEI_VERSION_VENDOR(ver)); 999 1000 if (SDEI_VERSION_MAJOR(ver) != 1) { 1001 pr_warn("Conflicting SDEI version detected.\n"); 1002 sdei_mark_interface_broken(); 1003 return -EINVAL; 1004 } 1005 1006 err = sdei_platform_reset(); 1007 if (err) 1008 return err; 1009 1010 sdei_entry_point = sdei_arch_get_entry_point(conduit); 1011 if (!sdei_entry_point) { 1012 /* Not supported due to hardware or boot configuration */ 1013 sdei_mark_interface_broken(); 1014 return 0; 1015 } 1016 1017 err = cpu_pm_register_notifier(&sdei_pm_nb); 1018 if (err) { 1019 pr_warn("Failed to register CPU PM notifier...\n"); 1020 goto error; 1021 } 1022 1023 err = register_reboot_notifier(&sdei_reboot_nb); 1024 if (err) { 1025 pr_warn("Failed to register reboot notifier...\n"); 1026 goto remove_cpupm; 1027 } 1028 1029 err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "SDEI", 1030 &sdei_cpuhp_up, &sdei_cpuhp_down); 1031 if (err < 0) { 1032 pr_warn("Failed to register CPU hotplug notifier...\n"); 1033 goto remove_reboot; 1034 } 1035 1036 sdei_hp_state = err; 1037 1038 return 0; 1039 1040 remove_reboot: 1041 unregister_reboot_notifier(&sdei_reboot_nb); 1042 1043 remove_cpupm: 1044 cpu_pm_unregister_notifier(&sdei_pm_nb); 1045 1046 error: 1047 sdei_mark_interface_broken(); 1048 return err; 1049 } 1050 1051 static const struct of_device_id sdei_of_match[] = { 1052 { .compatible = "arm,sdei-1.0" }, 1053 {} 1054 }; 1055 1056 static struct platform_driver sdei_driver = { 1057 .driver = { 1058 .name = "sdei", 1059 .pm = &sdei_pm_ops, 1060 .of_match_table = sdei_of_match, 1061 }, 1062 .probe = sdei_probe, 1063 }; 1064 1065 static bool __init sdei_present_acpi(void) 1066 { 1067 acpi_status status; 1068 struct acpi_table_header *sdei_table_header; 1069 1070 if (acpi_disabled) 1071 return false; 1072 1073 status = acpi_get_table(ACPI_SIG_SDEI, 0, &sdei_table_header); 1074 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { 1075 const char *msg = acpi_format_exception(status); 1076 1077 pr_info("Failed to get ACPI:SDEI table, %s\n", msg); 1078 } 1079 if (ACPI_FAILURE(status)) 1080 return false; 1081 1082 acpi_put_table(sdei_table_header); 1083 1084 return true; 1085 } 1086 1087 void __init acpi_sdei_init(void) 1088 { 1089 struct platform_device *pdev; 1090 int ret; 1091 1092 if (!sdei_present_acpi()) 1093 return; 1094 1095 pdev = platform_device_register_simple(sdei_driver.driver.name, 1096 0, NULL, 0); 1097 if (IS_ERR(pdev)) { 1098 ret = PTR_ERR(pdev); 1099 platform_driver_unregister(&sdei_driver); 1100 pr_info("Failed to register ACPI:SDEI platform device %d\n", 1101 ret); 1102 } 1103 } 1104 1105 static int __init sdei_init(void) 1106 { 1107 return platform_driver_register(&sdei_driver); 1108 } 1109 arch_initcall(sdei_init); 1110 1111 int sdei_event_handler(struct pt_regs *regs, 1112 struct sdei_registered_event *arg) 1113 { 1114 int err; 1115 u32 event_num = arg->event_num; 1116 1117 err = arg->callback(event_num, regs, arg->callback_arg); 1118 if (err) 1119 pr_err_ratelimited("event %u on CPU %u failed with error: %d\n", 1120 event_num, smp_processor_id(), err); 1121 1122 return err; 1123 } 1124 NOKPROBE_SYMBOL(sdei_event_handler); 1125 1126 void sdei_handler_abort(void) 1127 { 1128 /* 1129 * If the crash happened in an SDEI event handler then we need to 1130 * finish the handler with the firmware so that we can have working 1131 * interrupts in the crash kernel. 1132 */ 1133 if (__this_cpu_read(sdei_active_critical_event)) { 1134 pr_warn("still in SDEI critical event context, attempting to finish handler.\n"); 1135 __sdei_handler_abort(); 1136 __this_cpu_write(sdei_active_critical_event, NULL); 1137 } 1138 if (__this_cpu_read(sdei_active_normal_event)) { 1139 pr_warn("still in SDEI normal event context, attempting to finish handler.\n"); 1140 __sdei_handler_abort(); 1141 __this_cpu_write(sdei_active_normal_event, NULL); 1142 } 1143 } 1144