|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1988 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 "param.h" ! 10: #include "systm.h" ! 11: #include "user.h" ! 12: #include "proc.h" ! 13: #include "seg.h" ! 14: #include "acct.h" ! 15: #include "kernel.h" ! 16: ! 17: #include "psl.h" ! 18: #include "reg.h" ! 19: #include "pte.h" ! 20: #include "mtpr.h" ! 21: #ifdef KTRACE ! 22: #include "ktrace.h" ! 23: #endif ! 24: ! 25: #include "../tahoe/trap.h" ! 26: ! 27: #define USER 040 /* user-mode flag added to type */ ! 28: ! 29: struct sysent sysent[]; ! 30: int nsysent; ! 31: ! 32: char *trap_type[] = { ! 33: "Reserved addressing mode", /* T_RESADFLT */ ! 34: "Privileged instruction", /* T_PRIVINFLT */ ! 35: "Reserved operand", /* T_RESOPFLT */ ! 36: "Breakpoint", /* T_BPTFLT */ ! 37: 0, ! 38: "Kernel call", /* T_SYSCALL */ ! 39: "Arithmetic trap", /* T_ARITHTRAP */ ! 40: "System forced exception", /* T_ASTFLT */ ! 41: "Segmentation fault", /* T_SEGFLT */ ! 42: "Protection fault", /* T_PROTFLT */ ! 43: "Trace trap", /* T_TRCTRAP */ ! 44: 0, ! 45: "Page fault", /* T_PAGEFLT */ ! 46: "Page table fault", /* T_TABLEFLT */ ! 47: "Alignment fault", /* T_ALIGNFLT */ ! 48: "Kernel stack not valid", /* T_KSPNOTVAL */ ! 49: "Bus error", /* T_BUSERR */ ! 50: "Kernel debugger request", /* T_KDBTRAP */ ! 51: }; ! 52: int TRAP_TYPES = sizeof (trap_type) / sizeof (trap_type[0]); ! 53: ! 54: /* ! 55: * Called from the trap handler when a processor trap occurs. ! 56: */ ! 57: /*ARGSUSED*/ ! 58: trap(sp, type, hfs, accmst, acclst, dbl, code, pc, psl) ! 59: unsigned type, code; /* kdb assumes these are *not* registers */ ! 60: { ! 61: int r0, r1; /* must reserve space */ ! 62: register int *locr0 = ((int *)&psl)-PS; ! 63: register int i; ! 64: unsigned ucode = code; ! 65: register struct proc *p; ! 66: struct timeval syst; ! 67: ! 68: #ifdef lint ! 69: r0 = 0; r0 = r0; r1 = 0; r1 = r1; ! 70: #endif ! 71: syst = u.u_ru.ru_stime; ! 72: if (USERMODE(locr0[PS])) { ! 73: type |= USER; ! 74: u.u_ar0 = locr0; ! 75: } ! 76: switch (type) { ! 77: ! 78: default: ! 79: #ifdef KADB ! 80: if (kdb_trap(&psl)) ! 81: return; ! 82: #endif ! 83: printf("trap type %d, code = %x, pc = %x\n", type, code, pc); ! 84: type &= ~USER; ! 85: if (type < TRAP_TYPES && trap_type[type]) ! 86: panic(trap_type[type]); ! 87: else ! 88: panic("trap"); ! 89: /*NOTREACHED*/ ! 90: ! 91: case T_PROTFLT + USER: /* protection fault */ ! 92: i = SIGBUS; ! 93: break; ! 94: ! 95: case T_PRIVINFLT + USER: /* privileged instruction fault */ ! 96: case T_RESADFLT + USER: /* reserved addressing fault */ ! 97: case T_RESOPFLT + USER: /* resereved operand fault */ ! 98: case T_ALIGNFLT + USER: /* unaligned data fault */ ! 99: ucode = type &~ USER; ! 100: i = SIGILL; ! 101: break; ! 102: ! 103: case T_ASTFLT + USER: /* Allow process switch */ ! 104: case T_ASTFLT: ! 105: astoff(); ! 106: if ((u.u_procp->p_flag & SOWEUPC) && u.u_prof.pr_scale) { ! 107: addupc(pc, &u.u_prof, 1); ! 108: u.u_procp->p_flag &= ~SOWEUPC; ! 109: } ! 110: goto out; ! 111: ! 112: case T_ARITHTRAP + USER: ! 113: i = SIGFPE; ! 114: break; ! 115: ! 116: /* ! 117: * If the user SP is above the stack segment, ! 118: * grow the stack automatically. ! 119: */ ! 120: case T_SEGFLT + USER: ! 121: if (grow((unsigned)locr0[SP]) || grow(code)) ! 122: goto out; ! 123: i = SIGSEGV; ! 124: break; ! 125: ! 126: case T_TABLEFLT: /* allow page table faults in kernel */ ! 127: case T_TABLEFLT + USER: /* page table fault */ ! 128: panic("ptable fault"); ! 129: ! 130: case T_PAGEFLT: /* allow page faults in kernel mode */ ! 131: case T_PAGEFLT + USER: /* page fault */ ! 132: pagein(code, 0); ! 133: if (type == T_PAGEFLT) ! 134: return; ! 135: goto out; ! 136: ! 137: case T_BPTFLT + USER: /* bpt instruction fault */ ! 138: case T_TRCTRAP + USER: /* trace trap */ ! 139: locr0[PS] &= ~PSL_T; ! 140: i = SIGTRAP; ! 141: break; ! 142: ! 143: #ifdef notdef ! 144: /* THIS CODE IS BOGUS- delete? (KSP not valid is unrecoverable) ! 145: And what does KSPNOTVAL in user-mode mean? */ ! 146: /* ! 147: * For T_KSPNOTVAL and T_BUSERR, can not allow spl to ! 148: * drop to 0 as clock could go off and we would end up ! 149: * doing an rei to the interrupt stack at ipl 0 (a ! 150: * reserved operand fault). Instead, we allow psignal ! 151: * to post an ast, then return to user mode where we ! 152: * will reenter the kernel on the kernel's stack and ! 153: * can then service the signal. ! 154: */ ! 155: case T_KSPNOTVAL: ! 156: if (noproc) ! 157: panic("ksp not valid"); ! 158: /* fall thru... */ ! 159: case T_KSPNOTVAL + USER: ! 160: printf("pid %d: ksp not valid\n", u.u_procp->p_pid); ! 161: panic("ksp not valid - 2"); ! 162: /* must insure valid kernel stack pointer? */ ! 163: psignal(u.u_procp, SIGKILL); ! 164: return; ! 165: #endif ! 166: ! 167: case T_BUSERR + USER: ! 168: i = SIGBUS; ! 169: break; ! 170: } ! 171: trapsignal(i, ucode); ! 172: out: ! 173: p = u.u_procp; ! 174: if (i = CURSIG(p)) ! 175: psig(i); ! 176: p->p_pri = p->p_usrpri; ! 177: if (runrun) { ! 178: /* ! 179: * Since we are u.u_procp, clock will normally just change ! 180: * our priority without moving us from one queue to another ! 181: * (since the running process is not on a queue.) ! 182: * If that happened after we setrq ourselves but before we ! 183: * swtch()'ed, we might not be on the queue indicated by ! 184: * our priority. ! 185: */ ! 186: (void) splclock(); ! 187: setrq(p); ! 188: u.u_ru.ru_nivcsw++; ! 189: swtch(); ! 190: if (i = CURSIG(p)) ! 191: psig(i); ! 192: } ! 193: if (u.u_prof.pr_scale) { ! 194: int ticks; ! 195: struct timeval *tv = &u.u_ru.ru_stime; ! 196: ! 197: ticks = ((tv->tv_sec - syst.tv_sec) * 1000 + ! 198: (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000); ! 199: if (ticks) ! 200: addupc(locr0[PC], &u.u_prof, ticks); ! 201: } ! 202: curpri = p->p_pri; ! 203: } ! 204: ! 205: /* ! 206: * Called from locore when a system call occurs ! 207: */ ! 208: /*ARGSUSED*/ ! 209: syscall(sp, type, hfs, accmst, acclst, dbl, code, pc, psl) ! 210: unsigned code; ! 211: { ! 212: int r0, r1; /* must reserve space */ ! 213: register int *locr0 = ((int *)&psl)-PS; ! 214: register caddr_t params; ! 215: register int i; ! 216: register struct sysent *callp; ! 217: register struct proc *p = u.u_procp; ! 218: struct timeval syst; ! 219: int error, opc; ! 220: struct args { ! 221: int i[8]; ! 222: } args; ! 223: int rval[2]; ! 224: ! 225: #ifdef lint ! 226: r0 = 0; r0 = r0; r1 = 0; r1 = r1; ! 227: #endif ! 228: syst = u.u_ru.ru_stime; ! 229: if (!USERMODE(locr0[PS])) ! 230: panic("syscall"); ! 231: u.u_ar0 = locr0; ! 232: params = (caddr_t)locr0[FP] + NBPW; ! 233: /* BEGIN GROT */ ! 234: /* ! 235: * Try to reconstruct pc, assuming code ! 236: * is an immediate constant ! 237: */ ! 238: opc = pc - 2; /* short literal */ ! 239: if (code > 0x3f) { ! 240: opc--; /* byte immediate */ ! 241: if (code > 0x7f) { ! 242: opc--; /* word immediate */ ! 243: if (code > 0x7fff) ! 244: opc -= 2; /* long immediate */ ! 245: } ! 246: } ! 247: /* END GROT */ ! 248: if (code == 0) { /* indir */ ! 249: code = fuword(params); ! 250: params += NBPW; ! 251: } ! 252: if (code >= nsysent) ! 253: callp = &sysent[0]; /* indir (illegal) */ ! 254: else ! 255: callp = &sysent[code]; ! 256: if ((i = callp->sy_narg * sizeof (int)) && ! 257: (error = copyin(params, (caddr_t)&args, (u_int)i)) != 0) { ! 258: locr0[R0] = error; ! 259: locr0[PS] |= PSL_C; /* carry bit */ ! 260: #ifdef KTRACE ! 261: if (KTRPOINT(p, KTR_SYSCALL)) ! 262: ktrsyscall(p->p_tracep, code, callp->sy_narg, args.i); ! 263: #endif ! 264: goto done; ! 265: } ! 266: #ifdef KTRACE ! 267: if (KTRPOINT(p, KTR_SYSCALL)) ! 268: ktrsyscall(p->p_tracep, code, callp->sy_narg, args.i); ! 269: #endif ! 270: rval[0] = 0; ! 271: rval[1] = locr0[R1]; ! 272: error = (*callp->sy_call)(u.u_procp, &args, rval); ! 273: if (error == ERESTART) ! 274: pc = opc; ! 275: else if (error != EJUSTRETURN) { ! 276: if (error) { ! 277: locr0[R0] = error; ! 278: locr0[PS] |= PSL_C; /* carry bit */ ! 279: } else { ! 280: locr0[PS] &= ~PSL_C; /* clear carry bit */ ! 281: locr0[R0] = rval[0]; ! 282: locr0[R1] = rval[1]; ! 283: } ! 284: } ! 285: /* else if (error == EJUSTRETURN) */ ! 286: /* nothing to do */ ! 287: done: ! 288: /* ! 289: * Reinitialize proc pointer `p' as it may be different ! 290: * if this is a child returning from fork syscall. ! 291: */ ! 292: p = u.u_procp; ! 293: if (i = CURSIG(p)) ! 294: psig(i); ! 295: p->p_pri = p->p_usrpri; ! 296: if (runrun) { ! 297: /* ! 298: * Since we are u.u_procp, clock will normally just change ! 299: * our priority without moving us from one queue to another ! 300: * (since the running process is not on a queue.) ! 301: * If that happened after we setrq ourselves but before we ! 302: * swtch()'ed, we might not be on the queue indicated by ! 303: * our priority. ! 304: */ ! 305: (void) splclock(); ! 306: setrq(p); ! 307: u.u_ru.ru_nivcsw++; ! 308: swtch(); ! 309: if (i = CURSIG(p)) ! 310: psig(i); ! 311: } ! 312: if (u.u_prof.pr_scale) { ! 313: int ticks; ! 314: struct timeval *tv = &u.u_ru.ru_stime; ! 315: ! 316: ticks = ((tv->tv_sec - syst.tv_sec) * 1000 + ! 317: (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000); ! 318: if (ticks) ! 319: addupc(locr0[PC], &u.u_prof, ticks); ! 320: } ! 321: curpri = p->p_pri; ! 322: #ifdef KTRACE ! 323: if (KTRPOINT(p, KTR_SYSRET)) ! 324: ktrsysret(p->p_tracep, code, error, rval[0]); ! 325: #endif ! 326: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.