xref: /netbsd-src/sys/arch/atari/atari/trap.c (revision 68fa58437753598de948829082f591c269b48777)
1 /*	$NetBSD: trap.c,v 1.119 2023/10/05 19:41:03 ad Exp $	*/
2 
3 /*
4  * Copyright (c) 1988 University of Utah.
5  * Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
6  * All rights reserved.
7  *
8  * This code is derived from software contributed to Berkeley by
9  * the Systems Programming Group of the University of Utah Computer
10  * Science Department.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  * 3. Neither the name of the University nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  *
36  * from: Utah $Hdr: trap.c 1.32 91/04/06$
37  *
38  *	@(#)trap.c	7.15 (Berkeley) 8/2/91
39  */
40 
41 #include <sys/cdefs.h>
42 __KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.119 2023/10/05 19:41:03 ad Exp $");
43 
44 #include "opt_ddb.h"
45 #include "opt_execfmt.h"
46 #include "opt_kgdb.h"
47 #include "opt_compat_sunos.h"
48 #include "opt_fpu_emulate.h"
49 #include "opt_m68k_arch.h"
50 
51 #include <sys/param.h>
52 #include <sys/systm.h>
53 #include <sys/proc.h>
54 #include <sys/acct.h>
55 #include <sys/kernel.h>
56 #include <sys/signalvar.h>
57 #include <sys/resourcevar.h>
58 #include <sys/syslog.h>
59 #include <sys/syscall.h>
60 #include <sys/userret.h>
61 #include <sys/kauth.h>
62 
63 #include <uvm/uvm_extern.h>
64 
65 #include <m68k/cpu.h>
66 #include <m68k/cacheops.h>
67 
68 #include <machine/psl.h>
69 #include <machine/trap.h>
70 #include <machine/cpu.h>
71 #include <machine/pcb.h>
72 #include <machine/reg.h>
73 #include <machine/pte.h>
74 #ifdef DDB
75 #include <machine/db_machdep.h>
76 #endif
77 
78 #ifdef DEBUG
79 #include <dev/cons.h>  /* cngetc() */
80 #endif
81 
82 #ifdef FPU_EMULATE
83 #include <m68k/fpe/fpu_emulate.h>
84 #endif
85 
86 #ifdef COMPAT_SUNOS
87 #include <compat/sunos/sunos_syscall.h>
88 extern struct emul emul_sunos;
89 #endif
90 
91 void trap(struct frame *, int, u_int, u_int);
92 
93 static void panictrap(int, u_int, u_int, struct frame *);
94 static void trapcpfault(struct lwp *, struct frame *, int);
95 static void userret(struct lwp *, struct frame *fp, u_quad_t, u_int, int);
96 
97 const char *trap_type[] = {
98 	"Bus error",
99 	"Address error",
100 	"Illegal instruction",
101 	"Zero divide",
102 	"CHK instruction",
103 	"TRAPV instruction",
104 	"Privilege violation",
105 	"Trace trap",
106 	"MMU fault",
107 	"SSIR trap",
108 	"Format error",
109 	"68881 exception",
110 	"Coprocessor violation",
111 	"Async system trap"
112 };
113 int	trap_types = sizeof trap_type / sizeof trap_type[0];
114 
115 /*
116  * Size of various exception stack frames (minus the standard 8 bytes)
117  */
118 short	exframesize[] = {
119 	FMT0SIZE,	/* type 0 - normal (68020/030/040/060) */
120 	FMT1SIZE,	/* type 1 - throwaway (68020/030/040) */
121 	FMT2SIZE,	/* type 2 - normal 6-word (68020/030/040/060) */
122 	FMT3SIZE,	/* type 3 - FP post-instruction (68040/060) */
123 	FMT4SIZE,	/* type 4 - access error/fp disabled (68060) */
124 	-1, -1,		/* type 5-6 - undefined */
125 	FMT7SIZE,	/* type 7 - access error (68040) */
126 	58,		/* type 8 - bus fault (68010) */
127 	FMT9SIZE,	/* type 9 - coprocessor mid-instruction (68020/030) */
128 	FMTASIZE,	/* type A - short bus fault (68020/030) */
129 	FMTBSIZE,	/* type B - long bus fault (68020/030) */
130 	-1, -1, -1, -1	/* type C-F - undefined */
131 };
132 
133 #ifdef M68060
134 #define	KDFAULT_060(c)	(cputype == CPU_68060 && ((c) & FSLW_TM_SV))
135 #define	WRFAULT_060(c)	(cputype == CPU_68060 && ((c) & FSLW_RW_W))
136 #else
137 #define	KDFAULT_060(c)	0
138 #define	WRFAULT_060(c)	0
139 #endif
140 
141 #ifdef M68040
142 #define	KDFAULT_040(c)	(cputype == CPU_68040 && \
143 			 ((c) & SSW4_TMMASK) == SSW4_TMKD)
144 #define	WRFAULT_040(c)	(cputype == CPU_68040 && \
145 			 ((c) & (SSW4_LK|SSW4_RW)) != SSW4_RW)
146 #else
147 #define	KDFAULT_040(c)	0
148 #define	WRFAULT_040(c)	0
149 #endif
150 
151 #if defined(M68030) || defined(M68020)
152 #define	KDFAULT_OTH(c)	(cputype <= CPU_68030 && \
153 			 ((c) & (SSW_DF|SSW_FCMASK)) == (SSW_DF|FC_SUPERD))
154 #define	WRFAULT_OTH(c)	(cputype <= CPU_68030 && \
155 			 (((c) & SSW_DF) != 0 && \
156 			 ((((c) & SSW_RW) == 0) || (((c) & SSW_RM) != 0))))
157 #else
158 #define	KDFAULT_OTH(c)	0
159 #define	WRFAULT_OTH(c)	0
160 #endif
161 
162 #define	KDFAULT(c)	(KDFAULT_060(c) || KDFAULT_040(c) || KDFAULT_OTH(c))
163 #define	WRFAULT(c)	(WRFAULT_060(c) || WRFAULT_040(c) || WRFAULT_OTH(c))
164 
165 #ifdef DEBUG
166 int mmudebug = 0;
167 int mmupid   = -1;
168 #define MDB_FOLLOW	1
169 #define MDB_WBFOLLOW	2
170 #define MDB_WBFAILED	4
171 #define MDB_ISPID(pid)	((pid) == mmupid)
172 #endif
173 
174 extern struct pcb *curpcb;
175 
176 /*
177  * trap and syscall both need the following work done before returning
178  * to user mode.
179  */
180 static inline void
userret(struct lwp * l,struct frame * fp,u_quad_t oticks,u_int faultaddr,int fromtrap)181 userret(struct lwp *l, struct frame *fp, u_quad_t oticks, u_int faultaddr, int fromtrap)
182 {
183 	struct proc *p = l->l_proc;
184 #ifdef M68040
185 	int sig;
186 	int beenhere = 0;
187 
188 again:
189 #endif
190 	/* Invoke MI userret code */
191 	mi_userret(l);
192 
193 	/*
194 	 * If profiling, charge system time to the trapped pc.
195 	 */
196 	if (p->p_stflag & PST_PROFIL) {
197 		extern int psratio;
198 
199 		addupc_task(l, fp->f_pc,
200 			    (int)(p->p_sticks - oticks) * psratio);
201 	}
202 #ifdef M68040
203 	/*
204 	 * Deal with user mode writebacks (from trap, or from sigreturn).
205 	 * If any writeback fails, go back and attempt signal delivery.
206 	 * unless we have already been here and attempted the writeback
207 	 * (e.g. bad address with user ignoring SIGSEGV).  In that case
208 	 * we just return to the user without successfully completing
209 	 * the writebacks.  Maybe we should just drop the sucker?
210 	 */
211 	if (cputype == CPU_68040 && fp->f_format == FMT7) {
212 		if (beenhere) {
213 #ifdef DEBUG
214 			if (mmudebug & MDB_WBFAILED)
215 				printf(fromtrap ?
216 		"pid %d(%s): writeback aborted, pc=%x, fa=%x\n" :
217 		"pid %d(%s): writeback aborted in sigreturn, pc=%x\n",
218 				    p->p_pid, p->p_comm, fp->f_pc, faultaddr);
219 #endif
220 		} else if ((sig = m68040_writeback(fp, fromtrap))) {
221 			ksiginfo_t ksi;
222 			beenhere = 1;
223 			oticks = p->p_sticks;
224 			(void)memset(&ksi, 0, sizeof(ksi));
225 			ksi.ksi_signo = sig;
226 			ksi.ksi_addr = (void *)faultaddr;
227 			ksi.ksi_code = BUS_OBJERR;
228 			trapsignal(l, &ksi);
229 			goto again;
230 		}
231 	}
232 #endif
233 }
234 
235 /*
236  * Used by the common m68k syscall() and child_return() functions.
237  * XXX: Temporary until all m68k ports share common trap()/userret() code.
238  */
239 void machine_userret(struct lwp *, struct frame *, u_quad_t);
240 
241 void
machine_userret(struct lwp * l,struct frame * f,u_quad_t t)242 machine_userret(struct lwp *l, struct frame *f, u_quad_t t)
243 {
244 
245 	userret(l, f, t, 0, 0);
246 }
247 
248 static void
panictrap(int type,u_int code,u_int v,struct frame * fp)249 panictrap(int type, u_int code, u_int v, struct frame *fp)
250 {
251 	int	s;
252 
253 	printf("trap type %d, code = %x, v = %x\n", type, code, v);
254 	printf("%s program counter = 0x%x\n",
255 			(type & T_USER) ? "user" : "kernel", fp->f_pc);
256 
257 	/*
258 	 * Let the kernel debugger see the trap frame that
259 	 * caused us to panic.  This is a convenience so
260 	 * one can see registers at the point of failure.
261 	 */
262 	s = splhigh();
263 #ifdef KGDB
264 	/* If connected, step or cont returns 1 */
265 	if (kgdb_trap(type, &fp))
266 		goto kgdb_cont;
267 #endif
268 #ifdef DDB
269 	(void)kdb_trap(type, (db_regs_t *)fp);
270 #endif
271 #ifdef KGDB
272 kgdb_cont:
273 #endif
274 	splx(s);
275 
276 	if (panicstr) {
277 		printf("Double panic\n");
278 #ifdef DEBUG
279 		/* XXX Should be a machine dependent hook */
280 		printf("(press a key)\n");
281 		cnpollc(1);
282 		(void)cngetc();
283 		cnpollc(0);
284 #endif
285 	}
286 
287 	regdump((struct trapframe *)fp, 128);
288 	DCIS(); /* XXX? push cache */
289 
290 	type &= ~T_USER;
291 	if ((u_int)type < trap_types)
292 		panic(trap_type[type]);
293 	panic("trap");
294 	/*NOTREACHED*/
295 }
296 
297 /*
298  * return to fault handler
299  */
300 static void
trapcpfault(struct lwp * l,struct frame * fp,int error)301 trapcpfault(struct lwp *l, struct frame *fp, int error)
302 {
303 	struct pcb *pcb = lwp_getpcb(l);
304 
305 	/*
306 	 * We have arranged to catch this fault in one of the
307 	 * copy to/from user space routines, set PC to return to
308 	 * indicated location and set flag informing buserror code
309 	 * that it may need to clean up stack frame.
310 	 */
311 	fp->f_stackadj = exframesize[fp->f_format];
312 	fp->f_format = fp->f_vector = 0;
313 	fp->f_pc = (int)pcb->pcb_onfault;
314 	fp->f_regs[D0] = error;
315 }
316 
317 /*
318  * Trap is called from locore to handle most types of processor traps,
319  * including events such as simulated software interrupts/AST's.
320  * System calls are broken out for efficiency.
321  */
322 /*ARGSUSED*/
323 void
trap(struct frame * fp,int type,u_int code,u_int v)324 trap(struct frame *fp, int type, u_int code, u_int v)
325 {
326 	struct lwp	*l;
327 	struct proc	*p;
328 	struct pcb	*pcb;
329 	ksiginfo_t ksi;
330 	u_quad_t	sticks;
331 
332 	l = curlwp;
333 	sticks = 0;
334 
335 	curcpu()->ci_data.cpu_ntrap++;
336 
337 	KSI_INIT_TRAP(&ksi);
338 	ksi.ksi_trap = type & ~T_USER;
339 
340 	p = l->l_proc;
341 	pcb = lwp_getpcb(l);
342 	KASSERT(pcb != NULL);
343 
344 	if (USERMODE(fp->f_sr)) {
345 		type |= T_USER;
346 		sticks = p->p_sticks;
347 		l->l_md.md_regs = fp->f_regs;
348 	}
349 	switch (type) {
350 	default:
351 		panictrap(type, code, v, fp);
352 	/*
353 	 * Kernel Bus error
354 	 */
355 	case T_BUSERR:
356 		if (pcb->pcb_onfault == 0)
357 			panictrap(type, code, v, fp);
358 		trapcpfault(l, fp, EFAULT);
359 		return;
360 	/*
361 	 * User Bus/Addr error.
362 	 */
363 	case T_BUSERR|T_USER:
364 	case T_ADDRERR|T_USER:
365 		ksi.ksi_addr = (void *)v;
366 		ksi.ksi_signo = SIGBUS;
367 		ksi.ksi_code = (type == (T_BUSERR|T_USER)) ?
368 			BUS_OBJERR : BUS_ADRERR;
369 		break;
370 
371 	/*
372 	 * Kernel coprocessor violation
373 	 */
374 	case T_COPERR:
375 		/*FALLTHROUGH*/
376 	/*
377 	 * Kernel/User format error
378 	 */
379 	case T_FMTERR|T_USER:	/* do all RTE errors come in as T_USER? */
380 	case T_FMTERR:
381 		/*
382 		 * The user has most likely trashed the RTE or FP state info
383 		 * in the stack frame of a signal handler.
384 		 */
385 		type |= T_USER;
386 #ifdef DEBUG
387 		printf("pid %d: kernel %s exception\n", p->p_pid,
388 		    type==T_COPERR ? "coprocessor" : "format");
389 #endif
390 		mutex_enter(p->p_lock);
391 		SIGACTION(p, SIGILL).sa_handler = SIG_DFL;
392 		sigdelset(&p->p_sigctx.ps_sigignore, SIGILL);
393 		sigdelset(&p->p_sigctx.ps_sigcatch, SIGILL);
394 		sigdelset(&l->l_sigmask, SIGILL);
395 		mutex_exit(p->p_lock);
396 
397 		ksi.ksi_signo = SIGILL;
398 		ksi.ksi_addr = (void *)(int)fp->f_format;
399 				/* XXX was ILL_RESAD_FAULT */
400 		ksi.ksi_code = (type == T_COPERR) ?
401 			ILL_COPROC : ILL_ILLOPC;
402 		break;
403 
404 	/*
405 	 * User coprocessor violation
406 	 */
407 	case T_COPERR|T_USER:
408 	/* XXX What is a proper response here? */
409 		ksi.ksi_signo = SIGFPE;
410 		ksi.ksi_code = FPE_FLTINV;
411 		break;
412 
413 	/*
414 	 * 6888x exceptions
415 	 */
416 	case T_FPERR|T_USER:
417 		/*
418 		 * We pass along the 68881 status register which locore
419 		 * stashed in code for us.
420 		 */
421 		ksi.ksi_signo = SIGFPE;
422 		ksi.ksi_code = fpsr2siginfocode(code);
423 		break;
424 
425 	/*
426 	 * Unimplemented FPU instructions/datatypes.
427 	 */
428 	case T_FPEMULI|T_USER:
429 	case T_FPEMULD|T_USER:
430 #ifdef FPU_EMULATE
431 		if (fpu_emulate(fp, &pcb->pcb_fpregs, &ksi) == 0)
432 			; /* XXX - Deal with tracing? (fp->f_sr & PSL_T) */
433 #else
434 		uprintf("pid %d killed: no floating point support.\n",
435 			p->p_pid);
436 		ksi.ksi_signo = SIGILL;
437 		ksi.ksi_code = ILL_ILLOPC;
438 #endif
439 		break;
440 
441 	/*
442 	 * FPU faults in supervisor mode.
443 	 */
444 	case T_FPEMULI:
445 	case T_FPEMULD: {
446 		extern int	*nofault;
447 
448 		if (nofault)	/* If we're probing. */
449 			longjmp((label_t *) nofault);
450 		panictrap(type, code, v, fp);
451 	}
452 
453 	/*
454 	 * User illegal/privileged inst fault
455 	 */
456 	case T_ILLINST|T_USER:
457 	case T_PRIVINST|T_USER:
458 		ksi.ksi_addr = (void *)(int)fp->f_format;
459 				/* XXX was ILL_PRIVIN_FAULT */
460 		ksi.ksi_signo = SIGILL;
461 		ksi.ksi_code = (type == (T_PRIVINST|T_USER)) ?
462 			ILL_PRVOPC : ILL_ILLOPC;
463 		break;
464 
465 	/*
466 	 * divde by zero, CHK/TRAPV inst
467 	 */
468 	case T_ZERODIV|T_USER:
469 		ksi.ksi_code = FPE_FLTDIV;
470 	case T_CHKINST|T_USER:
471 	case T_TRAPVINST|T_USER:
472 		ksi.ksi_addr = (void *)(int)fp->f_format;
473 		ksi.ksi_signo = SIGFPE;
474 		break;
475 	/*
476 	 * XXX: Trace traps are a nightmare.
477 	 *
478 	 *	HP-UX uses trap #1 for breakpoints,
479 	 *	NetBSD/m68k uses trap #2,
480 	 *	SUN 3.x uses trap #15,
481 	 *	DDB and KGDB use trap #15 (for kernel breakpoints;
482 	 *	handled elsewhere).
483 	 *
484 	 * NetBSD and HP-UX traps get mapped by locore.s into T_TRACE.
485 	 * SUN 3.x traps get passed through as T_TRAP15 and are not really
486 	 * supported yet.
487 	 *
488 	 * XXX: We should never get kernel-mode T_TRAP15
489 	 * XXX: because locore.s now gives them special treatment.
490 	 */
491 	case T_TRAP15:
492 		fp->f_sr &= ~PSL_T;
493 		return;
494 
495 	case T_TRACE|T_USER:
496 #ifdef COMPAT_SUNOS
497 		/*
498 		 * SunOS uses Trap #2 for a "CPU cache flush".
499 		 * Just flush the on-chip caches and return.
500 		 */
501 		if (p->p_emul == &emul_sunos) {
502 			ICIA();
503 			DCIU();
504 			return;
505 		}
506 #endif
507 		/* FALLTHROUGH */
508 	case T_TRACE:		/* tracing a trap instruction */
509 	case T_TRAP15|T_USER:
510 		fp->f_sr &= ~PSL_T;
511 		ksi.ksi_signo = SIGTRAP;
512 		break;
513 	/*
514 	 * Kernel AST (should not happen)
515 	 */
516 	case T_ASTFLT:
517 		panictrap(type, code, v, fp);
518 	/*
519 	 * User AST
520 	 */
521 	case T_ASTFLT|T_USER:
522 		astpending = 0;
523 		/*
524 		 * We check for software interrupts first.  This is because
525 		 * they are at a higher level than ASTs, and on a VAX would
526 		 * interrupt the AST.  We assume that if we are processing
527 		 * an AST that we must be at IPL0 so we don't bother to
528 		 * check.  Note that we ensure that we are at least at SIR
529 		 * IPL while processing the SIR.
530 		 */
531 		spl1();
532 		/*FALLTHROUGH*/
533 	/*
534 	 * Software interrupt
535 	 */
536 	case T_SSIR:
537 	case T_SSIR|T_USER:
538 		/*
539 		 * If this was not an AST trap, we are all done.
540 		 */
541 		if (type != (T_ASTFLT|T_USER)) {
542 			curcpu()->ci_data.cpu_ntrap--;
543 			return;
544 		}
545 		spl0();
546 		if (l->l_pflag & LP_OWEUPC) {
547 			l->l_pflag &= ~LP_OWEUPC;
548 			ADDUPROF(l);
549 		}
550 		goto out;
551 	/*
552 	 * Kernel/User page fault
553 	 */
554 	case T_MMUFLT:
555 	case T_MMUFLT|T_USER:	/* page fault */
556 	    {
557 		vaddr_t	va;
558 		struct vmspace *vm = p->p_vmspace;
559 		struct vm_map *map;
560 		void *onfault;
561 		int rv;
562 		vm_prot_t ftype;
563 		extern struct vm_map *kernel_map;
564 
565 		onfault = pcb->pcb_onfault;
566 
567 #ifdef DEBUG
568 		if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid))
569 		printf("trap: T_MMUFLT pid=%d, code=%x, v=%x, pc=%x, sr=%x\n",
570 		       p ? p->p_pid : -1, code, v, fp->f_pc, fp->f_sr);
571 #endif
572 		/*
573 		 * It is only a kernel address space fault iff:
574 		 *	1. (type & T_USER) == 0  and
575 		 *	2. pcb_onfault not set or
576 		 *	3. pcb_onfault set but supervisor space data fault
577 		 * The last can occur during an exec() copyin where the
578 		 * argument space is lazy-allocated.
579 		 */
580 		if (type == T_MMUFLT && (onfault == 0 || KDFAULT(code)))
581 			map = kernel_map;
582 		else {
583 			map = vm ? &vm->vm_map : kernel_map;
584 		}
585 
586 		if (WRFAULT(code))
587 			ftype = VM_PROT_WRITE;
588 		else
589 			ftype = VM_PROT_READ;
590 		va = trunc_page(v);
591 #ifdef DEBUG
592 		if (map == kernel_map && va == 0) {
593 			printf("trap: bad kernel access at %x\n", v);
594 			panictrap(type, code, v, fp);
595 		}
596 #endif
597 		pcb->pcb_onfault = NULL;
598 		rv = uvm_fault(map, va, ftype);
599 		pcb->pcb_onfault = onfault;
600 #ifdef DEBUG
601 		if (rv && MDB_ISPID(p->p_pid))
602 			printf("vm_fault(%p, %lx, %x) -> %x\n",
603 			       map, va, ftype, rv);
604 #endif
605 		/*
606 		 * If this was a stack access we keep track of the maximum
607 		 * accessed stack size.  Also, if vm_fault gets a protection
608 		 * failure it is due to accessing the stack region outside
609 		 * the current limit and we need to reflect that as an access
610 		 * error.
611 		 */
612 		if (rv == 0) {
613 			if (map != kernel_map && (void *)va >= vm->vm_maxsaddr)
614 				uvm_grow(p, va);
615 
616 			if (type == T_MMUFLT) {
617 #ifdef M68040
618 				if (cputype == CPU_68040)
619 					(void) m68040_writeback(fp, 1);
620 #endif
621 				return;
622 			}
623 			goto out;
624 		}
625 		if (rv == EACCES) {
626 			ksi.ksi_code = SEGV_ACCERR;
627 			rv = EFAULT;
628 		} else
629 			ksi.ksi_code = SEGV_MAPERR;
630 		if (type == T_MMUFLT) {
631 			if (onfault) {
632 				trapcpfault(l, fp, rv);
633 				return;
634 			}
635 			printf("\nvm_fault(%p, %lx, %x) -> %x\n",
636 			       map, va, ftype, rv);
637 			printf("  type %x, code [mmu,,ssw]: %x\n",
638 			       type, code);
639 			panictrap(type, code, v, fp);
640 		}
641 		ksi.ksi_addr = (void *)v;
642 		switch (rv) {
643 		case ENOMEM:
644 			printf("UVM: pid %d (%s), uid %d killed: out of swap\n",
645 			       p->p_pid, p->p_comm,
646 			       l->l_cred ?
647 			       kauth_cred_geteuid(l->l_cred) : -1);
648 			ksi.ksi_signo = SIGKILL;
649 			break;
650 		case EINVAL:
651 			ksi.ksi_signo = SIGBUS;
652 			ksi.ksi_code = BUS_ADRERR;
653 			break;
654 		case EACCES:
655 			ksi.ksi_signo = SIGSEGV;
656 			ksi.ksi_code = SEGV_ACCERR;
657 			break;
658 		default:
659 			ksi.ksi_signo = SIGSEGV;
660 			ksi.ksi_code = SEGV_MAPERR;
661 			break;
662 		}
663 		break;
664 	    }
665 	}
666 
667 	if (ksi.ksi_signo)
668 		trapsignal(l, &ksi);
669 	if ((type & T_USER) == 0)
670 		return;
671 out:
672 	userret(l, fp, sticks, v, 1);
673 }
674