6583 remove whole-process swapping
1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * Copyright (c) 2012 Joyent, Inc. All rights reserved. 29 */ 30 31 #include <sys/mmu.h> 32 #include <sys/systm.h> 33 #include <sys/trap.h> 34 #include <sys/machtrap.h> 35 #include <sys/vtrace.h> 36 #include <sys/prsystm.h> 37 #include <sys/archsystm.h> 38 #include <sys/machsystm.h> 39 #include <sys/fpu/fpusystm.h> 40 #include <sys/tnf.h> 41 #include <sys/tnf_probe.h> 42 #include <sys/simulate.h> 43 #include <sys/ftrace.h> 44 #include <sys/ontrap.h> 45 #include <sys/kcpc.h> 46 #include <sys/kobj.h> 47 #include <sys/procfs.h> 48 #include <sys/sun4asi.h> 49 #include <sys/sdt.h> 50 #include <sys/fpras.h> 51 #include <sys/contract/process_impl.h> 52 53 #ifdef TRAPTRACE 54 #include <sys/traptrace.h> 55 #endif 56 57 int tudebug = 0; 58 static int tudebugbpt = 0; 59 static int tudebugfpe = 0; 60 61 static int alignfaults = 0; 62 63 #if defined(TRAPDEBUG) || defined(lint) 64 static int lodebug = 0; 65 #else 66 #define lodebug 0 67 #endif /* defined(TRAPDEBUG) || defined(lint) */ 68 69 70 int vis1_partial_support(struct regs *rp, k_siginfo_t *siginfo, uint_t *fault); 71 #pragma weak vis1_partial_support 72 73 void showregs(unsigned, struct regs *, caddr_t, uint_t); 74 #pragma weak showregs 75 76 void trap_async_hwerr(void); 77 #pragma weak trap_async_hwerr 78 79 void trap_async_berr_bto(int, struct regs *); 80 #pragma weak trap_async_berr_bto 81 82 static enum seg_rw get_accesstype(struct regs *); 83 static int nfload(struct regs *, int *); 84 static int swap_nc(struct regs *, int); 85 static int ldstub_nc(struct regs *, int); 86 void trap_cleanup(struct regs *, uint_t, k_siginfo_t *, int); 87 void trap_rtt(void); 88 89 static int 90 die(unsigned type, struct regs *rp, caddr_t addr, uint_t mmu_fsr) 91 { 92 struct panic_trap_info ti; 93 94 #ifdef TRAPTRACE 95 TRAPTRACE_FREEZE; 96 #endif 97 98 ti.trap_regs = rp; 99 ti.trap_type = type; 100 ti.trap_addr = addr; 101 ti.trap_mmu_fsr = mmu_fsr; 102 103 curthread->t_panic_trap = &ti; 104 105 if (type == T_DATA_MMU_MISS && addr < (caddr_t)KERNELBASE) { 106 panic("BAD TRAP: type=%x rp=%p addr=%p mmu_fsr=%x " 107 "occurred in module \"%s\" due to %s", 108 type, (void *)rp, (void *)addr, mmu_fsr, 109 mod_containing_pc((caddr_t)rp->r_pc), 110 addr < (caddr_t)PAGESIZE ? 111 "a NULL pointer dereference" : 112 "an illegal access to a user address"); 113 } else { 114 panic("BAD TRAP: type=%x rp=%p addr=%p mmu_fsr=%x", 115 type, (void *)rp, (void *)addr, mmu_fsr); 116 } 117 118 return (0); /* avoid optimization of restore in call's delay slot */ 119 } 120 121 #if defined(SF_ERRATA_23) || defined(SF_ERRATA_30) /* call ... illegal-insn */ 122 int ill_calls; 123 #endif 124 125 /* 126 * Currently, the only PREFETCH/PREFETCHA instructions which cause traps 127 * are the "strong" prefetches (fcn=20-23). But we check for all flavors of 128 * PREFETCH, in case some future variant also causes a DATA_MMU_MISS. 129 */ 130 #define IS_PREFETCH(i) (((i) & 0xc1780000) == 0xc1680000) 131 132 #define IS_FLUSH(i) (((i) & 0xc1f80000) == 0x81d80000) 133 #define IS_SWAP(i) (((i) & 0xc1f80000) == 0xc0780000) 134 #define IS_LDSTUB(i) (((i) & 0xc1f80000) == 0xc0680000) 135 #define IS_FLOAT(i) (((i) & 0x1000000) != 0) 136 #define IS_STORE(i) (((i) >> 21) & 1) 137 138 /* 139 * Called from the trap handler when a processor trap occurs. 140 */ 141 /*VARARGS2*/ 142 void 143 trap(struct regs *rp, caddr_t addr, uint32_t type, uint32_t mmu_fsr) 144 { 145 proc_t *p = ttoproc(curthread); 146 klwp_id_t lwp = ttolwp(curthread); 147 struct machpcb *mpcb = NULL; 148 k_siginfo_t siginfo; 149 uint_t op3, fault = 0; 150 int stepped = 0; 151 greg_t oldpc; 152 int mstate; 153 char *badaddr; 154 faultcode_t res; 155 enum fault_type fault_type; 156 enum seg_rw rw; 157 uintptr_t lofault; 158 label_t *onfault; 159 int instr; 160 int iskernel; 161 int watchcode; 162 int watchpage; 163 extern faultcode_t pagefault(caddr_t, enum fault_type, 164 enum seg_rw, int); 165 #ifdef sun4v 166 extern boolean_t tick_stick_emulation_active; 167 #endif /* sun4v */ 168 169 CPU_STATS_ADDQ(CPU, sys, trap, 1); 170 171 if (USERMODE(rp->r_tstate) || (type & T_USER)) { 172 /* 173 * Set lwp_state before trying to acquire any 174 * adaptive lock 175 */ 176 ASSERT(lwp != NULL); 177 lwp->lwp_state = LWP_SYS; 178 /* 179 * Set up the current cred to use during this trap. u_cred 180 * no longer exists. t_cred is used instead. 181 * The current process credential applies to the thread for 182 * the entire trap. If trapping from the kernel, this 183 * should already be set up. 184 */ 185 if (curthread->t_cred != p->p_cred) { 186 cred_t *oldcred = curthread->t_cred; 187 /* 188 * DTrace accesses t_cred in probe context. t_cred 189 * must always be either NULL, or point to a valid, 190 * allocated cred structure. 191 */ 192 curthread->t_cred = crgetcred(); 193 crfree(oldcred); 194 } 195 type |= T_USER; 196 ASSERT((type == (T_SYS_RTT_PAGE | T_USER)) || 197 (type == (T_SYS_RTT_ALIGN | T_USER)) || 198 lwp->lwp_regs == rp); 199 mpcb = lwptompcb(lwp); 200 switch (type) { 201 case T_WIN_OVERFLOW + T_USER: 202 case T_WIN_UNDERFLOW + T_USER: 203 case T_SYS_RTT_PAGE + T_USER: 204 case T_DATA_MMU_MISS + T_USER: 205 mstate = LMS_DFAULT; 206 break; 207 case T_INSTR_MMU_MISS + T_USER: 208 mstate = LMS_TFAULT; 209 break; 210 default: 211 mstate = LMS_TRAP; 212 break; 213 } 214 /* Kernel probe */ 215 TNF_PROBE_1(thread_state, "thread", /* CSTYLED */, 216 tnf_microstate, state, (char)mstate); 217 mstate = new_mstate(curthread, mstate); 218 siginfo.si_signo = 0; 219 stepped = 220 lwp->lwp_pcb.pcb_step != STEP_NONE && 221 ((oldpc = rp->r_pc), prundostep()) && 222 mmu_btop((uintptr_t)addr) == mmu_btop((uintptr_t)oldpc); 223 /* this assignment must not precede call to prundostep() */ 224 oldpc = rp->r_pc; 225 } 226 227 TRACE_1(TR_FAC_TRAP, TR_C_TRAP_HANDLER_ENTER, 228 "C_trap_handler_enter:type %x", type); 229 230 #ifdef F_DEFERRED 231 /* 232 * Take any pending floating point exceptions now. 233 * If the floating point unit has an exception to handle, 234 * just return to user-level to let the signal handler run. 235 * The instruction that got us to trap() will be reexecuted on 236 * return from the signal handler and we will trap to here again. 237 * This is necessary to disambiguate simultaneous traps which 238 * happen when a floating-point exception is pending and a 239 * machine fault is incurred. 240 */ 241 if (type & USER) { 242 /* 243 * FP_TRAPPED is set only by sendsig() when it copies 244 * out the floating-point queue for the signal handler. 245 * It is set there so we can test it here and in syscall(). 246 */ 247 mpcb->mpcb_flags &= ~FP_TRAPPED; 248 syncfpu(); 249 if (mpcb->mpcb_flags & FP_TRAPPED) { 250 /* 251 * trap() has have been called recursively and may 252 * have stopped the process, so do single step 253 * support for /proc. 254 */ 255 mpcb->mpcb_flags &= ~FP_TRAPPED; 256 goto out; 257 } 258 } 259 #endif 260 switch (type) { 261 case T_DATA_MMU_MISS: 262 case T_INSTR_MMU_MISS + T_USER: 263 case T_DATA_MMU_MISS + T_USER: 264 case T_DATA_PROT + T_USER: 265 case T_AST + T_USER: 266 case T_SYS_RTT_PAGE + T_USER: 267 case T_FLUSH_PCB + T_USER: 268 case T_FLUSHW + T_USER: 269 break; 270 271 default: 272 FTRACE_3("trap(): type=0x%lx, regs=0x%lx, addr=0x%lx", 273 (ulong_t)type, (ulong_t)rp, (ulong_t)addr); 274 break; 275 } 276 277 switch (type) { 278 279 default: 280 /* 281 * Check for user software trap. 282 */ 283 if (type & T_USER) { 284 if (tudebug) 285 showregs(type, rp, (caddr_t)0, 0); 286 if ((type & ~T_USER) >= T_SOFTWARE_TRAP) { 287 bzero(&siginfo, sizeof (siginfo)); 288 siginfo.si_signo = SIGILL; 289 siginfo.si_code = ILL_ILLTRP; 290 siginfo.si_addr = (caddr_t)rp->r_pc; 291 siginfo.si_trapno = type &~ T_USER; 292 fault = FLTILL; 293 break; 294 } 295 } 296 addr = (caddr_t)rp->r_pc; 297 (void) die(type, rp, addr, 0); 298 /*NOTREACHED*/ 299 300 case T_ALIGNMENT: /* supv alignment error */ 301 if (nfload(rp, NULL)) 302 goto cleanup; 303 304 if (curthread->t_lofault) { 305 if (lodebug) { 306 showregs(type, rp, addr, 0); 307 traceback((caddr_t)rp->r_sp); 308 } 309 rp->r_g1 = EFAULT; 310 rp->r_pc = curthread->t_lofault; 311 rp->r_npc = rp->r_pc + 4; 312 goto cleanup; 313 } 314 (void) die(type, rp, addr, 0); 315 /*NOTREACHED*/ 316 317 case T_INSTR_EXCEPTION: /* sys instruction access exception */ 318 addr = (caddr_t)rp->r_pc; 319 (void) die(type, rp, addr, mmu_fsr); 320 /*NOTREACHED*/ 321 322 case T_INSTR_MMU_MISS: /* sys instruction mmu miss */ 323 addr = (caddr_t)rp->r_pc; 324 (void) die(type, rp, addr, 0); 325 /*NOTREACHED*/ 326 327 case T_DATA_EXCEPTION: /* system data access exception */ 328 switch (X_FAULT_TYPE(mmu_fsr)) { 329 case FT_RANGE: 330 /* 331 * This happens when we attempt to dereference an 332 * address in the address hole. If t_ontrap is set, 333 * then break and fall through to T_DATA_MMU_MISS / 334 * T_DATA_PROT case below. If lofault is set, then 335 * honour it (perhaps the user gave us a bogus 336 * address in the hole to copyin from or copyout to?) 337 */ 338 339 if (curthread->t_ontrap != NULL) 340 break; 341 342 addr = (caddr_t)((uintptr_t)addr & TAGACC_VADDR_MASK); 343 if (curthread->t_lofault) { 344 if (lodebug) { 345 showregs(type, rp, addr, 0); 346 traceback((caddr_t)rp->r_sp); 347 } 348 rp->r_g1 = EFAULT; 349 rp->r_pc = curthread->t_lofault; 350 rp->r_npc = rp->r_pc + 4; 351 goto cleanup; 352 } 353 (void) die(type, rp, addr, mmu_fsr); 354 /*NOTREACHED*/ 355 356 case FT_PRIV: 357 /* 358 * This can happen if we access ASI_USER from a kernel 359 * thread. To support pxfs, we need to honor lofault if 360 * we're doing a copyin/copyout from a kernel thread. 361 */ 362 363 if (nfload(rp, NULL)) 364 goto cleanup; 365 addr = (caddr_t)((uintptr_t)addr & TAGACC_VADDR_MASK); 366 if (curthread->t_lofault) { 367 if (lodebug) { 368 showregs(type, rp, addr, 0); 369 traceback((caddr_t)rp->r_sp); 370 } 371 rp->r_g1 = EFAULT; 372 rp->r_pc = curthread->t_lofault; 373 rp->r_npc = rp->r_pc + 4; 374 goto cleanup; 375 } 376 (void) die(type, rp, addr, mmu_fsr); 377 /*NOTREACHED*/ 378 379 default: 380 if (nfload(rp, NULL)) 381 goto cleanup; 382 addr = (caddr_t)((uintptr_t)addr & TAGACC_VADDR_MASK); 383 (void) die(type, rp, addr, mmu_fsr); 384 /*NOTREACHED*/ 385 386 case FT_NFO: 387 break; 388 } 389 /* fall into ... */ 390 391 case T_DATA_MMU_MISS: /* system data mmu miss */ 392 case T_DATA_PROT: /* system data protection fault */ 393 if (nfload(rp, &instr)) 394 goto cleanup; 395 396 /* 397 * If we're under on_trap() protection (see <sys/ontrap.h>), 398 * set ot_trap and return from the trap to the trampoline. 399 */ 400 if (curthread->t_ontrap != NULL) { 401 on_trap_data_t *otp = curthread->t_ontrap; 402 403 TRACE_0(TR_FAC_TRAP, TR_C_TRAP_HANDLER_EXIT, 404 "C_trap_handler_exit"); 405 TRACE_0(TR_FAC_TRAP, TR_TRAP_END, "trap_end"); 406 407 if (otp->ot_prot & OT_DATA_ACCESS) { 408 otp->ot_trap |= OT_DATA_ACCESS; 409 rp->r_pc = otp->ot_trampoline; 410 rp->r_npc = rp->r_pc + 4; 411 goto cleanup; 412 } 413 } 414 lofault = curthread->t_lofault; 415 onfault = curthread->t_onfault; 416 curthread->t_lofault = 0; 417 418 mstate = new_mstate(curthread, LMS_KFAULT); 419 420 switch (type) { 421 case T_DATA_PROT: 422 fault_type = F_PROT; 423 rw = S_WRITE; 424 break; 425 case T_INSTR_MMU_MISS: 426 fault_type = F_INVAL; 427 rw = S_EXEC; 428 break; 429 case T_DATA_MMU_MISS: 430 case T_DATA_EXCEPTION: 431 /* 432 * The hardware doesn't update the sfsr on mmu 433 * misses so it is not easy to find out whether 434 * the access was a read or a write so we need 435 * to decode the actual instruction. 436 */ 437 fault_type = F_INVAL; 438 rw = get_accesstype(rp); 439 break; 440 default: 441 cmn_err(CE_PANIC, "trap: unknown type %x", type); 442 break; 443 } 444 /* 445 * We determine if access was done to kernel or user 446 * address space. The addr passed into trap is really the 447 * tag access register. 448 */ 449 iskernel = (((uintptr_t)addr & TAGACC_CTX_MASK) == KCONTEXT); 450 addr = (caddr_t)((uintptr_t)addr & TAGACC_VADDR_MASK); 451 452 res = pagefault(addr, fault_type, rw, iskernel); 453 if (!iskernel && res == FC_NOMAP && 454 addr < p->p_usrstack && grow(addr)) 455 res = 0; 456 457 (void) new_mstate(curthread, mstate); 458 459 /* 460 * Restore lofault and onfault. If we resolved the fault, exit. 461 * If we didn't and lofault wasn't set, die. 462 */ 463 curthread->t_lofault = lofault; 464 curthread->t_onfault = onfault; 465 466 if (res == 0) 467 goto cleanup; 468 469 if (IS_PREFETCH(instr)) { 470 /* skip prefetch instructions in kernel-land */ 471 rp->r_pc = rp->r_npc; 472 rp->r_npc += 4; 473 goto cleanup; 474 } 475 476 if ((lofault == 0 || lodebug) && 477 (calc_memaddr(rp, &badaddr) == SIMU_SUCCESS)) 478 addr = badaddr; 479 if (lofault == 0) 480 (void) die(type, rp, addr, 0); 481 /* 482 * Cannot resolve fault. Return to lofault. 483 */ 484 if (lodebug) { 485 showregs(type, rp, addr, 0); 486 traceback((caddr_t)rp->r_sp); 487 } 488 if (FC_CODE(res) == FC_OBJERR) 489 res = FC_ERRNO(res); 490 else 491 res = EFAULT; 492 rp->r_g1 = res; 493 rp->r_pc = curthread->t_lofault; 494 rp->r_npc = curthread->t_lofault + 4; 495 goto cleanup; 496 497 case T_INSTR_EXCEPTION + T_USER: /* user insn access exception */ 498 bzero(&siginfo, sizeof (siginfo)); 499 siginfo.si_addr = (caddr_t)rp->r_pc; 500 siginfo.si_signo = SIGSEGV; 501 siginfo.si_code = X_FAULT_TYPE(mmu_fsr) == FT_PRIV ? 502 SEGV_ACCERR : SEGV_MAPERR; 503 fault = FLTBOUNDS; 504 break; 505 506 case T_WIN_OVERFLOW + T_USER: /* window overflow in ??? */ 507 case T_WIN_UNDERFLOW + T_USER: /* window underflow in ??? */ 508 case T_SYS_RTT_PAGE + T_USER: /* window underflow in user_rtt */ 509 case T_INSTR_MMU_MISS + T_USER: /* user instruction mmu miss */ 510 case T_DATA_MMU_MISS + T_USER: /* user data mmu miss */ 511 case T_DATA_PROT + T_USER: /* user data protection fault */ 512 switch (type) { 513 case T_INSTR_MMU_MISS + T_USER: 514 addr = (caddr_t)rp->r_pc; 515 fault_type = F_INVAL; 516 rw = S_EXEC; 517 break; 518 519 case T_DATA_MMU_MISS + T_USER: 520 addr = (caddr_t)((uintptr_t)addr & TAGACC_VADDR_MASK); 521 fault_type = F_INVAL; 522 /* 523 * The hardware doesn't update the sfsr on mmu misses 524 * so it is not easy to find out whether the access 525 * was a read or a write so we need to decode the 526 * actual instruction. XXX BUGLY HW 527 */ 528 rw = get_accesstype(rp); 529 break; 530 531 case T_DATA_PROT + T_USER: 532 addr = (caddr_t)((uintptr_t)addr & TAGACC_VADDR_MASK); 533 fault_type = F_PROT; 534 rw = S_WRITE; 535 break; 536 537 case T_WIN_OVERFLOW + T_USER: 538 addr = (caddr_t)((uintptr_t)addr & TAGACC_VADDR_MASK); 539 fault_type = F_INVAL; 540 rw = S_WRITE; 541 break; 542 543 case T_WIN_UNDERFLOW + T_USER: 544 case T_SYS_RTT_PAGE + T_USER: 545 addr = (caddr_t)((uintptr_t)addr & TAGACC_VADDR_MASK); 546 fault_type = F_INVAL; 547 rw = S_READ; 548 break; 549 550 default: 551 cmn_err(CE_PANIC, "trap: unknown type %x", type); 552 break; 553 } 554 555 /* 556 * If we are single stepping do not call pagefault 557 */ 558 if (stepped) { 559 res = FC_NOMAP; 560 } else { 561 caddr_t vaddr = addr; 562 size_t sz; 563 int ta; 564 565 ASSERT(!(curthread->t_flag & T_WATCHPT)); 566 watchpage = (pr_watch_active(p) && 567 type != T_WIN_OVERFLOW + T_USER && 568 type != T_WIN_UNDERFLOW + T_USER && 569 type != T_SYS_RTT_PAGE + T_USER && 570 pr_is_watchpage(addr, rw)); 571 572 if (!watchpage || 573 (sz = instr_size(rp, &vaddr, rw)) <= 0) 574 /* EMPTY */; 575 else if ((watchcode = pr_is_watchpoint(&vaddr, &ta, 576 sz, NULL, rw)) != 0) { 577 if (ta) { 578 do_watch_step(vaddr, sz, rw, 579 watchcode, rp->r_pc); 580 fault_type = F_INVAL; 581 } else { 582 bzero(&siginfo, sizeof (siginfo)); 583 siginfo.si_signo = SIGTRAP; 584 siginfo.si_code = watchcode; 585 siginfo.si_addr = vaddr; 586 siginfo.si_trapafter = 0; 587 siginfo.si_pc = (caddr_t)rp->r_pc; 588 fault = FLTWATCH; 589 break; 590 } 591 } else { 592 if (rw != S_EXEC && 593 pr_watch_emul(rp, vaddr, rw)) 594 goto out; 595 do_watch_step(vaddr, sz, rw, 0, 0); 596 fault_type = F_INVAL; 597 } 598 599 if (pr_watch_active(p) && 600 (type == T_WIN_OVERFLOW + T_USER || 601 type == T_WIN_UNDERFLOW + T_USER || 602 type == T_SYS_RTT_PAGE + T_USER)) { 603 int dotwo = (type == T_WIN_UNDERFLOW + T_USER); 604 if (copy_return_window(dotwo)) 605 goto out; 606 fault_type = F_INVAL; 607 } 608 609 res = pagefault(addr, fault_type, rw, 0); 610 611 /* 612 * If pagefault succeed, ok. 613 * Otherwise grow the stack automatically. 614 */ 615 if (res == 0 || 616 (res == FC_NOMAP && 617 type != T_INSTR_MMU_MISS + T_USER && 618 addr < p->p_usrstack && 619 grow(addr))) { 620 int ismem = prismember(&p->p_fltmask, FLTPAGE); 621 622 /* 623 * instr_size() is used to get the exact 624 * address of the fault, instead of the 625 * page of the fault. Unfortunately it is 626 * very slow, and this is an important 627 * code path. Don't call it unless 628 * correctness is needed. ie. if FLTPAGE 629 * is set, or we're profiling. 630 */ 631 632 if (curthread->t_rprof != NULL || ismem) 633 (void) instr_size(rp, &addr, rw); 634 635 lwp->lwp_lastfault = FLTPAGE; 636 lwp->lwp_lastfaddr = addr; 637 638 if (ismem) { 639 bzero(&siginfo, sizeof (siginfo)); 640 siginfo.si_addr = addr; 641 (void) stop_on_fault(FLTPAGE, &siginfo); 642 } 643 goto out; 644 } 645 646 if (type != (T_INSTR_MMU_MISS + T_USER)) { 647 /* 648 * check for non-faulting loads, also 649 * fetch the instruction to check for 650 * flush 651 */ 652 if (nfload(rp, &instr)) 653 goto out; 654 655 /* skip userland prefetch instructions */ 656 if (IS_PREFETCH(instr)) { 657 rp->r_pc = rp->r_npc; 658 rp->r_npc += 4; 659 goto out; 660 /*NOTREACHED*/ 661 } 662 663 /* 664 * check if the instruction was a 665 * flush. ABI allows users to specify 666 * an illegal address on the flush 667 * instruction so we simply return in 668 * this case. 669 * 670 * NB: the hardware should set a bit 671 * indicating this trap was caused by 672 * a flush instruction. Instruction 673 * decoding is bugly! 674 */ 675 if (IS_FLUSH(instr)) { 676 /* skip the flush instruction */ 677 rp->r_pc = rp->r_npc; 678 rp->r_npc += 4; 679 goto out; 680 /*NOTREACHED*/ 681 } 682 } else if (res == FC_PROT) { 683 report_stack_exec(p, addr); 684 } 685 686 if (tudebug) 687 showregs(type, rp, addr, 0); 688 } 689 690 /* 691 * In the case where both pagefault and grow fail, 692 * set the code to the value provided by pagefault. 693 */ 694 (void) instr_size(rp, &addr, rw); 695 bzero(&siginfo, sizeof (siginfo)); 696 siginfo.si_addr = addr; 697 if (FC_CODE(res) == FC_OBJERR) { 698 siginfo.si_errno = FC_ERRNO(res); 699 if (siginfo.si_errno != EINTR) { 700 siginfo.si_signo = SIGBUS; 701 siginfo.si_code = BUS_OBJERR; 702 fault = FLTACCESS; 703 } 704 } else { /* FC_NOMAP || FC_PROT */ 705 siginfo.si_signo = SIGSEGV; 706 siginfo.si_code = (res == FC_NOMAP) ? 707 SEGV_MAPERR : SEGV_ACCERR; 708 fault = FLTBOUNDS; 709 } 710 /* 711 * If this is the culmination of a single-step, 712 * reset the addr, code, signal and fault to 713 * indicate a hardware trace trap. 714 */ 715 if (stepped) { 716 pcb_t *pcb = &lwp->lwp_pcb; 717 718 siginfo.si_signo = 0; 719 fault = 0; 720 if (pcb->pcb_step == STEP_WASACTIVE) { 721 pcb->pcb_step = STEP_NONE; 722 pcb->pcb_tracepc = NULL; 723 oldpc = rp->r_pc - 4; 724 } 725 /* 726 * If both NORMAL_STEP and WATCH_STEP are in 727 * effect, give precedence to WATCH_STEP. 728 * One or the other must be set at this point. 729 */ 730 ASSERT(pcb->pcb_flags & (NORMAL_STEP|WATCH_STEP)); 731 if ((fault = undo_watch_step(&siginfo)) == 0 && 732 (pcb->pcb_flags & NORMAL_STEP)) { 733 siginfo.si_signo = SIGTRAP; 734 siginfo.si_code = TRAP_TRACE; 735 siginfo.si_addr = (caddr_t)rp->r_pc; 736 fault = FLTTRACE; 737 } 738 pcb->pcb_flags &= ~(NORMAL_STEP|WATCH_STEP); 739 } 740 break; 741 742 case T_DATA_EXCEPTION + T_USER: /* user data access exception */ 743 744 if (&vis1_partial_support != NULL) { 745 bzero(&siginfo, sizeof (siginfo)); 746 if (vis1_partial_support(rp, 747 &siginfo, &fault) == 0) 748 goto out; 749 } 750 751 if (nfload(rp, &instr)) 752 goto out; 753 if (IS_FLUSH(instr)) { 754 /* skip the flush instruction */ 755 rp->r_pc = rp->r_npc; 756 rp->r_npc += 4; 757 goto out; 758 /*NOTREACHED*/ 759 } 760 bzero(&siginfo, sizeof (siginfo)); 761 siginfo.si_addr = addr; 762 switch (X_FAULT_TYPE(mmu_fsr)) { 763 case FT_ATOMIC_NC: 764 if ((IS_SWAP(instr) && swap_nc(rp, instr)) || 765 (IS_LDSTUB(instr) && ldstub_nc(rp, instr))) { 766 /* skip the atomic */ 767 rp->r_pc = rp->r_npc; 768 rp->r_npc += 4; 769 goto out; 770 } 771 /* fall into ... */ 772 case FT_PRIV: 773 siginfo.si_signo = SIGSEGV; 774 siginfo.si_code = SEGV_ACCERR; 775 fault = FLTBOUNDS; 776 break; 777 case FT_SPEC_LD: 778 case FT_ILL_ALT: 779 siginfo.si_signo = SIGILL; 780 siginfo.si_code = ILL_ILLADR; 781 fault = FLTILL; 782 break; 783 default: 784 siginfo.si_signo = SIGSEGV; 785 siginfo.si_code = SEGV_MAPERR; 786 fault = FLTBOUNDS; 787 break; 788 } 789 break; 790 791 case T_SYS_RTT_ALIGN + T_USER: /* user alignment error */ 792 case T_ALIGNMENT + T_USER: /* user alignment error */ 793 if (tudebug) 794 showregs(type, rp, addr, 0); 795 /* 796 * If the user has to do unaligned references 797 * the ugly stuff gets done here. 798 */ 799 alignfaults++; 800 if (&vis1_partial_support != NULL) { 801 bzero(&siginfo, sizeof (siginfo)); 802 if (vis1_partial_support(rp, 803 &siginfo, &fault) == 0) 804 goto out; 805 } 806 807 bzero(&siginfo, sizeof (siginfo)); 808 if (type == T_SYS_RTT_ALIGN + T_USER) { 809 if (nfload(rp, NULL)) 810 goto out; 811 /* 812 * Can't do unaligned stack access 813 */ 814 siginfo.si_signo = SIGBUS; 815 siginfo.si_code = BUS_ADRALN; 816 siginfo.si_addr = addr; 817 fault = FLTACCESS; 818 break; 819 } 820 821 /* 822 * Try to fix alignment before non-faulting load test. 823 */ 824 if (p->p_fixalignment) { 825 if (do_unaligned(rp, &badaddr) == SIMU_SUCCESS) { 826 rp->r_pc = rp->r_npc; 827 rp->r_npc += 4; 828 goto out; 829 } 830 if (nfload(rp, NULL)) 831 goto out; 832 siginfo.si_signo = SIGSEGV; 833 siginfo.si_code = SEGV_MAPERR; 834 siginfo.si_addr = badaddr; 835 fault = FLTBOUNDS; 836 } else { 837 if (nfload(rp, NULL)) 838 goto out; 839 siginfo.si_signo = SIGBUS; 840 siginfo.si_code = BUS_ADRALN; 841 if (rp->r_pc & 3) { /* offending address, if pc */ 842 siginfo.si_addr = (caddr_t)rp->r_pc; 843 } else { 844 if (calc_memaddr(rp, &badaddr) == SIMU_UNALIGN) 845 siginfo.si_addr = badaddr; 846 else 847 siginfo.si_addr = (caddr_t)rp->r_pc; 848 } 849 fault = FLTACCESS; 850 } 851 break; 852 853 case T_PRIV_INSTR + T_USER: /* privileged instruction fault */ 854 if (tudebug) 855 showregs(type, rp, (caddr_t)0, 0); 856 857 bzero(&siginfo, sizeof (siginfo)); 858 #ifdef sun4v 859 /* 860 * If this instruction fault is a non-privileged %tick 861 * or %stick trap, and %tick/%stick user emulation is 862 * enabled as a result of an OS suspend, then simulate 863 * the register read. We rely on simulate_rdtick to fail 864 * if the instruction is not a %tick or %stick read, 865 * causing us to fall through to the normal privileged 866 * instruction handling. 867 */ 868 if (tick_stick_emulation_active && 869 (X_FAULT_TYPE(mmu_fsr) == FT_NEW_PRVACT) && 870 simulate_rdtick(rp) == SIMU_SUCCESS) { 871 /* skip the successfully simulated instruction */ 872 rp->r_pc = rp->r_npc; 873 rp->r_npc += 4; 874 goto out; 875 } 876 #endif 877 siginfo.si_signo = SIGILL; 878 siginfo.si_code = ILL_PRVOPC; 879 siginfo.si_addr = (caddr_t)rp->r_pc; 880 fault = FLTILL; 881 break; 882 883 case T_UNIMP_INSTR: /* priv illegal instruction fault */ 884 if (fpras_implemented) { 885 /* 886 * Call fpras_chktrap indicating that 887 * we've come from a trap handler and pass 888 * the regs. That function may choose to panic 889 * (in which case it won't return) or it may 890 * determine that a reboot is desired. In the 891 * latter case it must alter pc/npc to skip 892 * the illegal instruction and continue at 893 * a controlled address. 894 */ 895 if (&fpras_chktrap) { 896 if (fpras_chktrap(rp)) 897 goto cleanup; 898 } 899 } 900 #if defined(SF_ERRATA_23) || defined(SF_ERRATA_30) /* call ... illegal-insn */ 901 instr = *(int *)rp->r_pc; 902 if ((instr & 0xc0000000) == 0x40000000) { 903 long pc; 904 905 rp->r_o7 = (long long)rp->r_pc; 906 pc = rp->r_pc + ((instr & 0x3fffffff) << 2); 907 rp->r_pc = rp->r_npc; 908 rp->r_npc = pc; 909 ill_calls++; 910 goto cleanup; 911 } 912 #endif /* SF_ERRATA_23 || SF_ERRATA_30 */ 913 /* 914 * It's not an fpras failure and it's not SF_ERRATA_23 - die 915 */ 916 addr = (caddr_t)rp->r_pc; 917 (void) die(type, rp, addr, 0); 918 /*NOTREACHED*/ 919 920 case T_UNIMP_INSTR + T_USER: /* illegal instruction fault */ 921 #if defined(SF_ERRATA_23) || defined(SF_ERRATA_30) /* call ... illegal-insn */ 922 instr = fetch_user_instr((caddr_t)rp->r_pc); 923 if ((instr & 0xc0000000) == 0x40000000) { 924 long pc; 925 926 rp->r_o7 = (long long)rp->r_pc; 927 pc = rp->r_pc + ((instr & 0x3fffffff) << 2); 928 rp->r_pc = rp->r_npc; 929 rp->r_npc = pc; 930 ill_calls++; 931 goto out; 932 } 933 #endif /* SF_ERRATA_23 || SF_ERRATA_30 */ 934 if (tudebug) 935 showregs(type, rp, (caddr_t)0, 0); 936 bzero(&siginfo, sizeof (siginfo)); 937 /* 938 * Try to simulate the instruction. 939 */ 940 switch (simulate_unimp(rp, &badaddr)) { 941 case SIMU_RETRY: 942 goto out; /* regs are already set up */ 943 /*NOTREACHED*/ 944 945 case SIMU_SUCCESS: 946 /* skip the successfully simulated instruction */ 947 rp->r_pc = rp->r_npc; 948 rp->r_npc += 4; 949 goto out; 950 /*NOTREACHED*/ 951 952 case SIMU_FAULT: 953 siginfo.si_signo = SIGSEGV; 954 siginfo.si_code = SEGV_MAPERR; 955 siginfo.si_addr = badaddr; 956 fault = FLTBOUNDS; 957 break; 958 959 case SIMU_DZERO: 960 siginfo.si_signo = SIGFPE; 961 siginfo.si_code = FPE_INTDIV; 962 siginfo.si_addr = (caddr_t)rp->r_pc; 963 fault = FLTIZDIV; 964 break; 965 966 case SIMU_UNALIGN: 967 siginfo.si_signo = SIGBUS; 968 siginfo.si_code = BUS_ADRALN; 969 siginfo.si_addr = badaddr; 970 fault = FLTACCESS; 971 break; 972 973 case SIMU_ILLEGAL: 974 default: 975 siginfo.si_signo = SIGILL; 976 op3 = (instr >> 19) & 0x3F; 977 if ((IS_FLOAT(instr) && (op3 == IOP_V8_STQFA) || 978 (op3 == IOP_V8_STDFA))) 979 siginfo.si_code = ILL_ILLADR; 980 else 981 siginfo.si_code = ILL_ILLOPC; 982 siginfo.si_addr = (caddr_t)rp->r_pc; 983 fault = FLTILL; 984 break; 985 } 986 break; 987 988 case T_UNIMP_LDD + T_USER: 989 case T_UNIMP_STD + T_USER: 990 if (tudebug) 991 showregs(type, rp, (caddr_t)0, 0); 992 switch (simulate_lddstd(rp, &badaddr)) { 993 case SIMU_SUCCESS: 994 /* skip the successfully simulated instruction */ 995 rp->r_pc = rp->r_npc; 996 rp->r_npc += 4; 997 goto out; 998 /*NOTREACHED*/ 999 1000 case SIMU_FAULT: 1001 if (nfload(rp, NULL)) 1002 goto out; 1003 siginfo.si_signo = SIGSEGV; 1004 siginfo.si_code = SEGV_MAPERR; 1005 siginfo.si_addr = badaddr; 1006 fault = FLTBOUNDS; 1007 break; 1008 1009 case SIMU_UNALIGN: 1010 if (nfload(rp, NULL)) 1011 goto out; 1012 siginfo.si_signo = SIGBUS; 1013 siginfo.si_code = BUS_ADRALN; 1014 siginfo.si_addr = badaddr; 1015 fault = FLTACCESS; 1016 break; 1017 1018 case SIMU_ILLEGAL: 1019 default: 1020 siginfo.si_signo = SIGILL; 1021 siginfo.si_code = ILL_ILLOPC; 1022 siginfo.si_addr = (caddr_t)rp->r_pc; 1023 fault = FLTILL; 1024 break; 1025 } 1026 break; 1027 1028 case T_UNIMP_LDD: 1029 case T_UNIMP_STD: 1030 if (simulate_lddstd(rp, &badaddr) == SIMU_SUCCESS) { 1031 /* skip the successfully simulated instruction */ 1032 rp->r_pc = rp->r_npc; 1033 rp->r_npc += 4; 1034 goto cleanup; 1035 /*NOTREACHED*/ 1036 } 1037 /* 1038 * A third party driver executed an {LDD,STD,LDDA,STDA} 1039 * that we couldn't simulate. 1040 */ 1041 if (nfload(rp, NULL)) 1042 goto cleanup; 1043 1044 if (curthread->t_lofault) { 1045 if (lodebug) { 1046 showregs(type, rp, addr, 0); 1047 traceback((caddr_t)rp->r_sp); 1048 } 1049 rp->r_g1 = EFAULT; 1050 rp->r_pc = curthread->t_lofault; 1051 rp->r_npc = rp->r_pc + 4; 1052 goto cleanup; 1053 } 1054 (void) die(type, rp, addr, 0); 1055 /*NOTREACHED*/ 1056 1057 case T_IDIV0 + T_USER: /* integer divide by zero */ 1058 case T_DIV0 + T_USER: /* integer divide by zero */ 1059 if (tudebug && tudebugfpe) 1060 showregs(type, rp, (caddr_t)0, 0); 1061 bzero(&siginfo, sizeof (siginfo)); 1062 siginfo.si_signo = SIGFPE; 1063 siginfo.si_code = FPE_INTDIV; 1064 siginfo.si_addr = (caddr_t)rp->r_pc; 1065 fault = FLTIZDIV; 1066 break; 1067 1068 case T_INT_OVERFLOW + T_USER: /* integer overflow */ 1069 if (tudebug && tudebugfpe) 1070 showregs(type, rp, (caddr_t)0, 0); 1071 bzero(&siginfo, sizeof (siginfo)); 1072 siginfo.si_signo = SIGFPE; 1073 siginfo.si_code = FPE_INTOVF; 1074 siginfo.si_addr = (caddr_t)rp->r_pc; 1075 fault = FLTIOVF; 1076 break; 1077 1078 case T_BREAKPOINT + T_USER: /* breakpoint trap (t 1) */ 1079 if (tudebug && tudebugbpt) 1080 showregs(type, rp, (caddr_t)0, 0); 1081 bzero(&siginfo, sizeof (siginfo)); 1082 siginfo.si_signo = SIGTRAP; 1083 siginfo.si_code = TRAP_BRKPT; 1084 siginfo.si_addr = (caddr_t)rp->r_pc; 1085 fault = FLTBPT; 1086 break; 1087 1088 case T_TAG_OVERFLOW + T_USER: /* tag overflow (taddcctv, tsubcctv) */ 1089 if (tudebug) 1090 showregs(type, rp, (caddr_t)0, 0); 1091 bzero(&siginfo, sizeof (siginfo)); 1092 siginfo.si_signo = SIGEMT; 1093 siginfo.si_code = EMT_TAGOVF; 1094 siginfo.si_addr = (caddr_t)rp->r_pc; 1095 fault = FLTACCESS; 1096 break; 1097 1098 case T_FLUSH_PCB + T_USER: /* finish user window overflow */ 1099 case T_FLUSHW + T_USER: /* finish user window flush */ 1100 /* 1101 * This trap is entered from sys_rtt in locore.s when, 1102 * upon return to user is is found that there are user 1103 * windows in pcb_wbuf. This happens because they could 1104 * not be saved on the user stack, either because it 1105 * wasn't resident or because it was misaligned. 1106 */ 1107 { 1108 int error; 1109 caddr_t sp; 1110 1111 error = flush_user_windows_to_stack(&sp); 1112 /* 1113 * Possible errors: 1114 * error copying out 1115 * unaligned stack pointer 1116 * The first is given to us as the return value 1117 * from flush_user_windows_to_stack(). The second 1118 * results in residual windows in the pcb. 1119 */ 1120 if (error != 0) { 1121 /* 1122 * EINTR comes from a signal during copyout; 1123 * we should not post another signal. 1124 */ 1125 if (error != EINTR) { 1126 /* 1127 * Zap the process with a SIGSEGV - process 1128 * may be managing its own stack growth by 1129 * taking SIGSEGVs on a different signal stack. 1130 */ 1131 bzero(&siginfo, sizeof (siginfo)); 1132 siginfo.si_signo = SIGSEGV; 1133 siginfo.si_code = SEGV_MAPERR; 1134 siginfo.si_addr = sp; 1135 fault = FLTBOUNDS; 1136 } 1137 break; 1138 } else if (mpcb->mpcb_wbcnt) { 1139 bzero(&siginfo, sizeof (siginfo)); 1140 siginfo.si_signo = SIGILL; 1141 siginfo.si_code = ILL_BADSTK; 1142 siginfo.si_addr = (caddr_t)rp->r_pc; 1143 fault = FLTILL; 1144 break; 1145 } 1146 } 1147 1148 /* 1149 * T_FLUSHW is used when handling a ta 0x3 -- the old flush 1150 * window trap -- which is implemented by executing the 1151 * flushw instruction. The flushw can trap if any of the 1152 * stack pages are not writable for whatever reason. In this 1153 * case only, we advance the pc to the next instruction so 1154 * that the user thread doesn't needlessly execute the trap 1155 * again. Normally this wouldn't be a problem -- we'll 1156 * usually only end up here if this is the first touch to a 1157 * stack page -- since the second execution won't trap, but 1158 * if there's a watchpoint on the stack page the user thread 1159 * would spin, continuously executing the trap instruction. 1160 */ 1161 if (type == T_FLUSHW + T_USER) { 1162 rp->r_pc = rp->r_npc; 1163 rp->r_npc += 4; 1164 } 1165 goto out; 1166 1167 case T_AST + T_USER: /* profiling or resched pseudo trap */ 1168 if (lwp->lwp_pcb.pcb_flags & CPC_OVERFLOW) { 1169 lwp->lwp_pcb.pcb_flags &= ~CPC_OVERFLOW; 1170 if (kcpc_overflow_ast()) { 1171 /* 1172 * Signal performance counter overflow 1173 */ 1174 if (tudebug) 1175 showregs(type, rp, (caddr_t)0, 0); 1176 bzero(&siginfo, sizeof (siginfo)); 1177 siginfo.si_signo = SIGEMT; 1178 siginfo.si_code = EMT_CPCOVF; 1179 siginfo.si_addr = (caddr_t)rp->r_pc; 1180 /* for trap_cleanup(), below */ 1181 oldpc = rp->r_pc - 4; 1182 fault = FLTCPCOVF; 1183 } 1184 } 1185 1186 /* 1187 * The CPC_OVERFLOW check above may already have populated 1188 * siginfo and set fault, so the checks below must not 1189 * touch these and the functions they call must use 1190 * trapsig() directly. 1191 */ 1192 1193 if (lwp->lwp_pcb.pcb_flags & ASYNC_HWERR) { 1194 lwp->lwp_pcb.pcb_flags &= ~ASYNC_HWERR; 1195 trap_async_hwerr(); 1196 } 1197 1198 if (lwp->lwp_pcb.pcb_flags & ASYNC_BERR) { 1199 lwp->lwp_pcb.pcb_flags &= ~ASYNC_BERR; 1200 trap_async_berr_bto(ASYNC_BERR, rp); 1201 } 1202 1203 if (lwp->lwp_pcb.pcb_flags & ASYNC_BTO) { 1204 lwp->lwp_pcb.pcb_flags &= ~ASYNC_BTO; 1205 trap_async_berr_bto(ASYNC_BTO, rp); 1206 } 1207 1208 break; 1209 } 1210 1211 if (fault) { 1212 /* We took a fault so abort single step. */ 1213 lwp->lwp_pcb.pcb_flags &= ~(NORMAL_STEP|WATCH_STEP); 1214 } 1215 trap_cleanup(rp, fault, &siginfo, oldpc == rp->r_pc); 1216 1217 out: /* We can't get here from a system trap */ 1218 ASSERT(type & T_USER); 1219 trap_rtt(); 1220 (void) new_mstate(curthread, mstate); 1221 /* Kernel probe */ 1222 TNF_PROBE_1(thread_state, "thread", /* CSTYLED */, 1223 tnf_microstate, state, LMS_USER); 1224 1225 TRACE_0(TR_FAC_TRAP, TR_C_TRAP_HANDLER_EXIT, "C_trap_handler_exit"); 1226 return; 1227 1228 cleanup: /* system traps end up here */ 1229 ASSERT(!(type & T_USER)); 1230 1231 TRACE_0(TR_FAC_TRAP, TR_C_TRAP_HANDLER_EXIT, "C_trap_handler_exit"); 1232 } 1233 1234 void 1235 trap_cleanup( 1236 struct regs *rp, 1237 uint_t fault, 1238 k_siginfo_t *sip, 1239 int restartable) 1240 { 1241 extern void aio_cleanup(); 1242 proc_t *p = ttoproc(curthread); 1243 klwp_id_t lwp = ttolwp(curthread); 1244 1245 if (fault) { 1246 /* 1247 * Remember the fault and fault address 1248 * for real-time (SIGPROF) profiling. 1249 */ 1250 lwp->lwp_lastfault = fault; 1251 lwp->lwp_lastfaddr = sip->si_addr; 1252 1253 DTRACE_PROC2(fault, int, fault, ksiginfo_t *, sip); 1254 1255 /* 1256 * If a debugger has declared this fault to be an 1257 * event of interest, stop the lwp. Otherwise just 1258 * deliver the associated signal. 1259 */ 1260 if (sip->si_signo != SIGKILL && 1261 prismember(&p->p_fltmask, fault) && 1262 stop_on_fault(fault, sip) == 0) 1263 sip->si_signo = 0; 1264 } 1265 1266 if (sip->si_signo) 1267 trapsig(sip, restartable); 1268 1269 if (lwp->lwp_oweupc) 1270 profil_tick(rp->r_pc); 1271 1272 if (curthread->t_astflag | curthread->t_sig_check) { 1273 /* 1274 * Turn off the AST flag before checking all the conditions that 1275 * may have caused an AST. This flag is on whenever a signal or 1276 * unusual condition should be handled after the next trap or 1277 * syscall. 1278 */ 1279 astoff(curthread); 1280 curthread->t_sig_check = 0; 1281 1282 /* 1283 * The following check is legal for the following reasons: 1284 * 1) The thread we are checking, is ourselves, so there is 1285 * no way the proc can go away. 1286 * 2) The only time we need to be protected by the 1287 * lock is if the binding is changed. 1288 * 1289 * Note we will still take the lock and check the binding 1290 * if the condition was true without the lock held. This 1291 * prevents lock contention among threads owned by the 1292 * same proc. 1293 */ 1294 1295 if (curthread->t_proc_flag & TP_CHANGEBIND) { 1296 mutex_enter(&p->p_lock); 1297 if (curthread->t_proc_flag & TP_CHANGEBIND) { 1298 timer_lwpbind(); 1299 curthread->t_proc_flag &= ~TP_CHANGEBIND; 1300 } 1301 mutex_exit(&p->p_lock); 1302 } 1303 1304 /* 1305 * for kaio requests that are on the per-process poll queue, 1306 * aiop->aio_pollq, they're AIO_POLL bit is set, the kernel 1307 * should copyout their result_t to user memory. by copying 1308 * out the result_t, the user can poll on memory waiting 1309 * for the kaio request to complete. 1310 */ 1311 if (p->p_aio) 1312 aio_cleanup(0); 1313 1314 /* 1315 * If this LWP was asked to hold, call holdlwp(), which will 1316 * stop. holdlwps() sets this up and calls pokelwps() which 1317 * sets the AST flag. 1318 * 1319 * Also check TP_EXITLWP, since this is used by fresh new LWPs 1320 * through lwp_rtt(). That flag is set if the lwp_create(2) 1321 * syscall failed after creating the LWP. 1322 */ 1323 if (ISHOLD(p)) 1324 holdlwp(); 1325 1326 /* 1327 * All code that sets signals and makes ISSIG evaluate true must 1328 * set t_astflag afterwards. 1329 */ 1330 if (ISSIG_PENDING(curthread, lwp, p)) { 1331 if (issig(FORREAL)) 1332 psig(); 1333 curthread->t_sig_check = 1; 1334 } 1335 1336 if (curthread->t_rprof != NULL) { 1337 realsigprof(0, 0, 0); 1338 curthread->t_sig_check = 1; 1339 } 1340 } 1341 } 1342 1343 /* 1344 * Called from fp_traps when a floating point trap occurs. 1345 * Note that the T_DATA_EXCEPTION case does not use X_FAULT_TYPE(mmu_fsr), 1346 * because mmu_fsr (now changed to code) is always 0. 1347 * Note that the T_UNIMP_INSTR case does not call simulate_unimp(), 1348 * because the simulator only simulates multiply and divide instructions, 1349 * which would not cause floating point traps in the first place. 1350 * XXX - Supervisor mode floating point traps? 1351 */ 1352 void 1353 fpu_trap(struct regs *rp, caddr_t addr, uint32_t type, uint32_t code) 1354 { 1355 proc_t *p = ttoproc(curthread); 1356 klwp_id_t lwp = ttolwp(curthread); 1357 k_siginfo_t siginfo; 1358 uint_t op3, fault = 0; 1359 int mstate; 1360 char *badaddr; 1361 kfpu_t *fp; 1362 struct _fpq *pfpq; 1363 uint32_t inst; 1364 utrap_handler_t *utrapp; 1365 1366 CPU_STATS_ADDQ(CPU, sys, trap, 1); 1367 1368 if (USERMODE(rp->r_tstate)) { 1369 /* 1370 * Set lwp_state before trying to acquire any 1371 * adaptive lock 1372 */ 1373 ASSERT(lwp != NULL); 1374 lwp->lwp_state = LWP_SYS; 1375 /* 1376 * Set up the current cred to use during this trap. u_cred 1377 * no longer exists. t_cred is used instead. 1378 * The current process credential applies to the thread for 1379 * the entire trap. If trapping from the kernel, this 1380 * should already be set up. 1381 */ 1382 if (curthread->t_cred != p->p_cred) { 1383 cred_t *oldcred = curthread->t_cred; 1384 /* 1385 * DTrace accesses t_cred in probe context. t_cred 1386 * must always be either NULL, or point to a valid, 1387 * allocated cred structure. 1388 */ 1389 curthread->t_cred = crgetcred(); 1390 crfree(oldcred); 1391 } 1392 ASSERT(lwp->lwp_regs == rp); 1393 mstate = new_mstate(curthread, LMS_TRAP); 1394 siginfo.si_signo = 0; 1395 type |= T_USER; 1396 } 1397 1398 TRACE_1(TR_FAC_TRAP, TR_C_TRAP_HANDLER_ENTER, 1399 "C_fpu_trap_handler_enter:type %x", type); 1400 1401 if (tudebug && tudebugfpe) 1402 showregs(type, rp, addr, 0); 1403 1404 bzero(&siginfo, sizeof (siginfo)); 1405 siginfo.si_code = code; 1406 siginfo.si_addr = addr; 1407 1408 switch (type) { 1409 1410 case T_FP_EXCEPTION_IEEE + T_USER: /* FPU arithmetic exception */ 1411 /* 1412 * FPU arithmetic exception - fake up a fpq if we 1413 * came here directly from _fp_ieee_exception, 1414 * which is indicated by a zero fpu_qcnt. 1415 */ 1416 fp = lwptofpu(curthread->t_lwp); 1417 utrapp = curthread->t_procp->p_utraps; 1418 if (fp->fpu_qcnt == 0) { 1419 inst = fetch_user_instr((caddr_t)rp->r_pc); 1420 lwp->lwp_state = LWP_SYS; 1421 pfpq = &fp->fpu_q->FQu.fpq; 1422 pfpq->fpq_addr = (uint32_t *)rp->r_pc; 1423 pfpq->fpq_instr = inst; 1424 fp->fpu_qcnt = 1; 1425 fp->fpu_q_entrysize = sizeof (struct _fpq); 1426 #ifdef SF_V9_TABLE_28 1427 /* 1428 * Spitfire and blackbird followed the SPARC V9 manual 1429 * paragraph 3 of section 5.1.7.9 FSR_current_exception 1430 * (cexc) for setting fsr.cexc bits on underflow and 1431 * overflow traps when the fsr.tem.inexact bit is set, 1432 * instead of following Table 28. Bugid 1263234. 1433 */ 1434 { 1435 extern int spitfire_bb_fsr_bug; 1436 1437 if (spitfire_bb_fsr_bug && 1438 (fp->fpu_fsr & FSR_TEM_NX)) { 1439 if (((fp->fpu_fsr & FSR_TEM_OF) == 0) && 1440 (fp->fpu_fsr & FSR_CEXC_OF)) { 1441 fp->fpu_fsr &= ~FSR_CEXC_OF; 1442 fp->fpu_fsr |= FSR_CEXC_NX; 1443 _fp_write_pfsr(&fp->fpu_fsr); 1444 siginfo.si_code = FPE_FLTRES; 1445 } 1446 if (((fp->fpu_fsr & FSR_TEM_UF) == 0) && 1447 (fp->fpu_fsr & FSR_CEXC_UF)) { 1448 fp->fpu_fsr &= ~FSR_CEXC_UF; 1449 fp->fpu_fsr |= FSR_CEXC_NX; 1450 _fp_write_pfsr(&fp->fpu_fsr); 1451 siginfo.si_code = FPE_FLTRES; 1452 } 1453 } 1454 } 1455 #endif /* SF_V9_TABLE_28 */ 1456 rp->r_pc = rp->r_npc; 1457 rp->r_npc += 4; 1458 } else if (utrapp && utrapp[UT_FP_EXCEPTION_IEEE_754]) { 1459 /* 1460 * The user had a trap handler installed. Jump to 1461 * the trap handler instead of signalling the process. 1462 */ 1463 rp->r_pc = (long)utrapp[UT_FP_EXCEPTION_IEEE_754]; 1464 rp->r_npc = rp->r_pc + 4; 1465 break; 1466 } 1467 siginfo.si_signo = SIGFPE; 1468 fault = FLTFPE; 1469 break; 1470 1471 case T_DATA_EXCEPTION + T_USER: /* user data access exception */ 1472 siginfo.si_signo = SIGSEGV; 1473 fault = FLTBOUNDS; 1474 break; 1475 1476 case T_LDDF_ALIGN + T_USER: /* 64 bit user lddfa alignment error */ 1477 case T_STDF_ALIGN + T_USER: /* 64 bit user stdfa alignment error */ 1478 alignfaults++; 1479 lwp->lwp_state = LWP_SYS; 1480 if (&vis1_partial_support != NULL) { 1481 bzero(&siginfo, sizeof (siginfo)); 1482 if (vis1_partial_support(rp, 1483 &siginfo, &fault) == 0) 1484 goto out; 1485 } 1486 if (do_unaligned(rp, &badaddr) == SIMU_SUCCESS) { 1487 rp->r_pc = rp->r_npc; 1488 rp->r_npc += 4; 1489 goto out; 1490 } 1491 fp = lwptofpu(curthread->t_lwp); 1492 fp->fpu_qcnt = 0; 1493 siginfo.si_signo = SIGSEGV; 1494 siginfo.si_code = SEGV_MAPERR; 1495 siginfo.si_addr = badaddr; 1496 fault = FLTBOUNDS; 1497 break; 1498 1499 case T_ALIGNMENT + T_USER: /* user alignment error */ 1500 /* 1501 * If the user has to do unaligned references 1502 * the ugly stuff gets done here. 1503 * Only handles vanilla loads and stores. 1504 */ 1505 alignfaults++; 1506 if (p->p_fixalignment) { 1507 if (do_unaligned(rp, &badaddr) == SIMU_SUCCESS) { 1508 rp->r_pc = rp->r_npc; 1509 rp->r_npc += 4; 1510 goto out; 1511 } 1512 siginfo.si_signo = SIGSEGV; 1513 siginfo.si_code = SEGV_MAPERR; 1514 siginfo.si_addr = badaddr; 1515 fault = FLTBOUNDS; 1516 } else { 1517 siginfo.si_signo = SIGBUS; 1518 siginfo.si_code = BUS_ADRALN; 1519 if (rp->r_pc & 3) { /* offending address, if pc */ 1520 siginfo.si_addr = (caddr_t)rp->r_pc; 1521 } else { 1522 if (calc_memaddr(rp, &badaddr) == SIMU_UNALIGN) 1523 siginfo.si_addr = badaddr; 1524 else 1525 siginfo.si_addr = (caddr_t)rp->r_pc; 1526 } 1527 fault = FLTACCESS; 1528 } 1529 break; 1530 1531 case T_UNIMP_INSTR + T_USER: /* illegal instruction fault */ 1532 siginfo.si_signo = SIGILL; 1533 inst = fetch_user_instr((caddr_t)rp->r_pc); 1534 op3 = (inst >> 19) & 0x3F; 1535 if ((op3 == IOP_V8_STQFA) || (op3 == IOP_V8_STDFA)) 1536 siginfo.si_code = ILL_ILLADR; 1537 else 1538 siginfo.si_code = ILL_ILLTRP; 1539 fault = FLTILL; 1540 break; 1541 1542 default: 1543 (void) die(type, rp, addr, 0); 1544 /*NOTREACHED*/ 1545 } 1546 1547 /* 1548 * We can't get here from a system trap 1549 * Never restart any instruction which got here from an fp trap. 1550 */ 1551 ASSERT(type & T_USER); 1552 1553 trap_cleanup(rp, fault, &siginfo, 0); 1554 out: 1555 trap_rtt(); 1556 (void) new_mstate(curthread, mstate); 1557 } 1558 1559 void 1560 trap_rtt(void) 1561 { 1562 klwp_id_t lwp = ttolwp(curthread); 1563 1564 /* 1565 * Restore register window if a debugger modified it. 1566 * Set up to perform a single-step if a debugger requested it. 1567 */ 1568 if (lwp->lwp_pcb.pcb_xregstat != XREGNONE) 1569 xregrestore(lwp, 0); 1570 1571 /* 1572 * Set state to LWP_USER here so preempt won't give us a kernel 1573 * priority if it occurs after this point. Call CL_TRAPRET() to 1574 * restore the user-level priority. 1575 * 1576 * It is important that no locks (other than spinlocks) be entered 1577 * after this point before returning to user mode (unless lwp_state 1578 * is set back to LWP_SYS). 1579 */ 1580 lwp->lwp_state = LWP_USER; 1581 if (curthread->t_trapret) { 1582 curthread->t_trapret = 0; 1583 thread_lock(curthread); 1584 CL_TRAPRET(curthread); 1585 thread_unlock(curthread); 1586 } 1587 if (CPU->cpu_runrun || curthread->t_schedflag & TS_ANYWAITQ) 1588 preempt(); 1589 prunstop(); 1590 if (lwp->lwp_pcb.pcb_step != STEP_NONE) 1591 prdostep(); 1592 1593 TRACE_0(TR_FAC_TRAP, TR_C_TRAP_HANDLER_EXIT, "C_trap_handler_exit"); 1594 } 1595 1596 #define IS_LDASI(o) \ 1597 ((o) == (uint32_t)0xC0C00000 || (o) == (uint32_t)0xC0800000 || \ 1598 (o) == (uint32_t)0xC1800000) 1599 #define IS_IMM_ASI(i) (((i) & 0x2000) == 0) 1600 #define IS_ASINF(a) (((a) & 0xF6) == 0x82) 1601 #define IS_LDDA(i) (((i) & 0xC1F80000) == 0xC0980000) 1602 1603 static int 1604 nfload(struct regs *rp, int *instrp) 1605 { 1606 uint_t instr, asi, op3, rd; 1607 size_t len; 1608 struct as *as; 1609 caddr_t addr; 1610 FPU_DREGS_TYPE zero; 1611 extern int segnf_create(); 1612 1613 if (USERMODE(rp->r_tstate)) 1614 instr = fetch_user_instr((caddr_t)rp->r_pc); 1615 else 1616 instr = *(int *)rp->r_pc; 1617 1618 if (instrp) 1619 *instrp = instr; 1620 1621 op3 = (uint_t)(instr & 0xC1E00000); 1622 if (!IS_LDASI(op3)) 1623 return (0); 1624 if (IS_IMM_ASI(instr)) 1625 asi = (instr & 0x1FE0) >> 5; 1626 else 1627 asi = (uint_t)((rp->r_tstate >> TSTATE_ASI_SHIFT) & 1628 TSTATE_ASI_MASK); 1629 if (!IS_ASINF(asi)) 1630 return (0); 1631 if (calc_memaddr(rp, &addr) == SIMU_SUCCESS) { 1632 len = 1; 1633 as = USERMODE(rp->r_tstate) ? ttoproc(curthread)->p_as : &kas; 1634 as_rangelock(as); 1635 if (as_gap(as, len, &addr, &len, 0, addr) == 0) 1636 (void) as_map(as, addr, len, segnf_create, NULL); 1637 as_rangeunlock(as); 1638 } 1639 zero = 0; 1640 rd = (instr >> 25) & 0x1f; 1641 if (IS_FLOAT(instr)) { 1642 uint_t dbflg = ((instr >> 19) & 3) == 3; 1643 1644 if (dbflg) { /* clever v9 reg encoding */ 1645 if (rd & 1) 1646 rd = (rd & 0x1e) | 0x20; 1647 rd >>= 1; 1648 } 1649 if (fpu_exists) { 1650 if (!(_fp_read_fprs() & FPRS_FEF)) 1651 fp_enable(); 1652 1653 if (dbflg) 1654 _fp_write_pdreg(&zero, rd); 1655 else 1656 _fp_write_pfreg((uint_t *)&zero, rd); 1657 } else { 1658 kfpu_t *fp = lwptofpu(curthread->t_lwp); 1659 1660 if (!fp->fpu_en) 1661 fp_enable(); 1662 1663 if (dbflg) 1664 fp->fpu_fr.fpu_dregs[rd] = zero; 1665 else 1666 fp->fpu_fr.fpu_regs[rd] = 0; 1667 } 1668 } else { 1669 (void) putreg(&zero, rp, rd, &addr); 1670 if (IS_LDDA(instr)) 1671 (void) putreg(&zero, rp, rd + 1, &addr); 1672 } 1673 rp->r_pc = rp->r_npc; 1674 rp->r_npc += 4; 1675 return (1); 1676 } 1677 1678 kmutex_t atomic_nc_mutex; 1679 1680 /* 1681 * The following couple of routines are for userland drivers which 1682 * do atomics to noncached addresses. This sort of worked on previous 1683 * platforms -- the operation really wasn't atomic, but it didn't generate 1684 * a trap as sun4u systems do. 1685 */ 1686 static int 1687 swap_nc(struct regs *rp, int instr) 1688 { 1689 uint64_t rdata, mdata; 1690 caddr_t addr, badaddr; 1691 uint_t tmp, rd; 1692 1693 (void) flush_user_windows_to_stack(NULL); 1694 rd = (instr >> 25) & 0x1f; 1695 if (calc_memaddr(rp, &addr) != SIMU_SUCCESS) 1696 return (0); 1697 if (getreg(rp, rd, &rdata, &badaddr)) 1698 return (0); 1699 mutex_enter(&atomic_nc_mutex); 1700 if (fuword32(addr, &tmp) == -1) { 1701 mutex_exit(&atomic_nc_mutex); 1702 return (0); 1703 } 1704 mdata = (u_longlong_t)tmp; 1705 if (suword32(addr, (uint32_t)rdata) == -1) { 1706 mutex_exit(&atomic_nc_mutex); 1707 return (0); 1708 } 1709 (void) putreg(&mdata, rp, rd, &badaddr); 1710 mutex_exit(&atomic_nc_mutex); 1711 return (1); 1712 } 1713 1714 static int 1715 ldstub_nc(struct regs *rp, int instr) 1716 { 1717 uint64_t mdata; 1718 caddr_t addr, badaddr; 1719 uint_t rd; 1720 uint8_t tmp; 1721 1722 (void) flush_user_windows_to_stack(NULL); 1723 rd = (instr >> 25) & 0x1f; 1724 if (calc_memaddr(rp, &addr) != SIMU_SUCCESS) 1725 return (0); 1726 mutex_enter(&atomic_nc_mutex); 1727 if (fuword8(addr, &tmp) == -1) { 1728 mutex_exit(&atomic_nc_mutex); 1729 return (0); 1730 } 1731 mdata = (u_longlong_t)tmp; 1732 if (suword8(addr, (uint8_t)0xff) == -1) { 1733 mutex_exit(&atomic_nc_mutex); 1734 return (0); 1735 } 1736 (void) putreg(&mdata, rp, rd, &badaddr); 1737 mutex_exit(&atomic_nc_mutex); 1738 return (1); 1739 } 1740 1741 /* 1742 * This function helps instr_size() determine the operand size. 1743 * It is called for the extended ldda/stda asi's. 1744 */ 1745 int 1746 extended_asi_size(int asi) 1747 { 1748 switch (asi) { 1749 case ASI_PST8_P: 1750 case ASI_PST8_S: 1751 case ASI_PST16_P: 1752 case ASI_PST16_S: 1753 case ASI_PST32_P: 1754 case ASI_PST32_S: 1755 case ASI_PST8_PL: 1756 case ASI_PST8_SL: 1757 case ASI_PST16_PL: 1758 case ASI_PST16_SL: 1759 case ASI_PST32_PL: 1760 case ASI_PST32_SL: 1761 return (8); 1762 case ASI_FL8_P: 1763 case ASI_FL8_S: 1764 case ASI_FL8_PL: 1765 case ASI_FL8_SL: 1766 return (1); 1767 case ASI_FL16_P: 1768 case ASI_FL16_S: 1769 case ASI_FL16_PL: 1770 case ASI_FL16_SL: 1771 return (2); 1772 case ASI_BLK_P: 1773 case ASI_BLK_S: 1774 case ASI_BLK_PL: 1775 case ASI_BLK_SL: 1776 case ASI_BLK_COMMIT_P: 1777 case ASI_BLK_COMMIT_S: 1778 return (64); 1779 } 1780 1781 return (0); 1782 } 1783 1784 /* 1785 * Patch non-zero to disable preemption of threads in the kernel. 1786 */ 1787 int IGNORE_KERNEL_PREEMPTION = 0; /* XXX - delete this someday */ 1788 1789 struct kpreempt_cnts { /* kernel preemption statistics */ 1790 int kpc_idle; /* executing idle thread */ 1791 int kpc_intr; /* executing interrupt thread */ 1792 int kpc_clock; /* executing clock thread */ 1793 int kpc_blocked; /* thread has blocked preemption (t_preempt) */ 1794 int kpc_notonproc; /* thread is surrendering processor */ 1795 int kpc_inswtch; /* thread has ratified scheduling decision */ 1796 int kpc_prilevel; /* processor interrupt level is too high */ 1797 int kpc_apreempt; /* asynchronous preemption */ 1798 int kpc_spreempt; /* synchronous preemption */ 1799 } kpreempt_cnts; 1800 1801 /* 1802 * kernel preemption: forced rescheduling 1803 * preempt the running kernel thread. 1804 */ 1805 void 1806 kpreempt(int asyncspl) 1807 { 1808 if (IGNORE_KERNEL_PREEMPTION) { 1809 aston(CPU->cpu_dispthread); 1810 return; 1811 } 1812 /* 1813 * Check that conditions are right for kernel preemption 1814 */ 1815 do { 1816 if (curthread->t_preempt) { 1817 /* 1818 * either a privileged thread (idle, panic, interrupt) 1819 * or will check when t_preempt is lowered 1820 * We need to specifically handle the case where 1821 * the thread is in the middle of swtch (resume has 1822 * been called) and has its t_preempt set 1823 * [idle thread and a thread which is in kpreempt 1824 * already] and then a high priority thread is 1825 * available in the local dispatch queue. 1826 * In this case the resumed thread needs to take a 1827 * trap so that it can call kpreempt. We achieve 1828 * this by using siron(). 1829 * How do we detect this condition: 1830 * idle thread is running and is in the midst of 1831 * resume: curthread->t_pri == -1 && CPU->dispthread 1832 * != CPU->thread 1833 * Need to ensure that this happens only at high pil 1834 * resume is called at high pil 1835 * Only in resume_from_idle is the pil changed. 1836 */ 1837 if (curthread->t_pri < 0) { 1838 kpreempt_cnts.kpc_idle++; 1839 if (CPU->cpu_dispthread != CPU->cpu_thread) 1840 siron(); 1841 } else if (curthread->t_flag & T_INTR_THREAD) { 1842 kpreempt_cnts.kpc_intr++; 1843 if (curthread->t_pil == CLOCK_LEVEL) 1844 kpreempt_cnts.kpc_clock++; 1845 } else { 1846 kpreempt_cnts.kpc_blocked++; 1847 if (CPU->cpu_dispthread != CPU->cpu_thread) 1848 siron(); 1849 } 1850 aston(CPU->cpu_dispthread); 1851 return; 1852 } 1853 if (curthread->t_state != TS_ONPROC || 1854 curthread->t_disp_queue != CPU->cpu_disp) { 1855 /* this thread will be calling swtch() shortly */ 1856 kpreempt_cnts.kpc_notonproc++; 1857 if (CPU->cpu_thread != CPU->cpu_dispthread) { 1858 /* already in swtch(), force another */ 1859 kpreempt_cnts.kpc_inswtch++; 1860 siron(); 1861 } 1862 return; 1863 } 1864 1865 if (((asyncspl != KPREEMPT_SYNC) ? spltoipl(asyncspl) : 1866 getpil()) >= DISP_LEVEL) { 1867 /* 1868 * We can't preempt this thread if it is at 1869 * a PIL >= DISP_LEVEL since it may be holding 1870 * a spin lock (like sched_lock). 1871 */ 1872 siron(); /* check back later */ 1873 kpreempt_cnts.kpc_prilevel++; 1874 return; 1875 } 1876 1877 /* 1878 * block preemption so we don't have multiple preemptions 1879 * pending on the interrupt stack 1880 */ 1881 curthread->t_preempt++; 1882 if (asyncspl != KPREEMPT_SYNC) { 1883 splx(asyncspl); 1884 kpreempt_cnts.kpc_apreempt++; 1885 } else 1886 kpreempt_cnts.kpc_spreempt++; 1887 1888 preempt(); 1889 curthread->t_preempt--; 1890 } while (CPU->cpu_kprunrun); 1891 } 1892 1893 static enum seg_rw 1894 get_accesstype(struct regs *rp) 1895 { 1896 uint32_t instr; 1897 1898 if (USERMODE(rp->r_tstate)) 1899 instr = fetch_user_instr((caddr_t)rp->r_pc); 1900 else 1901 instr = *(uint32_t *)rp->r_pc; 1902 1903 if (IS_FLUSH(instr)) 1904 return (S_OTHER); 1905 1906 if (IS_STORE(instr)) 1907 return (S_WRITE); 1908 else 1909 return (S_READ); 1910 } 1911 1912 /* 1913 * Handle an asynchronous hardware error. 1914 * The policy is currently to send a hardware error contract event to 1915 * the process's process contract and to kill the process. Eventually 1916 * we may want to instead send a special signal whose default 1917 * disposition is to generate the contract event. 1918 */ 1919 void 1920 trap_async_hwerr(void) 1921 { 1922 k_siginfo_t si; 1923 proc_t *p = ttoproc(curthread); 1924 extern void print_msg_hwerr(ctid_t ct_id, proc_t *p); 1925 1926 errorq_drain(ue_queue); /* flush pending async error messages */ 1927 1928 print_msg_hwerr(p->p_ct_process->conp_contract.ct_id, p); 1929 1930 contract_process_hwerr(p->p_ct_process, p); 1931 1932 bzero(&si, sizeof (k_siginfo_t)); 1933 si.si_signo = SIGKILL; 1934 si.si_code = SI_NOINFO; 1935 trapsig(&si, 1); 1936 } 1937 1938 /* 1939 * Handle bus error and bus timeout for a user process by sending SIGBUS 1940 * The type is either ASYNC_BERR or ASYNC_BTO. 1941 */ 1942 void 1943 trap_async_berr_bto(int type, struct regs *rp) 1944 { 1945 k_siginfo_t si; 1946 1947 errorq_drain(ue_queue); /* flush pending async error messages */ 1948 bzero(&si, sizeof (k_siginfo_t)); 1949 1950 si.si_signo = SIGBUS; 1951 si.si_code = (type == ASYNC_BERR ? BUS_OBJERR : BUS_ADRERR); 1952 si.si_addr = (caddr_t)rp->r_pc; /* AFAR unavailable - future RFE */ 1953 si.si_errno = ENXIO; 1954 1955 trapsig(&si, 1); 1956 } --- EOF ---