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