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: stable/12/sys/mips/mips/trap.c 360693 2020-05-06 17:12:26Z brooks $");
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 = (vm_offset_t)trapframe->badvaddr;
674 			rv = vm_fault_trap(kernel_map, va, ftype,
675 			    VM_FAULT_NORMAL, NULL, NULL);
676 			if (rv == KERN_SUCCESS)
677 				return (trapframe->pc);
678 			if (td->td_pcb->pcb_onfault != NULL) {
679 				pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault;
680 				td->td_pcb->pcb_onfault = NULL;
681 				return (pc);
682 			}
683 			goto err;
684 		}
685 
686 		/*
687 		 * It is an error for the kernel to access user space except
688 		 * through the copyin/copyout routines.
689 		 */
690 		if (td->td_pcb->pcb_onfault == NULL)
691 			goto err;
692 
693 		goto dofault;
694 
695 	case T_TLB_LD_MISS + T_USER:
696 		ftype = VM_PROT_READ;
697 		goto dofault;
698 
699 	case T_TLB_ST_MISS + T_USER:
700 		ftype = VM_PROT_WRITE;
701 dofault:
702 		{
703 			vm_offset_t va;
704 			struct vmspace *vm;
705 			vm_map_t map;
706 			int rv = 0;
707 
708 			vm = p->p_vmspace;
709 			map = &vm->vm_map;
710 			va = (vm_offset_t)trapframe->badvaddr;
711 			if (KERNLAND(trapframe->badvaddr)) {
712 				/*
713 				 * Don't allow user-mode faults in kernel
714 				 * address space.
715 				 */
716 				goto nogo;
717 			}
718 
719 			rv = vm_fault_trap(map, va, ftype, VM_FAULT_NORMAL,
720 			    &i, &ucode);
721 			/*
722 			 * XXXDTRACE: add dtrace_doubletrap_func here?
723 			 */
724 #ifdef VMFAULT_TRACE
725 			printf("vm_fault(%p (pmap %p), %p (%p), %x, %d) -> %x at pc %p\n",
726 			    map, &vm->vm_pmap, (void *)va, (void *)(intptr_t)trapframe->badvaddr,
727 			    ftype, VM_FAULT_NORMAL, rv, (void *)(intptr_t)trapframe->pc);
728 #endif
729 
730 			if (rv == KERN_SUCCESS) {
731 				if (!usermode) {
732 					return (trapframe->pc);
733 				}
734 				goto out;
735 			}
736 	nogo:
737 			if (!usermode) {
738 				if (td->td_pcb->pcb_onfault != NULL) {
739 					pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault;
740 					td->td_pcb->pcb_onfault = NULL;
741 					return (pc);
742 				}
743 				goto err;
744 			}
745 			addr = trapframe->pc;
746 
747 			msg = "BAD_PAGE_FAULT";
748 			log_bad_page_fault(msg, trapframe, type);
749 
750 			break;
751 		}
752 
753 	case T_ADDR_ERR_LD + T_USER:	/* misaligned or kseg access */
754 	case T_ADDR_ERR_ST + T_USER:	/* misaligned or kseg access */
755 		if (trapframe->badvaddr < 0 ||
756 		    trapframe->badvaddr >= VM_MAXUSER_ADDRESS) {
757 			msg = "ADDRESS_SPACE_ERR";
758 		} else if (allow_unaligned_acc) {
759 			int mode;
760 
761 			if (type == (T_ADDR_ERR_LD + T_USER))
762 				mode = VM_PROT_READ;
763 			else
764 				mode = VM_PROT_WRITE;
765 
766 			access_type = emulate_unaligned_access(trapframe, mode);
767 			if (access_type != 0)
768 				goto out;
769 			msg = "ALIGNMENT_FIX_ERR";
770 		} else {
771 			msg = "ADDRESS_ERR";
772 		}
773 
774 		/* FALL THROUGH */
775 
776 	case T_BUS_ERR_IFETCH + T_USER:	/* BERR asserted to cpu */
777 	case T_BUS_ERR_LD_ST + T_USER:	/* BERR asserted to cpu */
778 		ucode = 0;	/* XXX should be VM_PROT_something */
779 		i = SIGBUS;
780 		addr = trapframe->pc;
781 		if (!msg)
782 			msg = "BUS_ERR";
783 		log_bad_page_fault(msg, trapframe, type);
784 		break;
785 
786 	case T_SYSCALL + T_USER:
787 		{
788 			td->td_sa.trapframe = trapframe;
789 			syscallenter(td);
790 
791 #if !defined(SMP) && (defined(DDB) || defined(DEBUG))
792 			if (trp == trapdebug)
793 				trapdebug[TRAPSIZE - 1].code = td->td_sa.code;
794 			else
795 				trp[-1].code = td->td_sa.code;
796 #endif
797 			trapdebug_enter(td->td_frame, -td->td_sa.code);
798 
799 			/*
800 			 * The sync'ing of I & D caches for SYS_ptrace() is
801 			 * done by procfs_domem() through procfs_rwmem()
802 			 * instead of being done here under a special check
803 			 * for SYS_ptrace().
804 			 */
805 			syscallret(td);
806 			return (trapframe->pc);
807 		}
808 
809 #if defined(KDTRACE_HOOKS) || defined(DDB)
810 	case T_BREAK:
811 #ifdef KDTRACE_HOOKS
812 		if (!usermode && dtrace_invop_jump_addr != 0) {
813 			dtrace_invop_jump_addr(trapframe);
814 			return (trapframe->pc);
815 		}
816 #endif
817 #ifdef DDB
818 		kdb_trap(type, 0, trapframe);
819 		return (trapframe->pc);
820 #endif
821 #endif
822 
823 	case T_BREAK + T_USER:
824 		{
825 			intptr_t va;
826 			uint32_t instr;
827 
828 			i = SIGTRAP;
829 			ucode = TRAP_BRKPT;
830 			addr = trapframe->pc;
831 
832 			/* compute address of break instruction */
833 			va = trapframe->pc;
834 			if (DELAYBRANCH(trapframe->cause))
835 				va += sizeof(int);
836 
837 			if (td->td_md.md_ss_addr != va)
838 				break;
839 
840 			/* read break instruction */
841 			instr = fuword32((caddr_t)va);
842 
843 			if (instr != MIPS_BREAK_SSTEP)
844 				break;
845 
846 			CTR3(KTR_PTRACE,
847 			    "trap: tid %d, single step at %#lx: %#08x",
848 			    td->td_tid, va, instr);
849 			PROC_LOCK(p);
850 			_PHOLD(p);
851 			error = ptrace_clear_single_step(td);
852 			_PRELE(p);
853 			PROC_UNLOCK(p);
854 			if (error == 0)
855 				ucode = TRAP_TRACE;
856 			break;
857 		}
858 
859 	case T_IWATCH + T_USER:
860 	case T_DWATCH + T_USER:
861 		{
862 			intptr_t va;
863 
864 			/* compute address of trapped instruction */
865 			va = trapframe->pc;
866 			if (DELAYBRANCH(trapframe->cause))
867 				va += sizeof(int);
868 			printf("watch exception @ %p\n", (void *)va);
869 			i = SIGTRAP;
870 			ucode = TRAP_BRKPT;
871 			addr = va;
872 			break;
873 		}
874 
875 	case T_TRAP + T_USER:
876 		{
877 			intptr_t va;
878 			struct trapframe *locr0 = td->td_frame;
879 
880 			/* compute address of trap instruction */
881 			va = trapframe->pc;
882 			if (DELAYBRANCH(trapframe->cause))
883 				va += sizeof(int);
884 
885 			if (DELAYBRANCH(trapframe->cause)) {	/* Check BD bit */
886 				locr0->pc = MipsEmulateBranch(locr0, trapframe->pc, 0,
887 				    0);
888 			} else {
889 				locr0->pc += sizeof(int);
890 			}
891 			addr = va;
892 			i = SIGEMT;	/* Stuff it with something for now */
893 			break;
894 		}
895 
896 	case T_RES_INST + T_USER:
897 		{
898 			InstFmt inst;
899 			inst = *(InstFmt *)(intptr_t)trapframe->pc;
900 			switch (inst.RType.op) {
901 			case OP_SPECIAL3:
902 				switch (inst.RType.func) {
903 				case OP_RDHWR:
904 					/* Register 29 used for TLS */
905 					if (inst.RType.rd == 29) {
906 						frame_regs = &(trapframe->zero);
907 						frame_regs[inst.RType.rt] = (register_t)(intptr_t)td->td_md.md_tls;
908 						frame_regs[inst.RType.rt] += td->td_md.md_tls_tcb_offset;
909 						trapframe->pc += sizeof(int);
910 						goto out;
911 					}
912 				break;
913 				}
914 			break;
915 			}
916 
917 			log_illegal_instruction("RES_INST", trapframe);
918 			i = SIGILL;
919 			addr = trapframe->pc;
920 		}
921 		break;
922 	case T_C2E:
923 	case T_C2E + T_USER:
924 		goto err;
925 		break;
926 	case T_COP_UNUSABLE:
927 #ifdef	CPU_CNMIPS
928 		cop = (trapframe->cause & MIPS_CR_COP_ERR) >> MIPS_CR_COP_ERR_SHIFT;
929 		/* Handle only COP2 exception */
930 		if (cop != 2)
931 			goto err;
932 
933 		addr = trapframe->pc;
934 		/* save userland cop2 context if it has been touched */
935 		if ((td->td_md.md_flags & MDTD_COP2USED) &&
936 		    (td->td_md.md_cop2owner == COP2_OWNER_USERLAND)) {
937 			if (td->td_md.md_ucop2)
938 				octeon_cop2_save(td->td_md.md_ucop2);
939 			else
940 				panic("COP2 was used in user mode but md_ucop2 is NULL");
941 		}
942 
943 		if (td->td_md.md_cop2 == NULL) {
944 			td->td_md.md_cop2 = octeon_cop2_alloc_ctx();
945 			if (td->td_md.md_cop2 == NULL)
946 				panic("Failed to allocate COP2 context");
947 			memset(td->td_md.md_cop2, 0, sizeof(*td->td_md.md_cop2));
948 		}
949 
950 		octeon_cop2_restore(td->td_md.md_cop2);
951 
952 		/* Make userland re-request its context */
953 		td->td_frame->sr &= ~MIPS_SR_COP_2_BIT;
954 		td->td_md.md_flags |= MDTD_COP2USED;
955 		td->td_md.md_cop2owner = COP2_OWNER_KERNEL;
956 		/* Enable COP2, it will be disabled in cpu_switch */
957 		mips_wr_status(mips_rd_status() | MIPS_SR_COP_2_BIT);
958 		return (trapframe->pc);
959 #else
960 		goto err;
961 		break;
962 #endif
963 
964 	case T_COP_UNUSABLE + T_USER:
965 		cop = (trapframe->cause & MIPS_CR_COP_ERR) >> MIPS_CR_COP_ERR_SHIFT;
966 		if (cop == 1) {
967 			/* FP (COP1) instruction */
968 			if (cpuinfo.fpu_id == 0) {
969 				log_illegal_instruction("COP1_UNUSABLE",
970 				    trapframe);
971 				i = SIGILL;
972 				break;
973 			}
974 			addr = trapframe->pc;
975 			MipsSwitchFPState(PCPU_GET(fpcurthread), td->td_frame);
976 			PCPU_SET(fpcurthread, td);
977 #if defined(__mips_n32) || defined(__mips_n64)
978 			td->td_frame->sr |= MIPS_SR_COP_1_BIT | MIPS_SR_FR;
979 #else
980 			td->td_frame->sr |= MIPS_SR_COP_1_BIT;
981 #endif
982 			td->td_md.md_flags |= MDTD_FPUSED;
983 			goto out;
984 		}
985 #ifdef	CPU_CNMIPS
986 		else  if (cop == 2) {
987 			addr = trapframe->pc;
988 			if ((td->td_md.md_flags & MDTD_COP2USED) &&
989 			    (td->td_md.md_cop2owner == COP2_OWNER_KERNEL)) {
990 				if (td->td_md.md_cop2)
991 					octeon_cop2_save(td->td_md.md_cop2);
992 				else
993 					panic("COP2 was used in kernel mode but md_cop2 is NULL");
994 			}
995 
996 			if (td->td_md.md_ucop2 == NULL) {
997 				td->td_md.md_ucop2 = octeon_cop2_alloc_ctx();
998 				if (td->td_md.md_ucop2 == NULL)
999 					panic("Failed to allocate userland COP2 context");
1000 				memset(td->td_md.md_ucop2, 0, sizeof(*td->td_md.md_ucop2));
1001 			}
1002 
1003 			octeon_cop2_restore(td->td_md.md_ucop2);
1004 
1005 			td->td_frame->sr |= MIPS_SR_COP_2_BIT;
1006 			td->td_md.md_flags |= MDTD_COP2USED;
1007 			td->td_md.md_cop2owner = COP2_OWNER_USERLAND;
1008 			goto out;
1009 		}
1010 #endif
1011 		else {
1012 			log_illegal_instruction("COPn_UNUSABLE", trapframe);
1013 			i = SIGILL;	/* only FPU instructions allowed */
1014 			break;
1015 		}
1016 
1017 	case T_FPE:
1018 #if !defined(SMP) && (defined(DDB) || defined(DEBUG))
1019 		trapDump("fpintr");
1020 #else
1021 		printf("FPU Trap: PC %#jx CR %x SR %x\n",
1022 		    (intmax_t)trapframe->pc, (unsigned)trapframe->cause, (unsigned)trapframe->sr);
1023 		goto err;
1024 #endif
1025 
1026 	case T_FPE + T_USER:
1027 		if (!emulate_fp) {
1028 			i = SIGFPE;
1029 			addr = trapframe->pc;
1030 			break;
1031 		}
1032 		MipsFPTrap(trapframe->sr, trapframe->cause, trapframe->pc);
1033 		goto out;
1034 
1035 	case T_OVFLOW + T_USER:
1036 		i = SIGFPE;
1037 		addr = trapframe->pc;
1038 		break;
1039 
1040 	case T_ADDR_ERR_LD:	/* misaligned access */
1041 	case T_ADDR_ERR_ST:	/* misaligned access */
1042 #ifdef TRAP_DEBUG
1043 		if (trap_debug) {
1044 			printf("+++ ADDR_ERR: type = %d, badvaddr = %#jx\n", type,
1045 			    (intmax_t)trapframe->badvaddr);
1046 		}
1047 #endif
1048 		/* Only allow emulation on a user address */
1049 		if (allow_unaligned_acc &&
1050 		    ((vm_offset_t)trapframe->badvaddr < VM_MAXUSER_ADDRESS)) {
1051 			int mode;
1052 
1053 			if (type == T_ADDR_ERR_LD)
1054 				mode = VM_PROT_READ;
1055 			else
1056 				mode = VM_PROT_WRITE;
1057 
1058 			access_type = emulate_unaligned_access(trapframe, mode);
1059 			if (access_type != 0)
1060 				return (trapframe->pc);
1061 		}
1062 		/* FALLTHROUGH */
1063 
1064 	case T_BUS_ERR_LD_ST:	/* BERR asserted to cpu */
1065 		if (td->td_pcb->pcb_onfault != NULL) {
1066 			pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault;
1067 			td->td_pcb->pcb_onfault = NULL;
1068 			return (pc);
1069 		}
1070 
1071 		/* FALLTHROUGH */
1072 
1073 	default:
1074 err:
1075 
1076 #if !defined(SMP) && defined(DEBUG)
1077 		trapDump("trap");
1078 #endif
1079 #ifdef SMP
1080 		printf("cpu:%d-", PCPU_GET(cpuid));
1081 #endif
1082 		printf("Trap cause = %d (%s - ", type,
1083 		    trap_type[type & (~T_USER)]);
1084 
1085 		if (type & T_USER)
1086 			printf("user mode)\n");
1087 		else
1088 			printf("kernel mode)\n");
1089 
1090 #ifdef TRAP_DEBUG
1091 		if (trap_debug)
1092 			printf("badvaddr = %#jx, pc = %#jx, ra = %#jx, sr = %#jxx\n",
1093 			       (intmax_t)trapframe->badvaddr, (intmax_t)trapframe->pc, (intmax_t)trapframe->ra,
1094 			       (intmax_t)trapframe->sr);
1095 #endif
1096 
1097 #ifdef KDB
1098 		if (debugger_on_trap) {
1099 			kdb_why = KDB_WHY_TRAP;
1100 			kdb_trap(type, 0, trapframe);
1101 			kdb_why = KDB_WHY_UNSET;
1102 		}
1103 #endif
1104 		panic("trap");
1105 	}
1106 	td->td_frame->pc = trapframe->pc;
1107 	td->td_frame->cause = trapframe->cause;
1108 	td->td_frame->badvaddr = trapframe->badvaddr;
1109 	ksiginfo_init_trap(&ksi);
1110 	ksi.ksi_signo = i;
1111 	ksi.ksi_code = ucode;
1112 	ksi.ksi_addr = (void *)addr;
1113 	ksi.ksi_trapno = type;
1114 	trapsignal(td, &ksi);
1115 out:
1116 
1117 	/*
1118 	 * Note: we should only get here if returning to user mode.
1119 	 */
1120 	userret(td, trapframe);
1121 	return (trapframe->pc);
1122 }
1123 
1124 #if !defined(SMP) && (defined(DDB) || defined(DEBUG))
1125 void
trapDump(char * msg)1126 trapDump(char *msg)
1127 {
1128 	register_t s;
1129 	int i;
1130 
1131 	s = intr_disable();
1132 	printf("trapDump(%s)\n", msg);
1133 	for (i = 0; i < TRAPSIZE; i++) {
1134 		if (trp == trapdebug) {
1135 			trp = &trapdebug[TRAPSIZE - 1];
1136 		} else {
1137 			trp--;
1138 		}
1139 
1140 		if (trp->cause == 0)
1141 			break;
1142 
1143 		printf("%s: ADR %jx PC %jx CR %jx SR %jx\n",
1144 		    trap_type[(trp->cause & MIPS_CR_EXC_CODE) >>
1145 			MIPS_CR_EXC_CODE_SHIFT],
1146 		    (intmax_t)trp->vadr, (intmax_t)trp->pc,
1147 		    (intmax_t)trp->cause, (intmax_t)trp->status);
1148 
1149 		printf("   RA %jx SP %jx code %d\n", (intmax_t)trp->ra,
1150 		    (intmax_t)trp->sp, (int)trp->code);
1151 	}
1152 	intr_restore(s);
1153 }
1154 #endif
1155 
1156 
1157 /*
1158  * Return the resulting PC as if the branch was executed.
1159  */
1160 uintptr_t
MipsEmulateBranch(struct trapframe * framePtr,uintptr_t instPC,int fpcCSR,uintptr_t instptr)1161 MipsEmulateBranch(struct trapframe *framePtr, uintptr_t instPC, int fpcCSR,
1162     uintptr_t instptr)
1163 {
1164 	InstFmt inst;
1165 	register_t *regsPtr = (register_t *) framePtr;
1166 	uintptr_t retAddr = 0;
1167 	int condition;
1168 
1169 #define	GetBranchDest(InstPtr, inst) \
1170 	(InstPtr + 4 + ((short)inst.IType.imm << 2))
1171 
1172 
1173 	if (instptr) {
1174 		if (instptr < MIPS_KSEG0_START)
1175 			inst.word = fuword32((void *)instptr);
1176 		else
1177 			inst = *(InstFmt *) instptr;
1178 	} else {
1179 		if ((vm_offset_t)instPC < MIPS_KSEG0_START)
1180 			inst.word = fuword32((void *)instPC);
1181 		else
1182 			inst = *(InstFmt *) instPC;
1183 	}
1184 
1185 	switch ((int)inst.JType.op) {
1186 	case OP_SPECIAL:
1187 		switch ((int)inst.RType.func) {
1188 		case OP_JR:
1189 		case OP_JALR:
1190 			retAddr = regsPtr[inst.RType.rs];
1191 			break;
1192 
1193 		default:
1194 			retAddr = instPC + 4;
1195 			break;
1196 		}
1197 		break;
1198 
1199 	case OP_BCOND:
1200 		switch ((int)inst.IType.rt) {
1201 		case OP_BLTZ:
1202 		case OP_BLTZL:
1203 		case OP_BLTZAL:
1204 		case OP_BLTZALL:
1205 			if ((int)(regsPtr[inst.RType.rs]) < 0)
1206 				retAddr = GetBranchDest(instPC, inst);
1207 			else
1208 				retAddr = instPC + 8;
1209 			break;
1210 
1211 		case OP_BGEZ:
1212 		case OP_BGEZL:
1213 		case OP_BGEZAL:
1214 		case OP_BGEZALL:
1215 			if ((int)(regsPtr[inst.RType.rs]) >= 0)
1216 				retAddr = GetBranchDest(instPC, inst);
1217 			else
1218 				retAddr = instPC + 8;
1219 			break;
1220 
1221 		case OP_TGEI:
1222 		case OP_TGEIU:
1223 		case OP_TLTI:
1224 		case OP_TLTIU:
1225 		case OP_TEQI:
1226 		case OP_TNEI:
1227 			retAddr = instPC + 4;	/* Like syscall... */
1228 			break;
1229 
1230 		default:
1231 			panic("MipsEmulateBranch: Bad branch cond");
1232 		}
1233 		break;
1234 
1235 	case OP_J:
1236 	case OP_JAL:
1237 		retAddr = (inst.JType.target << 2) |
1238 		    ((unsigned)(instPC + 4) & 0xF0000000);
1239 		break;
1240 
1241 	case OP_BEQ:
1242 	case OP_BEQL:
1243 		if (regsPtr[inst.RType.rs] == regsPtr[inst.RType.rt])
1244 			retAddr = GetBranchDest(instPC, inst);
1245 		else
1246 			retAddr = instPC + 8;
1247 		break;
1248 
1249 	case OP_BNE:
1250 	case OP_BNEL:
1251 		if (regsPtr[inst.RType.rs] != regsPtr[inst.RType.rt])
1252 			retAddr = GetBranchDest(instPC, inst);
1253 		else
1254 			retAddr = instPC + 8;
1255 		break;
1256 
1257 	case OP_BLEZ:
1258 	case OP_BLEZL:
1259 		if ((int)(regsPtr[inst.RType.rs]) <= 0)
1260 			retAddr = GetBranchDest(instPC, inst);
1261 		else
1262 			retAddr = instPC + 8;
1263 		break;
1264 
1265 	case OP_BGTZ:
1266 	case OP_BGTZL:
1267 		if ((int)(regsPtr[inst.RType.rs]) > 0)
1268 			retAddr = GetBranchDest(instPC, inst);
1269 		else
1270 			retAddr = instPC + 8;
1271 		break;
1272 
1273 	case OP_COP1:
1274 		switch (inst.RType.rs) {
1275 		case OP_BCx:
1276 		case OP_BCy:
1277 			if ((inst.RType.rt & COPz_BC_TF_MASK) == COPz_BC_TRUE)
1278 				condition = fpcCSR & MIPS_FPU_COND_BIT;
1279 			else
1280 				condition = !(fpcCSR & MIPS_FPU_COND_BIT);
1281 			if (condition)
1282 				retAddr = GetBranchDest(instPC, inst);
1283 			else
1284 				retAddr = instPC + 8;
1285 			break;
1286 
1287 		default:
1288 			retAddr = instPC + 4;
1289 		}
1290 		break;
1291 
1292 	default:
1293 		retAddr = instPC + 4;
1294 	}
1295 	return (retAddr);
1296 }
1297 
1298 static void
log_frame_dump(struct trapframe * frame)1299 log_frame_dump(struct trapframe *frame)
1300 {
1301 	log(LOG_ERR, "Trapframe Register Dump:\n");
1302 	log(LOG_ERR, "\tzero: %#jx\tat: %#jx\tv0: %#jx\tv1: %#jx\n",
1303 	    (intmax_t)0, (intmax_t)frame->ast, (intmax_t)frame->v0, (intmax_t)frame->v1);
1304 
1305 	log(LOG_ERR, "\ta0: %#jx\ta1: %#jx\ta2: %#jx\ta3: %#jx\n",
1306 	    (intmax_t)frame->a0, (intmax_t)frame->a1, (intmax_t)frame->a2, (intmax_t)frame->a3);
1307 
1308 #if defined(__mips_n32) || defined(__mips_n64)
1309 	log(LOG_ERR, "\ta4: %#jx\ta5: %#jx\ta6: %#jx\ta6: %#jx\n",
1310 	    (intmax_t)frame->a4, (intmax_t)frame->a5, (intmax_t)frame->a6, (intmax_t)frame->a7);
1311 
1312 	log(LOG_ERR, "\tt0: %#jx\tt1: %#jx\tt2: %#jx\tt3: %#jx\n",
1313 	    (intmax_t)frame->t0, (intmax_t)frame->t1, (intmax_t)frame->t2, (intmax_t)frame->t3);
1314 #else
1315 	log(LOG_ERR, "\tt0: %#jx\tt1: %#jx\tt2: %#jx\tt3: %#jx\n",
1316 	    (intmax_t)frame->t0, (intmax_t)frame->t1, (intmax_t)frame->t2, (intmax_t)frame->t3);
1317 
1318 	log(LOG_ERR, "\tt4: %#jx\tt5: %#jx\tt6: %#jx\tt7: %#jx\n",
1319 	    (intmax_t)frame->t4, (intmax_t)frame->t5, (intmax_t)frame->t6, (intmax_t)frame->t7);
1320 #endif
1321 	log(LOG_ERR, "\tt8: %#jx\tt9: %#jx\ts0: %#jx\ts1: %#jx\n",
1322 	    (intmax_t)frame->t8, (intmax_t)frame->t9, (intmax_t)frame->s0, (intmax_t)frame->s1);
1323 
1324 	log(LOG_ERR, "\ts2: %#jx\ts3: %#jx\ts4: %#jx\ts5: %#jx\n",
1325 	    (intmax_t)frame->s2, (intmax_t)frame->s3, (intmax_t)frame->s4, (intmax_t)frame->s5);
1326 
1327 	log(LOG_ERR, "\ts6: %#jx\ts7: %#jx\tk0: %#jx\tk1: %#jx\n",
1328 	    (intmax_t)frame->s6, (intmax_t)frame->s7, (intmax_t)frame->k0, (intmax_t)frame->k1);
1329 
1330 	log(LOG_ERR, "\tgp: %#jx\tsp: %#jx\ts8: %#jx\tra: %#jx\n",
1331 	    (intmax_t)frame->gp, (intmax_t)frame->sp, (intmax_t)frame->s8, (intmax_t)frame->ra);
1332 
1333 	log(LOG_ERR, "\tsr: %#jx\tmullo: %#jx\tmulhi: %#jx\tbadvaddr: %#jx\n",
1334 	    (intmax_t)frame->sr, (intmax_t)frame->mullo, (intmax_t)frame->mulhi, (intmax_t)frame->badvaddr);
1335 
1336 	log(LOG_ERR, "\tcause: %#jx\tpc: %#jx\n",
1337 	    (intmax_t)frame->cause, (intmax_t)frame->pc);
1338 }
1339 
1340 #ifdef TRAP_DEBUG
1341 static void
trap_frame_dump(struct trapframe * frame)1342 trap_frame_dump(struct trapframe *frame)
1343 {
1344 	printf("Trapframe Register Dump:\n");
1345 	printf("\tzero: %#jx\tat: %#jx\tv0: %#jx\tv1: %#jx\n",
1346 	    (intmax_t)0, (intmax_t)frame->ast, (intmax_t)frame->v0, (intmax_t)frame->v1);
1347 
1348 	printf("\ta0: %#jx\ta1: %#jx\ta2: %#jx\ta3: %#jx\n",
1349 	    (intmax_t)frame->a0, (intmax_t)frame->a1, (intmax_t)frame->a2, (intmax_t)frame->a3);
1350 #if defined(__mips_n32) || defined(__mips_n64)
1351 	printf("\ta4: %#jx\ta5: %#jx\ta6: %#jx\ta7: %#jx\n",
1352 	    (intmax_t)frame->a4, (intmax_t)frame->a5, (intmax_t)frame->a6, (intmax_t)frame->a7);
1353 
1354 	printf("\tt0: %#jx\tt1: %#jx\tt2: %#jx\tt3: %#jx\n",
1355 	    (intmax_t)frame->t0, (intmax_t)frame->t1, (intmax_t)frame->t2, (intmax_t)frame->t3);
1356 #else
1357 	printf("\tt0: %#jx\tt1: %#jx\tt2: %#jx\tt3: %#jx\n",
1358 	    (intmax_t)frame->t0, (intmax_t)frame->t1, (intmax_t)frame->t2, (intmax_t)frame->t3);
1359 
1360 	printf("\tt4: %#jx\tt5: %#jx\tt6: %#jx\tt7: %#jx\n",
1361 	    (intmax_t)frame->t4, (intmax_t)frame->t5, (intmax_t)frame->t6, (intmax_t)frame->t7);
1362 #endif
1363 	printf("\tt8: %#jx\tt9: %#jx\ts0: %#jx\ts1: %#jx\n",
1364 	    (intmax_t)frame->t8, (intmax_t)frame->t9, (intmax_t)frame->s0, (intmax_t)frame->s1);
1365 
1366 	printf("\ts2: %#jx\ts3: %#jx\ts4: %#jx\ts5: %#jx\n",
1367 	    (intmax_t)frame->s2, (intmax_t)frame->s3, (intmax_t)frame->s4, (intmax_t)frame->s5);
1368 
1369 	printf("\ts6: %#jx\ts7: %#jx\tk0: %#jx\tk1: %#jx\n",
1370 	    (intmax_t)frame->s6, (intmax_t)frame->s7, (intmax_t)frame->k0, (intmax_t)frame->k1);
1371 
1372 	printf("\tgp: %#jx\tsp: %#jx\ts8: %#jx\tra: %#jx\n",
1373 	    (intmax_t)frame->gp, (intmax_t)frame->sp, (intmax_t)frame->s8, (intmax_t)frame->ra);
1374 
1375 	printf("\tsr: %#jx\tmullo: %#jx\tmulhi: %#jx\tbadvaddr: %#jx\n",
1376 	    (intmax_t)frame->sr, (intmax_t)frame->mullo, (intmax_t)frame->mulhi, (intmax_t)frame->badvaddr);
1377 
1378 	printf("\tcause: %#jx\tpc: %#jx\n",
1379 	    (intmax_t)frame->cause, (intmax_t)frame->pc);
1380 }
1381 
1382 #endif
1383 
1384 
1385 static void
get_mapping_info(vm_offset_t va,pd_entry_t ** pdepp,pt_entry_t ** ptepp)1386 get_mapping_info(vm_offset_t va, pd_entry_t **pdepp, pt_entry_t **ptepp)
1387 {
1388 	pt_entry_t *ptep;
1389 	pd_entry_t *pdep;
1390 	struct proc *p = curproc;
1391 
1392 	pdep = (&(p->p_vmspace->vm_pmap.pm_segtab[(va >> SEGSHIFT) & (NPDEPG - 1)]));
1393 	if (*pdep)
1394 		ptep = pmap_pte(&p->p_vmspace->vm_pmap, va);
1395 	else
1396 		ptep = (pt_entry_t *)0;
1397 
1398 	*pdepp = pdep;
1399 	*ptepp = ptep;
1400 }
1401 
1402 static void
log_illegal_instruction(const char * msg,struct trapframe * frame)1403 log_illegal_instruction(const char *msg, struct trapframe *frame)
1404 {
1405 	pt_entry_t *ptep;
1406 	pd_entry_t *pdep;
1407 	unsigned int *addr, instr[4];
1408 	struct thread *td;
1409 	struct proc *p;
1410 	register_t pc;
1411 
1412 	td = curthread;
1413 	p = td->td_proc;
1414 
1415 #ifdef SMP
1416 	printf("cpuid = %d\n", PCPU_GET(cpuid));
1417 #endif
1418 	pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0);
1419 	log(LOG_ERR, "%s: pid %d tid %ld (%s), uid %d: pc %#jx ra %#jx\n",
1420 	    msg, p->p_pid, (long)td->td_tid, p->p_comm,
1421 	    p->p_ucred ? p->p_ucred->cr_uid : -1,
1422 	    (intmax_t)pc,
1423 	    (intmax_t)frame->ra);
1424 
1425 	/* log registers in trap frame */
1426 	log_frame_dump(frame);
1427 
1428 	get_mapping_info((vm_offset_t)pc, &pdep, &ptep);
1429 
1430 	/*
1431 	 * Dump a few words around faulting instruction, if the addres is
1432 	 * valid.
1433 	 */
1434 	addr = (unsigned int *)(intptr_t)pc;
1435 	if ((pc & 3) == 0 && copyin(addr, instr, sizeof(instr)) == 0) {
1436 		/* dump page table entry for faulting instruction */
1437 		log(LOG_ERR, "Page table info for pc address %#jx: pde = %p, pte = %#jx\n",
1438 		    (intmax_t)pc, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0));
1439 
1440 		log(LOG_ERR, "Dumping 4 words starting at pc address %p: \n",
1441 		    addr);
1442 		log(LOG_ERR, "%08x %08x %08x %08x\n",
1443 		    instr[0], instr[1], instr[2], instr[3]);
1444 	} else {
1445 		log(LOG_ERR, "pc address %#jx is inaccessible, pde = %p, pte = %#jx\n",
1446 		    (intmax_t)pc, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0));
1447 	}
1448 }
1449 
1450 static void
log_bad_page_fault(char * msg,struct trapframe * frame,int trap_type)1451 log_bad_page_fault(char *msg, struct trapframe *frame, int trap_type)
1452 {
1453 	pt_entry_t *ptep;
1454 	pd_entry_t *pdep;
1455 	unsigned int *addr, instr[4];
1456 	struct thread *td;
1457 	struct proc *p;
1458 	char *read_or_write;
1459 	register_t pc;
1460 
1461 	trap_type &= ~T_USER;
1462 
1463 	td = curthread;
1464 	p = td->td_proc;
1465 
1466 #ifdef SMP
1467 	printf("cpuid = %d\n", PCPU_GET(cpuid));
1468 #endif
1469 	switch (trap_type) {
1470 	case T_TLB_MOD:
1471 	case T_TLB_ST_MISS:
1472 	case T_ADDR_ERR_ST:
1473 		read_or_write = "write";
1474 		break;
1475 	case T_TLB_LD_MISS:
1476 	case T_ADDR_ERR_LD:
1477 	case T_BUS_ERR_IFETCH:
1478 		read_or_write = "read";
1479 		break;
1480 	default:
1481 		read_or_write = "unknown";
1482 	}
1483 
1484 	pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0);
1485 	log(LOG_ERR, "%s: pid %d tid %ld (%s), uid %d: pc %#jx got a %s fault "
1486 	    "(type %#x) at %#jx\n",
1487 	    msg, p->p_pid, (long)td->td_tid, p->p_comm,
1488 	    p->p_ucred ? p->p_ucred->cr_uid : -1,
1489 	    (intmax_t)pc,
1490 	    read_or_write,
1491 	    trap_type,
1492 	    (intmax_t)frame->badvaddr);
1493 
1494 	/* log registers in trap frame */
1495 	log_frame_dump(frame);
1496 
1497 	get_mapping_info((vm_offset_t)pc, &pdep, &ptep);
1498 
1499 	/*
1500 	 * Dump a few words around faulting instruction, if the addres is
1501 	 * valid.
1502 	 */
1503 	addr = (unsigned int *)(intptr_t)pc;
1504 	if ((pc & 3) == 0 && pc != frame->badvaddr &&
1505 	    trap_type != T_BUS_ERR_IFETCH &&
1506 	    copyin((caddr_t)(intptr_t)pc, instr, sizeof(instr)) == 0) {
1507 		/* dump page table entry for faulting instruction */
1508 		log(LOG_ERR, "Page table info for pc address %#jx: pde = %p, pte = %#jx\n",
1509 		    (intmax_t)pc, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0));
1510 
1511 		log(LOG_ERR, "Dumping 4 words starting at pc address %p: \n",
1512 		    addr);
1513 		log(LOG_ERR, "%08x %08x %08x %08x\n",
1514 		    instr[0], instr[1], instr[2], instr[3]);
1515 	} else {
1516 		log(LOG_ERR, "pc address %#jx is inaccessible, pde = %p, pte = %#jx\n",
1517 		    (intmax_t)pc, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0));
1518 	}
1519 
1520 	get_mapping_info((vm_offset_t)frame->badvaddr, &pdep, &ptep);
1521 	log(LOG_ERR, "Page table info for bad address %#jx: pde = %p, pte = %#jx\n",
1522 	    (intmax_t)frame->badvaddr, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0));
1523 }
1524 
1525 
1526 /*
1527  * Unaligned load/store emulation
1528  */
1529 static int
mips_unaligned_load_store(struct trapframe * frame,int mode,register_t addr,register_t pc)1530 mips_unaligned_load_store(struct trapframe *frame, int mode, register_t addr, register_t pc)
1531 {
1532 	register_t *reg = (register_t *) frame;
1533 	u_int32_t inst = *((u_int32_t *)(intptr_t)pc);
1534 	register_t value_msb, value;
1535 	unsigned size;
1536 
1537 	/*
1538 	 * ADDR_ERR faults have higher priority than TLB
1539 	 * Miss faults.  Therefore, it is necessary to
1540 	 * verify that the faulting address is a valid
1541 	 * virtual address within the process' address space
1542 	 * before trying to emulate the unaligned access.
1543 	 */
1544 	switch (MIPS_INST_OPCODE(inst)) {
1545 	case OP_LHU: case OP_LH:
1546 	case OP_SH:
1547 		size = 2;
1548 		break;
1549 	case OP_LWU: case OP_LW:
1550 	case OP_SW:
1551 		size = 4;
1552 		break;
1553 	case OP_LD:
1554 	case OP_SD:
1555 		size = 8;
1556 		break;
1557 	default:
1558 		printf("%s: unhandled opcode in address error: %#x\n", __func__, MIPS_INST_OPCODE(inst));
1559 		return (0);
1560 	}
1561 
1562 	if (!useracc((void *)rounddown2((vm_offset_t)addr, size), size * 2, mode))
1563 		return (0);
1564 
1565 	/*
1566 	 * XXX
1567 	 * Handle LL/SC LLD/SCD.
1568 	 */
1569 	switch (MIPS_INST_OPCODE(inst)) {
1570 	case OP_LHU:
1571 		KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction."));
1572 		lbu_macro(value_msb, addr);
1573 		addr += 1;
1574 		lbu_macro(value, addr);
1575 		value |= value_msb << 8;
1576 		reg[MIPS_INST_RT(inst)] = value;
1577 		return (MIPS_LHU_ACCESS);
1578 
1579 	case OP_LH:
1580 		KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction."));
1581 		lb_macro(value_msb, addr);
1582 		addr += 1;
1583 		lbu_macro(value, addr);
1584 		value |= value_msb << 8;
1585 		reg[MIPS_INST_RT(inst)] = value;
1586 		return (MIPS_LH_ACCESS);
1587 
1588 	case OP_LWU:
1589 		KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction."));
1590 		lwl_macro(value, addr);
1591 		addr += 3;
1592 		lwr_macro(value, addr);
1593 		value &= 0xffffffff;
1594 		reg[MIPS_INST_RT(inst)] = value;
1595 		return (MIPS_LWU_ACCESS);
1596 
1597 	case OP_LW:
1598 		KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction."));
1599 		lwl_macro(value, addr);
1600 		addr += 3;
1601 		lwr_macro(value, addr);
1602 		reg[MIPS_INST_RT(inst)] = value;
1603 		return (MIPS_LW_ACCESS);
1604 
1605 #if defined(__mips_n32) || defined(__mips_n64)
1606 	case OP_LD:
1607 		KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction."));
1608 		ldl_macro(value, addr);
1609 		addr += 7;
1610 		ldr_macro(value, addr);
1611 		reg[MIPS_INST_RT(inst)] = value;
1612 		return (MIPS_LD_ACCESS);
1613 #endif
1614 
1615 	case OP_SH:
1616 		KASSERT(mode == VM_PROT_WRITE, ("access mode must be write for store instruction."));
1617 		value = reg[MIPS_INST_RT(inst)];
1618 		value_msb = value >> 8;
1619 		sb_macro(value_msb, addr);
1620 		addr += 1;
1621 		sb_macro(value, addr);
1622 		return (MIPS_SH_ACCESS);
1623 
1624 	case OP_SW:
1625 		KASSERT(mode == VM_PROT_WRITE, ("access mode must be write for store instruction."));
1626 		value = reg[MIPS_INST_RT(inst)];
1627 		swl_macro(value, addr);
1628 		addr += 3;
1629 		swr_macro(value, addr);
1630 		return (MIPS_SW_ACCESS);
1631 
1632 #if defined(__mips_n32) || defined(__mips_n64)
1633 	case OP_SD:
1634 		KASSERT(mode == VM_PROT_WRITE, ("access mode must be write for store instruction."));
1635 		value = reg[MIPS_INST_RT(inst)];
1636 		sdl_macro(value, addr);
1637 		addr += 7;
1638 		sdr_macro(value, addr);
1639 		return (MIPS_SD_ACCESS);
1640 #endif
1641 	}
1642 	panic("%s: should not be reached.", __func__);
1643 }
1644 
1645 
1646 /*
1647  * XXX TODO: SMP?
1648  */
1649 static struct timeval unaligned_lasterr;
1650 static int unaligned_curerr;
1651 
1652 static int unaligned_pps_log_limit = 4;
1653 
1654 SYSCTL_INT(_machdep, OID_AUTO, unaligned_log_pps_limit, CTLFLAG_RWTUN,
1655     &unaligned_pps_log_limit, 0,
1656     "limit number of userland unaligned log messages per second");
1657 
1658 static int
emulate_unaligned_access(struct trapframe * frame,int mode)1659 emulate_unaligned_access(struct trapframe *frame, int mode)
1660 {
1661 	register_t pc;
1662 	int access_type = 0;
1663 	struct thread *td = curthread;
1664 	struct proc *p = curproc;
1665 
1666 	pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0);
1667 
1668 	/*
1669 	 * Fall through if it's instruction fetch exception
1670 	 */
1671 	if (!((pc & 3) || (pc == frame->badvaddr))) {
1672 
1673 		/*
1674 		 * Handle unaligned load and store
1675 		 */
1676 
1677 		/*
1678 		 * Return access type if the instruction was emulated.
1679 		 * Otherwise restore pc and fall through.
1680 		 */
1681 		access_type = mips_unaligned_load_store(frame,
1682 		    mode, frame->badvaddr, pc);
1683 
1684 		if (access_type) {
1685 			if (DELAYBRANCH(frame->cause))
1686 				frame->pc = MipsEmulateBranch(frame, frame->pc,
1687 				    0, 0);
1688 			else
1689 				frame->pc += 4;
1690 
1691 			if (ppsratecheck(&unaligned_lasterr,
1692 			    &unaligned_curerr, unaligned_pps_log_limit)) {
1693 				/* XXX TODO: keep global/tid/pid counters? */
1694 				log(LOG_INFO,
1695 				    "Unaligned %s: pid=%ld (%s), tid=%ld, "
1696 				    "pc=%#jx, badvaddr=%#jx\n",
1697 				    access_name[access_type - 1],
1698 				    (long) p->p_pid,
1699 				    p->p_comm,
1700 				    (long) td->td_tid,
1701 				    (intmax_t)pc,
1702 				    (intmax_t)frame->badvaddr);
1703 			}
1704 		}
1705 	}
1706 	return access_type;
1707 }
1708