Annotation of 43BSDReno/sys/hp300/trap.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1988 University of Utah.
                      3:  * Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
                      4:  * All rights reserved.
                      5:  *
                      6:  * This code is derived from software contributed to Berkeley by
                      7:  * the Systems Programming Group of the University of Utah Computer
                      8:  * Science Department.
                      9:  *
                     10:  * Redistribution is only permitted until one year after the first shipment
                     11:  * of 4.4BSD by the Regents.  Otherwise, redistribution and use in source and
                     12:  * binary forms are permitted provided that: (1) source distributions retain
                     13:  * this entire copyright notice and comment, and (2) distributions including
                     14:  * binaries display the following acknowledgement:  This product includes
                     15:  * software developed by the University of California, Berkeley and its
                     16:  * contributors'' in the documentation or other materials provided with the
                     17:  * distribution and in all advertising materials mentioning features or use
                     18:  * of this software.  Neither the name of the University nor the names of
                     19:  * its contributors may be used to endorse or promote products derived from
                     20:  * this software without specific prior written permission.
                     21:  * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
                     22:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
                     23:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     24:  *
                     25:  * from: Utah $Hdr: trap.c 1.28 89/09/25$
                     26:  *
                     27:  *     @(#)trap.c      7.7 (Berkeley) 6/25/90
                     28:  */
                     29: 
                     30: #include "cpu.h"
                     31: #include "psl.h"
                     32: #include "reg.h"
                     33: #include "pte.h"
                     34: #include "mtpr.h"
                     35: 
                     36: #include "param.h"
                     37: #include "systm.h"
                     38: #include "user.h"
                     39: #include "proc.h"
                     40: #include "seg.h"
                     41: #include "trap.h"
                     42: #include "acct.h"
                     43: #include "kernel.h"
                     44: #include "vm.h"
                     45: #include "cmap.h"
                     46: #include "syslog.h"
                     47: #ifdef KTRACE
                     48: #include "ktrace.h"
                     49: #endif
                     50: 
                     51: #ifdef HPUXCOMPAT
                     52: #include "../hpux/hpux.h"
                     53: #endif
                     54: 
                     55: #define        USER    040             /* user-mode flag added to type */
                     56: 
                     57: struct sysent  sysent[];
                     58: int    nsysent;
                     59: 
                     60: char   *trap_type[] = {
                     61:        "Bus error",
                     62:        "Address error",
                     63:        "Illegal instruction",
                     64:        "Zero divide",
                     65:        "CHK instruction",
                     66:        "TRAPV instruction",
                     67:        "Privilege violation",
                     68:        "Trace trap",
                     69:        "MMU fault",
                     70:        "SSIR trap",
                     71:        "Format error",
                     72:        "68881 exception",
                     73:        "Coprocessor violation",
                     74:        "Async system trap"
                     75: };
                     76: #define        TRAP_TYPES      (sizeof trap_type / sizeof trap_type[0])
                     77: 
                     78: #ifdef DEBUG
                     79: int mmudebug = 0;
                     80: #endif
                     81: 
                     82: /*
                     83:  * Called from the trap handler when a processor trap occurs.
                     84:  */
                     85: /*ARGSUSED*/
                     86: trap(type, code, v, frame)
                     87:        int type;
                     88:        unsigned code;
                     89:        register unsigned v;
                     90:        struct frame frame;
                     91: {
                     92:        register int i;
                     93:        unsigned ucode = 0;
                     94:        register struct proc *p = u.u_procp;
                     95:        struct timeval syst;
                     96:        unsigned ncode;
                     97: 
                     98:        cnt.v_trap++;
                     99:        syst = u.u_ru.ru_stime;
                    100:        if (USERMODE(frame.f_sr)) {
                    101:                type |= USER;
                    102:                u.u_ar0 = frame.f_regs;
                    103:        }
                    104:        switch (type) {
                    105: 
                    106:        default:
                    107: dopanic:
                    108: #ifdef KGDB
                    109:                if (!panicstr && kgdb_trap(type, code, v, &frame))
                    110:                        return;
                    111: #endif
                    112:                printf("trap type %d, code = %x, v = %x\n", type, code, v);
                    113:                regdump(frame.f_regs, 128);
                    114:                type &= ~USER;
                    115:                if ((unsigned)type < TRAP_TYPES)
                    116:                        panic(trap_type[type]);
                    117:                panic("trap");
                    118: 
                    119:        case T_BUSERR:          /* kernel bus error */
                    120:                if (!u.u_pcb.pcb_onfault)
                    121:                        goto dopanic;
                    122:                /*
                    123:                 * If we have arranged to catch this fault in any of the
                    124:                 * copy to/from user space routines, set PC to return to
                    125:                 * indicated location and set flag informing buserror code
                    126:                 * that it may need to clean up stack frame.
                    127:                 */
                    128: copyfault:
                    129:                frame.f_pc = (int) u.u_pcb.pcb_onfault;
                    130:                frame.f_stackadj = -1;
                    131:                return;
                    132: 
                    133:        case T_BUSERR+USER:     /* bus error */
                    134:        case T_ADDRERR+USER:    /* address error */
                    135:                i = SIGBUS;
                    136:                break;
                    137: 
                    138: #ifdef FPCOPROC
                    139:        case T_COPERR:          /* kernel coprocessor violation */
                    140: #endif
                    141:        case T_FMTERR:          /* kernel format error */
                    142:        /*
                    143:         * The user has most likely trashed the RTE or FP state info
                    144:         * in the stack frame of a signal handler.
                    145:         */
                    146:                type |= USER;
                    147:                printf("pid %d: kernel %s exception\n", u.u_procp->p_pid,
                    148:                       type==T_COPERR ? "coprocessor" : "format");
                    149:                u.u_signal[SIGILL] = SIG_DFL;
                    150:                i = sigmask(SIGILL);
                    151:                p->p_sigignore &= ~i;
                    152:                p->p_sigcatch &= ~i;
                    153:                p->p_sigmask &= ~i;
                    154:                i = SIGILL;
                    155:                ucode = frame.f_format; /* XXX was ILL_RESAD_FAULT */
                    156:                break;
                    157: 
                    158: #ifdef FPCOPROC
                    159:        case T_COPERR+USER:     /* user coprocessor violation */
                    160:        /* What is a proper response here? */
                    161:                ucode = 0;
                    162:                i = SIGFPE;
                    163:                break;
                    164: 
                    165:        case T_FPERR+USER:              /* 68881 exceptions */
                    166:        /*
                    167:         * We pass along the 68881 status register which locore stashed
                    168:         * in code for us.  Note that there is a possibility that the
                    169:         * bit pattern of this register will conflict with one of the
                    170:         * FPE_* codes defined in signal.h.  Fortunately for us, the
                    171:         * only such codes we use are all in the range 1-7 and the low
                    172:         * 3 bits of the status register are defined as 0 so there is
                    173:         * no clash.
                    174:         */
                    175:                ucode = code;
                    176:                i = SIGFPE;
                    177:                break;
                    178: #endif
                    179: 
                    180:        case T_ILLINST+USER:    /* illegal instruction fault */
                    181: #ifdef HPUXCOMPAT
                    182:                if (u.u_procp->p_flag & SHPUX) {
                    183:                        ucode = HPUX_ILL_ILLINST_TRAP;
                    184:                        i = SIGILL;
                    185:                        break;
                    186:                }
                    187:                /* fall through */
                    188: #endif
                    189:        case T_PRIVINST+USER:   /* privileged instruction fault */
                    190: #ifdef HPUXCOMPAT
                    191:                if (u.u_procp->p_flag & SHPUX)
                    192:                        ucode = HPUX_ILL_PRIV_TRAP;
                    193:                else
                    194: #endif
                    195:                ucode = frame.f_format; /* XXX was ILL_PRIVIN_FAULT */
                    196:                i = SIGILL;
                    197:                break;
                    198: 
                    199:        case T_ZERODIV+USER:    /* Divide by zero */
                    200: #ifdef HPUXCOMPAT
                    201:                if (u.u_procp->p_flag & SHPUX)
                    202:                        ucode = HPUX_FPE_INTDIV_TRAP;
                    203:                else
                    204: #endif
                    205:                ucode = frame.f_format; /* XXX was FPE_INTDIV_TRAP */
                    206:                i = SIGFPE;
                    207:                break;
                    208: 
                    209:        case T_CHKINST+USER:    /* CHK instruction trap */
                    210: #ifdef HPUXCOMPAT
                    211:                if (u.u_procp->p_flag & SHPUX) {
                    212:                        /* handled differently under hp-ux */
                    213:                        i = SIGILL;
                    214:                        ucode = HPUX_ILL_CHK_TRAP;
                    215:                        break;
                    216:                }
                    217: #endif
                    218:                ucode = frame.f_format; /* XXX was FPE_SUBRNG_TRAP */
                    219:                i = SIGFPE;
                    220:                break;
                    221: 
                    222:        case T_TRAPVINST+USER:  /* TRAPV instruction trap */
                    223: #ifdef HPUXCOMPAT
                    224:                if (u.u_procp->p_flag & SHPUX) {
                    225:                        /* handled differently under hp-ux */
                    226:                        i = SIGILL;
                    227:                        ucode = HPUX_ILL_TRAPV_TRAP;
                    228:                        break;
                    229:                }
                    230: #endif
                    231:                ucode = frame.f_format; /* XXX was FPE_INTOVF_TRAP */
                    232:                i = SIGFPE;
                    233:                break;
                    234: 
                    235:        /*
                    236:         * XXX: Trace traps are a nightmare.
                    237:         *
                    238:         *      HP-UX uses trap #1 for breakpoints,
                    239:         *      HPBSD uses trap #2,
                    240:         *      SUN 3.x uses trap #15,
                    241:         *      KGDB uses trap #15 (for kernel breakpoints).
                    242:         *
                    243:         * HPBSD and HP-UX traps both get mapped by locore.s into T_TRACE.
                    244:         * SUN 3.x traps get passed through as T_TRAP15 and are not really
                    245:         * supported yet.  KGDB traps are also passed through as T_TRAP15
                    246:         * and are not used yet.
                    247:         */
                    248:        case T_TRACE:           /* kernel trace trap */
                    249:        case T_TRAP15:          /* SUN (or KGDB) kernel trace trap */
                    250: #ifdef KGDB
                    251:                if (kgdb_trap(type, code, v, &frame))
                    252:                        return;
                    253: #endif
                    254:                frame.f_sr &= ~PSL_T;
                    255:                i = SIGTRAP;
                    256:                break;
                    257: 
                    258:        case T_TRACE+USER:      /* user trace trap */
                    259:        case T_TRAP15+USER:     /* SUN user trace trap */
                    260:                frame.f_sr &= ~PSL_T;
                    261:                i = SIGTRAP;
                    262:                break;
                    263: 
                    264:        case T_ASTFLT:          /* system async trap, cannot happen */
                    265:                goto dopanic;
                    266: 
                    267:        case T_ASTFLT+USER:     /* user async trap */
                    268:                astoff();
                    269:                /*
                    270:                 * We check for software interrupts first.  This is because
                    271:                 * they are at a higher level than ASTs, and on a VAX would
                    272:                 * interrupt the AST.  We assume that if we are processing
                    273:                 * an AST that we must be at IPL0 so we don't bother to
                    274:                 * check.  Note that we ensure that we are at least at SIR
                    275:                 * IPL while processing the SIR.
                    276:                 */
                    277:                spl1();
                    278:                /* fall into... */
                    279: 
                    280:        case T_SSIR:            /* software interrupt */
                    281:        case T_SSIR+USER:
                    282:                if (ssir & SIR_NET) {
                    283:                        siroff(SIR_NET);
                    284:                        cnt.v_soft++;
                    285:                        netintr();
                    286:                }
                    287:                if (ssir & SIR_CLOCK) {
                    288:                        siroff(SIR_CLOCK);
                    289:                        cnt.v_soft++;
                    290:                        softclock((caddr_t)frame.f_pc, (int)frame.f_sr);
                    291:                }
                    292:                /*
                    293:                 * If this was not an AST trap, we are all done.
                    294:                 */
                    295:                if (type != T_ASTFLT+USER) {
                    296:                        cnt.v_trap--;
                    297:                        return;
                    298:                }
                    299:                spl0();
                    300: #ifndef PROFTIMER
                    301:                if ((u.u_procp->p_flag&SOWEUPC) && u.u_prof.pr_scale) {
                    302:                        addupc(frame.f_pc, &u.u_prof, 1);
                    303:                        u.u_procp->p_flag &= ~SOWEUPC;
                    304:                }
                    305: #endif
                    306:                goto out;
                    307: 
                    308:        case T_MMUFLT:          /* kernel mode page fault */
                    309:                /*
                    310:                 * Could be caused by a page fault in one of the copy to/from
                    311:                 * user space routines.  If so, we will have a catch address.
                    312:                 */
                    313:                if (!u.u_pcb.pcb_onfault)
                    314:                        goto dopanic;
                    315:                /* fall into ... */
                    316: 
                    317:        case T_MMUFLT+USER:     /* page fault */
                    318: /*
                    319:                printf("trap: T_MMUFLT pid %d, code %x, v %x, pc %x, ps %x\n",
                    320:                       p->p_pid, code, v, frame.f_pc, frame.f_sr);
                    321: */
                    322:                if (v >= USRSTACK) {
                    323:                        if (type == T_MMUFLT)
                    324:                                goto copyfault;
                    325:                        i = SIGSEGV;
                    326:                        break;
                    327:                }
                    328:                ncode = code >> 16;
                    329: #if defined(HP330) || defined(HP360) || defined(HP370)
                    330:                /*
                    331:                 * Crudely map PMMU faults into HP MMU faults.
                    332:                 */
                    333:                if (mmutype != MMU_HP) {
                    334:                        int ocode = ncode;
                    335:                        ncode = 0;
                    336:                        if (ocode & PMMU_WP)
                    337:                                ncode |= MMU_WPF;
                    338:                        else if (ocode & PMMU_INV) {
                    339:                                if ((ocode & PMMU_LVLMASK) == 2)
                    340:                                        ncode |= MMU_PF;
                    341:                                else 
                    342:                                        ncode |= MMU_PTF;
                    343:                        }
                    344:                        /*
                    345:                         * RMW cycle, must load ATC by hand
                    346:                         */
                    347:                        else if ((code & (SSW_DF|SSW_RM)) == (SSW_DF|SSW_RM)) {
                    348: #ifdef DEBUG
                    349:                                log(LOG_WARNING,
                    350:                                    "RMW fault at %x: MMUSR %x SSW %x\n",
                    351:                                    v, ocode, code & 0xFFFF);
                    352: #endif
                    353:                                ploadw((caddr_t)v);
                    354:                                return;
                    355:                        }
                    356:                        /*
                    357:                         * Fault with no fault bits, should indicate bad
                    358:                         * hardware but we see this on 340s using starbase
                    359:                         * sometimes (faults accessing catseye registers)
                    360:                         */
                    361:                        else {
                    362:                                log(LOG_WARNING,
                    363:                                    "Bad PMMU fault at %x: MMUSR %x SSW %x\n",
                    364:                                    v, ocode, code & 0xFFFF);
                    365:                                return;
                    366:                        }
                    367: #ifdef DEBUG
                    368:                        if (mmudebug && mmudebug == p->p_pid)
                    369:                                printf("MMU %d: v%x, os%x, ns%x\n",
                    370:                                       p->p_pid, v, ocode, ncode);
                    371: #endif
                    372:                }
                    373: #endif
                    374: #ifdef DEBUG
                    375:                if ((ncode & (MMU_PTF|MMU_PF|MMU_WPF|MMU_FPE)) == 0) {
                    376:                        printf("T_MMUFLT with no fault bits\n");
                    377:                        goto dopanic;
                    378:                }
                    379: #endif
                    380:                if (ncode & MMU_PTF) {
                    381: #ifdef DEBUG
                    382:                        /*
                    383:                         * NOTE: we use a u_int instead of an ste since the
                    384:                         * current compiler generates bogus code for some
                    385:                         * bitfield operations (i.e. attempts to access last
                    386:                         * word of a page as a longword causing fault).
                    387:                         */
                    388:                        extern struct ste *vtoste();
                    389:                        u_int *ste = (u_int *)vtoste(p, v);
                    390: 
                    391:                        if (*ste & SG_V) {
                    392:                                if (ncode & MMU_WPF) {
                    393:                                        printf("PTF|WPF...\n");
                    394:                                        if (type == T_MMUFLT)
                    395:                                                goto copyfault;
                    396:                                        i = SIGBUS;
                    397:                                        break;
                    398:                                }
                    399:                                printf("MMU_PTF with sg_v, ste@%x = %x\n",
                    400:                                       ste, *ste);
                    401:                                goto dopanic;
                    402:                        }
                    403: #endif
                    404: #ifdef HPUXCOMPAT
                    405:                        if (ISHPMMADDR(v)) {
                    406:                                extern struct ste *vtoste();
                    407:                                u_int *bste, *nste;
                    408: 
                    409:                                bste = (u_int *)vtoste(p, HPMMBASEADDR(v));
                    410:                                nste = (u_int *)vtoste(p, v);
                    411:                                if ((*bste & SG_V) && *nste == SG_NV) {
                    412:                                        *nste = *bste;
                    413:                                        TBIAU();
                    414:                                        return;
                    415:                                }
                    416:                        }
                    417: #endif
                    418:                growit:
                    419:                        if (type == T_MMUFLT)
                    420:                                goto copyfault;
                    421:                        if (grow((unsigned)frame.f_regs[SP]) || grow(v))
                    422:                                goto out;
                    423:                        i = SIGSEGV;
                    424:                        break;
                    425:                }
                    426: #ifdef HPUXCOMPAT
                    427:                if (ISHPMMADDR(v)) {
                    428:                        TBIS(v);
                    429:                        v = HPMMBASEADDR(v);
                    430:                }
                    431: #endif
                    432:                /*
                    433:                 * NOTE: WPF without PG_V is possible
                    434:                 * (e.g. attempt to write shared text which is paged out)
                    435:                 */
                    436:                if (ncode & MMU_WPF) {
                    437: #ifdef DEBUG
                    438:                        extern struct ste *vtoste();
                    439:                        u_int *ste = (u_int *)vtoste(p, v);
                    440: 
                    441:                        if (!(*ste & SG_V)) {
                    442:                                printf("MMU_WPF without sg_v, ste@%x = %x\n",
                    443:                                       ste, *ste);
                    444:                                goto dopanic;
                    445:                        }
                    446: #endif
                    447:                        if (type == T_MMUFLT)
                    448:                                goto copyfault;
                    449:                        i = SIGBUS;
                    450:                        break;
                    451:                }
                    452:                if (ncode & MMU_PF) {
                    453:                        register u_int vp;
                    454: #ifdef DEBUG
                    455:                        extern struct ste *vtoste();
                    456:                        u_int *ste = (u_int *)vtoste(p, v);
                    457:                        struct pte *pte;
                    458: 
                    459:                        if (!(*ste & SG_V)) {
                    460:                                printf("MMU_PF without sg_v, ste@%x = %x\n",
                    461:                                       ste, *ste);
                    462:                                goto dopanic;
                    463:                        }
                    464: #endif
                    465:                        vp = btop(v);
                    466:                        if (vp >= dptov(p, p->p_dsize) &&
                    467:                            vp < sptov(p, p->p_ssize-1))
                    468:                                goto growit;
                    469: #ifdef DEBUG
                    470:                        pte = vtopte(p, vp);
                    471:                        if (*(u_int *)pte & PG_V) {
                    472:                                printf("MMU_PF with pg_v, pte = %x\n",
                    473:                                       *(u_int *)pte);
                    474:                                goto dopanic;
                    475:                        }
                    476: #endif
                    477:                        pagein(v, 0);
                    478:                        if (type == T_MMUFLT)
                    479:                                return;
                    480:                        goto out;
                    481:                }
                    482: #ifdef DEBUG
                    483:                printf("T_MMUFLT: unrecognized scenerio\n");
                    484:                goto dopanic;
                    485: #endif
                    486:        }
                    487:        trapsignal(i, ucode);
                    488:        if ((type & USER) == 0)
                    489:                return;
                    490: out:
                    491:        p = u.u_procp;
                    492:        if (i = CURSIG(p))
                    493:                psig(i);
                    494:        p->p_pri = p->p_usrpri;
                    495:        if (runrun) {
                    496:                /*
                    497:                 * Since we are u.u_procp, clock will normally just change
                    498:                 * our priority without moving us from one queue to another
                    499:                 * (since the running process is not on a queue.)
                    500:                 * If that happened after we setrq ourselves but before we
                    501:                 * swtch()'ed, we might not be on the queue indicated by
                    502:                 * our priority.
                    503:                 */
                    504:                (void) splclock();
                    505:                setrq(p);
                    506:                u.u_ru.ru_nivcsw++;
                    507:                swtch();
                    508:                if (i = CURSIG(p))
                    509:                        psig(i);
                    510:        }
                    511:        if (u.u_prof.pr_scale) {
                    512:                int ticks;
                    513:                struct timeval *tv = &u.u_ru.ru_stime;
                    514: 
                    515:                ticks = ((tv->tv_sec - syst.tv_sec) * 1000 +
                    516:                        (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000);
                    517:                if (ticks) {
                    518: #ifdef PROFTIMER
                    519:                        extern int profscale;
                    520:                        addupc(frame.f_pc, &u.u_prof, ticks * profscale);
                    521: #else
                    522:                        addupc(frame.f_pc, &u.u_prof, ticks);
                    523: #endif
                    524:                }
                    525:        }
                    526:        curpri = p->p_pri;
                    527: }
                    528: 
                    529: /*
                    530:  * Called from the trap handler when a system call occurs
                    531:  */
                    532: /*ARGSUSED*/
                    533: syscall(code, frame)
                    534:        volatile int code;
                    535:        struct frame frame;
                    536: {
                    537:        register caddr_t params;
                    538:        register int i;
                    539:        register struct sysent *callp;
                    540:        register struct proc *p = u.u_procp;
                    541:        int error, opc, numsys;
                    542:        struct args {
                    543:                int i[8];
                    544:        } args;
                    545:        int rval[2];
                    546:        struct timeval syst;
                    547:        struct sysent *systab;
                    548: #ifdef HPUXCOMPAT
                    549:        extern struct sysent hpuxsysent[];
                    550:        extern int hpuxnsysent, notimp();
                    551: #endif
                    552: 
                    553:        cnt.v_syscall++;
                    554:        syst = u.u_ru.ru_stime;
                    555:        if (!USERMODE(frame.f_sr))
                    556:                panic("syscall");
                    557:        u.u_ar0 = frame.f_regs;
                    558:        opc = frame.f_pc - 2;
                    559:        systab = sysent;
                    560:        numsys = nsysent;
                    561: #ifdef HPUXCOMPAT
                    562:        if (p->p_flag & SHPUX) {
                    563:                systab = hpuxsysent;
                    564:                numsys = hpuxnsysent;
                    565:        }
                    566: #endif
                    567:        params = (caddr_t)frame.f_regs[SP] + NBPW;
                    568:        if (code == 0) {                        /* indir */
                    569:                code = fuword(params);
                    570:                params += NBPW;
                    571:        }
                    572:        if (code >= numsys)
                    573:                callp = &systab[0];             /* indir (illegal) */
                    574:        else
                    575:                callp = &systab[code];
                    576:        if ((i = callp->sy_narg * sizeof (int)) &&
                    577:            (error = copyin(params, (caddr_t)&args, (u_int)i))) {
                    578: #ifdef HPUXCOMPAT
                    579:                if (p->p_flag & SHPUX)
                    580:                        error = bsdtohpuxerrno(error);
                    581: #endif
                    582:                frame.f_regs[D0] = (u_char) error;
                    583:                frame.f_sr |= PSL_C;    /* carry bit */
                    584: #ifdef KTRACE
                    585:                if (KTRPOINT(p, KTR_SYSCALL))
                    586:                        ktrsyscall(p->p_tracep, code, callp->sy_narg, args.i);
                    587: #endif
                    588:                goto done;
                    589:        }
                    590: #ifdef KTRACE
                    591:        if (KTRPOINT(p, KTR_SYSCALL))
                    592:                ktrsyscall(p->p_tracep, code, callp->sy_narg, args.i);
                    593: #endif
                    594:        rval[0] = 0;
                    595:        rval[1] = frame.f_regs[D1];
                    596: #ifdef HPUXCOMPAT
                    597:        /* debug kludge */
                    598:        if (callp->sy_call == notimp)
                    599:                error = notimp(u.u_procp, args.i, rval, code, callp->sy_narg);
                    600:        else
                    601: #endif
                    602:        error = (*callp->sy_call)(u.u_procp, &args, rval);
                    603:        if (error == ERESTART)
                    604:                frame.f_pc = opc;
                    605:        else if (error != EJUSTRETURN) {
                    606:                if (error) {
                    607: #ifdef HPUXCOMPAT
                    608:                        if (p->p_flag & SHPUX)
                    609:                                error = bsdtohpuxerrno(error);
                    610: #endif
                    611:                        frame.f_regs[D0] = (u_char) error;
                    612:                        frame.f_sr |= PSL_C;    /* carry bit */
                    613:                } else {
                    614:                        frame.f_regs[D0] = rval[0];
                    615:                        frame.f_regs[D1] = rval[1];
                    616:                        frame.f_sr &= ~PSL_C;
                    617:                }
                    618:        }
                    619:        /* else if (error == EJUSTRETURN) */
                    620:                /* nothing to do */
                    621: 
                    622: done:
                    623:        /*
                    624:         * Reinitialize proc pointer `p' as it may be different
                    625:         * if this is a child returning from fork syscall.
                    626:         */
                    627:        p = u.u_procp;
                    628:        /*
                    629:         * XXX the check for sigreturn ensures that we don't
                    630:         * attempt to set up a call to a signal handler (sendsig) before
                    631:         * we have cleaned up the stack from the last call (sigreturn).
                    632:         * Allowing this seems to lock up the machine in certain scenarios.
                    633:         * What should really be done is to clean up the signal handling
                    634:         * so that this is not a problem.
                    635:         */
                    636: #include "syscall.h"
                    637:        if (code != SYS_sigreturn && (i = CURSIG(p)))
                    638:                psig(i);
                    639:        p->p_pri = p->p_usrpri;
                    640:        if (runrun) {
                    641:                /*
                    642:                 * Since we are u.u_procp, clock will normally just change
                    643:                 * our priority without moving us from one queue to another
                    644:                 * (since the running process is not on a queue.)
                    645:                 * If that happened after we setrq ourselves but before we
                    646:                 * swtch()'ed, we might not be on the queue indicated by
                    647:                 * our priority.
                    648:                 */
                    649:                (void) splclock();
                    650:                setrq(p);
                    651:                u.u_ru.ru_nivcsw++;
                    652:                swtch();
                    653:                if (code != SYS_sigreturn && (i = CURSIG(p)))
                    654:                        psig(i);
                    655:        }
                    656:        if (u.u_prof.pr_scale) {
                    657:                int ticks;
                    658:                struct timeval *tv = &u.u_ru.ru_stime;
                    659: 
                    660:                ticks = ((tv->tv_sec - syst.tv_sec) * 1000 +
                    661:                        (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000);
                    662:                if (ticks) {
                    663: #ifdef PROFTIMER
                    664:                        extern int profscale;
                    665:                        addupc(frame.f_pc, &u.u_prof, ticks * profscale);
                    666: #else
                    667:                        addupc(frame.f_pc, &u.u_prof, ticks);
                    668: #endif
                    669:                }
                    670:        }
                    671:        curpri = p->p_pri;
                    672: #ifdef KTRACE
                    673:        if (KTRPOINT(p, KTR_SYSRET))
                    674:                ktrsysret(p->p_tracep, code, error, rval[0]);
                    675: #endif
                    676: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.