141475Smckusick /* 241475Smckusick * Copyright (c) 1988 University of Utah. 341475Smckusick * Copyright (c) 1982, 1986, 1990 The Regents of the University of California. 441475Smckusick * All rights reserved. 541475Smckusick * 641475Smckusick * This code is derived from software contributed to Berkeley by 741475Smckusick * the Systems Programming Group of the University of Utah Computer 841475Smckusick * Science Department. 941475Smckusick * 1041475Smckusick * %sccs.include.redist.c% 1141475Smckusick * 1241475Smckusick * from: Utah $Hdr: trap.c 1.28 89/09/25$ 1341475Smckusick * 14*45751Smckusick * @(#)trap.c 7.8 (Berkeley) 12/05/90 1541475Smckusick */ 1641475Smckusick 1741475Smckusick #include "cpu.h" 1841475Smckusick #include "psl.h" 1941475Smckusick #include "reg.h" 2041475Smckusick #include "mtpr.h" 2141475Smckusick 2241475Smckusick #include "param.h" 2341475Smckusick #include "systm.h" 2441475Smckusick #include "user.h" 2541475Smckusick #include "proc.h" 2641475Smckusick #include "seg.h" 2741475Smckusick #include "trap.h" 2841475Smckusick #include "acct.h" 2941475Smckusick #include "kernel.h" 3041475Smckusick #include "syslog.h" 3141475Smckusick #ifdef KTRACE 3241475Smckusick #include "ktrace.h" 3341475Smckusick #endif 3441475Smckusick 35*45751Smckusick #include "../vm/vm_param.h" 36*45751Smckusick #include "../vm/pmap.h" 37*45751Smckusick #include "../vm/vm_map.h" 38*45751Smckusick #include "vmmeter.h" 39*45751Smckusick 4041475Smckusick #ifdef HPUXCOMPAT 4141475Smckusick #include "../hpux/hpux.h" 4241475Smckusick #endif 4341475Smckusick 4441475Smckusick #define USER 040 /* user-mode flag added to type */ 4541475Smckusick 4641475Smckusick struct sysent sysent[]; 4741475Smckusick int nsysent; 4841475Smckusick 4941475Smckusick char *trap_type[] = { 5041475Smckusick "Bus error", 5141475Smckusick "Address error", 5241475Smckusick "Illegal instruction", 5341475Smckusick "Zero divide", 5441475Smckusick "CHK instruction", 5541475Smckusick "TRAPV instruction", 5641475Smckusick "Privilege violation", 5741475Smckusick "Trace trap", 5841475Smckusick "MMU fault", 5941475Smckusick "SSIR trap", 6041475Smckusick "Format error", 6141475Smckusick "68881 exception", 6241475Smckusick "Coprocessor violation", 6341475Smckusick "Async system trap" 6441475Smckusick }; 6541475Smckusick #define TRAP_TYPES (sizeof trap_type / sizeof trap_type[0]) 6641475Smckusick 6741475Smckusick #ifdef DEBUG 6841475Smckusick int mmudebug = 0; 6941475Smckusick #endif 7041475Smckusick 7141475Smckusick /* 7241475Smckusick * Called from the trap handler when a processor trap occurs. 7341475Smckusick */ 7441475Smckusick /*ARGSUSED*/ 7541475Smckusick trap(type, code, v, frame) 7641475Smckusick int type; 7741475Smckusick unsigned code; 7841475Smckusick register unsigned v; 7941475Smckusick struct frame frame; 8041475Smckusick { 8141475Smckusick register int i; 8241475Smckusick unsigned ucode = 0; 8341475Smckusick register struct proc *p = u.u_procp; 8441475Smckusick struct timeval syst; 8541475Smckusick unsigned ncode; 8641475Smckusick 8741475Smckusick cnt.v_trap++; 8841475Smckusick syst = u.u_ru.ru_stime; 8941475Smckusick if (USERMODE(frame.f_sr)) { 9041475Smckusick type |= USER; 9141475Smckusick u.u_ar0 = frame.f_regs; 9241475Smckusick } 9341475Smckusick switch (type) { 9441475Smckusick 9541475Smckusick default: 9641475Smckusick dopanic: 9741475Smckusick #ifdef KGDB 9841475Smckusick if (!panicstr && kgdb_trap(type, code, v, &frame)) 9941475Smckusick return; 10041475Smckusick #endif 10141475Smckusick printf("trap type %d, code = %x, v = %x\n", type, code, v); 10241475Smckusick regdump(frame.f_regs, 128); 10341475Smckusick type &= ~USER; 10441475Smckusick if ((unsigned)type < TRAP_TYPES) 10541475Smckusick panic(trap_type[type]); 10641475Smckusick panic("trap"); 10741475Smckusick 10841475Smckusick case T_BUSERR: /* kernel bus error */ 10941475Smckusick if (!u.u_pcb.pcb_onfault) 11041475Smckusick goto dopanic; 11141475Smckusick /* 11241475Smckusick * If we have arranged to catch this fault in any of the 11341475Smckusick * copy to/from user space routines, set PC to return to 11441475Smckusick * indicated location and set flag informing buserror code 11541475Smckusick * that it may need to clean up stack frame. 11641475Smckusick */ 11741475Smckusick copyfault: 11841475Smckusick frame.f_pc = (int) u.u_pcb.pcb_onfault; 11941475Smckusick frame.f_stackadj = -1; 12041475Smckusick return; 12141475Smckusick 12241475Smckusick case T_BUSERR+USER: /* bus error */ 12341475Smckusick case T_ADDRERR+USER: /* address error */ 12441475Smckusick i = SIGBUS; 12541475Smckusick break; 12641475Smckusick 12741475Smckusick #ifdef FPCOPROC 12841475Smckusick case T_COPERR: /* kernel coprocessor violation */ 12941475Smckusick #endif 13041475Smckusick case T_FMTERR: /* kernel format error */ 13141475Smckusick /* 13241475Smckusick * The user has most likely trashed the RTE or FP state info 13341475Smckusick * in the stack frame of a signal handler. 13441475Smckusick */ 13542370Skarels type |= USER; 13641475Smckusick printf("pid %d: kernel %s exception\n", u.u_procp->p_pid, 13741475Smckusick type==T_COPERR ? "coprocessor" : "format"); 13841475Smckusick u.u_signal[SIGILL] = SIG_DFL; 13941475Smckusick i = sigmask(SIGILL); 14041475Smckusick p->p_sigignore &= ~i; 14141475Smckusick p->p_sigcatch &= ~i; 14241475Smckusick p->p_sigmask &= ~i; 14342370Skarels i = SIGILL; 14441475Smckusick ucode = frame.f_format; /* XXX was ILL_RESAD_FAULT */ 14542370Skarels break; 14641475Smckusick 14741475Smckusick #ifdef FPCOPROC 14841475Smckusick case T_COPERR+USER: /* user coprocessor violation */ 14941475Smckusick /* What is a proper response here? */ 15041475Smckusick ucode = 0; 15141475Smckusick i = SIGFPE; 15241475Smckusick break; 15341475Smckusick 15441475Smckusick case T_FPERR+USER: /* 68881 exceptions */ 15541475Smckusick /* 15641475Smckusick * We pass along the 68881 status register which locore stashed 15741475Smckusick * in code for us. Note that there is a possibility that the 15841475Smckusick * bit pattern of this register will conflict with one of the 15941475Smckusick * FPE_* codes defined in signal.h. Fortunately for us, the 16041475Smckusick * only such codes we use are all in the range 1-7 and the low 16141475Smckusick * 3 bits of the status register are defined as 0 so there is 16241475Smckusick * no clash. 16341475Smckusick */ 16441475Smckusick ucode = code; 16541475Smckusick i = SIGFPE; 16641475Smckusick break; 16741475Smckusick #endif 16841475Smckusick 16941475Smckusick case T_ILLINST+USER: /* illegal instruction fault */ 17041475Smckusick #ifdef HPUXCOMPAT 17141475Smckusick if (u.u_procp->p_flag & SHPUX) { 17241475Smckusick ucode = HPUX_ILL_ILLINST_TRAP; 17341475Smckusick i = SIGILL; 17441475Smckusick break; 17541475Smckusick } 17641475Smckusick /* fall through */ 17741475Smckusick #endif 17841475Smckusick case T_PRIVINST+USER: /* privileged instruction fault */ 17941475Smckusick #ifdef HPUXCOMPAT 18041475Smckusick if (u.u_procp->p_flag & SHPUX) 18141475Smckusick ucode = HPUX_ILL_PRIV_TRAP; 18241475Smckusick else 18341475Smckusick #endif 18441475Smckusick ucode = frame.f_format; /* XXX was ILL_PRIVIN_FAULT */ 18541475Smckusick i = SIGILL; 18641475Smckusick break; 18741475Smckusick 18841475Smckusick case T_ZERODIV+USER: /* Divide by zero */ 18941475Smckusick #ifdef HPUXCOMPAT 19041475Smckusick if (u.u_procp->p_flag & SHPUX) 19141475Smckusick ucode = HPUX_FPE_INTDIV_TRAP; 19241475Smckusick else 19341475Smckusick #endif 19441475Smckusick ucode = frame.f_format; /* XXX was FPE_INTDIV_TRAP */ 19541475Smckusick i = SIGFPE; 19641475Smckusick break; 19741475Smckusick 19841475Smckusick case T_CHKINST+USER: /* CHK instruction trap */ 19941475Smckusick #ifdef HPUXCOMPAT 20041475Smckusick if (u.u_procp->p_flag & SHPUX) { 20141475Smckusick /* handled differently under hp-ux */ 20241475Smckusick i = SIGILL; 20341475Smckusick ucode = HPUX_ILL_CHK_TRAP; 20441475Smckusick break; 20541475Smckusick } 20641475Smckusick #endif 20741475Smckusick ucode = frame.f_format; /* XXX was FPE_SUBRNG_TRAP */ 20841475Smckusick i = SIGFPE; 20941475Smckusick break; 21041475Smckusick 21141475Smckusick case T_TRAPVINST+USER: /* TRAPV instruction trap */ 21241475Smckusick #ifdef HPUXCOMPAT 21341475Smckusick if (u.u_procp->p_flag & SHPUX) { 21441475Smckusick /* handled differently under hp-ux */ 21541475Smckusick i = SIGILL; 21641475Smckusick ucode = HPUX_ILL_TRAPV_TRAP; 21741475Smckusick break; 21841475Smckusick } 21941475Smckusick #endif 22041475Smckusick ucode = frame.f_format; /* XXX was FPE_INTOVF_TRAP */ 22141475Smckusick i = SIGFPE; 22241475Smckusick break; 22341475Smckusick 22441475Smckusick /* 22541475Smckusick * XXX: Trace traps are a nightmare. 22641475Smckusick * 22741475Smckusick * HP-UX uses trap #1 for breakpoints, 22841475Smckusick * HPBSD uses trap #2, 22941475Smckusick * SUN 3.x uses trap #15, 23041475Smckusick * KGDB uses trap #15 (for kernel breakpoints). 23141475Smckusick * 23241475Smckusick * HPBSD and HP-UX traps both get mapped by locore.s into T_TRACE. 23341475Smckusick * SUN 3.x traps get passed through as T_TRAP15 and are not really 23441475Smckusick * supported yet. KGDB traps are also passed through as T_TRAP15 23541475Smckusick * and are not used yet. 23641475Smckusick */ 23741475Smckusick case T_TRACE: /* kernel trace trap */ 23841475Smckusick case T_TRAP15: /* SUN (or KGDB) kernel trace trap */ 23941475Smckusick #ifdef KGDB 24041475Smckusick if (kgdb_trap(type, code, v, &frame)) 24141475Smckusick return; 24241475Smckusick #endif 24341475Smckusick frame.f_sr &= ~PSL_T; 24441475Smckusick i = SIGTRAP; 24541475Smckusick break; 24641475Smckusick 24741475Smckusick case T_TRACE+USER: /* user trace trap */ 24841475Smckusick case T_TRAP15+USER: /* SUN user trace trap */ 24941475Smckusick frame.f_sr &= ~PSL_T; 25041475Smckusick i = SIGTRAP; 25141475Smckusick break; 25241475Smckusick 25343413Shibler case T_ASTFLT: /* system async trap, cannot happen */ 25441475Smckusick goto dopanic; 25541475Smckusick 25643413Shibler case T_ASTFLT+USER: /* user async trap */ 25741475Smckusick astoff(); 25841475Smckusick /* 25941475Smckusick * We check for software interrupts first. This is because 26041475Smckusick * they are at a higher level than ASTs, and on a VAX would 26141475Smckusick * interrupt the AST. We assume that if we are processing 26241475Smckusick * an AST that we must be at IPL0 so we don't bother to 26341475Smckusick * check. Note that we ensure that we are at least at SIR 26441475Smckusick * IPL while processing the SIR. 26541475Smckusick */ 26641475Smckusick spl1(); 26741475Smckusick /* fall into... */ 26841475Smckusick 26941475Smckusick case T_SSIR: /* software interrupt */ 27041475Smckusick case T_SSIR+USER: 27141475Smckusick if (ssir & SIR_NET) { 27241475Smckusick siroff(SIR_NET); 27341475Smckusick cnt.v_soft++; 27441475Smckusick netintr(); 27541475Smckusick } 27641475Smckusick if (ssir & SIR_CLOCK) { 27741475Smckusick siroff(SIR_CLOCK); 27841475Smckusick cnt.v_soft++; 27941475Smckusick softclock((caddr_t)frame.f_pc, (int)frame.f_sr); 28041475Smckusick } 28141475Smckusick /* 28241475Smckusick * If this was not an AST trap, we are all done. 28341475Smckusick */ 28443413Shibler if (type != T_ASTFLT+USER) { 28541475Smckusick cnt.v_trap--; 28641475Smckusick return; 28741475Smckusick } 28841475Smckusick spl0(); 28941475Smckusick #ifndef PROFTIMER 29041475Smckusick if ((u.u_procp->p_flag&SOWEUPC) && u.u_prof.pr_scale) { 29141475Smckusick addupc(frame.f_pc, &u.u_prof, 1); 29241475Smckusick u.u_procp->p_flag &= ~SOWEUPC; 29341475Smckusick } 29441475Smckusick #endif 29541475Smckusick goto out; 29641475Smckusick 29741475Smckusick case T_MMUFLT: /* kernel mode page fault */ 29841475Smckusick /* fall into ... */ 29941475Smckusick 30041475Smckusick case T_MMUFLT+USER: /* page fault */ 301*45751Smckusick { 302*45751Smckusick register vm_offset_t va; 303*45751Smckusick register vm_map_t map; 304*45751Smckusick int rv; 305*45751Smckusick vm_prot_t ftype; 306*45751Smckusick extern vm_map_t kernel_map; 307*45751Smckusick unsigned nss; 308*45751Smckusick 30941475Smckusick /* 310*45751Smckusick * It is only a kernel address space fault iff: 311*45751Smckusick * 1. (type & USER) == 0 and 312*45751Smckusick * 2. pcb_onfault not set or 313*45751Smckusick * 3. pcb_onfault set but supervisor space data fault 314*45751Smckusick * The last can occur during an exec() copyin where the 315*45751Smckusick * argument space is lazy-allocated. 31641475Smckusick */ 317*45751Smckusick if (type == T_MMUFLT && 318*45751Smckusick (!u.u_pcb.pcb_onfault || 319*45751Smckusick (code & (SSW_DF|FC_SUPERD)) == (SSW_DF|FC_SUPERD))) 320*45751Smckusick map = kernel_map; 321*45751Smckusick else 322*45751Smckusick map = u.u_procp->p_map; 323*45751Smckusick if ((code & (SSW_DF|SSW_RW)) == SSW_DF) /* what about RMW? */ 324*45751Smckusick ftype = VM_PROT_READ | VM_PROT_WRITE; 325*45751Smckusick else 326*45751Smckusick ftype = VM_PROT_READ; 327*45751Smckusick va = trunc_page((vm_offset_t)v); 32841475Smckusick #ifdef DEBUG 329*45751Smckusick if (map == kernel_map && va == 0) { 330*45751Smckusick printf("trap: bad kernel access at %x\n", v); 33141475Smckusick goto dopanic; 33241475Smckusick } 33341475Smckusick #endif 33441475Smckusick /* 335*45751Smckusick * XXX: rude hack to make stack limits "work" 33641475Smckusick */ 337*45751Smckusick nss = 0; 338*45751Smckusick if ((caddr_t)va >= u.u_maxsaddr && map != kernel_map) { 339*45751Smckusick nss = clrnd(btoc(USRSTACK-(unsigned)va)); 340*45751Smckusick if (nss > btoc(u.u_rlimit[RLIMIT_STACK].rlim_cur)) { 341*45751Smckusick rv = KERN_FAILURE; 342*45751Smckusick goto nogo; 34341475Smckusick } 34441475Smckusick } 345*45751Smckusick rv = vm_fault(map, va, ftype, FALSE); 346*45751Smckusick if (rv == KERN_SUCCESS) { 347*45751Smckusick /* 348*45751Smckusick * XXX: continuation of rude stack hack 349*45751Smckusick */ 350*45751Smckusick if (nss > u.u_ssize) 351*45751Smckusick u.u_ssize = nss; 35241475Smckusick if (type == T_MMUFLT) 35341475Smckusick return; 35441475Smckusick goto out; 35541475Smckusick } 356*45751Smckusick nogo: 357*45751Smckusick if (type == T_MMUFLT) { 358*45751Smckusick if (u.u_pcb.pcb_onfault) 359*45751Smckusick goto copyfault; 360*45751Smckusick printf("vm_fault(%x, %x, %x, 0) -> %x\n", 361*45751Smckusick map, va, ftype, rv); 362*45751Smckusick printf(" type %x, code [mmu,,ssw]: %x\n", 363*45751Smckusick type, code); 364*45751Smckusick goto dopanic; 365*45751Smckusick } 366*45751Smckusick i = (rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV; 367*45751Smckusick break; 368*45751Smckusick } 36941475Smckusick } 37041475Smckusick trapsignal(i, ucode); 37141475Smckusick if ((type & USER) == 0) 37241475Smckusick return; 37341475Smckusick out: 37441475Smckusick p = u.u_procp; 37542370Skarels if (i = CURSIG(p)) 37642370Skarels psig(i); 37741475Smckusick p->p_pri = p->p_usrpri; 37841475Smckusick if (runrun) { 37941475Smckusick /* 38041475Smckusick * Since we are u.u_procp, clock will normally just change 38141475Smckusick * our priority without moving us from one queue to another 38241475Smckusick * (since the running process is not on a queue.) 38341475Smckusick * If that happened after we setrq ourselves but before we 38441475Smckusick * swtch()'ed, we might not be on the queue indicated by 38541475Smckusick * our priority. 38641475Smckusick */ 38741475Smckusick (void) splclock(); 38841475Smckusick setrq(p); 38941475Smckusick u.u_ru.ru_nivcsw++; 39041475Smckusick swtch(); 39142370Skarels if (i = CURSIG(p)) 39242370Skarels psig(i); 39341475Smckusick } 39441475Smckusick if (u.u_prof.pr_scale) { 39541475Smckusick int ticks; 39641475Smckusick struct timeval *tv = &u.u_ru.ru_stime; 39741475Smckusick 39841475Smckusick ticks = ((tv->tv_sec - syst.tv_sec) * 1000 + 39941475Smckusick (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000); 40041475Smckusick if (ticks) { 40141475Smckusick #ifdef PROFTIMER 40241475Smckusick extern int profscale; 40341475Smckusick addupc(frame.f_pc, &u.u_prof, ticks * profscale); 40441475Smckusick #else 40541475Smckusick addupc(frame.f_pc, &u.u_prof, ticks); 40641475Smckusick #endif 40741475Smckusick } 40841475Smckusick } 40941475Smckusick curpri = p->p_pri; 41041475Smckusick } 41141475Smckusick 41241475Smckusick /* 41341475Smckusick * Called from the trap handler when a system call occurs 41441475Smckusick */ 41541475Smckusick /*ARGSUSED*/ 41641475Smckusick syscall(code, frame) 41741475Smckusick volatile int code; 41841475Smckusick struct frame frame; 41941475Smckusick { 42041475Smckusick register caddr_t params; 42141475Smckusick register int i; 42241475Smckusick register struct sysent *callp; 42342370Skarels register struct proc *p = u.u_procp; 42442370Skarels int error, opc, numsys; 42544018Skarels struct args { 42644018Skarels int i[8]; 42744018Skarels } args; 42844018Skarels int rval[2]; 42941475Smckusick struct timeval syst; 43041475Smckusick struct sysent *systab; 43141475Smckusick #ifdef HPUXCOMPAT 43241475Smckusick extern struct sysent hpuxsysent[]; 43341475Smckusick extern int hpuxnsysent, notimp(); 43441475Smckusick #endif 43541475Smckusick 43641475Smckusick cnt.v_syscall++; 43742371Smckusick syst = u.u_ru.ru_stime; 43841475Smckusick if (!USERMODE(frame.f_sr)) 43941475Smckusick panic("syscall"); 44042371Smckusick u.u_ar0 = frame.f_regs; 44141475Smckusick opc = frame.f_pc - 2; 44241475Smckusick systab = sysent; 44341475Smckusick numsys = nsysent; 44441475Smckusick #ifdef HPUXCOMPAT 44542370Skarels if (p->p_flag & SHPUX) { 44641475Smckusick systab = hpuxsysent; 44741475Smckusick numsys = hpuxnsysent; 44841475Smckusick } 44941475Smckusick #endif 45041475Smckusick params = (caddr_t)frame.f_regs[SP] + NBPW; 45142370Skarels if (code == 0) { /* indir */ 45242370Skarels code = fuword(params); 45341475Smckusick params += NBPW; 45442370Skarels } 45542370Skarels if (code >= numsys) 45642370Skarels callp = &systab[0]; /* indir (illegal) */ 45742370Skarels else 45842370Skarels callp = &systab[code]; 45941475Smckusick if ((i = callp->sy_narg * sizeof (int)) && 46044018Skarels (error = copyin(params, (caddr_t)&args, (u_int)i))) { 46141475Smckusick #ifdef HPUXCOMPAT 46241475Smckusick if (p->p_flag & SHPUX) 46342370Skarels error = bsdtohpuxerrno(error); 46441475Smckusick #endif 46542370Skarels frame.f_regs[D0] = (u_char) error; 46641475Smckusick frame.f_sr |= PSL_C; /* carry bit */ 46741475Smckusick #ifdef KTRACE 46843641Skarels if (KTRPOINT(p, KTR_SYSCALL)) 46944018Skarels ktrsyscall(p->p_tracep, code, callp->sy_narg, args.i); 47041475Smckusick #endif 47141475Smckusick goto done; 47241475Smckusick } 47341475Smckusick #ifdef KTRACE 47443641Skarels if (KTRPOINT(p, KTR_SYSCALL)) 47544018Skarels ktrsyscall(p->p_tracep, code, callp->sy_narg, args.i); 47641475Smckusick #endif 47743641Skarels rval[0] = 0; 47843641Skarels rval[1] = frame.f_regs[D1]; 47941475Smckusick #ifdef HPUXCOMPAT 48042370Skarels /* debug kludge */ 48142370Skarels if (callp->sy_call == notimp) 48244018Skarels error = notimp(u.u_procp, args.i, rval, code, callp->sy_narg); 48342370Skarels else 48441475Smckusick #endif 48544018Skarels error = (*callp->sy_call)(u.u_procp, &args, rval); 48642370Skarels if (error == ERESTART) 48742370Skarels frame.f_pc = opc; 48842370Skarels else if (error != EJUSTRETURN) { 48942370Skarels if (error) { 49041475Smckusick #ifdef HPUXCOMPAT 49142370Skarels if (p->p_flag & SHPUX) 49242370Skarels error = bsdtohpuxerrno(error); 49341475Smckusick #endif 49442370Skarels frame.f_regs[D0] = (u_char) error; 49542370Skarels frame.f_sr |= PSL_C; /* carry bit */ 49641475Smckusick } else { 49743641Skarels frame.f_regs[D0] = rval[0]; 49843641Skarels frame.f_regs[D1] = rval[1]; 49941475Smckusick frame.f_sr &= ~PSL_C; 50041475Smckusick } 50142370Skarels } 50242370Skarels /* else if (error == EJUSTRETURN) */ 50341475Smckusick /* nothing to do */ 50442370Skarels 50541475Smckusick done: 50641475Smckusick /* 50742370Skarels * Reinitialize proc pointer `p' as it may be different 50842370Skarels * if this is a child returning from fork syscall. 50942370Skarels */ 51042371Smckusick p = u.u_procp; 51142370Skarels /* 51242371Smckusick * XXX the check for sigreturn ensures that we don't 51341475Smckusick * attempt to set up a call to a signal handler (sendsig) before 51441475Smckusick * we have cleaned up the stack from the last call (sigreturn). 51541475Smckusick * Allowing this seems to lock up the machine in certain scenarios. 51641475Smckusick * What should really be done is to clean up the signal handling 51741475Smckusick * so that this is not a problem. 51841475Smckusick */ 51942371Smckusick #include "syscall.h" 52042371Smckusick if (code != SYS_sigreturn && (i = CURSIG(p))) 52142370Skarels psig(i); 52241475Smckusick p->p_pri = p->p_usrpri; 52341475Smckusick if (runrun) { 52441475Smckusick /* 52541475Smckusick * Since we are u.u_procp, clock will normally just change 52641475Smckusick * our priority without moving us from one queue to another 52741475Smckusick * (since the running process is not on a queue.) 52841475Smckusick * If that happened after we setrq ourselves but before we 52941475Smckusick * swtch()'ed, we might not be on the queue indicated by 53041475Smckusick * our priority. 53141475Smckusick */ 53241475Smckusick (void) splclock(); 53341475Smckusick setrq(p); 53442371Smckusick u.u_ru.ru_nivcsw++; 53541475Smckusick swtch(); 53643413Shibler if (code != SYS_sigreturn && (i = CURSIG(p))) 53742370Skarels psig(i); 53841475Smckusick } 53942371Smckusick if (u.u_prof.pr_scale) { 54041475Smckusick int ticks; 54142371Smckusick struct timeval *tv = &u.u_ru.ru_stime; 54241475Smckusick 54341475Smckusick ticks = ((tv->tv_sec - syst.tv_sec) * 1000 + 54441475Smckusick (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000); 54541475Smckusick if (ticks) { 54641475Smckusick #ifdef PROFTIMER 54741475Smckusick extern int profscale; 54842371Smckusick addupc(frame.f_pc, &u.u_prof, ticks * profscale); 54941475Smckusick #else 55042371Smckusick addupc(frame.f_pc, &u.u_prof, ticks); 55141475Smckusick #endif 55241475Smckusick } 55341475Smckusick } 55441475Smckusick curpri = p->p_pri; 55541475Smckusick #ifdef KTRACE 55643641Skarels if (KTRPOINT(p, KTR_SYSRET)) 55743641Skarels ktrsysret(p->p_tracep, code, error, rval[0]); 55841475Smckusick #endif 55941475Smckusick } 560