[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

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