|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1982, 1986 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.3 (Berkeley) 5/19/88 ! 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 "dir.h" ! 16: #include "user.h" ! 17: #include "assym.s" ! 18: #include "proc.h" ! 19: #include "seg.h" ! 20: #include "trap.h" ! 21: #include "acct.h" ! 22: #include "kernel.h" ! 23: #ifdef SYSCALLTRACE ! 24: #include "../sys/syscalls.c" ! 25: #endif ! 26: ! 27: #include "mtpr.h" ! 28: ! 29: #define USER 040 /* user-mode flag added to type */ ! 30: ! 31: struct sysent sysent[]; ! 32: int nsysent; ! 33: ! 34: char *trap_type[] = { ! 35: "Reserved addressing mode", ! 36: "Privileged instruction", ! 37: "Reserved operand", ! 38: "Breakpoint", ! 39: "Xfc trap", ! 40: "Syscall trap", ! 41: "Arithmetic fault", ! 42: "Ast trap", ! 43: "Segmentation fault", ! 44: "Protection fault", ! 45: "Trace trap", ! 46: "Compatibility mode trap", ! 47: "Page fault", ! 48: "Page table fault", ! 49: "Kernel debugger trap", ! 50: }; ! 51: int TRAP_TYPES = (sizeof trap_type / sizeof trap_type[0]); ! 52: ! 53: /* ! 54: * Called from the trap handler when a processor trap occurs. ! 55: */ ! 56: /*ARGSUSED*/ ! 57: trap(sp, type, code, pc, psl) ! 58: int sp, type; ! 59: unsigned code; ! 60: int pc, psl; ! 61: { ! 62: register int *locr0 = ((int *)&psl)-PS; ! 63: register int i; ! 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: /* resereved operand fault */ ! 92: u.u_code = 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: u.u_code = code; ! 106: i = SIGFPE; ! 107: break; ! 108: ! 109: /* ! 110: * If the user SP is above the stack segment, ! 111: * grow the stack automatically. ! 112: */ ! 113: case T_SEGFLT+USER: ! 114: if (grow((unsigned)locr0[SP]) || grow(code)) ! 115: goto out; ! 116: i = SIGSEGV; ! 117: break; ! 118: ! 119: case T_TABLEFLT: /* allow page table faults in kernel mode */ ! 120: case T_TABLEFLT+USER: /* page table fault */ ! 121: panic("ptable fault"); ! 122: ! 123: case T_PAGEFLT: /* allow page faults in kernel mode */ ! 124: case T_PAGEFLT+USER: /* page fault */ ! 125: i = u.u_error; ! 126: pagein(code, 0); ! 127: u.u_error = i; ! 128: if (type == T_PAGEFLT) ! 129: return; ! 130: goto out; ! 131: ! 132: case T_BPTFLT+USER: /* bpt instruction fault */ ! 133: case T_TRCTRAP+USER: /* trace trap */ ! 134: locr0[PS] &= ~PSL_T; ! 135: i = SIGTRAP; ! 136: break; ! 137: ! 138: case T_XFCFLT+USER: /* xfc instruction fault */ ! 139: i = SIGEMT; ! 140: break; ! 141: ! 142: case T_COMPATFLT+USER: /* compatibility mode fault */ ! 143: u.u_acflag |= ACOMPAT; ! 144: u.u_code = code; ! 145: i = SIGILL; ! 146: break; ! 147: } ! 148: psignal(u.u_procp, i); ! 149: out: ! 150: p = u.u_procp; ! 151: if (p->p_cursig || ISSIG(p)) ! 152: psig(); ! 153: p->p_pri = p->p_usrpri; ! 154: if (runrun) { ! 155: /* ! 156: * Since we are u.u_procp, clock will normally just change ! 157: * our priority without moving us from one queue to another ! 158: * (since the running process is not on a queue.) ! 159: * If that happened after we setrq ourselves but before we ! 160: * swtch()'ed, we might not be on the queue indicated by ! 161: * our priority. ! 162: */ ! 163: (void) splclock(); ! 164: setrq(p); ! 165: u.u_ru.ru_nivcsw++; ! 166: swtch(); ! 167: } ! 168: if (u.u_prof.pr_scale) { ! 169: int ticks; ! 170: struct timeval *tv = &u.u_ru.ru_stime; ! 171: ! 172: ticks = ((tv->tv_sec - syst.tv_sec) * 1000 + ! 173: (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000); ! 174: if (ticks) ! 175: addupc(locr0[PC], &u.u_prof, ticks); ! 176: } ! 177: curpri = p->p_pri; ! 178: } ! 179: ! 180: #ifdef SYSCALLTRACE ! 181: int syscalltrace = 0; ! 182: #endif ! 183: /* ! 184: * Called from the trap handler when a system call occurs ! 185: */ ! 186: /*ARGSUSED*/ ! 187: syscall(sp, type, code, pc, psl) ! 188: unsigned code; ! 189: { ! 190: register int *locr0 = ((int *)&psl)-PS; ! 191: register caddr_t params; /* known to be r10 below */ ! 192: register int i; /* known to be r9 below */ ! 193: register struct sysent *callp; ! 194: register struct proc *p; ! 195: int opc; ! 196: struct timeval syst; ! 197: ! 198: syst = u.u_ru.ru_stime; ! 199: if (!USERMODE(locr0[PS])) ! 200: panic("syscall"); ! 201: u.u_ar0 = locr0; ! 202: if (code == 139) { /* XXX 4.2 COMPATIBILITY */ ! 203: osigcleanup(); /* XXX 4.2 COMPATIBILITY */ ! 204: goto done; /* XXX 4.2 COMPATIBILITY */ ! 205: } /* XXX 4.2 COMPATIBILITY */ ! 206: params = (caddr_t)locr0[AP] + NBPW; ! 207: u.u_error = 0; ! 208: opc = pc - 2; ! 209: if (code > 63) ! 210: opc -= 2; ! 211: if (code >= nsysent) ! 212: callp = &sysent[0]; /* indir (illegal) */ ! 213: else { ! 214: callp = &sysent[code]; ! 215: if (callp == sysent) { /* indir */ ! 216: i = fuword(params); ! 217: params += NBPW; ! 218: if ((unsigned)i >= nsysent) ! 219: callp = &sysent[0]; ! 220: else ! 221: callp = &sysent[i]; ! 222: } ! 223: } ! 224: if ((i = callp->sy_narg * sizeof (int)) && ! 225: (u.u_error = copyin(params, (caddr_t)u.u_arg, (u_int)i)) != 0) { ! 226: locr0[R0] = u.u_error; ! 227: locr0[PS] |= PSL_C; /* carry bit */ ! 228: goto done; ! 229: } ! 230: u.u_r.r_val1 = 0; ! 231: u.u_r.r_val2 = locr0[R1]; ! 232: if (setjmp(&u.u_qsave)) { ! 233: if (u.u_error == 0 && u.u_eosys != RESTARTSYS) ! 234: u.u_error = EINTR; ! 235: } else { ! 236: u.u_eosys = NORMALRETURN; ! 237: #ifdef SYSCALLTRACE ! 238: if (syscalltrace) { ! 239: register int i; ! 240: char *cp; ! 241: ! 242: if (code >= nsysent) ! 243: printf("0x%x", code); ! 244: else ! 245: printf("%s", syscallnames[code]); ! 246: cp = "("; ! 247: for (i= 0; i < callp->sy_narg; i++) { ! 248: printf("%s%x", cp, u.u_arg[i]); ! 249: cp = ", "; ! 250: } ! 251: if (i) ! 252: putchar(')', 0); ! 253: putchar('\n', 0); ! 254: } ! 255: #endif ! 256: (*(callp->sy_call))(); ! 257: } ! 258: if (u.u_eosys == NORMALRETURN) { ! 259: if (u.u_error) { ! 260: locr0[R0] = u.u_error; ! 261: locr0[PS] |= PSL_C; /* carry bit */ ! 262: } else { ! 263: locr0[R0] = u.u_r.r_val1; ! 264: locr0[R1] = u.u_r.r_val2; ! 265: locr0[PS] &= ~PSL_C; ! 266: } ! 267: } else if (u.u_eosys == RESTARTSYS) ! 268: pc = opc; ! 269: /* else if (u.u_eosys == JUSTRETURN) */ ! 270: /* nothing to do */ ! 271: done: ! 272: p = u.u_procp; ! 273: if (p->p_cursig || ISSIG(p)) ! 274: psig(); ! 275: p->p_pri = p->p_usrpri; ! 276: if (runrun) { ! 277: /* ! 278: * Since we are u.u_procp, clock will normally just change ! 279: * our priority without moving us from one queue to another ! 280: * (since the running process is not on a queue.) ! 281: * If that happened after we setrq ourselves but before we ! 282: * swtch()'ed, we might not be on the queue indicated by ! 283: * our priority. ! 284: */ ! 285: (void) splclock(); ! 286: setrq(p); ! 287: u.u_ru.ru_nivcsw++; ! 288: swtch(); ! 289: } ! 290: if (u.u_prof.pr_scale) { ! 291: int ticks; ! 292: struct timeval *tv = &u.u_ru.ru_stime; ! 293: ! 294: ticks = ((tv->tv_sec - syst.tv_sec) * 1000 + ! 295: (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000); ! 296: if (ticks) ! 297: addupc(locr0[PC], &u.u_prof, ticks); ! 298: } ! 299: curpri = p->p_pri; ! 300: } ! 301: ! 302: /* ! 303: * nonexistent system call-- signal process (may want to handle it) ! 304: * flag error if process won't see signal immediately ! 305: * Q: should we do that all the time ?? ! 306: */ ! 307: nosys() ! 308: { ! 309: if (u.u_signal[SIGSYS] == SIG_IGN || u.u_signal[SIGSYS] == SIG_HOLD) ! 310: u.u_error = EINVAL; ! 311: psignal(u.u_procp, SIGSYS); ! 312: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.