xref: /freebsd-12.1/sys/mips/mips/trap.c (revision 0e365aec)
1 /*	$OpenBSD: trap.c,v 1.19 1998/09/30 12:40:41 pefo Exp $	*/
2 /* tracked to 1.23 */
3 /*-
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  * Copyright (c) 1988 University of Utah.
7  * Copyright (c) 1992, 1993
8  *	The Regents of the University of California.  All rights reserved.
9  *
10  * This code is derived from software contributed to Berkeley by
11  * the Systems Programming Group of the University of Utah Computer
12  * Science Department and Ralph Campbell.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions
16  * are met:
17  * 1. Redistributions of source code must retain the above copyright
18  *    notice, this list of conditions and the following disclaimer.
19  * 2. Redistributions in binary form must reproduce the above copyright
20  *    notice, this list of conditions and the following disclaimer in the
21  *    documentation and/or other materials provided with the distribution.
22  * 3. Neither the name of the University nor the names of its contributors
23  *    may be used to endorse or promote products derived from this software
24  *    without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36  * SUCH DAMAGE.
37  *
38  * from: Utah Hdr: trap.c 1.32 91/04/06
39  *
40  *	from: @(#)trap.c	8.5 (Berkeley) 1/11/94
41  *	JNPR: trap.c,v 1.13.2.2 2007/08/29 10:03:49 girish
42  */
43 #include <sys/cdefs.h>
44 __FBSDID("$FreeBSD$");
45 
46 #include "opt_ddb.h"
47 #include "opt_ktrace.h"
48 
49 #include <sys/param.h>
50 #include <sys/systm.h>
51 #include <sys/sysent.h>
52 #include <sys/proc.h>
53 #include <sys/kernel.h>
54 #include <sys/signalvar.h>
55 #include <sys/syscall.h>
56 #include <sys/lock.h>
57 #include <vm/vm.h>
58 #include <vm/vm_extern.h>
59 #include <vm/vm_kern.h>
60 #include <vm/vm_page.h>
61 #include <vm/vm_map.h>
62 #include <vm/vm_param.h>
63 #include <sys/vmmeter.h>
64 #include <sys/ptrace.h>
65 #include <sys/user.h>
66 #include <sys/buf.h>
67 #include <sys/vnode.h>
68 #include <sys/pioctl.h>
69 #include <sys/sysctl.h>
70 #include <sys/syslog.h>
71 #include <sys/bus.h>
72 #ifdef KTRACE
73 #include <sys/ktrace.h>
74 #endif
75 #include <net/netisr.h>
76 
77 #include <machine/trap.h>
78 #include <machine/cpu.h>
79 #include <machine/cpuinfo.h>
80 #include <machine/pte.h>
81 #include <machine/pmap.h>
82 #include <machine/md_var.h>
83 #include <machine/mips_opcode.h>
84 #include <machine/frame.h>
85 #include <machine/regnum.h>
86 #include <machine/tls.h>
87 
88 #ifdef DDB
89 #include <machine/db_machdep.h>
90 #include <ddb/db_sym.h>
91 #include <ddb/ddb.h>
92 #include <sys/kdb.h>
93 #endif
94 
95 #ifdef KDTRACE_HOOKS
96 #include <sys/dtrace_bsd.h>
97 #endif
98 
99 #ifdef TRAP_DEBUG
100 int trap_debug = 0;
101 SYSCTL_INT(_machdep, OID_AUTO, trap_debug, CTLFLAG_RW,
102     &trap_debug, 0, "Debug information on all traps");
103 #endif
104 
105 #define	lbu_macro(data, addr)						\
106 	__asm __volatile ("lbu %0, 0x0(%1)"				\
107 			: "=r" (data)	/* outputs */			\
108 			: "r" (addr));	/* inputs */
109 
110 #define	lb_macro(data, addr)						\
111 	__asm __volatile ("lb %0, 0x0(%1)"				\
112 			: "=r" (data)	/* outputs */			\
113 			: "r" (addr));	/* inputs */
114 
115 #define	lwl_macro(data, addr)						\
116 	__asm __volatile ("lwl %0, 0x0(%1)"				\
117 			: "=r" (data)	/* outputs */			\
118 			: "r" (addr));	/* inputs */
119 
120 #define	lwr_macro(data, addr)						\
121 	__asm __volatile ("lwr %0, 0x0(%1)"				\
122 			: "=r" (data)	/* outputs */			\
123 			: "r" (addr));	/* inputs */
124 
125 #define	ldl_macro(data, addr)						\
126 	__asm __volatile ("ldl %0, 0x0(%1)"				\
127 			: "=r" (data)	/* outputs */			\
128 			: "r" (addr));	/* inputs */
129 
130 #define	ldr_macro(data, addr)						\
131 	__asm __volatile ("ldr %0, 0x0(%1)"				\
132 			: "=r" (data)	/* outputs */			\
133 			: "r" (addr));	/* inputs */
134 
135 #define	sb_macro(data, addr)						\
136 	__asm __volatile ("sb %0, 0x0(%1)"				\
137 			:				/* outputs */	\
138 			: "r" (data), "r" (addr));	/* inputs */
139 
140 #define	swl_macro(data, addr)						\
141 	__asm __volatile ("swl %0, 0x0(%1)"				\
142 			: 				/* outputs */	\
143 			: "r" (data), "r" (addr));	/* inputs */
144 
145 #define	swr_macro(data, addr)						\
146 	__asm __volatile ("swr %0, 0x0(%1)"				\
147 			: 				/* outputs */	\
148 			: "r" (data), "r" (addr));	/* inputs */
149 
150 #define	sdl_macro(data, addr)						\
151 	__asm __volatile ("sdl %0, 0x0(%1)"				\
152 			: 				/* outputs */	\
153 			: "r" (data), "r" (addr));	/* inputs */
154 
155 #define	sdr_macro(data, addr)						\
156 	__asm __volatile ("sdr %0, 0x0(%1)"				\
157 			:				/* outputs */	\
158 			: "r" (data), "r" (addr));	/* inputs */
159 
160 static void log_illegal_instruction(const char *, struct trapframe *);
161 static void log_bad_page_fault(char *, struct trapframe *, int);
162 static void log_frame_dump(struct trapframe *frame);
163 static void get_mapping_info(vm_offset_t, pd_entry_t **, pt_entry_t **);
164 
165 int (*dtrace_invop_jump_addr)(struct trapframe *);
166 
167 #ifdef TRAP_DEBUG
168 static void trap_frame_dump(struct trapframe *frame);
169 #endif
170 
171 void (*machExceptionTable[]) (void)= {
172 /*
173  * The kernel exception handlers.
174  */
175 	MipsKernIntr,		/* external interrupt */
176 	MipsKernGenException,	/* TLB modification */
177 	MipsTLBInvalidException,/* TLB miss (load or instr. fetch) */
178 	MipsTLBInvalidException,/* TLB miss (store) */
179 	MipsKernGenException,	/* address error (load or I-fetch) */
180 	MipsKernGenException,	/* address error (store) */
181 	MipsKernGenException,	/* bus error (I-fetch) */
182 	MipsKernGenException,	/* bus error (load or store) */
183 	MipsKernGenException,	/* system call */
184 	MipsKernGenException,	/* breakpoint */
185 	MipsKernGenException,	/* reserved instruction */
186 	MipsKernGenException,	/* coprocessor unusable */
187 	MipsKernGenException,	/* arithmetic overflow */
188 	MipsKernGenException,	/* trap exception */
189 	MipsKernGenException,	/* virtual coherence exception inst */
190 	MipsKernGenException,	/* floating point exception */
191 	MipsKernGenException,	/* reserved */
192 	MipsKernGenException,	/* reserved */
193 	MipsKernGenException,	/* reserved */
194 	MipsKernGenException,	/* reserved */
195 	MipsKernGenException,	/* reserved */
196 	MipsKernGenException,	/* reserved */
197 	MipsKernGenException,	/* reserved */
198 	MipsKernGenException,	/* watch exception */
199 	MipsKernGenException,	/* reserved */
200 	MipsKernGenException,	/* reserved */
201 	MipsKernGenException,	/* reserved */
202 	MipsKernGenException,	/* reserved */
203 	MipsKernGenException,	/* reserved */
204 	MipsKernGenException,	/* reserved */
205 	MipsKernGenException,	/* reserved */
206 	MipsKernGenException,	/* virtual coherence exception data */
207 /*
208  * The user exception handlers.
209  */
210 	MipsUserIntr,		/* 0 */
211 	MipsUserGenException,	/* 1 */
212 	MipsTLBInvalidException,/* 2 */
213 	MipsTLBInvalidException,/* 3 */
214 	MipsUserGenException,	/* 4 */
215 	MipsUserGenException,	/* 5 */
216 	MipsUserGenException,	/* 6 */
217 	MipsUserGenException,	/* 7 */
218 	MipsUserGenException,	/* 8 */
219 	MipsUserGenException,	/* 9 */
220 	MipsUserGenException,	/* 10 */
221 	MipsUserGenException,	/* 11 */
222 	MipsUserGenException,	/* 12 */
223 	MipsUserGenException,	/* 13 */
224 	MipsUserGenException,	/* 14 */
225 	MipsUserGenException,	/* 15 */
226 	MipsUserGenException,	/* 16 */
227 	MipsUserGenException,	/* 17 */
228 	MipsUserGenException,	/* 18 */
229 	MipsUserGenException,	/* 19 */
230 	MipsUserGenException,	/* 20 */
231 	MipsUserGenException,	/* 21 */
232 	MipsUserGenException,	/* 22 */
233 	MipsUserGenException,	/* 23 */
234 	MipsUserGenException,	/* 24 */
235 	MipsUserGenException,	/* 25 */
236 	MipsUserGenException,	/* 26 */
237 	MipsUserGenException,	/* 27 */
238 	MipsUserGenException,	/* 28 */
239 	MipsUserGenException,	/* 29 */
240 	MipsUserGenException,	/* 20 */
241 	MipsUserGenException,	/* 31 */
242 };
243 
244 char *trap_type[] = {
245 	"external interrupt",
246 	"TLB modification",
247 	"TLB miss (load or instr. fetch)",
248 	"TLB miss (store)",
249 	"address error (load or I-fetch)",
250 	"address error (store)",
251 	"bus error (I-fetch)",
252 	"bus error (load or store)",
253 	"system call",
254 	"breakpoint",
255 	"reserved instruction",
256 	"coprocessor unusable",
257 	"arithmetic overflow",
258 	"trap",
259 	"virtual coherency instruction",
260 	"floating point",
261 	"reserved 16",
262 	"reserved 17",
263 	"reserved 18",
264 	"reserved 19",
265 	"reserved 20",
266 	"reserved 21",
267 	"reserved 22",
268 	"watch",
269 	"reserved 24",
270 	"reserved 25",
271 	"reserved 26",
272 	"reserved 27",
273 	"reserved 28",
274 	"reserved 29",
275 	"reserved 30",
276 	"virtual coherency data",
277 };
278 
279 #if !defined(SMP) && (defined(DDB) || defined(DEBUG))
280 struct trapdebug trapdebug[TRAPSIZE], *trp = trapdebug;
281 #endif
282 
283 #define	KERNLAND(x)	((vm_offset_t)(x) >= VM_MIN_KERNEL_ADDRESS && (vm_offset_t)(x) < VM_MAX_KERNEL_ADDRESS)
284 #define	DELAYBRANCH(x)	((x) & MIPS_CR_BR_DELAY)
285 
286 /*
287  * MIPS load/store access type
288  */
289 enum {
290 	MIPS_LHU_ACCESS = 1,
291 	MIPS_LH_ACCESS,
292 	MIPS_LWU_ACCESS,
293 	MIPS_LW_ACCESS,
294 	MIPS_LD_ACCESS,
295 	MIPS_SH_ACCESS,
296 	MIPS_SW_ACCESS,
297 	MIPS_SD_ACCESS
298 };
299 
300 char *access_name[] = {
301 	"Load Halfword Unsigned",
302 	"Load Halfword",
303 	"Load Word Unsigned",
304 	"Load Word",
305 	"Load Doubleword",
306 	"Store Halfword",
307 	"Store Word",
308 	"Store Doubleword"
309 };
310 
311 #ifdef	CPU_CNMIPS
312 #include <machine/octeon_cop2.h>
313 #endif
314 
315 static int allow_unaligned_acc = 1;
316 
317 SYSCTL_INT(_vm, OID_AUTO, allow_unaligned_acc, CTLFLAG_RW,
318     &allow_unaligned_acc, 0, "Allow unaligned accesses");
319 
320 /*
321  * FP emulation is assumed to work on O32, but the code is outdated and crufty
322  * enough that it's a more sensible default to have it disabled when using
323  * other ABIs.  At the very least, it needs a lot of help in using
324  * type-semantic ABI-oblivious macros for everything it does.
325  */
326 #if defined(__mips_o32)
327 static int emulate_fp = 1;
328 #else
329 static int emulate_fp = 0;
330 #endif
331 SYSCTL_INT(_machdep, OID_AUTO, emulate_fp, CTLFLAG_RW,
332     &emulate_fp, 0, "Emulate unimplemented FPU instructions");
333 
334 static int emulate_unaligned_access(struct trapframe *frame, int mode);
335 
336 extern void fswintrberr(void); /* XXX */
337 
338 int
cpu_fetch_syscall_args(struct thread * td)339 cpu_fetch_syscall_args(struct thread *td)
340 {
341 	struct trapframe *locr0;
342 	struct sysentvec *se;
343 	struct syscall_args *sa;
344 	int error, nsaved;
345 
346 	locr0 = td->td_frame;
347 	sa = &td->td_sa;
348 
349 	bzero(sa->args, sizeof(sa->args));
350 
351 	/* compute next PC after syscall instruction */
352 	td->td_pcb->pcb_tpc = sa->trapframe->pc; /* Remember if restart */
353 	if (DELAYBRANCH(sa->trapframe->cause))	 /* Check BD bit */
354 		locr0->pc = MipsEmulateBranch(locr0, sa->trapframe->pc, 0, 0);
355 	else
356 		locr0->pc += sizeof(int);
357 	sa->code = locr0->v0;
358 
359 	switch (sa->code) {
360 	case SYS___syscall:
361 	case SYS_syscall:
362 		/*
363 		 * This is an indirect syscall, in which the code is the first argument.
364 		 */
365 #if (!defined(__mips_n32) && !defined(__mips_n64)) || defined(COMPAT_FREEBSD32)
366 		if (sa->code == SYS___syscall && SV_PROC_FLAG(td->td_proc, SV_ILP32)) {
367 			/*
368 			 * Like syscall, but code is a quad, so as to maintain alignment
369 			 * for the rest of the arguments.
370 			 */
371 			if (_QUAD_LOWWORD == 0)
372 				sa->code = locr0->a0;
373 			else
374 				sa->code = locr0->a1;
375 			sa->args[0] = locr0->a2;
376 			sa->args[1] = locr0->a3;
377 			nsaved = 2;
378 			break;
379 		}
380 #endif
381 		/*
382 		 * This is either not a quad syscall, or is a quad syscall with a
383 		 * new ABI in which quads fit in a single register.
384 		 */
385 		sa->code = locr0->a0;
386 		sa->args[0] = locr0->a1;
387 		sa->args[1] = locr0->a2;
388 		sa->args[2] = locr0->a3;
389 		nsaved = 3;
390 #if defined(__mips_n32) || defined(__mips_n64)
391 #ifdef COMPAT_FREEBSD32
392 		if (!SV_PROC_FLAG(td->td_proc, SV_ILP32)) {
393 #endif
394 			/*
395 			 * Non-o32 ABIs support more arguments in registers.
396 			 */
397 			sa->args[3] = locr0->a4;
398 			sa->args[4] = locr0->a5;
399 			sa->args[5] = locr0->a6;
400 			sa->args[6] = locr0->a7;
401 			nsaved += 4;
402 #ifdef COMPAT_FREEBSD32
403 		}
404 #endif
405 #endif
406 		break;
407 	default:
408 		/*
409 		 * A direct syscall, arguments are just parameters to the syscall.
410 		 */
411 		sa->args[0] = locr0->a0;
412 		sa->args[1] = locr0->a1;
413 		sa->args[2] = locr0->a2;
414 		sa->args[3] = locr0->a3;
415 		nsaved = 4;
416 #if defined (__mips_n32) || defined(__mips_n64)
417 #ifdef COMPAT_FREEBSD32
418 		if (!SV_PROC_FLAG(td->td_proc, SV_ILP32)) {
419 #endif
420 			/*
421 			 * Non-o32 ABIs support more arguments in registers.
422 			 */
423 			sa->args[4] = locr0->a4;
424 			sa->args[5] = locr0->a5;
425 			sa->args[6] = locr0->a6;
426 			sa->args[7] = locr0->a7;
427 			nsaved += 4;
428 #ifdef COMPAT_FREEBSD32
429 		}
430 #endif
431 #endif
432 		break;
433 	}
434 
435 #ifdef TRAP_DEBUG
436 	if (trap_debug)
437 		printf("SYSCALL #%d pid:%u\n", sa->code, td->td_proc->p_pid);
438 #endif
439 
440 	se = td->td_proc->p_sysent;
441 	/*
442 	 * XXX
443 	 * Shouldn't this go before switching on the code?
444 	 */
445 	if (se->sv_mask)
446 		sa->code &= se->sv_mask;
447 
448 	if (sa->code >= se->sv_size)
449 		sa->callp = &se->sv_table[0];
450 	else
451 		sa->callp = &se->sv_table[sa->code];
452 
453 	sa->narg = sa->callp->sy_narg;
454 
455 	if (sa->narg > nsaved) {
456 #if defined(__mips_n32) || defined(__mips_n64)
457 		/*
458 		 * XXX
459 		 * Is this right for new ABIs?  I think the 4 there
460 		 * should be 8, size there are 8 registers to skip,
461 		 * not 4, but I'm not certain.
462 		 */
463 #ifdef COMPAT_FREEBSD32
464 		if (!SV_PROC_FLAG(td->td_proc, SV_ILP32))
465 #endif
466 			printf("SYSCALL #%u pid:%u, narg (%u) > nsaved (%u).\n",
467 			    sa->code, td->td_proc->p_pid, sa->narg, nsaved);
468 #endif
469 #if (defined(__mips_n32) || defined(__mips_n64)) && defined(COMPAT_FREEBSD32)
470 		if (SV_PROC_FLAG(td->td_proc, SV_ILP32)) {
471 			unsigned i;
472 			int32_t arg;
473 
474 			error = 0; /* XXX GCC is awful.  */
475 			for (i = nsaved; i < sa->narg; i++) {
476 				error = copyin((caddr_t)(intptr_t)(locr0->sp +
477 				    (4 + (i - nsaved)) * sizeof(int32_t)),
478 				    (caddr_t)&arg, sizeof arg);
479 				if (error != 0)
480 					break;
481 				sa->args[i] = arg;
482 			}
483 		} else
484 #endif
485 		error = copyin((caddr_t)(intptr_t)(locr0->sp +
486 		    4 * sizeof(register_t)), (caddr_t)&sa->args[nsaved],
487 		   (u_int)(sa->narg - nsaved) * sizeof(register_t));
488 		if (error != 0) {
489 			locr0->v0 = error;
490 			locr0->a3 = 1;
491 		}
492 	} else
493 		error = 0;
494 
495 	if (error == 0) {
496 		td->td_retval[0] = 0;
497 		td->td_retval[1] = locr0->v1;
498 	}
499 
500 	return (error);
501 }
502 
503 #undef __FBSDID
504 #define __FBSDID(x)
505 #include "../../kern/subr_syscall.c"
506 
507 /*
508  * Handle an exception.
509  * Called from MipsKernGenException() or MipsUserGenException()
510  * when a processor trap occurs.
511  * In the case of a kernel trap, we return the pc where to resume if
512  * p->p_addr->u_pcb.pcb_onfault is set, otherwise, return old pc.
513  */
514 register_t
trap(struct trapframe * trapframe)515 trap(struct trapframe *trapframe)
516 {
517 	int type, usermode;
518 	int i = 0;
519 	unsigned ucode = 0;
520 	struct thread *td = curthread;
521 	struct proc *p = curproc;
522 	vm_prot_t ftype;
523 	pmap_t pmap;
524 	int access_type;
525 	ksiginfo_t ksi;
526 	char *msg = NULL;
527 	intptr_t addr = 0;
528 	register_t pc;
529 	int cop, error;
530 	register_t *frame_regs;
531 
532 	trapdebug_enter(trapframe, 0);
533 #ifdef KDB
534 	if (kdb_active) {
535 		kdb_reenter();
536 		return (0);
537 	}
538 #endif
539 	type = (trapframe->cause & MIPS_CR_EXC_CODE) >> MIPS_CR_EXC_CODE_SHIFT;
540 	if (TRAPF_USERMODE(trapframe)) {
541 		type |= T_USER;
542 		usermode = 1;
543 	} else {
544 		usermode = 0;
545 	}
546 
547 	/*
548 	 * Enable hardware interrupts if they were on before the trap. If it
549 	 * was off disable all so we don't accidently enable it when doing a
550 	 * return to userland.
551 	 */
552 	if (trapframe->sr & MIPS_SR_INT_IE) {
553 		set_intr_mask(trapframe->sr & MIPS_SR_INT_MASK);
554 		intr_enable();
555 	} else {
556 		intr_disable();
557 	}
558 
559 #ifdef TRAP_DEBUG
560 	if (trap_debug) {
561 		static vm_offset_t last_badvaddr = 0;
562 		static vm_offset_t this_badvaddr = 0;
563 		static int count = 0;
564 		u_int32_t pid;
565 
566 		printf("trap type %x (%s - ", type,
567 		    trap_type[type & (~T_USER)]);
568 
569 		if (type & T_USER)
570 			printf("user mode)\n");
571 		else
572 			printf("kernel mode)\n");
573 
574 #ifdef SMP
575 		printf("cpuid = %d\n", PCPU_GET(cpuid));
576 #endif
577 		pid = mips_rd_entryhi() & TLBHI_ASID_MASK;
578 		printf("badaddr = %#jx, pc = %#jx, ra = %#jx, sp = %#jx, sr = %jx, pid = %d, ASID = %u\n",
579 		    (intmax_t)trapframe->badvaddr, (intmax_t)trapframe->pc, (intmax_t)trapframe->ra,
580 		    (intmax_t)trapframe->sp, (intmax_t)trapframe->sr,
581 		    (curproc ? curproc->p_pid : -1), pid);
582 
583 		switch (type & ~T_USER) {
584 		case T_TLB_MOD:
585 		case T_TLB_LD_MISS:
586 		case T_TLB_ST_MISS:
587 		case T_ADDR_ERR_LD:
588 		case T_ADDR_ERR_ST:
589 			this_badvaddr = trapframe->badvaddr;
590 			break;
591 		case T_SYSCALL:
592 			this_badvaddr = trapframe->ra;
593 			break;
594 		default:
595 			this_badvaddr = trapframe->pc;
596 			break;
597 		}
598 		if ((last_badvaddr == this_badvaddr) &&
599 		    ((type & ~T_USER) != T_SYSCALL) &&
600 		    ((type & ~T_USER) != T_COP_UNUSABLE)) {
601 			if (++count == 3) {
602 				trap_frame_dump(trapframe);
603 				panic("too many faults at %p\n", (void *)last_badvaddr);
604 			}
605 		} else {
606 			last_badvaddr = this_badvaddr;
607 			count = 0;
608 		}
609 	}
610 #endif
611 
612 #ifdef KDTRACE_HOOKS
613 	/*
614 	 * A trap can occur while DTrace executes a probe. Before
615 	 * executing the probe, DTrace blocks re-scheduling and sets
616 	 * a flag in its per-cpu flags to indicate that it doesn't
617 	 * want to fault. On returning from the probe, the no-fault
618 	 * flag is cleared and finally re-scheduling is enabled.
619 	 *
620 	 * If the DTrace kernel module has registered a trap handler,
621 	 * call it and if it returns non-zero, assume that it has
622 	 * handled the trap and modified the trap frame so that this
623 	 * function can return normally.
624 	 */
625 	/*
626 	 * XXXDTRACE: add pid probe handler here (if ever)
627 	 */
628 	if (!usermode) {
629 		if (dtrace_trap_func != NULL &&
630 		    (*dtrace_trap_func)(trapframe, type) != 0)
631 			return (trapframe->pc);
632 	}
633 #endif
634 
635 	switch (type) {
636 	case T_MCHECK:
637 #ifdef DDB
638 		kdb_trap(type, 0, trapframe);
639 #endif
640 		panic("MCHECK\n");
641 		break;
642 	case T_TLB_MOD:
643 		/* check for kernel address */
644 		if (KERNLAND(trapframe->badvaddr)) {
645 			if (pmap_emulate_modified(kernel_pmap,
646 			    trapframe->badvaddr) != 0) {
647 				ftype = VM_PROT_WRITE;
648 				goto kernel_fault;
649 			}
650 			return (trapframe->pc);
651 		}
652 		/* FALLTHROUGH */
653 
654 	case T_TLB_MOD + T_USER:
655 		pmap = &p->p_vmspace->vm_pmap;
656 		if (pmap_emulate_modified(pmap, trapframe->badvaddr) != 0) {
657 			ftype = VM_PROT_WRITE;
658 			goto dofault;
659 		}
660 		if (!usermode)
661 			return (trapframe->pc);
662 		goto out;
663 
664 	case T_TLB_LD_MISS:
665 	case T_TLB_ST_MISS:
666 		ftype = (type == T_TLB_ST_MISS) ? VM_PROT_WRITE : VM_PROT_READ;
667 		/* check for kernel address */
668 		if (KERNLAND(trapframe->badvaddr)) {
669 			vm_offset_t va;
670 			int rv;
671 
672 	kernel_fault:
673 			va = trunc_page((vm_offset_t)trapframe->badvaddr);
674 			rv = vm_fault(kernel_map, va, ftype, VM_FAULT_NORMAL);
675 			if (rv == KERN_SUCCESS)
676 				return (trapframe->pc);
677 			if (td->td_pcb->pcb_onfault != NULL) {
678 				pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault;
679 				td->td_pcb->pcb_onfault = NULL;
680 				return (pc);
681 			}
682 			goto err;
683 		}
684 
685 		/*
686 		 * It is an error for the kernel to access user space except
687 		 * through the copyin/copyout routines.
688 		 */
689 		if (td->td_pcb->pcb_onfault == NULL)
690 			goto err;
691 
692 		goto dofault;
693 
694 	case T_TLB_LD_MISS + T_USER:
695 		ftype = VM_PROT_READ;
696 		goto dofault;
697 
698 	case T_TLB_ST_MISS + T_USER:
699 		ftype = VM_PROT_WRITE;
700 dofault:
701 		{
702 			vm_offset_t va;
703 			struct vmspace *vm;
704 			vm_map_t map;
705 			int rv = 0;
706 
707 			vm = p->p_vmspace;
708 			map = &vm->vm_map;
709 			va = trunc_page((vm_offset_t)trapframe->badvaddr);
710 			if (KERNLAND(trapframe->badvaddr)) {
711 				/*
712 				 * Don't allow user-mode faults in kernel
713 				 * address space.
714 				 */
715 				goto nogo;
716 			}
717 
718 			rv = vm_fault(map, va, ftype, VM_FAULT_NORMAL);
719 			/*
720 			 * XXXDTRACE: add dtrace_doubletrap_func here?
721 			 */
722 #ifdef VMFAULT_TRACE
723 			printf("vm_fault(%p (pmap %p), %p (%p), %x, %d) -> %x at pc %p\n",
724 			    map, &vm->vm_pmap, (void *)va, (void *)(intptr_t)trapframe->badvaddr,
725 			    ftype, VM_FAULT_NORMAL, rv, (void *)(intptr_t)trapframe->pc);
726 #endif
727 
728 			if (rv == KERN_SUCCESS) {
729 				if (!usermode) {
730 					return (trapframe->pc);
731 				}
732 				goto out;
733 			}
734 	nogo:
735 			if (!usermode) {
736 				if (td->td_pcb->pcb_onfault != NULL) {
737 					pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault;
738 					td->td_pcb->pcb_onfault = NULL;
739 					return (pc);
740 				}
741 				goto err;
742 			}
743 			i = SIGSEGV;
744 			if (rv == KERN_PROTECTION_FAILURE)
745 				ucode = SEGV_ACCERR;
746 			else
747 				ucode = SEGV_MAPERR;
748 			addr = trapframe->pc;
749 
750 			msg = "BAD_PAGE_FAULT";
751 			log_bad_page_fault(msg, trapframe, type);
752 
753 			break;
754 		}
755 
756 	case T_ADDR_ERR_LD + T_USER:	/* misaligned or kseg access */
757 	case T_ADDR_ERR_ST + T_USER:	/* misaligned or kseg access */
758 		if (trapframe->badvaddr < 0 ||
759 		    trapframe->badvaddr >= VM_MAXUSER_ADDRESS) {
760 			msg = "ADDRESS_SPACE_ERR";
761 		} else if (allow_unaligned_acc) {
762 			int mode;
763 
764 			if (type == (T_ADDR_ERR_LD + T_USER))
765 				mode = VM_PROT_READ;
766 			else
767 				mode = VM_PROT_WRITE;
768 
769 			access_type = emulate_unaligned_access(trapframe, mode);
770 			if (access_type != 0)
771 				goto out;
772 			msg = "ALIGNMENT_FIX_ERR";
773 		} else {
774 			msg = "ADDRESS_ERR";
775 		}
776 
777 		/* FALL THROUGH */
778 
779 	case T_BUS_ERR_IFETCH + T_USER:	/* BERR asserted to cpu */
780 	case T_BUS_ERR_LD_ST + T_USER:	/* BERR asserted to cpu */
781 		ucode = 0;	/* XXX should be VM_PROT_something */
782 		i = SIGBUS;
783 		addr = trapframe->pc;
784 		if (!msg)
785 			msg = "BUS_ERR";
786 		log_bad_page_fault(msg, trapframe, type);
787 		break;
788 
789 	case T_SYSCALL + T_USER:
790 		{
791 			int error;
792 
793 			td->td_sa.trapframe = trapframe;
794 			error = syscallenter(td);
795 
796 #if !defined(SMP) && (defined(DDB) || defined(DEBUG))
797 			if (trp == trapdebug)
798 				trapdebug[TRAPSIZE - 1].code = td->td_sa.code;
799 			else
800 				trp[-1].code = td->td_sa.code;
801 #endif
802 			trapdebug_enter(td->td_frame, -td->td_sa.code);
803 
804 			/*
805 			 * The sync'ing of I & D caches for SYS_ptrace() is
806 			 * done by procfs_domem() through procfs_rwmem()
807 			 * instead of being done here under a special check
808 			 * for SYS_ptrace().
809 			 */
810 			syscallret(td, error);
811 			return (trapframe->pc);
812 		}
813 
814 #if defined(KDTRACE_HOOKS) || defined(DDB)
815 	case T_BREAK:
816 #ifdef KDTRACE_HOOKS
817 		if (!usermode && dtrace_invop_jump_addr != 0) {
818 			dtrace_invop_jump_addr(trapframe);
819 			return (trapframe->pc);
820 		}
821 #endif
822 #ifdef DDB
823 		kdb_trap(type, 0, trapframe);
824 		return (trapframe->pc);
825 #endif
826 #endif
827 
828 	case T_BREAK + T_USER:
829 		{
830 			intptr_t va;
831 			uint32_t instr;
832 
833 			i = SIGTRAP;
834 			ucode = TRAP_BRKPT;
835 			addr = trapframe->pc;
836 
837 			/* compute address of break instruction */
838 			va = trapframe->pc;
839 			if (DELAYBRANCH(trapframe->cause))
840 				va += sizeof(int);
841 
842 			if (td->td_md.md_ss_addr != va)
843 				break;
844 
845 			/* read break instruction */
846 			instr = fuword32((caddr_t)va);
847 
848 			if (instr != MIPS_BREAK_SSTEP)
849 				break;
850 
851 			CTR3(KTR_PTRACE,
852 			    "trap: tid %d, single step at %#lx: %#08x",
853 			    td->td_tid, va, instr);
854 			PROC_LOCK(p);
855 			_PHOLD(p);
856 			error = ptrace_clear_single_step(td);
857 			_PRELE(p);
858 			PROC_UNLOCK(p);
859 			if (error == 0)
860 				ucode = TRAP_TRACE;
861 			break;
862 		}
863 
864 	case T_IWATCH + T_USER:
865 	case T_DWATCH + T_USER:
866 		{
867 			intptr_t va;
868 
869 			/* compute address of trapped instruction */
870 			va = trapframe->pc;
871 			if (DELAYBRANCH(trapframe->cause))
872 				va += sizeof(int);
873 			printf("watch exception @ %p\n", (void *)va);
874 			i = SIGTRAP;
875 			ucode = TRAP_BRKPT;
876 			addr = va;
877 			break;
878 		}
879 
880 	case T_TRAP + T_USER:
881 		{
882 			intptr_t va;
883 			struct trapframe *locr0 = td->td_frame;
884 
885 			/* compute address of trap instruction */
886 			va = trapframe->pc;
887 			if (DELAYBRANCH(trapframe->cause))
888 				va += sizeof(int);
889 
890 			if (DELAYBRANCH(trapframe->cause)) {	/* Check BD bit */
891 				locr0->pc = MipsEmulateBranch(locr0, trapframe->pc, 0,
892 				    0);
893 			} else {
894 				locr0->pc += sizeof(int);
895 			}
896 			addr = va;
897 			i = SIGEMT;	/* Stuff it with something for now */
898 			break;
899 		}
900 
901 	case T_RES_INST + T_USER:
902 		{
903 			InstFmt inst;
904 			inst = *(InstFmt *)(intptr_t)trapframe->pc;
905 			switch (inst.RType.op) {
906 			case OP_SPECIAL3:
907 				switch (inst.RType.func) {
908 				case OP_RDHWR:
909 					/* Register 29 used for TLS */
910 					if (inst.RType.rd == 29) {
911 						frame_regs = &(trapframe->zero);
912 						frame_regs[inst.RType.rt] = (register_t)(intptr_t)td->td_md.md_tls;
913 						frame_regs[inst.RType.rt] += td->td_md.md_tls_tcb_offset;
914 						trapframe->pc += sizeof(int);
915 						goto out;
916 					}
917 				break;
918 				}
919 			break;
920 			}
921 
922 			log_illegal_instruction("RES_INST", trapframe);
923 			i = SIGILL;
924 			addr = trapframe->pc;
925 		}
926 		break;
927 	case T_C2E:
928 	case T_C2E + T_USER:
929 		goto err;
930 		break;
931 	case T_COP_UNUSABLE:
932 #ifdef	CPU_CNMIPS
933 		cop = (trapframe->cause & MIPS_CR_COP_ERR) >> MIPS_CR_COP_ERR_SHIFT;
934 		/* Handle only COP2 exception */
935 		if (cop != 2)
936 			goto err;
937 
938 		addr = trapframe->pc;
939 		/* save userland cop2 context if it has been touched */
940 		if ((td->td_md.md_flags & MDTD_COP2USED) &&
941 		    (td->td_md.md_cop2owner == COP2_OWNER_USERLAND)) {
942 			if (td->td_md.md_ucop2)
943 				octeon_cop2_save(td->td_md.md_ucop2);
944 			else
945 				panic("COP2 was used in user mode but md_ucop2 is NULL");
946 		}
947 
948 		if (td->td_md.md_cop2 == NULL) {
949 			td->td_md.md_cop2 = octeon_cop2_alloc_ctx();
950 			if (td->td_md.md_cop2 == NULL)
951 				panic("Failed to allocate COP2 context");
952 			memset(td->td_md.md_cop2, 0, sizeof(*td->td_md.md_cop2));
953 		}
954 
955 		octeon_cop2_restore(td->td_md.md_cop2);
956 
957 		/* Make userland re-request its context */
958 		td->td_frame->sr &= ~MIPS_SR_COP_2_BIT;
959 		td->td_md.md_flags |= MDTD_COP2USED;
960 		td->td_md.md_cop2owner = COP2_OWNER_KERNEL;
961 		/* Enable COP2, it will be disabled in cpu_switch */
962 		mips_wr_status(mips_rd_status() | MIPS_SR_COP_2_BIT);
963 		return (trapframe->pc);
964 #else
965 		goto err;
966 		break;
967 #endif
968 
969 	case T_COP_UNUSABLE + T_USER:
970 		cop = (trapframe->cause & MIPS_CR_COP_ERR) >> MIPS_CR_COP_ERR_SHIFT;
971 		if (cop == 1) {
972 			/* FP (COP1) instruction */
973 			if (cpuinfo.fpu_id == 0) {
974 				log_illegal_instruction("COP1_UNUSABLE",
975 				    trapframe);
976 				i = SIGILL;
977 				break;
978 			}
979 			addr = trapframe->pc;
980 			MipsSwitchFPState(PCPU_GET(fpcurthread), td->td_frame);
981 			PCPU_SET(fpcurthread, td);
982 #if defined(__mips_n32) || defined(__mips_n64)
983 			td->td_frame->sr |= MIPS_SR_COP_1_BIT | MIPS_SR_FR;
984 #else
985 			td->td_frame->sr |= MIPS_SR_COP_1_BIT;
986 #endif
987 			td->td_md.md_flags |= MDTD_FPUSED;
988 			goto out;
989 		}
990 #ifdef	CPU_CNMIPS
991 		else  if (cop == 2) {
992 			addr = trapframe->pc;
993 			if ((td->td_md.md_flags & MDTD_COP2USED) &&
994 			    (td->td_md.md_cop2owner == COP2_OWNER_KERNEL)) {
995 				if (td->td_md.md_cop2)
996 					octeon_cop2_save(td->td_md.md_cop2);
997 				else
998 					panic("COP2 was used in kernel mode but md_cop2 is NULL");
999 			}
1000 
1001 			if (td->td_md.md_ucop2 == NULL) {
1002 				td->td_md.md_ucop2 = octeon_cop2_alloc_ctx();
1003 				if (td->td_md.md_ucop2 == NULL)
1004 					panic("Failed to allocate userland COP2 context");
1005 				memset(td->td_md.md_ucop2, 0, sizeof(*td->td_md.md_ucop2));
1006 			}
1007 
1008 			octeon_cop2_restore(td->td_md.md_ucop2);
1009 
1010 			td->td_frame->sr |= MIPS_SR_COP_2_BIT;
1011 			td->td_md.md_flags |= MDTD_COP2USED;
1012 			td->td_md.md_cop2owner = COP2_OWNER_USERLAND;
1013 			goto out;
1014 		}
1015 #endif
1016 		else {
1017 			log_illegal_instruction("COPn_UNUSABLE", trapframe);
1018 			i = SIGILL;	/* only FPU instructions allowed */
1019 			break;
1020 		}
1021 
1022 	case T_FPE:
1023 #if !defined(SMP) && (defined(DDB) || defined(DEBUG))
1024 		trapDump("fpintr");
1025 #else
1026 		printf("FPU Trap: PC %#jx CR %x SR %x\n",
1027 		    (intmax_t)trapframe->pc, (unsigned)trapframe->cause, (unsigned)trapframe->sr);
1028 		goto err;
1029 #endif
1030 
1031 	case T_FPE + T_USER:
1032 		if (!emulate_fp) {
1033 			i = SIGFPE;
1034 			addr = trapframe->pc;
1035 			break;
1036 		}
1037 		MipsFPTrap(trapframe->sr, trapframe->cause, trapframe->pc);
1038 		goto out;
1039 
1040 	case T_OVFLOW + T_USER:
1041 		i = SIGFPE;
1042 		addr = trapframe->pc;
1043 		break;
1044 
1045 	case T_ADDR_ERR_LD:	/* misaligned access */
1046 	case T_ADDR_ERR_ST:	/* misaligned access */
1047 #ifdef TRAP_DEBUG
1048 		if (trap_debug) {
1049 			printf("+++ ADDR_ERR: type = %d, badvaddr = %#jx\n", type,
1050 			    (intmax_t)trapframe->badvaddr);
1051 		}
1052 #endif
1053 		/* Only allow emulation on a user address */
1054 		if (allow_unaligned_acc &&
1055 		    ((vm_offset_t)trapframe->badvaddr < VM_MAXUSER_ADDRESS)) {
1056 			int mode;
1057 
1058 			if (type == T_ADDR_ERR_LD)
1059 				mode = VM_PROT_READ;
1060 			else
1061 				mode = VM_PROT_WRITE;
1062 
1063 			access_type = emulate_unaligned_access(trapframe, mode);
1064 			if (access_type != 0)
1065 				return (trapframe->pc);
1066 		}
1067 		/* FALLTHROUGH */
1068 
1069 	case T_BUS_ERR_LD_ST:	/* BERR asserted to cpu */
1070 		if (td->td_pcb->pcb_onfault != NULL) {
1071 			pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault;
1072 			td->td_pcb->pcb_onfault = NULL;
1073 			return (pc);
1074 		}
1075 
1076 		/* FALLTHROUGH */
1077 
1078 	default:
1079 err:
1080 
1081 #if !defined(SMP) && defined(DEBUG)
1082 		trapDump("trap");
1083 #endif
1084 #ifdef SMP
1085 		printf("cpu:%d-", PCPU_GET(cpuid));
1086 #endif
1087 		printf("Trap cause = %d (%s - ", type,
1088 		    trap_type[type & (~T_USER)]);
1089 
1090 		if (type & T_USER)
1091 			printf("user mode)\n");
1092 		else
1093 			printf("kernel mode)\n");
1094 
1095 #ifdef TRAP_DEBUG
1096 		if (trap_debug)
1097 			printf("badvaddr = %#jx, pc = %#jx, ra = %#jx, sr = %#jxx\n",
1098 			       (intmax_t)trapframe->badvaddr, (intmax_t)trapframe->pc, (intmax_t)trapframe->ra,
1099 			       (intmax_t)trapframe->sr);
1100 #endif
1101 
1102 #ifdef KDB
1103 		if (debugger_on_trap) {
1104 			kdb_why = KDB_WHY_TRAP;
1105 			kdb_trap(type, 0, trapframe);
1106 			kdb_why = KDB_WHY_UNSET;
1107 		}
1108 #endif
1109 		panic("trap");
1110 	}
1111 	td->td_frame->pc = trapframe->pc;
1112 	td->td_frame->cause = trapframe->cause;
1113 	td->td_frame->badvaddr = trapframe->badvaddr;
1114 	ksiginfo_init_trap(&ksi);
1115 	ksi.ksi_signo = i;
1116 	ksi.ksi_code = ucode;
1117 	ksi.ksi_addr = (void *)addr;
1118 	ksi.ksi_trapno = type;
1119 	trapsignal(td, &ksi);
1120 out:
1121 
1122 	/*
1123 	 * Note: we should only get here if returning to user mode.
1124 	 */
1125 	userret(td, trapframe);
1126 	return (trapframe->pc);
1127 }
1128 
1129 #if !defined(SMP) && (defined(DDB) || defined(DEBUG))
1130 void
trapDump(char * msg)1131 trapDump(char *msg)
1132 {
1133 	register_t s;
1134 	int i;
1135 
1136 	s = intr_disable();
1137 	printf("trapDump(%s)\n", msg);
1138 	for (i = 0; i < TRAPSIZE; i++) {
1139 		if (trp == trapdebug) {
1140 			trp = &trapdebug[TRAPSIZE - 1];
1141 		} else {
1142 			trp--;
1143 		}
1144 
1145 		if (trp->cause == 0)
1146 			break;
1147 
1148 		printf("%s: ADR %jx PC %jx CR %jx SR %jx\n",
1149 		    trap_type[(trp->cause & MIPS_CR_EXC_CODE) >>
1150 			MIPS_CR_EXC_CODE_SHIFT],
1151 		    (intmax_t)trp->vadr, (intmax_t)trp->pc,
1152 		    (intmax_t)trp->cause, (intmax_t)trp->status);
1153 
1154 		printf("   RA %jx SP %jx code %d\n", (intmax_t)trp->ra,
1155 		    (intmax_t)trp->sp, (int)trp->code);
1156 	}
1157 	intr_restore(s);
1158 }
1159 #endif
1160 
1161 
1162 /*
1163  * Return the resulting PC as if the branch was executed.
1164  */
1165 uintptr_t
MipsEmulateBranch(struct trapframe * framePtr,uintptr_t instPC,int fpcCSR,uintptr_t instptr)1166 MipsEmulateBranch(struct trapframe *framePtr, uintptr_t instPC, int fpcCSR,
1167     uintptr_t instptr)
1168 {
1169 	InstFmt inst;
1170 	register_t *regsPtr = (register_t *) framePtr;
1171 	uintptr_t retAddr = 0;
1172 	int condition;
1173 
1174 #define	GetBranchDest(InstPtr, inst) \
1175 	(InstPtr + 4 + ((short)inst.IType.imm << 2))
1176 
1177 
1178 	if (instptr) {
1179 		if (instptr < MIPS_KSEG0_START)
1180 			inst.word = fuword32((void *)instptr);
1181 		else
1182 			inst = *(InstFmt *) instptr;
1183 	} else {
1184 		if ((vm_offset_t)instPC < MIPS_KSEG0_START)
1185 			inst.word = fuword32((void *)instPC);
1186 		else
1187 			inst = *(InstFmt *) instPC;
1188 	}
1189 
1190 	switch ((int)inst.JType.op) {
1191 	case OP_SPECIAL:
1192 		switch ((int)inst.RType.func) {
1193 		case OP_JR:
1194 		case OP_JALR:
1195 			retAddr = regsPtr[inst.RType.rs];
1196 			break;
1197 
1198 		default:
1199 			retAddr = instPC + 4;
1200 			break;
1201 		}
1202 		break;
1203 
1204 	case OP_BCOND:
1205 		switch ((int)inst.IType.rt) {
1206 		case OP_BLTZ:
1207 		case OP_BLTZL:
1208 		case OP_BLTZAL:
1209 		case OP_BLTZALL:
1210 			if ((int)(regsPtr[inst.RType.rs]) < 0)
1211 				retAddr = GetBranchDest(instPC, inst);
1212 			else
1213 				retAddr = instPC + 8;
1214 			break;
1215 
1216 		case OP_BGEZ:
1217 		case OP_BGEZL:
1218 		case OP_BGEZAL:
1219 		case OP_BGEZALL:
1220 			if ((int)(regsPtr[inst.RType.rs]) >= 0)
1221 				retAddr = GetBranchDest(instPC, inst);
1222 			else
1223 				retAddr = instPC + 8;
1224 			break;
1225 
1226 		case OP_TGEI:
1227 		case OP_TGEIU:
1228 		case OP_TLTI:
1229 		case OP_TLTIU:
1230 		case OP_TEQI:
1231 		case OP_TNEI:
1232 			retAddr = instPC + 4;	/* Like syscall... */
1233 			break;
1234 
1235 		default:
1236 			panic("MipsEmulateBranch: Bad branch cond");
1237 		}
1238 		break;
1239 
1240 	case OP_J:
1241 	case OP_JAL:
1242 		retAddr = (inst.JType.target << 2) |
1243 		    ((unsigned)(instPC + 4) & 0xF0000000);
1244 		break;
1245 
1246 	case OP_BEQ:
1247 	case OP_BEQL:
1248 		if (regsPtr[inst.RType.rs] == regsPtr[inst.RType.rt])
1249 			retAddr = GetBranchDest(instPC, inst);
1250 		else
1251 			retAddr = instPC + 8;
1252 		break;
1253 
1254 	case OP_BNE:
1255 	case OP_BNEL:
1256 		if (regsPtr[inst.RType.rs] != regsPtr[inst.RType.rt])
1257 			retAddr = GetBranchDest(instPC, inst);
1258 		else
1259 			retAddr = instPC + 8;
1260 		break;
1261 
1262 	case OP_BLEZ:
1263 	case OP_BLEZL:
1264 		if ((int)(regsPtr[inst.RType.rs]) <= 0)
1265 			retAddr = GetBranchDest(instPC, inst);
1266 		else
1267 			retAddr = instPC + 8;
1268 		break;
1269 
1270 	case OP_BGTZ:
1271 	case OP_BGTZL:
1272 		if ((int)(regsPtr[inst.RType.rs]) > 0)
1273 			retAddr = GetBranchDest(instPC, inst);
1274 		else
1275 			retAddr = instPC + 8;
1276 		break;
1277 
1278 	case OP_COP1:
1279 		switch (inst.RType.rs) {
1280 		case OP_BCx:
1281 		case OP_BCy:
1282 			if ((inst.RType.rt & COPz_BC_TF_MASK) == COPz_BC_TRUE)
1283 				condition = fpcCSR & MIPS_FPU_COND_BIT;
1284 			else
1285 				condition = !(fpcCSR & MIPS_FPU_COND_BIT);
1286 			if (condition)
1287 				retAddr = GetBranchDest(instPC, inst);
1288 			else
1289 				retAddr = instPC + 8;
1290 			break;
1291 
1292 		default:
1293 			retAddr = instPC + 4;
1294 		}
1295 		break;
1296 
1297 	default:
1298 		retAddr = instPC + 4;
1299 	}
1300 	return (retAddr);
1301 }
1302 
1303 static void
log_frame_dump(struct trapframe * frame)1304 log_frame_dump(struct trapframe *frame)
1305 {
1306 	log(LOG_ERR, "Trapframe Register Dump:\n");
1307 	log(LOG_ERR, "\tzero: %#jx\tat: %#jx\tv0: %#jx\tv1: %#jx\n",
1308 	    (intmax_t)0, (intmax_t)frame->ast, (intmax_t)frame->v0, (intmax_t)frame->v1);
1309 
1310 	log(LOG_ERR, "\ta0: %#jx\ta1: %#jx\ta2: %#jx\ta3: %#jx\n",
1311 	    (intmax_t)frame->a0, (intmax_t)frame->a1, (intmax_t)frame->a2, (intmax_t)frame->a3);
1312 
1313 #if defined(__mips_n32) || defined(__mips_n64)
1314 	log(LOG_ERR, "\ta4: %#jx\ta5: %#jx\ta6: %#jx\ta6: %#jx\n",
1315 	    (intmax_t)frame->a4, (intmax_t)frame->a5, (intmax_t)frame->a6, (intmax_t)frame->a7);
1316 
1317 	log(LOG_ERR, "\tt0: %#jx\tt1: %#jx\tt2: %#jx\tt3: %#jx\n",
1318 	    (intmax_t)frame->t0, (intmax_t)frame->t1, (intmax_t)frame->t2, (intmax_t)frame->t3);
1319 #else
1320 	log(LOG_ERR, "\tt0: %#jx\tt1: %#jx\tt2: %#jx\tt3: %#jx\n",
1321 	    (intmax_t)frame->t0, (intmax_t)frame->t1, (intmax_t)frame->t2, (intmax_t)frame->t3);
1322 
1323 	log(LOG_ERR, "\tt4: %#jx\tt5: %#jx\tt6: %#jx\tt7: %#jx\n",
1324 	    (intmax_t)frame->t4, (intmax_t)frame->t5, (intmax_t)frame->t6, (intmax_t)frame->t7);
1325 #endif
1326 	log(LOG_ERR, "\tt8: %#jx\tt9: %#jx\ts0: %#jx\ts1: %#jx\n",
1327 	    (intmax_t)frame->t8, (intmax_t)frame->t9, (intmax_t)frame->s0, (intmax_t)frame->s1);
1328 
1329 	log(LOG_ERR, "\ts2: %#jx\ts3: %#jx\ts4: %#jx\ts5: %#jx\n",
1330 	    (intmax_t)frame->s2, (intmax_t)frame->s3, (intmax_t)frame->s4, (intmax_t)frame->s5);
1331 
1332 	log(LOG_ERR, "\ts6: %#jx\ts7: %#jx\tk0: %#jx\tk1: %#jx\n",
1333 	    (intmax_t)frame->s6, (intmax_t)frame->s7, (intmax_t)frame->k0, (intmax_t)frame->k1);
1334 
1335 	log(LOG_ERR, "\tgp: %#jx\tsp: %#jx\ts8: %#jx\tra: %#jx\n",
1336 	    (intmax_t)frame->gp, (intmax_t)frame->sp, (intmax_t)frame->s8, (intmax_t)frame->ra);
1337 
1338 	log(LOG_ERR, "\tsr: %#jx\tmullo: %#jx\tmulhi: %#jx\tbadvaddr: %#jx\n",
1339 	    (intmax_t)frame->sr, (intmax_t)frame->mullo, (intmax_t)frame->mulhi, (intmax_t)frame->badvaddr);
1340 
1341 	log(LOG_ERR, "\tcause: %#jx\tpc: %#jx\n",
1342 	    (intmax_t)frame->cause, (intmax_t)frame->pc);
1343 }
1344 
1345 #ifdef TRAP_DEBUG
1346 static void
trap_frame_dump(struct trapframe * frame)1347 trap_frame_dump(struct trapframe *frame)
1348 {
1349 	printf("Trapframe Register Dump:\n");
1350 	printf("\tzero: %#jx\tat: %#jx\tv0: %#jx\tv1: %#jx\n",
1351 	    (intmax_t)0, (intmax_t)frame->ast, (intmax_t)frame->v0, (intmax_t)frame->v1);
1352 
1353 	printf("\ta0: %#jx\ta1: %#jx\ta2: %#jx\ta3: %#jx\n",
1354 	    (intmax_t)frame->a0, (intmax_t)frame->a1, (intmax_t)frame->a2, (intmax_t)frame->a3);
1355 #if defined(__mips_n32) || defined(__mips_n64)
1356 	printf("\ta4: %#jx\ta5: %#jx\ta6: %#jx\ta7: %#jx\n",
1357 	    (intmax_t)frame->a4, (intmax_t)frame->a5, (intmax_t)frame->a6, (intmax_t)frame->a7);
1358 
1359 	printf("\tt0: %#jx\tt1: %#jx\tt2: %#jx\tt3: %#jx\n",
1360 	    (intmax_t)frame->t0, (intmax_t)frame->t1, (intmax_t)frame->t2, (intmax_t)frame->t3);
1361 #else
1362 	printf("\tt0: %#jx\tt1: %#jx\tt2: %#jx\tt3: %#jx\n",
1363 	    (intmax_t)frame->t0, (intmax_t)frame->t1, (intmax_t)frame->t2, (intmax_t)frame->t3);
1364 
1365 	printf("\tt4: %#jx\tt5: %#jx\tt6: %#jx\tt7: %#jx\n",
1366 	    (intmax_t)frame->t4, (intmax_t)frame->t5, (intmax_t)frame->t6, (intmax_t)frame->t7);
1367 #endif
1368 	printf("\tt8: %#jx\tt9: %#jx\ts0: %#jx\ts1: %#jx\n",
1369 	    (intmax_t)frame->t8, (intmax_t)frame->t9, (intmax_t)frame->s0, (intmax_t)frame->s1);
1370 
1371 	printf("\ts2: %#jx\ts3: %#jx\ts4: %#jx\ts5: %#jx\n",
1372 	    (intmax_t)frame->s2, (intmax_t)frame->s3, (intmax_t)frame->s4, (intmax_t)frame->s5);
1373 
1374 	printf("\ts6: %#jx\ts7: %#jx\tk0: %#jx\tk1: %#jx\n",
1375 	    (intmax_t)frame->s6, (intmax_t)frame->s7, (intmax_t)frame->k0, (intmax_t)frame->k1);
1376 
1377 	printf("\tgp: %#jx\tsp: %#jx\ts8: %#jx\tra: %#jx\n",
1378 	    (intmax_t)frame->gp, (intmax_t)frame->sp, (intmax_t)frame->s8, (intmax_t)frame->ra);
1379 
1380 	printf("\tsr: %#jx\tmullo: %#jx\tmulhi: %#jx\tbadvaddr: %#jx\n",
1381 	    (intmax_t)frame->sr, (intmax_t)frame->mullo, (intmax_t)frame->mulhi, (intmax_t)frame->badvaddr);
1382 
1383 	printf("\tcause: %#jx\tpc: %#jx\n",
1384 	    (intmax_t)frame->cause, (intmax_t)frame->pc);
1385 }
1386 
1387 #endif
1388 
1389 
1390 static void
get_mapping_info(vm_offset_t va,pd_entry_t ** pdepp,pt_entry_t ** ptepp)1391 get_mapping_info(vm_offset_t va, pd_entry_t **pdepp, pt_entry_t **ptepp)
1392 {
1393 	pt_entry_t *ptep;
1394 	pd_entry_t *pdep;
1395 	struct proc *p = curproc;
1396 
1397 	pdep = (&(p->p_vmspace->vm_pmap.pm_segtab[(va >> SEGSHIFT) & (NPDEPG - 1)]));
1398 	if (*pdep)
1399 		ptep = pmap_pte(&p->p_vmspace->vm_pmap, va);
1400 	else
1401 		ptep = (pt_entry_t *)0;
1402 
1403 	*pdepp = pdep;
1404 	*ptepp = ptep;
1405 }
1406 
1407 static void
log_illegal_instruction(const char * msg,struct trapframe * frame)1408 log_illegal_instruction(const char *msg, struct trapframe *frame)
1409 {
1410 	pt_entry_t *ptep;
1411 	pd_entry_t *pdep;
1412 	unsigned int *addr;
1413 	struct thread *td;
1414 	struct proc *p;
1415 	register_t pc;
1416 
1417 	td = curthread;
1418 	p = td->td_proc;
1419 
1420 #ifdef SMP
1421 	printf("cpuid = %d\n", PCPU_GET(cpuid));
1422 #endif
1423 	pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0);
1424 	log(LOG_ERR, "%s: pid %d tid %ld (%s), uid %d: pc %#jx ra %#jx\n",
1425 	    msg, p->p_pid, (long)td->td_tid, p->p_comm,
1426 	    p->p_ucred ? p->p_ucred->cr_uid : -1,
1427 	    (intmax_t)pc,
1428 	    (intmax_t)frame->ra);
1429 
1430 	/* log registers in trap frame */
1431 	log_frame_dump(frame);
1432 
1433 	get_mapping_info((vm_offset_t)pc, &pdep, &ptep);
1434 
1435 	/*
1436 	 * Dump a few words around faulting instruction, if the addres is
1437 	 * valid.
1438 	 */
1439 	if (!(pc & 3) &&
1440 	    useracc((caddr_t)(intptr_t)pc, sizeof(int) * 4, VM_PROT_READ)) {
1441 		/* dump page table entry for faulting instruction */
1442 		log(LOG_ERR, "Page table info for pc address %#jx: pde = %p, pte = %#jx\n",
1443 		    (intmax_t)pc, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0));
1444 
1445 		addr = (unsigned int *)(intptr_t)pc;
1446 		log(LOG_ERR, "Dumping 4 words starting at pc address %p: \n",
1447 		    addr);
1448 		log(LOG_ERR, "%08x %08x %08x %08x\n",
1449 		    addr[0], addr[1], addr[2], addr[3]);
1450 	} else {
1451 		log(LOG_ERR, "pc address %#jx is inaccessible, pde = %p, pte = %#jx\n",
1452 		    (intmax_t)pc, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0));
1453 	}
1454 }
1455 
1456 static void
log_bad_page_fault(char * msg,struct trapframe * frame,int trap_type)1457 log_bad_page_fault(char *msg, struct trapframe *frame, int trap_type)
1458 {
1459 	pt_entry_t *ptep;
1460 	pd_entry_t *pdep;
1461 	unsigned int *addr;
1462 	struct thread *td;
1463 	struct proc *p;
1464 	char *read_or_write;
1465 	register_t pc;
1466 
1467 	trap_type &= ~T_USER;
1468 
1469 	td = curthread;
1470 	p = td->td_proc;
1471 
1472 #ifdef SMP
1473 	printf("cpuid = %d\n", PCPU_GET(cpuid));
1474 #endif
1475 	switch (trap_type) {
1476 	case T_TLB_MOD:
1477 	case T_TLB_ST_MISS:
1478 	case T_ADDR_ERR_ST:
1479 		read_or_write = "write";
1480 		break;
1481 	case T_TLB_LD_MISS:
1482 	case T_ADDR_ERR_LD:
1483 	case T_BUS_ERR_IFETCH:
1484 		read_or_write = "read";
1485 		break;
1486 	default:
1487 		read_or_write = "unknown";
1488 	}
1489 
1490 	pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0);
1491 	log(LOG_ERR, "%s: pid %d tid %ld (%s), uid %d: pc %#jx got a %s fault "
1492 	    "(type %#x) at %#jx\n",
1493 	    msg, p->p_pid, (long)td->td_tid, p->p_comm,
1494 	    p->p_ucred ? p->p_ucred->cr_uid : -1,
1495 	    (intmax_t)pc,
1496 	    read_or_write,
1497 	    trap_type,
1498 	    (intmax_t)frame->badvaddr);
1499 
1500 	/* log registers in trap frame */
1501 	log_frame_dump(frame);
1502 
1503 	get_mapping_info((vm_offset_t)pc, &pdep, &ptep);
1504 
1505 	/*
1506 	 * Dump a few words around faulting instruction, if the addres is
1507 	 * valid.
1508 	 */
1509 	if (!(pc & 3) && (pc != frame->badvaddr) &&
1510 	    (trap_type != T_BUS_ERR_IFETCH) &&
1511 	    useracc((caddr_t)(intptr_t)pc, sizeof(int) * 4, VM_PROT_READ)) {
1512 		/* dump page table entry for faulting instruction */
1513 		log(LOG_ERR, "Page table info for pc address %#jx: pde = %p, pte = %#jx\n",
1514 		    (intmax_t)pc, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0));
1515 
1516 		addr = (unsigned int *)(intptr_t)pc;
1517 		log(LOG_ERR, "Dumping 4 words starting at pc address %p: \n",
1518 		    addr);
1519 		log(LOG_ERR, "%08x %08x %08x %08x\n",
1520 		    addr[0], addr[1], addr[2], addr[3]);
1521 	} else {
1522 		log(LOG_ERR, "pc address %#jx is inaccessible, pde = %p, pte = %#jx\n",
1523 		    (intmax_t)pc, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0));
1524 	}
1525 
1526 	get_mapping_info((vm_offset_t)frame->badvaddr, &pdep, &ptep);
1527 	log(LOG_ERR, "Page table info for bad address %#jx: pde = %p, pte = %#jx\n",
1528 	    (intmax_t)frame->badvaddr, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0));
1529 }
1530 
1531 
1532 /*
1533  * Unaligned load/store emulation
1534  */
1535 static int
mips_unaligned_load_store(struct trapframe * frame,int mode,register_t addr,register_t pc)1536 mips_unaligned_load_store(struct trapframe *frame, int mode, register_t addr, register_t pc)
1537 {
1538 	register_t *reg = (register_t *) frame;
1539 	u_int32_t inst = *((u_int32_t *)(intptr_t)pc);
1540 	register_t value_msb, value;
1541 	unsigned size;
1542 
1543 	/*
1544 	 * ADDR_ERR faults have higher priority than TLB
1545 	 * Miss faults.  Therefore, it is necessary to
1546 	 * verify that the faulting address is a valid
1547 	 * virtual address within the process' address space
1548 	 * before trying to emulate the unaligned access.
1549 	 */
1550 	switch (MIPS_INST_OPCODE(inst)) {
1551 	case OP_LHU: case OP_LH:
1552 	case OP_SH:
1553 		size = 2;
1554 		break;
1555 	case OP_LWU: case OP_LW:
1556 	case OP_SW:
1557 		size = 4;
1558 		break;
1559 	case OP_LD:
1560 	case OP_SD:
1561 		size = 8;
1562 		break;
1563 	default:
1564 		printf("%s: unhandled opcode in address error: %#x\n", __func__, MIPS_INST_OPCODE(inst));
1565 		return (0);
1566 	}
1567 
1568 	if (!useracc((void *)rounddown2((vm_offset_t)addr, size), size * 2, mode))
1569 		return (0);
1570 
1571 	/*
1572 	 * XXX
1573 	 * Handle LL/SC LLD/SCD.
1574 	 */
1575 	switch (MIPS_INST_OPCODE(inst)) {
1576 	case OP_LHU:
1577 		KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction."));
1578 		lbu_macro(value_msb, addr);
1579 		addr += 1;
1580 		lbu_macro(value, addr);
1581 		value |= value_msb << 8;
1582 		reg[MIPS_INST_RT(inst)] = value;
1583 		return (MIPS_LHU_ACCESS);
1584 
1585 	case OP_LH:
1586 		KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction."));
1587 		lb_macro(value_msb, addr);
1588 		addr += 1;
1589 		lbu_macro(value, addr);
1590 		value |= value_msb << 8;
1591 		reg[MIPS_INST_RT(inst)] = value;
1592 		return (MIPS_LH_ACCESS);
1593 
1594 	case OP_LWU:
1595 		KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction."));
1596 		lwl_macro(value, addr);
1597 		addr += 3;
1598 		lwr_macro(value, addr);
1599 		value &= 0xffffffff;
1600 		reg[MIPS_INST_RT(inst)] = value;
1601 		return (MIPS_LWU_ACCESS);
1602 
1603 	case OP_LW:
1604 		KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction."));
1605 		lwl_macro(value, addr);
1606 		addr += 3;
1607 		lwr_macro(value, addr);
1608 		reg[MIPS_INST_RT(inst)] = value;
1609 		return (MIPS_LW_ACCESS);
1610 
1611 #if defined(__mips_n32) || defined(__mips_n64)
1612 	case OP_LD:
1613 		KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction."));
1614 		ldl_macro(value, addr);
1615 		addr += 7;
1616 		ldr_macro(value, addr);
1617 		reg[MIPS_INST_RT(inst)] = value;
1618 		return (MIPS_LD_ACCESS);
1619 #endif
1620 
1621 	case OP_SH:
1622 		KASSERT(mode == VM_PROT_WRITE, ("access mode must be write for store instruction."));
1623 		value = reg[MIPS_INST_RT(inst)];
1624 		value_msb = value >> 8;
1625 		sb_macro(value_msb, addr);
1626 		addr += 1;
1627 		sb_macro(value, addr);
1628 		return (MIPS_SH_ACCESS);
1629 
1630 	case OP_SW:
1631 		KASSERT(mode == VM_PROT_WRITE, ("access mode must be write for store instruction."));
1632 		value = reg[MIPS_INST_RT(inst)];
1633 		swl_macro(value, addr);
1634 		addr += 3;
1635 		swr_macro(value, addr);
1636 		return (MIPS_SW_ACCESS);
1637 
1638 #if defined(__mips_n32) || defined(__mips_n64)
1639 	case OP_SD:
1640 		KASSERT(mode == VM_PROT_WRITE, ("access mode must be write for store instruction."));
1641 		value = reg[MIPS_INST_RT(inst)];
1642 		sdl_macro(value, addr);
1643 		addr += 7;
1644 		sdr_macro(value, addr);
1645 		return (MIPS_SD_ACCESS);
1646 #endif
1647 	}
1648 	panic("%s: should not be reached.", __func__);
1649 }
1650 
1651 
1652 /*
1653  * XXX TODO: SMP?
1654  */
1655 static struct timeval unaligned_lasterr;
1656 static int unaligned_curerr;
1657 
1658 static int unaligned_pps_log_limit = 4;
1659 
1660 SYSCTL_INT(_machdep, OID_AUTO, unaligned_log_pps_limit, CTLFLAG_RWTUN,
1661     &unaligned_pps_log_limit, 0,
1662     "limit number of userland unaligned log messages per second");
1663 
1664 static int
emulate_unaligned_access(struct trapframe * frame,int mode)1665 emulate_unaligned_access(struct trapframe *frame, int mode)
1666 {
1667 	register_t pc;
1668 	int access_type = 0;
1669 	struct thread *td = curthread;
1670 	struct proc *p = curproc;
1671 
1672 	pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0);
1673 
1674 	/*
1675 	 * Fall through if it's instruction fetch exception
1676 	 */
1677 	if (!((pc & 3) || (pc == frame->badvaddr))) {
1678 
1679 		/*
1680 		 * Handle unaligned load and store
1681 		 */
1682 
1683 		/*
1684 		 * Return access type if the instruction was emulated.
1685 		 * Otherwise restore pc and fall through.
1686 		 */
1687 		access_type = mips_unaligned_load_store(frame,
1688 		    mode, frame->badvaddr, pc);
1689 
1690 		if (access_type) {
1691 			if (DELAYBRANCH(frame->cause))
1692 				frame->pc = MipsEmulateBranch(frame, frame->pc,
1693 				    0, 0);
1694 			else
1695 				frame->pc += 4;
1696 
1697 			if (ppsratecheck(&unaligned_lasterr,
1698 			    &unaligned_curerr, unaligned_pps_log_limit)) {
1699 				/* XXX TODO: keep global/tid/pid counters? */
1700 				log(LOG_INFO,
1701 				    "Unaligned %s: pid=%ld (%s), tid=%ld, "
1702 				    "pc=%#jx, badvaddr=%#jx\n",
1703 				    access_name[access_type - 1],
1704 				    (long) p->p_pid,
1705 				    p->p_comm,
1706 				    (long) td->td_tid,
1707 				    (intmax_t)pc,
1708 				    (intmax_t)frame->badvaddr);
1709 			}
1710 		}
1711 	}
1712 	return access_type;
1713 }
1714