| .. | .. |
|---|
| 264 | 264 | (esr & ESR_ELx_FSC_TYPE) != ESR_ELx_FSC_FAULT) |
|---|
| 265 | 265 | return false; |
|---|
| 266 | 266 | |
|---|
| 267 | | - local_irq_save(flags); |
|---|
| 267 | + flags = hard_local_irq_save(); |
|---|
| 268 | 268 | asm volatile("at s1e1r, %0" :: "r" (addr)); |
|---|
| 269 | 269 | isb(); |
|---|
| 270 | 270 | par = read_sysreg_par(); |
|---|
| 271 | | - local_irq_restore(flags); |
|---|
| 271 | + hard_local_irq_restore(flags); |
|---|
| 272 | 272 | |
|---|
| 273 | 273 | /* |
|---|
| 274 | 274 | * If we now have a valid translation, treat the translation fault as |
|---|
| .. | .. |
|---|
| 399 | 399 | msg = "paging request"; |
|---|
| 400 | 400 | } |
|---|
| 401 | 401 | |
|---|
| 402 | + /* |
|---|
| 403 | + * Dovetail: Don't bother restoring the in-band stage in the |
|---|
| 404 | + * non-recoverable fault case, we got busted and a full stage |
|---|
| 405 | + * switch is likely to make things even worse. Try at least to |
|---|
| 406 | + * get some debug output before panicing. |
|---|
| 407 | + */ |
|---|
| 402 | 408 | die_kernel_fault(msg, addr, esr, regs); |
|---|
| 403 | 409 | } |
|---|
| 404 | 410 | |
|---|
| .. | .. |
|---|
| 471 | 477 | if (user_mode(regs)) { |
|---|
| 472 | 478 | const struct fault_info *inf = esr_to_fault_info(esr); |
|---|
| 473 | 479 | |
|---|
| 480 | + mark_trap_entry(ARM64_TRAP_ACCESS, regs); |
|---|
| 474 | 481 | set_thread_esr(addr, esr); |
|---|
| 475 | 482 | arm64_force_sig_fault(inf->sig, inf->code, far, inf->name); |
|---|
| 483 | + mark_trap_exit(ARM64_TRAP_ACCESS, regs); |
|---|
| 476 | 484 | } else { |
|---|
| 477 | 485 | __do_kernel_fault(addr, esr, regs); |
|---|
| 478 | 486 | } |
|---|
| .. | .. |
|---|
| 536 | 544 | |
|---|
| 537 | 545 | if (kprobe_page_fault(regs, esr)) |
|---|
| 538 | 546 | return 0; |
|---|
| 547 | + |
|---|
| 548 | + mark_trap_entry(ARM64_TRAP_ACCESS, regs); |
|---|
| 539 | 549 | |
|---|
| 540 | 550 | /* |
|---|
| 541 | 551 | * If we're in an interrupt or have no user context, we must not take |
|---|
| .. | .. |
|---|
| 612 | 622 | if (fault_signal_pending(fault, regs)) { |
|---|
| 613 | 623 | if (!user_mode(regs)) |
|---|
| 614 | 624 | goto no_context; |
|---|
| 615 | | - return 0; |
|---|
| 625 | + goto out; |
|---|
| 616 | 626 | } |
|---|
| 617 | 627 | |
|---|
| 618 | 628 | if (fault & VM_FAULT_RETRY) { |
|---|
| .. | .. |
|---|
| 637 | 647 | */ |
|---|
| 638 | 648 | if (likely(!(fault & (VM_FAULT_ERROR | VM_FAULT_BADMAP | |
|---|
| 639 | 649 | VM_FAULT_BADACCESS)))) |
|---|
| 640 | | - return 0; |
|---|
| 650 | + goto out; |
|---|
| 641 | 651 | |
|---|
| 642 | 652 | /* |
|---|
| 643 | 653 | * If we are in kernel mode at this point, we have no context to |
|---|
| .. | .. |
|---|
| 653 | 663 | * oom-killed). |
|---|
| 654 | 664 | */ |
|---|
| 655 | 665 | pagefault_out_of_memory(); |
|---|
| 656 | | - return 0; |
|---|
| 666 | + goto out; |
|---|
| 657 | 667 | } |
|---|
| 658 | 668 | |
|---|
| 659 | 669 | inf = esr_to_fault_info(esr); |
|---|
| .. | .. |
|---|
| 682 | 692 | far, inf->name); |
|---|
| 683 | 693 | } |
|---|
| 684 | 694 | |
|---|
| 685 | | - return 0; |
|---|
| 695 | + goto out; |
|---|
| 686 | 696 | |
|---|
| 687 | 697 | no_context: |
|---|
| 688 | 698 | __do_kernel_fault(addr, esr, regs); |
|---|
| 699 | +out: |
|---|
| 700 | + mark_trap_exit(ARM64_TRAP_ACCESS, regs); |
|---|
| 689 | 701 | return 0; |
|---|
| 690 | 702 | } |
|---|
| 691 | 703 | |
|---|
| .. | .. |
|---|
| 731 | 743 | const struct fault_info *inf; |
|---|
| 732 | 744 | unsigned long siaddr; |
|---|
| 733 | 745 | |
|---|
| 746 | + mark_trap_entry(ARM64_TRAP_SEA, regs); |
|---|
| 747 | + |
|---|
| 734 | 748 | inf = esr_to_fault_info(esr); |
|---|
| 735 | 749 | |
|---|
| 736 | 750 | if (user_mode(regs) && apei_claim_sea(regs) == 0) { |
|---|
| .. | .. |
|---|
| 738 | 752 | * APEI claimed this as a firmware-first notification. |
|---|
| 739 | 753 | * Some processing deferred to task_work before ret_to_user(). |
|---|
| 740 | 754 | */ |
|---|
| 741 | | - return 0; |
|---|
| 755 | + goto out; |
|---|
| 742 | 756 | } |
|---|
| 743 | 757 | |
|---|
| 744 | 758 | if (esr & ESR_ELx_FnV) { |
|---|
| .. | .. |
|---|
| 753 | 767 | } |
|---|
| 754 | 768 | trace_android_rvh_do_sea(regs, esr, siaddr, inf->name); |
|---|
| 755 | 769 | arm64_notify_die(inf->name, regs, inf->sig, inf->code, siaddr, esr); |
|---|
| 770 | +out: |
|---|
| 771 | + mark_trap_exit(ARM64_TRAP_SEA, regs); |
|---|
| 756 | 772 | |
|---|
| 757 | 773 | return 0; |
|---|
| 758 | 774 | } |
|---|
| .. | .. |
|---|
| 845 | 861 | if (!inf->fn(far, esr, regs)) |
|---|
| 846 | 862 | return; |
|---|
| 847 | 863 | |
|---|
| 864 | + mark_trap_entry(ARM64_TRAP_ACCESS, regs); |
|---|
| 865 | + |
|---|
| 848 | 866 | if (!user_mode(regs)) { |
|---|
| 849 | 867 | pr_alert("Unhandled fault at 0x%016lx\n", addr); |
|---|
| 850 | 868 | trace_android_rvh_do_mem_abort(regs, esr, addr, inf->name); |
|---|
| .. | .. |
|---|
| 858 | 876 | * address to the signal handler. |
|---|
| 859 | 877 | */ |
|---|
| 860 | 878 | arm64_notify_die(inf->name, regs, inf->sig, inf->code, addr, esr); |
|---|
| 879 | + mark_trap_exit(ARM64_TRAP_ACCESS, regs); |
|---|
| 861 | 880 | } |
|---|
| 862 | 881 | NOKPROBE_SYMBOL(do_mem_abort); |
|---|
| 863 | 882 | |
|---|
| .. | .. |
|---|
| 871 | 890 | void do_sp_pc_abort(unsigned long addr, unsigned int esr, struct pt_regs *regs) |
|---|
| 872 | 891 | { |
|---|
| 873 | 892 | trace_android_rvh_do_sp_pc_abort(regs, esr, addr, user_mode(regs)); |
|---|
| 893 | + mark_trap_entry(ARM64_TRAP_ALIGN, regs); |
|---|
| 874 | 894 | |
|---|
| 875 | 895 | arm64_notify_die("SP/PC alignment exception", regs, SIGBUS, BUS_ADRALN, |
|---|
| 876 | 896 | addr, esr); |
|---|
| 897 | + |
|---|
| 898 | + mark_trap_exit(ARM64_TRAP_ALIGN, regs); |
|---|
| 877 | 899 | } |
|---|
| 878 | 900 | NOKPROBE_SYMBOL(do_sp_pc_abort); |
|---|
| 879 | 901 | |
|---|
| .. | .. |
|---|
| 968 | 990 | if (cortex_a76_erratum_1463225_debug_handler(regs)) |
|---|
| 969 | 991 | return; |
|---|
| 970 | 992 | |
|---|
| 993 | + mark_trap_entry(ARM64_TRAP_DEBUG, regs); |
|---|
| 994 | + |
|---|
| 971 | 995 | debug_exception_enter(regs); |
|---|
| 972 | 996 | |
|---|
| 973 | 997 | if (user_mode(regs) && !is_ttbr0_addr(pc)) |
|---|
| .. | .. |
|---|
| 978 | 1002 | } |
|---|
| 979 | 1003 | |
|---|
| 980 | 1004 | debug_exception_exit(regs); |
|---|
| 1005 | + |
|---|
| 1006 | + mark_trap_exit(ARM64_TRAP_DEBUG, regs); |
|---|
| 981 | 1007 | } |
|---|
| 982 | 1008 | NOKPROBE_SYMBOL(do_debug_exception); |
|---|
| 983 | 1009 | |
|---|