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