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*49125Skarels * @(#)trap.c 7.11 (Berkeley) 05/04/91 1541475Smckusick */ 1641475Smckusick 1748465Skarels #include "param.h" 1848465Skarels #include "systm.h" 1948465Skarels #include "proc.h" 2048465Skarels #include "seg.h" 2148465Skarels #include "acct.h" 2248465Skarels #include "kernel.h" 2348465Skarels #include "signalvar.h" 2448465Skarels #include "resourcevar.h" 2548465Skarels #include "syslog.h" 2648465Skarels #include "user.h" 2748465Skarels #ifdef KTRACE 2848465Skarels #include "ktrace.h" 2948465Skarels #endif 3048465Skarels 31*49125Skarels #include "../include/psl.h" 3248465Skarels #include "../include/trap.h" 3345788Sbostic #include "../include/cpu.h" 3445788Sbostic #include "../include/reg.h" 3545788Sbostic #include "../include/mtpr.h" 3641475Smckusick 3748465Skarels #include "vm/vm.h" 3845788Sbostic #include "vm/pmap.h" 3948465Skarels #include "vmmeter.h" 4045751Smckusick 4141475Smckusick #ifdef HPUXCOMPAT 4241475Smckusick #include "../hpux/hpux.h" 4341475Smckusick #endif 4441475Smckusick 4541475Smckusick #define USER 040 /* user-mode flag added to type */ 4641475Smckusick 4741475Smckusick struct sysent sysent[]; 4841475Smckusick int nsysent; 4941475Smckusick 5041475Smckusick char *trap_type[] = { 5141475Smckusick "Bus error", 5241475Smckusick "Address error", 5341475Smckusick "Illegal instruction", 5441475Smckusick "Zero divide", 5541475Smckusick "CHK instruction", 5641475Smckusick "TRAPV instruction", 5741475Smckusick "Privilege violation", 5841475Smckusick "Trace trap", 5941475Smckusick "MMU fault", 6041475Smckusick "SSIR trap", 6141475Smckusick "Format error", 6241475Smckusick "68881 exception", 6341475Smckusick "Coprocessor violation", 6441475Smckusick "Async system trap" 6541475Smckusick }; 6641475Smckusick #define TRAP_TYPES (sizeof trap_type / sizeof trap_type[0]) 6741475Smckusick 6841475Smckusick #ifdef DEBUG 6941475Smckusick int mmudebug = 0; 7041475Smckusick #endif 7141475Smckusick 7241475Smckusick /* 7341475Smckusick * Called from the trap handler when a processor trap occurs. 7441475Smckusick */ 7541475Smckusick /*ARGSUSED*/ 7641475Smckusick trap(type, code, v, frame) 7741475Smckusick int type; 7841475Smckusick unsigned code; 7941475Smckusick register unsigned v; 8041475Smckusick struct frame frame; 8141475Smckusick { 8241475Smckusick register int i; 8341475Smckusick unsigned ucode = 0; 8448465Skarels register struct proc *p = curproc; 8541475Smckusick struct timeval syst; 8641475Smckusick unsigned ncode; 8741475Smckusick 8841475Smckusick cnt.v_trap++; 8948465Skarels syst = p->p_stime; 9041475Smckusick if (USERMODE(frame.f_sr)) { 9141475Smckusick type |= USER; 9248465Skarels p->p_regs = frame.f_regs; 9341475Smckusick } 9441475Smckusick switch (type) { 9541475Smckusick 9641475Smckusick default: 9741475Smckusick dopanic: 9841475Smckusick printf("trap type %d, code = %x, v = %x\n", type, code, v); 9941475Smckusick regdump(frame.f_regs, 128); 10041475Smckusick type &= ~USER; 10141475Smckusick if ((unsigned)type < TRAP_TYPES) 10241475Smckusick panic(trap_type[type]); 10341475Smckusick panic("trap"); 10441475Smckusick 10541475Smckusick case T_BUSERR: /* kernel bus error */ 106*49125Skarels if (!p->p_addr->u_pcb.pcb_onfault) 10741475Smckusick goto dopanic; 10841475Smckusick /* 10941475Smckusick * If we have arranged to catch this fault in any of the 11041475Smckusick * copy to/from user space routines, set PC to return to 11141475Smckusick * indicated location and set flag informing buserror code 11241475Smckusick * that it may need to clean up stack frame. 11341475Smckusick */ 11441475Smckusick copyfault: 115*49125Skarels frame.f_pc = (int) p->p_addr->u_pcb.pcb_onfault; 11641475Smckusick frame.f_stackadj = -1; 11741475Smckusick return; 11841475Smckusick 11941475Smckusick case T_BUSERR+USER: /* bus error */ 12041475Smckusick case T_ADDRERR+USER: /* address error */ 12141475Smckusick i = SIGBUS; 12241475Smckusick break; 12341475Smckusick 12441475Smckusick #ifdef FPCOPROC 12541475Smckusick case T_COPERR: /* kernel coprocessor violation */ 12641475Smckusick #endif 12741475Smckusick case T_FMTERR: /* kernel format error */ 12841475Smckusick /* 12941475Smckusick * The user has most likely trashed the RTE or FP state info 13041475Smckusick * in the stack frame of a signal handler. 13141475Smckusick */ 13242370Skarels type |= USER; 13348465Skarels printf("pid %d: kernel %s exception\n", p->p_pid, 13441475Smckusick type==T_COPERR ? "coprocessor" : "format"); 13548465Skarels p->p_sigacts->ps_sigact[SIGILL] = SIG_DFL; 13641475Smckusick i = sigmask(SIGILL); 13741475Smckusick p->p_sigignore &= ~i; 13841475Smckusick p->p_sigcatch &= ~i; 13941475Smckusick p->p_sigmask &= ~i; 14042370Skarels i = SIGILL; 14141475Smckusick ucode = frame.f_format; /* XXX was ILL_RESAD_FAULT */ 14242370Skarels break; 14341475Smckusick 14441475Smckusick #ifdef FPCOPROC 14541475Smckusick case T_COPERR+USER: /* user coprocessor violation */ 14641475Smckusick /* What is a proper response here? */ 14741475Smckusick ucode = 0; 14841475Smckusick i = SIGFPE; 14941475Smckusick break; 15041475Smckusick 15141475Smckusick case T_FPERR+USER: /* 68881 exceptions */ 15241475Smckusick /* 15341475Smckusick * We pass along the 68881 status register which locore stashed 15441475Smckusick * in code for us. Note that there is a possibility that the 15541475Smckusick * bit pattern of this register will conflict with one of the 15641475Smckusick * FPE_* codes defined in signal.h. Fortunately for us, the 15741475Smckusick * only such codes we use are all in the range 1-7 and the low 15841475Smckusick * 3 bits of the status register are defined as 0 so there is 15941475Smckusick * no clash. 16041475Smckusick */ 16141475Smckusick ucode = code; 16241475Smckusick i = SIGFPE; 16341475Smckusick break; 16441475Smckusick #endif 16541475Smckusick 16641475Smckusick case T_ILLINST+USER: /* illegal instruction fault */ 16741475Smckusick #ifdef HPUXCOMPAT 16848465Skarels if (p->p_flag & SHPUX) { 16941475Smckusick ucode = HPUX_ILL_ILLINST_TRAP; 17041475Smckusick i = SIGILL; 17141475Smckusick break; 17241475Smckusick } 17341475Smckusick /* fall through */ 17441475Smckusick #endif 17541475Smckusick case T_PRIVINST+USER: /* privileged instruction fault */ 17641475Smckusick #ifdef HPUXCOMPAT 17748465Skarels if (p->p_flag & SHPUX) 17841475Smckusick ucode = HPUX_ILL_PRIV_TRAP; 17941475Smckusick else 18041475Smckusick #endif 18141475Smckusick ucode = frame.f_format; /* XXX was ILL_PRIVIN_FAULT */ 18241475Smckusick i = SIGILL; 18341475Smckusick break; 18441475Smckusick 18541475Smckusick case T_ZERODIV+USER: /* Divide by zero */ 18641475Smckusick #ifdef HPUXCOMPAT 18748465Skarels if (p->p_flag & SHPUX) 18841475Smckusick ucode = HPUX_FPE_INTDIV_TRAP; 18941475Smckusick else 19041475Smckusick #endif 19141475Smckusick ucode = frame.f_format; /* XXX was FPE_INTDIV_TRAP */ 19241475Smckusick i = SIGFPE; 19341475Smckusick break; 19441475Smckusick 19541475Smckusick case T_CHKINST+USER: /* CHK instruction trap */ 19641475Smckusick #ifdef HPUXCOMPAT 19748465Skarels if (p->p_flag & SHPUX) { 19841475Smckusick /* handled differently under hp-ux */ 19941475Smckusick i = SIGILL; 20041475Smckusick ucode = HPUX_ILL_CHK_TRAP; 20141475Smckusick break; 20241475Smckusick } 20341475Smckusick #endif 20441475Smckusick ucode = frame.f_format; /* XXX was FPE_SUBRNG_TRAP */ 20541475Smckusick i = SIGFPE; 20641475Smckusick break; 20741475Smckusick 20841475Smckusick case T_TRAPVINST+USER: /* TRAPV instruction trap */ 20941475Smckusick #ifdef HPUXCOMPAT 21048465Skarels if (p->p_flag & SHPUX) { 21141475Smckusick /* handled differently under hp-ux */ 21241475Smckusick i = SIGILL; 21341475Smckusick ucode = HPUX_ILL_TRAPV_TRAP; 21441475Smckusick break; 21541475Smckusick } 21641475Smckusick #endif 21741475Smckusick ucode = frame.f_format; /* XXX was FPE_INTOVF_TRAP */ 21841475Smckusick i = SIGFPE; 21941475Smckusick break; 22041475Smckusick 22141475Smckusick /* 22241475Smckusick * XXX: Trace traps are a nightmare. 22341475Smckusick * 22441475Smckusick * HP-UX uses trap #1 for breakpoints, 22541475Smckusick * HPBSD uses trap #2, 22641475Smckusick * SUN 3.x uses trap #15, 22748465Skarels * KGDB uses trap #15 (for kernel breakpoints; handled elsewhere). 22841475Smckusick * 22941475Smckusick * HPBSD and HP-UX traps both get mapped by locore.s into T_TRACE. 23041475Smckusick * SUN 3.x traps get passed through as T_TRAP15 and are not really 23148465Skarels * supported yet. 23241475Smckusick */ 23341475Smckusick case T_TRACE: /* kernel trace trap */ 23448465Skarels case T_TRAP15: /* SUN trace trap */ 23541475Smckusick frame.f_sr &= ~PSL_T; 23641475Smckusick i = SIGTRAP; 23741475Smckusick break; 23841475Smckusick 23941475Smckusick case T_TRACE+USER: /* user trace trap */ 24041475Smckusick case T_TRAP15+USER: /* SUN user trace trap */ 24141475Smckusick frame.f_sr &= ~PSL_T; 24241475Smckusick i = SIGTRAP; 24341475Smckusick break; 24441475Smckusick 24543413Shibler case T_ASTFLT: /* system async trap, cannot happen */ 24641475Smckusick goto dopanic; 24741475Smckusick 24843413Shibler case T_ASTFLT+USER: /* user async trap */ 249*49125Skarels astpending = 0; 25041475Smckusick /* 25141475Smckusick * We check for software interrupts first. This is because 25241475Smckusick * they are at a higher level than ASTs, and on a VAX would 25341475Smckusick * interrupt the AST. We assume that if we are processing 25441475Smckusick * an AST that we must be at IPL0 so we don't bother to 25541475Smckusick * check. Note that we ensure that we are at least at SIR 25641475Smckusick * IPL while processing the SIR. 25741475Smckusick */ 25841475Smckusick spl1(); 25941475Smckusick /* fall into... */ 26041475Smckusick 26141475Smckusick case T_SSIR: /* software interrupt */ 26241475Smckusick case T_SSIR+USER: 26341475Smckusick if (ssir & SIR_NET) { 26441475Smckusick siroff(SIR_NET); 26541475Smckusick cnt.v_soft++; 26641475Smckusick netintr(); 26741475Smckusick } 26841475Smckusick if (ssir & SIR_CLOCK) { 26941475Smckusick siroff(SIR_CLOCK); 27041475Smckusick cnt.v_soft++; 27141475Smckusick softclock((caddr_t)frame.f_pc, (int)frame.f_sr); 27241475Smckusick } 27341475Smckusick /* 27441475Smckusick * If this was not an AST trap, we are all done. 27541475Smckusick */ 27643413Shibler if (type != T_ASTFLT+USER) { 27741475Smckusick cnt.v_trap--; 27841475Smckusick return; 27941475Smckusick } 28041475Smckusick spl0(); 28141475Smckusick #ifndef PROFTIMER 28248465Skarels if ((p->p_flag&SOWEUPC) && p->p_stats->p_prof.pr_scale) { 28348465Skarels addupc(frame.f_pc, &p->p_stats->p_prof, 1); 28448465Skarels p->p_flag &= ~SOWEUPC; 28541475Smckusick } 28641475Smckusick #endif 28741475Smckusick goto out; 28841475Smckusick 28941475Smckusick case T_MMUFLT: /* kernel mode page fault */ 29041475Smckusick /* fall into ... */ 29141475Smckusick 29241475Smckusick case T_MMUFLT+USER: /* page fault */ 29345751Smckusick { 29445751Smckusick register vm_offset_t va; 29548465Skarels register struct vmspace *vm = p->p_vmspace; 29645751Smckusick register vm_map_t map; 29745751Smckusick int rv; 29845751Smckusick vm_prot_t ftype; 29945751Smckusick extern vm_map_t kernel_map; 30045751Smckusick unsigned nss; 30145751Smckusick 30241475Smckusick /* 30345751Smckusick * It is only a kernel address space fault iff: 30445751Smckusick * 1. (type & USER) == 0 and 30545751Smckusick * 2. pcb_onfault not set or 30645751Smckusick * 3. pcb_onfault set but supervisor space data fault 30745751Smckusick * The last can occur during an exec() copyin where the 30845751Smckusick * argument space is lazy-allocated. 30941475Smckusick */ 31045751Smckusick if (type == T_MMUFLT && 311*49125Skarels (!p->p_addr->u_pcb.pcb_onfault || 31245751Smckusick (code & (SSW_DF|FC_SUPERD)) == (SSW_DF|FC_SUPERD))) 31345751Smckusick map = kernel_map; 31445751Smckusick else 31548465Skarels map = &vm->vm_map; 31645751Smckusick if ((code & (SSW_DF|SSW_RW)) == SSW_DF) /* what about RMW? */ 31745751Smckusick ftype = VM_PROT_READ | VM_PROT_WRITE; 31845751Smckusick else 31945751Smckusick ftype = VM_PROT_READ; 32045751Smckusick va = trunc_page((vm_offset_t)v); 32141475Smckusick #ifdef DEBUG 32245751Smckusick if (map == kernel_map && va == 0) { 32345751Smckusick printf("trap: bad kernel access at %x\n", v); 32441475Smckusick goto dopanic; 32541475Smckusick } 32641475Smckusick #endif 32741475Smckusick /* 32845751Smckusick * XXX: rude hack to make stack limits "work" 32941475Smckusick */ 33045751Smckusick nss = 0; 33148465Skarels if ((caddr_t)va >= vm->vm_maxsaddr && map != kernel_map) { 33245751Smckusick nss = clrnd(btoc(USRSTACK-(unsigned)va)); 33348465Skarels if (nss > btoc(p->p_rlimit[RLIMIT_STACK].rlim_cur)) { 33445751Smckusick rv = KERN_FAILURE; 33545751Smckusick goto nogo; 33641475Smckusick } 33741475Smckusick } 33845751Smckusick rv = vm_fault(map, va, ftype, FALSE); 33945751Smckusick if (rv == KERN_SUCCESS) { 34045751Smckusick /* 34145751Smckusick * XXX: continuation of rude stack hack 34245751Smckusick */ 34348465Skarels if (nss > vm->vm_ssize) 34448465Skarels vm->vm_ssize = nss; 34541475Smckusick if (type == T_MMUFLT) 34641475Smckusick return; 34741475Smckusick goto out; 34841475Smckusick } 34945751Smckusick nogo: 35045751Smckusick if (type == T_MMUFLT) { 351*49125Skarels if (p->p_addr->u_pcb.pcb_onfault) 35245751Smckusick goto copyfault; 35345751Smckusick printf("vm_fault(%x, %x, %x, 0) -> %x\n", 35445751Smckusick map, va, ftype, rv); 35545751Smckusick printf(" type %x, code [mmu,,ssw]: %x\n", 35645751Smckusick type, code); 35745751Smckusick goto dopanic; 35845751Smckusick } 35948465Skarels ucode = v; 36045751Smckusick i = (rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV; 36145751Smckusick break; 36245751Smckusick } 36341475Smckusick } 36448465Skarels trapsignal(p, i, ucode); 36541475Smckusick if ((type & USER) == 0) 36641475Smckusick return; 36741475Smckusick out: 36848465Skarels while (i = CURSIG(p)) 36942370Skarels psig(i); 37041475Smckusick p->p_pri = p->p_usrpri; 37148465Skarels if (want_resched) { 37241475Smckusick /* 37348465Skarels * Since we are curproc, clock will normally just change 37441475Smckusick * our priority without moving us from one queue to another 37541475Smckusick * (since the running process is not on a queue.) 37641475Smckusick * If that happened after we setrq ourselves but before we 37741475Smckusick * swtch()'ed, we might not be on the queue indicated by 37841475Smckusick * our priority. 37941475Smckusick */ 38041475Smckusick (void) splclock(); 38141475Smckusick setrq(p); 38248465Skarels p->p_stats->p_ru.ru_nivcsw++; 38341475Smckusick swtch(); 38448465Skarels while (i = CURSIG(p)) 38542370Skarels psig(i); 38641475Smckusick } 38748465Skarels if (p->p_stats->p_prof.pr_scale) { 38841475Smckusick int ticks; 38948465Skarels struct timeval *tv = &p->p_stime; 39041475Smckusick 39141475Smckusick ticks = ((tv->tv_sec - syst.tv_sec) * 1000 + 39241475Smckusick (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000); 39341475Smckusick if (ticks) { 39441475Smckusick #ifdef PROFTIMER 39541475Smckusick extern int profscale; 39648465Skarels addupc(frame.f_pc, &p->p_stats->p_prof, 39748465Skarels ticks * profscale); 39841475Smckusick #else 39948465Skarels addupc(frame.f_pc, &p->p_stats->p_prof, ticks); 40041475Smckusick #endif 40141475Smckusick } 40241475Smckusick } 40341475Smckusick curpri = p->p_pri; 40441475Smckusick } 40541475Smckusick 40641475Smckusick /* 40741475Smckusick * Called from the trap handler when a system call occurs 40841475Smckusick */ 40941475Smckusick /*ARGSUSED*/ 41041475Smckusick syscall(code, frame) 41141475Smckusick volatile int code; 41241475Smckusick struct frame frame; 41341475Smckusick { 41441475Smckusick register caddr_t params; 41541475Smckusick register int i; 41641475Smckusick register struct sysent *callp; 41748465Skarels register struct proc *p = curproc; 41842370Skarels int error, opc, numsys; 41944018Skarels struct args { 42044018Skarels int i[8]; 42144018Skarels } args; 42244018Skarels int rval[2]; 42341475Smckusick struct timeval syst; 42441475Smckusick struct sysent *systab; 42541475Smckusick #ifdef HPUXCOMPAT 42641475Smckusick extern struct sysent hpuxsysent[]; 42741475Smckusick extern int hpuxnsysent, notimp(); 42841475Smckusick #endif 42941475Smckusick 43041475Smckusick cnt.v_syscall++; 43148465Skarels syst = p->p_stime; 43241475Smckusick if (!USERMODE(frame.f_sr)) 43341475Smckusick panic("syscall"); 43448465Skarels p->p_regs = frame.f_regs; 43541475Smckusick opc = frame.f_pc - 2; 43641475Smckusick systab = sysent; 43741475Smckusick numsys = nsysent; 43841475Smckusick #ifdef HPUXCOMPAT 43942370Skarels if (p->p_flag & SHPUX) { 44041475Smckusick systab = hpuxsysent; 44141475Smckusick numsys = hpuxnsysent; 44241475Smckusick } 44341475Smckusick #endif 44441475Smckusick params = (caddr_t)frame.f_regs[SP] + NBPW; 44542370Skarels if (code == 0) { /* indir */ 44642370Skarels code = fuword(params); 44741475Smckusick params += NBPW; 44842370Skarels } 44942370Skarels if (code >= numsys) 45042370Skarels callp = &systab[0]; /* indir (illegal) */ 45142370Skarels else 45242370Skarels callp = &systab[code]; 45341475Smckusick if ((i = callp->sy_narg * sizeof (int)) && 45444018Skarels (error = copyin(params, (caddr_t)&args, (u_int)i))) { 45541475Smckusick #ifdef HPUXCOMPAT 45641475Smckusick if (p->p_flag & SHPUX) 45742370Skarels error = bsdtohpuxerrno(error); 45841475Smckusick #endif 45942370Skarels frame.f_regs[D0] = (u_char) error; 46041475Smckusick frame.f_sr |= PSL_C; /* carry bit */ 46141475Smckusick #ifdef KTRACE 46243641Skarels if (KTRPOINT(p, KTR_SYSCALL)) 46344018Skarels ktrsyscall(p->p_tracep, code, callp->sy_narg, args.i); 46441475Smckusick #endif 46541475Smckusick goto done; 46641475Smckusick } 46741475Smckusick #ifdef KTRACE 46843641Skarels if (KTRPOINT(p, KTR_SYSCALL)) 46944018Skarels ktrsyscall(p->p_tracep, code, callp->sy_narg, args.i); 47041475Smckusick #endif 47143641Skarels rval[0] = 0; 47243641Skarels rval[1] = frame.f_regs[D1]; 47341475Smckusick #ifdef HPUXCOMPAT 47442370Skarels /* debug kludge */ 47542370Skarels if (callp->sy_call == notimp) 47648465Skarels error = notimp(p, args.i, rval, code, callp->sy_narg); 47742370Skarels else 47841475Smckusick #endif 47948465Skarels error = (*callp->sy_call)(p, &args, rval); 48042370Skarels if (error == ERESTART) 48142370Skarels frame.f_pc = opc; 48242370Skarels else if (error != EJUSTRETURN) { 48342370Skarels if (error) { 48441475Smckusick #ifdef HPUXCOMPAT 48542370Skarels if (p->p_flag & SHPUX) 48642370Skarels error = bsdtohpuxerrno(error); 48741475Smckusick #endif 48842370Skarels frame.f_regs[D0] = (u_char) error; 48942370Skarels frame.f_sr |= PSL_C; /* carry bit */ 49041475Smckusick } else { 49143641Skarels frame.f_regs[D0] = rval[0]; 49243641Skarels frame.f_regs[D1] = rval[1]; 49341475Smckusick frame.f_sr &= ~PSL_C; 49441475Smckusick } 49542370Skarels } 49642370Skarels /* else if (error == EJUSTRETURN) */ 49741475Smckusick /* nothing to do */ 49842370Skarels 49941475Smckusick done: 50041475Smckusick /* 50142370Skarels * Reinitialize proc pointer `p' as it may be different 50242370Skarels * if this is a child returning from fork syscall. 50342370Skarels */ 50448465Skarels p = curproc; 50542370Skarels /* 50642371Smckusick * XXX the check for sigreturn ensures that we don't 50741475Smckusick * attempt to set up a call to a signal handler (sendsig) before 50841475Smckusick * we have cleaned up the stack from the last call (sigreturn). 50941475Smckusick * Allowing this seems to lock up the machine in certain scenarios. 51041475Smckusick * What should really be done is to clean up the signal handling 51141475Smckusick * so that this is not a problem. 51241475Smckusick */ 51345788Sbostic #include "sys/syscall.h" 51448465Skarels if (code != SYS_sigreturn) 51548465Skarels while (i = CURSIG(p)) 51648465Skarels psig(i); 51741475Smckusick p->p_pri = p->p_usrpri; 51848465Skarels if (want_resched) { 51941475Smckusick /* 52048465Skarels * Since we are curproc, clock will normally just change 52141475Smckusick * our priority without moving us from one queue to another 52241475Smckusick * (since the running process is not on a queue.) 52341475Smckusick * If that happened after we setrq ourselves but before we 52441475Smckusick * swtch()'ed, we might not be on the queue indicated by 52541475Smckusick * our priority. 52641475Smckusick */ 52741475Smckusick (void) splclock(); 52841475Smckusick setrq(p); 52948465Skarels p->p_stats->p_ru.ru_nivcsw++; 53041475Smckusick swtch(); 53148465Skarels if (code != SYS_sigreturn) 53248465Skarels while (i = CURSIG(p)) 53348465Skarels psig(i); 53441475Smckusick } 53548465Skarels if (p->p_stats->p_prof.pr_scale) { 53641475Smckusick int ticks; 53748465Skarels struct timeval *tv = &p->p_stime; 53841475Smckusick 53941475Smckusick ticks = ((tv->tv_sec - syst.tv_sec) * 1000 + 54041475Smckusick (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000); 54141475Smckusick if (ticks) { 54241475Smckusick #ifdef PROFTIMER 54341475Smckusick extern int profscale; 54448465Skarels addupc(frame.f_pc, &p->p_stats->p_prof, 54548465Skarels ticks * profscale); 54641475Smckusick #else 54748465Skarels addupc(frame.f_pc, &p->p_stats->p_prof, ticks); 54841475Smckusick #endif 54941475Smckusick } 55041475Smckusick } 55141475Smckusick curpri = p->p_pri; 55241475Smckusick #ifdef KTRACE 55343641Skarels if (KTRPOINT(p, KTR_SYSRET)) 55443641Skarels ktrsysret(p->p_tracep, code, error, rval[0]); 55541475Smckusick #endif 55641475Smckusick } 557