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