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