.. | .. |
---|
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 | |
---|