1 /* $OpenBSD: trap.c,v 1.127 2024/11/08 08:43:38 miod Exp $ */
2 /* $NetBSD: trap.c,v 1.73 2001/08/09 01:03:01 eeh Exp $ */
3
4 /*
5 * Copyright (c) 1996
6 * The President and Fellows of Harvard College. All rights reserved.
7 * Copyright (c) 1992, 1993
8 * The Regents of the University of California. All rights reserved.
9 *
10 * This software was developed by the Computer Systems Engineering group
11 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
12 * contributed to Berkeley.
13 *
14 * All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by the University of
17 * California, Lawrence Berkeley Laboratory.
18 * This product includes software developed by Harvard University.
19 *
20 * Redistribution and use in source and binary forms, with or without
21 * modification, are permitted provided that the following conditions
22 * are met:
23 * 1. Redistributions of source code must retain the above copyright
24 * notice, this list of conditions and the following disclaimer.
25 * 2. Redistributions in binary form must reproduce the above copyright
26 * notice, this list of conditions and the following disclaimer in the
27 * documentation and/or other materials provided with the distribution.
28 * 3. All advertising materials mentioning features or use of this software
29 * must display the following acknowledgement:
30 * This product includes software developed by the University of
31 * California, Berkeley and its contributors.
32 * This product includes software developed by Harvard University.
33 * 4. Neither the name of the University nor the names of its contributors
34 * may be used to endorse or promote products derived from this software
35 * without specific prior written permission.
36 *
37 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
38 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
39 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
40 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
41 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
42 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
43 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
45 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
46 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47 * SUCH DAMAGE.
48 *
49 * @(#)trap.c 8.4 (Berkeley) 9/23/93
50 */
51
52 #include <sys/param.h>
53 #include <sys/systm.h>
54 #include <sys/proc.h>
55 #include <sys/signalvar.h>
56 #include <sys/user.h>
57 #include <sys/kernel.h>
58 #include <sys/malloc.h>
59 #include <sys/resource.h>
60 #include <sys/signal.h>
61 #include <sys/wait.h>
62 #include <sys/syscall.h>
63 #include <sys/syscall_mi.h>
64 #include <sys/syslog.h>
65
66 #include <uvm/uvm_extern.h>
67
68 #include <machine/cpu.h>
69 #include <machine/ctlreg.h>
70 #include <machine/fsr.h>
71 #include <machine/trap.h>
72 #include <machine/instr.h>
73 #include <machine/pmap.h>
74
75 #ifdef DDB
76 #include <machine/db_machdep.h>
77 #else
78 #include <machine/frame.h>
79 #endif
80
81 #include <sparc64/fpu/fpu_extern.h>
82 #include <sparc64/sparc64/cache.h>
83
84 /*
85 * Initial FPU state is all registers == all 1s, everything else == all 0s.
86 * This makes every floating point register a signalling NaN, with sign bit
87 * set, no matter how it is interpreted. Appendix N of the Sparc V8 document
88 * seems to imply that we should do this, and it does make sense.
89 */
90 const struct fpstate initfpstate = {
91 { ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0,
92 ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0 }
93 };
94
95 /*
96 * There are more than 100 trap types, but most are unused.
97 *
98 * Trap type 0 is taken over as an `Asynchronous System Trap'.
99 * This is left-over Vax emulation crap that should be fixed.
100 *
101 * Traps not supported on the spitfire are marked with `*',
102 * and additions are marked with `+'
103 */
104 static const char T[] = "*trap";
105 const char *trap_type[] = {
106 /* non-user vectors */
107 "ast", /* 0 */
108 "power on reset", /* 1 */
109 "watchdog reset", /* 2 */
110 "externally initiated reset",/*3 */
111 "software initiated reset",/* 4 */
112 "RED state exception", /* 5 */
113 T, T, /* 6..7 */
114 "instruction access exception", /* 8 */
115 "*instruction MMU miss",/* 9 */
116 "instruction access error",/* 0a */
117 T, T, T, T, T, /* 0b..0f */
118 "illegal instruction", /* 10 */
119 "privileged opcode", /* 11 */
120 "*unimplemented LDD", /* 12 */
121 "*unimplemented STD", /* 13 */
122 T, T, T, T, /* 14..17 */
123 T, T, T, T, T, T, T, T, /* 18..1f */
124 "fp disabled", /* 20 */
125 "fp exception ieee 754",/* 21 */
126 "fp exception other", /* 22 */
127 "tag overflow", /* 23 */
128 "clean window", /* 24 */
129 T, T, T, /* 25..27 -- trap continues */
130 "division by zero", /* 28 */
131 "*internal processor error",/* 29 */
132 T, T, T, T, T, T, /* 2a..2f */
133 "data access exception",/* 30 */
134 "*data access MMU miss",/* 31 */
135 "data access error", /* 32 */
136 "*data access protection",/* 33 */
137 "mem address not aligned", /* 34 */
138 "LDDF mem address not aligned",/* 35 */
139 "STDF mem address not aligned",/* 36 */
140 "privileged action", /* 37 */
141 "LDQF mem address not aligned",/* 38 */
142 "STQF mem address not aligned",/* 39 */
143 T, T, T, T, T, T, /* 3a..3f */
144 "*async data error", /* 40 */
145 "level 1 int", /* 41 */
146 "level 2 int", /* 42 */
147 "level 3 int", /* 43 */
148 "level 4 int", /* 44 */
149 "level 5 int", /* 45 */
150 "level 6 int", /* 46 */
151 "level 7 int", /* 47 */
152 "level 8 int", /* 48 */
153 "level 9 int", /* 49 */
154 "level 10 int", /* 4a */
155 "level 11 int", /* 4b */
156 "level 12 int", /* 4c */
157 "level 13 int", /* 4d */
158 "level 14 int", /* 4e */
159 "level 15 int", /* 4f */
160 T, T, T, T, T, T, T, T, /* 50..57 */
161 T, T, T, T, T, T, T, T, /* 58..5f */
162 "+interrupt vector", /* 60 */
163 "+PA_watchpoint", /* 61 */
164 "+VA_watchpoint", /* 62 */
165 "+corrected ECC error", /* 63 */
166 "+fast instruction access MMU miss",/* 64 */
167 T, T, T, /* 65..67 -- trap continues */
168 "+fast data access MMU miss",/* 68 */
169 T, T, T, /* 69..6b -- trap continues */
170 "+fast data access protection",/* 6c */
171 T, T, T, /* 6d..6f -- trap continues */
172 T, T, T, T, T, T, T, T, /* 70..77 */
173 T, T, T, T, T, T, T, T, /* 78..7f */
174 "spill 0 normal", /* 80 */
175 T, T, T, /* 81..83 -- trap continues */
176 "spill 1 normal", /* 84 */
177 T, T, T, /* 85..87 -- trap continues */
178 "spill 2 normal", /* 88 */
179 T, T, T, /* 89..8b -- trap continues */
180 "spill 3 normal", /* 8c */
181 T, T, T, /* 8d..8f -- trap continues */
182 "spill 4 normal", /* 90 */
183 T, T, T, /* 91..93 -- trap continues */
184 "spill 5 normal", /* 94 */
185 T, T, T, /* 95..97 -- trap continues */
186 "spill 6 normal", /* 98 */
187 T, T, T, /* 99..9b -- trap continues */
188 "spill 7 normal", /* 9c */
189 T, T, T, /* 9c..9f -- trap continues */
190 "spill 0 other", /* a0 */
191 T, T, T, /* a1..a3 -- trap continues */
192 "spill 1 other", /* a4 */
193 T, T, T, /* a5..a7 -- trap continues */
194 "spill 2 other", /* a8 */
195 T, T, T, /* a9..ab -- trap continues */
196 "spill 3 other", /* ac */
197 T, T, T, /* ad..af -- trap continues */
198 "spill 4 other", /* b0 */
199 T, T, T, /* b1..b3 -- trap continues */
200 "spill 5 other", /* b4 */
201 T, T, T, /* b5..b7 -- trap continues */
202 "spill 6 other", /* b8 */
203 T, T, T, /* b9..bb -- trap continues */
204 "spill 7 other", /* bc */
205 T, T, T, /* bc..bf -- trap continues */
206 "fill 0 normal", /* c0 */
207 T, T, T, /* c1..c3 -- trap continues */
208 "fill 1 normal", /* c4 */
209 T, T, T, /* c5..c7 -- trap continues */
210 "fill 2 normal", /* c8 */
211 T, T, T, /* c9..cb -- trap continues */
212 "fill 3 normal", /* cc */
213 T, T, T, /* cd..cf -- trap continues */
214 "fill 4 normal", /* d0 */
215 T, T, T, /* d1..d3 -- trap continues */
216 "fill 5 normal", /* d4 */
217 T, T, T, /* d5..d7 -- trap continues */
218 "fill 6 normal", /* d8 */
219 T, T, T, /* d9..db -- trap continues */
220 "fill 7 normal", /* dc */
221 T, T, T, /* dc..df -- trap continues */
222 "fill 0 other", /* e0 */
223 T, T, T, /* e1..e3 -- trap continues */
224 "fill 1 other", /* e4 */
225 T, T, T, /* e5..e7 -- trap continues */
226 "fill 2 other", /* e8 */
227 T, T, T, /* e9..eb -- trap continues */
228 "fill 3 other", /* ec */
229 T, T, T, /* ed..ef -- trap continues */
230 "fill 4 other", /* f0 */
231 T, T, T, /* f1..f3 -- trap continues */
232 "fill 5 other", /* f4 */
233 T, T, T, /* f5..f7 -- trap continues */
234 "fill 6 other", /* f8 */
235 T, T, T, /* f9..fb -- trap continues */
236 "fill 7 other", /* fc */
237 T, T, T, /* fc..ff -- trap continues */
238
239 /* user (software trap) vectors */
240 "syscall", /* 100 */
241 "breakpoint", /* 101 */
242 "zero divide", /* 102 */
243 "flush windows", /* 103 */
244 "clean windows", /* 104 */
245 "range check", /* 105 */
246 "fix align", /* 106 */
247 "integer overflow", /* 107 */
248 "svr4 syscall", /* 108 */
249 "4.4 syscall", /* 109 */
250 "kgdb exec", /* 10a */
251 T, T, T, T, T, /* 10b..10f */
252 T, T, T, T, T, T, T, T, /* 11a..117 */
253 T, T, T, T, T, T, T, T, /* 118..11f */
254 "svr4 getcc", /* 120 */
255 "svr4 setcc", /* 121 */
256 "svr4 getpsr", /* 122 */
257 "svr4 setpsr", /* 123 */
258 "svr4 gethrtime", /* 124 */
259 "svr4 gethrvtime", /* 125 */
260 T, /* 126 */
261 "svr4 gethrestime", /* 127 */
262 T, T, T, T, T, T, T, T, /* 128..12f */
263 T, T, /* 130..131 */
264 "get condition codes", /* 132 */
265 "set condition codes", /* 133 */
266 T, T, T, T, /* 134..137 */
267 T, T, T, T, T, T, T, T, /* 138..13f */
268 T, T, T, T, T, T, T, T, /* 140..147 */
269 T, T, T, T, T, T, T, T, /* 148..14f */
270 T, T, T, T, T, T, T, T, /* 150..157 */
271 T, T, T, T, T, T, T, T, /* 158..15f */
272 T, T, T, T, /* 160..163 */
273 "SVID syscall64", /* 164 */
274 "SPARC Intl syscall64", /* 165 */
275 "OS vendor spec syscall", /* 166 */
276 "HW OEM syscall", /* 167 */
277 "ret from deferred trap", /* 168 */
278 };
279
280 #define N_TRAP_TYPES (sizeof trap_type / sizeof *trap_type)
281
282 static inline void share_fpu(struct proc *, struct trapframe *);
283
284 void trap(struct trapframe *tf, unsigned type, vaddr_t pc, long tstate);
285 void data_access_fault(struct trapframe *tf, unsigned type, vaddr_t pc,
286 vaddr_t va, vaddr_t sfva, u_long sfsr);
287 void data_access_error(struct trapframe *tf, unsigned type,
288 vaddr_t afva, u_long afsr, vaddr_t sfva, u_long sfsr);
289 void text_access_fault(struct trapframe *tf, unsigned type,
290 vaddr_t pc, u_long sfsr);
291 void text_access_error(struct trapframe *tf, unsigned type,
292 vaddr_t pc, u_long sfsr, vaddr_t afva, u_long afsr);
293 void syscall(struct trapframe *, register_t code, register_t pc);
294
295 int copyinsn(struct proc *p, vaddr_t uva, int *insn);
296
297 /*
298 * If someone stole the FPU while we were away, do not enable it
299 * on return. This is not done in userret() above as it must follow
300 * the ktrsysret() in syscall(). Actually, it is likely that the
301 * ktrsysret should occur before the call to userret.
302 *
303 * Oh, and don't touch the FPU bit if we're returning to the kernel.
304 */
305 static inline void
share_fpu(struct proc * p,struct trapframe * tf)306 share_fpu(struct proc *p, struct trapframe *tf)
307 {
308 if (!(tf->tf_tstate & TSTATE_PRIV) &&
309 (tf->tf_tstate & TSTATE_PEF) && fpproc != p)
310 tf->tf_tstate &= ~TSTATE_PEF;
311 }
312
313 /*
314 * Called from locore.s trap handling, for non-MMU-related traps.
315 * (MMU-related traps go through mem_access_fault, below.)
316 */
317 void
trap(struct trapframe * tf,unsigned type,vaddr_t pc,long tstate)318 trap(struct trapframe *tf, unsigned type, vaddr_t pc, long tstate)
319 {
320 struct proc *p;
321 struct pcb *pcb;
322 int pstate = (tstate>>TSTATE_PSTATE_SHIFT);
323 u_int64_t s;
324 int64_t n;
325 union sigval sv;
326
327 sv.sival_ptr = (void *)pc;
328
329 /* This steps the PC over the trap. */
330 #define ADVANCE (n = tf->tf_npc, tf->tf_pc = n, tf->tf_npc = n + 4)
331
332 uvmexp.traps++;
333 /*
334 * Generally, kernel traps cause a panic. Any exceptions are
335 * handled early here.
336 */
337 if (pstate & PSTATE_PRIV) {
338 #ifdef DDB
339 if (type == T_BREAKPOINT) {
340 write_all_windows();
341 if (db_ktrap(type, tf)) {
342 /* ADVANCE; */
343 return;
344 }
345 }
346 if (type == T_PA_WATCHPT || type == T_VA_WATCHPT) {
347 if (db_ktrap(type, tf)) {
348 /* DDB must turn off watchpoints or something */
349 return;
350 }
351 }
352 #endif
353 /*
354 * The kernel needs to use FPU registers for block
355 * load/store. If we trap in privileged code, save
356 * the FPU state if there is any and enable the FPU.
357 *
358 * We rely on the kernel code properly enabling the FPU
359 * in %fprs, otherwise we'll hang here trying to enable
360 * the FPU.
361 */
362 if (type == T_FPDISABLED) {
363 struct proc *newfpproc;
364
365 if (CLKF_INTR((struct clockframe *)tf) || !curproc)
366 newfpproc = &proc0;
367 else {
368 newfpproc = curproc;
369 /* force other cpus to give up this fpstate */
370 if (newfpproc->p_md.md_fpstate)
371 fpusave_proc(newfpproc, 1);
372 }
373 if (fpproc != newfpproc) {
374 s = intr_disable();
375 if (fpproc != NULL) {
376 /* someone else had it, maybe? */
377 savefpstate(fpproc->p_md.md_fpstate);
378 fpproc = NULL;
379 }
380 intr_restore(s);
381
382 /* If we have an allocated fpstate, load it */
383 if (newfpproc->p_md.md_fpstate != 0) {
384 fpproc = newfpproc;
385 loadfpstate(fpproc->p_md.md_fpstate);
386 } else
387 fpproc = NULL;
388 }
389 /* Enable the FPU */
390 tf->tf_tstate |= (PSTATE_PEF<<TSTATE_PSTATE_SHIFT);
391 return;
392 }
393 if (type != T_SPILL_N_NORM && type != T_FILL_N_NORM)
394 goto dopanic;
395 }
396 if ((p = curproc) == NULL)
397 p = &proc0;
398 pcb = &p->p_addr->u_pcb;
399 p->p_md.md_tf = tf; /* for ptrace/signals */
400 refreshcreds(p);
401
402 switch (type) {
403
404 default:
405 if (type < 0x100) {
406 dopanic:
407 panic("trap type 0x%x (%s): pc=%lx npc=%lx pstate=%b",
408 type, type < N_TRAP_TYPES ? trap_type[type] : T,
409 pc, (long)tf->tf_npc, pstate, PSTATE_BITS);
410 /* NOTREACHED */
411 }
412 trapsignal(p, SIGILL, type, ILL_ILLOPC, sv);
413 break;
414
415 case T_AST:
416 p->p_md.md_astpending = 0;
417 uvmexp.softs++;
418 mi_ast(p, curcpu()->ci_want_resched);
419 break;
420
421 case T_RWRET:
422 /*
423 * XXX Flushing the user windows here should not be
424 * necessary, but not doing so here causes corruption
425 * of user windows on sun4v. Flushing them shouldn't
426 * be much of a performance penalty since we're
427 * probably going to spill any remaining user windows
428 * anyhow.
429 */
430 write_user_windows();
431 if (rwindow_save(p) == -1) {
432 trapsignal(p, SIGILL, 0, ILL_BADSTK, sv);
433 }
434 break;
435
436 case T_ILLINST:
437 {
438 union instr ins;
439
440 if (copyinsn(p, pc, &ins.i_int) != 0) {
441 /* XXX Can this happen? */
442 trapsignal(p, SIGILL, 0, ILL_ILLOPC, sv);
443 break;
444 }
445 if (ins.i_any.i_op == IOP_mem &&
446 (ins.i_op3.i_op3 == IOP3_LDQF ||
447 ins.i_op3.i_op3 == IOP3_STQF ||
448 ins.i_op3.i_op3 == IOP3_LDQFA ||
449 ins.i_op3.i_op3 == IOP3_STQFA)) {
450 if (emul_qf(ins.i_int, p, sv, tf))
451 ADVANCE;
452 break;
453 }
454 if (ins.i_any.i_op == IOP_reg &&
455 ins.i_op3.i_op3 == IOP3_POPC &&
456 ins.i_op3.i_rs1 == 0) {
457 if (emul_popc(ins.i_int, p, sv, tf))
458 ADVANCE;
459 break;
460 }
461 trapsignal(p, SIGILL, 0, ILL_ILLOPC, sv); /* XXX code? */
462 break;
463 }
464
465 case T_INST_EXCEPT:
466 case T_TEXTFAULT:
467 case T_PRIVINST:
468 case T_PRIVACT:
469 trapsignal(p, SIGILL, 0, ILL_ILLOPC, sv); /* XXX code? */
470 break;
471
472 case T_FPDISABLED: {
473 struct fpstate *fs = p->p_md.md_fpstate;
474
475 if (fs == NULL) {
476 KERNEL_LOCK();
477 fs = malloc((sizeof *fs), M_SUBPROC, M_WAITOK);
478 *fs = initfpstate;
479 p->p_md.md_fpstate = fs;
480 KERNEL_UNLOCK();
481 }
482 if (fpproc != p) { /* we do not have it */
483 /* but maybe another CPU has it? */
484 fpusave_proc(p, 1);
485 s = intr_disable();
486 if (fpproc != NULL) /* someone else had it */
487 savefpstate(fpproc->p_md.md_fpstate);
488 loadfpstate(fs);
489 fpproc = p; /* now we do have it */
490 intr_restore(s);
491 uvmexp.fpswtch++;
492 }
493 tf->tf_tstate |= (PSTATE_PEF<<TSTATE_PSTATE_SHIFT);
494 sparc_wr(fprs, FPRS_FEF, 0);
495 break;
496 }
497
498 case T_LDQF_ALIGN:
499 case T_STQF_ALIGN:
500 {
501 union instr ins;
502
503 if (copyinsn(p, pc, &ins.i_int) != 0) {
504 /* XXX Can this happen? */
505 trapsignal(p, SIGILL, 0, ILL_ILLOPC, sv);
506 break;
507 }
508 if (ins.i_any.i_op == IOP_mem &&
509 (ins.i_op3.i_op3 == IOP3_LDQF ||
510 ins.i_op3.i_op3 == IOP3_STQF ||
511 ins.i_op3.i_op3 == IOP3_LDQFA ||
512 ins.i_op3.i_op3 == IOP3_STQFA)) {
513 if (emul_qf(ins.i_int, p, sv, tf))
514 ADVANCE;
515 } else {
516 trapsignal(p, SIGILL, 0, ILL_ILLOPC, sv);
517 }
518 break;
519 }
520
521 case T_SPILL_N_NORM:
522 case T_FILL_N_NORM:
523 /*
524 * We got an alignment trap in the spill/fill handler.
525 *
526 * XXX We really should generate a bus error here, but
527 * we could be on the interrupt stack, and dumping
528 * core from the interrupt stack is not a good idea.
529 * It causes random crashes.
530 */
531 KERNEL_LOCK();
532 sigexit(p, SIGKILL);
533 /* NOTREACHED */
534 break;
535
536 case T_ALIGN:
537 case T_LDDF_ALIGN:
538 case T_STDF_ALIGN:
539 /*
540 * If we're busy doing copyin/copyout continue
541 */
542 if (p->p_addr->u_pcb.pcb_onfault) {
543 tf->tf_pc = (vaddr_t)p->p_addr->u_pcb.pcb_onfault;
544 tf->tf_npc = tf->tf_pc + 4;
545 break;
546 }
547
548 /* XXX sv.sival_ptr should be the fault address! */
549 trapsignal(p, SIGBUS, 0, BUS_ADRALN, sv); /* XXX code? */
550 break;
551
552 case T_FP_IEEE_754:
553 case T_FP_OTHER:
554 {
555 union instr ins;
556
557 /*
558 * Clean up after a floating point exception.
559 * fpu_cleanup can (and usually does) modify the
560 * state we save here, so we must `give up' the FPU
561 * chip context. (The software and hardware states
562 * will not match once fpu_cleanup does its job, so
563 * we must not save again later.)
564 */
565 if (p != fpproc)
566 panic("fpe without being the FP user");
567 s = intr_disable();
568 savefpstate(p->p_md.md_fpstate);
569 fpproc = NULL;
570 intr_restore(s);
571 /* tf->tf_psr &= ~PSR_EF; */ /* share_fpu will do this */
572 if (type == T_FP_OTHER) {
573 /*
574 * Read the faulting instruction;
575 * we might need to emulate it.
576 */
577 (void)copyinsn(p, pc, &ins.i_int);
578 } else
579 ins.i_int = 0;
580 ADVANCE;
581 fpu_cleanup(p, p->p_md.md_fpstate, ins, sv);
582 /* fpu_cleanup posts signals if needed */
583 break;
584 }
585
586 case T_TAGOF:
587 case T_BREAKPOINT:
588 trapsignal(p, SIGTRAP, 0, TRAP_BRKPT, sv);
589 break;
590
591 case T_DIV0:
592 ADVANCE;
593 trapsignal(p, SIGFPE, 0, FPE_INTDIV, sv);
594 break;
595
596 case T_CLEANWIN:
597 uprintf("T_CLEANWIN\n"); /* XXX Should not get this */
598 ADVANCE;
599 break;
600
601 case T_FLUSHWIN:
602 /* Software window flush for v8 software */
603 write_all_windows();
604 ADVANCE;
605 break;
606
607 case T_RANGECHECK:
608 ADVANCE;
609 trapsignal(p, SIGILL, 0, ILL_ILLOPN, sv); /* XXX code? */
610 break;
611
612 case T_FIXALIGN:
613 uprintf("T_FIXALIGN\n");
614 ADVANCE;
615 trapsignal(p, SIGILL, 0, ILL_ILLOPN, sv); /* XXX code? */
616 break;
617
618 case T_INTOF:
619 uprintf("T_INTOF\n"); /* XXX */
620 ADVANCE;
621 trapsignal(p, SIGFPE, FPE_INTOVF_TRAP, FPE_INTOVF, sv);
622 break;
623 }
624
625 userret(p);
626 share_fpu(p, tf);
627 #undef ADVANCE
628 }
629
630 /*
631 * Save windows from PCB into user stack, and return 0. This is used on
632 * window overflow pseudo-traps (from locore.s, just before returning to
633 * user mode) and when ptrace or sendsig needs a consistent state.
634 * As a side effect, rwindow_save() always sets pcb_nsaved to 0.
635 *
636 * If the windows cannot be saved, pcb_nsaved is restored and we return -1.
637 */
638 int
rwindow_save(struct proc * p)639 rwindow_save(struct proc *p)
640 {
641 struct pcb *pcb = &p->p_addr->u_pcb;
642 int i;
643
644 for (i = 0; i < pcb->pcb_nsaved; i++) {
645 pcb->pcb_rw[i].rw_in[7] ^= pcb->pcb_wcookie;
646 if (copyout(&pcb->pcb_rw[i], (void *)(pcb->pcb_rwsp[i] + BIAS),
647 sizeof(struct rwindow)))
648 return (-1);
649 }
650
651 pcb->pcb_nsaved = 0;
652 return (0);
653 }
654
655 /*
656 * Kill user windows (before exec) by writing back to stack or pcb
657 * and then erasing any pcb tracks. Otherwise we might try to write
658 * the registers into the new process after the exec.
659 */
660 void
pmap_unuse_final(struct proc * p)661 pmap_unuse_final(struct proc *p)
662 {
663
664 write_user_windows();
665 p->p_addr->u_pcb.pcb_nsaved = 0;
666 }
667
668 static inline int
accesstype(unsigned int type,u_long sfsr)669 accesstype(unsigned int type, u_long sfsr)
670 {
671 /*
672 * If it was a FAST_DATA_ACCESS_MMU_MISS we have no idea what the
673 * access was since the SFSR is not set. But we should never get
674 * here from there.
675 */
676 if (type == T_FDMMU_MISS || (sfsr & SFSR_FV) == 0)
677 return PROT_READ;
678 else if (sfsr & SFSR_W)
679 return PROT_WRITE;
680 return PROT_READ;
681 }
682
683 /*
684 * This routine handles MMU generated faults.
685 */
686 void
data_access_fault(struct trapframe * tf,unsigned type,vaddr_t pc,vaddr_t addr,vaddr_t sfva,u_long sfsr)687 data_access_fault(struct trapframe *tf, unsigned type, vaddr_t pc,
688 vaddr_t addr, vaddr_t sfva, u_long sfsr)
689 {
690 struct proc *p = curproc;
691 vaddr_t va = trunc_page(addr);
692 vm_prot_t access_type = accesstype(type, sfsr);
693 vaddr_t onfault;
694 union sigval sv;
695 int signal, sicode, error;
696
697 uvmexp.traps++;
698 if (p == NULL) /* safety check */
699 p = &proc0;
700
701 if (tf->tf_tstate & TSTATE_PRIV) {
702 #ifdef DDB
703 extern char Lfsprobe[];
704 /*
705 * If this was an access that we shouldn't try to page in,
706 * resume at the fault handler without any action.
707 */
708 if (p->p_addr->u_pcb.pcb_onfault == Lfsprobe)
709 goto kfault;
710 #endif
711
712 /*
713 * During autoconfiguration, faults are never OK unless
714 * pcb_onfault is set. Once running normally we must allow
715 * exec() to cause copy-on-write faults to kernel addresses.
716 */
717 if (cold)
718 goto kfault;
719 if (!(addr & TLB_TAG_ACCESS_CTX)) {
720 /* CTXT == NUCLEUS */
721
722 error = uvm_fault(kernel_map, va, 0, access_type);
723 if (error == 0)
724 return;
725 goto kfault;
726 }
727 } else {
728 p->p_md.md_tf = tf;
729 refreshcreds(p);
730 if (!uvm_map_inentry(p, &p->p_spinentry, PROC_STACK(p),
731 "[%s]%d/%d sp=%lx inside %lx-%lx: not MAP_STACK\n",
732 uvm_map_inentry_sp, p->p_vmspace->vm_map.sserial))
733 goto out;
734 }
735
736 onfault = (vaddr_t)p->p_addr->u_pcb.pcb_onfault;
737 p->p_addr->u_pcb.pcb_onfault = NULL;
738 error = uvm_fault(&p->p_vmspace->vm_map, (vaddr_t)va, 0, access_type);
739 p->p_addr->u_pcb.pcb_onfault = (void *)onfault;
740
741 /*
742 * If this was a stack access we keep track of the maximum
743 * accessed stack size. Also, if uvm_fault gets a protection
744 * failure it is due to accessing the stack region outside
745 * the current limit and we need to reflect that as an access
746 * error.
747 */
748 if (error == 0) {
749 uvm_grow(p, va);
750 goto out;
751 }
752
753 /*
754 * Pagein failed. If doing copyin/out, return to onfault
755 * address. Any other page fault in kernel, die; if user
756 * fault, deliver SIGSEGV.
757 */
758 if (tf->tf_tstate & TSTATE_PRIV) {
759 kfault:
760 onfault = (long)p->p_addr->u_pcb.pcb_onfault;
761 if (!onfault) {
762 (void) splhigh();
763 panic("kernel data fault: pc=%lx addr=%lx",
764 pc, addr);
765 /* NOTREACHED */
766 }
767 tf->tf_pc = onfault;
768 tf->tf_npc = onfault + 4;
769 return;
770 }
771
772 if (type == T_FDMMU_MISS || (sfsr & SFSR_FV) == 0)
773 sv.sival_ptr = (void *)va;
774 else
775 sv.sival_ptr = (void *)sfva;
776
777 signal = SIGSEGV;
778 sicode = SEGV_MAPERR;
779 if (error == ENOMEM) {
780 printf("UVM: pid %d (%s), uid %d killed: out of swap\n",
781 p->p_p->ps_pid, p->p_p->ps_comm,
782 p->p_ucred ? (int)p->p_ucred->cr_uid : -1);
783 signal = SIGKILL;
784 } else if (error == EACCES)
785 sicode = SEGV_ACCERR;
786 else if (error == EIO) {
787 signal = SIGBUS;
788 sicode = BUS_OBJERR;
789 }
790 trapsignal(p, signal, access_type, sicode, sv);
791
792 out:
793 if ((tf->tf_tstate & TSTATE_PRIV) == 0) {
794 userret(p);
795 share_fpu(p, tf);
796 }
797 }
798
799 /*
800 * This routine handles deferred errors caused by the memory
801 * or I/O bus subsystems. Most of these are fatal, and even
802 * if they are not, recovery is painful. Also, the TPC and
803 * TNPC values are probably not valid if we're not doing a
804 * special PEEK/POKE code sequence.
805 */
806 void
data_access_error(struct trapframe * tf,unsigned type,vaddr_t afva,u_long afsr,vaddr_t sfva,u_long sfsr)807 data_access_error(struct trapframe *tf, unsigned type, vaddr_t afva,
808 u_long afsr, vaddr_t sfva, u_long sfsr)
809 {
810 struct proc *p = curproc;
811 u_long pc;
812 vaddr_t onfault;
813 union sigval sv;
814
815 uvmexp.traps++;
816 if (p == NULL) /* safety check */
817 p = &proc0;
818
819 /*
820 * Catch PCI config space reads.
821 */
822 if (curcpu()->ci_pci_probe) {
823 curcpu()->ci_pci_fault = 1;
824 goto out;
825 }
826
827 pc = tf->tf_pc;
828
829 onfault = (long)p->p_addr->u_pcb.pcb_onfault;
830 printf("data error type %x sfsr=%lx sfva=%lx afsr=%lx afva=%lx tf=%p\n",
831 type, sfsr, sfva, afsr, afva, tf);
832
833 if (afsr == 0 && sfsr == 0) {
834 printf("data_access_error: no fault\n");
835 goto out; /* No fault. Why were we called? */
836 }
837
838 if (tf->tf_tstate & TSTATE_PRIV) {
839 if (!onfault) {
840 (void) splhigh();
841 panic("data fault: pc=%lx addr=%lx sfsr=%lb",
842 (u_long)pc, (long)sfva, sfsr, SFSR_BITS);
843 /* NOTREACHED */
844 }
845
846 /*
847 * If this was a privileged error but not a probe, we
848 * cannot recover, so panic.
849 */
850 if (afsr & ASFR_PRIV) {
851 panic("Privileged Async Fault: AFAR %p AFSR %lx\n%lb",
852 (void *)afva, afsr, afsr, AFSR_BITS);
853 /* NOTREACHED */
854 }
855 tf->tf_pc = onfault;
856 tf->tf_npc = onfault + 4;
857 return;
858 }
859
860 sv.sival_ptr = (void *)pc;
861 trapsignal(p, SIGSEGV, PROT_READ | PROT_WRITE, SEGV_MAPERR, sv);
862
863 out:
864 if ((tf->tf_tstate & TSTATE_PRIV) == 0) {
865 userret(p);
866 share_fpu(p, tf);
867 }
868 }
869
870 /*
871 * This routine handles MMU generated faults.
872 */
873 void
text_access_fault(struct trapframe * tf,unsigned type,vaddr_t pc,u_long sfsr)874 text_access_fault(struct trapframe *tf, unsigned type, vaddr_t pc,
875 u_long sfsr)
876 {
877 struct proc *p = curproc;
878 vaddr_t va = trunc_page(pc);
879 vm_prot_t access_type = PROT_EXEC;
880 union sigval sv;
881 int signal, sicode, error;
882
883 uvmexp.traps++;
884 if (p == NULL) /* safety check */
885 panic("text_access_fault: no curproc");
886
887 sv.sival_ptr = (void *)pc;
888
889 if (tf->tf_tstate & TSTATE_PRIV) {
890 (void) splhigh();
891 panic("kernel text_access_fault: pc=%lx va=%lx", pc, va);
892 /* NOTREACHED */
893 }
894
895 p->p_md.md_tf = tf;
896 refreshcreds(p);
897 if (!uvm_map_inentry(p, &p->p_spinentry, PROC_STACK(p),
898 "[%s]%d/%d sp=%lx inside %lx-%lx: not MAP_STACK\n",
899 uvm_map_inentry_sp, p->p_vmspace->vm_map.sserial))
900 goto out;
901
902 error = uvm_fault(&p->p_vmspace->vm_map, va, 0, access_type);
903 if (error == 0)
904 goto out;
905
906 signal = SIGSEGV;
907 sicode = SEGV_MAPERR;
908 if (error == EACCES)
909 sicode = SEGV_ACCERR;
910 else if (error == EIO) {
911 signal = SIGBUS;
912 sicode = BUS_OBJERR;
913 }
914 trapsignal(p, signal, access_type, sicode, sv);
915
916 out:
917 userret(p);
918 share_fpu(p, tf);
919 }
920
921
922 /*
923 * This routine handles deferred errors caused by the memory
924 * or I/O bus subsystems. Most of these are fatal, and even
925 * if they are not, recovery is painful. Also, the TPC and
926 * TNPC values are probably not valid if we're not doing a
927 * special PEEK/POKE code sequence.
928 */
929 void
text_access_error(struct trapframe * tf,unsigned type,vaddr_t pc,u_long sfsr,vaddr_t afva,u_long afsr)930 text_access_error(struct trapframe *tf, unsigned type, vaddr_t pc,
931 u_long sfsr, vaddr_t afva, u_long afsr)
932 {
933 struct proc *p = curproc;
934 vaddr_t va = trunc_page(pc);
935 vm_prot_t access_type = PROT_EXEC;
936 union sigval sv;
937 int signal, sicode, error;
938
939 uvmexp.traps++;
940 if (p == NULL) /* safety check */
941 p = &proc0;
942
943 sv.sival_ptr = (void *)pc;
944
945 if ((afsr) != 0) {
946 printf("text_access_error: memory error...\n");
947 printf("type %d sfsr=%lx sfva=%lx afsr=%lx afva=%lx tf=%p\n",
948 type, sfsr, pc, afsr, afva, tf);
949
950 if (tf->tf_tstate & TSTATE_PRIV)
951 panic("text_access_error: kernel memory error");
952
953 /* User fault -- Berr */
954 trapsignal(p, SIGBUS, 0, BUS_ADRALN, sv);
955 }
956
957 if ((sfsr & SFSR_FV) == 0 || (sfsr & SFSR_FT) == 0)
958 goto out; /* No fault. Why were we called? */
959
960 if (tf->tf_tstate & TSTATE_PRIV) {
961 (void) splhigh();
962 panic("kernel text error: pc=%lx sfsr=%lb", pc,
963 sfsr, SFSR_BITS);
964 /* NOTREACHED */
965 }
966
967 p->p_md.md_tf = tf;
968 refreshcreds(p);
969 if (!uvm_map_inentry(p, &p->p_spinentry, PROC_STACK(p),
970 "[%s]%d/%d sp=%lx inside %lx-%lx: not MAP_STACK\n",
971 uvm_map_inentry_sp, p->p_vmspace->vm_map.sserial))
972 goto out;
973
974 error = uvm_fault(&p->p_vmspace->vm_map, va, 0, access_type);
975 if (error == 0)
976 goto out;
977
978 signal = SIGSEGV;
979 sicode = SEGV_MAPERR;
980 if (error == EACCES)
981 sicode = SEGV_ACCERR;
982 else if (error == EIO) {
983 signal = SIGBUS;
984 sicode = BUS_OBJERR;
985 }
986 trapsignal(p, signal, access_type, sicode, sv);
987
988 out:
989 if ((tf->tf_tstate & TSTATE_PRIV) == 0) {
990 userret(p);
991 share_fpu(p, tf);
992 }
993 }
994
995 /*
996 * System calls. `pc' is just a copy of tf->tf_pc.
997 *
998 * Note that the things labelled `out' registers in the trapframe were the
999 * `in' registers within the syscall trap code (because of the automatic
1000 * `save' effect of each trap). They are, however, the %o registers of the
1001 * thing that made the system call, and are named that way here.
1002 */
1003 void
syscall(struct trapframe * tf,register_t code,register_t pc)1004 syscall(struct trapframe *tf, register_t code, register_t pc)
1005 {
1006 const struct sysent *callp;
1007 struct proc *p = curproc;
1008 int error = ENOSYS, new;
1009 register_t rval[2];
1010 register_t *args;
1011
1012 if ((tf->tf_out[6] & 1) == 0)
1013 sigexit(p, SIGILL);
1014
1015 uvmexp.syscalls++;
1016 #ifdef DIAGNOSTIC
1017 if (tf->tf_tstate & TSTATE_PRIV)
1018 panic("syscall from kernel");
1019 if (curpcb != &p->p_addr->u_pcb)
1020 panic("syscall: cpcb/ppcb mismatch");
1021 if (tf != (struct trapframe *)((caddr_t)curpcb + USPACE) - 1)
1022 panic("syscall: trapframe");
1023 #endif
1024 p->p_md.md_tf = tf;
1025 new = code & SYSCALL_G2RFLAG;
1026 code &= ~SYSCALL_G2RFLAG;
1027
1028 if (code <= 0 || code >= SYS_MAXSYSCALL)
1029 goto bad;
1030 callp = sysent + code;
1031
1032 /*
1033 * The first six system call arguments are in the six %o registers.
1034 * Any arguments beyond that are in the `argument extension' area
1035 * of the user's stack frame (see <machine/frame.h>), but no system
1036 * call currently uses more than six arguments.
1037 */
1038 args = (register_t *)&tf->tf_out[0];
1039
1040 rval[0] = 0;
1041 rval[1] = 0;
1042
1043 error = mi_syscall(p, code, callp, args, rval);
1044
1045 switch (error) {
1046 vaddr_t dest;
1047 case 0:
1048 /* Note: fork() does not return here in the child */
1049 tf->tf_out[0] = rval[0];
1050 if (new) {
1051 /* jmp %g2 on success */
1052 dest = tf->tf_global[2];
1053 if (dest & 3) {
1054 error = EINVAL;
1055 goto bad;
1056 }
1057 } else {
1058 /* old system call convention: clear C on success */
1059 tf->tf_tstate &= ~(((int64_t)(ICC_C|XCC_C))<<TSTATE_CCR_SHIFT); /* success */
1060 dest = tf->tf_npc;
1061 }
1062 tf->tf_pc = dest;
1063 tf->tf_npc = dest + 4;
1064 break;
1065
1066 case ERESTART:
1067 case EJUSTRETURN:
1068 /* nothing to do */
1069 break;
1070
1071 default:
1072 bad:
1073 tf->tf_out[0] = error;
1074 tf->tf_tstate |= (((int64_t)(ICC_C|XCC_C))<<TSTATE_CCR_SHIFT); /* fail */
1075 dest = tf->tf_npc;
1076 tf->tf_pc = dest;
1077 tf->tf_npc = dest + 4;
1078 break;
1079 }
1080
1081 mi_syscall_return(p, code, error, rval);
1082 share_fpu(p, tf);
1083 }
1084
1085 /*
1086 * Process the tail end of a fork() for the child.
1087 */
1088 void
child_return(void * arg)1089 child_return(void *arg)
1090 {
1091 struct proc *p = arg;
1092 struct trapframe *tf = p->p_md.md_tf;
1093 vaddr_t dest;
1094
1095 /* Duplicate efforts of syscall(), but slightly differently */
1096 if (tf->tf_global[1] & SYSCALL_G2RFLAG) {
1097 /* jmp %g2 on success */
1098 dest = tf->tf_global[2];
1099 } else {
1100 dest = tf->tf_npc;
1101 tf->tf_tstate &= ~(((int64_t)(ICC_C|XCC_C))<<TSTATE_CCR_SHIFT);
1102 }
1103
1104 /* Skip trap instruction. */
1105 tf->tf_pc = dest;
1106 tf->tf_npc = dest + 4;
1107
1108 /*
1109 * Return values in the frame set by cpu_fork().
1110 */
1111 tf->tf_out[0] = 0;
1112
1113 KERNEL_UNLOCK();
1114
1115 mi_child_return(p);
1116 }
1117
1118 int
copyinsn(struct proc * p,vaddr_t uva,int * insn)1119 copyinsn(struct proc *p, vaddr_t uva, int *insn)
1120 {
1121 struct vm_map *map = &p->p_vmspace->vm_map;
1122 int error = 0;
1123
1124 if (__predict_false((uva & 3) != 0))
1125 return EFAULT;
1126
1127 do {
1128 if (pmap_copyinsn(map->pmap, uva, (uint32_t *)insn) == 0)
1129 break;
1130 error = uvm_fault(map, trunc_page(uva), 0, PROT_EXEC);
1131 } while (error == 0);
1132
1133 return error;
1134 }
1135