Home | History | Annotate | Line # | Download | only in arm32
fault.c revision 1.27
      1 /*	$NetBSD: fault.c,v 1.27 2003/04/18 11:08:25 scw Exp $	*/
      2 
      3 /*
      4  * Copyright 2003 Wasabi Systems, Inc.
      5  * All rights reserved.
      6  *
      7  * Written by Steve C. Woodford for Wasabi Systems, Inc.
      8  *
      9  * Redistribution and use in source and binary forms, with or without
     10  * modification, are permitted provided that the following conditions
     11  * are met:
     12  * 1. Redistributions of source code must retain the above copyright
     13  *    notice, this list of conditions and the following disclaimer.
     14  * 2. Redistributions in binary form must reproduce the above copyright
     15  *    notice, this list of conditions and the following disclaimer in the
     16  *    documentation and/or other materials provided with the distribution.
     17  * 3. All advertising materials mentioning features or use of this software
     18  *    must display the following acknowledgement:
     19  *      This product includes software developed for the NetBSD Project by
     20  *      Wasabi Systems, Inc.
     21  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
     22  *    or promote products derived from this software without specific prior
     23  *    written permission.
     24  *
     25  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
     26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     27  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     28  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
     29  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     30  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     33  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     35  * POSSIBILITY OF SUCH DAMAGE.
     36  */
     37 /*
     38  * Copyright (c) 1994-1997 Mark Brinicombe.
     39  * Copyright (c) 1994 Brini.
     40  * All rights reserved.
     41  *
     42  * This code is derived from software written for Brini by Mark Brinicombe
     43  *
     44  * Redistribution and use in source and binary forms, with or without
     45  * modification, are permitted provided that the following conditions
     46  * are met:
     47  * 1. Redistributions of source code must retain the above copyright
     48  *    notice, this list of conditions and the following disclaimer.
     49  * 2. Redistributions in binary form must reproduce the above copyright
     50  *    notice, this list of conditions and the following disclaimer in the
     51  *    documentation and/or other materials provided with the distribution.
     52  * 3. All advertising materials mentioning features or use of this software
     53  *    must display the following acknowledgement:
     54  *	This product includes software developed by Brini.
     55  * 4. The name of the company nor the name of the author may be used to
     56  *    endorse or promote products derived from this software without specific
     57  *    prior written permission.
     58  *
     59  * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
     60  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     61  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     62  * IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
     63  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     64  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     65  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     66  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     67  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     68  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     69  * SUCH DAMAGE.
     70  *
     71  * RiscBSD kernel project
     72  *
     73  * fault.c
     74  *
     75  * Fault handlers
     76  *
     77  * Created      : 28/11/94
     78  */
     79 
     80 #include "opt_ddb.h"
     81 #include "opt_pmap_debug.h"
     82 
     83 #include <sys/types.h>
     84 __KERNEL_RCSID(0, "$NetBSD: fault.c,v 1.27 2003/04/18 11:08:25 scw Exp $");
     85 
     86 #include <sys/param.h>
     87 #include <sys/systm.h>
     88 #include <sys/proc.h>
     89 #include <sys/user.h>
     90 #include <sys/kernel.h>
     91 
     92 #include <uvm/uvm_extern.h>
     93 
     94 #include <arm/cpuconf.h>
     95 
     96 #include <machine/frame.h>
     97 #include <arm/arm32/katelib.h>
     98 #include <machine/cpu.h>
     99 #include <machine/intr.h>
    100 #ifdef DDB
    101 #include <machine/db_machdep.h>
    102 #endif
    103 
    104 #include <arch/arm/arm/disassem.h>
    105 #include <arm/arm32/machdep.h>
    106 
    107 extern char fusubailout[];
    108 
    109 #ifdef DEBUG
    110 int last_fault_code;	/* For the benefit of pmap_fault_fixup() */
    111 #endif
    112 
    113 static void report_abort __P((const char *, u_int, u_int, u_int));
    114 
    115 /* Abort code */
    116 
    117 /* Define text descriptions of the different aborts */
    118 
    119 static const char *aborts[16] = {
    120 	"Write buffer fault",
    121 	"Alignment fault",
    122 	"Write buffer fault",
    123 	"Alignment fault",
    124 	"Bus error (LF section)",
    125 	"Translation fault (section)",
    126 	"Bus error (page)",
    127 	"Translation fault (page)",
    128 	"Bus error (section)",
    129 	"Domain error (section)",
    130 	"Bus error (page)",
    131 	"Domain error (page)",
    132 	"Bus error trans (L1)",
    133 	"Permission error (section)",
    134 	"Bus error trans (L2)",
    135 	"Permission error (page)"
    136 };
    137 
    138 static void
    139 report_abort(prefix, fault_status, fault_address, fault_pc)
    140 	const char *prefix;
    141 	u_int fault_status;
    142 	u_int fault_address;
    143 	u_int fault_pc;
    144 {
    145 #ifndef DEBUG
    146 	if (prefix == NULL) {
    147 #endif
    148 		if (prefix)
    149 			printf("%s ", prefix);
    150 		printf("Data abort: '%s' status=%03x address=%08x PC=%08x\n",
    151 		    aborts[fault_status & FAULT_TYPE_MASK],
    152 		    fault_status & 0xfff, fault_address, fault_pc);
    153 #ifndef DEBUG
    154 	}
    155 #endif
    156 }
    157 
    158 static __volatile int data_abort_expected;
    159 static __volatile int data_abort_received;
    160 
    161 int
    162 badaddr_read(void *addr, size_t size, void *rptr)
    163 {
    164 	u_long rcpt;
    165 	int rv;
    166 
    167 	/* Tell the Data Abort handler that we're expecting one. */
    168 	data_abort_received = 0;
    169 	data_abort_expected = 1;
    170 
    171 	cpu_drain_writebuf();
    172 
    173 	/* Read from the test address. */
    174 	switch (size) {
    175 	case sizeof(uint8_t):
    176 		__asm __volatile("ldrb %0, [%1]"
    177 			: "=r" (rcpt)
    178 			: "r" (addr));
    179 		break;
    180 
    181 	case sizeof(uint16_t):
    182 		__asm __volatile("ldrh %0, [%1]"
    183 			: "=r" (rcpt)
    184 			: "r" (addr));
    185 		break;
    186 
    187 	case sizeof(uint32_t):
    188 		__asm __volatile("ldr %0, [%1]"
    189 			: "=r" (rcpt)
    190 			: "r" (addr));
    191 		break;
    192 
    193 	default:
    194 		data_abort_expected = 0;
    195 		panic("badaddr: invalid size (%lu)", (u_long) size);
    196 	}
    197 
    198 	/* Disallow further Data Aborts. */
    199 	data_abort_expected = 0;
    200 
    201 	rv = data_abort_received;
    202 	data_abort_received = 0;
    203 
    204 	/* Copy the data back if no fault occurred. */
    205 	if (rptr != NULL && rv == 0) {
    206 		switch (size) {
    207 		case sizeof(uint8_t):
    208 			*(uint8_t *) rptr = rcpt;
    209 			break;
    210 
    211 		case sizeof(uint16_t):
    212 			*(uint16_t *) rptr = rcpt;
    213 			break;
    214 
    215 		case sizeof(uint32_t):
    216 			*(uint32_t *) rptr = rcpt;
    217 			break;
    218 		}
    219 	}
    220 
    221 	/* Return true if the address was invalid. */
    222 	return (rv);
    223 }
    224 
    225 /*
    226  * void data_abort_handler(trapframe_t *frame)
    227  *
    228  * Abort handler called when read/write occurs at an address of
    229  * a non existent or restricted (access permissions) memory page.
    230  * We first need to identify the type of page fault.
    231  */
    232 
    233 #define TRAP_CODE ((fault_status & 0x0f) | (fault_address & 0xfffffff0))
    234 
    235 /* Determine if we can recover from a fault */
    236 #ifdef ARM32_PMAP_NEW
    237 #define	IS_FATAL_FAULT(x)					\
    238 	(((1 << (x)) &						\
    239 	  ((1 << FAULT_WRTBUF_0) | (1 << FAULT_WRTBUF_1) |	\
    240 	   (1 << FAULT_BUSERR_0) | (1 << FAULT_BUSERR_1) |	\
    241 	   (1 << FAULT_BUSERR_2) | (1 << FAULT_BUSERR_3) |	\
    242 	   (1 << FAULT_BUSTRNL1) | (1 << FAULT_BUSTRNL2) |	\
    243 	   (1 << FAULT_ALIGN_0)  | (1 << FAULT_ALIGN_1))) != 0)
    244 #else
    245 #define	IS_FATAL_FAULT(x)					\
    246 	(((1 << (x)) &						\
    247 	  ((1 << FAULT_WRTBUF_0) | (1 << FAULT_WRTBUF_1) |	\
    248 	   (1 << FAULT_BUSERR_0) | (1 << FAULT_BUSERR_1) |	\
    249 	   (1 << FAULT_BUSERR_2) | (1 << FAULT_BUSERR_3) |	\
    250 	   (1 << FAULT_BUSTRNL1) | (1 << FAULT_BUSTRNL2) |	\
    251 	   (1 << FAULT_DOMAIN_S) | (1 << FAULT_DOMAIN_P) |	\
    252 	   (1 << FAULT_ALIGN_0)  | (1 << FAULT_ALIGN_1))) != 0)
    253 #endif
    254 
    255 void
    256 data_abort_handler(frame)
    257 	trapframe_t *frame;
    258 {
    259 	struct lwp *l;
    260 	struct proc *p;
    261 	struct pcb *pcb;
    262 	u_int fault_address;
    263 	u_int fault_status;
    264 	u_int fault_pc;
    265 	u_int fault_instruction;
    266 	int fault_code, fatal_fault;
    267 	int user;
    268 	int error;
    269 	int rv;
    270 	void *onfault;
    271 	vaddr_t va;
    272 	struct vmspace *vm;
    273 	struct vm_map *map;
    274 	vm_prot_t ftype;
    275 	extern struct vm_map *kernel_map;
    276 
    277 	/*
    278 	 * If we were expecting a Data Abort, signal that we got
    279 	 * one, adjust the PC to skip the faulting insn, and
    280 	 * return.
    281 	 */
    282 	if (data_abort_expected) {
    283 		data_abort_received = 1;
    284 		frame->tf_pc += INSN_SIZE;
    285 		return;
    286 	}
    287 
    288 	/*
    289 	 * Must get fault address and status from the CPU before
    290 	 * re-enabling interrupts.  (Interrupt handlers may take
    291 	 * R/M emulation faults.)
    292 	 */
    293 	fault_address = cpu_faultaddress();
    294 	fault_status = cpu_faultstatus();
    295 	fault_pc = frame->tf_pc;
    296 
    297 	/*
    298 	 * Enable IRQ's (disabled by CPU on abort) if trapframe
    299 	 * shows they were enabled.
    300 	 */
    301 	if (!(frame->tf_spsr & I32_bit))
    302 		enable_interrupts(I32_bit);
    303 
    304 #ifdef DEBUG
    305 	if ((GetCPSR() & PSR_MODE) != PSR_SVC32_MODE)
    306 		panic("data_abort_handler: not in SVC32 mode");
    307 #endif
    308 
    309 	/* Update vmmeter statistics */
    310 	uvmexp.traps++;
    311 
    312 	/* Extract the fault code from the fault status */
    313 	fault_code = fault_status & FAULT_TYPE_MASK;
    314 	fatal_fault = IS_FATAL_FAULT(fault_code);
    315 
    316 	/* Get the current lwp structure or lwp0 if there is none */
    317 	l = curlwp == NULL ? &lwp0 : curlwp;
    318 	p = l->l_proc;
    319 
    320 	/*
    321 	 * can't use curpcb, as it might be NULL; and we have p in
    322 	 * a register anyway
    323 	 */
    324 	pcb = &l->l_addr->u_pcb;
    325 
    326 	/* fusubailout is used by [fs]uswintr to avoid page faulting */
    327 	if (pcb->pcb_onfault &&
    328 	    (fatal_fault || pcb->pcb_onfault == fusubailout)) {
    329 
    330 		frame->tf_r0 = EFAULT;
    331 copyfault:
    332 #ifdef DEBUG
    333 		printf("Using pcb_onfault=%p addr=%08x st=%08x l=%p\n",
    334 		    pcb->pcb_onfault, fault_address, fault_status, l);
    335 #endif
    336 		frame->tf_pc = (u_int)pcb->pcb_onfault;
    337 		if ((frame->tf_spsr & PSR_MODE) == PSR_USR32_MODE)
    338 			panic("Yikes pcb_onfault=%p during USR mode fault",
    339 			    pcb->pcb_onfault);
    340 		return;
    341 	}
    342 
    343 	/* More debug stuff */
    344 
    345 	fault_instruction = ReadWord(fault_pc);
    346 
    347 #ifdef PMAP_DEBUG
    348 	if (pmap_debug_level >= 0) {
    349 		report_abort(NULL, fault_status, fault_address, fault_pc);
    350 		printf("Instruction @V%08x = %08x\n",
    351 		    fault_pc, fault_instruction);
    352 	}
    353 #endif
    354 
    355 	/* Call the cpu specific abort fixup routine */
    356 	error = cpu_dataabt_fixup(frame);
    357 	if (error == ABORT_FIXUP_RETURN)
    358 		return;
    359 	if (error == ABORT_FIXUP_FAILED) {
    360 		printf("pc = 0x%08x, opcode 0x%08x, insn = ", fault_pc, *((u_int *)fault_pc));
    361 		disassemble(fault_pc);
    362 		printf("data abort handler: fixup failed for this instruction\n");
    363 	}
    364 
    365 #ifdef PMAP_DEBUG
    366 	if (pmap_debug_level >= 0)
    367 		printf("fault in process %p\n", p);
    368 #endif
    369 
    370 #ifdef DEBUG
    371 	/* Is this needed ? (XXXSCW: yes. can happen during boot ...) */
    372 	if (!cold && pcb != curpcb) {
    373 		printf("data_abort: Alert ! pcb(%p) != curpcb(%p)\n",
    374 		    pcb, curpcb);
    375 		printf("data_abort: Alert ! proc(%p), curlwp(%p)\n",
    376 		    p, curlwp);
    377 	}
    378 #endif	/* DEBUG */
    379 
    380 	/* Were we in user mode when the abort occurred ? */
    381 	if ((frame->tf_spsr & PSR_MODE) == PSR_USR32_MODE) {
    382 		/*
    383 		 * Note that the fault was from USR mode.
    384 		 */
    385 		user = 1;
    386 		l->l_addr->u_pcb.pcb_tf = frame;
    387 	} else
    388 		user = 0;
    389 
    390 	/* check if this was a failed fixup */
    391 	if (error == ABORT_FIXUP_FAILED) {
    392 		if (user) {
    393 			trapsignal(l, SIGSEGV, TRAP_CODE);
    394 			userret(l);
    395 			return;
    396 		};
    397 		panic("Data abort fixup failed in kernel - we're dead");
    398 	};
    399 
    400 	/* Now act on the fault type */
    401 	if (fatal_fault) {
    402 		/*
    403 		 * None of these faults should happen on a perfectly
    404 		 * functioning system. They indicate either some gross
    405 		 * problem with the kernel, or a hardware problem.
    406 		 * In either case, stop.
    407 		 */
    408 		report_abort(NULL, fault_status, fault_address, fault_pc);
    409 
    410 we_re_toast:
    411 		/*
    412 		 * Were are dead, try and provide some debug
    413 		 * information before dying.
    414 		 */
    415 #ifdef DDB
    416 		printf("Unhandled trap (frame = %p)\n", frame);
    417 		report_abort(NULL, fault_status, fault_address, fault_pc);
    418 		kdb_trap(-1, frame);
    419 		return;
    420 #else
    421 		panic("Unhandled trap (frame = %p)", frame);
    422 #endif	/* DDB */
    423 	}
    424 
    425 	/*
    426 	 * At this point, we're dealing with one of the following faults:
    427 	 *
    428 	 *  FAULT_TRANS_P	Page Translation Fault
    429 	 *  FAULT_PERM_P	Page Permission Fault
    430 	 *  FAULT_TRANS_S	Section Translation Fault
    431 	 *  FAULT_PERM_S	Section Permission Fault
    432 	 *
    433 	 * And if ARM32_PMAP_NEW is in effect:
    434 	 *
    435 	 *  FAULT_DOMAIN_P	Page Domain Error Fault
    436 	 *  FAULT_DOMAIN_S	Section Domain Error Fault
    437 	 *
    438 	 * Page/section translation/permission fault -- need to fault in
    439 	 * the page.
    440 	 *
    441 	 * Page/section domain fault -- need to see if the L1 entry can
    442 	 * be fixed up.
    443 	 */
    444 	vm = p->p_vmspace;
    445 	va = trunc_page((vaddr_t)fault_address);
    446 
    447 #ifdef PMAP_DEBUG
    448 	if (pmap_debug_level >= 0)
    449 		printf("page fault: addr=V%08lx ", va);
    450 #endif
    451 
    452 	/*
    453 	 * It is only a kernel address space fault iff:
    454 	 *	1. user == 0  and
    455 	 *	2. pcb_onfault not set or
    456 	 *	3. pcb_onfault set but supervisor space fault
    457 	 * The last can occur during an exec() copyin where the
    458 	 * argument space is lazy-allocated.
    459 	 */
    460 	if (!user &&
    461 	    (va >= VM_MIN_KERNEL_ADDRESS || va < VM_MIN_ADDRESS)) {
    462 		/* Was the fault due to the FPE/IPKDB ? */
    463 		if ((frame->tf_spsr & PSR_MODE) == PSR_UND32_MODE) {
    464 			report_abort("UND32", fault_status,
    465 			    fault_address, fault_pc);
    466 			trapsignal(l, SIGSEGV, TRAP_CODE);
    467 
    468 			/*
    469 			 * Force exit via userret()
    470 			 * This is necessary as the FPE is an extension
    471 			 * to userland that actually runs in a
    472 			 * priveledged mode but uses USR mode
    473 			 * permissions for its accesses.
    474 			 */
    475 			userret(l);
    476 			return;
    477 		}
    478 		map = kernel_map;
    479 	} else
    480 		map = &vm->vm_map;
    481 
    482 #ifdef PMAP_DEBUG
    483 	if (pmap_debug_level >= 0)
    484 		printf("vmmap=%p ", map);
    485 #endif
    486 
    487 	if (map == NULL)
    488 		printf("No map for fault address va = 0x%08lx", va);
    489 
    490 	/*
    491 	 * We need to know whether the page should be mapped
    492 	 * as R or R/W. The MMU does not give us the info as
    493 	 * to whether the fault was caused by a read or a write.
    494 	 * This means we need to disassemble the instruction
    495 	 * responsible and determine if it was a read or write
    496 	 * instruction.
    497 	 */
    498 	/* STR instruction ? */
    499 	if ((fault_instruction & 0x0c100000) == 0x04000000)
    500 		ftype = VM_PROT_WRITE;
    501 	/* STM or CDT instruction ? */
    502 	else if ((fault_instruction & 0x0a100000) == 0x08000000)
    503 		ftype = VM_PROT_WRITE;
    504 	/* STRH, STRSH or STRSB instruction ? */
    505 	else if ((fault_instruction & 0x0e100090) == 0x00000090)
    506 		ftype = VM_PROT_WRITE;
    507 	/* SWP instruction ? */
    508 	else if ((fault_instruction & 0x0fb00ff0) == 0x01000090)
    509 		ftype = VM_PROT_READ | VM_PROT_WRITE;
    510 	else
    511 		ftype = VM_PROT_READ;
    512 
    513 #ifdef PMAP_DEBUG
    514 	if (pmap_debug_level >= 0)
    515 		printf("fault protection = %d\n", ftype);
    516 #endif
    517 
    518 #ifndef ARM32_PMAP_NEW
    519 	if ((ftype & VM_PROT_WRITE) ?
    520 	    pmap_modified_emulation(map->pmap, va) :
    521 	    pmap_handled_emulation(map->pmap, va))
    522 		goto out;
    523 #else
    524 	if (pmap_fault_fixup(map->pmap, va, ftype))
    525 		goto out;
    526 #endif
    527 
    528 	if (current_intr_depth > 0) {
    529 #ifdef DDB
    530 		printf("Non-emulated page fault with intr_depth > 0\n");
    531 		report_abort(NULL, fault_status, fault_address, fault_pc);
    532 		kdb_trap(-1, frame);
    533 		return;
    534 #else
    535 		panic("Fault with intr_depth > 0");
    536 #endif	/* DDB */
    537 	}
    538 
    539 	onfault = pcb->pcb_onfault;
    540 	pcb->pcb_onfault = NULL;
    541 	rv = uvm_fault(map, va, 0, ftype);
    542 	pcb->pcb_onfault = onfault;
    543 	if (rv == 0) {
    544 		if (user != 0) /* Record any stack growth... */
    545 			uvm_grow(p, trunc_page(va));
    546 		goto out;
    547 	}
    548 	if (user == 0) {
    549 		if (pcb->pcb_onfault) {
    550 			frame->tf_r0 = rv;
    551 			goto copyfault;
    552 		}
    553 		printf("[u]vm_fault(%p, %lx, %x, 0) -> %x\n", map, va, ftype,
    554 		    rv);
    555 		goto we_re_toast;
    556 	}
    557 
    558 	report_abort("", fault_status, fault_address, fault_pc);
    559 	if (rv == ENOMEM) {
    560 		printf("UVM: pid %d (%s), uid %d killed: "
    561 		    "out of swap\n", p->p_pid, p->p_comm,
    562 		    (p->p_cred && p->p_ucred) ?  p->p_ucred->cr_uid : -1);
    563 			trapsignal(l, SIGKILL, TRAP_CODE);
    564 	} else
    565 		trapsignal(l, SIGSEGV, TRAP_CODE);
    566 
    567 out:
    568 	/* Call userret() if it was a USR mode fault */
    569 	if (user)
    570 		userret(l);
    571 }
    572 
    573 
    574 /*
    575  * void prefetch_abort_handler(trapframe_t *frame)
    576  *
    577  * Abort handler called when instruction execution occurs at
    578  * a non existent or restricted (access permissions) memory page.
    579  * If the address is invalid and we were in SVC mode then panic as
    580  * the kernel should never prefetch abort.
    581  * If the address is invalid and the page is mapped then the user process
    582  * does no have read permission so send it a signal.
    583  * Otherwise fault the page in and try again.
    584  */
    585 
    586 void
    587 prefetch_abort_handler(frame)
    588 	trapframe_t *frame;
    589 {
    590 	struct lwp *l;
    591 	struct proc *p;
    592 	struct vm_map *map;
    593 	vaddr_t fault_pc, va;
    594 	int error;
    595 
    596 	/*
    597 	 * Enable IRQ's (disabled by the abort) This always comes
    598 	 * from user mode so we know interrupts were not disabled.
    599 	 * But we check anyway.
    600 	 */
    601 	if (!(frame->tf_spsr & I32_bit))
    602 		enable_interrupts(I32_bit);
    603 
    604 #ifdef DEBUG
    605 	if ((GetCPSR() & PSR_MODE) != PSR_SVC32_MODE)
    606 		panic("prefetch_abort_handler: not in SVC32 mode");
    607 #endif
    608 
    609 	/* Update vmmeter statistics */
    610 	uvmexp.traps++;
    611 
    612 	/* Call the cpu specific abort fixup routine */
    613 	error = cpu_prefetchabt_fixup(frame);
    614 	if (error == ABORT_FIXUP_RETURN)
    615 		return;
    616 	if (error == ABORT_FIXUP_FAILED)
    617 		panic("prefetch abort fixup failed");
    618 
    619 	/* Get the current proc structure or proc0 if there is none */
    620 	if ((l = curlwp) == NULL) {
    621 		l = &lwp0;
    622 #ifdef DEBUG
    623 		printf("Prefetch abort with curlwp == 0\n");
    624 #endif
    625 	}
    626 	p = l->l_proc;
    627 
    628 #ifdef PMAP_DEBUG
    629 	if (pmap_debug_level >= 0)
    630 		printf("prefetch fault in process %p %s\n", p, p->p_comm);
    631 #endif
    632 
    633 	/* Get fault address */
    634 	fault_pc = frame->tf_pc;
    635 	va = trunc_page(fault_pc);
    636 
    637 	/* Was the prefectch abort from USR32 mode ? */
    638 	if ((frame->tf_spsr & PSR_MODE) == PSR_USR32_MODE) {
    639 		l->l_addr->u_pcb.pcb_tf = frame;
    640 	} else {
    641 		/*
    642 		 * All the kernel code pages are loaded at boot time
    643 		 * and do not get paged
    644 		 */
    645 	        panic("Prefetch abort in non-USR mode (frame=%p PC=0x%08lx)",
    646 	            frame, fault_pc);
    647 	}
    648 
    649 	map = &p->p_vmspace->vm_map;
    650 
    651 #ifdef PMAP_DEBUG
    652 	if (pmap_debug_level >= 0)
    653 		printf("prefetch_abort: PC = %08lx\n", fault_pc);
    654 #endif
    655 	/* Ok validate the address, can only execute in USER space */
    656 	if (fault_pc < VM_MIN_ADDRESS || fault_pc >= VM_MAXUSER_ADDRESS) {
    657 #ifdef DEBUG
    658 		printf("prefetch: pc (%08lx) not in user process space\n",
    659 		    fault_pc);
    660 #endif
    661 		trapsignal(l, SIGSEGV, fault_pc);
    662 		userret(l);
    663 		return;
    664 	}
    665 
    666 #ifndef ARM32_PMAP_NEW
    667 #ifdef CPU_SA110
    668 	/*
    669 	 * There are bugs in the rev K SA110.  This is a check for one
    670 	 * of them.
    671 	 */
    672 	if (curcpu()->ci_arm_cputype == CPU_ID_SA110 &&
    673 	    curcpu()->ci_arm_cpurev < 3) {
    674 		/* Always current pmap */
    675 		pt_entry_t *pte = vtopte((vaddr_t) fault_pc);
    676 		struct pmap *pmap = p->p_vmspace->vm_map.pmap;
    677 
    678 		if (pmap_pde_v(pmap_pde(pmap, (vaddr_t) fault_pc)) &&
    679 		    pmap_pte_v(pte)) {
    680 			extern int kernel_debug;
    681 			if (kernel_debug & 1) {
    682 				printf("prefetch_abort: page is already "
    683 				    "mapped - pte=%p *pte=%08x\n", pte, *pte);
    684 				printf("prefetch_abort: pc=%08lx proc=%p "
    685 				    "process=%s\n", fault_pc, p, p->p_comm);
    686 				printf("prefetch_abort: far=%08x fs=%x\n",
    687 				    cpu_faultaddress(), cpu_faultstatus());
    688 				printf("prefetch_abort: trapframe=%08x\n",
    689 				    (u_int)frame);
    690 			}
    691 #ifdef DDB
    692 			if (kernel_debug & 2)
    693 				Debugger();
    694 #endif
    695 		}
    696 	}
    697 #endif /* CPU_SA110 */
    698 
    699 	if (pmap_handled_emulation(map->pmap, va))
    700 		goto out;
    701 
    702 #else	/* ARM32_PMAP_NEW */
    703 
    704 	/*
    705 	 * See if the pmap can handle this fault on its own...
    706 	 */
    707 	if (pmap_fault_fixup(map->pmap, va, VM_PROT_READ))
    708 		goto out;
    709 #endif
    710 
    711 	if (current_intr_depth > 0) {
    712 #ifdef DDB
    713 		printf("Non-emulated prefetch abort with intr_depth > 0\n");
    714 		kdb_trap(-1, frame);
    715 		return;
    716 #else
    717 		panic("Prefetch Abort with intr_depth > 0");
    718 #endif
    719 	}
    720 
    721 	error = uvm_fault(map, va, 0, VM_PROT_READ);
    722 	if (error == 0)
    723 		goto out;
    724 
    725 	if (error == ENOMEM) {
    726 		printf("UVM: pid %d (%s), uid %d killed: "
    727 		    "out of swap\n", p->p_pid, p->p_comm,
    728 		    (p->p_cred && p->p_ucred) ?  p->p_ucred->cr_uid : -1);
    729 		trapsignal(l, SIGKILL, fault_pc);
    730 	} else
    731 		trapsignal(l, SIGSEGV, fault_pc);
    732 out:
    733 	userret(l);
    734 }
    735