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