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 * 1249317Shibler * from: Utah $Hdr: trap.c 1.32 91/04/06$ 1341475Smckusick * 14*52380Smckusick * @(#)trap.c 7.18 (Berkeley) 02/05/92 1541475Smckusick */ 1641475Smckusick 1748465Skarels #include "param.h" 1848465Skarels #include "systm.h" 1948465Skarels #include "proc.h" 2048465Skarels #include "acct.h" 2148465Skarels #include "kernel.h" 2248465Skarels #include "signalvar.h" 2348465Skarels #include "resourcevar.h" 2448465Skarels #include "syslog.h" 2548465Skarels #include "user.h" 2648465Skarels #ifdef KTRACE 2748465Skarels #include "ktrace.h" 2848465Skarels #endif 2948465Skarels 3049125Skarels #include "../include/psl.h" 3148465Skarels #include "../include/trap.h" 3245788Sbostic #include "../include/cpu.h" 3345788Sbostic #include "../include/reg.h" 3445788Sbostic #include "../include/mtpr.h" 3541475Smckusick 3648465Skarels #include "vm/vm.h" 3745788Sbostic #include "vm/pmap.h" 3845751Smckusick 3941475Smckusick #ifdef HPUXCOMPAT 4041475Smckusick #include "../hpux/hpux.h" 4141475Smckusick #endif 4241475Smckusick 4341475Smckusick struct sysent sysent[]; 4441475Smckusick int nsysent; 4541475Smckusick 4641475Smckusick char *trap_type[] = { 4741475Smckusick "Bus error", 4841475Smckusick "Address error", 4941475Smckusick "Illegal instruction", 5041475Smckusick "Zero divide", 5141475Smckusick "CHK instruction", 5241475Smckusick "TRAPV instruction", 5341475Smckusick "Privilege violation", 5441475Smckusick "Trace trap", 5541475Smckusick "MMU fault", 5641475Smckusick "SSIR trap", 5741475Smckusick "Format error", 5841475Smckusick "68881 exception", 5941475Smckusick "Coprocessor violation", 6041475Smckusick "Async system trap" 6141475Smckusick }; 6241475Smckusick #define TRAP_TYPES (sizeof trap_type / sizeof trap_type[0]) 6341475Smckusick 6449317Shibler /* 6549317Shibler * Size of various exception stack frames (minus the standard 8 bytes) 6649317Shibler */ 6749317Shibler short exframesize[] = { 6849317Shibler FMT0SIZE, /* type 0 - normal (68020/030/040) */ 6949317Shibler FMT1SIZE, /* type 1 - throwaway (68020/030/040) */ 7049317Shibler FMT2SIZE, /* type 2 - normal 6-word (68020/030/040) */ 7149317Shibler -1, /* type 3 - FP post-instruction (68040) */ 7249317Shibler -1, -1, -1, /* type 4-6 - undefined */ 7349317Shibler -1, /* type 7 - access error (68040) */ 7449317Shibler 58, /* type 8 - bus fault (68010) */ 7549317Shibler FMT9SIZE, /* type 9 - coprocessor mid-instruction (68020/030) */ 7649317Shibler FMTASIZE, /* type A - short bus fault (68020/030) */ 7749317Shibler FMTBSIZE, /* type B - long bus fault (68020/030) */ 7849317Shibler -1, -1, -1, -1 /* type C-F - undefined */ 7949317Shibler }; 8049317Shibler 8141475Smckusick #ifdef DEBUG 8241475Smckusick int mmudebug = 0; 8341475Smckusick #endif 8441475Smckusick 8541475Smckusick /* 8649531Skarels * Trap is called from locore to handle most types of processor traps, 8749531Skarels * including events such as simulated software interrupts/AST's. 8849531Skarels * System calls are broken out for efficiency. 8941475Smckusick */ 9041475Smckusick /*ARGSUSED*/ 9141475Smckusick trap(type, code, v, frame) 9241475Smckusick int type; 9341475Smckusick unsigned code; 9441475Smckusick register unsigned v; 9541475Smckusick struct frame frame; 9641475Smckusick { 9741475Smckusick register int i; 9841475Smckusick unsigned ucode = 0; 9948465Skarels register struct proc *p = curproc; 10041475Smckusick struct timeval syst; 10141475Smckusick unsigned ncode; 10250753Skarels int s; 10341475Smckusick 10441475Smckusick cnt.v_trap++; 10548465Skarels syst = p->p_stime; 10641475Smckusick if (USERMODE(frame.f_sr)) { 10749531Skarels type |= T_USER; 108*52380Smckusick p->p_md.md_regs = frame.f_regs; 10941475Smckusick } 11041475Smckusick switch (type) { 11141475Smckusick 11241475Smckusick default: 11341475Smckusick dopanic: 11441475Smckusick printf("trap type %d, code = %x, v = %x\n", type, code, v); 11541475Smckusick regdump(frame.f_regs, 128); 11649531Skarels type &= ~T_USER; 11741475Smckusick if ((unsigned)type < TRAP_TYPES) 11841475Smckusick panic(trap_type[type]); 11941475Smckusick panic("trap"); 12041475Smckusick 12141475Smckusick case T_BUSERR: /* kernel bus error */ 12249125Skarels if (!p->p_addr->u_pcb.pcb_onfault) 12341475Smckusick goto dopanic; 12441475Smckusick /* 12541475Smckusick * If we have arranged to catch this fault in any of the 12641475Smckusick * copy to/from user space routines, set PC to return to 12741475Smckusick * indicated location and set flag informing buserror code 12841475Smckusick * that it may need to clean up stack frame. 12941475Smckusick */ 13041475Smckusick copyfault: 13149317Shibler frame.f_stackadj = exframesize[frame.f_format]; 13249317Shibler frame.f_format = frame.f_vector = 0; 13349125Skarels frame.f_pc = (int) p->p_addr->u_pcb.pcb_onfault; 13441475Smckusick return; 13541475Smckusick 13649531Skarels case T_BUSERR|T_USER: /* bus error */ 13749531Skarels case T_ADDRERR|T_USER: /* address error */ 13841475Smckusick i = SIGBUS; 13941475Smckusick break; 14041475Smckusick 14141475Smckusick #ifdef FPCOPROC 14241475Smckusick case T_COPERR: /* kernel coprocessor violation */ 14341475Smckusick #endif 14441475Smckusick case T_FMTERR: /* kernel format error */ 14541475Smckusick /* 14641475Smckusick * The user has most likely trashed the RTE or FP state info 14741475Smckusick * in the stack frame of a signal handler. 14841475Smckusick */ 14949531Skarels type |= T_USER; 15048465Skarels printf("pid %d: kernel %s exception\n", p->p_pid, 15141475Smckusick type==T_COPERR ? "coprocessor" : "format"); 15248465Skarels p->p_sigacts->ps_sigact[SIGILL] = SIG_DFL; 15341475Smckusick i = sigmask(SIGILL); 15441475Smckusick p->p_sigignore &= ~i; 15541475Smckusick p->p_sigcatch &= ~i; 15641475Smckusick p->p_sigmask &= ~i; 15742370Skarels i = SIGILL; 15841475Smckusick ucode = frame.f_format; /* XXX was ILL_RESAD_FAULT */ 15942370Skarels break; 16041475Smckusick 16141475Smckusick #ifdef FPCOPROC 16249531Skarels case T_COPERR|T_USER: /* user coprocessor violation */ 16341475Smckusick /* What is a proper response here? */ 16441475Smckusick ucode = 0; 16541475Smckusick i = SIGFPE; 16641475Smckusick break; 16741475Smckusick 16849531Skarels case T_FPERR|T_USER: /* 68881 exceptions */ 16941475Smckusick /* 17041475Smckusick * We pass along the 68881 status register which locore stashed 17141475Smckusick * in code for us. Note that there is a possibility that the 17241475Smckusick * bit pattern of this register will conflict with one of the 17341475Smckusick * FPE_* codes defined in signal.h. Fortunately for us, the 17441475Smckusick * only such codes we use are all in the range 1-7 and the low 17541475Smckusick * 3 bits of the status register are defined as 0 so there is 17641475Smckusick * no clash. 17741475Smckusick */ 17841475Smckusick ucode = code; 17941475Smckusick i = SIGFPE; 18041475Smckusick break; 18141475Smckusick #endif 18241475Smckusick 18349531Skarels case T_ILLINST|T_USER: /* illegal instruction fault */ 18441475Smckusick #ifdef HPUXCOMPAT 18548465Skarels if (p->p_flag & SHPUX) { 18641475Smckusick ucode = HPUX_ILL_ILLINST_TRAP; 18741475Smckusick i = SIGILL; 18841475Smckusick break; 18941475Smckusick } 19041475Smckusick /* fall through */ 19141475Smckusick #endif 19249531Skarels case T_PRIVINST|T_USER: /* privileged instruction fault */ 19341475Smckusick #ifdef HPUXCOMPAT 19448465Skarels if (p->p_flag & SHPUX) 19541475Smckusick ucode = HPUX_ILL_PRIV_TRAP; 19641475Smckusick else 19741475Smckusick #endif 19841475Smckusick ucode = frame.f_format; /* XXX was ILL_PRIVIN_FAULT */ 19941475Smckusick i = SIGILL; 20041475Smckusick break; 20141475Smckusick 20249531Skarels case T_ZERODIV|T_USER: /* Divide by zero */ 20341475Smckusick #ifdef HPUXCOMPAT 20448465Skarels if (p->p_flag & SHPUX) 20541475Smckusick ucode = HPUX_FPE_INTDIV_TRAP; 20641475Smckusick else 20741475Smckusick #endif 20841475Smckusick ucode = frame.f_format; /* XXX was FPE_INTDIV_TRAP */ 20941475Smckusick i = SIGFPE; 21041475Smckusick break; 21141475Smckusick 21249531Skarels case T_CHKINST|T_USER: /* CHK instruction trap */ 21341475Smckusick #ifdef HPUXCOMPAT 21448465Skarels if (p->p_flag & SHPUX) { 21541475Smckusick /* handled differently under hp-ux */ 21641475Smckusick i = SIGILL; 21741475Smckusick ucode = HPUX_ILL_CHK_TRAP; 21841475Smckusick break; 21941475Smckusick } 22041475Smckusick #endif 22141475Smckusick ucode = frame.f_format; /* XXX was FPE_SUBRNG_TRAP */ 22241475Smckusick i = SIGFPE; 22341475Smckusick break; 22441475Smckusick 22549531Skarels case T_TRAPVINST|T_USER: /* TRAPV instruction trap */ 22641475Smckusick #ifdef HPUXCOMPAT 22748465Skarels if (p->p_flag & SHPUX) { 22841475Smckusick /* handled differently under hp-ux */ 22941475Smckusick i = SIGILL; 23041475Smckusick ucode = HPUX_ILL_TRAPV_TRAP; 23141475Smckusick break; 23241475Smckusick } 23341475Smckusick #endif 23441475Smckusick ucode = frame.f_format; /* XXX was FPE_INTOVF_TRAP */ 23541475Smckusick i = SIGFPE; 23641475Smckusick break; 23741475Smckusick 23841475Smckusick /* 23941475Smckusick * XXX: Trace traps are a nightmare. 24041475Smckusick * 24141475Smckusick * HP-UX uses trap #1 for breakpoints, 24241475Smckusick * HPBSD uses trap #2, 24341475Smckusick * SUN 3.x uses trap #15, 24448465Skarels * KGDB uses trap #15 (for kernel breakpoints; handled elsewhere). 24541475Smckusick * 24641475Smckusick * HPBSD and HP-UX traps both get mapped by locore.s into T_TRACE. 24741475Smckusick * SUN 3.x traps get passed through as T_TRAP15 and are not really 24848465Skarels * supported yet. 24941475Smckusick */ 25041475Smckusick case T_TRACE: /* kernel trace trap */ 25148465Skarels case T_TRAP15: /* SUN trace trap */ 25241475Smckusick frame.f_sr &= ~PSL_T; 25341475Smckusick i = SIGTRAP; 25441475Smckusick break; 25541475Smckusick 25649531Skarels case T_TRACE|T_USER: /* user trace trap */ 25749531Skarels case T_TRAP15|T_USER: /* SUN user trace trap */ 25841475Smckusick frame.f_sr &= ~PSL_T; 25941475Smckusick i = SIGTRAP; 26041475Smckusick break; 26141475Smckusick 26243413Shibler case T_ASTFLT: /* system async trap, cannot happen */ 26341475Smckusick goto dopanic; 26441475Smckusick 26549531Skarels case T_ASTFLT|T_USER: /* user async trap */ 26649125Skarels astpending = 0; 26741475Smckusick /* 26841475Smckusick * We check for software interrupts first. This is because 26941475Smckusick * they are at a higher level than ASTs, and on a VAX would 27041475Smckusick * interrupt the AST. We assume that if we are processing 27141475Smckusick * an AST that we must be at IPL0 so we don't bother to 27241475Smckusick * check. Note that we ensure that we are at least at SIR 27341475Smckusick * IPL while processing the SIR. 27441475Smckusick */ 27541475Smckusick spl1(); 27641475Smckusick /* fall into... */ 27741475Smckusick 27841475Smckusick case T_SSIR: /* software interrupt */ 27949531Skarels case T_SSIR|T_USER: 28041475Smckusick if (ssir & SIR_NET) { 28141475Smckusick siroff(SIR_NET); 28241475Smckusick cnt.v_soft++; 28341475Smckusick netintr(); 28441475Smckusick } 28541475Smckusick if (ssir & SIR_CLOCK) { 28641475Smckusick siroff(SIR_CLOCK); 28741475Smckusick cnt.v_soft++; 28841475Smckusick softclock((caddr_t)frame.f_pc, (int)frame.f_sr); 28941475Smckusick } 29041475Smckusick /* 29141475Smckusick * If this was not an AST trap, we are all done. 29241475Smckusick */ 29350753Skarels if (type != (T_ASTFLT|T_USER)) { 29441475Smckusick cnt.v_trap--; 29541475Smckusick return; 29641475Smckusick } 29741475Smckusick spl0(); 29841475Smckusick #ifndef PROFTIMER 29948465Skarels if ((p->p_flag&SOWEUPC) && p->p_stats->p_prof.pr_scale) { 30048465Skarels addupc(frame.f_pc, &p->p_stats->p_prof, 1); 30148465Skarels p->p_flag &= ~SOWEUPC; 30241475Smckusick } 30341475Smckusick #endif 30441475Smckusick goto out; 30541475Smckusick 30641475Smckusick case T_MMUFLT: /* kernel mode page fault */ 30741475Smckusick /* fall into ... */ 30841475Smckusick 30949531Skarels case T_MMUFLT|T_USER: /* page fault */ 31045751Smckusick { 31145751Smckusick register vm_offset_t va; 31248465Skarels register struct vmspace *vm = p->p_vmspace; 31345751Smckusick register vm_map_t map; 31445751Smckusick int rv; 31545751Smckusick vm_prot_t ftype; 31645751Smckusick extern vm_map_t kernel_map; 31745751Smckusick 31841475Smckusick /* 31945751Smckusick * It is only a kernel address space fault iff: 32049531Skarels * 1. (type & T_USER) == 0 and 32145751Smckusick * 2. pcb_onfault not set or 32245751Smckusick * 3. pcb_onfault set but supervisor space data fault 32345751Smckusick * The last can occur during an exec() copyin where the 32445751Smckusick * argument space is lazy-allocated. 32541475Smckusick */ 32645751Smckusick if (type == T_MMUFLT && 32749125Skarels (!p->p_addr->u_pcb.pcb_onfault || 32845751Smckusick (code & (SSW_DF|FC_SUPERD)) == (SSW_DF|FC_SUPERD))) 32945751Smckusick map = kernel_map; 33045751Smckusick else 33148465Skarels map = &vm->vm_map; 33245751Smckusick if ((code & (SSW_DF|SSW_RW)) == SSW_DF) /* what about RMW? */ 33345751Smckusick ftype = VM_PROT_READ | VM_PROT_WRITE; 33445751Smckusick else 33545751Smckusick ftype = VM_PROT_READ; 33645751Smckusick va = trunc_page((vm_offset_t)v); 33741475Smckusick #ifdef DEBUG 33845751Smckusick if (map == kernel_map && va == 0) { 33945751Smckusick printf("trap: bad kernel access at %x\n", v); 34041475Smckusick goto dopanic; 34141475Smckusick } 34241475Smckusick #endif 34349317Shibler rv = vm_fault(map, va, ftype, FALSE); 34441475Smckusick /* 34549317Shibler * If this was a stack access we keep track of the maximum 34649317Shibler * accessed stack size. Also, if vm_fault gets a protection 34749317Shibler * failure it is due to accessing the stack region outside 34849317Shibler * the current limit and we need to reflect that as an access 34949317Shibler * error. 35041475Smckusick */ 35148465Skarels if ((caddr_t)va >= vm->vm_maxsaddr && map != kernel_map) { 35249317Shibler if (rv == KERN_SUCCESS) { 35349317Shibler unsigned nss; 35449317Shibler 35549317Shibler nss = clrnd(btoc(USRSTACK-(unsigned)va)); 35649317Shibler if (nss > vm->vm_ssize) 35749317Shibler vm->vm_ssize = nss; 35849317Shibler } else if (rv == KERN_PROTECTION_FAILURE) 35949317Shibler rv = KERN_INVALID_ADDRESS; 36041475Smckusick } 36145751Smckusick if (rv == KERN_SUCCESS) { 36241475Smckusick if (type == T_MMUFLT) 36341475Smckusick return; 36441475Smckusick goto out; 36541475Smckusick } 36645751Smckusick if (type == T_MMUFLT) { 36749125Skarels if (p->p_addr->u_pcb.pcb_onfault) 36845751Smckusick goto copyfault; 36945751Smckusick printf("vm_fault(%x, %x, %x, 0) -> %x\n", 37045751Smckusick map, va, ftype, rv); 37145751Smckusick printf(" type %x, code [mmu,,ssw]: %x\n", 37245751Smckusick type, code); 37345751Smckusick goto dopanic; 37445751Smckusick } 37548465Skarels ucode = v; 37645751Smckusick i = (rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV; 37745751Smckusick break; 37845751Smckusick } 37941475Smckusick } 38048465Skarels trapsignal(p, i, ucode); 38149531Skarels if ((type & T_USER) == 0) 38241475Smckusick return; 38341475Smckusick out: 38448465Skarels while (i = CURSIG(p)) 38542370Skarels psig(i); 38641475Smckusick p->p_pri = p->p_usrpri; 38748465Skarels if (want_resched) { 38841475Smckusick /* 38948465Skarels * Since we are curproc, clock will normally just change 39041475Smckusick * our priority without moving us from one queue to another 39141475Smckusick * (since the running process is not on a queue.) 39241475Smckusick * If that happened after we setrq ourselves but before we 39341475Smckusick * swtch()'ed, we might not be on the queue indicated by 39441475Smckusick * our priority. 39541475Smckusick */ 39650753Skarels s = splclock(); 39741475Smckusick setrq(p); 39848465Skarels p->p_stats->p_ru.ru_nivcsw++; 39941475Smckusick swtch(); 40050753Skarels splx(s); 40148465Skarels while (i = CURSIG(p)) 40242370Skarels psig(i); 40341475Smckusick } 40448465Skarels if (p->p_stats->p_prof.pr_scale) { 40541475Smckusick int ticks; 40648465Skarels struct timeval *tv = &p->p_stime; 40741475Smckusick 40841475Smckusick ticks = ((tv->tv_sec - syst.tv_sec) * 1000 + 40941475Smckusick (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000); 41041475Smckusick if (ticks) { 41141475Smckusick #ifdef PROFTIMER 41241475Smckusick extern int profscale; 41348465Skarels addupc(frame.f_pc, &p->p_stats->p_prof, 41448465Skarels ticks * profscale); 41541475Smckusick #else 41648465Skarels addupc(frame.f_pc, &p->p_stats->p_prof, ticks); 41741475Smckusick #endif 41841475Smckusick } 41941475Smckusick } 42041475Smckusick curpri = p->p_pri; 42141475Smckusick } 42241475Smckusick 42341475Smckusick /* 42449531Skarels * Proces a system call. 42541475Smckusick */ 42641475Smckusick syscall(code, frame) 42741475Smckusick volatile int code; 42841475Smckusick struct frame frame; 42941475Smckusick { 43041475Smckusick register caddr_t params; 43141475Smckusick register int i; 43241475Smckusick register struct sysent *callp; 43348465Skarels register struct proc *p = curproc; 43450753Skarels int error, opc, numsys, s; 43544018Skarels struct args { 43644018Skarels int i[8]; 43744018Skarels } args; 43844018Skarels int rval[2]; 43941475Smckusick struct timeval syst; 44041475Smckusick struct sysent *systab; 44141475Smckusick #ifdef HPUXCOMPAT 44241475Smckusick extern struct sysent hpuxsysent[]; 44341475Smckusick extern int hpuxnsysent, notimp(); 44441475Smckusick #endif 44541475Smckusick 44641475Smckusick cnt.v_syscall++; 44748465Skarels syst = p->p_stime; 44841475Smckusick if (!USERMODE(frame.f_sr)) 44941475Smckusick panic("syscall"); 450*52380Smckusick p->p_md.md_regs = frame.f_regs; 45141475Smckusick opc = frame.f_pc - 2; 45241475Smckusick systab = sysent; 45341475Smckusick numsys = nsysent; 45441475Smckusick #ifdef HPUXCOMPAT 45542370Skarels if (p->p_flag & SHPUX) { 45641475Smckusick systab = hpuxsysent; 45741475Smckusick numsys = hpuxnsysent; 45841475Smckusick } 45941475Smckusick #endif 46049531Skarels params = (caddr_t)frame.f_regs[SP] + sizeof(int); 46142370Skarels if (code == 0) { /* indir */ 46242370Skarels code = fuword(params); 46349531Skarels params += sizeof(int); 46442370Skarels } 46542370Skarels if (code >= numsys) 46642370Skarels callp = &systab[0]; /* indir (illegal) */ 46742370Skarels else 46842370Skarels callp = &systab[code]; 46941475Smckusick if ((i = callp->sy_narg * sizeof (int)) && 47044018Skarels (error = copyin(params, (caddr_t)&args, (u_int)i))) { 47141475Smckusick #ifdef HPUXCOMPAT 47241475Smckusick if (p->p_flag & SHPUX) 47342370Skarels error = bsdtohpuxerrno(error); 47441475Smckusick #endif 47549362Skarels frame.f_regs[D0] = error; 47641475Smckusick frame.f_sr |= PSL_C; /* carry bit */ 47741475Smckusick #ifdef KTRACE 47843641Skarels if (KTRPOINT(p, KTR_SYSCALL)) 47944018Skarels ktrsyscall(p->p_tracep, code, callp->sy_narg, args.i); 48041475Smckusick #endif 48141475Smckusick goto done; 48241475Smckusick } 48341475Smckusick #ifdef KTRACE 48443641Skarels if (KTRPOINT(p, KTR_SYSCALL)) 48544018Skarels ktrsyscall(p->p_tracep, code, callp->sy_narg, args.i); 48641475Smckusick #endif 48743641Skarels rval[0] = 0; 48843641Skarels rval[1] = frame.f_regs[D1]; 48941475Smckusick #ifdef HPUXCOMPAT 49042370Skarels /* debug kludge */ 49142370Skarels if (callp->sy_call == notimp) 49248465Skarels error = notimp(p, args.i, rval, code, callp->sy_narg); 49342370Skarels else 49441475Smckusick #endif 49548465Skarels error = (*callp->sy_call)(p, &args, rval); 49642370Skarels if (error == ERESTART) 49742370Skarels frame.f_pc = opc; 49842370Skarels else if (error != EJUSTRETURN) { 49942370Skarels if (error) { 50041475Smckusick #ifdef HPUXCOMPAT 50142370Skarels if (p->p_flag & SHPUX) 50242370Skarels error = bsdtohpuxerrno(error); 50341475Smckusick #endif 50449362Skarels frame.f_regs[D0] = error; 50542370Skarels frame.f_sr |= PSL_C; /* carry bit */ 50641475Smckusick } else { 50743641Skarels frame.f_regs[D0] = rval[0]; 50843641Skarels frame.f_regs[D1] = rval[1]; 50941475Smckusick frame.f_sr &= ~PSL_C; 51041475Smckusick } 51142370Skarels } 51242370Skarels /* else if (error == EJUSTRETURN) */ 51341475Smckusick /* nothing to do */ 51442370Skarels 51541475Smckusick done: 51641475Smckusick /* 51742370Skarels * Reinitialize proc pointer `p' as it may be different 51842370Skarels * if this is a child returning from fork syscall. 51942370Skarels */ 52048465Skarels p = curproc; 52149317Shibler while (i = CURSIG(p)) 52249317Shibler psig(i); 52341475Smckusick p->p_pri = p->p_usrpri; 52448465Skarels if (want_resched) { 52541475Smckusick /* 52648465Skarels * Since we are curproc, clock will normally just change 52741475Smckusick * our priority without moving us from one queue to another 52841475Smckusick * (since the running process is not on a queue.) 52941475Smckusick * If that happened after we setrq ourselves but before we 53041475Smckusick * swtch()'ed, we might not be on the queue indicated by 53141475Smckusick * our priority. 53241475Smckusick */ 53350753Skarels s = splclock(); 53441475Smckusick setrq(p); 53548465Skarels p->p_stats->p_ru.ru_nivcsw++; 53641475Smckusick swtch(); 53750753Skarels splx(s); 53849317Shibler while (i = CURSIG(p)) 53949317Shibler psig(i); 54041475Smckusick } 54148465Skarels if (p->p_stats->p_prof.pr_scale) { 54241475Smckusick int ticks; 54348465Skarels struct timeval *tv = &p->p_stime; 54441475Smckusick 54541475Smckusick ticks = ((tv->tv_sec - syst.tv_sec) * 1000 + 54641475Smckusick (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000); 54741475Smckusick if (ticks) { 54841475Smckusick #ifdef PROFTIMER 54941475Smckusick extern int profscale; 55048465Skarels addupc(frame.f_pc, &p->p_stats->p_prof, 55148465Skarels ticks * profscale); 55241475Smckusick #else 55348465Skarels addupc(frame.f_pc, &p->p_stats->p_prof, ticks); 55441475Smckusick #endif 55541475Smckusick } 55641475Smckusick } 55741475Smckusick curpri = p->p_pri; 55841475Smckusick #ifdef KTRACE 55943641Skarels if (KTRPOINT(p, KTR_SYSRET)) 56043641Skarels ktrsysret(p->p_tracep, code, error, rval[0]); 56141475Smckusick #endif 56241475Smckusick } 563