| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: fault.c,v 1.108 2019/04/06 03:06:25 thorpej Exp $ */ | | 1 | /* $NetBSD: fault.c,v 1.108.4.1 2019/12/08 14:31:57 martin Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright 2003 Wasabi Systems, Inc. | | 4 | * Copyright 2003 Wasabi Systems, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Written by Steve C. Woodford for Wasabi Systems, Inc. | | 7 | * Written by Steve C. Woodford for Wasabi Systems, Inc. |
8 | * | | 8 | * |
9 | * Redistribution and use in source and binary forms, with or without | | 9 | * Redistribution and use in source and binary forms, with or without |
10 | * modification, are permitted provided that the following conditions | | 10 | * modification, are permitted provided that the following conditions |
11 | * are met: | | 11 | * are met: |
12 | * 1. Redistributions of source code must retain the above copyright | | 12 | * 1. Redistributions of source code must retain the above copyright |
13 | * notice, this list of conditions and the following disclaimer. | | 13 | * notice, this list of conditions and the following disclaimer. |
14 | * 2. Redistributions in binary form must reproduce the above copyright | | 14 | * 2. Redistributions in binary form must reproduce the above copyright |
| @@ -71,27 +71,27 @@ | | | @@ -71,27 +71,27 @@ |
71 | * RiscBSD kernel project | | 71 | * RiscBSD kernel project |
72 | * | | 72 | * |
73 | * fault.c | | 73 | * fault.c |
74 | * | | 74 | * |
75 | * Fault handlers | | 75 | * Fault handlers |
76 | * | | 76 | * |
77 | * Created : 28/11/94 | | 77 | * Created : 28/11/94 |
78 | */ | | 78 | */ |
79 | | | 79 | |
80 | #include "opt_ddb.h" | | 80 | #include "opt_ddb.h" |
81 | #include "opt_kgdb.h" | | 81 | #include "opt_kgdb.h" |
82 | | | 82 | |
83 | #include <sys/types.h> | | 83 | #include <sys/types.h> |
84 | __KERNEL_RCSID(0, "$NetBSD: fault.c,v 1.108 2019/04/06 03:06:25 thorpej Exp $"); | | 84 | __KERNEL_RCSID(0, "$NetBSD: fault.c,v 1.108.4.1 2019/12/08 14:31:57 martin Exp $"); |
85 | | | 85 | |
86 | #include <sys/param.h> | | 86 | #include <sys/param.h> |
87 | #include <sys/systm.h> | | 87 | #include <sys/systm.h> |
88 | #include <sys/proc.h> | | 88 | #include <sys/proc.h> |
89 | #include <sys/kernel.h> | | 89 | #include <sys/kernel.h> |
90 | #include <sys/kauth.h> | | 90 | #include <sys/kauth.h> |
91 | #include <sys/cpu.h> | | 91 | #include <sys/cpu.h> |
92 | #include <sys/intr.h> | | 92 | #include <sys/intr.h> |
93 | | | 93 | |
94 | #include <uvm/uvm_extern.h> | | 94 | #include <uvm/uvm_extern.h> |
95 | #include <uvm/uvm_stat.h> | | 95 | #include <uvm/uvm_stat.h> |
96 | #ifdef UVMHIST | | 96 | #ifdef UVMHIST |
97 | #include <uvm/uvm.h> | | 97 | #include <uvm/uvm.h> |
| @@ -828,26 +828,29 @@ prefetch_abort_handler(trapframe_t *tf) | | | @@ -828,26 +828,29 @@ prefetch_abort_handler(trapframe_t *tf) |
828 | break; | | 828 | break; |
829 | } | | 829 | } |
830 | | | 830 | |
831 | /* Prefetch aborts cannot happen in kernel mode */ | | 831 | /* Prefetch aborts cannot happen in kernel mode */ |
832 | if (__predict_false(!user)) | | 832 | if (__predict_false(!user)) |
833 | dab_fatal(tf, 0, tf->tf_pc, NULL, NULL); | | 833 | dab_fatal(tf, 0, tf->tf_pc, NULL, NULL); |
834 | | | 834 | |
835 | /* Get fault address */ | | 835 | /* Get fault address */ |
836 | fault_pc = tf->tf_pc; | | 836 | fault_pc = tf->tf_pc; |
837 | KASSERTMSG(tf == lwp_trapframe(l), "tf %p vs %p", tf, lwp_trapframe(l)); | | 837 | KASSERTMSG(tf == lwp_trapframe(l), "tf %p vs %p", tf, lwp_trapframe(l)); |
838 | UVMHIST_LOG(maphist, " (pc=0x%jx, l=0x%#jx, tf=0x%#jx)", | | 838 | UVMHIST_LOG(maphist, " (pc=0x%jx, l=0x%#jx, tf=0x%#jx)", |
839 | fault_pc, (uintptr_t)l, (uintptr_t)tf, 0); | | 839 | fault_pc, (uintptr_t)l, (uintptr_t)tf, 0); |
840 | | | 840 | |
| | | 841 | #ifdef THUMB_CODE |
| | | 842 | recheck: |
| | | 843 | #endif |
841 | /* Ok validate the address, can only execute in USER space */ | | 844 | /* Ok validate the address, can only execute in USER space */ |
842 | if (__predict_false(fault_pc >= VM_MAXUSER_ADDRESS || | | 845 | if (__predict_false(fault_pc >= VM_MAXUSER_ADDRESS || |
843 | (fault_pc < VM_MIN_ADDRESS && vector_page == ARM_VECTORS_LOW))) { | | 846 | (fault_pc < VM_MIN_ADDRESS && vector_page == ARM_VECTORS_LOW))) { |
844 | KSI_INIT_TRAP(&ksi); | | 847 | KSI_INIT_TRAP(&ksi); |
845 | ksi.ksi_signo = SIGSEGV; | | 848 | ksi.ksi_signo = SIGSEGV; |
846 | ksi.ksi_code = SEGV_ACCERR; | | 849 | ksi.ksi_code = SEGV_ACCERR; |
847 | ksi.ksi_addr = (uint32_t *)(intptr_t) fault_pc; | | 850 | ksi.ksi_addr = (uint32_t *)(intptr_t) fault_pc; |
848 | ksi.ksi_trap = fault_pc; | | 851 | ksi.ksi_trap = fault_pc; |
849 | goto do_trapsignal; | | 852 | goto do_trapsignal; |
850 | } | | 853 | } |
851 | | | 854 | |
852 | map = &l->l_proc->p_vmspace->vm_map; | | 855 | map = &l->l_proc->p_vmspace->vm_map; |
853 | va = trunc_page(fault_pc); | | 856 | va = trunc_page(fault_pc); |
| @@ -887,26 +890,38 @@ prefetch_abort_handler(trapframe_t *tf) | | | @@ -887,26 +890,38 @@ prefetch_abort_handler(trapframe_t *tf) |
887 | l->l_cred ? kauth_cred_geteuid(l->l_cred) : -1); | | 890 | l->l_cred ? kauth_cred_geteuid(l->l_cred) : -1); |
888 | ksi.ksi_signo = SIGKILL; | | 891 | ksi.ksi_signo = SIGKILL; |
889 | } else | | 892 | } else |
890 | ksi.ksi_signo = SIGSEGV; | | 893 | ksi.ksi_signo = SIGSEGV; |
891 | | | 894 | |
892 | ksi.ksi_code = SEGV_MAPERR; | | 895 | ksi.ksi_code = SEGV_MAPERR; |
893 | ksi.ksi_addr = (uint32_t *)(intptr_t) fault_pc; | | 896 | ksi.ksi_addr = (uint32_t *)(intptr_t) fault_pc; |
894 | ksi.ksi_trap = fault_pc; | | 897 | ksi.ksi_trap = fault_pc; |
895 | | | 898 | |
896 | do_trapsignal: | | 899 | do_trapsignal: |
897 | call_trapsignal(l, tf, &ksi); | | 900 | call_trapsignal(l, tf, &ksi); |
898 | | | 901 | |
899 | out: | | 902 | out: |
| | | 903 | |
| | | 904 | #ifdef THUMB_CODE |
| | | 905 | #define THUMB_32BIT(hi) (((hi) & 0xe000) == 0xe000 && ((hi) & 0x1800)) |
| | | 906 | /* thumb-32 instruction was located on page boundary? */ |
| | | 907 | if ((tf->tf_spsr & PSR_T_bit) && |
| | | 908 | ((fault_pc & PAGE_MASK) == (PAGE_SIZE - THUMB_INSN_SIZE)) && |
| | | 909 | THUMB_32BIT(*(uint16_t *)tf->tf_pc)) { |
| | | 910 | fault_pc = tf->tf_pc + THUMB_INSN_SIZE; |
| | | 911 | goto recheck; |
| | | 912 | } |
| | | 913 | #endif /* THUMB_CODE */ |
| | | 914 | |
900 | KASSERT(!TRAP_USERMODE(tf) || VALID_R15_PSR(tf->tf_pc, tf->tf_spsr)); | | 915 | KASSERT(!TRAP_USERMODE(tf) || VALID_R15_PSR(tf->tf_pc, tf->tf_spsr)); |
901 | userret(l); | | 916 | userret(l); |
902 | } | | 917 | } |
903 | | | 918 | |
904 | /* | | 919 | /* |
905 | * Tentatively read an 8, 16, or 32-bit value from 'addr'. | | 920 | * Tentatively read an 8, 16, or 32-bit value from 'addr'. |
906 | * If the read succeeds, the value is written to 'rptr' and zero is returned. | | 921 | * If the read succeeds, the value is written to 'rptr' and zero is returned. |
907 | * Else, return EFAULT. | | 922 | * Else, return EFAULT. |
908 | */ | | 923 | */ |
909 | int | | 924 | int |
910 | badaddr_read(void *addr, size_t size, void *rptr) | | 925 | badaddr_read(void *addr, size_t size, void *rptr) |
911 | { | | 926 | { |
912 | extern int badaddr_read_1(const uint8_t *, uint8_t *); | | 927 | extern int badaddr_read_1(const uint8_t *, uint8_t *); |