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*49362Skarels * @(#)trap.c 7.13 (Berkeley) 05/07/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 3149125Skarels #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 6849317Shibler /* 6949317Shibler * Size of various exception stack frames (minus the standard 8 bytes) 7049317Shibler */ 7149317Shibler short exframesize[] = { 7249317Shibler FMT0SIZE, /* type 0 - normal (68020/030/040) */ 7349317Shibler FMT1SIZE, /* type 1 - throwaway (68020/030/040) */ 7449317Shibler FMT2SIZE, /* type 2 - normal 6-word (68020/030/040) */ 7549317Shibler -1, /* type 3 - FP post-instruction (68040) */ 7649317Shibler -1, -1, -1, /* type 4-6 - undefined */ 7749317Shibler -1, /* type 7 - access error (68040) */ 7849317Shibler 58, /* type 8 - bus fault (68010) */ 7949317Shibler FMT9SIZE, /* type 9 - coprocessor mid-instruction (68020/030) */ 8049317Shibler FMTASIZE, /* type A - short bus fault (68020/030) */ 8149317Shibler FMTBSIZE, /* type B - long bus fault (68020/030) */ 8249317Shibler -1, -1, -1, -1 /* type C-F - undefined */ 8349317Shibler }; 8449317Shibler 8541475Smckusick #ifdef DEBUG 8641475Smckusick int mmudebug = 0; 8741475Smckusick #endif 8841475Smckusick 8941475Smckusick /* 9041475Smckusick * Called from the trap handler when a processor trap occurs. 9141475Smckusick */ 9241475Smckusick /*ARGSUSED*/ 9341475Smckusick trap(type, code, v, frame) 9441475Smckusick int type; 9541475Smckusick unsigned code; 9641475Smckusick register unsigned v; 9741475Smckusick struct frame frame; 9841475Smckusick { 9941475Smckusick register int i; 10041475Smckusick unsigned ucode = 0; 10148465Skarels register struct proc *p = curproc; 10241475Smckusick struct timeval syst; 10341475Smckusick unsigned ncode; 10441475Smckusick 10541475Smckusick cnt.v_trap++; 10648465Skarels syst = p->p_stime; 10741475Smckusick if (USERMODE(frame.f_sr)) { 10841475Smckusick type |= USER; 10948465Skarels p->p_regs = frame.f_regs; 11041475Smckusick } 11141475Smckusick switch (type) { 11241475Smckusick 11341475Smckusick default: 11441475Smckusick dopanic: 11541475Smckusick printf("trap type %d, code = %x, v = %x\n", type, code, v); 11641475Smckusick regdump(frame.f_regs, 128); 11741475Smckusick type &= ~USER; 11841475Smckusick if ((unsigned)type < TRAP_TYPES) 11941475Smckusick panic(trap_type[type]); 12041475Smckusick panic("trap"); 12141475Smckusick 12241475Smckusick case T_BUSERR: /* kernel bus error */ 12349125Skarels if (!p->p_addr->u_pcb.pcb_onfault) 12441475Smckusick goto dopanic; 12541475Smckusick /* 12641475Smckusick * If we have arranged to catch this fault in any of the 12741475Smckusick * copy to/from user space routines, set PC to return to 12841475Smckusick * indicated location and set flag informing buserror code 12941475Smckusick * that it may need to clean up stack frame. 13041475Smckusick */ 13141475Smckusick copyfault: 13249317Shibler frame.f_stackadj = exframesize[frame.f_format]; 13349317Shibler frame.f_format = frame.f_vector = 0; 13449125Skarels frame.f_pc = (int) p->p_addr->u_pcb.pcb_onfault; 13541475Smckusick return; 13641475Smckusick 13741475Smckusick case T_BUSERR+USER: /* bus error */ 13841475Smckusick case T_ADDRERR+USER: /* address error */ 13941475Smckusick i = SIGBUS; 14041475Smckusick break; 14141475Smckusick 14241475Smckusick #ifdef FPCOPROC 14341475Smckusick case T_COPERR: /* kernel coprocessor violation */ 14441475Smckusick #endif 14541475Smckusick case T_FMTERR: /* kernel format error */ 14641475Smckusick /* 14741475Smckusick * The user has most likely trashed the RTE or FP state info 14841475Smckusick * in the stack frame of a signal handler. 14941475Smckusick */ 15042370Skarels type |= USER; 15148465Skarels printf("pid %d: kernel %s exception\n", p->p_pid, 15241475Smckusick type==T_COPERR ? "coprocessor" : "format"); 15348465Skarels p->p_sigacts->ps_sigact[SIGILL] = SIG_DFL; 15441475Smckusick i = sigmask(SIGILL); 15541475Smckusick p->p_sigignore &= ~i; 15641475Smckusick p->p_sigcatch &= ~i; 15741475Smckusick p->p_sigmask &= ~i; 15842370Skarels i = SIGILL; 15941475Smckusick ucode = frame.f_format; /* XXX was ILL_RESAD_FAULT */ 16042370Skarels break; 16141475Smckusick 16241475Smckusick #ifdef FPCOPROC 16341475Smckusick case T_COPERR+USER: /* user coprocessor violation */ 16441475Smckusick /* What is a proper response here? */ 16541475Smckusick ucode = 0; 16641475Smckusick i = SIGFPE; 16741475Smckusick break; 16841475Smckusick 16949317Shibler case T_FPERR+USER: /* 68881 exceptions */ 17041475Smckusick /* 17141475Smckusick * We pass along the 68881 status register which locore stashed 17241475Smckusick * in code for us. Note that there is a possibility that the 17341475Smckusick * bit pattern of this register will conflict with one of the 17441475Smckusick * FPE_* codes defined in signal.h. Fortunately for us, the 17541475Smckusick * only such codes we use are all in the range 1-7 and the low 17641475Smckusick * 3 bits of the status register are defined as 0 so there is 17741475Smckusick * no clash. 17841475Smckusick */ 17941475Smckusick ucode = code; 18041475Smckusick i = SIGFPE; 18141475Smckusick break; 18241475Smckusick #endif 18341475Smckusick 18441475Smckusick case T_ILLINST+USER: /* illegal instruction fault */ 18541475Smckusick #ifdef HPUXCOMPAT 18648465Skarels if (p->p_flag & SHPUX) { 18741475Smckusick ucode = HPUX_ILL_ILLINST_TRAP; 18841475Smckusick i = SIGILL; 18941475Smckusick break; 19041475Smckusick } 19141475Smckusick /* fall through */ 19241475Smckusick #endif 19341475Smckusick case T_PRIVINST+USER: /* privileged instruction fault */ 19441475Smckusick #ifdef HPUXCOMPAT 19548465Skarels if (p->p_flag & SHPUX) 19641475Smckusick ucode = HPUX_ILL_PRIV_TRAP; 19741475Smckusick else 19841475Smckusick #endif 19941475Smckusick ucode = frame.f_format; /* XXX was ILL_PRIVIN_FAULT */ 20041475Smckusick i = SIGILL; 20141475Smckusick break; 20241475Smckusick 20341475Smckusick case T_ZERODIV+USER: /* Divide by zero */ 20441475Smckusick #ifdef HPUXCOMPAT 20548465Skarels if (p->p_flag & SHPUX) 20641475Smckusick ucode = HPUX_FPE_INTDIV_TRAP; 20741475Smckusick else 20841475Smckusick #endif 20941475Smckusick ucode = frame.f_format; /* XXX was FPE_INTDIV_TRAP */ 21041475Smckusick i = SIGFPE; 21141475Smckusick break; 21241475Smckusick 21341475Smckusick case T_CHKINST+USER: /* CHK instruction trap */ 21441475Smckusick #ifdef HPUXCOMPAT 21548465Skarels if (p->p_flag & SHPUX) { 21641475Smckusick /* handled differently under hp-ux */ 21741475Smckusick i = SIGILL; 21841475Smckusick ucode = HPUX_ILL_CHK_TRAP; 21941475Smckusick break; 22041475Smckusick } 22141475Smckusick #endif 22241475Smckusick ucode = frame.f_format; /* XXX was FPE_SUBRNG_TRAP */ 22341475Smckusick i = SIGFPE; 22441475Smckusick break; 22541475Smckusick 22641475Smckusick case T_TRAPVINST+USER: /* TRAPV instruction trap */ 22741475Smckusick #ifdef HPUXCOMPAT 22848465Skarels if (p->p_flag & SHPUX) { 22941475Smckusick /* handled differently under hp-ux */ 23041475Smckusick i = SIGILL; 23141475Smckusick ucode = HPUX_ILL_TRAPV_TRAP; 23241475Smckusick break; 23341475Smckusick } 23441475Smckusick #endif 23541475Smckusick ucode = frame.f_format; /* XXX was FPE_INTOVF_TRAP */ 23641475Smckusick i = SIGFPE; 23741475Smckusick break; 23841475Smckusick 23941475Smckusick /* 24041475Smckusick * XXX: Trace traps are a nightmare. 24141475Smckusick * 24241475Smckusick * HP-UX uses trap #1 for breakpoints, 24341475Smckusick * HPBSD uses trap #2, 24441475Smckusick * SUN 3.x uses trap #15, 24548465Skarels * KGDB uses trap #15 (for kernel breakpoints; handled elsewhere). 24641475Smckusick * 24741475Smckusick * HPBSD and HP-UX traps both get mapped by locore.s into T_TRACE. 24841475Smckusick * SUN 3.x traps get passed through as T_TRAP15 and are not really 24948465Skarels * supported yet. 25041475Smckusick */ 25141475Smckusick case T_TRACE: /* kernel trace trap */ 25248465Skarels case T_TRAP15: /* SUN trace trap */ 25341475Smckusick frame.f_sr &= ~PSL_T; 25441475Smckusick i = SIGTRAP; 25541475Smckusick break; 25641475Smckusick 25741475Smckusick case T_TRACE+USER: /* user trace trap */ 25841475Smckusick case T_TRAP15+USER: /* SUN user trace trap */ 25941475Smckusick frame.f_sr &= ~PSL_T; 26041475Smckusick i = SIGTRAP; 26141475Smckusick break; 26241475Smckusick 26343413Shibler case T_ASTFLT: /* system async trap, cannot happen */ 26441475Smckusick goto dopanic; 26541475Smckusick 26643413Shibler case T_ASTFLT+USER: /* user async trap */ 26749125Skarels astpending = 0; 26841475Smckusick /* 26941475Smckusick * We check for software interrupts first. This is because 27041475Smckusick * they are at a higher level than ASTs, and on a VAX would 27141475Smckusick * interrupt the AST. We assume that if we are processing 27241475Smckusick * an AST that we must be at IPL0 so we don't bother to 27341475Smckusick * check. Note that we ensure that we are at least at SIR 27441475Smckusick * IPL while processing the SIR. 27541475Smckusick */ 27641475Smckusick spl1(); 27741475Smckusick /* fall into... */ 27841475Smckusick 27941475Smckusick case T_SSIR: /* software interrupt */ 28041475Smckusick case T_SSIR+USER: 28141475Smckusick if (ssir & SIR_NET) { 28241475Smckusick siroff(SIR_NET); 28341475Smckusick cnt.v_soft++; 28441475Smckusick netintr(); 28541475Smckusick } 28641475Smckusick if (ssir & SIR_CLOCK) { 28741475Smckusick siroff(SIR_CLOCK); 28841475Smckusick cnt.v_soft++; 28941475Smckusick softclock((caddr_t)frame.f_pc, (int)frame.f_sr); 29041475Smckusick } 29141475Smckusick /* 29241475Smckusick * If this was not an AST trap, we are all done. 29341475Smckusick */ 29443413Shibler if (type != T_ASTFLT+USER) { 29541475Smckusick cnt.v_trap--; 29641475Smckusick return; 29741475Smckusick } 29841475Smckusick spl0(); 29941475Smckusick #ifndef PROFTIMER 30048465Skarels if ((p->p_flag&SOWEUPC) && p->p_stats->p_prof.pr_scale) { 30148465Skarels addupc(frame.f_pc, &p->p_stats->p_prof, 1); 30248465Skarels p->p_flag &= ~SOWEUPC; 30341475Smckusick } 30441475Smckusick #endif 30541475Smckusick goto out; 30641475Smckusick 30741475Smckusick case T_MMUFLT: /* kernel mode page fault */ 30841475Smckusick /* fall into ... */ 30941475Smckusick 31041475Smckusick case T_MMUFLT+USER: /* page fault */ 31145751Smckusick { 31245751Smckusick register vm_offset_t va; 31348465Skarels register struct vmspace *vm = p->p_vmspace; 31445751Smckusick register vm_map_t map; 31545751Smckusick int rv; 31645751Smckusick vm_prot_t ftype; 31745751Smckusick extern vm_map_t kernel_map; 31845751Smckusick 31941475Smckusick /* 32045751Smckusick * It is only a kernel address space fault iff: 32145751Smckusick * 1. (type & USER) == 0 and 32245751Smckusick * 2. pcb_onfault not set or 32345751Smckusick * 3. pcb_onfault set but supervisor space data fault 32445751Smckusick * The last can occur during an exec() copyin where the 32545751Smckusick * argument space is lazy-allocated. 32641475Smckusick */ 32745751Smckusick if (type == T_MMUFLT && 32849125Skarels (!p->p_addr->u_pcb.pcb_onfault || 32945751Smckusick (code & (SSW_DF|FC_SUPERD)) == (SSW_DF|FC_SUPERD))) 33045751Smckusick map = kernel_map; 33145751Smckusick else 33248465Skarels map = &vm->vm_map; 33345751Smckusick if ((code & (SSW_DF|SSW_RW)) == SSW_DF) /* what about RMW? */ 33445751Smckusick ftype = VM_PROT_READ | VM_PROT_WRITE; 33545751Smckusick else 33645751Smckusick ftype = VM_PROT_READ; 33745751Smckusick va = trunc_page((vm_offset_t)v); 33841475Smckusick #ifdef DEBUG 33945751Smckusick if (map == kernel_map && va == 0) { 34045751Smckusick printf("trap: bad kernel access at %x\n", v); 34141475Smckusick goto dopanic; 34241475Smckusick } 34341475Smckusick #endif 34449317Shibler rv = vm_fault(map, va, ftype, FALSE); 34541475Smckusick /* 34649317Shibler * If this was a stack access we keep track of the maximum 34749317Shibler * accessed stack size. Also, if vm_fault gets a protection 34849317Shibler * failure it is due to accessing the stack region outside 34949317Shibler * the current limit and we need to reflect that as an access 35049317Shibler * error. 35141475Smckusick */ 35248465Skarels if ((caddr_t)va >= vm->vm_maxsaddr && map != kernel_map) { 35349317Shibler if (rv == KERN_SUCCESS) { 35449317Shibler unsigned nss; 35549317Shibler 35649317Shibler nss = clrnd(btoc(USRSTACK-(unsigned)va)); 35749317Shibler if (nss > vm->vm_ssize) 35849317Shibler vm->vm_ssize = nss; 35949317Shibler } else if (rv == KERN_PROTECTION_FAILURE) 36049317Shibler rv = KERN_INVALID_ADDRESS; 36141475Smckusick } 36245751Smckusick if (rv == KERN_SUCCESS) { 36341475Smckusick if (type == T_MMUFLT) 36441475Smckusick return; 36541475Smckusick goto out; 36641475Smckusick } 36745751Smckusick if (type == T_MMUFLT) { 36849125Skarels if (p->p_addr->u_pcb.pcb_onfault) 36945751Smckusick goto copyfault; 37045751Smckusick printf("vm_fault(%x, %x, %x, 0) -> %x\n", 37145751Smckusick map, va, ftype, rv); 37245751Smckusick printf(" type %x, code [mmu,,ssw]: %x\n", 37345751Smckusick type, code); 37445751Smckusick goto dopanic; 37545751Smckusick } 37648465Skarels ucode = v; 37745751Smckusick i = (rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV; 37845751Smckusick break; 37945751Smckusick } 38041475Smckusick } 38148465Skarels trapsignal(p, i, ucode); 38241475Smckusick if ((type & USER) == 0) 38341475Smckusick return; 38441475Smckusick out: 38548465Skarels while (i = CURSIG(p)) 38642370Skarels psig(i); 38741475Smckusick p->p_pri = p->p_usrpri; 38848465Skarels if (want_resched) { 38941475Smckusick /* 39048465Skarels * Since we are curproc, clock will normally just change 39141475Smckusick * our priority without moving us from one queue to another 39241475Smckusick * (since the running process is not on a queue.) 39341475Smckusick * If that happened after we setrq ourselves but before we 39441475Smckusick * swtch()'ed, we might not be on the queue indicated by 39541475Smckusick * our priority. 39641475Smckusick */ 39741475Smckusick (void) splclock(); 39841475Smckusick setrq(p); 39948465Skarels p->p_stats->p_ru.ru_nivcsw++; 40041475Smckusick swtch(); 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 /* 42441475Smckusick * Called from the trap handler when a system call occurs 42541475Smckusick */ 42641475Smckusick /*ARGSUSED*/ 42741475Smckusick syscall(code, frame) 42841475Smckusick volatile int code; 42941475Smckusick struct frame frame; 43041475Smckusick { 43141475Smckusick register caddr_t params; 43241475Smckusick register int i; 43341475Smckusick register struct sysent *callp; 43448465Skarels register struct proc *p = curproc; 43542370Skarels int error, opc, numsys; 43644018Skarels struct args { 43744018Skarels int i[8]; 43844018Skarels } args; 43944018Skarels int rval[2]; 44041475Smckusick struct timeval syst; 44141475Smckusick struct sysent *systab; 44241475Smckusick #ifdef HPUXCOMPAT 44341475Smckusick extern struct sysent hpuxsysent[]; 44441475Smckusick extern int hpuxnsysent, notimp(); 44541475Smckusick #endif 44641475Smckusick 44741475Smckusick cnt.v_syscall++; 44848465Skarels syst = p->p_stime; 44941475Smckusick if (!USERMODE(frame.f_sr)) 45041475Smckusick panic("syscall"); 45148465Skarels p->p_regs = frame.f_regs; 45241475Smckusick opc = frame.f_pc - 2; 45341475Smckusick systab = sysent; 45441475Smckusick numsys = nsysent; 45541475Smckusick #ifdef HPUXCOMPAT 45642370Skarels if (p->p_flag & SHPUX) { 45741475Smckusick systab = hpuxsysent; 45841475Smckusick numsys = hpuxnsysent; 45941475Smckusick } 46041475Smckusick #endif 46141475Smckusick params = (caddr_t)frame.f_regs[SP] + NBPW; 46242370Skarels if (code == 0) { /* indir */ 46342370Skarels code = fuword(params); 46441475Smckusick params += NBPW; 46542370Skarels } 46642370Skarels if (code >= numsys) 46742370Skarels callp = &systab[0]; /* indir (illegal) */ 46842370Skarels else 46942370Skarels callp = &systab[code]; 47041475Smckusick if ((i = callp->sy_narg * sizeof (int)) && 47144018Skarels (error = copyin(params, (caddr_t)&args, (u_int)i))) { 47241475Smckusick #ifdef HPUXCOMPAT 47341475Smckusick if (p->p_flag & SHPUX) 47442370Skarels error = bsdtohpuxerrno(error); 47541475Smckusick #endif 476*49362Skarels frame.f_regs[D0] = error; 47741475Smckusick frame.f_sr |= PSL_C; /* carry bit */ 47841475Smckusick #ifdef KTRACE 47943641Skarels if (KTRPOINT(p, KTR_SYSCALL)) 48044018Skarels ktrsyscall(p->p_tracep, code, callp->sy_narg, args.i); 48141475Smckusick #endif 48241475Smckusick goto done; 48341475Smckusick } 48441475Smckusick #ifdef KTRACE 48543641Skarels if (KTRPOINT(p, KTR_SYSCALL)) 48644018Skarels ktrsyscall(p->p_tracep, code, callp->sy_narg, args.i); 48741475Smckusick #endif 48843641Skarels rval[0] = 0; 48943641Skarels rval[1] = frame.f_regs[D1]; 49041475Smckusick #ifdef HPUXCOMPAT 49142370Skarels /* debug kludge */ 49242370Skarels if (callp->sy_call == notimp) 49348465Skarels error = notimp(p, args.i, rval, code, callp->sy_narg); 49442370Skarels else 49541475Smckusick #endif 49648465Skarels error = (*callp->sy_call)(p, &args, rval); 49742370Skarels if (error == ERESTART) 49842370Skarels frame.f_pc = opc; 49942370Skarels else if (error != EJUSTRETURN) { 50042370Skarels if (error) { 50141475Smckusick #ifdef HPUXCOMPAT 50242370Skarels if (p->p_flag & SHPUX) 50342370Skarels error = bsdtohpuxerrno(error); 50441475Smckusick #endif 505*49362Skarels frame.f_regs[D0] = error; 50642370Skarels frame.f_sr |= PSL_C; /* carry bit */ 50741475Smckusick } else { 50843641Skarels frame.f_regs[D0] = rval[0]; 50943641Skarels frame.f_regs[D1] = rval[1]; 51041475Smckusick frame.f_sr &= ~PSL_C; 51141475Smckusick } 51242370Skarels } 51342370Skarels /* else if (error == EJUSTRETURN) */ 51441475Smckusick /* nothing to do */ 51542370Skarels 51641475Smckusick done: 51741475Smckusick /* 51842370Skarels * Reinitialize proc pointer `p' as it may be different 51942370Skarels * if this is a child returning from fork syscall. 52042370Skarels */ 52148465Skarels p = curproc; 52249317Shibler while (i = CURSIG(p)) 52349317Shibler psig(i); 52441475Smckusick p->p_pri = p->p_usrpri; 52548465Skarels if (want_resched) { 52641475Smckusick /* 52748465Skarels * Since we are curproc, clock will normally just change 52841475Smckusick * our priority without moving us from one queue to another 52941475Smckusick * (since the running process is not on a queue.) 53041475Smckusick * If that happened after we setrq ourselves but before we 53141475Smckusick * swtch()'ed, we might not be on the queue indicated by 53241475Smckusick * our priority. 53341475Smckusick */ 53441475Smckusick (void) splclock(); 53541475Smckusick setrq(p); 53648465Skarels p->p_stats->p_ru.ru_nivcsw++; 53741475Smckusick swtch(); 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