xref: /openbsd/sys/arch/sparc64/sparc64/trap.c (revision 0e99c760)
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