Home | History | Annotate | Line # | Download | only in arm32
fault.c revision 1.33
      1 /*	$NetBSD: fault.c,v 1.33 2003/09/19 11:42:20 agc 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_kgdb.h"
     82 #include "opt_pmap_debug.h"
     83 
     84 #include <sys/types.h>
     85 __KERNEL_RCSID(0, "$NetBSD: fault.c,v 1.33 2003/09/19 11:42:20 agc Exp $");
     86 
     87 #include <sys/param.h>
     88 #include <sys/systm.h>
     89 #include <sys/proc.h>
     90 #include <sys/savar.h>
     91 #include <sys/user.h>
     92 #include <sys/kernel.h>
     93 
     94 #include <uvm/uvm_extern.h>
     95 
     96 #include <arm/cpuconf.h>
     97 
     98 #include <machine/frame.h>
     99 #include <arm/arm32/katelib.h>
    100 #include <machine/cpu.h>
    101 #include <machine/intr.h>
    102 #if defined(DDB) || defined(KGDB)
    103 #include <machine/db_machdep.h>
    104 #ifdef KGDB
    105 #include <sys/kgdb.h>
    106 #endif
    107 #if !defined(DDB)
    108 #define kdb_trap	kgdb_trap
    109 #endif
    110 #endif
    111 
    112 #include <arch/arm/arm/disassem.h>
    113 #include <arm/arm32/machdep.h>
    114 
    115 extern char fusubailout[];
    116 
    117 #ifdef DEBUG
    118 int last_fault_code;	/* For the benefit of pmap_fault_fixup() */
    119 #endif
    120 
    121 static void report_abort __P((const char *, u_int, u_int, u_int));
    122 
    123 /* Abort code */
    124 
    125 /* Define text descriptions of the different aborts */
    126 
    127 static const char *aborts[16] = {
    128 	"Write buffer fault",
    129 	"Alignment fault",
    130 	"Write buffer fault",
    131 	"Alignment fault",
    132 	"Bus error (LF section)",
    133 	"Translation fault (section)",
    134 	"Bus error (page)",
    135 	"Translation fault (page)",
    136 	"Bus error (section)",
    137 	"Domain error (section)",
    138 	"Bus error (page)",
    139 	"Domain error (page)",
    140 	"Bus error trans (L1)",
    141 	"Permission error (section)",
    142 	"Bus error trans (L2)",
    143 	"Permission error (page)"
    144 };
    145 
    146 static void
    147 report_abort(prefix, fault_status, fault_address, fault_pc)
    148 	const char *prefix;
    149 	u_int fault_status;
    150 	u_int fault_address;
    151 	u_int fault_pc;
    152 {
    153 #ifndef DEBUG
    154 	if (prefix == NULL) {
    155 #endif
    156 		if (prefix)
    157 			printf("%s ", prefix);
    158 		printf("Data abort: '%s' status=%03x address=%08x PC=%08x\n",
    159 		    aborts[fault_status & FAULT_TYPE_MASK],
    160 		    fault_status & 0xfff, fault_address, fault_pc);
    161 #ifndef DEBUG
    162 	}
    163 #endif
    164 }
    165 
    166 static __volatile int data_abort_expected;
    167 static __volatile int data_abort_received;
    168 
    169 int
    170 badaddr_read(void *addr, size_t size, void *rptr)
    171 {
    172 	u_long rcpt;
    173 	int rv;
    174 
    175 	/* Tell the Data Abort handler that we're expecting one. */
    176 	data_abort_received = 0;
    177 	data_abort_expected = 1;
    178 
    179 	cpu_drain_writebuf();
    180 
    181 	/* Read from the test address. */
    182 	switch (size) {
    183 	case sizeof(uint8_t):
    184 		__asm __volatile("ldrb %0, [%1]"
    185 			: "=r" (rcpt)
    186 			: "r" (addr));
    187 		break;
    188 
    189 	case sizeof(uint16_t):
    190 		__asm __volatile("ldrh %0, [%1]"
    191 			: "=r" (rcpt)
    192 			: "r" (addr));
    193 		break;
    194 
    195 	case sizeof(uint32_t):
    196 		__asm __volatile("ldr %0, [%1]"
    197 			: "=r" (rcpt)
    198 			: "r" (addr));
    199 		break;
    200 
    201 	default:
    202 		data_abort_expected = 0;
    203 		panic("badaddr: invalid size (%lu)", (u_long) size);
    204 	}
    205 
    206 	/* Disallow further Data Aborts. */
    207 	data_abort_expected = 0;
    208 
    209 	rv = data_abort_received;
    210 	data_abort_received = 0;
    211 
    212 	/* Copy the data back if no fault occurred. */
    213 	if (rptr != NULL && rv == 0) {
    214 		switch (size) {
    215 		case sizeof(uint8_t):
    216 			*(uint8_t *) rptr = rcpt;
    217 			break;
    218 
    219 		case sizeof(uint16_t):
    220 			*(uint16_t *) rptr = rcpt;
    221 			break;
    222 
    223 		case sizeof(uint32_t):
    224 			*(uint32_t *) rptr = rcpt;
    225 			break;
    226 		}
    227 	}
    228 
    229 	/* Return true if the address was invalid. */
    230 	return (rv);
    231 }
    232 
    233 /*
    234  * void data_abort_handler(trapframe_t *frame)
    235  *
    236  * Abort handler called when read/write occurs at an address of
    237  * a non existent or restricted (access permissions) memory page.
    238  * We first need to identify the type of page fault.
    239  */
    240 
    241 #define TRAP_CODE ((fault_status & 0x0f) | (fault_address & 0xfffffff0))
    242 
    243 /* Determine if we can recover from a fault */
    244 #define	IS_FATAL_FAULT(x)					\
    245 	(((1 << (x)) &						\
    246 	  ((1 << FAULT_WRTBUF_0) | (1 << FAULT_WRTBUF_1) |	\
    247 	   (1 << FAULT_BUSERR_0) | (1 << FAULT_BUSERR_1) |	\
    248 	   (1 << FAULT_BUSERR_2) | (1 << FAULT_BUSERR_3) |	\
    249 	   (1 << FAULT_BUSTRNL1) | (1 << FAULT_BUSTRNL2) |	\
    250 	   (1 << FAULT_ALIGN_0)  | (1 << FAULT_ALIGN_1))) != 0)
    251 
    252 void
    253 data_abort_handler(frame)
    254 	trapframe_t *frame;
    255 {
    256 	struct lwp *l;
    257 	struct proc *p;
    258 	struct pcb *pcb;
    259 	u_int fault_address;
    260 	u_int fault_status;
    261 	u_int fault_pc;
    262 	u_int fault_instruction;
    263 	int fault_code, fatal_fault;
    264 	int user;
    265 	int error;
    266 	int rv;
    267 	void *onfault;
    268 	vaddr_t va;
    269 	struct vmspace *vm;
    270 	struct vm_map *map;
    271 	vm_prot_t ftype;
    272 	extern struct vm_map *kernel_map;
    273 
    274 	/*
    275 	 * If we were expecting a Data Abort, signal that we got
    276 	 * one, adjust the PC to skip the faulting insn, and
    277 	 * return.
    278 	 */
    279 	if (data_abort_expected) {
    280 		data_abort_received = 1;
    281 		frame->tf_pc += INSN_SIZE;
    282 		return;
    283 	}
    284 
    285 	/*
    286 	 * Must get fault address and status from the CPU before
    287 	 * re-enabling interrupts.  (Interrupt handlers may take
    288 	 * R/M emulation faults.)
    289 	 */
    290 	fault_address = cpu_faultaddress();
    291 	fault_status = cpu_faultstatus();
    292 	fault_pc = frame->tf_pc;
    293 
    294 	/*
    295 	 * Enable IRQ's (disabled by CPU on abort) if trapframe
    296 	 * shows they were enabled.
    297 	 */
    298 	if (!(frame->tf_spsr & I32_bit))
    299 		enable_interrupts(I32_bit);
    300 
    301 #ifdef DEBUG
    302 	if ((GetCPSR() & PSR_MODE) != PSR_SVC32_MODE)
    303 		panic("data_abort_handler: not in SVC32 mode");
    304 #endif
    305 
    306 	/* Update vmmeter statistics */
    307 	uvmexp.traps++;
    308 
    309 	/* Extract the fault code from the fault status */
    310 	fault_code = fault_status & FAULT_TYPE_MASK;
    311 	fatal_fault = IS_FATAL_FAULT(fault_code);
    312 
    313 	/* Get the current lwp structure or lwp0 if there is none */
    314 	l = curlwp == NULL ? &lwp0 : curlwp;
    315 	p = l->l_proc;
    316 
    317 	/*
    318 	 * can't use curpcb, as it might be NULL; and we have p in
    319 	 * a register anyway
    320 	 */
    321 	pcb = &l->l_addr->u_pcb;
    322 
    323 	/* fusubailout is used by [fs]uswintr to avoid page faulting */
    324 	if (pcb->pcb_onfault &&
    325 	    (fatal_fault || pcb->pcb_onfault == fusubailout)) {
    326 
    327 		frame->tf_r0 = EFAULT;
    328 copyfault:
    329 #ifdef DEBUG
    330 		printf("Using pcb_onfault=%p addr=%08x st=%08x l=%p\n",
    331 		    pcb->pcb_onfault, fault_address, fault_status, l);
    332 #endif
    333 		frame->tf_pc = (u_int)pcb->pcb_onfault;
    334 		if ((frame->tf_spsr & PSR_MODE) == PSR_USR32_MODE)
    335 			panic("Yikes pcb_onfault=%p during USR mode fault",
    336 			    pcb->pcb_onfault);
    337 		return;
    338 	}
    339 
    340 	/* More debug stuff */
    341 
    342 	fault_instruction = ReadWord(fault_pc);
    343 
    344 #ifdef PMAP_DEBUG
    345 	if (pmap_debug_level >= 0) {
    346 		report_abort(NULL, fault_status, fault_address, fault_pc);
    347 		printf("Instruction @V%08x = %08x\n",
    348 		    fault_pc, fault_instruction);
    349 	}
    350 #endif
    351 
    352 	/* Call the cpu specific abort fixup routine */
    353 	error = cpu_dataabt_fixup(frame);
    354 	if (error == ABORT_FIXUP_RETURN)
    355 		return;
    356 	if (error == ABORT_FIXUP_FAILED) {
    357 		printf("pc = 0x%08x, opcode 0x%08x, insn = ", fault_pc, *((u_int *)fault_pc));
    358 		disassemble(fault_pc);
    359 		printf("data abort handler: fixup failed for this instruction\n");
    360 	}
    361 
    362 #ifdef PMAP_DEBUG
    363 	if (pmap_debug_level >= 0)
    364 		printf("fault in process %p\n", p);
    365 #endif
    366 
    367 #ifdef DEBUG
    368 	/* Is this needed ? (XXXSCW: yes. can happen during boot ...) */
    369 	if (!cold && pcb != curpcb) {
    370 		printf("data_abort: Alert ! pcb(%p) != curpcb(%p)\n",
    371 		    pcb, curpcb);
    372 		printf("data_abort: Alert ! proc(%p), curlwp(%p)\n",
    373 		    p, curlwp);
    374 	}
    375 #endif	/* DEBUG */
    376 
    377 	/* Were we in user mode when the abort occurred ? */
    378 	if ((frame->tf_spsr & PSR_MODE) == PSR_USR32_MODE) {
    379 		/*
    380 		 * Note that the fault was from USR mode.
    381 		 */
    382 		user = 1;
    383 		l->l_addr->u_pcb.pcb_tf = frame;
    384 	} else
    385 		user = 0;
    386 
    387 	/* check if this was a failed fixup */
    388 	if (error == ABORT_FIXUP_FAILED) {
    389 		if (user) {
    390 			trapsignal(l, SIGSEGV, TRAP_CODE);
    391 			userret(l);
    392 			return;
    393 		};
    394 		panic("Data abort fixup failed in kernel - we're dead");
    395 	};
    396 
    397 	/* Now act on the fault type */
    398 	if (fatal_fault) {
    399 		/*
    400 		 * None of these faults should happen on a perfectly
    401 		 * functioning system. They indicate either some gross
    402 		 * problem with the kernel, or a hardware problem.
    403 		 * In either case, stop.
    404 		 */
    405 		report_abort(NULL, fault_status, fault_address, fault_pc);
    406 
    407 we_re_toast:
    408 		/*
    409 		 * Were are dead, try and provide some debug
    410 		 * information before dying.
    411 		 */
    412 #if defined(DDB) || defined(KGDB)
    413 		printf("Unhandled trap (frame = %p)\n", frame);
    414 		report_abort(NULL, fault_status, fault_address, fault_pc);
    415 		kdb_trap(T_FAULT, frame);
    416 		return;
    417 #else
    418 		panic("Unhandled trap (frame = %p)", frame);
    419 #endif	/* DDB || KGDB */
    420 	}
    421 
    422 	/*
    423 	 * At this point, we're dealing with one of the following faults:
    424 	 *
    425 	 *  FAULT_TRANS_P	Page Translation Fault
    426 	 *  FAULT_PERM_P	Page Permission Fault
    427 	 *  FAULT_TRANS_S	Section Translation Fault
    428 	 *  FAULT_PERM_S	Section Permission Fault
    429 	 *  FAULT_DOMAIN_P	Page Domain Error Fault
    430 	 *  FAULT_DOMAIN_S	Section Domain Error Fault
    431 	 *
    432 	 * Page/section translation/permission fault -- need to fault in
    433 	 * the page.
    434 	 *
    435 	 * Page/section domain fault -- need to see if the L1 entry can
    436 	 * be fixed up.
    437 	 */
    438 	vm = p->p_vmspace;
    439 	va = trunc_page((vaddr_t)fault_address);
    440 
    441 #ifdef PMAP_DEBUG
    442 	if (pmap_debug_level >= 0)
    443 		printf("page fault: addr=V%08lx ", va);
    444 #endif
    445 
    446 	/*
    447 	 * It is only a kernel address space fault iff:
    448 	 *	1. user == 0  and
    449 	 *	2. pcb_onfault not set or
    450 	 *	3. pcb_onfault set but supervisor space fault
    451 	 * The last can occur during an exec() copyin where the
    452 	 * argument space is lazy-allocated.
    453 	 */
    454 	if (!user &&
    455 	    (va >= VM_MIN_KERNEL_ADDRESS || va < VM_MIN_ADDRESS)) {
    456 		/* Was the fault due to the FPE/IPKDB ? */
    457 		if ((frame->tf_spsr & PSR_MODE) == PSR_UND32_MODE) {
    458 			report_abort("UND32", fault_status,
    459 			    fault_address, fault_pc);
    460 			trapsignal(l, SIGSEGV, TRAP_CODE);
    461 
    462 			/*
    463 			 * Force exit via userret()
    464 			 * This is necessary as the FPE is an extension
    465 			 * to userland that actually runs in a
    466 			 * priveledged mode but uses USR mode
    467 			 * permissions for its accesses.
    468 			 */
    469 			userret(l);
    470 			return;
    471 		}
    472 		map = kernel_map;
    473 	} else {
    474 		map = &vm->vm_map;
    475 		if (l->l_flag & L_SA) {
    476 			KDASSERT(p != NULL && p->p_sa != NULL);
    477 			p->p_sa->sa_vp_faultaddr = (vaddr_t)fault_address;
    478 			l->l_flag |= L_SA_PAGEFAULT;
    479 		}
    480 	}
    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 	if (pmap_fault_fixup(map->pmap, va, ftype, user))
    519 		goto out;
    520 
    521 	if (current_intr_depth > 0) {
    522 #if defined(DDB) || defined(KGDB)
    523 		printf("Non-emulated page fault with intr_depth > 0\n");
    524 		report_abort(NULL, fault_status, fault_address, fault_pc);
    525 		kdb_trap(T_FAULT, frame);
    526 		return;
    527 #else
    528 		panic("Fault with intr_depth > 0");
    529 #endif	/* DDB */
    530 	}
    531 
    532 	onfault = pcb->pcb_onfault;
    533 	pcb->pcb_onfault = NULL;
    534 	rv = uvm_fault(map, va, 0, ftype);
    535 	pcb->pcb_onfault = onfault;
    536 	if (map != kernel_map)
    537 		l->l_flag &= ~L_SA_PAGEFAULT;
    538 	if (rv == 0) {
    539 		if (user != 0) /* Record any stack growth... */
    540 			uvm_grow(p, trunc_page(va));
    541 		goto out;
    542 	}
    543 	if (user == 0) {
    544 		if (pcb->pcb_onfault) {
    545 			frame->tf_r0 = rv;
    546 			goto copyfault;
    547 		}
    548 		printf("[u]vm_fault(%p, %lx, %x, 0) -> %x\n", map, va, ftype,
    549 		    rv);
    550 		goto we_re_toast;
    551 	}
    552 
    553 	report_abort("", fault_status, fault_address, fault_pc);
    554 	if (rv == ENOMEM) {
    555 		printf("UVM: pid %d (%s), uid %d killed: "
    556 		    "out of swap\n", p->p_pid, p->p_comm,
    557 		    (p->p_cred && p->p_ucred) ?  p->p_ucred->cr_uid : -1);
    558 			trapsignal(l, SIGKILL, TRAP_CODE);
    559 	} else
    560 		trapsignal(l, SIGSEGV, TRAP_CODE);
    561 
    562 out:
    563 	/* Call userret() if it was a USR mode fault */
    564 	if (user)
    565 		userret(l);
    566 }
    567 
    568 
    569 /*
    570  * void prefetch_abort_handler(trapframe_t *frame)
    571  *
    572  * Abort handler called when instruction execution occurs at
    573  * a non existent or restricted (access permissions) memory page.
    574  * If the address is invalid and we were in SVC mode then panic as
    575  * the kernel should never prefetch abort.
    576  * If the address is invalid and the page is mapped then the user process
    577  * does no have read permission so send it a signal.
    578  * Otherwise fault the page in and try again.
    579  */
    580 
    581 void
    582 prefetch_abort_handler(frame)
    583 	trapframe_t *frame;
    584 {
    585 	struct lwp *l;
    586 	struct proc *p;
    587 	struct vm_map *map;
    588 	vaddr_t fault_pc, va;
    589 	int error;
    590 
    591 	/*
    592 	 * Enable IRQ's (disabled by the abort) This always comes
    593 	 * from user mode so we know interrupts were not disabled.
    594 	 * But we check anyway.
    595 	 */
    596 	if (!(frame->tf_spsr & I32_bit))
    597 		enable_interrupts(I32_bit);
    598 
    599 #ifdef DEBUG
    600 	if ((GetCPSR() & PSR_MODE) != PSR_SVC32_MODE)
    601 		panic("prefetch_abort_handler: not in SVC32 mode");
    602 #endif
    603 
    604 	/* Update vmmeter statistics */
    605 	uvmexp.traps++;
    606 
    607 	/* Call the cpu specific abort fixup routine */
    608 	error = cpu_prefetchabt_fixup(frame);
    609 	if (error == ABORT_FIXUP_RETURN)
    610 		return;
    611 	if (error == ABORT_FIXUP_FAILED)
    612 		panic("prefetch abort fixup failed");
    613 
    614 	/* Get the current proc structure or proc0 if there is none */
    615 	if ((l = curlwp) == NULL) {
    616 		l = &lwp0;
    617 #ifdef DEBUG
    618 		printf("Prefetch abort with curlwp == 0\n");
    619 #endif
    620 	}
    621 	p = l->l_proc;
    622 
    623 #ifdef PMAP_DEBUG
    624 	if (pmap_debug_level >= 0)
    625 		printf("prefetch fault in process %p %s\n", p, p->p_comm);
    626 #endif
    627 
    628 	/* Get fault address */
    629 	fault_pc = frame->tf_pc;
    630 	va = trunc_page(fault_pc);
    631 
    632 	/* Was the prefectch abort from USR32 mode ? */
    633 	if ((frame->tf_spsr & PSR_MODE) == PSR_USR32_MODE) {
    634 		l->l_addr->u_pcb.pcb_tf = frame;
    635 	} else {
    636 		/*
    637 		 * All the kernel code pages are loaded at boot time
    638 		 * and do not get paged
    639 		 */
    640 	        panic("Prefetch abort in non-USR mode (frame=%p PC=0x%08lx)",
    641 	            frame, fault_pc);
    642 	}
    643 
    644 	map = &p->p_vmspace->vm_map;
    645 
    646 #ifdef PMAP_DEBUG
    647 	if (pmap_debug_level >= 0)
    648 		printf("prefetch_abort: PC = %08lx\n", fault_pc);
    649 #endif
    650 	/* Ok validate the address, can only execute in USER space */
    651 	if (fault_pc < VM_MIN_ADDRESS || fault_pc >= VM_MAXUSER_ADDRESS) {
    652 #ifdef DEBUG
    653 		printf("prefetch: pc (%08lx) not in user process space\n",
    654 		    fault_pc);
    655 #endif
    656 		trapsignal(l, SIGSEGV, fault_pc);
    657 		userret(l);
    658 		return;
    659 	}
    660 
    661 	/*
    662 	 * See if the pmap can handle this fault on its own...
    663 	 */
    664 	if (pmap_fault_fixup(map->pmap, va, VM_PROT_READ, 1))
    665 		goto out;
    666 
    667 	if (current_intr_depth > 0) {
    668 #ifdef DDB
    669 		printf("Non-emulated prefetch abort with intr_depth > 0\n");
    670 		kdb_trap(T_FAULT, frame);
    671 		return;
    672 #else
    673 		panic("Prefetch Abort with intr_depth > 0");
    674 #endif
    675 	}
    676 
    677 	error = uvm_fault(map, va, 0, VM_PROT_READ);
    678 	if (error == 0)
    679 		goto out;
    680 
    681 	if (error == ENOMEM) {
    682 		printf("UVM: pid %d (%s), uid %d killed: "
    683 		    "out of swap\n", p->p_pid, p->p_comm,
    684 		    (p->p_cred && p->p_ucred) ?  p->p_ucred->cr_uid : -1);
    685 		trapsignal(l, SIGKILL, fault_pc);
    686 	} else
    687 		trapsignal(l, SIGSEGV, fault_pc);
    688 out:
    689 	userret(l);
    690 }
    691