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