|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1982, 1986, 1990 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: * ! 6: * @(#)trap.c 7.10 (Berkeley) 6/25/90 ! 7: */ ! 8: ! 9: #include "psl.h" ! 10: #include "reg.h" ! 11: #include "pte.h" ! 12: ! 13: #include "param.h" ! 14: #include "systm.h" ! 15: #include "user.h" ! 16: #include "assym.s" ! 17: #include "proc.h" ! 18: #include "seg.h" ! 19: #include "trap.h" ! 20: #include "acct.h" ! 21: #include "kernel.h" ! 22: #ifdef KTRACE ! 23: #include "ktrace.h" ! 24: #endif ! 25: ! 26: #include "mtpr.h" ! 27: ! 28: #define USER 040 /* user-mode flag added to type */ ! 29: ! 30: struct sysent sysent[]; ! 31: int nsysent; ! 32: ! 33: char *trap_type[] = { ! 34: "Reserved addressing mode", ! 35: "Privileged instruction", ! 36: "Reserved operand", ! 37: "Breakpoint", ! 38: "Xfc trap", ! 39: "Syscall trap", ! 40: "Arithmetic fault", ! 41: "Ast trap", ! 42: "Segmentation fault", ! 43: "Protection fault", ! 44: "Trace trap", ! 45: "Compatibility mode trap", ! 46: "Page fault", ! 47: "Page table fault", ! 48: "Kernel debugger trap", ! 49: }; ! 50: int TRAP_TYPES = (sizeof trap_type / sizeof trap_type[0]); ! 51: ! 52: /* ! 53: * Called from the trap handler when a processor trap occurs. ! 54: */ ! 55: /*ARGSUSED*/ ! 56: trap(sp, type, code, pc, psl) ! 57: int sp, type; ! 58: unsigned code; ! 59: int pc, psl; ! 60: { ! 61: register int *locr0 = ((int *)&psl)-PS; ! 62: register int i; ! 63: unsigned ucode = code; ! 64: register struct proc *p; ! 65: struct timeval syst; ! 66: ! 67: syst = u.u_ru.ru_stime; ! 68: if (USERMODE(locr0[PS])) { ! 69: type |= USER; ! 70: u.u_ar0 = locr0; ! 71: } ! 72: switch (type) { ! 73: ! 74: default: ! 75: #ifdef KADB ! 76: if (kdb_trap(&psl)) ! 77: return; ! 78: #endif ! 79: printf("trap type %d, code = %x, pc = %x\n", type, code, pc); ! 80: type &= ~USER; ! 81: if ((unsigned)type < TRAP_TYPES) ! 82: panic(trap_type[type]); ! 83: panic("trap"); ! 84: ! 85: case T_PROTFLT+USER: /* protection fault */ ! 86: i = SIGBUS; ! 87: break; ! 88: ! 89: case T_PRIVINFLT+USER: /* privileged instruction fault */ ! 90: case T_RESADFLT+USER: /* reserved addressing fault */ ! 91: case T_RESOPFLT+USER: /* reserved operand fault */ ! 92: ucode = type &~ USER; ! 93: i = SIGILL; ! 94: break; ! 95: ! 96: case T_ASTFLT+USER: ! 97: astoff(); ! 98: if ((u.u_procp->p_flag & SOWEUPC) && u.u_prof.pr_scale) { ! 99: addupc(pc, &u.u_prof, 1); ! 100: u.u_procp->p_flag &= ~SOWEUPC; ! 101: } ! 102: goto out; ! 103: ! 104: case T_ARITHTRAP+USER: ! 105: i = SIGFPE; ! 106: break; ! 107: ! 108: /* ! 109: * If the user SP is above the stack segment, ! 110: * grow the stack automatically. ! 111: */ ! 112: case T_SEGFLT+USER: ! 113: if (grow((unsigned)locr0[SP]) || grow(code)) ! 114: goto out; ! 115: i = SIGSEGV; ! 116: break; ! 117: ! 118: case T_TABLEFLT: /* allow page table faults in kernel mode */ ! 119: case T_TABLEFLT+USER: /* page table fault */ ! 120: panic("ptable fault"); ! 121: ! 122: case T_PAGEFLT: /* allow page faults in kernel mode */ ! 123: case T_PAGEFLT+USER: /* page fault */ ! 124: pagein(code, 0); ! 125: if (type == T_PAGEFLT) ! 126: return; ! 127: goto out; ! 128: ! 129: case T_BPTFLT+USER: /* bpt instruction fault */ ! 130: case T_TRCTRAP+USER: /* trace trap */ ! 131: locr0[PS] &= ~PSL_T; ! 132: i = SIGTRAP; ! 133: break; ! 134: ! 135: case T_XFCFLT+USER: /* xfc instruction fault */ ! 136: i = SIGEMT; ! 137: break; ! 138: ! 139: case T_COMPATFLT+USER: /* compatibility mode fault */ ! 140: u.u_acflag |= ACOMPAT; ! 141: i = SIGILL; ! 142: break; ! 143: } ! 144: trapsignal(i, ucode); ! 145: out: ! 146: p = u.u_procp; ! 147: if (i = CURSIG(p)) ! 148: psig(i); ! 149: p->p_pri = p->p_usrpri; ! 150: if (runrun) { ! 151: /* ! 152: * Since we are u.u_procp, clock will normally just change ! 153: * our priority without moving us from one queue to another ! 154: * (since the running process is not on a queue.) ! 155: * If that happened after we setrq ourselves but before we ! 156: * swtch()'ed, we might not be on the queue indicated by ! 157: * our priority. ! 158: */ ! 159: (void) splclock(); ! 160: setrq(p); ! 161: u.u_ru.ru_nivcsw++; ! 162: swtch(); ! 163: if (i = CURSIG(p)) ! 164: psig(i); ! 165: } ! 166: if (u.u_prof.pr_scale) { ! 167: int ticks; ! 168: struct timeval *tv = &u.u_ru.ru_stime; ! 169: ! 170: ticks = ((tv->tv_sec - syst.tv_sec) * 1000 + ! 171: (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000); ! 172: if (ticks) ! 173: addupc(locr0[PC], &u.u_prof, ticks); ! 174: } ! 175: curpri = p->p_pri; ! 176: } ! 177: ! 178: /* ! 179: * Called from the trap handler when a system call occurs ! 180: */ ! 181: /*ARGSUSED*/ ! 182: syscall(sp, type, code, pc, psl) ! 183: unsigned code; ! 184: { ! 185: register int *locr0 = ((int *)&psl)-PS; ! 186: register caddr_t params; /* known to be r10 below */ ! 187: register int i; /* known to be r9 below */ ! 188: register struct sysent *callp; ! 189: register struct proc *p = u.u_procp; ! 190: int error, opc; ! 191: struct args { ! 192: int i[8]; ! 193: } args; ! 194: int rval[2]; ! 195: struct timeval syst; ! 196: ! 197: syst = u.u_ru.ru_stime; ! 198: if (!USERMODE(locr0[PS])) ! 199: panic("syscall"); ! 200: u.u_ar0 = locr0; ! 201: params = (caddr_t)locr0[AP] + NBPW; ! 202: opc = pc - 2; ! 203: if (code > 63) ! 204: opc -= 2; ! 205: if (code == 0) { /* indir */ ! 206: code = fuword(params); ! 207: params += NBPW; ! 208: } ! 209: if (code >= nsysent) ! 210: callp = &sysent[0]; /* indir (illegal) */ ! 211: else ! 212: callp = &sysent[code]; ! 213: if ((i = callp->sy_narg * sizeof (int)) && ! 214: (error = copyin(params, (caddr_t)&args, (u_int)i)) != 0) { ! 215: locr0[R0] = error; ! 216: locr0[PS] |= PSL_C; /* carry bit */ ! 217: #ifdef KTRACE ! 218: if (KTRPOINT(p, KTR_SYSCALL)) ! 219: ktrsyscall(p->p_tracep, code, callp->sy_narg, args.i); ! 220: #endif ! 221: goto done; ! 222: } ! 223: #ifdef KTRACE ! 224: if (KTRPOINT(p, KTR_SYSCALL)) ! 225: ktrsyscall(p->p_tracep, code, callp->sy_narg, args.i); ! 226: #endif ! 227: rval[0] = 0; ! 228: rval[1] = locr0[R1]; ! 229: error = (*callp->sy_call)(u.u_procp, &args, rval); ! 230: if (error == ERESTART) ! 231: pc = opc; ! 232: else if (error != EJUSTRETURN) { ! 233: if (error) { ! 234: locr0[R0] = error; ! 235: locr0[PS] |= PSL_C; /* carry bit */ ! 236: } else { ! 237: locr0[R0] = rval[0]; ! 238: locr0[R1] = rval[1]; ! 239: locr0[PS] &= ~PSL_C; ! 240: } ! 241: } ! 242: /* else if (error == EJUSTRETURN) */ ! 243: /* nothing to do */ ! 244: done: ! 245: /* ! 246: * Reinitialize proc pointer `p' as it may be different ! 247: * if this is a child returning from fork syscall. ! 248: */ ! 249: p = u.u_procp; ! 250: if (i = CURSIG(p)) ! 251: psig(i); ! 252: p->p_pri = p->p_usrpri; ! 253: if (runrun) { ! 254: /* ! 255: * Since we are u.u_procp, clock will normally just change ! 256: * our priority without moving us from one queue to another ! 257: * (since the running process is not on a queue.) ! 258: * If that happened after we setrq ourselves but before we ! 259: * swtch()'ed, we might not be on the queue indicated by ! 260: * our priority. ! 261: */ ! 262: (void) splclock(); ! 263: setrq(p); ! 264: u.u_ru.ru_nivcsw++; ! 265: swtch(); ! 266: if (i = CURSIG(p)) ! 267: psig(i); ! 268: } ! 269: if (u.u_prof.pr_scale) { ! 270: int ticks; ! 271: struct timeval *tv = &u.u_ru.ru_stime; ! 272: ! 273: ticks = ((tv->tv_sec - syst.tv_sec) * 1000 + ! 274: (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000); ! 275: if (ticks) ! 276: addupc(locr0[PC], &u.u_prof, ticks); ! 277: } ! 278: curpri = p->p_pri; ! 279: #ifdef KTRACE ! 280: if (KTRPOINT(p, KTR_SYSRET)) ! 281: ktrsysret(p->p_tracep, code, error, rval[0]); ! 282: #endif ! 283: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.