|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1988 University of Utah. ! 3: * Copyright (c) 1982, 1986, 1990 The Regents of the University of California. ! 4: * All rights reserved. ! 5: * ! 6: * This code is derived from software contributed to Berkeley by ! 7: * the Systems Programming Group of the University of Utah Computer ! 8: * Science Department. ! 9: * ! 10: * Redistribution is only permitted until one year after the first shipment ! 11: * of 4.4BSD by the Regents. Otherwise, redistribution and use in source and ! 12: * binary forms are permitted provided that: (1) source distributions retain ! 13: * this entire copyright notice and comment, and (2) distributions including ! 14: * binaries display the following acknowledgement: This product includes ! 15: * software developed by the University of California, Berkeley and its ! 16: * contributors'' in the documentation or other materials provided with the ! 17: * distribution and in all advertising materials mentioning features or use ! 18: * of this software. Neither the name of the University nor the names of ! 19: * its contributors may be used to endorse or promote products derived from ! 20: * this software without specific prior written permission. ! 21: * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ! 22: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ! 23: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 24: * ! 25: * from: Utah $Hdr: trap.c 1.28 89/09/25$ ! 26: * ! 27: * @(#)trap.c 7.7 (Berkeley) 6/25/90 ! 28: */ ! 29: ! 30: #include "cpu.h" ! 31: #include "psl.h" ! 32: #include "reg.h" ! 33: #include "pte.h" ! 34: #include "mtpr.h" ! 35: ! 36: #include "param.h" ! 37: #include "systm.h" ! 38: #include "user.h" ! 39: #include "proc.h" ! 40: #include "seg.h" ! 41: #include "trap.h" ! 42: #include "acct.h" ! 43: #include "kernel.h" ! 44: #include "vm.h" ! 45: #include "cmap.h" ! 46: #include "syslog.h" ! 47: #ifdef KTRACE ! 48: #include "ktrace.h" ! 49: #endif ! 50: ! 51: #ifdef HPUXCOMPAT ! 52: #include "../hpux/hpux.h" ! 53: #endif ! 54: ! 55: #define USER 040 /* user-mode flag added to type */ ! 56: ! 57: struct sysent sysent[]; ! 58: int nsysent; ! 59: ! 60: char *trap_type[] = { ! 61: "Bus error", ! 62: "Address error", ! 63: "Illegal instruction", ! 64: "Zero divide", ! 65: "CHK instruction", ! 66: "TRAPV instruction", ! 67: "Privilege violation", ! 68: "Trace trap", ! 69: "MMU fault", ! 70: "SSIR trap", ! 71: "Format error", ! 72: "68881 exception", ! 73: "Coprocessor violation", ! 74: "Async system trap" ! 75: }; ! 76: #define TRAP_TYPES (sizeof trap_type / sizeof trap_type[0]) ! 77: ! 78: #ifdef DEBUG ! 79: int mmudebug = 0; ! 80: #endif ! 81: ! 82: /* ! 83: * Called from the trap handler when a processor trap occurs. ! 84: */ ! 85: /*ARGSUSED*/ ! 86: trap(type, code, v, frame) ! 87: int type; ! 88: unsigned code; ! 89: register unsigned v; ! 90: struct frame frame; ! 91: { ! 92: register int i; ! 93: unsigned ucode = 0; ! 94: register struct proc *p = u.u_procp; ! 95: struct timeval syst; ! 96: unsigned ncode; ! 97: ! 98: cnt.v_trap++; ! 99: syst = u.u_ru.ru_stime; ! 100: if (USERMODE(frame.f_sr)) { ! 101: type |= USER; ! 102: u.u_ar0 = frame.f_regs; ! 103: } ! 104: switch (type) { ! 105: ! 106: default: ! 107: dopanic: ! 108: #ifdef KGDB ! 109: if (!panicstr && kgdb_trap(type, code, v, &frame)) ! 110: return; ! 111: #endif ! 112: printf("trap type %d, code = %x, v = %x\n", type, code, v); ! 113: regdump(frame.f_regs, 128); ! 114: type &= ~USER; ! 115: if ((unsigned)type < TRAP_TYPES) ! 116: panic(trap_type[type]); ! 117: panic("trap"); ! 118: ! 119: case T_BUSERR: /* kernel bus error */ ! 120: if (!u.u_pcb.pcb_onfault) ! 121: goto dopanic; ! 122: /* ! 123: * If we have arranged to catch this fault in any of the ! 124: * copy to/from user space routines, set PC to return to ! 125: * indicated location and set flag informing buserror code ! 126: * that it may need to clean up stack frame. ! 127: */ ! 128: copyfault: ! 129: frame.f_pc = (int) u.u_pcb.pcb_onfault; ! 130: frame.f_stackadj = -1; ! 131: return; ! 132: ! 133: case T_BUSERR+USER: /* bus error */ ! 134: case T_ADDRERR+USER: /* address error */ ! 135: i = SIGBUS; ! 136: break; ! 137: ! 138: #ifdef FPCOPROC ! 139: case T_COPERR: /* kernel coprocessor violation */ ! 140: #endif ! 141: case T_FMTERR: /* kernel format error */ ! 142: /* ! 143: * The user has most likely trashed the RTE or FP state info ! 144: * in the stack frame of a signal handler. ! 145: */ ! 146: type |= USER; ! 147: printf("pid %d: kernel %s exception\n", u.u_procp->p_pid, ! 148: type==T_COPERR ? "coprocessor" : "format"); ! 149: u.u_signal[SIGILL] = SIG_DFL; ! 150: i = sigmask(SIGILL); ! 151: p->p_sigignore &= ~i; ! 152: p->p_sigcatch &= ~i; ! 153: p->p_sigmask &= ~i; ! 154: i = SIGILL; ! 155: ucode = frame.f_format; /* XXX was ILL_RESAD_FAULT */ ! 156: break; ! 157: ! 158: #ifdef FPCOPROC ! 159: case T_COPERR+USER: /* user coprocessor violation */ ! 160: /* What is a proper response here? */ ! 161: ucode = 0; ! 162: i = SIGFPE; ! 163: break; ! 164: ! 165: case T_FPERR+USER: /* 68881 exceptions */ ! 166: /* ! 167: * We pass along the 68881 status register which locore stashed ! 168: * in code for us. Note that there is a possibility that the ! 169: * bit pattern of this register will conflict with one of the ! 170: * FPE_* codes defined in signal.h. Fortunately for us, the ! 171: * only such codes we use are all in the range 1-7 and the low ! 172: * 3 bits of the status register are defined as 0 so there is ! 173: * no clash. ! 174: */ ! 175: ucode = code; ! 176: i = SIGFPE; ! 177: break; ! 178: #endif ! 179: ! 180: case T_ILLINST+USER: /* illegal instruction fault */ ! 181: #ifdef HPUXCOMPAT ! 182: if (u.u_procp->p_flag & SHPUX) { ! 183: ucode = HPUX_ILL_ILLINST_TRAP; ! 184: i = SIGILL; ! 185: break; ! 186: } ! 187: /* fall through */ ! 188: #endif ! 189: case T_PRIVINST+USER: /* privileged instruction fault */ ! 190: #ifdef HPUXCOMPAT ! 191: if (u.u_procp->p_flag & SHPUX) ! 192: ucode = HPUX_ILL_PRIV_TRAP; ! 193: else ! 194: #endif ! 195: ucode = frame.f_format; /* XXX was ILL_PRIVIN_FAULT */ ! 196: i = SIGILL; ! 197: break; ! 198: ! 199: case T_ZERODIV+USER: /* Divide by zero */ ! 200: #ifdef HPUXCOMPAT ! 201: if (u.u_procp->p_flag & SHPUX) ! 202: ucode = HPUX_FPE_INTDIV_TRAP; ! 203: else ! 204: #endif ! 205: ucode = frame.f_format; /* XXX was FPE_INTDIV_TRAP */ ! 206: i = SIGFPE; ! 207: break; ! 208: ! 209: case T_CHKINST+USER: /* CHK instruction trap */ ! 210: #ifdef HPUXCOMPAT ! 211: if (u.u_procp->p_flag & SHPUX) { ! 212: /* handled differently under hp-ux */ ! 213: i = SIGILL; ! 214: ucode = HPUX_ILL_CHK_TRAP; ! 215: break; ! 216: } ! 217: #endif ! 218: ucode = frame.f_format; /* XXX was FPE_SUBRNG_TRAP */ ! 219: i = SIGFPE; ! 220: break; ! 221: ! 222: case T_TRAPVINST+USER: /* TRAPV instruction trap */ ! 223: #ifdef HPUXCOMPAT ! 224: if (u.u_procp->p_flag & SHPUX) { ! 225: /* handled differently under hp-ux */ ! 226: i = SIGILL; ! 227: ucode = HPUX_ILL_TRAPV_TRAP; ! 228: break; ! 229: } ! 230: #endif ! 231: ucode = frame.f_format; /* XXX was FPE_INTOVF_TRAP */ ! 232: i = SIGFPE; ! 233: break; ! 234: ! 235: /* ! 236: * XXX: Trace traps are a nightmare. ! 237: * ! 238: * HP-UX uses trap #1 for breakpoints, ! 239: * HPBSD uses trap #2, ! 240: * SUN 3.x uses trap #15, ! 241: * KGDB uses trap #15 (for kernel breakpoints). ! 242: * ! 243: * HPBSD and HP-UX traps both get mapped by locore.s into T_TRACE. ! 244: * SUN 3.x traps get passed through as T_TRAP15 and are not really ! 245: * supported yet. KGDB traps are also passed through as T_TRAP15 ! 246: * and are not used yet. ! 247: */ ! 248: case T_TRACE: /* kernel trace trap */ ! 249: case T_TRAP15: /* SUN (or KGDB) kernel trace trap */ ! 250: #ifdef KGDB ! 251: if (kgdb_trap(type, code, v, &frame)) ! 252: return; ! 253: #endif ! 254: frame.f_sr &= ~PSL_T; ! 255: i = SIGTRAP; ! 256: break; ! 257: ! 258: case T_TRACE+USER: /* user trace trap */ ! 259: case T_TRAP15+USER: /* SUN user trace trap */ ! 260: frame.f_sr &= ~PSL_T; ! 261: i = SIGTRAP; ! 262: break; ! 263: ! 264: case T_ASTFLT: /* system async trap, cannot happen */ ! 265: goto dopanic; ! 266: ! 267: case T_ASTFLT+USER: /* user async trap */ ! 268: astoff(); ! 269: /* ! 270: * We check for software interrupts first. This is because ! 271: * they are at a higher level than ASTs, and on a VAX would ! 272: * interrupt the AST. We assume that if we are processing ! 273: * an AST that we must be at IPL0 so we don't bother to ! 274: * check. Note that we ensure that we are at least at SIR ! 275: * IPL while processing the SIR. ! 276: */ ! 277: spl1(); ! 278: /* fall into... */ ! 279: ! 280: case T_SSIR: /* software interrupt */ ! 281: case T_SSIR+USER: ! 282: if (ssir & SIR_NET) { ! 283: siroff(SIR_NET); ! 284: cnt.v_soft++; ! 285: netintr(); ! 286: } ! 287: if (ssir & SIR_CLOCK) { ! 288: siroff(SIR_CLOCK); ! 289: cnt.v_soft++; ! 290: softclock((caddr_t)frame.f_pc, (int)frame.f_sr); ! 291: } ! 292: /* ! 293: * If this was not an AST trap, we are all done. ! 294: */ ! 295: if (type != T_ASTFLT+USER) { ! 296: cnt.v_trap--; ! 297: return; ! 298: } ! 299: spl0(); ! 300: #ifndef PROFTIMER ! 301: if ((u.u_procp->p_flag&SOWEUPC) && u.u_prof.pr_scale) { ! 302: addupc(frame.f_pc, &u.u_prof, 1); ! 303: u.u_procp->p_flag &= ~SOWEUPC; ! 304: } ! 305: #endif ! 306: goto out; ! 307: ! 308: case T_MMUFLT: /* kernel mode page fault */ ! 309: /* ! 310: * Could be caused by a page fault in one of the copy to/from ! 311: * user space routines. If so, we will have a catch address. ! 312: */ ! 313: if (!u.u_pcb.pcb_onfault) ! 314: goto dopanic; ! 315: /* fall into ... */ ! 316: ! 317: case T_MMUFLT+USER: /* page fault */ ! 318: /* ! 319: printf("trap: T_MMUFLT pid %d, code %x, v %x, pc %x, ps %x\n", ! 320: p->p_pid, code, v, frame.f_pc, frame.f_sr); ! 321: */ ! 322: if (v >= USRSTACK) { ! 323: if (type == T_MMUFLT) ! 324: goto copyfault; ! 325: i = SIGSEGV; ! 326: break; ! 327: } ! 328: ncode = code >> 16; ! 329: #if defined(HP330) || defined(HP360) || defined(HP370) ! 330: /* ! 331: * Crudely map PMMU faults into HP MMU faults. ! 332: */ ! 333: if (mmutype != MMU_HP) { ! 334: int ocode = ncode; ! 335: ncode = 0; ! 336: if (ocode & PMMU_WP) ! 337: ncode |= MMU_WPF; ! 338: else if (ocode & PMMU_INV) { ! 339: if ((ocode & PMMU_LVLMASK) == 2) ! 340: ncode |= MMU_PF; ! 341: else ! 342: ncode |= MMU_PTF; ! 343: } ! 344: /* ! 345: * RMW cycle, must load ATC by hand ! 346: */ ! 347: else if ((code & (SSW_DF|SSW_RM)) == (SSW_DF|SSW_RM)) { ! 348: #ifdef DEBUG ! 349: log(LOG_WARNING, ! 350: "RMW fault at %x: MMUSR %x SSW %x\n", ! 351: v, ocode, code & 0xFFFF); ! 352: #endif ! 353: ploadw((caddr_t)v); ! 354: return; ! 355: } ! 356: /* ! 357: * Fault with no fault bits, should indicate bad ! 358: * hardware but we see this on 340s using starbase ! 359: * sometimes (faults accessing catseye registers) ! 360: */ ! 361: else { ! 362: log(LOG_WARNING, ! 363: "Bad PMMU fault at %x: MMUSR %x SSW %x\n", ! 364: v, ocode, code & 0xFFFF); ! 365: return; ! 366: } ! 367: #ifdef DEBUG ! 368: if (mmudebug && mmudebug == p->p_pid) ! 369: printf("MMU %d: v%x, os%x, ns%x\n", ! 370: p->p_pid, v, ocode, ncode); ! 371: #endif ! 372: } ! 373: #endif ! 374: #ifdef DEBUG ! 375: if ((ncode & (MMU_PTF|MMU_PF|MMU_WPF|MMU_FPE)) == 0) { ! 376: printf("T_MMUFLT with no fault bits\n"); ! 377: goto dopanic; ! 378: } ! 379: #endif ! 380: if (ncode & MMU_PTF) { ! 381: #ifdef DEBUG ! 382: /* ! 383: * NOTE: we use a u_int instead of an ste since the ! 384: * current compiler generates bogus code for some ! 385: * bitfield operations (i.e. attempts to access last ! 386: * word of a page as a longword causing fault). ! 387: */ ! 388: extern struct ste *vtoste(); ! 389: u_int *ste = (u_int *)vtoste(p, v); ! 390: ! 391: if (*ste & SG_V) { ! 392: if (ncode & MMU_WPF) { ! 393: printf("PTF|WPF...\n"); ! 394: if (type == T_MMUFLT) ! 395: goto copyfault; ! 396: i = SIGBUS; ! 397: break; ! 398: } ! 399: printf("MMU_PTF with sg_v, ste@%x = %x\n", ! 400: ste, *ste); ! 401: goto dopanic; ! 402: } ! 403: #endif ! 404: #ifdef HPUXCOMPAT ! 405: if (ISHPMMADDR(v)) { ! 406: extern struct ste *vtoste(); ! 407: u_int *bste, *nste; ! 408: ! 409: bste = (u_int *)vtoste(p, HPMMBASEADDR(v)); ! 410: nste = (u_int *)vtoste(p, v); ! 411: if ((*bste & SG_V) && *nste == SG_NV) { ! 412: *nste = *bste; ! 413: TBIAU(); ! 414: return; ! 415: } ! 416: } ! 417: #endif ! 418: growit: ! 419: if (type == T_MMUFLT) ! 420: goto copyfault; ! 421: if (grow((unsigned)frame.f_regs[SP]) || grow(v)) ! 422: goto out; ! 423: i = SIGSEGV; ! 424: break; ! 425: } ! 426: #ifdef HPUXCOMPAT ! 427: if (ISHPMMADDR(v)) { ! 428: TBIS(v); ! 429: v = HPMMBASEADDR(v); ! 430: } ! 431: #endif ! 432: /* ! 433: * NOTE: WPF without PG_V is possible ! 434: * (e.g. attempt to write shared text which is paged out) ! 435: */ ! 436: if (ncode & MMU_WPF) { ! 437: #ifdef DEBUG ! 438: extern struct ste *vtoste(); ! 439: u_int *ste = (u_int *)vtoste(p, v); ! 440: ! 441: if (!(*ste & SG_V)) { ! 442: printf("MMU_WPF without sg_v, ste@%x = %x\n", ! 443: ste, *ste); ! 444: goto dopanic; ! 445: } ! 446: #endif ! 447: if (type == T_MMUFLT) ! 448: goto copyfault; ! 449: i = SIGBUS; ! 450: break; ! 451: } ! 452: if (ncode & MMU_PF) { ! 453: register u_int vp; ! 454: #ifdef DEBUG ! 455: extern struct ste *vtoste(); ! 456: u_int *ste = (u_int *)vtoste(p, v); ! 457: struct pte *pte; ! 458: ! 459: if (!(*ste & SG_V)) { ! 460: printf("MMU_PF without sg_v, ste@%x = %x\n", ! 461: ste, *ste); ! 462: goto dopanic; ! 463: } ! 464: #endif ! 465: vp = btop(v); ! 466: if (vp >= dptov(p, p->p_dsize) && ! 467: vp < sptov(p, p->p_ssize-1)) ! 468: goto growit; ! 469: #ifdef DEBUG ! 470: pte = vtopte(p, vp); ! 471: if (*(u_int *)pte & PG_V) { ! 472: printf("MMU_PF with pg_v, pte = %x\n", ! 473: *(u_int *)pte); ! 474: goto dopanic; ! 475: } ! 476: #endif ! 477: pagein(v, 0); ! 478: if (type == T_MMUFLT) ! 479: return; ! 480: goto out; ! 481: } ! 482: #ifdef DEBUG ! 483: printf("T_MMUFLT: unrecognized scenerio\n"); ! 484: goto dopanic; ! 485: #endif ! 486: } ! 487: trapsignal(i, ucode); ! 488: if ((type & USER) == 0) ! 489: return; ! 490: out: ! 491: p = u.u_procp; ! 492: if (i = CURSIG(p)) ! 493: psig(i); ! 494: p->p_pri = p->p_usrpri; ! 495: if (runrun) { ! 496: /* ! 497: * Since we are u.u_procp, clock will normally just change ! 498: * our priority without moving us from one queue to another ! 499: * (since the running process is not on a queue.) ! 500: * If that happened after we setrq ourselves but before we ! 501: * swtch()'ed, we might not be on the queue indicated by ! 502: * our priority. ! 503: */ ! 504: (void) splclock(); ! 505: setrq(p); ! 506: u.u_ru.ru_nivcsw++; ! 507: swtch(); ! 508: if (i = CURSIG(p)) ! 509: psig(i); ! 510: } ! 511: if (u.u_prof.pr_scale) { ! 512: int ticks; ! 513: struct timeval *tv = &u.u_ru.ru_stime; ! 514: ! 515: ticks = ((tv->tv_sec - syst.tv_sec) * 1000 + ! 516: (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000); ! 517: if (ticks) { ! 518: #ifdef PROFTIMER ! 519: extern int profscale; ! 520: addupc(frame.f_pc, &u.u_prof, ticks * profscale); ! 521: #else ! 522: addupc(frame.f_pc, &u.u_prof, ticks); ! 523: #endif ! 524: } ! 525: } ! 526: curpri = p->p_pri; ! 527: } ! 528: ! 529: /* ! 530: * Called from the trap handler when a system call occurs ! 531: */ ! 532: /*ARGSUSED*/ ! 533: syscall(code, frame) ! 534: volatile int code; ! 535: struct frame frame; ! 536: { ! 537: register caddr_t params; ! 538: register int i; ! 539: register struct sysent *callp; ! 540: register struct proc *p = u.u_procp; ! 541: int error, opc, numsys; ! 542: struct args { ! 543: int i[8]; ! 544: } args; ! 545: int rval[2]; ! 546: struct timeval syst; ! 547: struct sysent *systab; ! 548: #ifdef HPUXCOMPAT ! 549: extern struct sysent hpuxsysent[]; ! 550: extern int hpuxnsysent, notimp(); ! 551: #endif ! 552: ! 553: cnt.v_syscall++; ! 554: syst = u.u_ru.ru_stime; ! 555: if (!USERMODE(frame.f_sr)) ! 556: panic("syscall"); ! 557: u.u_ar0 = frame.f_regs; ! 558: opc = frame.f_pc - 2; ! 559: systab = sysent; ! 560: numsys = nsysent; ! 561: #ifdef HPUXCOMPAT ! 562: if (p->p_flag & SHPUX) { ! 563: systab = hpuxsysent; ! 564: numsys = hpuxnsysent; ! 565: } ! 566: #endif ! 567: params = (caddr_t)frame.f_regs[SP] + NBPW; ! 568: if (code == 0) { /* indir */ ! 569: code = fuword(params); ! 570: params += NBPW; ! 571: } ! 572: if (code >= numsys) ! 573: callp = &systab[0]; /* indir (illegal) */ ! 574: else ! 575: callp = &systab[code]; ! 576: if ((i = callp->sy_narg * sizeof (int)) && ! 577: (error = copyin(params, (caddr_t)&args, (u_int)i))) { ! 578: #ifdef HPUXCOMPAT ! 579: if (p->p_flag & SHPUX) ! 580: error = bsdtohpuxerrno(error); ! 581: #endif ! 582: frame.f_regs[D0] = (u_char) error; ! 583: frame.f_sr |= PSL_C; /* carry bit */ ! 584: #ifdef KTRACE ! 585: if (KTRPOINT(p, KTR_SYSCALL)) ! 586: ktrsyscall(p->p_tracep, code, callp->sy_narg, args.i); ! 587: #endif ! 588: goto done; ! 589: } ! 590: #ifdef KTRACE ! 591: if (KTRPOINT(p, KTR_SYSCALL)) ! 592: ktrsyscall(p->p_tracep, code, callp->sy_narg, args.i); ! 593: #endif ! 594: rval[0] = 0; ! 595: rval[1] = frame.f_regs[D1]; ! 596: #ifdef HPUXCOMPAT ! 597: /* debug kludge */ ! 598: if (callp->sy_call == notimp) ! 599: error = notimp(u.u_procp, args.i, rval, code, callp->sy_narg); ! 600: else ! 601: #endif ! 602: error = (*callp->sy_call)(u.u_procp, &args, rval); ! 603: if (error == ERESTART) ! 604: frame.f_pc = opc; ! 605: else if (error != EJUSTRETURN) { ! 606: if (error) { ! 607: #ifdef HPUXCOMPAT ! 608: if (p->p_flag & SHPUX) ! 609: error = bsdtohpuxerrno(error); ! 610: #endif ! 611: frame.f_regs[D0] = (u_char) error; ! 612: frame.f_sr |= PSL_C; /* carry bit */ ! 613: } else { ! 614: frame.f_regs[D0] = rval[0]; ! 615: frame.f_regs[D1] = rval[1]; ! 616: frame.f_sr &= ~PSL_C; ! 617: } ! 618: } ! 619: /* else if (error == EJUSTRETURN) */ ! 620: /* nothing to do */ ! 621: ! 622: done: ! 623: /* ! 624: * Reinitialize proc pointer `p' as it may be different ! 625: * if this is a child returning from fork syscall. ! 626: */ ! 627: p = u.u_procp; ! 628: /* ! 629: * XXX the check for sigreturn ensures that we don't ! 630: * attempt to set up a call to a signal handler (sendsig) before ! 631: * we have cleaned up the stack from the last call (sigreturn). ! 632: * Allowing this seems to lock up the machine in certain scenarios. ! 633: * What should really be done is to clean up the signal handling ! 634: * so that this is not a problem. ! 635: */ ! 636: #include "syscall.h" ! 637: if (code != SYS_sigreturn && (i = CURSIG(p))) ! 638: psig(i); ! 639: p->p_pri = p->p_usrpri; ! 640: if (runrun) { ! 641: /* ! 642: * Since we are u.u_procp, clock will normally just change ! 643: * our priority without moving us from one queue to another ! 644: * (since the running process is not on a queue.) ! 645: * If that happened after we setrq ourselves but before we ! 646: * swtch()'ed, we might not be on the queue indicated by ! 647: * our priority. ! 648: */ ! 649: (void) splclock(); ! 650: setrq(p); ! 651: u.u_ru.ru_nivcsw++; ! 652: swtch(); ! 653: if (code != SYS_sigreturn && (i = CURSIG(p))) ! 654: psig(i); ! 655: } ! 656: if (u.u_prof.pr_scale) { ! 657: int ticks; ! 658: struct timeval *tv = &u.u_ru.ru_stime; ! 659: ! 660: ticks = ((tv->tv_sec - syst.tv_sec) * 1000 + ! 661: (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000); ! 662: if (ticks) { ! 663: #ifdef PROFTIMER ! 664: extern int profscale; ! 665: addupc(frame.f_pc, &u.u_prof, ticks * profscale); ! 666: #else ! 667: addupc(frame.f_pc, &u.u_prof, ticks); ! 668: #endif ! 669: } ! 670: } ! 671: curpri = p->p_pri; ! 672: #ifdef KTRACE ! 673: if (KTRPOINT(p, KTR_SYSRET)) ! 674: ktrsysret(p->p_tracep, code, error, rval[0]); ! 675: #endif ! 676: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.