xref: /freebsd/sys/arm/arm/trap-v6.c (revision fdafd315)
17e55f8c1SIan Lepore /*-
27e55f8c1SIan Lepore  * Copyright 2014 Olivier Houchard <cognet@FreeBSD.org>
37e55f8c1SIan Lepore  * Copyright 2014 Svatopluk Kraus <onwahe@gmail.com>
47e55f8c1SIan Lepore  * Copyright 2014 Michal Meloun <meloun@miracle.cz>
57e55f8c1SIan Lepore  * Copyright 2014 Andrew Turner <andrew@FreeBSD.org>
67e55f8c1SIan Lepore  * All rights reserved.
77e55f8c1SIan Lepore  *
87e55f8c1SIan Lepore  * Redistribution and use in source and binary forms, with or without
97e55f8c1SIan Lepore  * modification, are permitted provided that the following conditions
107e55f8c1SIan Lepore  * are met:
117e55f8c1SIan Lepore  * 1. Redistributions of source code must retain the above copyright
127e55f8c1SIan Lepore  *    notice, this list of conditions and the following disclaimer.
137e55f8c1SIan Lepore  * 2. Redistributions in binary form must reproduce the above copyright
147e55f8c1SIan Lepore  *    notice, this list of conditions and the following disclaimer in the
157e55f8c1SIan Lepore  *    documentation and/or other materials provided with the distribution.
167e55f8c1SIan Lepore  *
177e55f8c1SIan Lepore  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
187e55f8c1SIan Lepore  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
197e55f8c1SIan Lepore  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
207e55f8c1SIan Lepore  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
217e55f8c1SIan Lepore  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
227e55f8c1SIan Lepore  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
237e55f8c1SIan Lepore  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
247e55f8c1SIan Lepore  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
257e55f8c1SIan Lepore  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
267e55f8c1SIan Lepore  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
277e55f8c1SIan Lepore  * SUCH DAMAGE.
287e55f8c1SIan Lepore  */
297e55f8c1SIan Lepore 
307e55f8c1SIan Lepore #include "opt_ktrace.h"
317e55f8c1SIan Lepore 
327e55f8c1SIan Lepore #include <sys/param.h>
337e55f8c1SIan Lepore #include <sys/bus.h>
347e55f8c1SIan Lepore #include <sys/systm.h>
357e55f8c1SIan Lepore #include <sys/proc.h>
367e55f8c1SIan Lepore #include <sys/kernel.h>
377e55f8c1SIan Lepore #include <sys/lock.h>
387e55f8c1SIan Lepore #include <sys/mutex.h>
397e55f8c1SIan Lepore #include <sys/signalvar.h>
407e55f8c1SIan Lepore #include <sys/ktr.h>
419ed01c32SGleb Smirnoff #include <sys/vmmeter.h>
427e55f8c1SIan Lepore #ifdef KTRACE
437e55f8c1SIan Lepore #include <sys/uio.h>
447e55f8c1SIan Lepore #include <sys/ktrace.h>
457e55f8c1SIan Lepore #endif
467e55f8c1SIan Lepore 
477e55f8c1SIan Lepore #include <vm/vm.h>
487e55f8c1SIan Lepore #include <vm/pmap.h>
497e55f8c1SIan Lepore #include <vm/vm_kern.h>
507e55f8c1SIan Lepore #include <vm/vm_map.h>
517e55f8c1SIan Lepore #include <vm/vm_extern.h>
527e55f8c1SIan Lepore #include <vm/vm_param.h>
537e55f8c1SIan Lepore 
547e55f8c1SIan Lepore #include <machine/cpu.h>
557e55f8c1SIan Lepore #include <machine/frame.h>
567e55f8c1SIan Lepore #include <machine/machdep.h>
577e55f8c1SIan Lepore #include <machine/pcb.h>
587e55f8c1SIan Lepore 
597e55f8c1SIan Lepore #ifdef KDB
607e55f8c1SIan Lepore #include <sys/kdb.h>
617e55f8c1SIan Lepore #include <machine/db_machdep.h>
627e55f8c1SIan Lepore #endif
637e55f8c1SIan Lepore 
64c2188153SAndrew Turner #ifdef KDTRACE_HOOKS
65c2188153SAndrew Turner #include <sys/dtrace_bsd.h>
66c2188153SAndrew Turner #endif
67c2188153SAndrew Turner 
688826d904SIan Lepore extern char cachebailout[];
697e55f8c1SIan Lepore 
707e55f8c1SIan Lepore struct ksig {
717e55f8c1SIan Lepore 	int sig;
727e55f8c1SIan Lepore 	u_long code;
737e55f8c1SIan Lepore 	vm_offset_t	addr;
747e55f8c1SIan Lepore };
757e55f8c1SIan Lepore 
767e55f8c1SIan Lepore typedef int abort_func_t(struct trapframe *, u_int, u_int, u_int, u_int,
777e55f8c1SIan Lepore     struct thread *, struct ksig *);
787e55f8c1SIan Lepore 
797e55f8c1SIan Lepore static abort_func_t abort_fatal;
807e55f8c1SIan Lepore static abort_func_t abort_align;
817e55f8c1SIan Lepore static abort_func_t abort_icache;
827e55f8c1SIan Lepore 
837e55f8c1SIan Lepore struct abort {
847e55f8c1SIan Lepore 	abort_func_t	*func;
857e55f8c1SIan Lepore 	const char	*desc;
867e55f8c1SIan Lepore };
877e55f8c1SIan Lepore 
887e55f8c1SIan Lepore /*
897e55f8c1SIan Lepore  * How are the aborts handled?
907e55f8c1SIan Lepore  *
917e55f8c1SIan Lepore  * Undefined Code:
927e55f8c1SIan Lepore  *  - Always fatal as we do not know what does it mean.
937e55f8c1SIan Lepore  * Imprecise External Abort:
947e55f8c1SIan Lepore  *  - Always fatal, but can be handled somehow in the future.
9536fb9d5fSSvatopluk Kraus  *    Now, due to PCIe buggy hardware, ignored.
967e55f8c1SIan Lepore  * Precise External Abort:
977e55f8c1SIan Lepore  *  - Always fatal, but who knows in the future???
987e55f8c1SIan Lepore  * Debug Event:
997e55f8c1SIan Lepore  *  - Special handling.
1007e55f8c1SIan Lepore  * External Translation Abort (L1 & L2)
10136fb9d5fSSvatopluk Kraus  *  - Always fatal as something is screwed up in page tables or hardware.
1027e55f8c1SIan Lepore  * Domain Fault (L1 & L2):
1037e55f8c1SIan Lepore  *  - Always fatal as we do not play game with domains.
1047e55f8c1SIan Lepore  * Alignment Fault:
10536fb9d5fSSvatopluk Kraus  *  - Everything should be aligned in kernel with exception of user to kernel
10636fb9d5fSSvatopluk Kraus  *    and vice versa data copying, so if pcb_onfault is not set, it's fatal.
1077e55f8c1SIan Lepore  *    We generate signal in case of abort from user mode.
1087e55f8c1SIan Lepore  * Instruction cache maintenance:
1097e55f8c1SIan Lepore  *  - According to manual, this is translation fault during cache maintenance
1107e55f8c1SIan Lepore  *    operation. So, it could be really complex in SMP case and fuzzy too
1117e55f8c1SIan Lepore  *    for cache operations working on virtual addresses. For now, we will
1127e55f8c1SIan Lepore  *    consider this abort as fatal. In fact, no cache maintenance on
1137e55f8c1SIan Lepore  *    not mapped virtual addresses should be called. As cache maintenance
1145bdf58e1SGordon Bergling  *    operation (except DMB, DSB, and Flush Prefetch Buffer) are privileged,
1157e55f8c1SIan Lepore  *    the abort is fatal for user mode as well for now. (This is good place to
1167e55f8c1SIan Lepore  *    note that cache maintenance on virtual address fill TLB.)
1177e55f8c1SIan Lepore  * Acces Bit (L1 & L2):
1187e55f8c1SIan Lepore  *  - Fast hardware emulation for kernel and user mode.
1197e55f8c1SIan Lepore  * Translation Fault (L1 & L2):
1207e55f8c1SIan Lepore  *  - Standard fault mechanism is held including vm_fault().
1217e55f8c1SIan Lepore  * Permission Fault (L1 & L2):
12236fb9d5fSSvatopluk Kraus  *  - Fast hardware emulation of modify bits and in other cases, standard
1237e55f8c1SIan Lepore  *    fault mechanism is held including vm_fault().
1247e55f8c1SIan Lepore  */
1257e55f8c1SIan Lepore 
1267e55f8c1SIan Lepore static const struct abort aborts[] = {
1277e55f8c1SIan Lepore 	{abort_fatal,	"Undefined Code (0x000)"},
1287e55f8c1SIan Lepore 	{abort_align,	"Alignment Fault"},
1297e55f8c1SIan Lepore 	{abort_fatal,	"Debug Event"},
1307e55f8c1SIan Lepore 	{NULL,		"Access Bit (L1)"},
1318826d904SIan Lepore 	{NULL,		"Instruction cache maintenance"},
1327e55f8c1SIan Lepore 	{NULL,		"Translation Fault (L1)"},
1337e55f8c1SIan Lepore 	{NULL,		"Access Bit (L2)"},
1347e55f8c1SIan Lepore 	{NULL,		"Translation Fault (L2)"},
1357e55f8c1SIan Lepore 
1367e55f8c1SIan Lepore 	{abort_fatal,	"External Abort"},
1377e55f8c1SIan Lepore 	{abort_fatal,	"Domain Fault (L1)"},
1387e55f8c1SIan Lepore 	{abort_fatal,	"Undefined Code (0x00A)"},
1397e55f8c1SIan Lepore 	{abort_fatal,	"Domain Fault (L2)"},
1407e55f8c1SIan Lepore 	{abort_fatal,	"External Translation Abort (L1)"},
1417e55f8c1SIan Lepore 	{NULL,		"Permission Fault (L1)"},
1427e55f8c1SIan Lepore 	{abort_fatal,	"External Translation Abort (L2)"},
1437e55f8c1SIan Lepore 	{NULL,		"Permission Fault (L2)"},
1447e55f8c1SIan Lepore 
1457e55f8c1SIan Lepore 	{abort_fatal,	"TLB Conflict Abort"},
1467e55f8c1SIan Lepore 	{abort_fatal,	"Undefined Code (0x401)"},
1477e55f8c1SIan Lepore 	{abort_fatal,	"Undefined Code (0x402)"},
1487e55f8c1SIan Lepore 	{abort_fatal,	"Undefined Code (0x403)"},
1497e55f8c1SIan Lepore 	{abort_fatal,	"Undefined Code (0x404)"},
1507e55f8c1SIan Lepore 	{abort_fatal,	"Undefined Code (0x405)"},
1517e55f8c1SIan Lepore 	{abort_fatal,	"Asynchronous External Abort"},
1527e55f8c1SIan Lepore 	{abort_fatal,	"Undefined Code (0x407)"},
1537e55f8c1SIan Lepore 
1547e55f8c1SIan Lepore 	{abort_fatal,	"Asynchronous Parity Error on Memory Access"},
1557e55f8c1SIan Lepore 	{abort_fatal,	"Parity Error on Memory Access"},
1567e55f8c1SIan Lepore 	{abort_fatal,	"Undefined Code (0x40A)"},
1577e55f8c1SIan Lepore 	{abort_fatal,	"Undefined Code (0x40B)"},
1587e55f8c1SIan Lepore 	{abort_fatal,	"Parity Error on Translation (L1)"},
1597e55f8c1SIan Lepore 	{abort_fatal,	"Undefined Code (0x40D)"},
1607e55f8c1SIan Lepore 	{abort_fatal,	"Parity Error on Translation (L2)"},
1617e55f8c1SIan Lepore 	{abort_fatal,	"Undefined Code (0x40F)"}
1627e55f8c1SIan Lepore };
1637e55f8c1SIan Lepore 
1647e55f8c1SIan Lepore static __inline void
call_trapsignal(struct thread * td,int sig,int code,vm_offset_t addr,int trapno)16591371fbcSJohn Baldwin call_trapsignal(struct thread *td, int sig, int code, vm_offset_t addr,
16691371fbcSJohn Baldwin     int trapno)
1677e55f8c1SIan Lepore {
1687e55f8c1SIan Lepore 	ksiginfo_t ksi;
1697e55f8c1SIan Lepore 
1707e55f8c1SIan Lepore 	CTR4(KTR_TRAP, "%s: addr: %#x, sig: %d, code: %d",
1717e55f8c1SIan Lepore 	   __func__, addr, sig, code);
1727e55f8c1SIan Lepore 
1737e55f8c1SIan Lepore 	/*
1747e55f8c1SIan Lepore 	 * TODO: some info would be nice to know
1757e55f8c1SIan Lepore 	 * if we are serving data or prefetch abort.
1767e55f8c1SIan Lepore 	 */
1777e55f8c1SIan Lepore 
1787e55f8c1SIan Lepore 	ksiginfo_init_trap(&ksi);
1797e55f8c1SIan Lepore 	ksi.ksi_signo = sig;
1807e55f8c1SIan Lepore 	ksi.ksi_code = code;
1817e55f8c1SIan Lepore 	ksi.ksi_addr = (void *)addr;
18291371fbcSJohn Baldwin 	ksi.ksi_trapno = trapno;
1837e55f8c1SIan Lepore 	trapsignal(td, &ksi);
1847e55f8c1SIan Lepore }
1857e55f8c1SIan Lepore 
1867e55f8c1SIan Lepore /*
1877e55f8c1SIan Lepore  * abort_imprecise() handles the following abort:
1887e55f8c1SIan Lepore  *
1897e55f8c1SIan Lepore  *  FAULT_EA_IMPREC - Imprecise External Abort
1907e55f8c1SIan Lepore  *
1917e55f8c1SIan Lepore  * The imprecise means that we don't know where the abort happened,
1927e55f8c1SIan Lepore  * thus FAR is undefined. The abort should not never fire, but hot
19336fb9d5fSSvatopluk Kraus  * plugging or accidental hardware failure can be the cause of it.
1947e55f8c1SIan Lepore  * If the abort happens, it can even be on different (thread) context.
1957e55f8c1SIan Lepore  * Without any additional support, the abort is fatal, as we do not
1967e55f8c1SIan Lepore  * know what really happened.
1977e55f8c1SIan Lepore  *
1987e55f8c1SIan Lepore  * QQQ: Some additional functionality, like pcb_onfault but global,
1997e55f8c1SIan Lepore  *      can be implemented. Imprecise handlers could be registered
2007e55f8c1SIan Lepore  *      which tell us if the abort is caused by something they know
2017e55f8c1SIan Lepore  *      about. They should return one of three codes like:
2027e55f8c1SIan Lepore  *		FAULT_IS_MINE,
2037e55f8c1SIan Lepore  *		FAULT_CAN_BE_MINE,
2047e55f8c1SIan Lepore  *		FAULT_IS_NOT_MINE.
2057e55f8c1SIan Lepore  *      The handlers should be called until some of them returns
2067e55f8c1SIan Lepore  *      FAULT_IS_MINE value or all was called. If all handlers return
2077e55f8c1SIan Lepore  *	FAULT_IS_NOT_MINE value, then the abort is fatal.
2087e55f8c1SIan Lepore  */
2097e55f8c1SIan Lepore static __inline void
abort_imprecise(struct trapframe * tf,u_int fsr,u_int prefetch,bool usermode)210bee75f52SSvatopluk Kraus abort_imprecise(struct trapframe *tf, u_int fsr, u_int prefetch, bool usermode)
2117e55f8c1SIan Lepore {
21236fb9d5fSSvatopluk Kraus 
21336fb9d5fSSvatopluk Kraus 	/*
21436fb9d5fSSvatopluk Kraus 	 * XXX - We can got imprecise abort as result of access
2157e55f8c1SIan Lepore 	 * to not-present PCI/PCIe configuration space.
2167e55f8c1SIan Lepore 	 */
2177e55f8c1SIan Lepore #if 0
2187e55f8c1SIan Lepore 	goto out;
2197e55f8c1SIan Lepore #endif
2207e55f8c1SIan Lepore 	abort_fatal(tf, FAULT_EA_IMPREC, fsr, 0, prefetch, curthread, NULL);
2217e55f8c1SIan Lepore 
2227e55f8c1SIan Lepore 	/*
2237e55f8c1SIan Lepore 	 * Returning from this function means that we ignore
2247e55f8c1SIan Lepore 	 * the abort for good reason. Note that imprecise abort
2257e55f8c1SIan Lepore 	 * could fire any time even in user mode.
2267e55f8c1SIan Lepore 	 */
2277e55f8c1SIan Lepore 
2287e55f8c1SIan Lepore #if 0
2297e55f8c1SIan Lepore out:
2307e55f8c1SIan Lepore 	if (usermode)
2317e55f8c1SIan Lepore 		userret(curthread, tf);
2327e55f8c1SIan Lepore #endif
2337e55f8c1SIan Lepore }
2347e55f8c1SIan Lepore 
2357e55f8c1SIan Lepore /*
2367e55f8c1SIan Lepore  * abort_debug() handles the following abort:
2377e55f8c1SIan Lepore  *
2387e55f8c1SIan Lepore  *  FAULT_DEBUG - Debug Event
2397e55f8c1SIan Lepore  *
2407e55f8c1SIan Lepore  */
2417e55f8c1SIan Lepore static __inline void
abort_debug(struct trapframe * tf,u_int fsr,u_int prefetch,bool usermode,u_int far)242bee75f52SSvatopluk Kraus abort_debug(struct trapframe *tf, u_int fsr, u_int prefetch, bool usermode,
2437e55f8c1SIan Lepore     u_int far)
2447e55f8c1SIan Lepore {
24536fb9d5fSSvatopluk Kraus 
2467e55f8c1SIan Lepore 	if (usermode) {
2477e55f8c1SIan Lepore 		struct thread *td;
2487e55f8c1SIan Lepore 
2497e55f8c1SIan Lepore 		td = curthread;
25091371fbcSJohn Baldwin 		call_trapsignal(td, SIGTRAP, TRAP_BRKPT, far, FAULT_DEBUG);
2517e55f8c1SIan Lepore 		userret(td, tf);
2527e55f8c1SIan Lepore 	} else {
2537e55f8c1SIan Lepore #ifdef KDB
254595f8a59SZbigniew Bodek 		kdb_trap((prefetch) ? T_BREAKPOINT : T_WATCHPOINT, 0, tf);
2557e55f8c1SIan Lepore #else
2567e55f8c1SIan Lepore 		printf("No debugger in kernel.\n");
2577e55f8c1SIan Lepore #endif
2587e55f8c1SIan Lepore 	}
2597e55f8c1SIan Lepore }
2607e55f8c1SIan Lepore 
2617e55f8c1SIan Lepore /*
2627e55f8c1SIan Lepore  * Abort handler.
2637e55f8c1SIan Lepore  *
2647e55f8c1SIan Lepore  * FAR, FSR, and everything what can be lost after enabling
2657e55f8c1SIan Lepore  * interrupts must be grabbed before the interrupts will be
2667e55f8c1SIan Lepore  * enabled. Note that when interrupts will be enabled, we
2677e55f8c1SIan Lepore  * could even migrate to another CPU ...
2687e55f8c1SIan Lepore  *
2697e55f8c1SIan Lepore  * TODO: move quick cases to ASM
2707e55f8c1SIan Lepore  */
2717e55f8c1SIan Lepore void
abort_handler(struct trapframe * tf,int prefetch)2727e55f8c1SIan Lepore abort_handler(struct trapframe *tf, int prefetch)
2737e55f8c1SIan Lepore {
2747e55f8c1SIan Lepore 	struct thread *td;
2757e55f8c1SIan Lepore 	vm_offset_t far, va;
276bee75f52SSvatopluk Kraus 	int idx, rv;
2777e55f8c1SIan Lepore 	uint32_t fsr;
2787e55f8c1SIan Lepore 	struct ksig ksig;
2797e55f8c1SIan Lepore 	struct proc *p;
2807e55f8c1SIan Lepore 	struct pcb *pcb;
2817e55f8c1SIan Lepore 	struct vm_map *map;
2827e55f8c1SIan Lepore 	struct vmspace *vm;
2837e55f8c1SIan Lepore 	vm_prot_t ftype;
284bee75f52SSvatopluk Kraus 	bool usermode;
285df08823dSKonstantin Belousov 	int bp_harden, ucode;
2867e55f8c1SIan Lepore #ifdef INVARIANTS
2877e55f8c1SIan Lepore 	void *onfault;
2887e55f8c1SIan Lepore #endif
289f196c104SSvatopluk Kraus 
29083c9dea1SGleb Smirnoff 	VM_CNT_INC(v_trap);
2917e55f8c1SIan Lepore 	td = curthread;
292f196c104SSvatopluk Kraus 
2937e55f8c1SIan Lepore 	fsr = (prefetch) ? cp15_ifsr_get(): cp15_dfsr_get();
294d5b05f19SAndrew Turner #if __ARM_ARCH >= 7
295d5b05f19SAndrew Turner 	far = (prefetch) ? cp15_ifar_get() : cp15_dfar_get();
296d5b05f19SAndrew Turner #else
2977e55f8c1SIan Lepore 	far = (prefetch) ? TRAPF_PC(tf) : cp15_dfar_get();
298d5b05f19SAndrew Turner #endif
2997e55f8c1SIan Lepore 
3007e55f8c1SIan Lepore 	idx = FSR_TO_FAULT(fsr);
3017e55f8c1SIan Lepore 	usermode = TRAPF_USERMODE(tf);	/* Abort came from user mode? */
302a36b6ec0SMichal Meloun 
303a36b6ec0SMichal Meloun 	/*
304a36b6ec0SMichal Meloun 	 * Apply BP hardening by flushing the branch prediction cache
305a36b6ec0SMichal Meloun 	 * for prefaults on kernel addresses.
306a36b6ec0SMichal Meloun 	 */
307a36b6ec0SMichal Meloun 	if (__predict_false(prefetch && far > VM_MAXUSER_ADDRESS &&
308a36b6ec0SMichal Meloun 	    (idx == FAULT_TRAN_L2 || idx == FAULT_PERM_L2))) {
309a36b6ec0SMichal Meloun 		bp_harden = PCPU_GET(bp_harden_kind);
310a36b6ec0SMichal Meloun 		if (bp_harden == PCPU_BP_HARDEN_KIND_BPIALL)
311a36b6ec0SMichal Meloun 			_CP15_BPIALL();
312a36b6ec0SMichal Meloun 		else if (bp_harden == PCPU_BP_HARDEN_KIND_ICIALLU)
313a36b6ec0SMichal Meloun 			_CP15_ICIALLU();
314a36b6ec0SMichal Meloun 	}
315a36b6ec0SMichal Meloun 
3167e55f8c1SIan Lepore 	if (usermode)
3177e55f8c1SIan Lepore 		td->td_frame = tf;
3187e55f8c1SIan Lepore 
3193ee1f8b1SSvatopluk Kraus 	CTR6(KTR_TRAP, "%s: fsr %#x (idx %u) far %#x prefetch %u usermode %d",
3203ee1f8b1SSvatopluk Kraus 	    __func__, fsr, idx, far, prefetch, usermode);
3217e55f8c1SIan Lepore 
3227e55f8c1SIan Lepore 	/*
3237e55f8c1SIan Lepore 	 * Firstly, handle aborts that are not directly related to mapping.
3247e55f8c1SIan Lepore 	 */
3257e55f8c1SIan Lepore 	if (__predict_false(idx == FAULT_EA_IMPREC)) {
3267e55f8c1SIan Lepore 		abort_imprecise(tf, fsr, prefetch, usermode);
3277e55f8c1SIan Lepore 		return;
3287e55f8c1SIan Lepore 	}
3297e55f8c1SIan Lepore 
3307e55f8c1SIan Lepore 	if (__predict_false(idx == FAULT_DEBUG)) {
3317e55f8c1SIan Lepore 		abort_debug(tf, fsr, prefetch, usermode, far);
3327e55f8c1SIan Lepore 		return;
3337e55f8c1SIan Lepore 	}
3347e55f8c1SIan Lepore 
33536fb9d5fSSvatopluk Kraus 	/*
33636fb9d5fSSvatopluk Kraus 	 * ARM has a set of unprivileged load and store instructions
33736fb9d5fSSvatopluk Kraus 	 * (LDRT/LDRBT/STRT/STRBT ...) which are supposed to be used in other
33836fb9d5fSSvatopluk Kraus 	 * than user mode and OS should recognize their aborts and behave
33936fb9d5fSSvatopluk Kraus 	 * appropriately. However, there is no way how to do that reasonably
34036fb9d5fSSvatopluk Kraus 	 * in general unless we restrict the handling somehow.
34136fb9d5fSSvatopluk Kraus 	 *
34236fb9d5fSSvatopluk Kraus 	 * For now, these instructions are used only in copyin()/copyout()
34336fb9d5fSSvatopluk Kraus 	 * like functions where usermode buffers are checked in advance that
34436fb9d5fSSvatopluk Kraus 	 * they are not from KVA space. Thus, no action is needed here.
34536fb9d5fSSvatopluk Kraus 	 */
34636fb9d5fSSvatopluk Kraus 
347f196c104SSvatopluk Kraus 	/*
348f196c104SSvatopluk Kraus 	 * (1) Handle access and R/W hardware emulation aborts.
349f196c104SSvatopluk Kraus 	 * (2) Check that abort is not on pmap essential address ranges.
350f196c104SSvatopluk Kraus 	 *     There is no way how to fix it, so we don't even try.
351f196c104SSvatopluk Kraus 	 */
3527e55f8c1SIan Lepore 	rv = pmap_fault(PCPU_GET(curpmap), far, fsr, idx, usermode);
353b78e1f8aSSvatopluk Kraus 	if (rv == KERN_SUCCESS)
3547e55f8c1SIan Lepore 		return;
3557e55f8c1SIan Lepore #ifdef KDB
3567e55f8c1SIan Lepore 	if (kdb_active) {
3577e55f8c1SIan Lepore 		kdb_reenter();
3587e55f8c1SIan Lepore 		goto out;
3597e55f8c1SIan Lepore 	}
3607e55f8c1SIan Lepore #endif
361f196c104SSvatopluk Kraus 	if (rv == KERN_INVALID_ADDRESS)
362f196c104SSvatopluk Kraus 		goto nogo;
363f196c104SSvatopluk Kraus 
3647e55f8c1SIan Lepore 	if (__predict_false((td->td_pflags & TDP_NOFAULTING) != 0)) {
3657e55f8c1SIan Lepore 		/*
3667e55f8c1SIan Lepore 		 * Due to both processor errata and lazy TLB invalidation when
3677e55f8c1SIan Lepore 		 * access restrictions are removed from virtual pages, memory
3687e55f8c1SIan Lepore 		 * accesses that are allowed by the physical mapping layer may
3697e55f8c1SIan Lepore 		 * nonetheless cause one spurious page fault per virtual page.
3707e55f8c1SIan Lepore 		 * When the thread is executing a "no faulting" section that
3717e55f8c1SIan Lepore 		 * is bracketed by vm_fault_{disable,enable}_pagefaults(),
3727e55f8c1SIan Lepore 		 * every page fault is treated as a spurious page fault,
3737e55f8c1SIan Lepore 		 * unless it accesses the same virtual address as the most
3747e55f8c1SIan Lepore 		 * recent page fault within the same "no faulting" section.
3757e55f8c1SIan Lepore 		 */
3767e55f8c1SIan Lepore 		if (td->td_md.md_spurflt_addr != far ||
3777e55f8c1SIan Lepore 		    (td->td_pflags & TDP_RESETSPUR) != 0) {
3787e55f8c1SIan Lepore 			td->td_md.md_spurflt_addr = far;
3797e55f8c1SIan Lepore 			td->td_pflags &= ~TDP_RESETSPUR;
3807e55f8c1SIan Lepore 
3817e55f8c1SIan Lepore 			tlb_flush_local(far & ~PAGE_MASK);
3827e55f8c1SIan Lepore 			return;
3837e55f8c1SIan Lepore 		}
3847e55f8c1SIan Lepore 	} else {
3857e55f8c1SIan Lepore 		/*
3867e55f8c1SIan Lepore 		 * If we get a page fault while in a critical section, then
3877e55f8c1SIan Lepore 		 * it is most likely a fatal kernel page fault.  The kernel
3887e55f8c1SIan Lepore 		 * is already going to panic trying to get a sleep lock to
3897e55f8c1SIan Lepore 		 * do the VM lookup, so just consider it a fatal trap so the
3907e55f8c1SIan Lepore 		 * kernel can print out a useful trap message and even get
3917e55f8c1SIan Lepore 		 * to the debugger.
3927e55f8c1SIan Lepore 		 *
3937e55f8c1SIan Lepore 		 * If we get a page fault while holding a non-sleepable
3947e55f8c1SIan Lepore 		 * lock, then it is most likely a fatal kernel page fault.
3957e55f8c1SIan Lepore 		 * If WITNESS is enabled, then it's going to whine about
3967e55f8c1SIan Lepore 		 * bogus LORs with various VM locks, so just skip to the
3977e55f8c1SIan Lepore 		 * fatal trap handling directly.
3987e55f8c1SIan Lepore 		 */
3997e55f8c1SIan Lepore 		if (td->td_critnest != 0 ||
4007e55f8c1SIan Lepore 		    WITNESS_CHECK(WARN_SLEEPOK | WARN_GIANTOK, NULL,
4017e55f8c1SIan Lepore 		    "Kernel page fault") != 0) {
4027e55f8c1SIan Lepore 			abort_fatal(tf, idx, fsr, far, prefetch, td, &ksig);
4037e55f8c1SIan Lepore 			return;
4047e55f8c1SIan Lepore 		}
4057e55f8c1SIan Lepore 	}
4067e55f8c1SIan Lepore 
4077e55f8c1SIan Lepore 	/* Re-enable interrupts if they were enabled previously. */
4087e55f8c1SIan Lepore 	if (td->td_md.md_spinlock_count == 0) {
4097e55f8c1SIan Lepore 		if (__predict_true(tf->tf_spsr & PSR_I) == 0)
4107e55f8c1SIan Lepore 			enable_interrupts(PSR_I);
4117e55f8c1SIan Lepore 		if (__predict_true(tf->tf_spsr & PSR_F) == 0)
4127e55f8c1SIan Lepore 			enable_interrupts(PSR_F);
4137e55f8c1SIan Lepore 	}
4147e55f8c1SIan Lepore 
4157e55f8c1SIan Lepore 	p = td->td_proc;
4167e55f8c1SIan Lepore 	if (usermode) {
4177e55f8c1SIan Lepore 		td->td_pticks = 0;
418b53133a7SMateusz Guzik 		if (td->td_cowgen != atomic_load_int(&p->p_cowgen))
4194ea6a9a2SMateusz Guzik 			thread_cow_update(td);
4207e55f8c1SIan Lepore 	}
4217e55f8c1SIan Lepore 
4227e55f8c1SIan Lepore 	/* Invoke the appropriate handler, if necessary. */
4237e55f8c1SIan Lepore 	if (__predict_false(aborts[idx].func != NULL)) {
4247e55f8c1SIan Lepore 		if ((aborts[idx].func)(tf, idx, fsr, far, prefetch, td, &ksig))
4257e55f8c1SIan Lepore 			goto do_trapsignal;
4267e55f8c1SIan Lepore 		goto out;
4277e55f8c1SIan Lepore 	}
4287e55f8c1SIan Lepore 
4297e55f8c1SIan Lepore 	/*
430f196c104SSvatopluk Kraus 	 * At this point, we're dealing with one of the following aborts:
431f196c104SSvatopluk Kraus 	 *
432f196c104SSvatopluk Kraus 	 *  FAULT_ICACHE   - I-cache maintenance
433f196c104SSvatopluk Kraus 	 *  FAULT_TRAN_xx  - Translation
434f196c104SSvatopluk Kraus 	 *  FAULT_PERM_xx  - Permission
435f196c104SSvatopluk Kraus 	 */
436f196c104SSvatopluk Kraus 
437f196c104SSvatopluk Kraus 	/*
4388826d904SIan Lepore 	 * Don't pass faulting cache operation to vm_fault(). We don't want
4398826d904SIan Lepore 	 * to handle all vm stuff at this moment.
4408826d904SIan Lepore 	 */
4418826d904SIan Lepore 	pcb = td->td_pcb;
4428826d904SIan Lepore 	if (__predict_false(pcb->pcb_onfault == cachebailout)) {
4438826d904SIan Lepore 		tf->tf_r0 = far;		/* return failing address */
4448826d904SIan Lepore 		tf->tf_pc = (register_t)pcb->pcb_onfault;
4458826d904SIan Lepore 		return;
4468826d904SIan Lepore 	}
4478826d904SIan Lepore 
44836fb9d5fSSvatopluk Kraus 	/* Handle remaining I-cache aborts. */
4498826d904SIan Lepore 	if (idx == FAULT_ICACHE) {
4508826d904SIan Lepore 		if (abort_icache(tf, idx, fsr, far, prefetch, td, &ksig))
4518826d904SIan Lepore 			goto do_trapsignal;
4528826d904SIan Lepore 		goto out;
4538826d904SIan Lepore 	}
4548826d904SIan Lepore 
4557e55f8c1SIan Lepore 	va = trunc_page(far);
4567e55f8c1SIan Lepore 	if (va >= KERNBASE) {
4577e55f8c1SIan Lepore 		/*
4587e55f8c1SIan Lepore 		 * Don't allow user-mode faults in kernel address space.
4597e55f8c1SIan Lepore 		 */
4602e3294cdSMichal Meloun 		if (usermode) {
4612e3294cdSMichal Meloun 			ksig.sig = SIGSEGV;
4622e3294cdSMichal Meloun 			ksig.code = SEGV_ACCERR;
4637e55f8c1SIan Lepore 			goto nogo;
4642e3294cdSMichal Meloun 		}
4657e55f8c1SIan Lepore 
4667e55f8c1SIan Lepore 		map = kernel_map;
4677e55f8c1SIan Lepore 	} else {
4687e55f8c1SIan Lepore 		/*
4697e55f8c1SIan Lepore 		 * This is a fault on non-kernel virtual memory. If curproc
4707e55f8c1SIan Lepore 		 * is NULL or curproc->p_vmspace is NULL the fault is fatal.
4717e55f8c1SIan Lepore 		 */
4727e55f8c1SIan Lepore 		vm = (p != NULL) ? p->p_vmspace : NULL;
4732e3294cdSMichal Meloun 		if (vm == NULL) {
4742e3294cdSMichal Meloun 			ksig.sig = SIGSEGV;
4752e3294cdSMichal Meloun 			ksig.code = 0;
4767e55f8c1SIan Lepore 			goto nogo;
4772e3294cdSMichal Meloun 		}
4787e55f8c1SIan Lepore 
4797e55f8c1SIan Lepore 		map = &vm->vm_map;
4807e55f8c1SIan Lepore 		if (!usermode && (td->td_intr_nesting_level != 0 ||
4817e55f8c1SIan Lepore 		    pcb->pcb_onfault == NULL)) {
4827e55f8c1SIan Lepore 			abort_fatal(tf, idx, fsr, far, prefetch, td, &ksig);
4837e55f8c1SIan Lepore 			return;
4847e55f8c1SIan Lepore 		}
4857e55f8c1SIan Lepore 	}
4867e55f8c1SIan Lepore 
4877e55f8c1SIan Lepore 	ftype = (fsr & FSR_WNR) ? VM_PROT_WRITE : VM_PROT_READ;
4887e55f8c1SIan Lepore 	if (prefetch)
4897e55f8c1SIan Lepore 		ftype |= VM_PROT_EXECUTE;
4907e55f8c1SIan Lepore 
4917e55f8c1SIan Lepore #ifdef INVARIANTS
4927e55f8c1SIan Lepore 	onfault = pcb->pcb_onfault;
4937e55f8c1SIan Lepore 	pcb->pcb_onfault = NULL;
4947e55f8c1SIan Lepore #endif
4957e55f8c1SIan Lepore 
4961fa67124SKonstantin Belousov 	/* Fault in the page. */
497df08823dSKonstantin Belousov 	rv = vm_fault_trap(map, va, ftype, VM_FAULT_NORMAL, &ksig.sig,
498df08823dSKonstantin Belousov 	    &ucode);
499df08823dSKonstantin Belousov 	ksig.code = ucode;
5007e55f8c1SIan Lepore 
5017e55f8c1SIan Lepore #ifdef INVARIANTS
5027e55f8c1SIan Lepore 	pcb->pcb_onfault = onfault;
5037e55f8c1SIan Lepore #endif
5047e55f8c1SIan Lepore 
5057e55f8c1SIan Lepore 	if (__predict_true(rv == KERN_SUCCESS))
5067e55f8c1SIan Lepore 		goto out;
5077e55f8c1SIan Lepore nogo:
5087e55f8c1SIan Lepore 	if (!usermode) {
5097e55f8c1SIan Lepore 		if (td->td_intr_nesting_level == 0 &&
5107e55f8c1SIan Lepore 		    pcb->pcb_onfault != NULL) {
5117e55f8c1SIan Lepore 			tf->tf_r0 = rv;
5127e55f8c1SIan Lepore 			tf->tf_pc = (int)pcb->pcb_onfault;
5137e55f8c1SIan Lepore 			return;
5147e55f8c1SIan Lepore 		}
5157e55f8c1SIan Lepore 		CTR2(KTR_TRAP, "%s: vm_fault() failed with %d", __func__, rv);
5167e55f8c1SIan Lepore 		abort_fatal(tf, idx, fsr, far, prefetch, td, &ksig);
5177e55f8c1SIan Lepore 		return;
5187e55f8c1SIan Lepore 	}
5197e55f8c1SIan Lepore 
5207e55f8c1SIan Lepore 	ksig.addr = far;
5217e55f8c1SIan Lepore 
5227e55f8c1SIan Lepore do_trapsignal:
52391371fbcSJohn Baldwin 	call_trapsignal(td, ksig.sig, ksig.code, ksig.addr, idx);
5247e55f8c1SIan Lepore out:
5257e55f8c1SIan Lepore 	if (usermode)
5267e55f8c1SIan Lepore 		userret(td, tf);
5277e55f8c1SIan Lepore }
5287e55f8c1SIan Lepore 
5297e55f8c1SIan Lepore /*
5307e55f8c1SIan Lepore  * abort_fatal() handles the following data aborts:
53136fb9d5fSSvatopluk Kraus  *
5327e55f8c1SIan Lepore  *  FAULT_DEBUG		- Debug Event
5337e55f8c1SIan Lepore  *  FAULT_ACCESS_xx	- Acces Bit
5347e55f8c1SIan Lepore  *  FAULT_EA_PREC	- Precise External Abort
5357e55f8c1SIan Lepore  *  FAULT_DOMAIN_xx	- Domain Fault
5367e55f8c1SIan Lepore  *  FAULT_EA_TRAN_xx	- External Translation Abort
5377e55f8c1SIan Lepore  *  FAULT_EA_IMPREC	- Imprecise External Abort
5387e55f8c1SIan Lepore  *  + all undefined codes for ABORT
5397e55f8c1SIan Lepore  *
5407e55f8c1SIan Lepore  * We should never see these on a properly functioning system.
5417e55f8c1SIan Lepore  *
5427e55f8c1SIan Lepore  * This function is also called by the other handlers if they
5437e55f8c1SIan Lepore  * detect a fatal problem.
5447e55f8c1SIan Lepore  *
5457e55f8c1SIan Lepore  * Note: If 'l' is NULL, we assume we're dealing with a prefetch abort.
5467e55f8c1SIan Lepore  */
5477e55f8c1SIan Lepore static int
abort_fatal(struct trapframe * tf,u_int idx,u_int fsr,u_int far,u_int prefetch,struct thread * td,struct ksig * ksig)54836fb9d5fSSvatopluk Kraus abort_fatal(struct trapframe *tf, u_int idx, u_int fsr, u_int far,
54936fb9d5fSSvatopluk Kraus     u_int prefetch, struct thread *td, struct ksig *ksig)
5507e55f8c1SIan Lepore {
551bee75f52SSvatopluk Kraus 	bool usermode;
5527e55f8c1SIan Lepore 	const char *mode;
5537e55f8c1SIan Lepore 	const char *rw_mode;
55465d1a4cfSMitchell Horne #ifdef KDB
55565d1a4cfSMitchell Horne 	bool handled;
55665d1a4cfSMitchell Horne #endif
5577e55f8c1SIan Lepore 
5587e55f8c1SIan Lepore 	usermode = TRAPF_USERMODE(tf);
559c2188153SAndrew Turner #ifdef KDTRACE_HOOKS
560c2188153SAndrew Turner 	if (!usermode) {
561c2188153SAndrew Turner 		if (dtrace_trap_func != NULL && (*dtrace_trap_func)(tf, far))
562c2188153SAndrew Turner 			return (0);
563c2188153SAndrew Turner 	}
564c2188153SAndrew Turner #endif
565c2188153SAndrew Turner 
5667e55f8c1SIan Lepore 	mode = usermode ? "user" : "kernel";
5677e55f8c1SIan Lepore 	rw_mode  = fsr & FSR_WNR ? "write" : "read";
5687e55f8c1SIan Lepore 	disable_interrupts(PSR_I|PSR_F);
5697e55f8c1SIan Lepore 
5707e55f8c1SIan Lepore 	if (td != NULL) {
5717e55f8c1SIan Lepore 		printf("Fatal %s mode data abort: '%s' on %s\n", mode,
5727e55f8c1SIan Lepore 		    aborts[idx].desc, rw_mode);
5737e55f8c1SIan Lepore 		printf("trapframe: %p\nFSR=%08x, FAR=", tf, fsr);
5747e55f8c1SIan Lepore 		if (idx != FAULT_EA_IMPREC)
5757e55f8c1SIan Lepore 			printf("%08x, ", far);
5767e55f8c1SIan Lepore 		else
5777e55f8c1SIan Lepore 			printf("Invalid,  ");
5787e55f8c1SIan Lepore 		printf("spsr=%08x\n", tf->tf_spsr);
5797e55f8c1SIan Lepore 	} else {
5807e55f8c1SIan Lepore 		printf("Fatal %s mode prefetch abort at 0x%08x\n",
5817e55f8c1SIan Lepore 		    mode, tf->tf_pc);
5827e55f8c1SIan Lepore 		printf("trapframe: %p, spsr=%08x\n", tf, tf->tf_spsr);
5837e55f8c1SIan Lepore 	}
5847e55f8c1SIan Lepore 
5857e55f8c1SIan Lepore 	printf("r0 =%08x, r1 =%08x, r2 =%08x, r3 =%08x\n",
5867e55f8c1SIan Lepore 	    tf->tf_r0, tf->tf_r1, tf->tf_r2, tf->tf_r3);
5877e55f8c1SIan Lepore 	printf("r4 =%08x, r5 =%08x, r6 =%08x, r7 =%08x\n",
5887e55f8c1SIan Lepore 	    tf->tf_r4, tf->tf_r5, tf->tf_r6, tf->tf_r7);
5897e55f8c1SIan Lepore 	printf("r8 =%08x, r9 =%08x, r10=%08x, r11=%08x\n",
5907e55f8c1SIan Lepore 	    tf->tf_r8, tf->tf_r9, tf->tf_r10, tf->tf_r11);
5917e55f8c1SIan Lepore 	printf("r12=%08x, ", tf->tf_r12);
5927e55f8c1SIan Lepore 
5937e55f8c1SIan Lepore 	if (usermode)
5947e55f8c1SIan Lepore 		printf("usp=%08x, ulr=%08x",
5957e55f8c1SIan Lepore 		    tf->tf_usr_sp, tf->tf_usr_lr);
5967e55f8c1SIan Lepore 	else
5977e55f8c1SIan Lepore 		printf("ssp=%08x, slr=%08x",
5987e55f8c1SIan Lepore 		    tf->tf_svc_sp, tf->tf_svc_lr);
5997e55f8c1SIan Lepore 	printf(", pc =%08x\n\n", tf->tf_pc);
6007e55f8c1SIan Lepore 
6017e55f8c1SIan Lepore #ifdef KDB
602b317cfd4SJohn Baldwin 	if (debugger_on_trap) {
603c9c4d38aSAndriy Gapon 		kdb_why = KDB_WHY_TRAP;
60465d1a4cfSMitchell Horne 		handled = kdb_trap(fsr, 0, tf);
605c9c4d38aSAndriy Gapon 		kdb_why = KDB_WHY_UNSET;
60665d1a4cfSMitchell Horne 		if (handled)
60765d1a4cfSMitchell Horne 			return (0);
608c9c4d38aSAndriy Gapon 	}
6097e55f8c1SIan Lepore #endif
6107e55f8c1SIan Lepore 	panic("Fatal abort");
6117e55f8c1SIan Lepore 	/*NOTREACHED*/
6127e55f8c1SIan Lepore }
6137e55f8c1SIan Lepore 
6147e55f8c1SIan Lepore /*
6157e55f8c1SIan Lepore  * abort_align() handles the following data abort:
6167e55f8c1SIan Lepore  *
6177e55f8c1SIan Lepore  *  FAULT_ALIGN - Alignment fault
6187e55f8c1SIan Lepore  *
61936fb9d5fSSvatopluk Kraus  * Everything should be aligned in kernel with exception of user to kernel
62036fb9d5fSSvatopluk Kraus  * and vice versa data copying, so if pcb_onfault is not set, it's fatal.
62136fb9d5fSSvatopluk Kraus  * We generate signal in case of abort from user mode.
6227e55f8c1SIan Lepore  */
6237e55f8c1SIan Lepore static int
abort_align(struct trapframe * tf,u_int idx,u_int fsr,u_int far,u_int prefetch,struct thread * td,struct ksig * ksig)62436fb9d5fSSvatopluk Kraus abort_align(struct trapframe *tf, u_int idx, u_int fsr, u_int far,
62536fb9d5fSSvatopluk Kraus     u_int prefetch, struct thread *td, struct ksig *ksig)
6267e55f8c1SIan Lepore {
627bee75f52SSvatopluk Kraus 	bool usermode;
6287e55f8c1SIan Lepore 
6297e55f8c1SIan Lepore 	usermode = TRAPF_USERMODE(tf);
6307e55f8c1SIan Lepore 	if (!usermode) {
6317e55f8c1SIan Lepore 		if (td->td_intr_nesting_level == 0 && td != NULL &&
6327e55f8c1SIan Lepore 		    td->td_pcb->pcb_onfault != NULL) {
6339a54871fSSvatopluk Kraus 			tf->tf_r0 = EFAULT;
6347e55f8c1SIan Lepore 			tf->tf_pc = (int)td->td_pcb->pcb_onfault;
6357e55f8c1SIan Lepore 			return (0);
6367e55f8c1SIan Lepore 		}
6377e55f8c1SIan Lepore 		abort_fatal(tf, idx, fsr, far, prefetch, td, ksig);
6387e55f8c1SIan Lepore 	}
6397e55f8c1SIan Lepore 	/* Deliver a bus error signal to the process */
6409a54871fSSvatopluk Kraus 	ksig->code = BUS_ADRALN;
6417e55f8c1SIan Lepore 	ksig->sig = SIGBUS;
6427e55f8c1SIan Lepore 	ksig->addr = far;
6437e55f8c1SIan Lepore 	return (1);
6447e55f8c1SIan Lepore }
6457e55f8c1SIan Lepore 
6467e55f8c1SIan Lepore /*
6477e55f8c1SIan Lepore  * abort_icache() handles the following data abort:
6487e55f8c1SIan Lepore  *
6497e55f8c1SIan Lepore  * FAULT_ICACHE - Instruction cache maintenance
6507e55f8c1SIan Lepore  *
6517e55f8c1SIan Lepore  * According to manual, FAULT_ICACHE is translation fault during cache
6527e55f8c1SIan Lepore  * maintenance operation. In fact, no cache maintenance operation on
6537e55f8c1SIan Lepore  * not mapped virtual addresses should be called. As cache maintenance
6545bdf58e1SGordon Bergling  * operation (except DMB, DSB, and Flush Prefetch Buffer) are privileged,
6557e55f8c1SIan Lepore  * the abort is concider as fatal for now. However, all the matter with
6567e55f8c1SIan Lepore  * cache maintenance operation on virtual addresses could be really complex
6577e55f8c1SIan Lepore  * and fuzzy in SMP case, so maybe in future standard fault mechanism
6587e55f8c1SIan Lepore  * should be held here including vm_fault() calling.
6597e55f8c1SIan Lepore  */
6607e55f8c1SIan Lepore static int
abort_icache(struct trapframe * tf,u_int idx,u_int fsr,u_int far,u_int prefetch,struct thread * td,struct ksig * ksig)66136fb9d5fSSvatopluk Kraus abort_icache(struct trapframe *tf, u_int idx, u_int fsr, u_int far,
66236fb9d5fSSvatopluk Kraus     u_int prefetch, struct thread *td, struct ksig *ksig)
6637e55f8c1SIan Lepore {
66436fb9d5fSSvatopluk Kraus 
6657e55f8c1SIan Lepore 	abort_fatal(tf, idx, fsr, far, prefetch, td, ksig);
6667e55f8c1SIan Lepore 	return(0);
6677e55f8c1SIan Lepore }
668