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