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 * 1253933Shibler * from: Utah $Hdr: trap.c 1.35 91/12/26$ 1341475Smckusick * 14*54574Storek * @(#)trap.c 7.21 (Berkeley) 06/30/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 4053933Shibler #include "hp/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) */ 7153933Shibler FMT3SIZE, /* type 3 - FP post-instruction (68040) */ 7249317Shibler -1, -1, -1, /* type 4-6 - undefined */ 7353933Shibler FMT7SIZE, /* 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 8153933Shibler #if defined(HP380) 8253933Shibler #define KDFAULT(c) (mmutype == MMU_68040 ? \ 8353933Shibler ((c) & SSW4_TMMASK) == SSW4_TMKD : \ 8453933Shibler ((c) & (SSW_DF|FC_SUPERD)) == (SSW_DF|FC_SUPERD)) 8553933Shibler #define WRFAULT(c) (mmutype == MMU_68040 ? \ 8653933Shibler ((c) & SSW4_RW) == 0 : \ 8753933Shibler ((c) & (SSW_DF|SSW_RW)) == SSW_DF) 8853933Shibler #else 8953933Shibler #define KDFAULT(c) (((c) & (SSW_DF|SSW_FCMASK)) == (SSW_DF|FC_SUPERD)) 9053933Shibler #define WRFAULT(c) (((c) & (SSW_DF|SSW_RW)) == SSW_DF) 9153933Shibler #endif 9253933Shibler 9341475Smckusick #ifdef DEBUG 9441475Smckusick int mmudebug = 0; 9553933Shibler int mmupid = -1; 9653933Shibler #define MDB_FOLLOW 1 9753933Shibler #define MDB_WBFOLLOW 2 9853933Shibler #define MDB_WBFAILED 4 9953933Shibler #define MDB_ISPID(p) (p) == mmupid 10041475Smckusick #endif 10141475Smckusick 10241475Smckusick /* 10349531Skarels * Trap is called from locore to handle most types of processor traps, 10449531Skarels * including events such as simulated software interrupts/AST's. 10549531Skarels * System calls are broken out for efficiency. 10641475Smckusick */ 10741475Smckusick /*ARGSUSED*/ 10841475Smckusick trap(type, code, v, frame) 10941475Smckusick int type; 11041475Smckusick unsigned code; 11141475Smckusick register unsigned v; 11241475Smckusick struct frame frame; 11341475Smckusick { 11441475Smckusick register int i; 11541475Smckusick unsigned ucode = 0; 11648465Skarels register struct proc *p = curproc; 11741475Smckusick struct timeval syst; 11841475Smckusick unsigned ncode; 11950753Skarels int s; 12053933Shibler #if defined(HP380) 12153933Shibler int beenhere = 0; 12253933Shibler #endif 123*54574Storek extern char fswintr[]; 12441475Smckusick 12541475Smckusick cnt.v_trap++; 12648465Skarels syst = p->p_stime; 12741475Smckusick if (USERMODE(frame.f_sr)) { 12849531Skarels type |= T_USER; 12952380Smckusick p->p_md.md_regs = frame.f_regs; 13041475Smckusick } 13141475Smckusick switch (type) { 13241475Smckusick 13341475Smckusick default: 13441475Smckusick dopanic: 13541475Smckusick printf("trap type %d, code = %x, v = %x\n", type, code, v); 13641475Smckusick regdump(frame.f_regs, 128); 13749531Skarels type &= ~T_USER; 13841475Smckusick if ((unsigned)type < TRAP_TYPES) 13941475Smckusick panic(trap_type[type]); 14041475Smckusick panic("trap"); 14141475Smckusick 14241475Smckusick case T_BUSERR: /* kernel bus error */ 14349125Skarels if (!p->p_addr->u_pcb.pcb_onfault) 14441475Smckusick goto dopanic; 14541475Smckusick /* 14641475Smckusick * If we have arranged to catch this fault in any of the 14741475Smckusick * copy to/from user space routines, set PC to return to 14841475Smckusick * indicated location and set flag informing buserror code 14941475Smckusick * that it may need to clean up stack frame. 15041475Smckusick */ 15141475Smckusick copyfault: 15249317Shibler frame.f_stackadj = exframesize[frame.f_format]; 15349317Shibler frame.f_format = frame.f_vector = 0; 15449125Skarels frame.f_pc = (int) p->p_addr->u_pcb.pcb_onfault; 15541475Smckusick return; 15641475Smckusick 15749531Skarels case T_BUSERR|T_USER: /* bus error */ 15849531Skarels case T_ADDRERR|T_USER: /* address error */ 15953933Shibler ucode = v; 16041475Smckusick i = SIGBUS; 16141475Smckusick break; 16241475Smckusick 16341475Smckusick #ifdef FPCOPROC 16441475Smckusick case T_COPERR: /* kernel coprocessor violation */ 16541475Smckusick #endif 16653933Shibler case T_FMTERR|T_USER: /* do all RTE errors come in as T_USER? */ 16753933Shibler case T_FMTERR: /* ...just in case... */ 16841475Smckusick /* 16941475Smckusick * The user has most likely trashed the RTE or FP state info 17041475Smckusick * in the stack frame of a signal handler. 17141475Smckusick */ 17249531Skarels type |= T_USER; 17348465Skarels printf("pid %d: kernel %s exception\n", p->p_pid, 17441475Smckusick type==T_COPERR ? "coprocessor" : "format"); 17548465Skarels p->p_sigacts->ps_sigact[SIGILL] = SIG_DFL; 17641475Smckusick i = sigmask(SIGILL); 17741475Smckusick p->p_sigignore &= ~i; 17841475Smckusick p->p_sigcatch &= ~i; 17941475Smckusick p->p_sigmask &= ~i; 18042370Skarels i = SIGILL; 18141475Smckusick ucode = frame.f_format; /* XXX was ILL_RESAD_FAULT */ 18242370Skarels break; 18341475Smckusick 18441475Smckusick #ifdef FPCOPROC 18549531Skarels case T_COPERR|T_USER: /* user coprocessor violation */ 18641475Smckusick /* What is a proper response here? */ 18741475Smckusick ucode = 0; 18841475Smckusick i = SIGFPE; 18941475Smckusick break; 19041475Smckusick 19149531Skarels case T_FPERR|T_USER: /* 68881 exceptions */ 19241475Smckusick /* 19341475Smckusick * We pass along the 68881 status register which locore stashed 19441475Smckusick * in code for us. Note that there is a possibility that the 19541475Smckusick * bit pattern of this register will conflict with one of the 19641475Smckusick * FPE_* codes defined in signal.h. Fortunately for us, the 19741475Smckusick * only such codes we use are all in the range 1-7 and the low 19841475Smckusick * 3 bits of the status register are defined as 0 so there is 19941475Smckusick * no clash. 20041475Smckusick */ 20141475Smckusick ucode = code; 20241475Smckusick i = SIGFPE; 20341475Smckusick break; 20441475Smckusick #endif 20541475Smckusick 20653933Shibler #if defined(HP380) 20753933Shibler case T_FPEMULI|T_USER: /* unimplemented FP instuction */ 20853933Shibler case T_FPEMULD|T_USER: /* unimplemented FP data type */ 20953933Shibler /* XXX need to FSAVE */ 21053933Shibler printf("pid %d(%s): unimplemented FP %s at %x (EA %x)\n", 21153933Shibler p->p_pid, p->p_comm, 21253933Shibler frame.f_format == 2 ? "instruction" : "data type", 21353933Shibler frame.f_pc, frame.f_fmt2.f_iaddr); 21453933Shibler /* XXX need to FRESTORE */ 21553933Shibler i = SIGFPE; 21653933Shibler break; 21753933Shibler #endif 21853933Shibler 21949531Skarels case T_ILLINST|T_USER: /* illegal instruction fault */ 22041475Smckusick #ifdef HPUXCOMPAT 22148465Skarels if (p->p_flag & SHPUX) { 22241475Smckusick ucode = HPUX_ILL_ILLINST_TRAP; 22341475Smckusick i = SIGILL; 22441475Smckusick break; 22541475Smckusick } 22641475Smckusick /* fall through */ 22741475Smckusick #endif 22849531Skarels case T_PRIVINST|T_USER: /* privileged instruction fault */ 22941475Smckusick #ifdef HPUXCOMPAT 23048465Skarels if (p->p_flag & SHPUX) 23141475Smckusick ucode = HPUX_ILL_PRIV_TRAP; 23241475Smckusick else 23341475Smckusick #endif 23441475Smckusick ucode = frame.f_format; /* XXX was ILL_PRIVIN_FAULT */ 23541475Smckusick i = SIGILL; 23641475Smckusick break; 23741475Smckusick 23849531Skarels case T_ZERODIV|T_USER: /* Divide by zero */ 23941475Smckusick #ifdef HPUXCOMPAT 24048465Skarels if (p->p_flag & SHPUX) 24141475Smckusick ucode = HPUX_FPE_INTDIV_TRAP; 24241475Smckusick else 24341475Smckusick #endif 24441475Smckusick ucode = frame.f_format; /* XXX was FPE_INTDIV_TRAP */ 24541475Smckusick i = SIGFPE; 24641475Smckusick break; 24741475Smckusick 24849531Skarels case T_CHKINST|T_USER: /* CHK instruction trap */ 24941475Smckusick #ifdef HPUXCOMPAT 25048465Skarels if (p->p_flag & SHPUX) { 25141475Smckusick /* handled differently under hp-ux */ 25241475Smckusick i = SIGILL; 25341475Smckusick ucode = HPUX_ILL_CHK_TRAP; 25441475Smckusick break; 25541475Smckusick } 25641475Smckusick #endif 25741475Smckusick ucode = frame.f_format; /* XXX was FPE_SUBRNG_TRAP */ 25841475Smckusick i = SIGFPE; 25941475Smckusick break; 26041475Smckusick 26149531Skarels case T_TRAPVINST|T_USER: /* TRAPV instruction trap */ 26241475Smckusick #ifdef HPUXCOMPAT 26348465Skarels if (p->p_flag & SHPUX) { 26441475Smckusick /* handled differently under hp-ux */ 26541475Smckusick i = SIGILL; 26641475Smckusick ucode = HPUX_ILL_TRAPV_TRAP; 26741475Smckusick break; 26841475Smckusick } 26941475Smckusick #endif 27041475Smckusick ucode = frame.f_format; /* XXX was FPE_INTOVF_TRAP */ 27141475Smckusick i = SIGFPE; 27241475Smckusick break; 27341475Smckusick 27441475Smckusick /* 27541475Smckusick * XXX: Trace traps are a nightmare. 27641475Smckusick * 27741475Smckusick * HP-UX uses trap #1 for breakpoints, 27841475Smckusick * HPBSD uses trap #2, 27941475Smckusick * SUN 3.x uses trap #15, 28048465Skarels * KGDB uses trap #15 (for kernel breakpoints; handled elsewhere). 28141475Smckusick * 28241475Smckusick * HPBSD and HP-UX traps both get mapped by locore.s into T_TRACE. 28341475Smckusick * SUN 3.x traps get passed through as T_TRAP15 and are not really 28448465Skarels * supported yet. 28541475Smckusick */ 28641475Smckusick case T_TRACE: /* kernel trace trap */ 28748465Skarels case T_TRAP15: /* SUN trace trap */ 28841475Smckusick frame.f_sr &= ~PSL_T; 28941475Smckusick i = SIGTRAP; 29041475Smckusick break; 29141475Smckusick 29249531Skarels case T_TRACE|T_USER: /* user trace trap */ 29349531Skarels case T_TRAP15|T_USER: /* SUN user trace trap */ 29441475Smckusick frame.f_sr &= ~PSL_T; 29541475Smckusick i = SIGTRAP; 29641475Smckusick break; 29741475Smckusick 29843413Shibler case T_ASTFLT: /* system async trap, cannot happen */ 29941475Smckusick goto dopanic; 30041475Smckusick 30149531Skarels case T_ASTFLT|T_USER: /* user async trap */ 30249125Skarels astpending = 0; 30341475Smckusick /* 30441475Smckusick * We check for software interrupts first. This is because 30541475Smckusick * they are at a higher level than ASTs, and on a VAX would 30641475Smckusick * interrupt the AST. We assume that if we are processing 30741475Smckusick * an AST that we must be at IPL0 so we don't bother to 30841475Smckusick * check. Note that we ensure that we are at least at SIR 30941475Smckusick * IPL while processing the SIR. 31041475Smckusick */ 31141475Smckusick spl1(); 31241475Smckusick /* fall into... */ 31341475Smckusick 31441475Smckusick case T_SSIR: /* software interrupt */ 31549531Skarels case T_SSIR|T_USER: 31641475Smckusick if (ssir & SIR_NET) { 31741475Smckusick siroff(SIR_NET); 31841475Smckusick cnt.v_soft++; 31941475Smckusick netintr(); 32041475Smckusick } 32141475Smckusick if (ssir & SIR_CLOCK) { 32241475Smckusick siroff(SIR_CLOCK); 32341475Smckusick cnt.v_soft++; 32441475Smckusick softclock((caddr_t)frame.f_pc, (int)frame.f_sr); 32541475Smckusick } 32641475Smckusick /* 32741475Smckusick * If this was not an AST trap, we are all done. 32841475Smckusick */ 32950753Skarels if (type != (T_ASTFLT|T_USER)) { 33041475Smckusick cnt.v_trap--; 33141475Smckusick return; 33241475Smckusick } 33341475Smckusick spl0(); 33441475Smckusick #ifndef PROFTIMER 33548465Skarels if ((p->p_flag&SOWEUPC) && p->p_stats->p_prof.pr_scale) { 33648465Skarels addupc(frame.f_pc, &p->p_stats->p_prof, 1); 33748465Skarels p->p_flag &= ~SOWEUPC; 33841475Smckusick } 33941475Smckusick #endif 34041475Smckusick goto out; 34141475Smckusick 34241475Smckusick case T_MMUFLT: /* kernel mode page fault */ 343*54574Storek /* 344*54574Storek * If we were doing profiling ticks or other user mode 345*54574Storek * stuff from interrupt code, Just Say No. 346*54574Storek */ 347*54574Storek if (p->p_addr->u_pcb.pcb_onfault == fswintr) 348*54574Storek goto copyfault; 34941475Smckusick /* fall into ... */ 35041475Smckusick 35149531Skarels case T_MMUFLT|T_USER: /* page fault */ 35245751Smckusick { 35345751Smckusick register vm_offset_t va; 35448465Skarels register struct vmspace *vm = p->p_vmspace; 35545751Smckusick register vm_map_t map; 35645751Smckusick int rv; 35745751Smckusick vm_prot_t ftype; 35845751Smckusick extern vm_map_t kernel_map; 35945751Smckusick 36053933Shibler #ifdef DEBUG 36153933Shibler if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) 36253933Shibler printf("trap: T_MMUFLT pid=%d, code=%x, v=%x, pc=%x, sr=%x\n", 36353933Shibler p->p_pid, code, v, frame.f_pc, frame.f_sr); 36453933Shibler #endif 36541475Smckusick /* 36645751Smckusick * It is only a kernel address space fault iff: 36749531Skarels * 1. (type & T_USER) == 0 and 36845751Smckusick * 2. pcb_onfault not set or 36945751Smckusick * 3. pcb_onfault set but supervisor space data fault 37045751Smckusick * The last can occur during an exec() copyin where the 37145751Smckusick * argument space is lazy-allocated. 37241475Smckusick */ 37345751Smckusick if (type == T_MMUFLT && 37453933Shibler (!p->p_addr->u_pcb.pcb_onfault || KDFAULT(code))) 37545751Smckusick map = kernel_map; 37645751Smckusick else 37748465Skarels map = &vm->vm_map; 37853933Shibler if (WRFAULT(code)) 37945751Smckusick ftype = VM_PROT_READ | VM_PROT_WRITE; 38045751Smckusick else 38145751Smckusick ftype = VM_PROT_READ; 38245751Smckusick va = trunc_page((vm_offset_t)v); 38341475Smckusick #ifdef DEBUG 38445751Smckusick if (map == kernel_map && va == 0) { 38545751Smckusick printf("trap: bad kernel access at %x\n", v); 38641475Smckusick goto dopanic; 38741475Smckusick } 38841475Smckusick #endif 38949317Shibler rv = vm_fault(map, va, ftype, FALSE); 39053933Shibler #ifdef DEBUG 39153933Shibler if (rv && MDB_ISPID(p->p_pid)) 39253933Shibler printf("vm_fault(%x, %x, %x, 0) -> %x\n", 39353933Shibler map, va, ftype, rv); 39453933Shibler #endif 39541475Smckusick /* 39649317Shibler * If this was a stack access we keep track of the maximum 39749317Shibler * accessed stack size. Also, if vm_fault gets a protection 39849317Shibler * failure it is due to accessing the stack region outside 39949317Shibler * the current limit and we need to reflect that as an access 40049317Shibler * error. 40141475Smckusick */ 40248465Skarels if ((caddr_t)va >= vm->vm_maxsaddr && map != kernel_map) { 40349317Shibler if (rv == KERN_SUCCESS) { 40449317Shibler unsigned nss; 40549317Shibler 40649317Shibler nss = clrnd(btoc(USRSTACK-(unsigned)va)); 40749317Shibler if (nss > vm->vm_ssize) 40849317Shibler vm->vm_ssize = nss; 40949317Shibler } else if (rv == KERN_PROTECTION_FAILURE) 41049317Shibler rv = KERN_INVALID_ADDRESS; 41141475Smckusick } 41245751Smckusick if (rv == KERN_SUCCESS) { 41353933Shibler if (type == T_MMUFLT) { 41453933Shibler #if defined(HP380) 41553933Shibler if (mmutype == MMU_68040) 41653933Shibler (void) writeback(&frame, 1); 41753933Shibler #endif 41841475Smckusick return; 41953933Shibler } 42041475Smckusick goto out; 42141475Smckusick } 42245751Smckusick if (type == T_MMUFLT) { 42349125Skarels if (p->p_addr->u_pcb.pcb_onfault) 42445751Smckusick goto copyfault; 42545751Smckusick printf("vm_fault(%x, %x, %x, 0) -> %x\n", 42645751Smckusick map, va, ftype, rv); 42745751Smckusick printf(" type %x, code [mmu,,ssw]: %x\n", 42845751Smckusick type, code); 42945751Smckusick goto dopanic; 43045751Smckusick } 43148465Skarels ucode = v; 43245751Smckusick i = (rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV; 43345751Smckusick break; 43445751Smckusick } 43541475Smckusick } 43648465Skarels trapsignal(p, i, ucode); 43749531Skarels if ((type & T_USER) == 0) 43841475Smckusick return; 43941475Smckusick out: 44048465Skarels while (i = CURSIG(p)) 44142370Skarels psig(i); 44241475Smckusick p->p_pri = p->p_usrpri; 44348465Skarels if (want_resched) { 44441475Smckusick /* 44548465Skarels * Since we are curproc, clock will normally just change 44641475Smckusick * our priority without moving us from one queue to another 44741475Smckusick * (since the running process is not on a queue.) 44841475Smckusick * If that happened after we setrq ourselves but before we 44941475Smckusick * swtch()'ed, we might not be on the queue indicated by 45041475Smckusick * our priority. 45141475Smckusick */ 45250753Skarels s = splclock(); 45341475Smckusick setrq(p); 45448465Skarels p->p_stats->p_ru.ru_nivcsw++; 45541475Smckusick swtch(); 45650753Skarels splx(s); 45748465Skarels while (i = CURSIG(p)) 45842370Skarels psig(i); 45941475Smckusick } 46048465Skarels if (p->p_stats->p_prof.pr_scale) { 46141475Smckusick int ticks; 46248465Skarels struct timeval *tv = &p->p_stime; 46341475Smckusick 46441475Smckusick ticks = ((tv->tv_sec - syst.tv_sec) * 1000 + 46541475Smckusick (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000); 46641475Smckusick if (ticks) { 46741475Smckusick #ifdef PROFTIMER 46841475Smckusick extern int profscale; 46948465Skarels addupc(frame.f_pc, &p->p_stats->p_prof, 47048465Skarels ticks * profscale); 47141475Smckusick #else 47248465Skarels addupc(frame.f_pc, &p->p_stats->p_prof, ticks); 47341475Smckusick #endif 47441475Smckusick } 47541475Smckusick } 47653933Shibler #if defined(HP380) 47753933Shibler /* 47853933Shibler * Deal with user mode writebacks. 47953933Shibler * If any writeback fails, go back and attempt signal delivery. 48053933Shibler * unless we have already been here and attempted the writeback 48153933Shibler * (e.g. bad address with user ignoring SIGSEGV). In that case 48253933Shibler * we just return to the user without sucessfully completing 48353933Shibler * the writebacks. Maybe we should just drop the sucker? 48453933Shibler */ 48553933Shibler if (mmutype == MMU_68040 && frame.f_format == FMT7) { 48653933Shibler if (beenhere) { 48753933Shibler #ifdef DEBUG 48853933Shibler if (mmudebug & MDB_WBFAILED) 48953933Shibler printf("pid %d(%s): writeback aborted, pc=%x, fa=%x\n", 49053933Shibler p->p_pid, p->p_comm, frame.f_pc, v); 49153933Shibler #endif 49253933Shibler ; 49353933Shibler } else if (i = writeback(&frame, 1)) { 49453933Shibler beenhere++; 49553933Shibler ucode = v; 49653933Shibler syst = p->p_stime; 49753933Shibler trapsignal(p, i, ucode); 49853933Shibler goto out; 49953933Shibler } 50053933Shibler } 50153933Shibler #endif 50241475Smckusick curpri = p->p_pri; 50341475Smckusick } 50441475Smckusick 50553933Shibler #if defined(HP380) 50653933Shibler #ifdef DEBUG 50753933Shibler struct writebackstats { 50853933Shibler int calls; 50953933Shibler int cpushes; 51053933Shibler int move16s; 51153933Shibler int wb1s, wb2s, wb3s; 51253933Shibler int wbsize[4]; 51353933Shibler } wbstats; 51453933Shibler 51553933Shibler char *f7sz[] = { "longword", "byte", "word", "line" }; 51653933Shibler char *f7tt[] = { "normal", "MOVE16", "AFC", "ACK" }; 51753933Shibler char *f7tm[] = { "d-push", "u-data", "u-code", "M-data", 51853933Shibler "M-code", "k-data", "k-code", "RES" }; 51953933Shibler char wberrstr[] = 52053933Shibler "WARNING: pid %d(%s) writeback [%s] failed, pc=%x fa=%x wba=%x wbd=%x\n"; 52153933Shibler #endif 52253933Shibler 52353933Shibler writeback(fp, docachepush) 52453933Shibler struct frame *fp; 52553933Shibler int docachepush; 52653933Shibler { 52753933Shibler register struct fmt7 *f = &fp->f_fmt7; 52853933Shibler register struct proc *p = curproc; 52953933Shibler int err = 0; 53053933Shibler u_int fa; 53153933Shibler caddr_t oonfault = p->p_addr->u_pcb.pcb_onfault; 53253933Shibler 53353933Shibler #ifdef DEBUG 53453933Shibler if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) { 53553933Shibler printf(" pid=%d, fa=%x,", p->p_pid, f->f_fa); 53653933Shibler dumpssw(f->f_ssw); 53753933Shibler } 53853933Shibler wbstats.calls++; 53953933Shibler #endif 54053933Shibler /* 54153933Shibler * Deal with special cases first. 54253933Shibler */ 54353933Shibler if ((f->f_ssw & SSW4_TMMASK) == SSW4_TMDCP) { 54453933Shibler /* 54553933Shibler * Dcache push fault. 54653933Shibler * Line-align the address and write out the push data to 54753933Shibler * the indicated physical address. 54853933Shibler */ 54953933Shibler #ifdef DEBUG 55053933Shibler if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) { 55153933Shibler printf(" pushing %s to PA %x, data %x", 55253933Shibler f7sz[(f->f_ssw & SSW4_SZMASK) >> 5], 55353933Shibler f->f_fa, f->f_pd0); 55453933Shibler if ((f->f_ssw & SSW4_SZMASK) == SSW4_SZLN) 55553933Shibler printf("/%x/%x/%x", 55653933Shibler f->f_pd1, f->f_pd2, f->f_pd3); 55753933Shibler printf("\n"); 55853933Shibler } 55953933Shibler if (f->f_wb1s & SSW4_WBSV) 56053933Shibler panic("writeback: cache push with WB1S valid"); 56153933Shibler wbstats.cpushes++; 56253933Shibler #endif 56353933Shibler /* 56453933Shibler * XXX there are security problems if we attempt to do a 56553933Shibler * cache push after a signal handler has been called. 56653933Shibler */ 56753933Shibler if (docachepush) { 56853933Shibler pmap_enter(kernel_pmap, (vm_offset_t)vmmap, 56953933Shibler trunc_page(f->f_fa), VM_PROT_WRITE, TRUE); 57053933Shibler fa = (u_int)&vmmap[(f->f_fa & PGOFSET) & ~0xF]; 57153933Shibler bcopy((caddr_t)&f->f_pd0, (caddr_t)fa, 16); 57253933Shibler DCFL(pmap_extract(kernel_pmap, (vm_offset_t)fa)); 57353933Shibler pmap_remove(kernel_pmap, (vm_offset_t)vmmap, 57453933Shibler (vm_offset_t)&vmmap[NBPG]); 57553933Shibler } else 57653933Shibler printf("WARNING: pid %d(%s) uid %d: CPUSH not done\n", 57753933Shibler p->p_pid, p->p_comm, p->p_ucred->cr_uid); 57853933Shibler } else if ((f->f_ssw & (SSW4_RW|SSW4_TTMASK)) == SSW4_TTM16) { 57953933Shibler /* 58053933Shibler * MOVE16 fault. 58153933Shibler * Line-align the address and write out the push data to 58253933Shibler * the indicated virtual address. 58353933Shibler */ 58453933Shibler #ifdef DEBUG 58553933Shibler if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) 58653933Shibler printf(" MOVE16 to VA %x(%x), data %x/%x/%x/%x\n", 58753933Shibler f->f_fa, f->f_fa & ~0xF, f->f_pd0, f->f_pd1, 58853933Shibler f->f_pd2, f->f_pd3); 58953933Shibler if (f->f_wb1s & SSW4_WBSV) 59053933Shibler panic("writeback: MOVE16 with WB1S valid"); 59153933Shibler wbstats.move16s++; 59253933Shibler #endif 59353933Shibler if (KDFAULT(f->f_wb1s)) 59453933Shibler bcopy((caddr_t)&f->f_pd0, (caddr_t)(f->f_fa & ~0xF), 16); 59553933Shibler else 59653933Shibler err = suline((caddr_t)(f->f_fa & ~0xF), (caddr_t)&f->f_pd0); 59753933Shibler if (err) { 59853933Shibler fa = f->f_fa & ~0xF; 59953933Shibler #ifdef DEBUG 60053933Shibler if (mmudebug & MDB_WBFAILED) 60153933Shibler printf(wberrstr, p->p_pid, p->p_comm, 60253933Shibler "MOVE16", fp->f_pc, f->f_fa, 60353933Shibler f->f_fa & ~0xF, f->f_pd0); 60453933Shibler #endif 60553933Shibler } 60653933Shibler } else if (f->f_wb1s & SSW4_WBSV) { 60753933Shibler /* 60853933Shibler * Writeback #1. 60953933Shibler * Position the "memory-aligned" data and write it out. 61053933Shibler */ 61153933Shibler register u_int wb1d = f->f_wb1d; 61253933Shibler register int off; 61353933Shibler 61453933Shibler #ifdef DEBUG 61553933Shibler if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) 61653933Shibler dumpwb(1, f->f_wb1s, f->f_wb1a, f->f_wb1d); 61753933Shibler wbstats.wb1s++; 61853933Shibler wbstats.wbsize[(f->f_wb2s&SSW4_SZMASK)>>5]++; 61953933Shibler #endif 62053933Shibler off = (f->f_wb1a & 3) * 8; 62153933Shibler switch (f->f_wb1s & SSW4_SZMASK) { 62253933Shibler case SSW4_SZLW: 62353933Shibler if (off) 62453933Shibler wb1d = (wb1d >> (32 - off)) | (wb1d << off); 62553933Shibler if (KDFAULT(f->f_wb1s)) 62653933Shibler *(long *)f->f_wb1a = wb1d; 62753933Shibler else 62853933Shibler err = suword((caddr_t)f->f_wb1a, wb1d); 62953933Shibler break; 63053933Shibler case SSW4_SZB: 63153933Shibler off = 24 - off; 63253933Shibler if (off) 63353933Shibler wb1d >>= off; 63453933Shibler if (KDFAULT(f->f_wb1s)) 63553933Shibler *(char *)f->f_wb1a = wb1d; 63653933Shibler else 63753933Shibler err = subyte((caddr_t)f->f_wb1a, wb1d); 63853933Shibler break; 63953933Shibler case SSW4_SZW: 64053933Shibler off = (off + 16) % 32; 64153933Shibler if (off) 64253933Shibler wb1d = (wb1d >> (32 - off)) | (wb1d << off); 64353933Shibler if (KDFAULT(f->f_wb1s)) 64453933Shibler *(short *)f->f_wb1a = wb1d; 64553933Shibler else 64653933Shibler err = susword((caddr_t)f->f_wb1a, wb1d); 64753933Shibler break; 64853933Shibler } 64953933Shibler if (err) { 65053933Shibler fa = f->f_wb1a; 65153933Shibler #ifdef DEBUG 65253933Shibler if (mmudebug & MDB_WBFAILED) 65353933Shibler printf(wberrstr, p->p_pid, p->p_comm, 65453933Shibler "#1", fp->f_pc, f->f_fa, 65553933Shibler f->f_wb1a, f->f_wb1d); 65653933Shibler #endif 65753933Shibler } 65853933Shibler } 65953933Shibler /* 66053933Shibler * Deal with the "normal" writebacks. 66153933Shibler * 66253933Shibler * XXX writeback2 is known to reflect a LINE size writeback after 66353933Shibler * a MOVE16 was already dealt with above. Ignore it. 66453933Shibler */ 66553933Shibler if (err == 0 && (f->f_wb2s & SSW4_WBSV) && 66653933Shibler (f->f_wb2s & SSW4_SZMASK) != SSW4_SZLN) { 66753933Shibler #ifdef DEBUG 66853933Shibler if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) 66953933Shibler dumpwb(2, f->f_wb2s, f->f_wb2a, f->f_wb2d); 67053933Shibler wbstats.wb2s++; 67153933Shibler wbstats.wbsize[(f->f_wb2s&SSW4_SZMASK)>>5]++; 67253933Shibler #endif 67353933Shibler switch (f->f_wb2s & SSW4_SZMASK) { 67453933Shibler case SSW4_SZLW: 67553933Shibler if (KDFAULT(f->f_wb2s)) 67653933Shibler *(long *)f->f_wb2a = f->f_wb2d; 67753933Shibler else 67853933Shibler err = suword((caddr_t)f->f_wb2a, f->f_wb2d); 67953933Shibler break; 68053933Shibler case SSW4_SZB: 68153933Shibler if (KDFAULT(f->f_wb2s)) 68253933Shibler *(char *)f->f_wb2a = f->f_wb2d; 68353933Shibler else 68453933Shibler err = subyte((caddr_t)f->f_wb2a, f->f_wb2d); 68553933Shibler break; 68653933Shibler case SSW4_SZW: 68753933Shibler if (KDFAULT(f->f_wb2s)) 68853933Shibler *(short *)f->f_wb2a = f->f_wb2d; 68953933Shibler else 69053933Shibler err = susword((caddr_t)f->f_wb2a, f->f_wb2d); 69153933Shibler break; 69253933Shibler } 69353933Shibler if (err) { 69453933Shibler fa = f->f_wb2a; 69553933Shibler #ifdef DEBUG 69653933Shibler if (mmudebug & MDB_WBFAILED) { 69753933Shibler printf(wberrstr, p->p_pid, p->p_comm, 69853933Shibler "#2", fp->f_pc, f->f_fa, 69953933Shibler f->f_wb2a, f->f_wb2d); 70053933Shibler dumpssw(f->f_ssw); 70153933Shibler dumpwb(2, f->f_wb2s, f->f_wb2a, f->f_wb2d); 70253933Shibler } 70353933Shibler #endif 70453933Shibler } 70553933Shibler } 70653933Shibler if (err == 0 && (f->f_wb3s & SSW4_WBSV)) { 70753933Shibler #ifdef DEBUG 70853933Shibler if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) 70953933Shibler dumpwb(3, f->f_wb3s, f->f_wb3a, f->f_wb3d); 71053933Shibler wbstats.wb3s++; 71153933Shibler wbstats.wbsize[(f->f_wb3s&SSW4_SZMASK)>>5]++; 71253933Shibler #endif 71353933Shibler switch (f->f_wb3s & SSW4_SZMASK) { 71453933Shibler case SSW4_SZLW: 71553933Shibler if (KDFAULT(f->f_wb3s)) 71653933Shibler *(long *)f->f_wb3a = f->f_wb3d; 71753933Shibler else 71853933Shibler err = suword((caddr_t)f->f_wb3a, f->f_wb3d); 71953933Shibler break; 72053933Shibler case SSW4_SZB: 72153933Shibler if (KDFAULT(f->f_wb3s)) 72253933Shibler *(char *)f->f_wb3a = f->f_wb3d; 72353933Shibler else 72453933Shibler err = subyte((caddr_t)f->f_wb3a, f->f_wb3d); 72553933Shibler break; 72653933Shibler case SSW4_SZW: 72753933Shibler if (KDFAULT(f->f_wb3s)) 72853933Shibler *(short *)f->f_wb3a = f->f_wb3d; 72953933Shibler else 73053933Shibler err = susword((caddr_t)f->f_wb3a, f->f_wb3d); 73153933Shibler break; 73253933Shibler #ifdef DEBUG 73353933Shibler case SSW4_SZLN: 73453933Shibler panic("writeback: wb3s indicates LINE write"); 73553933Shibler #endif 73653933Shibler } 73753933Shibler if (err) { 73853933Shibler fa = f->f_wb3a; 73953933Shibler #ifdef DEBUG 74053933Shibler if (mmudebug & MDB_WBFAILED) 74153933Shibler printf(wberrstr, p->p_pid, p->p_comm, 74253933Shibler "#3", fp->f_pc, f->f_fa, 74353933Shibler f->f_wb3a, f->f_wb3d); 74453933Shibler #endif 74553933Shibler } 74653933Shibler } 74753933Shibler p->p_addr->u_pcb.pcb_onfault = oonfault; 74853933Shibler /* 74953933Shibler * Determine the cause of the failure if any translating to 75053933Shibler * a signal. If the corresponding VA is valid and RO it is 75153933Shibler * a protection fault (SIGBUS) otherwise consider it an 75253933Shibler * illegal reference (SIGSEGV). 75353933Shibler */ 75453933Shibler if (err) { 75553933Shibler if (vm_map_check_protection(&p->p_vmspace->vm_map, 75653933Shibler trunc_page(fa), round_page(fa), 75753933Shibler VM_PROT_READ) && 75853933Shibler !vm_map_check_protection(&p->p_vmspace->vm_map, 75953933Shibler trunc_page(fa), round_page(fa), 76053933Shibler VM_PROT_WRITE)) 76153933Shibler err = SIGBUS; 76253933Shibler else 76353933Shibler err = SIGSEGV; 76453933Shibler } 76553933Shibler return(err); 76653933Shibler } 76753933Shibler 76853933Shibler #ifdef DEBUG 76953933Shibler dumpssw(ssw) 77053933Shibler register u_short ssw; 77153933Shibler { 77253933Shibler printf(" SSW: %x: ", ssw); 77353933Shibler if (ssw & SSW4_CP) 77453933Shibler printf("CP,"); 77553933Shibler if (ssw & SSW4_CU) 77653933Shibler printf("CU,"); 77753933Shibler if (ssw & SSW4_CT) 77853933Shibler printf("CT,"); 77953933Shibler if (ssw & SSW4_CM) 78053933Shibler printf("CM,"); 78153933Shibler if (ssw & SSW4_MA) 78253933Shibler printf("MA,"); 78353933Shibler if (ssw & SSW4_ATC) 78453933Shibler printf("ATC,"); 78553933Shibler if (ssw & SSW4_LK) 78653933Shibler printf("LK,"); 78753933Shibler if (ssw & SSW4_RW) 78853933Shibler printf("RW,"); 78953933Shibler printf(" SZ=%s, TT=%s, TM=%s\n", 79053933Shibler f7sz[(ssw & SSW4_SZMASK) >> 5], 79153933Shibler f7tt[(ssw & SSW4_TTMASK) >> 3], 79253933Shibler f7tm[ssw & SSW4_TMMASK]); 79353933Shibler } 79453933Shibler 79553933Shibler dumpwb(num, s, a, d) 79653933Shibler int num; 79753933Shibler u_short s; 79853933Shibler u_int a, d; 79953933Shibler { 80053933Shibler register struct proc *p = curproc; 80153933Shibler vm_offset_t pa; 80253933Shibler 80353933Shibler printf(" writeback #%d: VA %x, data %x, SZ=%s, TT=%s, TM=%s\n", 80453933Shibler num, a, d, f7sz[(s & SSW4_SZMASK) >> 5], 80553933Shibler f7tt[(s & SSW4_TTMASK) >> 3], f7tm[s & SSW4_TMMASK]); 80653933Shibler printf(" PA "); 80753933Shibler pa = pmap_extract(&p->p_vmspace->vm_pmap, (vm_offset_t)a); 80853933Shibler if (pa == 0) 80953933Shibler printf("<invalid address>"); 81053933Shibler else 81153933Shibler printf("%x, current value %x", pa, fuword((caddr_t)a)); 81253933Shibler printf("\n"); 81353933Shibler } 81453933Shibler 81553933Shibler #ifdef HPFPLIB 81653933Shibler fppanic(frame) 81753933Shibler struct fppanicframe { 81853933Shibler int fpsaveframe; 81953933Shibler int regs[16]; 82053933Shibler int fpregs[8*3]; 82153933Shibler int fpcregs[3]; 82253933Shibler int hole[5]; 82353933Shibler int oa6; 82453933Shibler short sr; 82553933Shibler int pc; 82653933Shibler short vector; 82753933Shibler } frame; 82853933Shibler { 82953933Shibler printf("FP exception: pid %d(%s): no busy frame, ft=%x pc=%x vec=%x\n", 83053933Shibler curproc->p_pid, curproc->p_comm, 83153933Shibler frame.fpsaveframe, frame.pc, frame.vector); 83253933Shibler panic("bad FP exception"); 83353933Shibler } 83453933Shibler #endif 83553933Shibler #endif 83653933Shibler #endif 83753933Shibler 83841475Smckusick /* 83949531Skarels * Proces a system call. 84041475Smckusick */ 84141475Smckusick syscall(code, frame) 84253029Shibler volatile unsigned code; 84341475Smckusick struct frame frame; 84441475Smckusick { 84541475Smckusick register caddr_t params; 84641475Smckusick register int i; 84741475Smckusick register struct sysent *callp; 84848465Skarels register struct proc *p = curproc; 84950753Skarels int error, opc, numsys, s; 85044018Skarels struct args { 85144018Skarels int i[8]; 85244018Skarels } args; 85344018Skarels int rval[2]; 85441475Smckusick struct timeval syst; 85541475Smckusick struct sysent *systab; 85653933Shibler #if defined(HP380) 85753933Shibler int beenhere = 0; 85853933Shibler #endif 85941475Smckusick #ifdef HPUXCOMPAT 86041475Smckusick extern struct sysent hpuxsysent[]; 86141475Smckusick extern int hpuxnsysent, notimp(); 86241475Smckusick #endif 86341475Smckusick 86441475Smckusick cnt.v_syscall++; 86548465Skarels syst = p->p_stime; 86641475Smckusick if (!USERMODE(frame.f_sr)) 86741475Smckusick panic("syscall"); 86852380Smckusick p->p_md.md_regs = frame.f_regs; 86941475Smckusick opc = frame.f_pc - 2; 87041475Smckusick systab = sysent; 87141475Smckusick numsys = nsysent; 87241475Smckusick #ifdef HPUXCOMPAT 87342370Skarels if (p->p_flag & SHPUX) { 87441475Smckusick systab = hpuxsysent; 87541475Smckusick numsys = hpuxnsysent; 87641475Smckusick } 87741475Smckusick #endif 87849531Skarels params = (caddr_t)frame.f_regs[SP] + sizeof(int); 87942370Skarels if (code == 0) { /* indir */ 88042370Skarels code = fuword(params); 88149531Skarels params += sizeof(int); 88242370Skarels } 88342370Skarels if (code >= numsys) 88442370Skarels callp = &systab[0]; /* indir (illegal) */ 88542370Skarels else 88642370Skarels callp = &systab[code]; 88741475Smckusick if ((i = callp->sy_narg * sizeof (int)) && 88844018Skarels (error = copyin(params, (caddr_t)&args, (u_int)i))) { 88941475Smckusick #ifdef HPUXCOMPAT 89041475Smckusick if (p->p_flag & SHPUX) 89142370Skarels error = bsdtohpuxerrno(error); 89241475Smckusick #endif 89349362Skarels frame.f_regs[D0] = error; 89441475Smckusick frame.f_sr |= PSL_C; /* carry bit */ 89541475Smckusick #ifdef KTRACE 89643641Skarels if (KTRPOINT(p, KTR_SYSCALL)) 89744018Skarels ktrsyscall(p->p_tracep, code, callp->sy_narg, args.i); 89841475Smckusick #endif 89941475Smckusick goto done; 90041475Smckusick } 90141475Smckusick #ifdef KTRACE 90243641Skarels if (KTRPOINT(p, KTR_SYSCALL)) 90344018Skarels ktrsyscall(p->p_tracep, code, callp->sy_narg, args.i); 90441475Smckusick #endif 90543641Skarels rval[0] = 0; 90643641Skarels rval[1] = frame.f_regs[D1]; 90741475Smckusick #ifdef HPUXCOMPAT 90842370Skarels /* debug kludge */ 90942370Skarels if (callp->sy_call == notimp) 91048465Skarels error = notimp(p, args.i, rval, code, callp->sy_narg); 91142370Skarels else 91241475Smckusick #endif 91348465Skarels error = (*callp->sy_call)(p, &args, rval); 91442370Skarels if (error == ERESTART) 91542370Skarels frame.f_pc = opc; 91642370Skarels else if (error != EJUSTRETURN) { 91742370Skarels if (error) { 91841475Smckusick #ifdef HPUXCOMPAT 91942370Skarels if (p->p_flag & SHPUX) 92042370Skarels error = bsdtohpuxerrno(error); 92141475Smckusick #endif 92249362Skarels frame.f_regs[D0] = error; 92342370Skarels frame.f_sr |= PSL_C; /* carry bit */ 92441475Smckusick } else { 92543641Skarels frame.f_regs[D0] = rval[0]; 92643641Skarels frame.f_regs[D1] = rval[1]; 92741475Smckusick frame.f_sr &= ~PSL_C; 92841475Smckusick } 92942370Skarels } 93042370Skarels /* else if (error == EJUSTRETURN) */ 93141475Smckusick /* nothing to do */ 93242370Skarels 93341475Smckusick done: 93441475Smckusick /* 93542370Skarels * Reinitialize proc pointer `p' as it may be different 93642370Skarels * if this is a child returning from fork syscall. 93742370Skarels */ 93848465Skarels p = curproc; 93949317Shibler while (i = CURSIG(p)) 94049317Shibler psig(i); 94141475Smckusick p->p_pri = p->p_usrpri; 94248465Skarels if (want_resched) { 94341475Smckusick /* 94448465Skarels * Since we are curproc, clock will normally just change 94541475Smckusick * our priority without moving us from one queue to another 94641475Smckusick * (since the running process is not on a queue.) 94741475Smckusick * If that happened after we setrq ourselves but before we 94841475Smckusick * swtch()'ed, we might not be on the queue indicated by 94941475Smckusick * our priority. 95041475Smckusick */ 95150753Skarels s = splclock(); 95241475Smckusick setrq(p); 95348465Skarels p->p_stats->p_ru.ru_nivcsw++; 95441475Smckusick swtch(); 95550753Skarels splx(s); 95649317Shibler while (i = CURSIG(p)) 95749317Shibler psig(i); 95841475Smckusick } 95948465Skarels if (p->p_stats->p_prof.pr_scale) { 96041475Smckusick int ticks; 96148465Skarels struct timeval *tv = &p->p_stime; 96241475Smckusick 96341475Smckusick ticks = ((tv->tv_sec - syst.tv_sec) * 1000 + 96441475Smckusick (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000); 96541475Smckusick if (ticks) { 96641475Smckusick #ifdef PROFTIMER 96741475Smckusick extern int profscale; 96848465Skarels addupc(frame.f_pc, &p->p_stats->p_prof, 96948465Skarels ticks * profscale); 97041475Smckusick #else 97148465Skarels addupc(frame.f_pc, &p->p_stats->p_prof, ticks); 97241475Smckusick #endif 97341475Smckusick } 97441475Smckusick } 97553933Shibler #if defined(HP380) 97653933Shibler /* 97753933Shibler * Deal with writebacks when returning from sigreturn. 97853933Shibler * They may generate another signal to be processed. 97953933Shibler * Again, we don't attempt the writeback if we have already 98053933Shibler * tried and failed (see comment in trap). 98153933Shibler */ 98253933Shibler if (mmutype == MMU_68040 && frame.f_format == FMT7) { 98353933Shibler if (beenhere) { 98453933Shibler #ifdef DEBUG 98553933Shibler if (mmudebug & MDB_WBFAILED) 98653933Shibler printf("pid %d(%s): writeback aborted in sigreturn, pc=%x\n", 98753933Shibler p->p_pid, p->p_comm, frame.f_pc); 98853933Shibler #endif 98953933Shibler ; 99053933Shibler } else if (i = writeback(&frame, 0)) { 99153933Shibler beenhere++; 99253933Shibler syst = p->p_stime; 99353933Shibler trapsignal(p, i, 0); 99453933Shibler goto done; 99553933Shibler } 99653933Shibler } 99753933Shibler #endif 99841475Smckusick curpri = p->p_pri; 99941475Smckusick #ifdef KTRACE 100043641Skarels if (KTRPOINT(p, KTR_SYSRET)) 100143641Skarels ktrsysret(p->p_tracep, code, error, rval[0]); 100241475Smckusick #endif 100341475Smckusick } 1004