[BACK]Return to trap.c CVS log [TXT][DIR] Up to [local] / sys / arch / amd64 / amd64

Annotation of sys/arch/amd64/amd64/trap.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: trap.c,v 1.13 2007/05/11 10:06:55 pedro Exp $ */
        !             2: /*     $NetBSD: trap.c,v 1.2 2003/05/04 23:51:56 fvdl Exp $    */
        !             3:
        !             4: /*-
        !             5:  * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
        !             6:  * All rights reserved.
        !             7:  *
        !             8:  * This code is derived from software contributed to The NetBSD Foundation
        !             9:  * by Charles M. Hannum.
        !            10:  *
        !            11:  * Redistribution and use in source and binary forms, with or without
        !            12:  * modification, are permitted provided that the following conditions
        !            13:  * are met:
        !            14:  * 1. Redistributions of source code must retain the above copyright
        !            15:  *    notice, this list of conditions and the following disclaimer.
        !            16:  * 2. Redistributions in binary form must reproduce the above copyright
        !            17:  *    notice, this list of conditions and the following disclaimer in the
        !            18:  *    documentation and/or other materials provided with the distribution.
        !            19:  * 3. All advertising materials mentioning features or use of this software
        !            20:  *    must display the following acknowledgement:
        !            21:  *        This product includes software developed by the NetBSD
        !            22:  *        Foundation, Inc. and its contributors.
        !            23:  * 4. Neither the name of The NetBSD Foundation nor the names of its
        !            24:  *    contributors may be used to endorse or promote products derived
        !            25:  *    from this software without specific prior written permission.
        !            26:  *
        !            27:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
        !            28:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
        !            29:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        !            30:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
        !            31:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
        !            32:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
        !            33:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
        !            34:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
        !            35:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        !            36:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
        !            37:  * POSSIBILITY OF SUCH DAMAGE.
        !            38:  */
        !            39:
        !            40: /*-
        !            41:  * Copyright (c) 1990 The Regents of the University of California.
        !            42:  * All rights reserved.
        !            43:  *
        !            44:  * This code is derived from software contributed to Berkeley by
        !            45:  * the University of Utah, and William Jolitz.
        !            46:  *
        !            47:  * Redistribution and use in source and binary forms, with or without
        !            48:  * modification, are permitted provided that the following conditions
        !            49:  * are met:
        !            50:  * 1. Redistributions of source code must retain the above copyright
        !            51:  *    notice, this list of conditions and the following disclaimer.
        !            52:  * 2. Redistributions in binary form must reproduce the above copyright
        !            53:  *    notice, this list of conditions and the following disclaimer in the
        !            54:  *    documentation and/or other materials provided with the distribution.
        !            55:  * 3. Neither the name of the University nor the names of its contributors
        !            56:  *    may be used to endorse or promote products derived from this software
        !            57:  *    without specific prior written permission.
        !            58:  *
        !            59:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            60:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            61:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            62:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            63:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            64:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            65:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            66:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            67:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            68:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            69:  * SUCH DAMAGE.
        !            70:  *
        !            71:  *     @(#)trap.c      7.4 (Berkeley) 5/13/91
        !            72:  */
        !            73:
        !            74: /*
        !            75:  * amd64 Trap and System call handling
        !            76:  */
        !            77: #undef TRAP_SIGDEBUG
        !            78:
        !            79: #include <sys/param.h>
        !            80: #include <sys/systm.h>
        !            81: #include <sys/proc.h>
        !            82: #include <sys/user.h>
        !            83: #include <sys/acct.h>
        !            84: #include <sys/kernel.h>
        !            85: #include <sys/signal.h>
        !            86: #include <sys/syscall.h>
        !            87: #include <sys/reboot.h>
        !            88: #include <sys/pool.h>
        !            89:
        !            90: #include <uvm/uvm_extern.h>
        !            91:
        !            92: #include <machine/cpu.h>
        !            93: #include <machine/cpufunc.h>
        !            94: #include <machine/fpu.h>
        !            95: #include <machine/psl.h>
        !            96: #include <machine/reg.h>
        !            97: #include <machine/trap.h>
        !            98: #include <machine/userret.h>
        !            99: #ifdef DDB
        !           100: #include <machine/db_machdep.h>
        !           101: #endif
        !           102:
        !           103: #include "isa.h"
        !           104:
        !           105: #ifdef KGDB
        !           106: #include <sys/kgdb.h>
        !           107: #endif
        !           108:
        !           109: void trap(struct trapframe);
        !           110:
        !           111: const char *trap_type[] = {
        !           112:        "privileged instruction fault",         /*  0 T_PRIVINFLT */
        !           113:        "breakpoint trap",                      /*  1 T_BPTFLT */
        !           114:        "arithmetic trap",                      /*  2 T_ARITHTRAP */
        !           115:        "asynchronous system trap",             /*  3 T_ASTFLT */
        !           116:        "protection fault",                     /*  4 T_PROTFLT */
        !           117:        "trace trap",                           /*  5 T_TRCTRAP */
        !           118:        "page fault",                           /*  6 T_PAGEFLT */
        !           119:        "alignment fault",                      /*  7 T_ALIGNFLT */
        !           120:        "integer divide fault",                 /*  8 T_DIVIDE */
        !           121:        "non-maskable interrupt",               /*  9 T_NMI */
        !           122:        "overflow trap",                        /* 10 T_OFLOW */
        !           123:        "bounds check fault",                   /* 11 T_BOUND */
        !           124:        "FPU not available fault",              /* 12 T_DNA */
        !           125:        "double fault",                         /* 13 T_DOUBLEFLT */
        !           126:        "FPU operand fetch fault",              /* 14 T_FPOPFLT */
        !           127:        "invalid TSS fault",                    /* 15 T_TSSFLT */
        !           128:        "segment not present fault",            /* 16 T_SEGNPFLT */
        !           129:        "stack fault",                          /* 17 T_STKFLT */
        !           130:        "machine check",                        /* 18 T_MCA */
        !           131:        "SSE FP exception",                     /* 19 T_XMM */
        !           132:        "reserved trap",                        /* 20 T_RESERVED */
        !           133: };
        !           134: int    trap_types = sizeof trap_type / sizeof trap_type[0];
        !           135:
        !           136: #ifdef DEBUG
        !           137: int    trapdebug = 0;
        !           138: #endif
        !           139:
        !           140: #define        IDTVEC(name)    __CONCAT(X, name)
        !           141:
        !           142: #ifdef TRAP_SIGDEBUG
        !           143: static void frame_dump(struct trapframe *);
        !           144: #endif
        !           145:
        !           146: /*
        !           147:  * trap(frame):
        !           148:  *     Exception, fault, and trap interface to BSD kernel. This
        !           149:  * common code is called from assembly language IDT gate entry
        !           150:  * routines that prepare a suitable stack frame, and restore this
        !           151:  * frame after the exception has been processed. Note that the
        !           152:  * effect is as if the arguments were passed call by reference.
        !           153:  */
        !           154: /*ARGSUSED*/
        !           155: void
        !           156: trap(struct trapframe frame)
        !           157: {
        !           158:        struct proc *p = curproc;
        !           159:        int type = (int)frame.tf_trapno;
        !           160:        struct pcb *pcb;
        !           161:        extern char resume_iret[], IDTVEC(oosyscall)[];
        !           162: #if 0
        !           163:        extern char resume_pop_ds[], resume_pop_es[];
        !           164: #endif
        !           165:        struct trapframe *vframe;
        !           166:        void *resume;
        !           167:        caddr_t onfault;
        !           168:        int error;
        !           169:        uint64_t cr2;
        !           170:        union sigval sv;
        !           171:
        !           172:        uvmexp.traps++;
        !           173:
        !           174:        pcb = (p != NULL && p->p_addr != NULL) ? &p->p_addr->u_pcb : NULL;
        !           175:
        !           176: #ifdef DEBUG
        !           177:        if (trapdebug) {
        !           178:                printf("trap %d code %lx eip %lx cs %lx rflags %lx cr2 %lx "
        !           179:                       "cpl %x\n",
        !           180:                    type, frame.tf_err, frame.tf_rip, frame.tf_cs,
        !           181:                    frame.tf_rflags, rcr2(), curcpu()->ci_ilevel);
        !           182:                printf("curproc %p\n", curproc);
        !           183:                if (curproc)
        !           184:                        printf("pid %d\n", p->p_pid);
        !           185:        }
        !           186: #endif
        !           187:
        !           188:        if (!KERNELMODE(frame.tf_cs, frame.tf_rflags)) {
        !           189:                type |= T_USER;
        !           190:                p->p_md.md_regs = &frame;
        !           191:        }
        !           192:
        !           193:        switch (type) {
        !           194:
        !           195:        default:
        !           196:        we_re_toast:
        !           197: #ifdef KGDB
        !           198:                if (kgdb_trap(type, &frame))
        !           199:                        return;
        !           200:                else {
        !           201:                        /*
        !           202:                         * If this is a breakpoint, don't panic
        !           203:                         * if we're not connected.
        !           204:                         */
        !           205:                        if (type == T_BPTFLT) {
        !           206:                                printf("kgdb: ignored %s\n", trap_type[type]);
        !           207:                                return;
        !           208:                        }
        !           209:                }
        !           210: #endif
        !           211: #ifdef DDB
        !           212:                if (kdb_trap(type, 0, &frame))
        !           213:                        return;
        !           214: #endif
        !           215:                if (frame.tf_trapno < trap_types)
        !           216:                        printf("fatal %s", trap_type[frame.tf_trapno]);
        !           217:                else
        !           218:                        printf("unknown trap %ld", (u_long)frame.tf_trapno);
        !           219:                printf(" in %s mode\n", (type & T_USER) ? "user" : "supervisor");
        !           220:                printf("trap type %d code %lx rip %lx cs %lx rflags %lx cr2 "
        !           221:                       " %lx cpl %x rsp %lx\n",
        !           222:                    type, frame.tf_err, (u_long)frame.tf_rip, frame.tf_cs,
        !           223:                    frame.tf_rflags, rcr2(), curcpu()->ci_ilevel, frame.tf_rsp);
        !           224:
        !           225:                /* panic("trap"); */
        !           226:                boot(RB_HALT);
        !           227:                /*NOTREACHED*/
        !           228:
        !           229:        case T_PROTFLT:
        !           230:        case T_SEGNPFLT:
        !           231:        case T_ALIGNFLT:
        !           232:        case T_TSSFLT:
        !           233:                if (p == NULL)
        !           234:                        goto we_re_toast;
        !           235:                /* Check for copyin/copyout fault. */
        !           236:                if (pcb->pcb_onfault != 0) {
        !           237:                        error = EFAULT;
        !           238: copyfault:
        !           239:                        frame.tf_rip = (u_int64_t)pcb->pcb_onfault;
        !           240:                        frame.tf_rax = error;
        !           241:                        return;
        !           242:                }
        !           243:
        !           244:                /*
        !           245:                 * Check for failure during return to user mode.
        !           246:                 *
        !           247:                 * XXXfvdl check for rex prefix?
        !           248:                 *
        !           249:                 * We do this by looking at the instruction we faulted on.  The
        !           250:                 * specific instructions we recognize only happen when
        !           251:                 * returning from a trap, syscall, or interrupt.
        !           252:                 *
        !           253:                 * XXX
        !           254:                 * The heuristic used here will currently fail for the case of
        !           255:                 * one of the 2 pop instructions faulting when returning from a
        !           256:                 * a fast interrupt.  This should not be possible.  It can be
        !           257:                 * fixed by rearranging the trap frame so that the stack format
        !           258:                 * at this point is the same as on exit from a `slow'
        !           259:                 * interrupt.
        !           260:                 */
        !           261:                switch (*(u_char *)frame.tf_rip) {
        !           262:                case 0xcf:      /* iret */
        !           263:                        vframe = (void *)((u_int64_t)&frame.tf_rsp - 44);
        !           264:                        resume = resume_iret;
        !           265:                        break;
        !           266: /*
        !           267:  * XXXfvdl these are illegal in long mode (not in compat mode, though)
        !           268:  * and we do not take back the descriptors from the signal context anyway,
        !           269:  * but may do so later for USER_LDT, in which case we need to intercept
        !           270:  * other instructions (movl %eax, %Xs).
        !           271:  */
        !           272: #if 0
        !           273:                case 0x1f:      /* popl %ds */
        !           274:                        vframe = (void *)((u_int64_t)&frame.tf_rsp - 4);
        !           275:                        resume = resume_pop_ds;
        !           276:                        break;
        !           277:                case 0x07:      /* popl %es */
        !           278:                        vframe = (void *)((u_int64_t)&frame.tf_rsp - 0);
        !           279:                        resume = resume_pop_es;
        !           280:                        break;
        !           281: #endif
        !           282:                default:
        !           283:                        goto we_re_toast;
        !           284:                }
        !           285:                if (KERNELMODE(vframe->tf_cs, vframe->tf_rflags))
        !           286:                        goto we_re_toast;
        !           287:
        !           288:                frame.tf_rip = (u_int64_t)resume;
        !           289:                return;
        !           290:
        !           291:        case T_PROTFLT|T_USER:          /* protection fault */
        !           292:        case T_TSSFLT|T_USER:
        !           293:        case T_SEGNPFLT|T_USER:
        !           294:        case T_STKFLT|T_USER:
        !           295:        case T_NMI|T_USER:
        !           296: #ifdef TRAP_SIGDEBUG
        !           297:                printf("pid %d (%s): BUS at rip %lx addr %lx\n",
        !           298:                    p->p_pid, p->p_comm, frame.tf_rip, rcr2());
        !           299:                frame_dump(&frame);
        !           300: #endif
        !           301:                sv.sival_ptr = (void *)frame.tf_rip;
        !           302:                KERNEL_PROC_LOCK(p);
        !           303:                trapsignal(p, SIGBUS, type & ~T_USER, BUS_OBJERR, sv);
        !           304:                KERNEL_PROC_UNLOCK(p);
        !           305:                goto out;
        !           306:        case T_ALIGNFLT|T_USER:
        !           307:                sv.sival_ptr = (void *)frame.tf_rip;
        !           308:                KERNEL_PROC_LOCK(p);
        !           309:                trapsignal(p, SIGBUS, type & ~T_USER, BUS_ADRALN, sv);
        !           310:                KERNEL_PROC_UNLOCK(p);
        !           311:                goto out;
        !           312:
        !           313:        case T_PRIVINFLT|T_USER:        /* privileged instruction fault */
        !           314:                sv.sival_ptr = (void *)frame.tf_rip;
        !           315:                KERNEL_PROC_LOCK(p);
        !           316:                trapsignal(p, SIGILL, type & ~T_USER, ILL_PRVOPC, sv);
        !           317:                KERNEL_PROC_UNLOCK(p);
        !           318:                goto out;
        !           319:        case T_FPOPFLT|T_USER:          /* coprocessor operand fault */
        !           320: #ifdef TRAP_SIGDEBUG
        !           321:                printf("pid %d (%s): ILL at rip %lx addr %lx\n",
        !           322:                    p->p_pid, p->p_comm, frame.tf_rip, rcr2());
        !           323:                frame_dump(&frame);
        !           324: #endif
        !           325:                sv.sival_ptr = (void *)frame.tf_rip;
        !           326:                KERNEL_PROC_LOCK(p);
        !           327:                trapsignal(p, SIGILL, type & ~T_USER, ILL_COPROC, sv);
        !           328:                KERNEL_PROC_UNLOCK(p);
        !           329:                goto out;
        !           330:
        !           331:        case T_ASTFLT|T_USER:           /* Allow process switch */
        !           332:                uvmexp.softs++;
        !           333:                if (p->p_flag & P_OWEUPC) {
        !           334:                        KERNEL_PROC_LOCK(p);
        !           335:                        ADDUPROF(p);
        !           336:                        KERNEL_PROC_UNLOCK(p);
        !           337:                }
        !           338:                /* Allow a forced task switch. */
        !           339:                if (curcpu()->ci_want_resched)
        !           340:                        preempt(NULL);
        !           341:                goto out;
        !           342:
        !           343:        case T_BOUND|T_USER:
        !           344:                sv.sival_ptr = (void *)frame.tf_rip;
        !           345:                KERNEL_PROC_LOCK(p);
        !           346:                trapsignal(p, SIGFPE, type &~ T_USER, FPE_FLTSUB, sv);
        !           347:                KERNEL_PROC_UNLOCK(p);
        !           348:                goto out;
        !           349:        case T_OFLOW|T_USER:
        !           350:                sv.sival_ptr = (void *)frame.tf_rip;
        !           351:                KERNEL_PROC_LOCK(p);
        !           352:                trapsignal(p, SIGFPE, type &~ T_USER, FPE_INTOVF, sv);
        !           353:                KERNEL_PROC_UNLOCK(p);
        !           354:                goto out;
        !           355:        case T_DIVIDE|T_USER:
        !           356:                sv.sival_ptr = (void *)frame.tf_rip;
        !           357:                KERNEL_PROC_LOCK(p);
        !           358:                trapsignal(p, SIGFPE, type &~ T_USER, FPE_INTDIV, sv);
        !           359:                KERNEL_PROC_UNLOCK(p);
        !           360:                goto out;
        !           361:
        !           362:        case T_ARITHTRAP|T_USER:
        !           363:        case T_XMM|T_USER:
        !           364:                fputrap(&frame);
        !           365:                goto out;
        !           366:
        !           367:        case T_PAGEFLT:                 /* allow page faults in kernel mode */
        !           368:                if (p == NULL)
        !           369:                        goto we_re_toast;
        !           370: #ifdef MULTIPROCESSOR
        !           371:                if ((p->p_flag & P_BIGLOCK) == 0)
        !           372:                        goto we_re_toast;
        !           373: #endif
        !           374:                cr2 = rcr2();
        !           375:                KERNEL_LOCK();
        !           376:                goto faultcommon;
        !           377:
        !           378:        case T_PAGEFLT|T_USER: {        /* page fault */
        !           379:                vaddr_t va, fa;
        !           380:                struct vmspace *vm;
        !           381:                struct vm_map *map;
        !           382:                vm_prot_t ftype;
        !           383:                extern struct vm_map *kernel_map;
        !           384:
        !           385:                cr2 = rcr2();
        !           386:                KERNEL_PROC_LOCK(p);
        !           387: faultcommon:
        !           388:                vm = p->p_vmspace;
        !           389:                if (vm == NULL)
        !           390:                        goto we_re_toast;
        !           391:                fa = cr2;
        !           392:                va = trunc_page((vaddr_t)cr2);
        !           393:                /*
        !           394:                 * It is only a kernel address space fault iff:
        !           395:                 *      1. (type & T_USER) == 0  and
        !           396:                 *      2. pcb_onfault not set or
        !           397:                 *      3. pcb_onfault set but supervisor space fault
        !           398:                 * The last can occur during an exec() copyin where the
        !           399:                 * argument space is lazy-allocated.
        !           400:                 */
        !           401:                if (type == T_PAGEFLT && va >= VM_MIN_KERNEL_ADDRESS)
        !           402:                        map = kernel_map;
        !           403:                else
        !           404:                        map = &vm->vm_map;
        !           405:                if (frame.tf_err & PGEX_W)
        !           406:                        ftype = VM_PROT_WRITE;
        !           407:                else if (frame.tf_err & PGEX_I)
        !           408:                        ftype = VM_PROT_EXECUTE;
        !           409:                else
        !           410:                        ftype = VM_PROT_READ;
        !           411:
        !           412: #ifdef DIAGNOSTIC
        !           413:                if (map == kernel_map && va == 0) {
        !           414:                        printf("trap: bad kernel access at %lx\n", va);
        !           415:                        goto we_re_toast;
        !           416:                }
        !           417: #endif
        !           418:
        !           419:                /* Fault the original page in. */
        !           420:                onfault = pcb->pcb_onfault;
        !           421:                pcb->pcb_onfault = NULL;
        !           422:                error = uvm_fault(map, va, frame.tf_err & PGEX_P?
        !           423:                    VM_FAULT_PROTECT : VM_FAULT_INVALID, ftype);
        !           424:                pcb->pcb_onfault = onfault;
        !           425:                if (error == 0) {
        !           426:                        if (map != kernel_map)
        !           427:                                uvm_grow(p, va);
        !           428:
        !           429:                        if (type == T_PAGEFLT) {
        !           430:                                KERNEL_UNLOCK();
        !           431:                                return;
        !           432:                        }
        !           433:                        KERNEL_PROC_UNLOCK(p);
        !           434:                        goto out;
        !           435:                }
        !           436:                if (error == EACCES) {
        !           437:                        error = EFAULT;
        !           438:                }
        !           439:
        !           440:                if (type == T_PAGEFLT) {
        !           441:                        if (pcb->pcb_onfault != 0) {
        !           442:                                KERNEL_UNLOCK();
        !           443:                                goto copyfault;
        !           444:                        }
        !           445:                        printf("uvm_fault(%p, 0x%lx, 0, %d) -> %x\n",
        !           446:                            map, va, ftype, error);
        !           447:                        goto we_re_toast;
        !           448:                }
        !           449:                if (error == ENOMEM) {
        !           450:                        printf("UVM: pid %d (%s), uid %d killed: out of swap\n",
        !           451:                               p->p_pid, p->p_comm,
        !           452:                               p->p_cred && p->p_ucred ?
        !           453:                               (int)p->p_ucred->cr_uid : -1);
        !           454:                        sv.sival_ptr = (void *)fa;
        !           455:                        trapsignal(p, SIGKILL, T_PAGEFLT, SEGV_MAPERR, sv);
        !           456:                } else {
        !           457: #ifdef TRAP_SIGDEBUG
        !           458:                        printf("pid %d (%s): SEGV at rip %lx addr %lx\n",
        !           459:                            p->p_pid, p->p_comm, frame.tf_rip, va);
        !           460:                        frame_dump(&frame);
        !           461: #endif
        !           462:                        sv.sival_ptr = (void *)fa;
        !           463:                        trapsignal(p, SIGSEGV, T_PAGEFLT, SEGV_MAPERR, sv);
        !           464:                }
        !           465:                if (type == T_PAGEFLT)
        !           466:                        KERNEL_UNLOCK();
        !           467:                else
        !           468:                        KERNEL_PROC_UNLOCK(p);
        !           469:                break;
        !           470:        }
        !           471:
        !           472:        case T_TRCTRAP:
        !           473:                /* Check whether they single-stepped into a lcall. */
        !           474:                if (frame.tf_rip == (int)IDTVEC(oosyscall))
        !           475:                        return;
        !           476:                if (frame.tf_rip == (int)IDTVEC(oosyscall) + 1) {
        !           477:                        frame.tf_rflags &= ~PSL_T;
        !           478:                        return;
        !           479:                }
        !           480:                goto we_re_toast;
        !           481:
        !           482:        case T_BPTFLT|T_USER:           /* bpt instruction fault */
        !           483:        case T_TRCTRAP|T_USER:          /* trace trap */
        !           484: #ifdef MATH_EMULATE
        !           485:        trace:
        !           486: #endif
        !           487:                KERNEL_PROC_LOCK(p);
        !           488:                trapsignal(p, SIGTRAP, type &~ T_USER, TRAP_BRKPT, sv);
        !           489:                KERNEL_PROC_UNLOCK(p);
        !           490:                break;
        !           491:
        !           492: #if    NISA > 0
        !           493:        case T_NMI:
        !           494: #if defined(KGDB) || defined(DDB)
        !           495:                /* NMI can be hooked up to a pushbutton for debugging */
        !           496:                printf ("NMI ... going to debugger\n");
        !           497: #ifdef KGDB
        !           498:
        !           499:                if (kgdb_trap(type, &frame))
        !           500:                        return;
        !           501: #endif
        !           502: #ifdef DDB
        !           503:                if (kdb_trap(type, 0, &frame))
        !           504:                        return;
        !           505: #endif
        !           506: #endif /* KGDB || DDB */
        !           507:                /* machine/parity/power fail/"kitchen sink" faults */
        !           508:
        !           509:                if (x86_nmi() != 0)
        !           510:                        goto we_re_toast;
        !           511:                else
        !           512:                        return;
        !           513: #endif /* NISA > 0 */
        !           514:        }
        !           515:
        !           516:        if ((type & T_USER) == 0)
        !           517:                return;
        !           518: out:
        !           519:        userret(p);
        !           520: }
        !           521:
        !           522: #ifdef TRAP_SIGDEBUG
        !           523: static void
        !           524: frame_dump(struct trapframe *tf)
        !           525: {
        !           526:        printf("rip %p  rsp %p  rfl %p\n",
        !           527:            (void *)tf->tf_rip, (void *)tf->tf_rsp, (void *)tf->tf_rflags);
        !           528:        printf("rdi %p  rsi %p  rdx %p\n",
        !           529:            (void *)tf->tf_rdi, (void *)tf->tf_rsi, (void *)tf->tf_rdx);
        !           530:        printf("rcx %p  r8  %p  r9  %p\n",
        !           531:            (void *)tf->tf_rcx, (void *)tf->tf_r8, (void *)tf->tf_r9);
        !           532:        printf("r10 %p  r11 %p  r12 %p\n",
        !           533:            (void *)tf->tf_r10, (void *)tf->tf_r11, (void *)tf->tf_r12);
        !           534:        printf("r13 %p  r14 %p  r15 %p\n",
        !           535:            (void *)tf->tf_r13, (void *)tf->tf_r14, (void *)tf->tf_r15);
        !           536:        printf("rbp %p  rbx %p  rax %p\n",
        !           537:            (void *)tf->tf_rbp, (void *)tf->tf_rbx, (void *)tf->tf_rax);
        !           538: }
        !           539: #endif

CVSweb