fault.c revision 1.90 1 /* $NetBSD: fault.c,v 1.90 2013/08/18 06:28:18 matt 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
83 #include <sys/types.h>
84 __KERNEL_RCSID(0, "$NetBSD: fault.c,v 1.90 2013/08/18 06:28:18 matt Exp $");
85
86 #include <sys/param.h>
87 #include <sys/systm.h>
88 #include <sys/proc.h>
89 #include <sys/kernel.h>
90 #include <sys/kauth.h>
91 #include <sys/cpu.h>
92 #include <sys/intr.h>
93
94 #include <uvm/uvm_extern.h>
95 #include <uvm/uvm_stat.h>
96 #ifdef UVMHIST
97 #include <uvm/uvm.h>
98 #endif
99
100 #include <arm/locore.h>
101
102 #include <arm/arm32/katelib.h>
103
104 #include <machine/pcb.h>
105 #if defined(DDB) || defined(KGDB)
106 #include <machine/db_machdep.h>
107 #ifdef KGDB
108 #include <sys/kgdb.h>
109 #endif
110 #if !defined(DDB)
111 #define kdb_trap kgdb_trap
112 #endif
113 #endif
114
115 #include <arch/arm/arm/disassem.h>
116 #include <arm/arm32/machdep.h>
117
118 extern char fusubailout[];
119
120 #ifdef DEBUG
121 int last_fault_code; /* For the benefit of pmap_fault_fixup() */
122 #endif
123
124 #if defined(CPU_ARM3) || defined(CPU_ARM6) || \
125 defined(CPU_ARM7) || defined(CPU_ARM7TDMI)
126 /* These CPUs may need data/prefetch abort fixups */
127 #define CPU_ABORT_FIXUP_REQUIRED
128 #endif
129
130 struct data_abort {
131 int (*func)(trapframe_t *, u_int, u_int, struct lwp *, ksiginfo_t *);
132 const char *desc;
133 };
134
135 static int dab_fatal(trapframe_t *, u_int, u_int, struct lwp *, ksiginfo_t *);
136 static int dab_align(trapframe_t *, u_int, u_int, struct lwp *, ksiginfo_t *);
137 static int dab_buserr(trapframe_t *, u_int, u_int, struct lwp *, ksiginfo_t *);
138
139 static const struct data_abort data_aborts[] = {
140 {dab_fatal, "Vector Exception"},
141 {dab_align, "Alignment Fault 1"},
142 {dab_fatal, "Terminal Exception"},
143 {dab_align, "Alignment Fault 3"},
144 {dab_buserr, "External Linefetch Abort (S)"},
145 {NULL, "Translation Fault (S)"},
146 {dab_buserr, "External Linefetch Abort (P)"},
147 {NULL, "Translation Fault (P)"},
148 {dab_buserr, "External Non-Linefetch Abort (S)"},
149 {NULL, "Domain Fault (S)"},
150 {dab_buserr, "External Non-Linefetch Abort (P)"},
151 {NULL, "Domain Fault (P)"},
152 {dab_buserr, "External Translation Abort (L1)"},
153 {NULL, "Permission Fault (S)"},
154 {dab_buserr, "External Translation Abort (L2)"},
155 {NULL, "Permission Fault (P)"}
156 };
157
158 /* Determine if 'x' is a permission fault */
159 #define IS_PERMISSION_FAULT(x) \
160 (((1 << ((x) & FAULT_TYPE_MASK)) & \
161 ((1 << FAULT_PERM_P) | (1 << FAULT_PERM_S))) != 0)
162
163 #if 0
164 /* maybe one day we'll do emulations */
165 #define TRAPSIGNAL(l,k) (*(l)->l_proc->p_emul->e_trapsignal)((l), (k))
166 #else
167 #define TRAPSIGNAL(l,k) trapsignal((l), (k))
168 #endif
169
170 static inline void
171 call_trapsignal(struct lwp *l, ksiginfo_t *ksi)
172 {
173
174 TRAPSIGNAL(l, ksi);
175 }
176
177 static inline int
178 data_abort_fixup(trapframe_t *tf, u_int fsr, u_int far, struct lwp *l)
179 {
180 #ifdef CPU_ABORT_FIXUP_REQUIRED
181 int error;
182
183 /* Call the CPU specific data abort fixup routine */
184 error = cpu_dataabt_fixup(tf);
185 if (__predict_true(error != ABORT_FIXUP_FAILED))
186 return (error);
187
188 /*
189 * Oops, couldn't fix up the instruction
190 */
191 printf("%s: fixup for %s mode data abort failed.\n", __func__,
192 TRAP_USERMODE(tf) ? "user" : "kernel");
193 #ifdef THUMB_CODE
194 if (tf->tf_spsr & PSR_T_bit) {
195 printf("pc = 0x%08x, opcode 0x%04x, 0x%04x, insn = ",
196 tf->tf_pc, *((uint16 *)(tf->tf_pc & ~1)),
197 *((uint16 *)((tf->tf_pc + 2) & ~1)));
198 }
199 else
200 #endif
201 {
202 printf("pc = 0x%08x, opcode 0x%08x, insn = ", tf->tf_pc,
203 *((u_int *)tf->tf_pc));
204 }
205 disassemble(tf->tf_pc);
206
207 /* Die now if this happened in kernel mode */
208 if (!TRAP_USERMODE(tf))
209 dab_fatal(tf, fsr, far, l, NULL);
210
211 return (error);
212 #else
213 return (ABORT_FIXUP_OK);
214 #endif /* CPU_ABORT_FIXUP_REQUIRED */
215 }
216
217 void
218 data_abort_handler(trapframe_t *tf)
219 {
220 struct vm_map *map;
221 struct lwp * const l = curlwp;
222 struct cpu_info * const ci = curcpu();
223 u_int far, fsr;
224 vm_prot_t ftype;
225 void *onfault;
226 vaddr_t va;
227 int error;
228 ksiginfo_t ksi;
229
230 UVMHIST_FUNC(__func__); UVMHIST_CALLED(maphist);
231
232 /* Grab FAR/FSR before enabling interrupts */
233 far = cpu_faultaddress();
234 fsr = cpu_faultstatus();
235
236 /* Update vmmeter statistics */
237 ci->ci_data.cpu_ntrap++;
238
239 /* Re-enable interrupts if they were enabled previously */
240 KASSERT(!TRAP_USERMODE(tf) || (tf->tf_spsr & IF32_bits) == 0);
241 if (__predict_true((tf->tf_spsr & IF32_bits) != IF32_bits))
242 restore_interrupts(tf->tf_spsr & IF32_bits);
243
244 /* Get the current lwp structure */
245
246 UVMHIST_LOG(maphist, " (pc=0x%x, l=0x%x, far=0x%x, fsr=0x%x)",
247 tf->tf_pc, l, far, fsr);
248
249 /* Data abort came from user mode? */
250 bool user = (TRAP_USERMODE(tf) != 0);
251 if (user)
252 LWP_CACHE_CREDS(l, l->l_proc);
253
254 /* Grab the current pcb */
255 struct pcb * const pcb = lwp_getpcb(l);
256
257 curcpu()->ci_abt_evs[fsr & FAULT_TYPE_MASK].ev_count++;
258
259 /* Invoke the appropriate handler, if necessary */
260 if (__predict_false(data_aborts[fsr & FAULT_TYPE_MASK].func != NULL)) {
261 #ifdef DIAGNOSTIC
262 printf("%s: data_aborts fsr=0x%x far=0x%x\n",
263 __func__, fsr, far);
264 #endif
265 if ((data_aborts[fsr & FAULT_TYPE_MASK].func)(tf, fsr, far,
266 l, &ksi))
267 goto do_trapsignal;
268 goto out;
269 }
270
271 /*
272 * At this point, we're dealing with one of the following data aborts:
273 *
274 * FAULT_TRANS_S - Translation -- Section
275 * FAULT_TRANS_P - Translation -- Page
276 * FAULT_DOMAIN_S - Domain -- Section
277 * FAULT_DOMAIN_P - Domain -- Page
278 * FAULT_PERM_S - Permission -- Section
279 * FAULT_PERM_P - Permission -- Page
280 *
281 * These are the main virtual memory-related faults signalled by
282 * the MMU.
283 */
284
285 /* fusubailout is used by [fs]uswintr to avoid page faulting */
286 if (__predict_false(pcb->pcb_onfault == fusubailout)) {
287 tf->tf_r0 = EFAULT;
288 tf->tf_pc = (intptr_t) pcb->pcb_onfault;
289 return;
290 }
291
292 if (user) {
293 lwp_settrapframe(l, tf);
294 }
295
296 /*
297 * Make sure the Program Counter is sane. We could fall foul of
298 * someone executing Thumb code, in which case the PC might not
299 * be word-aligned. This would cause a kernel alignment fault
300 * further down if we have to decode the current instruction.
301 */
302 #ifdef THUMB_CODE
303 /*
304 * XXX: It would be nice to be able to support Thumb in the kernel
305 * at some point.
306 */
307 if (__predict_false(!user && (tf->tf_pc & 3) != 0)) {
308 printf("\n%s: Misaligned Kernel-mode Program Counter\n",
309 __func__);
310 dab_fatal(tf, fsr, far, l, NULL);
311 }
312 #else
313 if (__predict_false((tf->tf_pc & 3) != 0)) {
314 if (user) {
315 /*
316 * Give the user an illegal instruction signal.
317 */
318 /* Deliver a SIGILL to the process */
319 KSI_INIT_TRAP(&ksi);
320 ksi.ksi_signo = SIGILL;
321 ksi.ksi_code = ILL_ILLOPC;
322 ksi.ksi_addr = (uint32_t *)(intptr_t) far;
323 ksi.ksi_trap = fsr;
324 goto do_trapsignal;
325 }
326
327 /*
328 * The kernel never executes Thumb code.
329 */
330 printf("\n%s: Misaligned Kernel-mode Program Counter\n",
331 __func__);
332 dab_fatal(tf, fsr, far, l, NULL);
333 }
334 #endif
335
336 /* See if the CPU state needs to be fixed up */
337 switch (data_abort_fixup(tf, fsr, far, l)) {
338 case ABORT_FIXUP_RETURN:
339 return;
340 case ABORT_FIXUP_FAILED:
341 /* Deliver a SIGILL to the process */
342 KSI_INIT_TRAP(&ksi);
343 ksi.ksi_signo = SIGILL;
344 ksi.ksi_code = ILL_ILLOPC;
345 ksi.ksi_addr = (uint32_t *)(intptr_t) far;
346 ksi.ksi_trap = fsr;
347 goto do_trapsignal;
348 default:
349 break;
350 }
351
352 va = trunc_page((vaddr_t)far);
353
354 /*
355 * It is only a kernel address space fault iff:
356 * 1. user == 0 and
357 * 2. pcb_onfault not set or
358 * 3. pcb_onfault set and not LDRT/LDRBT/STRT/STRBT instruction.
359 */
360 if (!user && (va >= VM_MIN_KERNEL_ADDRESS ||
361 (va < VM_MIN_ADDRESS && vector_page == ARM_VECTORS_LOW)) &&
362 __predict_true((pcb->pcb_onfault == NULL ||
363 (ReadWord(tf->tf_pc) & 0x05200000) != 0x04200000))) {
364 map = kernel_map;
365
366 /* Was the fault due to the FPE/IPKDB ? */
367 if (__predict_false((tf->tf_spsr & PSR_MODE)==PSR_UND32_MODE)) {
368 KSI_INIT_TRAP(&ksi);
369 ksi.ksi_signo = SIGSEGV;
370 ksi.ksi_code = SEGV_ACCERR;
371 ksi.ksi_addr = (uint32_t *)(intptr_t) far;
372 ksi.ksi_trap = fsr;
373
374 /*
375 * Force exit via userret()
376 * This is necessary as the FPE is an extension to
377 * userland that actually runs in a priveledged mode
378 * but uses USR mode permissions for its accesses.
379 */
380 user = true;
381 goto do_trapsignal;
382 }
383 } else {
384 map = &l->l_proc->p_vmspace->vm_map;
385 }
386
387 /*
388 * We need to know whether the page should be mapped
389 * as R or R/W. The MMU does not give us the info as
390 * to whether the fault was caused by a read or a write.
391 *
392 * However, we know that a permission fault can only be
393 * the result of a write to a read-only location, so
394 * we can deal with those quickly.
395 *
396 * Otherwise we need to disassemble the instruction
397 * responsible to determine if it was a write.
398 */
399 if (IS_PERMISSION_FAULT(fsr))
400 ftype = VM_PROT_WRITE;
401 else {
402 #ifdef THUMB_CODE
403 /* Fast track the ARM case. */
404 if (__predict_false(tf->tf_spsr & PSR_T_bit)) {
405 u_int insn = fusword((void *)(tf->tf_pc & ~1));
406 u_int insn_f8 = insn & 0xf800;
407 u_int insn_fe = insn & 0xfe00;
408
409 if (insn_f8 == 0x6000 || /* STR(1) */
410 insn_f8 == 0x7000 || /* STRB(1) */
411 insn_f8 == 0x8000 || /* STRH(1) */
412 insn_f8 == 0x9000 || /* STR(3) */
413 insn_f8 == 0xc000 || /* STM */
414 insn_fe == 0x5000 || /* STR(2) */
415 insn_fe == 0x5200 || /* STRH(2) */
416 insn_fe == 0x5400) /* STRB(2) */
417 ftype = VM_PROT_WRITE;
418 else
419 ftype = VM_PROT_READ;
420 }
421 else
422 #endif
423 {
424 u_int insn = ReadWord(tf->tf_pc);
425
426 if (((insn & 0x0c100000) == 0x04000000) || /* STR[B] */
427 ((insn & 0x0e1000b0) == 0x000000b0) || /* STR[HD]*/
428 ((insn & 0x0a100000) == 0x08000000) || /* STM/CDT*/
429 ((insn & 0x0f9000f0) == 0x01800090)) /* STREX[BDH] */
430 ftype = VM_PROT_WRITE;
431 else if ((insn & 0x0fb00ff0) == 0x01000090)/* SWP */
432 ftype = VM_PROT_READ | VM_PROT_WRITE;
433 else
434 ftype = VM_PROT_READ;
435 }
436 }
437
438 /*
439 * See if the fault is as a result of ref/mod emulation,
440 * or domain mismatch.
441 */
442 #ifdef DEBUG
443 last_fault_code = fsr;
444 #endif
445 if (pmap_fault_fixup(map->pmap, va, ftype, user)) {
446 UVMHIST_LOG(maphist, " <- ref/mod emul", 0, 0, 0, 0);
447 goto out;
448 }
449
450 if (__predict_false(curcpu()->ci_intr_depth > 0)) {
451 if (pcb->pcb_onfault) {
452 tf->tf_r0 = EINVAL;
453 tf->tf_pc = (register_t)(intptr_t) pcb->pcb_onfault;
454 return;
455 }
456 printf("\nNon-emulated page fault with intr_depth > 0\n");
457 dab_fatal(tf, fsr, far, l, NULL);
458 }
459
460 onfault = pcb->pcb_onfault;
461 pcb->pcb_onfault = NULL;
462 error = uvm_fault(map, va, ftype);
463 pcb->pcb_onfault = onfault;
464
465 if (__predict_true(error == 0)) {
466 if (user)
467 uvm_grow(l->l_proc, va); /* Record any stack growth */
468 else
469 ucas_ras_check(tf);
470 UVMHIST_LOG(maphist, " <- uvm", 0, 0, 0, 0);
471 goto out;
472 }
473
474 if (user == 0) {
475 if (pcb->pcb_onfault) {
476 tf->tf_r0 = error;
477 tf->tf_pc = (register_t)(intptr_t) pcb->pcb_onfault;
478 return;
479 }
480
481 printf("\nuvm_fault(%p, %lx, %x) -> %x\n", map, va, ftype,
482 error);
483 dab_fatal(tf, fsr, far, l, NULL);
484 }
485
486 KSI_INIT_TRAP(&ksi);
487
488 if (error == ENOMEM) {
489 printf("UVM: pid %d (%s), uid %d killed: "
490 "out of swap\n", l->l_proc->p_pid, l->l_proc->p_comm,
491 l->l_cred ? kauth_cred_geteuid(l->l_cred) : -1);
492 ksi.ksi_signo = SIGKILL;
493 } else
494 ksi.ksi_signo = SIGSEGV;
495
496 ksi.ksi_code = (error == EACCES) ? SEGV_ACCERR : SEGV_MAPERR;
497 ksi.ksi_addr = (uint32_t *)(intptr_t) far;
498 ksi.ksi_trap = fsr;
499 UVMHIST_LOG(maphist, " <- error (%d)", error, 0, 0, 0);
500
501 do_trapsignal:
502 call_trapsignal(l, &ksi);
503 out:
504 /* If returning to user mode, make sure to invoke userret() */
505 if (user)
506 userret(l);
507 }
508
509 /*
510 * dab_fatal() handles the following data aborts:
511 *
512 * FAULT_WRTBUF_0 - Vector Exception
513 * FAULT_WRTBUF_1 - Terminal Exception
514 *
515 * We should never see these on a properly functioning system.
516 *
517 * This function is also called by the other handlers if they
518 * detect a fatal problem.
519 *
520 * Note: If 'l' is NULL, we assume we're dealing with a prefetch abort.
521 */
522 static int
523 dab_fatal(trapframe_t *tf, u_int fsr, u_int far, struct lwp *l, ksiginfo_t *ksi)
524 {
525 const char * const mode = TRAP_USERMODE(tf) ? "user" : "kernel";
526
527 if (l != NULL) {
528 printf("Fatal %s mode data abort: '%s'\n", mode,
529 data_aborts[fsr & FAULT_TYPE_MASK].desc);
530 printf("trapframe: %p\nFSR=%08x, FAR=", tf, fsr);
531 if ((fsr & FAULT_IMPRECISE) == 0)
532 printf("%08x, ", far);
533 else
534 printf("Invalid, ");
535 printf("spsr=%08x\n", tf->tf_spsr);
536 } else {
537 printf("Fatal %s mode prefetch abort at 0x%08x\n",
538 mode, tf->tf_pc);
539 printf("trapframe: %p, spsr=%08x\n", tf, tf->tf_spsr);
540 }
541
542 printf("r0 =%08x, r1 =%08x, r2 =%08x, r3 =%08x\n",
543 tf->tf_r0, tf->tf_r1, tf->tf_r2, tf->tf_r3);
544 printf("r4 =%08x, r5 =%08x, r6 =%08x, r7 =%08x\n",
545 tf->tf_r4, tf->tf_r5, tf->tf_r6, tf->tf_r7);
546 printf("r8 =%08x, r9 =%08x, r10=%08x, r11=%08x\n",
547 tf->tf_r8, tf->tf_r9, tf->tf_r10, tf->tf_r11);
548 printf("r12=%08x, ", tf->tf_r12);
549
550 if (TRAP_USERMODE(tf))
551 printf("usp=%08x, ulr=%08x",
552 tf->tf_usr_sp, tf->tf_usr_lr);
553 else
554 printf("ssp=%08x, slr=%08x",
555 tf->tf_svc_sp, tf->tf_svc_lr);
556 printf(", pc =%08x\n\n", tf->tf_pc);
557
558 #if defined(DDB) || defined(KGDB)
559 kdb_trap(T_FAULT, tf);
560 #endif
561 panic("Fatal abort");
562 /*NOTREACHED*/
563 }
564
565 /*
566 * dab_align() handles the following data aborts:
567 *
568 * FAULT_ALIGN_0 - Alignment fault
569 * FAULT_ALIGN_0 - Alignment fault
570 *
571 * These faults are fatal if they happen in kernel mode. Otherwise, we
572 * deliver a bus error to the process.
573 */
574 static int
575 dab_align(trapframe_t *tf, u_int fsr, u_int far, struct lwp *l, ksiginfo_t *ksi)
576 {
577 /* Alignment faults are always fatal if they occur in kernel mode */
578 if (!TRAP_USERMODE(tf))
579 dab_fatal(tf, fsr, far, l, NULL);
580
581 /* pcb_onfault *must* be NULL at this point */
582 KDASSERT(((struct pcb *)lwp_getpcb(l))->pcb_onfault == NULL);
583
584 /* See if the CPU state needs to be fixed up */
585 (void) data_abort_fixup(tf, fsr, far, l);
586
587 /* Deliver a bus error signal to the process */
588 KSI_INIT_TRAP(ksi);
589 ksi->ksi_signo = SIGBUS;
590 ksi->ksi_code = BUS_ADRALN;
591 ksi->ksi_addr = (uint32_t *)(intptr_t)far;
592 ksi->ksi_trap = fsr;
593
594 lwp_settrapframe(l, tf);
595
596 return (1);
597 }
598
599 /*
600 * dab_buserr() handles the following data aborts:
601 *
602 * FAULT_BUSERR_0 - External Abort on Linefetch -- Section
603 * FAULT_BUSERR_1 - External Abort on Linefetch -- Page
604 * FAULT_BUSERR_2 - External Abort on Non-linefetch -- Section
605 * FAULT_BUSERR_3 - External Abort on Non-linefetch -- Page
606 * FAULT_BUSTRNL1 - External abort on Translation -- Level 1
607 * FAULT_BUSTRNL2 - External abort on Translation -- Level 2
608 *
609 * If pcb_onfault is set, flag the fault and return to the handler.
610 * If the fault occurred in user mode, give the process a SIGBUS.
611 *
612 * Note: On XScale, FAULT_BUSERR_0, FAULT_BUSERR_1, and FAULT_BUSERR_2
613 * can be flagged as imprecise in the FSR. This causes a real headache
614 * since some of the machine state is lost. In this case, tf->tf_pc
615 * may not actually point to the offending instruction. In fact, if
616 * we've taken a double abort fault, it generally points somewhere near
617 * the top of "data_abort_entry" in exception.S.
618 *
619 * In all other cases, these data aborts are considered fatal.
620 */
621 static int
622 dab_buserr(trapframe_t *tf, u_int fsr, u_int far, struct lwp *l,
623 ksiginfo_t *ksi)
624 {
625 struct pcb *pcb = lwp_getpcb(l);
626
627 #ifdef __XSCALE__
628 if ((fsr & FAULT_IMPRECISE) != 0 &&
629 (tf->tf_spsr & PSR_MODE) == PSR_ABT32_MODE) {
630 /*
631 * Oops, an imprecise, double abort fault. We've lost the
632 * r14_abt/spsr_abt values corresponding to the original
633 * abort, and the spsr saved in the trapframe indicates
634 * ABT mode.
635 */
636 tf->tf_spsr &= ~PSR_MODE;
637
638 /*
639 * We use a simple heuristic to determine if the double abort
640 * happened as a result of a kernel or user mode access.
641 * If the current trapframe is at the top of the kernel stack,
642 * the fault _must_ have come from user mode.
643 */
644 if (tf != ((trapframe_t *)pcb->pcb_ksp) - 1) {
645 /*
646 * Kernel mode. We're either about to die a
647 * spectacular death, or pcb_onfault will come
648 * to our rescue. Either way, the current value
649 * of tf->tf_pc is irrelevant.
650 */
651 tf->tf_spsr |= PSR_SVC32_MODE;
652 if (pcb->pcb_onfault == NULL)
653 printf("\nKernel mode double abort!\n");
654 } else {
655 /*
656 * User mode. We've lost the program counter at the
657 * time of the fault (not that it was accurate anyway;
658 * it's not called an imprecise fault for nothing).
659 * About all we can do is copy r14_usr to tf_pc and
660 * hope for the best. The process is about to get a
661 * SIGBUS, so it's probably history anyway.
662 */
663 tf->tf_spsr |= PSR_USR32_MODE;
664 tf->tf_pc = tf->tf_usr_lr;
665 #ifdef THUMB_CODE
666 tf->tf_spsr &= ~PSR_T_bit;
667 if (tf->tf_usr_lr & 1)
668 tf->tf_spsr |= PSR_T_bit;
669 #endif
670 }
671 }
672
673 /* FAR is invalid for imprecise exceptions */
674 if ((fsr & FAULT_IMPRECISE) != 0)
675 far = 0;
676 #endif /* __XSCALE__ */
677
678 if (pcb->pcb_onfault) {
679 KDASSERT(TRAP_USERMODE(tf) == 0);
680 tf->tf_r0 = EFAULT;
681 tf->tf_pc = (register_t)(intptr_t) pcb->pcb_onfault;
682 return (0);
683 }
684
685 /* See if the CPU state needs to be fixed up */
686 (void) data_abort_fixup(tf, fsr, far, l);
687
688 /*
689 * At this point, if the fault happened in kernel mode, we're toast
690 */
691 if (!TRAP_USERMODE(tf))
692 dab_fatal(tf, fsr, far, l, NULL);
693
694 /* Deliver a bus error signal to the process */
695 KSI_INIT_TRAP(ksi);
696 ksi->ksi_signo = SIGBUS;
697 ksi->ksi_code = BUS_ADRERR;
698 ksi->ksi_addr = (uint32_t *)(intptr_t)far;
699 ksi->ksi_trap = fsr;
700
701 lwp_settrapframe(l, tf);
702
703 return (1);
704 }
705
706 static inline int
707 prefetch_abort_fixup(trapframe_t *tf)
708 {
709 #ifdef CPU_ABORT_FIXUP_REQUIRED
710 int error;
711
712 /* Call the CPU specific prefetch abort fixup routine */
713 error = cpu_prefetchabt_fixup(tf);
714 if (__predict_true(error != ABORT_FIXUP_FAILED))
715 return (error);
716
717 /*
718 * Oops, couldn't fix up the instruction
719 */
720 printf("%s: fixup for %s mode prefetch abort failed.\n", __func__,
721 TRAP_USERMODE(tf) ? "user" : "kernel");
722 #ifdef THUMB_CODE
723 if (tf->tf_spsr & PSR_T_bit) {
724 printf("pc = 0x%08x, opcode 0x%04x, 0x%04x, insn = ",
725 tf->tf_pc, *((uint16 *)(tf->tf_pc & ~1)),
726 *((uint16 *)((tf->tf_pc + 2) & ~1)));
727 }
728 else
729 #endif
730 {
731 printf("pc = 0x%08x, opcode 0x%08x, insn = ", tf->tf_pc,
732 *((u_int *)tf->tf_pc));
733 }
734 disassemble(tf->tf_pc);
735
736 /* Die now if this happened in kernel mode */
737 if (!TRAP_USERMODE(tf))
738 dab_fatal(tf, 0, tf->tf_pc, NULL, NULL);
739
740 return (error);
741 #else
742 return (ABORT_FIXUP_OK);
743 #endif /* CPU_ABORT_FIXUP_REQUIRED */
744 }
745
746 /*
747 * void prefetch_abort_handler(trapframe_t *tf)
748 *
749 * Abort handler called when instruction execution occurs at
750 * a non existent or restricted (access permissions) memory page.
751 * If the address is invalid and we were in SVC mode then panic as
752 * the kernel should never prefetch abort.
753 * If the address is invalid and the page is mapped then the user process
754 * does no have read permission so send it a signal.
755 * Otherwise fault the page in and try again.
756 */
757 void
758 prefetch_abort_handler(trapframe_t *tf)
759 {
760 struct lwp *l;
761 struct pcb *pcb;
762 struct vm_map *map;
763 vaddr_t fault_pc, va;
764 ksiginfo_t ksi;
765 int error, user;
766
767 UVMHIST_FUNC(__func__); UVMHIST_CALLED(maphist);
768
769 /* Update vmmeter statistics */
770 curcpu()->ci_data.cpu_ntrap++;
771
772 l = curlwp;
773 pcb = lwp_getpcb(l);
774
775 if ((user = TRAP_USERMODE(tf)) != 0)
776 LWP_CACHE_CREDS(l, l->l_proc);
777
778 /*
779 * Enable IRQ's (disabled by the abort) This always comes
780 * from user mode so we know interrupts were not disabled.
781 * But we check anyway.
782 */
783 KASSERT(!TRAP_USERMODE(tf) || (tf->tf_spsr & IF32_bits) == 0);
784 if (__predict_true((tf->tf_spsr & I32_bit) != IF32_bits))
785 restore_interrupts(tf->tf_spsr & IF32_bits);
786
787 /* See if the CPU state needs to be fixed up */
788 switch (prefetch_abort_fixup(tf)) {
789 case ABORT_FIXUP_RETURN:
790 KASSERT(!TRAP_USERMODE(tf) || (tf->tf_spsr & IF32_bits) == 0);
791 return;
792 case ABORT_FIXUP_FAILED:
793 /* Deliver a SIGILL to the process */
794 KSI_INIT_TRAP(&ksi);
795 ksi.ksi_signo = SIGILL;
796 ksi.ksi_code = ILL_ILLOPC;
797 ksi.ksi_addr = (uint32_t *)(intptr_t) tf->tf_pc;
798 lwp_settrapframe(l, tf);
799 goto do_trapsignal;
800 default:
801 break;
802 }
803
804 /* Prefetch aborts cannot happen in kernel mode */
805 if (__predict_false(!user))
806 dab_fatal(tf, 0, tf->tf_pc, NULL, NULL);
807
808 /* Get fault address */
809 fault_pc = tf->tf_pc;
810 lwp_settrapframe(l, tf);
811 UVMHIST_LOG(maphist, " (pc=0x%x, l=0x%x, tf=0x%x)", fault_pc, l, tf,
812 0);
813
814 /* Ok validate the address, can only execute in USER space */
815 if (__predict_false(fault_pc >= VM_MAXUSER_ADDRESS ||
816 (fault_pc < VM_MIN_ADDRESS && vector_page == ARM_VECTORS_LOW))) {
817 KSI_INIT_TRAP(&ksi);
818 ksi.ksi_signo = SIGSEGV;
819 ksi.ksi_code = SEGV_ACCERR;
820 ksi.ksi_addr = (uint32_t *)(intptr_t) fault_pc;
821 ksi.ksi_trap = fault_pc;
822 goto do_trapsignal;
823 }
824
825 map = &l->l_proc->p_vmspace->vm_map;
826 va = trunc_page(fault_pc);
827
828 /*
829 * See if the pmap can handle this fault on its own...
830 */
831 #ifdef DEBUG
832 last_fault_code = -1;
833 #endif
834 if (pmap_fault_fixup(map->pmap, va, VM_PROT_READ|VM_PROT_EXECUTE, 1)) {
835 UVMHIST_LOG (maphist, " <- emulated", 0, 0, 0, 0);
836 goto out;
837 }
838
839 #ifdef DIAGNOSTIC
840 if (__predict_false(curcpu()->ci_intr_depth > 0)) {
841 printf("\nNon-emulated prefetch abort with intr_depth > 0\n");
842 dab_fatal(tf, 0, tf->tf_pc, NULL, NULL);
843 }
844 #endif
845
846 KASSERT(pcb->pcb_onfault == NULL);
847 error = uvm_fault(map, va, VM_PROT_READ);
848
849 if (__predict_true(error == 0)) {
850 UVMHIST_LOG (maphist, " <- uvm", 0, 0, 0, 0);
851 goto out;
852 }
853 KSI_INIT_TRAP(&ksi);
854
855 UVMHIST_LOG (maphist, " <- fatal (%d)", error, 0, 0, 0);
856 if (error == ENOMEM) {
857 printf("UVM: pid %d (%s), uid %d killed: "
858 "out of swap\n", l->l_proc->p_pid, l->l_proc->p_comm,
859 l->l_cred ? kauth_cred_geteuid(l->l_cred) : -1);
860 ksi.ksi_signo = SIGKILL;
861 } else
862 ksi.ksi_signo = SIGSEGV;
863
864 ksi.ksi_code = SEGV_MAPERR;
865 ksi.ksi_addr = (uint32_t *)(intptr_t) fault_pc;
866 ksi.ksi_trap = fault_pc;
867
868 do_trapsignal:
869 call_trapsignal(l, &ksi);
870
871 out:
872 KASSERT(!TRAP_USERMODE(tf) || (tf->tf_spsr & IF32_bits) == 0);
873 userret(l);
874 }
875
876 /*
877 * Tentatively read an 8, 16, or 32-bit value from 'addr'.
878 * If the read succeeds, the value is written to 'rptr' and zero is returned.
879 * Else, return EFAULT.
880 */
881 int
882 badaddr_read(void *addr, size_t size, void *rptr)
883 {
884 extern int badaddr_read_1(const uint8_t *, uint8_t *);
885 extern int badaddr_read_2(const uint16_t *, uint16_t *);
886 extern int badaddr_read_4(const uint32_t *, uint32_t *);
887 union {
888 uint8_t v1;
889 uint16_t v2;
890 uint32_t v4;
891 } u;
892 int rv, s;
893
894 cpu_drain_writebuf();
895
896 s = splhigh();
897
898 /* Read from the test address. */
899 switch (size) {
900 case sizeof(uint8_t):
901 rv = badaddr_read_1(addr, &u.v1);
902 if (rv == 0 && rptr)
903 *(uint8_t *) rptr = u.v1;
904 break;
905
906 case sizeof(uint16_t):
907 rv = badaddr_read_2(addr, &u.v2);
908 if (rv == 0 && rptr)
909 *(uint16_t *) rptr = u.v2;
910 break;
911
912 case sizeof(uint32_t):
913 rv = badaddr_read_4(addr, &u.v4);
914 if (rv == 0 && rptr)
915 *(uint32_t *) rptr = u.v4;
916 break;
917
918 default:
919 panic("%s: invalid size (%zu)", __func__, size);
920 }
921
922 splx(s);
923
924 /* Return EFAULT if the address was invalid, else zero */
925 return (rv);
926 }
927