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