FreeBSD/Linux Kernel Cross Reference
sys/arm/arm/trap.c
1 /* $NetBSD: fault.c,v 1.45 2003/11/20 14:44:36 scw Exp $ */
2
3 /*-
4 * Copyright 2004 Olivier Houchard
5 * Copyright 2003 Wasabi Systems, Inc.
6 * All rights reserved.
7 *
8 * Written by Steve C. Woodford for Wasabi Systems, Inc.
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 for the NetBSD Project by
21 * Wasabi Systems, Inc.
22 * 4. The name of Wasabi Systems, Inc. may not be used to endorse
23 * or promote products derived from this software without specific prior
24 * written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38 /*-
39 * Copyright (c) 1994-1997 Mark Brinicombe.
40 * Copyright (c) 1994 Brini.
41 * All rights reserved.
42 *
43 * This code is derived from software written for Brini by Mark Brinicombe
44 *
45 * Redistribution and use in source and binary forms, with or without
46 * modification, are permitted provided that the following conditions
47 * are met:
48 * 1. Redistributions of source code must retain the above copyright
49 * notice, this list of conditions and the following disclaimer.
50 * 2. Redistributions in binary form must reproduce the above copyright
51 * notice, this list of conditions and the following disclaimer in the
52 * documentation and/or other materials provided with the distribution.
53 * 3. All advertising materials mentioning features or use of this software
54 * must display the following acknowledgement:
55 * This product includes software developed by Brini.
56 * 4. The name of the company nor the name of the author may be used to
57 * endorse or promote products derived from this software without specific
58 * prior written permission.
59 *
60 * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
61 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
62 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
63 * IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
64 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
65 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
66 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
67 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
68 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
69 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
70 * SUCH DAMAGE.
71 *
72 * RiscBSD kernel project
73 *
74 * fault.c
75 *
76 * Fault handlers
77 *
78 * Created : 28/11/94
79 */
80
81
82 #include "opt_ktrace.h"
83
84 #include <sys/cdefs.h>
85 __FBSDID("$FreeBSD: releng/6.1/sys/arm/arm/trap.c 147544 2005-06-23 11:39:18Z cognet $");
86
87 #include <sys/types.h>
88
89 #include <sys/param.h>
90 #include <sys/systm.h>
91 #include <sys/proc.h>
92 #include <sys/kernel.h>
93 #include <sys/lock.h>
94 #include <sys/mutex.h>
95 #include <sys/syscall.h>
96 #include <sys/sysent.h>
97 #include <sys/signalvar.h>
98 #include <sys/ktr.h>
99 #ifdef KTRACE
100 #include <sys/uio.h>
101 #include <sys/ktrace.h>
102 #endif
103 #include <sys/ptrace.h>
104 #include <sys/pioctl.h>
105
106 #include <vm/vm.h>
107 #include <vm/pmap.h>
108 #include <vm/vm_kern.h>
109 #include <vm/vm_map.h>
110 #include <vm/vm_extern.h>
111
112 #include <machine/cpuconf.h>
113 #include <machine/vmparam.h>
114 #include <machine/frame.h>
115 #include <machine/katelib.h>
116 #include <machine/cpu.h>
117 #include <machine/intr.h>
118 #include <machine/pcb.h>
119 #include <machine/proc.h>
120 #include <machine/swi.h>
121
122 #ifdef KDB
123 #include <sys/kdb.h>
124 #endif
125
126
127 void swi_handler(trapframe_t *);
128 void undefinedinstruction(trapframe_t *);
129
130 #include <machine/disassem.h>
131 #include <machine/machdep.h>
132
133 extern char fusubailout[];
134
135 #ifdef DEBUG
136 int last_fault_code; /* For the benefit of pmap_fault_fixup() */
137 #endif
138
139 #if defined(CPU_ARM7TDMI)
140 /* These CPUs may need data/prefetch abort fixups */
141 #define CPU_ABORT_FIXUP_REQUIRED
142 #endif
143
144 struct ksig {
145 int signb;
146 u_long code;
147 };
148 struct data_abort {
149 int (*func)(trapframe_t *, u_int, u_int, struct thread *, struct ksig *);
150 const char *desc;
151 };
152
153 static int dab_fatal(trapframe_t *, u_int, u_int, struct thread *, struct ksig *);
154 static int dab_align(trapframe_t *, u_int, u_int, struct thread *, struct ksig *);
155 static int dab_buserr(trapframe_t *, u_int, u_int, struct thread *, struct ksig *);
156
157 static const struct data_abort data_aborts[] = {
158 {dab_fatal, "Vector Exception"},
159 {dab_align, "Alignment Fault 1"},
160 {dab_fatal, "Terminal Exception"},
161 {dab_align, "Alignment Fault 3"},
162 {dab_buserr, "External Linefetch Abort (S)"},
163 {NULL, "Translation Fault (S)"},
164 {dab_buserr, "External Linefetch Abort (P)"},
165 {NULL, "Translation Fault (P)"},
166 {dab_buserr, "External Non-Linefetch Abort (S)"},
167 {NULL, "Domain Fault (S)"},
168 {dab_buserr, "External Non-Linefetch Abort (P)"},
169 {NULL, "Domain Fault (P)"},
170 {dab_buserr, "External Translation Abort (L1)"},
171 {NULL, "Permission Fault (S)"},
172 {dab_buserr, "External Translation Abort (L2)"},
173 {NULL, "Permission Fault (P)"}
174 };
175
176 /* Determine if a fault came from user mode */
177 #define TRAP_USERMODE(tf) ((tf->tf_spsr & PSR_MODE) == PSR_USR32_MODE)
178
179 /* Determine if 'x' is a permission fault */
180 #define IS_PERMISSION_FAULT(x) \
181 (((1 << ((x) & FAULT_TYPE_MASK)) & \
182 ((1 << FAULT_PERM_P) | (1 << FAULT_PERM_S))) != 0)
183
184 static __inline void
185 call_trapsignal(struct thread *td, int sig, u_long code)
186 {
187
188 trapsignal(td, sig, code);
189 }
190
191 static __inline int
192 data_abort_fixup(trapframe_t *tf, u_int fsr, u_int far, struct thread *td, struct ksig *ksig)
193 {
194 #ifdef CPU_ABORT_FIXUP_REQUIRED
195 int error;
196
197 /* Call the cpu specific data abort fixup routine */
198 error = cpu_dataabt_fixup(tf);
199 if (__predict_true(error != ABORT_FIXUP_FAILED))
200 return (error);
201
202 /*
203 * Oops, couldn't fix up the instruction
204 */
205 printf("data_abort_fixup: fixup for %s mode data abort failed.\n",
206 TRAP_USERMODE(tf) ? "user" : "kernel");
207 printf("pc = 0x%08x, opcode 0x%08x, insn = ", tf->tf_pc,
208 *((u_int *)tf->tf_pc));
209 disassemble(tf->tf_pc);
210
211 /* Die now if this happened in kernel mode */
212 if (!TRAP_USERMODE(tf))
213 dab_fatal(tf, fsr, far, td, NULL, ksig);
214
215 return (error);
216 #else
217 return (ABORT_FIXUP_OK);
218 #endif /* CPU_ABORT_FIXUP_REQUIRED */
219 }
220
221 void
222 data_abort_handler(trapframe_t *tf)
223 {
224 struct vm_map *map;
225 struct pcb *pcb;
226 struct thread *td;
227 u_int user, far, fsr;
228 vm_prot_t ftype;
229 void *onfault;
230 vm_offset_t va;
231 u_int sticks = 0;
232 int error = 0;
233 struct ksig ksig;
234 struct proc *p;
235
236
237 /* Grab FAR/FSR before enabling interrupts */
238 far = cpu_faultaddress();
239 fsr = cpu_faultstatus();
240 #if 0
241 printf("data abort: %p (from %p %p)\n", (void*)far, (void*)tf->tf_pc,
242 (void*)tf->tf_svc_lr);
243 #endif
244
245 /* Update vmmeter statistics */
246 #if 0
247 vmexp.traps++;
248 #endif
249
250 td = curthread;
251 p = td->td_proc;
252
253 PCPU_LAZY_INC(cnt.v_trap);
254 /* Data abort came from user mode? */
255 user = TRAP_USERMODE(tf);
256
257 if (user) {
258 sticks = td->td_sticks; td->td_frame = tf;
259 if (td->td_ucred != td->td_proc->p_ucred)
260 cred_update_thread(td);
261 if (td->td_pflags & TDP_SA)
262 thread_user_enter(td);
263
264 }
265 /* Grab the current pcb */
266 pcb = td->td_pcb;
267 /* Re-enable interrupts if they were enabled previously */
268 if (td->td_critnest == 0 && __predict_true(tf->tf_spsr & I32_bit) == 0)
269 enable_interrupts(I32_bit);
270
271 /* Invoke the appropriate handler, if necessary */
272 if (__predict_false(data_aborts[fsr & FAULT_TYPE_MASK].func != NULL)) {
273 if ((data_aborts[fsr & FAULT_TYPE_MASK].func)(tf, fsr, far,
274 td, &ksig)) {
275 goto do_trapsignal;
276 }
277 goto out;
278 }
279
280 /*
281 * At this point, we're dealing with one of the following data aborts:
282 *
283 * FAULT_TRANS_S - Translation -- Section
284 * FAULT_TRANS_P - Translation -- Page
285 * FAULT_DOMAIN_S - Domain -- Section
286 * FAULT_DOMAIN_P - Domain -- Page
287 * FAULT_PERM_S - Permission -- Section
288 * FAULT_PERM_P - Permission -- Page
289 *
290 * These are the main virtual memory-related faults signalled by
291 * the MMU.
292 */
293
294 /* fusubailout is used by [fs]uswintr to avoid page faulting */
295 if (__predict_false(pcb->pcb_onfault == fusubailout)) {
296 tf->tf_r0 = EFAULT;
297 tf->tf_pc = (register_t)(intptr_t) pcb->pcb_onfault;
298 return;
299 }
300
301 /*
302 * Make sure the Program Counter is sane. We could fall foul of
303 * someone executing Thumb code, in which case the PC might not
304 * be word-aligned. This would cause a kernel alignment fault
305 * further down if we have to decode the current instruction.
306 * XXX: It would be nice to be able to support Thumb at some point.
307 */
308 if (__predict_false((tf->tf_pc & 3) != 0)) {
309 if (user) {
310 /*
311 * Give the user an illegal instruction signal.
312 */
313 /* Deliver a SIGILL to the process */
314 ksig.signb = SIGILL;
315 ksig.code = 0;
316 goto do_trapsignal;
317 }
318
319 /*
320 * The kernel never executes Thumb code.
321 */
322 printf("\ndata_abort_fault: Misaligned Kernel-mode "
323 "Program Counter\n");
324 dab_fatal(tf, fsr, far, td, &ksig);
325 }
326
327 /* See if the cpu state needs to be fixed up */
328 switch (data_abort_fixup(tf, fsr, far, td, &ksig)) {
329 case ABORT_FIXUP_RETURN:
330 return;
331 case ABORT_FIXUP_FAILED:
332 /* Deliver a SIGILL to the process */
333 ksig.signb = SIGILL;
334 ksig.code = 0;
335 goto do_trapsignal;
336 default:
337 break;
338 }
339
340 va = trunc_page((vm_offset_t)far);
341
342 /*
343 * It is only a kernel address space fault iff:
344 * 1. user == 0 and
345 * 2. pcb_onfault not set or
346 * 3. pcb_onfault set and not LDRT/LDRBT/STRT/STRBT instruction.
347 */
348 if (user == 0 && (va >= VM_MIN_KERNEL_ADDRESS ||
349 (va < VM_MIN_ADDRESS && vector_page == ARM_VECTORS_LOW)) &&
350 __predict_true((pcb->pcb_onfault == NULL ||
351 (ReadWord(tf->tf_pc) & 0x05200000) != 0x04200000))) {
352 map = kernel_map;
353
354 /* Was the fault due to the FPE/IPKDB ? */
355 if (__predict_false((tf->tf_spsr & PSR_MODE)==PSR_UND32_MODE)) {
356
357 /*
358 * Force exit via userret()
359 * This is necessary as the FPE is an extension to
360 * userland that actually runs in a priveledged mode
361 * but uses USR mode permissions for its accesses.
362 */
363 user = 1;
364 ksig.signb = SIGSEGV;
365 ksig.code = 0;
366 goto do_trapsignal;
367 }
368 } else {
369 map = &td->td_proc->p_vmspace->vm_map;
370 }
371
372 /*
373 * We need to know whether the page should be mapped
374 * as R or R/W. The MMU does not give us the info as
375 * to whether the fault was caused by a read or a write.
376 *
377 * However, we know that a permission fault can only be
378 * the result of a write to a read-only location, so
379 * we can deal with those quickly.
380 *
381 * Otherwise we need to disassemble the instruction
382 * responsible to determine if it was a write.
383 */
384 if (IS_PERMISSION_FAULT(fsr)) {
385 ftype = VM_PROT_WRITE;
386 } else {
387 u_int insn = ReadWord(tf->tf_pc);
388
389 if (((insn & 0x0c100000) == 0x04000000) || /* STR/STRB */
390 ((insn & 0x0e1000b0) == 0x000000b0) || /* STRH/STRD */
391 ((insn & 0x0a100000) == 0x08000000)) /* STM/CDT */
392 {
393 ftype = VM_PROT_WRITE;
394 }
395 else
396 if ((insn & 0x0fb00ff0) == 0x01000090) /* SWP */
397 ftype = VM_PROT_READ | VM_PROT_WRITE;
398 else
399 ftype = VM_PROT_READ;
400 }
401
402 /*
403 * See if the fault is as a result of ref/mod emulation,
404 * or domain mismatch.
405 */
406 #ifdef DEBUG
407 last_fault_code = fsr;
408 #endif
409 if (pmap_fault_fixup(vmspace_pmap(td->td_proc->p_vmspace), va, ftype,
410 user)) {
411 goto out;
412 }
413
414 onfault = pcb->pcb_onfault;
415 pcb->pcb_onfault = NULL;
416 if (map != kernel_map) {
417 PROC_LOCK(p);
418 p->p_lock++;
419 PROC_UNLOCK(p);
420 }
421 error = vm_fault(map, va, ftype, (ftype & VM_PROT_WRITE) ?
422 VM_FAULT_DIRTY : VM_FAULT_NORMAL);
423 pcb->pcb_onfault = onfault;
424 if (__predict_true(error == 0)) {
425 goto out;
426 }
427
428 if (map != kernel_map) {
429 PROC_LOCK(p);
430 p->p_lock--;
431 PROC_UNLOCK(p);
432 }
433 if (user == 0) {
434 if (pcb->pcb_onfault) {
435 tf->tf_r0 = error;
436 tf->tf_pc = (register_t)(intptr_t) pcb->pcb_onfault;
437 return;
438 }
439
440 printf("\nvm_fault(%p, %x, %x, 0) -> %x\n", map, va, ftype,
441 error);
442 dab_fatal(tf, fsr, far, td, &ksig);
443 }
444
445
446 if (error == ENOMEM) {
447 printf("VM: pid %d (%s), uid %d killed: "
448 "out of swap\n", td->td_proc->p_pid, td->td_proc->p_comm,
449 (td->td_proc->p_ucred) ?
450 td->td_proc->p_ucred->cr_uid : -1);
451 ksig.signb = SIGKILL;
452 } else {
453 ksig.signb = SIGSEGV;
454 }
455 ksig.code = 0;
456 do_trapsignal:
457 call_trapsignal(td, ksig.signb, ksig.code);
458 out:
459 /* If returning to user mode, make sure to invoke userret() */
460 if (user)
461 userret(td, tf, sticks);
462 }
463
464 /*
465 * dab_fatal() handles the following data aborts:
466 *
467 * FAULT_WRTBUF_0 - Vector Exception
468 * FAULT_WRTBUF_1 - Terminal Exception
469 *
470 * We should never see these on a properly functioning system.
471 *
472 * This function is also called by the other handlers if they
473 * detect a fatal problem.
474 *
475 * Note: If 'l' is NULL, we assume we're dealing with a prefetch abort.
476 */
477 static int
478 dab_fatal(trapframe_t *tf, u_int fsr, u_int far, struct thread *td, struct ksig *ksig)
479 {
480 const char *mode;
481
482 mode = TRAP_USERMODE(tf) ? "user" : "kernel";
483
484 if (td != NULL) {
485 printf("Fatal %s mode data abort: '%s'\n", mode,
486 data_aborts[fsr & FAULT_TYPE_MASK].desc);
487 printf("trapframe: %p\nFSR=%08x, FAR=", tf, fsr);
488 if ((fsr & FAULT_IMPRECISE) == 0)
489 printf("%08x, ", far);
490 else
491 printf("Invalid, ");
492 printf("spsr=%08x\n", tf->tf_spsr);
493 } else {
494 printf("Fatal %s mode prefetch abort at 0x%08x\n",
495 mode, tf->tf_pc);
496 printf("trapframe: %p, spsr=%08x\n", tf, tf->tf_spsr);
497 }
498
499 printf("r0 =%08x, r1 =%08x, r2 =%08x, r3 =%08x\n",
500 tf->tf_r0, tf->tf_r1, tf->tf_r2, tf->tf_r3);
501 printf("r4 =%08x, r5 =%08x, r6 =%08x, r7 =%08x\n",
502 tf->tf_r4, tf->tf_r5, tf->tf_r6, tf->tf_r7);
503 printf("r8 =%08x, r9 =%08x, r10=%08x, r11=%08x\n",
504 tf->tf_r8, tf->tf_r9, tf->tf_r10, tf->tf_r11);
505 printf("r12=%08x, ", tf->tf_r12);
506
507 if (TRAP_USERMODE(tf))
508 printf("usp=%08x, ulr=%08x",
509 tf->tf_usr_sp, tf->tf_usr_lr);
510 else
511 printf("ssp=%08x, slr=%08x",
512 tf->tf_svc_sp, tf->tf_svc_lr);
513 printf(", pc =%08x\n\n", tf->tf_pc);
514
515 #ifdef KDB
516 kdb_trap(fsr, 0, tf);
517 #endif
518 panic("Fatal abort");
519 /*NOTREACHED*/
520 }
521
522 /*
523 * dab_align() handles the following data aborts:
524 *
525 * FAULT_ALIGN_0 - Alignment fault
526 * FAULT_ALIGN_0 - Alignment fault
527 *
528 * These faults are fatal if they happen in kernel mode. Otherwise, we
529 * deliver a bus error to the process.
530 */
531 static int
532 dab_align(trapframe_t *tf, u_int fsr, u_int far, struct thread *td, struct ksig *ksig)
533 {
534
535 /* Alignment faults are always fatal if they occur in kernel mode */
536 if (!TRAP_USERMODE(tf)) {
537 if (!td || !td->td_pcb->pcb_onfault)
538 dab_fatal(tf, fsr, far, td, ksig);
539 tf->tf_r0 = EFAULT;
540 tf->tf_pc = (int)td->td_pcb->pcb_onfault;
541 return (0);
542 }
543
544 /* pcb_onfault *must* be NULL at this point */
545
546 /* See if the cpu state needs to be fixed up */
547 (void) data_abort_fixup(tf, fsr, far, td, ksig);
548
549 /* Deliver a bus error signal to the process */
550 ksig->code = 0;
551 ksig->signb = SIGBUS;
552 td->td_frame = tf;
553
554 return (1);
555 }
556
557 /*
558 * dab_buserr() handles the following data aborts:
559 *
560 * FAULT_BUSERR_0 - External Abort on Linefetch -- Section
561 * FAULT_BUSERR_1 - External Abort on Linefetch -- Page
562 * FAULT_BUSERR_2 - External Abort on Non-linefetch -- Section
563 * FAULT_BUSERR_3 - External Abort on Non-linefetch -- Page
564 * FAULT_BUSTRNL1 - External abort on Translation -- Level 1
565 * FAULT_BUSTRNL2 - External abort on Translation -- Level 2
566 *
567 * If pcb_onfault is set, flag the fault and return to the handler.
568 * If the fault occurred in user mode, give the process a SIGBUS.
569 *
570 * Note: On XScale, FAULT_BUSERR_0, FAULT_BUSERR_1, and FAULT_BUSERR_2
571 * can be flagged as imprecise in the FSR. This causes a real headache
572 * since some of the machine state is lost. In this case, tf->tf_pc
573 * may not actually point to the offending instruction. In fact, if
574 * we've taken a double abort fault, it generally points somewhere near
575 * the top of "data_abort_entry" in exception.S.
576 *
577 * In all other cases, these data aborts are considered fatal.
578 */
579 static int
580 dab_buserr(trapframe_t *tf, u_int fsr, u_int far, struct thread *td, struct ksig *ksig)
581 {
582 struct pcb *pcb = td->td_pcb;
583
584 #ifdef __XSCALE__
585 if ((fsr & FAULT_IMPRECISE) != 0 &&
586 (tf->tf_spsr & PSR_MODE) == PSR_ABT32_MODE) {
587 /*
588 * Oops, an imprecise, double abort fault. We've lost the
589 * r14_abt/spsr_abt values corresponding to the original
590 * abort, and the spsr saved in the trapframe indicates
591 * ABT mode.
592 */
593 tf->tf_spsr &= ~PSR_MODE;
594
595 /*
596 * We use a simple heuristic to determine if the double abort
597 * happened as a result of a kernel or user mode access.
598 * If the current trapframe is at the top of the kernel stack,
599 * the fault _must_ have come from user mode.
600 */
601 if (tf != ((trapframe_t *)pcb->un_32.pcb32_sp) - 1) {
602 /*
603 * Kernel mode. We're either about to die a
604 * spectacular death, or pcb_onfault will come
605 * to our rescue. Either way, the current value
606 * of tf->tf_pc is irrelevant.
607 */
608 tf->tf_spsr |= PSR_SVC32_MODE;
609 if (pcb->pcb_onfault == NULL)
610 printf("\nKernel mode double abort!\n");
611 } else {
612 /*
613 * User mode. We've lost the program counter at the
614 * time of the fault (not that it was accurate anyway;
615 * it's not called an imprecise fault for nothing).
616 * About all we can do is copy r14_usr to tf_pc and
617 * hope for the best. The process is about to get a
618 * SIGBUS, so it's probably history anyway.
619 */
620 tf->tf_spsr |= PSR_USR32_MODE;
621 tf->tf_pc = tf->tf_usr_lr;
622 }
623 }
624
625 /* FAR is invalid for imprecise exceptions */
626 if ((fsr & FAULT_IMPRECISE) != 0)
627 far = 0;
628 #endif /* __XSCALE__ */
629
630 if (pcb->pcb_onfault) {
631 tf->tf_r0 = EFAULT;
632 tf->tf_pc = (register_t)(intptr_t) pcb->pcb_onfault;
633 return (0);
634 }
635
636 /* See if the cpu state needs to be fixed up */
637 (void) data_abort_fixup(tf, fsr, far, td, ksig);
638
639 /*
640 * At this point, if the fault happened in kernel mode, we're toast
641 */
642 if (!TRAP_USERMODE(tf))
643 dab_fatal(tf, fsr, far, td, ksig);
644
645 /* Deliver a bus error signal to the process */
646 ksig->signb = SIGBUS;
647 ksig->code = 0;
648 td->td_frame = tf;
649
650 return (1);
651 }
652
653 static __inline int
654 prefetch_abort_fixup(trapframe_t *tf, struct ksig *ksig)
655 {
656 #ifdef CPU_ABORT_FIXUP_REQUIRED
657 int error;
658
659 /* Call the cpu specific prefetch abort fixup routine */
660 error = cpu_prefetchabt_fixup(tf);
661 if (__predict_true(error != ABORT_FIXUP_FAILED))
662 return (error);
663
664 /*
665 * Oops, couldn't fix up the instruction
666 */
667 printf(
668 "prefetch_abort_fixup: fixup for %s mode prefetch abort failed.\n",
669 TRAP_USERMODE(tf) ? "user" : "kernel");
670 printf("pc = 0x%08x, opcode 0x%08x, insn = ", tf->tf_pc,
671 *((u_int *)tf->tf_pc));
672 disassemble(tf->tf_pc);
673
674 /* Die now if this happened in kernel mode */
675 if (!TRAP_USERMODE(tf))
676 dab_fatal(tf, 0, tf->tf_pc, NULL, ksig);
677
678 return (error);
679 #else
680 return (ABORT_FIXUP_OK);
681 #endif /* CPU_ABORT_FIXUP_REQUIRED */
682 }
683
684 /*
685 * void prefetch_abort_handler(trapframe_t *tf)
686 *
687 * Abort handler called when instruction execution occurs at
688 * a non existent or restricted (access permissions) memory page.
689 * If the address is invalid and we were in SVC mode then panic as
690 * the kernel should never prefetch abort.
691 * If the address is invalid and the page is mapped then the user process
692 * does no have read permission so send it a signal.
693 * Otherwise fault the page in and try again.
694 */
695 void
696 prefetch_abort_handler(trapframe_t *tf)
697 {
698 struct thread *td;
699 struct proc * p;
700 struct vm_map *map;
701 vm_offset_t fault_pc, va;
702 int error = 0;
703 u_int sticks = 0;
704 struct ksig ksig;
705
706
707 #if 0
708 /* Update vmmeter statistics */
709 uvmexp.traps++;
710 #endif
711 #if 0
712 printf("prefetch abort handler: %p %p\n", (void*)tf->tf_pc,
713 (void*)tf->tf_usr_lr);
714 #endif
715
716 td = curthread;
717 p = td->td_proc;
718 PCPU_LAZY_INC(cnt.v_trap);
719
720 if (TRAP_USERMODE(tf)) {
721 td->td_frame = tf;
722 if (td->td_ucred != td->td_proc->p_ucred)
723 cred_update_thread(td);
724 if (td->td_proc->p_flag & P_SA)
725 thread_user_enter(td);
726 }
727 fault_pc = tf->tf_pc;
728 if (td->td_critnest == 0 &&
729 __predict_true((tf->tf_spsr & I32_bit) == 0))
730 enable_interrupts(I32_bit);
731
732
733 /* See if the cpu state needs to be fixed up */
734 switch (prefetch_abort_fixup(tf, &ksig)) {
735 case ABORT_FIXUP_RETURN:
736 return;
737 case ABORT_FIXUP_FAILED:
738 /* Deliver a SIGILL to the process */
739 ksig.signb = SIGILL;
740 ksig.code = 0;
741 td->td_frame = tf;
742 goto do_trapsignal;
743 default:
744 break;
745 }
746
747 /* Prefetch aborts cannot happen in kernel mode */
748 if (__predict_false(!TRAP_USERMODE(tf)))
749 dab_fatal(tf, 0, tf->tf_pc, NULL, &ksig);
750 sticks = td->td_sticks;
751
752
753 /* Ok validate the address, can only execute in USER space */
754 if (__predict_false(fault_pc >= VM_MAXUSER_ADDRESS ||
755 (fault_pc < VM_MIN_ADDRESS && vector_page == ARM_VECTORS_LOW))) {
756 ksig.signb = SIGSEGV;
757 ksig.code = 0;
758 goto do_trapsignal;
759 }
760
761 map = &td->td_proc->p_vmspace->vm_map;
762 va = trunc_page(fault_pc);
763
764 /*
765 * See if the pmap can handle this fault on its own...
766 */
767 #ifdef DEBUG
768 last_fault_code = -1;
769 #endif
770 if (pmap_fault_fixup(map->pmap, va, VM_PROT_READ, 1))
771 goto out;
772
773 if (map != kernel_map) {
774 PROC_LOCK(p);
775 p->p_lock++;
776 PROC_UNLOCK(p);
777 }
778
779 error = vm_fault(map, va, VM_PROT_READ | VM_PROT_EXECUTE,
780 VM_FAULT_NORMAL);
781 if (map != kernel_map) {
782 PROC_LOCK(p);
783 p->p_lock--;
784 PROC_UNLOCK(p);
785 }
786
787 if (__predict_true(error == 0))
788 goto out;
789
790 if (error == ENOMEM) {
791 printf("VM: pid %d (%s), uid %d killed: "
792 "out of swap\n", td->td_proc->p_pid, td->td_proc->p_comm,
793 (td->td_proc->p_ucred) ?
794 td->td_proc->p_ucred->cr_uid : -1);
795 ksig.signb = SIGKILL;
796 } else {
797 ksig.signb = SIGSEGV;
798 }
799 ksig.code = 0;
800
801 do_trapsignal:
802 call_trapsignal(td, ksig.signb, ksig.code);
803
804 out:
805 userret(td, tf, sticks);
806
807 }
808
809 extern int badaddr_read_1(const uint8_t *, uint8_t *);
810 extern int badaddr_read_2(const uint16_t *, uint16_t *);
811 extern int badaddr_read_4(const uint32_t *, uint32_t *);
812 /*
813 * Tentatively read an 8, 16, or 32-bit value from 'addr'.
814 * If the read succeeds, the value is written to 'rptr' and zero is returned.
815 * Else, return EFAULT.
816 */
817 int
818 badaddr_read(void *addr, size_t size, void *rptr)
819 {
820 union {
821 uint8_t v1;
822 uint16_t v2;
823 uint32_t v4;
824 } u;
825 int rv;
826
827 cpu_drain_writebuf();
828
829 /* Read from the test address. */
830 switch (size) {
831 case sizeof(uint8_t):
832 rv = badaddr_read_1(addr, &u.v1);
833 if (rv == 0 && rptr)
834 *(uint8_t *) rptr = u.v1;
835 break;
836
837 case sizeof(uint16_t):
838 rv = badaddr_read_2(addr, &u.v2);
839 if (rv == 0 && rptr)
840 *(uint16_t *) rptr = u.v2;
841 break;
842
843 case sizeof(uint32_t):
844 rv = badaddr_read_4(addr, &u.v4);
845 if (rv == 0 && rptr)
846 *(uint32_t *) rptr = u.v4;
847 break;
848
849 default:
850 panic("badaddr: invalid size (%lu)", (u_long) size);
851 }
852
853 /* Return EFAULT if the address was invalid, else zero */
854 return (rv);
855 }
856
857 #define MAXARGS 8
858 static void
859 syscall(struct thread *td, trapframe_t *frame, u_int32_t insn)
860 {
861 struct proc *p = td->td_proc;
862 int code, error;
863 u_int nap, nargs;
864 register_t *ap, *args, copyargs[MAXARGS];
865 struct sysent *callp;
866 int locked = 0;
867 u_int sticks = 0;
868
869 PCPU_LAZY_INC(cnt.v_syscall);
870 sticks = td->td_sticks;
871 if (td->td_ucred != td->td_proc->p_ucred)
872 cred_update_thread(td);
873 switch (insn & SWI_OS_MASK) {
874 case 0: /* XXX: we need our own one. */
875 nap = 4;
876 break;
877 default:
878 trapsignal(td, SIGILL, 0);
879 userret(td, frame, td->td_sticks);
880 return;
881 }
882 code = insn & 0x000fffff;
883 sticks = td->td_sticks;
884 ap = &frame->tf_r0;
885 if (code == SYS_syscall) {
886 code = *ap++;
887
888 nap--;
889 } else if (code == SYS___syscall) {
890 code = *ap++;
891 nap -= 2;
892 ap++;
893 }
894 if (p->p_sysent->sv_mask)
895 code &= p->p_sysent->sv_mask;
896 if (code >= p->p_sysent->sv_size)
897 callp = &p->p_sysent->sv_table[0];
898 else
899 callp = &p->p_sysent->sv_table[code];
900 nargs = callp->sy_narg & SYF_ARGMASK;
901 memcpy(copyargs, ap, nap * sizeof(register_t));
902 if (nargs > nap) {
903 error = copyin((void *)frame->tf_usr_sp, copyargs + nap,
904 (nargs - nap) * sizeof(register_t));
905 if (error)
906 goto bad;
907 }
908 args = copyargs;
909 error = 0;
910 #ifdef KTRACE
911 if (KTRPOINT(td, KTR_SYSCALL))
912 ktrsyscall(code, nargs, args);
913 #endif
914
915 CTR4(KTR_SYSC, "syscall enter thread %p pid %d proc %s code %d", td,
916 td->td_proc->p_pid, td->td_proc->p_comm, code);
917 if ((callp->sy_narg & SYF_MPSAFE) == 0)
918 mtx_lock(&Giant);
919 locked = 1;
920 if (error == 0) {
921 td->td_retval[0] = 0;
922 td->td_retval[1] = 0;
923 STOPEVENT(p, S_SCE, (callp->sy_narg & SYF_ARGMASK));
924 PTRACESTOP_SC(p, td, S_PT_SCE);
925 error = (*callp->sy_call)(td, args);
926 }
927 switch (error) {
928 case 0:
929 #ifdef __ARMEB__
930 if ((insn & 0x000fffff) &&
931 (code != SYS_lseek)) {
932 /*
933 * 64-bit return, 32-bit syscall. Fixup byte order
934 */
935 frame->tf_r0 = 0;
936 frame->tf_r1 = td->td_retval[0];
937 } else {
938 frame->tf_r0 = td->td_retval[0];
939 frame->tf_r1 = td->td_retval[1];
940 }
941 #else
942 frame->tf_r0 = td->td_retval[0];
943 frame->tf_r1 = td->td_retval[1];
944 #endif
945 frame->tf_spsr &= ~PSR_C_bit; /* carry bit */
946 break;
947
948 case ERESTART:
949 /*
950 * Reconstruct the pc to point at the swi.
951 */
952 frame->tf_pc -= INSN_SIZE;
953 break;
954 case EJUSTRETURN:
955 /* nothing to do */
956 break;
957 default:
958 bad:
959 frame->tf_r0 = error;
960 frame->tf_spsr |= PSR_C_bit; /* carry bit */
961 break;
962 }
963 if (locked && (callp->sy_narg & SYF_MPSAFE) == 0)
964 mtx_unlock(&Giant);
965
966
967 userret(td, frame, sticks);
968 CTR4(KTR_SYSC, "syscall exit thread %p pid %d proc %s code %d", td,
969 td->td_proc->p_pid, td->td_proc->p_comm, code);
970
971 STOPEVENT(p, S_SCX, code);
972 PTRACESTOP_SC(p, td, S_PT_SCX);
973 #ifdef KTRACE
974 if (KTRPOINT(td, KTR_SYSRET))
975 ktrsysret(code, error, td->td_retval[0]);
976 #endif
977 mtx_assert(&sched_lock, MA_NOTOWNED);
978 mtx_assert(&Giant, MA_NOTOWNED);
979 }
980
981 void
982 swi_handler(trapframe_t *frame)
983 {
984 struct thread *td = curthread;
985 uint32_t insn;
986
987 td->td_frame = frame;
988
989 if (td->td_proc->p_flag & P_SA)
990 thread_user_enter(td);
991 /*
992 * Make sure the program counter is correctly aligned so we
993 * don't take an alignment fault trying to read the opcode.
994 */
995 if (__predict_false(((frame->tf_pc - INSN_SIZE) & 3) != 0)) {
996 trapsignal(td, SIGILL, 0);
997 userret(td, frame, td->td_sticks);
998 return;
999 }
1000 insn = *(u_int32_t *)(frame->tf_pc - INSN_SIZE);
1001 /*
1002 * Enable interrupts if they were enabled before the exception.
1003 * Since all syscalls *should* come from user mode it will always
1004 * be safe to enable them, but check anyway.
1005 */
1006 if (td->td_critnest == 0 && !(frame->tf_spsr & I32_bit))
1007 enable_interrupts(I32_bit);
1008
1009 syscall(td, frame, insn);
1010 }
1011
Cache object: 5638d605030554d7d447bf54df30c761
|