10Sstevel@tonic-gate/* 23446Smrj * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 30Sstevel@tonic-gate * Use is subject to license terms. 40Sstevel@tonic-gate */ 50Sstevel@tonic-gate 60Sstevel@tonic-gate/* 70Sstevel@tonic-gate * Copyright (c) 1989, 1990 William F. Jolitz. 80Sstevel@tonic-gate * Copyright (c) 1990 The Regents of the University of California. 90Sstevel@tonic-gate * All rights reserved. 100Sstevel@tonic-gate * 110Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without 120Sstevel@tonic-gate * modification, are permitted provided that the following conditions 130Sstevel@tonic-gate * are met: 140Sstevel@tonic-gate * 1. Redistributions of source code must retain the above copyright 150Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer. 160Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright 170Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in the 180Sstevel@tonic-gate * documentation and/or other materials provided with the distribution. 190Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this software 200Sstevel@tonic-gate * must display the following acknowledgement: 210Sstevel@tonic-gate * This product includes software developed by the University of 220Sstevel@tonic-gate * California, Berkeley and its contributors. 230Sstevel@tonic-gate * 4. Neither the name of the University nor the names of its contributors 240Sstevel@tonic-gate * may be used to endorse or promote products derived from this software 250Sstevel@tonic-gate * without specific prior written permission. 260Sstevel@tonic-gate * 270Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 280Sstevel@tonic-gate * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 290Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 300Sstevel@tonic-gate * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 310Sstevel@tonic-gate * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 320Sstevel@tonic-gate * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 330Sstevel@tonic-gate * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 340Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 350Sstevel@tonic-gate * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 360Sstevel@tonic-gate * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 370Sstevel@tonic-gate * SUCH DAMAGE. 380Sstevel@tonic-gate * 390Sstevel@tonic-gate * $FreeBSD: src/sys/amd64/amd64/exception.S,v 1.113 2003/10/15 02:04:52 peter Exp $ 400Sstevel@tonic-gate */ 410Sstevel@tonic-gate 420Sstevel@tonic-gate#pragma ident "%Z%%M% %I% %E% SMI" 430Sstevel@tonic-gate 440Sstevel@tonic-gate#include <sys/asm_linkage.h> 450Sstevel@tonic-gate#include <sys/asm_misc.h> 460Sstevel@tonic-gate#include <sys/trap.h> 470Sstevel@tonic-gate#include <sys/psw.h> 480Sstevel@tonic-gate#include <sys/regset.h> 490Sstevel@tonic-gate#include <sys/privregs.h> 500Sstevel@tonic-gate#include <sys/dtrace.h> 513446Smrj#include <sys/x86_archext.h> 520Sstevel@tonic-gate#include <sys/traptrace.h> 532006Sandrei#include <sys/machparam.h> 540Sstevel@tonic-gate 550Sstevel@tonic-gate/* 560Sstevel@tonic-gate * only one routine in this file is interesting to lint 570Sstevel@tonic-gate */ 580Sstevel@tonic-gate 590Sstevel@tonic-gate#if defined(__lint) 600Sstevel@tonic-gate 610Sstevel@tonic-gatevoid 620Sstevel@tonic-gatendptrap_frstor(void) 630Sstevel@tonic-gate{} 640Sstevel@tonic-gate 650Sstevel@tonic-gate#else 660Sstevel@tonic-gate 670Sstevel@tonic-gate#include "assym.h" 680Sstevel@tonic-gate 690Sstevel@tonic-gate/* 700Sstevel@tonic-gate * push $0 on stack for traps that do not 710Sstevel@tonic-gate * generate an error code. This is so the rest 720Sstevel@tonic-gate * of the kernel can expect a consistent stack 730Sstevel@tonic-gate * from from any exception. 740Sstevel@tonic-gate */ 753446Smrj 760Sstevel@tonic-gate#define TRAP_NOERR(trapno) \ 770Sstevel@tonic-gate push $0; \ 780Sstevel@tonic-gate push $trapno 790Sstevel@tonic-gate 803446Smrj#define NPTRAP_NOERR(trapno) TRAP_NOERR(trapno) 813446Smrj 820Sstevel@tonic-gate/* 830Sstevel@tonic-gate * error code already pushed by hw 840Sstevel@tonic-gate * onto stack. 850Sstevel@tonic-gate */ 860Sstevel@tonic-gate#define TRAP_ERR(trapno) \ 870Sstevel@tonic-gate push $trapno 880Sstevel@tonic-gate 893446Smrj 900Sstevel@tonic-gate /* 910Sstevel@tonic-gate * #DE 920Sstevel@tonic-gate */ 930Sstevel@tonic-gate ENTRY_NP(div0trap) 940Sstevel@tonic-gate TRAP_NOERR(T_ZERODIV) /* $0 */ 950Sstevel@tonic-gate jmp cmntrap 960Sstevel@tonic-gate SET_SIZE(div0trap) 970Sstevel@tonic-gate 980Sstevel@tonic-gate /* 990Sstevel@tonic-gate * #DB 1000Sstevel@tonic-gate * 1013446Smrj * Fetch %dr6 and clear it, handing off the value to the 1023446Smrj * cmntrap code in %r15/%esi 1033446Smrj */ 1043446Smrj ENTRY_NP(dbgtrap) 1053446Smrj TRAP_NOERR(T_SGLSTP) /* $1 */ 1063446Smrj 1073446Smrj#if defined(__amd64) 1083446Smrj /* 1090Sstevel@tonic-gate * If we get here as a result of single-stepping a sysenter 1100Sstevel@tonic-gate * instruction, we suddenly find ourselves taking a #db 1110Sstevel@tonic-gate * in kernel mode -before- we've swapgs'ed. So before we can 1120Sstevel@tonic-gate * take the trap, we do the swapgs here, and fix the return 1130Sstevel@tonic-gate * %rip in trap() so that we return immediately after the 1140Sstevel@tonic-gate * swapgs in the sysenter handler to avoid doing the swapgs again. 1150Sstevel@tonic-gate * 1160Sstevel@tonic-gate * Nobody said that the design of sysenter was particularly 1170Sstevel@tonic-gate * elegant, did they? 1180Sstevel@tonic-gate */ 119*4257Ssherrym 1200Sstevel@tonic-gate pushq %r11 121*4257Ssherrym 122*4257Ssherrym /* 123*4257Ssherrym * At this point the stack looks like this: 124*4257Ssherrym * 125*4257Ssherrym * (high address) r_ss 126*4257Ssherrym * r_rsp 127*4257Ssherrym * r_rfl 128*4257Ssherrym * r_cs 129*4257Ssherrym * r_rip <-- %rsp + 24 130*4257Ssherrym * r_err <-- %rsp + 16 131*4257Ssherrym * r_trapno <-- %rsp + 8 132*4257Ssherrym * (low address) %r11 <-- %rsp 133*4257Ssherrym */ 1340Sstevel@tonic-gate leaq sys_sysenter(%rip), %r11 135*4257Ssherrym cmpq %r11, 24(%rsp) /* Compare to saved r_rip on the stack */ 1360Sstevel@tonic-gate jne 1f 1373446Smrj SWAPGS 1380Sstevel@tonic-gate1: popq %r11 1393446Smrj 1403446Smrj INTR_PUSH 1413446Smrj movq %db6, %r15 1423446Smrj xorl %eax, %eax 1433446Smrj movq %rax, %db6 1440Sstevel@tonic-gate 1450Sstevel@tonic-gate#elif defined(__i386) 1463446Smrj 1473446Smrj INTR_PUSH 1483446Smrj movl %db6, %esi 1493446Smrj xorl %eax, %eax 1503446Smrj movl %eax, %db6 1513446Smrj#endif /* __i386 */ 1523446Smrj 1533446Smrj jmp cmntrap_pushed 1540Sstevel@tonic-gate SET_SIZE(dbgtrap) 1550Sstevel@tonic-gate 1560Sstevel@tonic-gate#if defined(__amd64) 1570Sstevel@tonic-gate 1580Sstevel@tonic-gate/* 1590Sstevel@tonic-gate * Macro to set the gsbase or kgsbase to the address of the struct cpu 1603446Smrj * for this processor. If we came from userland, set kgsbase else 1613446Smrj * set gsbase. We find the proper cpu struct by looping through 1620Sstevel@tonic-gate * the cpu structs for all processors till we find a match for the gdt 1630Sstevel@tonic-gate * of the trapping processor. The stack is expected to be pointing at 1643446Smrj * the standard regs pushed by hardware on a trap (plus error code and trapno). 1650Sstevel@tonic-gate */ 1660Sstevel@tonic-gate#define SET_CPU_GSBASE \ 1670Sstevel@tonic-gate subq $REGOFF_TRAPNO, %rsp; /* save regs */ \ 1680Sstevel@tonic-gate movq %rax, REGOFF_RAX(%rsp); \ 1690Sstevel@tonic-gate movq %rbx, REGOFF_RBX(%rsp); \ 1700Sstevel@tonic-gate movq %rcx, REGOFF_RCX(%rsp); \ 1710Sstevel@tonic-gate movq %rdx, REGOFF_RDX(%rsp); \ 1720Sstevel@tonic-gate movq %rbp, REGOFF_RBP(%rsp); \ 1730Sstevel@tonic-gate movq %rsp, %rbp; \ 1740Sstevel@tonic-gate subq $16, %rsp; /* space for gdt */ \ 1750Sstevel@tonic-gate sgdt 6(%rsp); \ 1760Sstevel@tonic-gate movq 8(%rsp), %rcx; /* %rcx has gdt to match */ \ 1770Sstevel@tonic-gate xorl %ebx, %ebx; /* loop index */ \ 1780Sstevel@tonic-gate leaq cpu(%rip), %rdx; /* cpu pointer array */ \ 1790Sstevel@tonic-gate1: \ 1800Sstevel@tonic-gate movq (%rdx, %rbx, CLONGSIZE), %rax; /* get cpu[i] */ \ 1810Sstevel@tonic-gate cmpq $0x0, %rax; /* cpu[i] == NULL ? */ \ 1820Sstevel@tonic-gate je 2f; /* yes, continue */ \ 1830Sstevel@tonic-gate cmpq %rcx, CPU_GDT(%rax); /* gdt == cpu[i]->cpu_gdt ? */ \ 1840Sstevel@tonic-gate je 3f; /* yes, go set gsbase */ \ 1850Sstevel@tonic-gate2: \ 1860Sstevel@tonic-gate incl %ebx; /* i++ */ \ 1870Sstevel@tonic-gate cmpl $NCPU, %ebx; /* i < NCPU ? */ \ 1880Sstevel@tonic-gate jb 1b; /* yes, loop */ \ 1890Sstevel@tonic-gate/* XXX BIG trouble if we fall thru here. We didn't find a gdt match */ \ 1900Sstevel@tonic-gate3: \ 1910Sstevel@tonic-gate movl $MSR_AMD_KGSBASE, %ecx; \ 1920Sstevel@tonic-gate cmpw $KCS_SEL, REGOFF_CS(%rbp); /* trap from kernel? */ \ 1930Sstevel@tonic-gate jne 4f; /* no, go set KGSBASE */ \ 1940Sstevel@tonic-gate movl $MSR_AMD_GSBASE, %ecx; /* yes, set GSBASE */ \ 1950Sstevel@tonic-gate mfence; /* OPTERON_ERRATUM_88 */ \ 1960Sstevel@tonic-gate4: \ 1970Sstevel@tonic-gate movq %rax, %rdx; /* write base register */ \ 1980Sstevel@tonic-gate shrq $32, %rdx; \ 1990Sstevel@tonic-gate wrmsr; \ 2000Sstevel@tonic-gate movq REGOFF_RDX(%rbp), %rdx; /* restore regs */ \ 2010Sstevel@tonic-gate movq REGOFF_RCX(%rbp), %rcx; \ 2020Sstevel@tonic-gate movq REGOFF_RBX(%rbp), %rbx; \ 2030Sstevel@tonic-gate movq REGOFF_RAX(%rbp), %rax; \ 2040Sstevel@tonic-gate movq %rbp, %rsp; \ 2050Sstevel@tonic-gate movq REGOFF_RBP(%rsp), %rbp; \ 2060Sstevel@tonic-gate addq $REGOFF_TRAPNO, %rsp /* pop stack */ 2073446Smrj 2080Sstevel@tonic-gate#endif /* __amd64 */ 2093446Smrj 2100Sstevel@tonic-gate 2110Sstevel@tonic-gate#if defined(__amd64) 2120Sstevel@tonic-gate 2130Sstevel@tonic-gate /* 2140Sstevel@tonic-gate * #NMI 2150Sstevel@tonic-gate */ 2160Sstevel@tonic-gate ENTRY_NP(nmiint) 2170Sstevel@tonic-gate TRAP_NOERR(T_NMIFLT) /* $2 */ 2180Sstevel@tonic-gate 2190Sstevel@tonic-gate SET_CPU_GSBASE 2200Sstevel@tonic-gate 2210Sstevel@tonic-gate /* 2220Sstevel@tonic-gate * Save all registers and setup segment registers 2230Sstevel@tonic-gate * with kernel selectors. 2240Sstevel@tonic-gate */ 2250Sstevel@tonic-gate INTR_PUSH 2263446Smrj INTGATE_INIT_KERNEL_FLAGS 2270Sstevel@tonic-gate 2280Sstevel@tonic-gate TRACE_PTR(%r12, %rax, %eax, %rdx, $TT_TRAP) 2290Sstevel@tonic-gate TRACE_REGS(%r12, %rsp, %rax, %rbx) 2300Sstevel@tonic-gate TRACE_STAMP(%r12) 2310Sstevel@tonic-gate 2320Sstevel@tonic-gate movq %rsp, %rbp 2330Sstevel@tonic-gate 2340Sstevel@tonic-gate movq %rbp, %rdi 2350Sstevel@tonic-gate call av_dispatch_nmivect 2360Sstevel@tonic-gate 2370Sstevel@tonic-gate INTR_POP 2383446Smrj IRET 2393446Smrj /*NOTREACHED*/ 2400Sstevel@tonic-gate SET_SIZE(nmiint) 2410Sstevel@tonic-gate 2420Sstevel@tonic-gate#elif defined(__i386) 2430Sstevel@tonic-gate 2440Sstevel@tonic-gate /* 2450Sstevel@tonic-gate * #NMI 2460Sstevel@tonic-gate */ 2470Sstevel@tonic-gate ENTRY_NP(nmiint) 2480Sstevel@tonic-gate TRAP_NOERR(T_NMIFLT) /* $2 */ 2490Sstevel@tonic-gate 2500Sstevel@tonic-gate /* 2510Sstevel@tonic-gate * Save all registers and setup segment registers 2520Sstevel@tonic-gate * with kernel selectors. 2530Sstevel@tonic-gate */ 2540Sstevel@tonic-gate INTR_PUSH 2553446Smrj INTGATE_INIT_KERNEL_FLAGS 2560Sstevel@tonic-gate 2573446Smrj TRACE_PTR(%edi, %ebx, %ebx, %ecx, $TT_TRAP) 2583446Smrj TRACE_REGS(%edi, %esp, %ebx, %ecx) 2593446Smrj TRACE_STAMP(%edi) 2600Sstevel@tonic-gate 2613446Smrj movl %esp, %ebp 2623446Smrj 2633446Smrj pushl %ebp 2643446Smrj call av_dispatch_nmivect 2650Sstevel@tonic-gate addl $4, %esp 2660Sstevel@tonic-gate 2670Sstevel@tonic-gate INTR_POP_USER 2683446Smrj IRET 2690Sstevel@tonic-gate SET_SIZE(nmiint) 2700Sstevel@tonic-gate 2710Sstevel@tonic-gate#endif /* __i386 */ 2720Sstevel@tonic-gate 2730Sstevel@tonic-gate /* 2740Sstevel@tonic-gate * #BP 2750Sstevel@tonic-gate */ 2760Sstevel@tonic-gate ENTRY_NP(brktrap) 2773446Smrj 2780Sstevel@tonic-gate#if defined(__amd64) 2790Sstevel@tonic-gate cmpw $KCS_SEL, 8(%rsp) 2803446Smrj jne bp_user 2810Sstevel@tonic-gate 2820Sstevel@tonic-gate /* 2830Sstevel@tonic-gate * This is a breakpoint in the kernel -- it is very likely that this 2840Sstevel@tonic-gate * is DTrace-induced. To unify DTrace handling, we spoof this as an 2850Sstevel@tonic-gate * invalid opcode (#UD) fault. Note that #BP is a trap, not a fault -- 2860Sstevel@tonic-gate * we must decrement the trapping %rip to make it appear as a fault. 2870Sstevel@tonic-gate * We then push a non-zero error code to indicate that this is coming 2880Sstevel@tonic-gate * from #BP. 2890Sstevel@tonic-gate */ 2900Sstevel@tonic-gate decq (%rsp) 2910Sstevel@tonic-gate push $1 /* error code -- non-zero for #BP */ 2920Sstevel@tonic-gate jmp ud_kernel 2933446Smrj 2943446Smrjbp_user: 2953446Smrj#endif /* __amd64 */ 2963446Smrj 2973446Smrj NPTRAP_NOERR(T_BPTFLT) /* $3 */ 2983446Smrj jmp dtrace_trap 2993446Smrj 3000Sstevel@tonic-gate SET_SIZE(brktrap) 3010Sstevel@tonic-gate 3020Sstevel@tonic-gate /* 3030Sstevel@tonic-gate * #OF 3040Sstevel@tonic-gate */ 3050Sstevel@tonic-gate ENTRY_NP(ovflotrap) 3060Sstevel@tonic-gate TRAP_NOERR(T_OVFLW) /* $4 */ 3070Sstevel@tonic-gate jmp cmntrap 3080Sstevel@tonic-gate SET_SIZE(ovflotrap) 3090Sstevel@tonic-gate 3100Sstevel@tonic-gate /* 3110Sstevel@tonic-gate * #BR 3120Sstevel@tonic-gate */ 3130Sstevel@tonic-gate ENTRY_NP(boundstrap) 3140Sstevel@tonic-gate TRAP_NOERR(T_BOUNDFLT) /* $5 */ 3150Sstevel@tonic-gate jmp cmntrap 3160Sstevel@tonic-gate SET_SIZE(boundstrap) 3170Sstevel@tonic-gate 3180Sstevel@tonic-gate#if defined(__amd64) 3190Sstevel@tonic-gate 3200Sstevel@tonic-gate ENTRY_NP(invoptrap) 3213446Smrj 3220Sstevel@tonic-gate cmpw $KCS_SEL, 8(%rsp) 3230Sstevel@tonic-gate jne ud_user 3240Sstevel@tonic-gate 3250Sstevel@tonic-gate push $0 /* error code -- zero for #UD */ 3260Sstevel@tonic-gateud_kernel: 3270Sstevel@tonic-gate push $0xdddd /* a dummy trap number */ 3283446Smrj INTR_PUSH 3290Sstevel@tonic-gate movq REGOFF_RIP(%rsp), %rdi 3300Sstevel@tonic-gate movq REGOFF_RSP(%rsp), %rsi 3310Sstevel@tonic-gate movq REGOFF_RAX(%rsp), %rdx 3320Sstevel@tonic-gate pushq (%rsi) 3330Sstevel@tonic-gate movq %rsp, %rsi 3340Sstevel@tonic-gate call dtrace_invop 3350Sstevel@tonic-gate ALTENTRY(dtrace_invop_callsite) 3360Sstevel@tonic-gate addq $8, %rsp 3370Sstevel@tonic-gate cmpl $DTRACE_INVOP_PUSHL_EBP, %eax 3380Sstevel@tonic-gate je ud_push 3390Sstevel@tonic-gate cmpl $DTRACE_INVOP_LEAVE, %eax 3400Sstevel@tonic-gate je ud_leave 3410Sstevel@tonic-gate cmpl $DTRACE_INVOP_NOP, %eax 3420Sstevel@tonic-gate je ud_nop 3430Sstevel@tonic-gate cmpl $DTRACE_INVOP_RET, %eax 3440Sstevel@tonic-gate je ud_ret 3450Sstevel@tonic-gate jmp ud_trap 3460Sstevel@tonic-gate 3470Sstevel@tonic-gateud_push: 3480Sstevel@tonic-gate /* 3490Sstevel@tonic-gate * We must emulate a "pushq %rbp". To do this, we pull the stack 3500Sstevel@tonic-gate * down 8 bytes, and then store the base pointer. 3510Sstevel@tonic-gate */ 3520Sstevel@tonic-gate INTR_POP 3530Sstevel@tonic-gate subq $16, %rsp /* make room for %rbp */ 3540Sstevel@tonic-gate pushq %rax /* push temp */ 3550Sstevel@tonic-gate movq 24(%rsp), %rax /* load calling RIP */ 3560Sstevel@tonic-gate addq $1, %rax /* increment over trapping instr */ 3570Sstevel@tonic-gate movq %rax, 8(%rsp) /* store calling RIP */ 3580Sstevel@tonic-gate movq 32(%rsp), %rax /* load calling CS */ 3590Sstevel@tonic-gate movq %rax, 16(%rsp) /* store calling CS */ 3600Sstevel@tonic-gate movq 40(%rsp), %rax /* load calling RFLAGS */ 3610Sstevel@tonic-gate movq %rax, 24(%rsp) /* store calling RFLAGS */ 3620Sstevel@tonic-gate movq 48(%rsp), %rax /* load calling RSP */ 3630Sstevel@tonic-gate subq $8, %rax /* make room for %rbp */ 3640Sstevel@tonic-gate movq %rax, 32(%rsp) /* store calling RSP */ 3650Sstevel@tonic-gate movq 56(%rsp), %rax /* load calling SS */ 3660Sstevel@tonic-gate movq %rax, 40(%rsp) /* store calling SS */ 3670Sstevel@tonic-gate movq 32(%rsp), %rax /* reload calling RSP */ 3680Sstevel@tonic-gate movq %rbp, (%rax) /* store %rbp there */ 3690Sstevel@tonic-gate popq %rax /* pop off temp */ 3703446Smrj IRET /* return from interrupt */ 3713446Smrj /*NOTREACHED*/ 3720Sstevel@tonic-gate 3730Sstevel@tonic-gateud_leave: 3740Sstevel@tonic-gate /* 3750Sstevel@tonic-gate * We must emulate a "leave", which is the same as a "movq %rbp, %rsp" 3760Sstevel@tonic-gate * followed by a "popq %rbp". This is quite a bit simpler on amd64 3770Sstevel@tonic-gate * than it is on i386 -- we can exploit the fact that the %rsp is 3780Sstevel@tonic-gate * explicitly saved to effect the pop without having to reshuffle 3790Sstevel@tonic-gate * the other data pushed for the trap. 3800Sstevel@tonic-gate */ 3810Sstevel@tonic-gate INTR_POP 3820Sstevel@tonic-gate pushq %rax /* push temp */ 3830Sstevel@tonic-gate movq 8(%rsp), %rax /* load calling RIP */ 3840Sstevel@tonic-gate addq $1, %rax /* increment over trapping instr */ 3850Sstevel@tonic-gate movq %rax, 8(%rsp) /* store calling RIP */ 3860Sstevel@tonic-gate movq (%rbp), %rax /* get new %rbp */ 3870Sstevel@tonic-gate addq $8, %rbp /* adjust new %rsp */ 3880Sstevel@tonic-gate movq %rbp, 32(%rsp) /* store new %rsp */ 3890Sstevel@tonic-gate movq %rax, %rbp /* set new %rbp */ 3900Sstevel@tonic-gate popq %rax /* pop off temp */ 3913446Smrj IRET /* return from interrupt */ 3923446Smrj /*NOTREACHED*/ 3930Sstevel@tonic-gate 3940Sstevel@tonic-gateud_nop: 3950Sstevel@tonic-gate /* 3960Sstevel@tonic-gate * We must emulate a "nop". This is obviously not hard: we need only 3970Sstevel@tonic-gate * advance the %rip by one. 3980Sstevel@tonic-gate */ 3990Sstevel@tonic-gate INTR_POP 4000Sstevel@tonic-gate incq (%rsp) 4013446Smrj IRET 4023446Smrj /*NOTREACHED*/ 4030Sstevel@tonic-gate 4040Sstevel@tonic-gateud_ret: 4050Sstevel@tonic-gate INTR_POP 4060Sstevel@tonic-gate pushq %rax /* push temp */ 4070Sstevel@tonic-gate movq 32(%rsp), %rax /* load %rsp */ 4080Sstevel@tonic-gate movq (%rax), %rax /* load calling RIP */ 4090Sstevel@tonic-gate movq %rax, 8(%rsp) /* store calling RIP */ 4100Sstevel@tonic-gate addq $8, 32(%rsp) /* adjust new %rsp */ 4110Sstevel@tonic-gate popq %rax /* pop off temp */ 4123446Smrj IRET /* return from interrupt */ 4133446Smrj /*NOTREACHED*/ 4140Sstevel@tonic-gate 4150Sstevel@tonic-gateud_trap: 4160Sstevel@tonic-gate /* 4170Sstevel@tonic-gate * We're going to let the kernel handle this as a normal #UD. If, 4180Sstevel@tonic-gate * however, we came through #BP and are spoofing #UD (in this case, 4190Sstevel@tonic-gate * the stored error value will be non-zero), we need to de-spoof 4200Sstevel@tonic-gate * the trap by incrementing %rip and pushing T_BPTFLT. 4210Sstevel@tonic-gate */ 4220Sstevel@tonic-gate cmpq $0, REGOFF_ERR(%rsp) 4230Sstevel@tonic-gate je ud_ud 4240Sstevel@tonic-gate incq REGOFF_RIP(%rsp) 4250Sstevel@tonic-gate addq $REGOFF_RIP, %rsp 4263446Smrj NPTRAP_NOERR(T_BPTFLT) /* $3 */ 4270Sstevel@tonic-gate jmp cmntrap 4280Sstevel@tonic-gate 4290Sstevel@tonic-gateud_ud: 4300Sstevel@tonic-gate addq $REGOFF_RIP, %rsp 4310Sstevel@tonic-gateud_user: 4323446Smrj NPTRAP_NOERR(T_ILLINST) 4330Sstevel@tonic-gate jmp cmntrap 4340Sstevel@tonic-gate SET_SIZE(invoptrap) 4350Sstevel@tonic-gate 4360Sstevel@tonic-gate#elif defined(__i386) 4370Sstevel@tonic-gate 4380Sstevel@tonic-gate /* 4390Sstevel@tonic-gate * #UD 4400Sstevel@tonic-gate */ 4410Sstevel@tonic-gate ENTRY_NP(invoptrap) 4420Sstevel@tonic-gate /* 4430Sstevel@tonic-gate * If we are taking an invalid opcode trap while in the kernel, this 4440Sstevel@tonic-gate * is likely an FBT probe point. 4450Sstevel@tonic-gate */ 4460Sstevel@tonic-gate pushl %gs 4470Sstevel@tonic-gate cmpw $KGS_SEL, (%esp) 4480Sstevel@tonic-gate jne 8f 4493446Smrj 4500Sstevel@tonic-gate addl $4, %esp 4510Sstevel@tonic-gate pusha 4520Sstevel@tonic-gate pushl %eax /* push %eax -- may be return value */ 4530Sstevel@tonic-gate pushl %esp /* push stack pointer */ 4540Sstevel@tonic-gate addl $48, (%esp) /* adjust to incoming args */ 4550Sstevel@tonic-gate pushl 40(%esp) /* push calling EIP */ 4560Sstevel@tonic-gate call dtrace_invop 4570Sstevel@tonic-gate ALTENTRY(dtrace_invop_callsite) 4580Sstevel@tonic-gate addl $12, %esp 4590Sstevel@tonic-gate cmpl $DTRACE_INVOP_PUSHL_EBP, %eax 4600Sstevel@tonic-gate je 1f 4610Sstevel@tonic-gate cmpl $DTRACE_INVOP_POPL_EBP, %eax 4620Sstevel@tonic-gate je 2f 4630Sstevel@tonic-gate cmpl $DTRACE_INVOP_LEAVE, %eax 4640Sstevel@tonic-gate je 3f 4650Sstevel@tonic-gate cmpl $DTRACE_INVOP_NOP, %eax 4660Sstevel@tonic-gate je 4f 4670Sstevel@tonic-gate jmp 7f 4680Sstevel@tonic-gate1: 4690Sstevel@tonic-gate /* 4700Sstevel@tonic-gate * We must emulate a "pushl %ebp". To do this, we pull the stack 4710Sstevel@tonic-gate * down 4 bytes, and then store the base pointer. 4720Sstevel@tonic-gate */ 4730Sstevel@tonic-gate popa 4740Sstevel@tonic-gate subl $4, %esp /* make room for %ebp */ 4750Sstevel@tonic-gate pushl %eax /* push temp */ 4760Sstevel@tonic-gate movl 8(%esp), %eax /* load calling EIP */ 4770Sstevel@tonic-gate incl %eax /* increment over LOCK prefix */ 4780Sstevel@tonic-gate movl %eax, 4(%esp) /* store calling EIP */ 4790Sstevel@tonic-gate movl 12(%esp), %eax /* load calling CS */ 4800Sstevel@tonic-gate movl %eax, 8(%esp) /* store calling CS */ 4810Sstevel@tonic-gate movl 16(%esp), %eax /* load calling EFLAGS */ 4820Sstevel@tonic-gate movl %eax, 12(%esp) /* store calling EFLAGS */ 4830Sstevel@tonic-gate movl %ebp, 16(%esp) /* push %ebp */ 4840Sstevel@tonic-gate popl %eax /* pop off temp */ 4853446Smrj jmp _emul_done 4860Sstevel@tonic-gate2: 4870Sstevel@tonic-gate /* 4880Sstevel@tonic-gate * We must emulate a "popl %ebp". To do this, we do the opposite of 4890Sstevel@tonic-gate * the above: we remove the %ebp from the stack, and squeeze up the 4900Sstevel@tonic-gate * saved state from the trap. 4910Sstevel@tonic-gate */ 4920Sstevel@tonic-gate popa 4930Sstevel@tonic-gate pushl %eax /* push temp */ 4940Sstevel@tonic-gate movl 16(%esp), %ebp /* pop %ebp */ 4950Sstevel@tonic-gate movl 12(%esp), %eax /* load calling EFLAGS */ 4960Sstevel@tonic-gate movl %eax, 16(%esp) /* store calling EFLAGS */ 4970Sstevel@tonic-gate movl 8(%esp), %eax /* load calling CS */ 4980Sstevel@tonic-gate movl %eax, 12(%esp) /* store calling CS */ 4990Sstevel@tonic-gate movl 4(%esp), %eax /* load calling EIP */ 5000Sstevel@tonic-gate incl %eax /* increment over LOCK prefix */ 5010Sstevel@tonic-gate movl %eax, 8(%esp) /* store calling EIP */ 5020Sstevel@tonic-gate popl %eax /* pop off temp */ 5030Sstevel@tonic-gate addl $4, %esp /* adjust stack pointer */ 5043446Smrj jmp _emul_done 5050Sstevel@tonic-gate3: 5060Sstevel@tonic-gate /* 5070Sstevel@tonic-gate * We must emulate a "leave", which is the same as a "movl %ebp, %esp" 5080Sstevel@tonic-gate * followed by a "popl %ebp". This looks similar to the above, but 5090Sstevel@tonic-gate * requires two temporaries: one for the new base pointer, and one 5100Sstevel@tonic-gate * for the staging register. 5110Sstevel@tonic-gate */ 5120Sstevel@tonic-gate popa 5130Sstevel@tonic-gate pushl %eax /* push temp */ 5140Sstevel@tonic-gate pushl %ebx /* push temp */ 5150Sstevel@tonic-gate movl %ebp, %ebx /* set temp to old %ebp */ 5160Sstevel@tonic-gate movl (%ebx), %ebp /* pop %ebp */ 5170Sstevel@tonic-gate movl 16(%esp), %eax /* load calling EFLAGS */ 5180Sstevel@tonic-gate movl %eax, (%ebx) /* store calling EFLAGS */ 5190Sstevel@tonic-gate movl 12(%esp), %eax /* load calling CS */ 5200Sstevel@tonic-gate movl %eax, -4(%ebx) /* store calling CS */ 5210Sstevel@tonic-gate movl 8(%esp), %eax /* load calling EIP */ 5220Sstevel@tonic-gate incl %eax /* increment over LOCK prefix */ 5230Sstevel@tonic-gate movl %eax, -8(%ebx) /* store calling EIP */ 5240Sstevel@tonic-gate movl %ebx, -4(%esp) /* temporarily store new %esp */ 5250Sstevel@tonic-gate popl %ebx /* pop off temp */ 5260Sstevel@tonic-gate popl %eax /* pop off temp */ 5270Sstevel@tonic-gate movl -12(%esp), %esp /* set stack pointer */ 5280Sstevel@tonic-gate subl $8, %esp /* adjust for three pushes, one pop */ 5293446Smrj jmp _emul_done 5300Sstevel@tonic-gate4: 5310Sstevel@tonic-gate /* 5320Sstevel@tonic-gate * We must emulate a "nop". This is obviously not hard: we need only 5330Sstevel@tonic-gate * advance the %eip by one. 5340Sstevel@tonic-gate */ 5350Sstevel@tonic-gate popa 5360Sstevel@tonic-gate incl (%esp) 5373446Smrj_emul_done: 5383446Smrj IRET /* return from interrupt */ 5390Sstevel@tonic-gate7: 5400Sstevel@tonic-gate popa 5410Sstevel@tonic-gate pushl $0 5420Sstevel@tonic-gate pushl $T_ILLINST /* $6 */ 5430Sstevel@tonic-gate jmp cmntrap 5440Sstevel@tonic-gate8: 5450Sstevel@tonic-gate addl $4, %esp 5460Sstevel@tonic-gate pushl $0 5470Sstevel@tonic-gate pushl $T_ILLINST /* $6 */ 5480Sstevel@tonic-gate jmp cmntrap 5490Sstevel@tonic-gate SET_SIZE(invoptrap) 5500Sstevel@tonic-gate 5510Sstevel@tonic-gate#endif /* __i386 */ 5520Sstevel@tonic-gate 5530Sstevel@tonic-gate#if defined(__amd64) 5540Sstevel@tonic-gate 5550Sstevel@tonic-gate /* 5560Sstevel@tonic-gate * #NM 5570Sstevel@tonic-gate */ 5580Sstevel@tonic-gate ENTRY_NP(ndptrap) 5590Sstevel@tonic-gate /* 5600Sstevel@tonic-gate * We want to do this quickly as every lwp using fp will take this 5610Sstevel@tonic-gate * after a context switch -- we do the frequent path in ndptrap_frstor 5620Sstevel@tonic-gate * below; for all other cases, we let the trap code handle it 5630Sstevel@tonic-gate */ 5640Sstevel@tonic-gate pushq %rax 5650Sstevel@tonic-gate pushq %rbx 5660Sstevel@tonic-gate cmpw $KCS_SEL, 24(%rsp) /* did we come from kernel mode? */ 5670Sstevel@tonic-gate jne 1f 5680Sstevel@tonic-gate LOADCPU(%rbx) /* if yes, don't swapgs */ 5690Sstevel@tonic-gate jmp 2f 5700Sstevel@tonic-gate1: 5713446Smrj SWAPGS /* if from user, need swapgs */ 5720Sstevel@tonic-gate LOADCPU(%rbx) 5733446Smrj SWAPGS 5740Sstevel@tonic-gate2: 5750Sstevel@tonic-gate cmpl $0, fpu_exists(%rip) 5760Sstevel@tonic-gate je .handle_in_trap /* let trap handle no fp case */ 5770Sstevel@tonic-gate movq CPU_THREAD(%rbx), %rax /* %rax = curthread */ 5780Sstevel@tonic-gate movl $FPU_EN, %ebx 5790Sstevel@tonic-gate movq T_LWP(%rax), %rax /* %rax = lwp */ 5800Sstevel@tonic-gate testq %rax, %rax 5810Sstevel@tonic-gate jz .handle_in_trap /* should not happen? */ 5820Sstevel@tonic-gate#if LWP_PCB_FPU != 0 5830Sstevel@tonic-gate addq $LWP_PCB_FPU, %rax /* &lwp->lwp_pcb.pcb_fpu */ 5840Sstevel@tonic-gate#endif 5850Sstevel@tonic-gate testl %ebx, PCB_FPU_FLAGS(%rax) 5860Sstevel@tonic-gate jz .handle_in_trap /* must be the first fault */ 5870Sstevel@tonic-gate clts 5880Sstevel@tonic-gate andl $_BITNOT(FPU_VALID), PCB_FPU_FLAGS(%rax) 5890Sstevel@tonic-gate#if FPU_CTX_FPU_REGS != 0 5900Sstevel@tonic-gate addq $FPU_CTX_FPU_REGS, %rax 5910Sstevel@tonic-gate#endif 5920Sstevel@tonic-gate /* 5930Sstevel@tonic-gate * the label below is used in trap.c to detect FP faults in 5940Sstevel@tonic-gate * kernel due to user fault. 5950Sstevel@tonic-gate */ 5960Sstevel@tonic-gate ALTENTRY(ndptrap_frstor) 5970Sstevel@tonic-gate fxrstor (%rax) 5980Sstevel@tonic-gate popq %rbx 5990Sstevel@tonic-gate popq %rax 6003446Smrj IRET 6013446Smrj /*NOTREACHED*/ 6020Sstevel@tonic-gate 6030Sstevel@tonic-gate.handle_in_trap: 6040Sstevel@tonic-gate popq %rbx 6050Sstevel@tonic-gate popq %rax 6060Sstevel@tonic-gate TRAP_NOERR(T_NOEXTFLT) /* $7 */ 6070Sstevel@tonic-gate jmp cmninttrap 6080Sstevel@tonic-gate SET_SIZE(ndptrap_frstor) 6090Sstevel@tonic-gate SET_SIZE(ndptrap) 6100Sstevel@tonic-gate 6110Sstevel@tonic-gate#elif defined(__i386) 6120Sstevel@tonic-gate 6130Sstevel@tonic-gate ENTRY_NP(ndptrap) 6140Sstevel@tonic-gate /* 6150Sstevel@tonic-gate * We want to do this quickly as every lwp using fp will take this 6160Sstevel@tonic-gate * after a context switch -- we do the frequent path in fpnoextflt 6170Sstevel@tonic-gate * below; for all other cases, we let the trap code handle it 6180Sstevel@tonic-gate */ 6190Sstevel@tonic-gate pushl %eax 6200Sstevel@tonic-gate pushl %ebx 6210Sstevel@tonic-gate pushl %ds 6220Sstevel@tonic-gate pushl %gs 6230Sstevel@tonic-gate movl $KDS_SEL, %ebx 6240Sstevel@tonic-gate movw %bx, %ds 6250Sstevel@tonic-gate movl $KGS_SEL, %eax 6260Sstevel@tonic-gate movw %ax, %gs 6273446Smrj LOADCPU(%eax) 6280Sstevel@tonic-gate cmpl $0, fpu_exists 6290Sstevel@tonic-gate je .handle_in_trap /* let trap handle no fp case */ 6303446Smrj movl CPU_THREAD(%eax), %ebx /* %ebx = curthread */ 6313446Smrj movl $FPU_EN, %eax 6323446Smrj movl T_LWP(%ebx), %ebx /* %ebx = lwp */ 6333446Smrj testl %ebx, %ebx 6340Sstevel@tonic-gate jz .handle_in_trap /* should not happen? */ 6350Sstevel@tonic-gate#if LWP_PCB_FPU != 0 6363446Smrj addl $LWP_PCB_FPU, %ebx /* &lwp->lwp_pcb.pcb_fpu */ 6370Sstevel@tonic-gate#endif 6383446Smrj testl %eax, PCB_FPU_FLAGS(%ebx) 6390Sstevel@tonic-gate jz .handle_in_trap /* must be the first fault */ 6403446Smrj CLTS 6413446Smrj andl $_BITNOT(FPU_VALID), PCB_FPU_FLAGS(%ebx) 6420Sstevel@tonic-gate#if FPU_CTX_FPU_REGS != 0 6433446Smrj addl $FPU_CTX_FPU_REGS, %ebx 6440Sstevel@tonic-gate#endif 6450Sstevel@tonic-gate /* 6460Sstevel@tonic-gate * the label below is used in trap.c to detect FP faults in kernel 6470Sstevel@tonic-gate * due to user fault. 6480Sstevel@tonic-gate */ 6490Sstevel@tonic-gate ALTENTRY(ndptrap_frstor) 6503446Smrj .globl _patch_fxrstor_ebx 6513446Smrj_patch_fxrstor_ebx: 6523446Smrj frstor (%ebx) /* may be patched to fxrstor */ 6530Sstevel@tonic-gate nop /* (including this byte) */ 6540Sstevel@tonic-gate popl %gs 6550Sstevel@tonic-gate popl %ds 6560Sstevel@tonic-gate popl %ebx 6570Sstevel@tonic-gate popl %eax 6583446Smrj IRET 6590Sstevel@tonic-gate 6600Sstevel@tonic-gate.handle_in_trap: 6610Sstevel@tonic-gate popl %gs 6620Sstevel@tonic-gate popl %ds 6630Sstevel@tonic-gate popl %ebx 6640Sstevel@tonic-gate popl %eax 6653446Smrj TRAP_NOERR(T_NOEXTFLT) /* $7 */ 6660Sstevel@tonic-gate jmp cmninttrap 6670Sstevel@tonic-gate SET_SIZE(ndptrap_frstor) 6680Sstevel@tonic-gate SET_SIZE(ndptrap) 6690Sstevel@tonic-gate 6700Sstevel@tonic-gate#endif /* __i386 */ 6710Sstevel@tonic-gate 6720Sstevel@tonic-gate#if defined(__amd64) 6730Sstevel@tonic-gate 6740Sstevel@tonic-gate /* 6750Sstevel@tonic-gate * #DF 6760Sstevel@tonic-gate */ 6770Sstevel@tonic-gate ENTRY_NP(syserrtrap) 6780Sstevel@tonic-gate pushq $T_DBLFLT 6790Sstevel@tonic-gate 6800Sstevel@tonic-gate SET_CPU_GSBASE 6810Sstevel@tonic-gate 6820Sstevel@tonic-gate /* 6830Sstevel@tonic-gate * We share this handler with kmdb (if kmdb is loaded). As such, we may 6840Sstevel@tonic-gate * have reached this point after encountering a #df in kmdb. If that 6850Sstevel@tonic-gate * happens, we'll still be on kmdb's IDT. We need to switch back to this 6860Sstevel@tonic-gate * CPU's IDT before proceeding. Furthermore, if we did arrive here from 6870Sstevel@tonic-gate * kmdb, kmdb is probably in a very sickly state, and shouldn't be 6880Sstevel@tonic-gate * entered from the panic flow. We'll suppress that entry by setting 6890Sstevel@tonic-gate * nopanicdebug. 6900Sstevel@tonic-gate */ 6910Sstevel@tonic-gate pushq %rax 6920Sstevel@tonic-gate subq $DESCTBR_SIZE, %rsp 6930Sstevel@tonic-gate sidt (%rsp) 6940Sstevel@tonic-gate movq %gs:CPU_IDT, %rax 6950Sstevel@tonic-gate cmpq %rax, DTR_BASE(%rsp) 6960Sstevel@tonic-gate je 1f 6970Sstevel@tonic-gate 6980Sstevel@tonic-gate movq %rax, DTR_BASE(%rsp) 6990Sstevel@tonic-gate movw $_MUL(NIDT, GATE_DESC_SIZE), DTR_LIMIT(%rsp) 7000Sstevel@tonic-gate lidt (%rsp) 7010Sstevel@tonic-gate 7020Sstevel@tonic-gate movl $1, nopanicdebug 7030Sstevel@tonic-gate 7040Sstevel@tonic-gate1: addq $DESCTBR_SIZE, %rsp 7050Sstevel@tonic-gate popq %rax 7060Sstevel@tonic-gate 7070Sstevel@tonic-gate DFTRAP_PUSH 7080Sstevel@tonic-gate 7090Sstevel@tonic-gate /* 7100Sstevel@tonic-gate * freeze trap trace. 7110Sstevel@tonic-gate */ 7120Sstevel@tonic-gate#ifdef TRAPTRACE 7130Sstevel@tonic-gate leaq trap_trace_freeze(%rip), %r11 7140Sstevel@tonic-gate incl (%r11) 7150Sstevel@tonic-gate#endif 7160Sstevel@tonic-gate 7170Sstevel@tonic-gate ENABLE_INTR_FLAGS 7180Sstevel@tonic-gate 7190Sstevel@tonic-gate movq %rsp, %rdi /* ®s */ 7200Sstevel@tonic-gate xorl %esi, %esi /* clear address */ 7210Sstevel@tonic-gate xorl %edx, %edx /* cpuid = 0 */ 7220Sstevel@tonic-gate call trap 7230Sstevel@tonic-gate 7240Sstevel@tonic-gate SET_SIZE(syserrtrap) 7250Sstevel@tonic-gate 7260Sstevel@tonic-gate#elif defined(__i386) 7270Sstevel@tonic-gate 7280Sstevel@tonic-gate /* 7290Sstevel@tonic-gate * #DF 7300Sstevel@tonic-gate */ 7310Sstevel@tonic-gate ENTRY_NP(syserrtrap) 7320Sstevel@tonic-gate cli /* disable interrupts */ 7330Sstevel@tonic-gate 7340Sstevel@tonic-gate /* 7350Sstevel@tonic-gate * We share this handler with kmdb (if kmdb is loaded). As such, we may 7360Sstevel@tonic-gate * have reached this point after encountering a #df in kmdb. If that 7370Sstevel@tonic-gate * happens, we'll still be on kmdb's IDT. We need to switch back to this 7380Sstevel@tonic-gate * CPU's IDT before proceeding. Furthermore, if we did arrive here from 7390Sstevel@tonic-gate * kmdb, kmdb is probably in a very sickly state, and shouldn't be 7400Sstevel@tonic-gate * entered from the panic flow. We'll suppress that entry by setting 7410Sstevel@tonic-gate * nopanicdebug. 7420Sstevel@tonic-gate */ 7430Sstevel@tonic-gate subl $DESCTBR_SIZE, %esp 7440Sstevel@tonic-gate movl %gs:CPU_IDT, %eax 7450Sstevel@tonic-gate sidt (%esp) 7460Sstevel@tonic-gate cmpl DTR_BASE(%esp), %eax 7470Sstevel@tonic-gate je 1f 7480Sstevel@tonic-gate 7490Sstevel@tonic-gate movl %eax, DTR_BASE(%esp) 7500Sstevel@tonic-gate movw $_MUL(NIDT, GATE_DESC_SIZE), DTR_LIMIT(%esp) 7510Sstevel@tonic-gate lidt (%esp) 7520Sstevel@tonic-gate 7530Sstevel@tonic-gate movl $1, nopanicdebug 7540Sstevel@tonic-gate 7550Sstevel@tonic-gate1: addl $DESCTBR_SIZE, %esp 7560Sstevel@tonic-gate 7570Sstevel@tonic-gate /* 7580Sstevel@tonic-gate * Check the CPL in the TSS to see what mode 7590Sstevel@tonic-gate * (user or kernel) we took the fault in. At this 7600Sstevel@tonic-gate * point we are running in the context of the double 7610Sstevel@tonic-gate * fault task (dftss) but the CPU's task points to 7620Sstevel@tonic-gate * the previous task (ktss) where the process context 7630Sstevel@tonic-gate * has been saved as the result of the task switch. 7640Sstevel@tonic-gate */ 7650Sstevel@tonic-gate movl %gs:CPU_TSS, %eax /* get the TSS */ 7660Sstevel@tonic-gate movl TSS_SS(%eax), %ebx /* save the fault SS */ 7670Sstevel@tonic-gate movl TSS_ESP(%eax), %edx /* save the fault ESP */ 7680Sstevel@tonic-gate testw $CPL_MASK, TSS_CS(%eax) /* user mode ? */ 7690Sstevel@tonic-gate jz make_frame 7700Sstevel@tonic-gate movw TSS_SS0(%eax), %ss /* get on the kernel stack */ 7710Sstevel@tonic-gate movl TSS_ESP0(%eax), %esp 7720Sstevel@tonic-gate 7730Sstevel@tonic-gate /* 7740Sstevel@tonic-gate * Clear the NT flag to avoid a task switch when the process 7750Sstevel@tonic-gate * finally pops the EFL off the stack via an iret. Clear 7760Sstevel@tonic-gate * the TF flag since that is what the processor does for 7770Sstevel@tonic-gate * a normal exception. Clear the IE flag so that interrupts 7780Sstevel@tonic-gate * remain disabled. 7790Sstevel@tonic-gate */ 7800Sstevel@tonic-gate movl TSS_EFL(%eax), %ecx 7810Sstevel@tonic-gate andl $_BITNOT(PS_NT|PS_T|PS_IE), %ecx 7820Sstevel@tonic-gate pushl %ecx 7830Sstevel@tonic-gate popfl /* restore the EFL */ 7840Sstevel@tonic-gate movw TSS_LDT(%eax), %cx /* restore the LDT */ 7850Sstevel@tonic-gate lldt %cx 7860Sstevel@tonic-gate 7870Sstevel@tonic-gate /* 7880Sstevel@tonic-gate * Restore process segment selectors. 7890Sstevel@tonic-gate */ 7900Sstevel@tonic-gate movw TSS_DS(%eax), %ds 7910Sstevel@tonic-gate movw TSS_ES(%eax), %es 7920Sstevel@tonic-gate movw TSS_FS(%eax), %fs 7930Sstevel@tonic-gate movw TSS_GS(%eax), %gs 7940Sstevel@tonic-gate 7950Sstevel@tonic-gate /* 7960Sstevel@tonic-gate * Restore task segment selectors. 7970Sstevel@tonic-gate */ 7980Sstevel@tonic-gate movl $KDS_SEL, TSS_DS(%eax) 7990Sstevel@tonic-gate movl $KDS_SEL, TSS_ES(%eax) 8000Sstevel@tonic-gate movl $KDS_SEL, TSS_SS(%eax) 8010Sstevel@tonic-gate movl $KFS_SEL, TSS_FS(%eax) 8020Sstevel@tonic-gate movl $KGS_SEL, TSS_GS(%eax) 8030Sstevel@tonic-gate 8040Sstevel@tonic-gate /* 8050Sstevel@tonic-gate * Clear the TS bit, the busy bits in both task 8060Sstevel@tonic-gate * descriptors, and switch tasks. 8070Sstevel@tonic-gate */ 8080Sstevel@tonic-gate clts 8090Sstevel@tonic-gate leal gdt0, %ecx 8100Sstevel@tonic-gate movl DFTSS_SEL+4(%ecx), %esi 8110Sstevel@tonic-gate andl $_BITNOT(0x200), %esi 8120Sstevel@tonic-gate movl %esi, DFTSS_SEL+4(%ecx) 8130Sstevel@tonic-gate movl KTSS_SEL+4(%ecx), %esi 8140Sstevel@tonic-gate andl $_BITNOT(0x200), %esi 8150Sstevel@tonic-gate movl %esi, KTSS_SEL+4(%ecx) 8160Sstevel@tonic-gate movw $KTSS_SEL, %cx 8170Sstevel@tonic-gate ltr %cx 8180Sstevel@tonic-gate 8190Sstevel@tonic-gate /* 8200Sstevel@tonic-gate * Restore part of the process registers. 8210Sstevel@tonic-gate */ 8220Sstevel@tonic-gate movl TSS_EBP(%eax), %ebp 8230Sstevel@tonic-gate movl TSS_ECX(%eax), %ecx 8240Sstevel@tonic-gate movl TSS_ESI(%eax), %esi 8250Sstevel@tonic-gate movl TSS_EDI(%eax), %edi 8260Sstevel@tonic-gate 8270Sstevel@tonic-gatemake_frame: 8280Sstevel@tonic-gate /* 8290Sstevel@tonic-gate * Make a trap frame. Leave the error code (0) on 8300Sstevel@tonic-gate * the stack since the first word on a trap stack is 8310Sstevel@tonic-gate * unused anyway. 8320Sstevel@tonic-gate */ 8330Sstevel@tonic-gate pushl %ebx / fault SS 8340Sstevel@tonic-gate pushl %edx / fault ESP 8350Sstevel@tonic-gate pushl TSS_EFL(%eax) / fault EFL 8360Sstevel@tonic-gate pushl TSS_CS(%eax) / fault CS 8370Sstevel@tonic-gate pushl TSS_EIP(%eax) / fault EIP 8380Sstevel@tonic-gate pushl $0 / error code 8390Sstevel@tonic-gate pushl $T_DBLFLT / trap number 8 8400Sstevel@tonic-gate movl TSS_EBX(%eax), %ebx / restore EBX 8410Sstevel@tonic-gate movl TSS_EDX(%eax), %edx / restore EDX 8420Sstevel@tonic-gate movl TSS_EAX(%eax), %eax / restore EAX 8430Sstevel@tonic-gate sti / enable interrupts 8440Sstevel@tonic-gate jmp cmntrap 8450Sstevel@tonic-gate SET_SIZE(syserrtrap) 8460Sstevel@tonic-gate 8470Sstevel@tonic-gate#endif /* __i386 */ 8480Sstevel@tonic-gate 8490Sstevel@tonic-gate ENTRY_NP(overrun) 8500Sstevel@tonic-gate push $0 8510Sstevel@tonic-gate TRAP_NOERR(T_EXTOVRFLT) /* $9 i386 only - not generated */ 8520Sstevel@tonic-gate jmp cmninttrap 8530Sstevel@tonic-gate SET_SIZE(overrun) 8540Sstevel@tonic-gate 8550Sstevel@tonic-gate /* 8560Sstevel@tonic-gate * #TS 8570Sstevel@tonic-gate */ 8580Sstevel@tonic-gate ENTRY_NP(invtsstrap) 8590Sstevel@tonic-gate TRAP_ERR(T_TSSFLT) /* $10 already have error code on stack */ 8600Sstevel@tonic-gate jmp cmntrap 8610Sstevel@tonic-gate SET_SIZE(invtsstrap) 8620Sstevel@tonic-gate 8630Sstevel@tonic-gate /* 8640Sstevel@tonic-gate * #NP 8650Sstevel@tonic-gate */ 8660Sstevel@tonic-gate ENTRY_NP(segnptrap) 8670Sstevel@tonic-gate TRAP_ERR(T_SEGFLT) /* $11 already have error code on stack */ 8680Sstevel@tonic-gate#if defined(__amd64) 8690Sstevel@tonic-gate SET_CPU_GSBASE 8700Sstevel@tonic-gate#endif 8710Sstevel@tonic-gate jmp cmntrap 8720Sstevel@tonic-gate SET_SIZE(segnptrap) 8730Sstevel@tonic-gate 8740Sstevel@tonic-gate /* 8750Sstevel@tonic-gate * #SS 8760Sstevel@tonic-gate */ 8770Sstevel@tonic-gate ENTRY_NP(stktrap) 8780Sstevel@tonic-gate TRAP_ERR(T_STKFLT) /* $12 already have error code on stack */ 8790Sstevel@tonic-gate jmp cmntrap 8800Sstevel@tonic-gate SET_SIZE(stktrap) 8810Sstevel@tonic-gate 8820Sstevel@tonic-gate /* 8830Sstevel@tonic-gate * #GP 8840Sstevel@tonic-gate */ 8850Sstevel@tonic-gate ENTRY_NP(gptrap) 8860Sstevel@tonic-gate TRAP_ERR(T_GPFLT) /* $13 already have error code on stack */ 8870Sstevel@tonic-gate#if defined(__amd64) 8880Sstevel@tonic-gate SET_CPU_GSBASE 8890Sstevel@tonic-gate#endif 8900Sstevel@tonic-gate jmp cmntrap 8910Sstevel@tonic-gate SET_SIZE(gptrap) 8920Sstevel@tonic-gate 8930Sstevel@tonic-gate /* 8940Sstevel@tonic-gate * #PF 8950Sstevel@tonic-gate */ 8960Sstevel@tonic-gate ENTRY_NP(pftrap) 8970Sstevel@tonic-gate TRAP_ERR(T_PGFLT) /* $14 already have error code on stack */ 8983446Smrj INTR_PUSH 8993446Smrj 9003446Smrj#if defined(__amd64) 9013446Smrj movq %cr2, %r15 9023446Smrj#elif defined(__i386) 9033446Smrj movl %cr2, %esi 9043446Smrj#endif /* __i386 */ 9053446Smrj 9063446Smrj jmp cmntrap_pushed 9070Sstevel@tonic-gate SET_SIZE(pftrap) 9080Sstevel@tonic-gate 9090Sstevel@tonic-gate#if !defined(__amd64) 9100Sstevel@tonic-gate 9113446Smrj .globl idt0_default_r 9123446Smrj 9130Sstevel@tonic-gate /* 9140Sstevel@tonic-gate * #PF pentium bug workaround 9150Sstevel@tonic-gate */ 9160Sstevel@tonic-gate ENTRY_NP(pentium_pftrap) 9170Sstevel@tonic-gate pushl %eax 9180Sstevel@tonic-gate movl %cr2, %eax 9190Sstevel@tonic-gate andl $MMU_STD_PAGEMASK, %eax 9200Sstevel@tonic-gate 9210Sstevel@tonic-gate cmpl %eax, %cs:idt0_default_r+2 /* fixme */ 9220Sstevel@tonic-gate 9230Sstevel@tonic-gate je check_for_user_address 9240Sstevel@tonic-gateuser_mode: 9250Sstevel@tonic-gate popl %eax 9260Sstevel@tonic-gate pushl $T_PGFLT /* $14 */ 9270Sstevel@tonic-gate jmp cmntrap 9280Sstevel@tonic-gatecheck_for_user_address: 9290Sstevel@tonic-gate /* 9300Sstevel@tonic-gate * Before we assume that we have an unmapped trap on our hands, 9310Sstevel@tonic-gate * check to see if this is a fault from user mode. If it is, 9320Sstevel@tonic-gate * we'll kick back into the page fault handler. 9330Sstevel@tonic-gate */ 9340Sstevel@tonic-gate movl 4(%esp), %eax /* error code */ 9350Sstevel@tonic-gate andl $PF_ERR_USER, %eax 9360Sstevel@tonic-gate jnz user_mode 9370Sstevel@tonic-gate 9380Sstevel@tonic-gate /* 9390Sstevel@tonic-gate * We now know that this is the invalid opcode trap. 9400Sstevel@tonic-gate */ 9410Sstevel@tonic-gate popl %eax 9420Sstevel@tonic-gate addl $4, %esp /* pop error code */ 9430Sstevel@tonic-gate jmp invoptrap 9440Sstevel@tonic-gate SET_SIZE(pentium_pftrap) 9450Sstevel@tonic-gate 9460Sstevel@tonic-gate#endif /* !__amd64 */ 9470Sstevel@tonic-gate 9480Sstevel@tonic-gate ENTRY_NP(resvtrap) 9490Sstevel@tonic-gate TRAP_NOERR(15) /* (reserved) */ 9500Sstevel@tonic-gate jmp cmntrap 9510Sstevel@tonic-gate SET_SIZE(resvtrap) 9520Sstevel@tonic-gate 9530Sstevel@tonic-gate /* 9540Sstevel@tonic-gate * #MF 9550Sstevel@tonic-gate */ 9560Sstevel@tonic-gate ENTRY_NP(ndperr) 9570Sstevel@tonic-gate TRAP_NOERR(T_EXTERRFLT) /* $16 */ 9580Sstevel@tonic-gate jmp cmninttrap 9590Sstevel@tonic-gate SET_SIZE(ndperr) 9600Sstevel@tonic-gate 9610Sstevel@tonic-gate /* 9620Sstevel@tonic-gate * #AC 9630Sstevel@tonic-gate */ 9640Sstevel@tonic-gate ENTRY_NP(achktrap) 9650Sstevel@tonic-gate TRAP_ERR(T_ALIGNMENT) /* $17 */ 9660Sstevel@tonic-gate jmp cmntrap 9670Sstevel@tonic-gate SET_SIZE(achktrap) 9680Sstevel@tonic-gate 9690Sstevel@tonic-gate /* 9700Sstevel@tonic-gate * #MC 9710Sstevel@tonic-gate */ 9721414Scindi .globl cmi_mca_trap /* see uts/i86pc/os/cmi.c */ 9731414Scindi 9741414Scindi#if defined(__amd64) 9751414Scindi 9760Sstevel@tonic-gate ENTRY_NP(mcetrap) 9770Sstevel@tonic-gate TRAP_NOERR(T_MCE) /* $18 */ 9783446Smrj 97910Skucharsk SET_CPU_GSBASE 9803446Smrj 9811414Scindi INTR_PUSH 9823446Smrj INTGATE_INIT_KERNEL_FLAGS 9831414Scindi 9841414Scindi TRACE_PTR(%rdi, %rbx, %ebx, %rcx, $TT_TRAP) 9851414Scindi TRACE_REGS(%rdi, %rsp, %rbx, %rcx) 9861414Scindi TRACE_STAMP(%rdi) 9871414Scindi 9881414Scindi movq %rsp, %rbp 9891414Scindi 9901414Scindi movq %rsp, %rdi /* arg0 = struct regs *rp */ 9911414Scindi call cmi_mca_trap /* cmi_mca_trap(rp); */ 9921414Scindi 9931414Scindi jmp _sys_rtt 9941414Scindi SET_SIZE(mcetrap) 9951414Scindi 9961414Scindi#else 9971414Scindi 9981414Scindi ENTRY_NP(mcetrap) 9991414Scindi TRAP_NOERR(T_MCE) /* $18 */ 10003446Smrj 10011414Scindi INTR_PUSH 10023446Smrj INTGATE_INIT_KERNEL_FLAGS 10031414Scindi 10043446Smrj TRACE_PTR(%edi, %ebx, %ebx, %ecx, $TT_TRAP) 10053446Smrj TRACE_REGS(%edi, %esp, %ebx, %ecx) 10063446Smrj TRACE_STAMP(%edi) 10073446Smrj 10081414Scindi movl %esp, %ebp 10091414Scindi 10101414Scindi movl %esp, %ecx 10111414Scindi pushl %ecx /* arg0 = struct regs *rp */ 10121414Scindi call cmi_mca_trap /* cmi_mca_trap(rp) */ 10131414Scindi addl $4, %esp /* pop arg0 */ 10141414Scindi 10151414Scindi jmp _sys_rtt 10161414Scindi SET_SIZE(mcetrap) 10171414Scindi 101810Skucharsk#endif 10190Sstevel@tonic-gate 10200Sstevel@tonic-gate /* 10210Sstevel@tonic-gate * #XF 10220Sstevel@tonic-gate */ 10230Sstevel@tonic-gate ENTRY_NP(xmtrap) 10240Sstevel@tonic-gate TRAP_NOERR(T_SIMDFPE) /* $19 */ 10250Sstevel@tonic-gate jmp cmntrap 10260Sstevel@tonic-gate SET_SIZE(xmtrap) 10270Sstevel@tonic-gate 10280Sstevel@tonic-gate ENTRY_NP(invaltrap) 10290Sstevel@tonic-gate TRAP_NOERR(30) /* very invalid */ 10300Sstevel@tonic-gate jmp cmntrap 10310Sstevel@tonic-gate SET_SIZE(invaltrap) 10320Sstevel@tonic-gate 10330Sstevel@tonic-gate ENTRY_NP(invalint) 10340Sstevel@tonic-gate TRAP_NOERR(31) /* even more so */ 10350Sstevel@tonic-gate jmp cmnint 10360Sstevel@tonic-gate SET_SIZE(invalint) 10370Sstevel@tonic-gate 10380Sstevel@tonic-gate .globl fasttable 10390Sstevel@tonic-gate 10400Sstevel@tonic-gate#if defined(__amd64) 10410Sstevel@tonic-gate 10420Sstevel@tonic-gate ENTRY_NP(fasttrap) 10430Sstevel@tonic-gate cmpl $T_LASTFAST, %eax 10440Sstevel@tonic-gate ja 1f 10450Sstevel@tonic-gate orl %eax, %eax /* (zero extend top 32-bits) */ 10460Sstevel@tonic-gate leaq fasttable(%rip), %r11 10470Sstevel@tonic-gate leaq (%r11, %rax, CLONGSIZE), %r11 10480Sstevel@tonic-gate jmp *(%r11) 10490Sstevel@tonic-gate1: 10500Sstevel@tonic-gate /* 10510Sstevel@tonic-gate * Fast syscall number was illegal. Make it look 10520Sstevel@tonic-gate * as if the INT failed. Modify %rip to point before the 10530Sstevel@tonic-gate * INT, push the expected error code and fake a GP fault. 10540Sstevel@tonic-gate * 10550Sstevel@tonic-gate * XXX Why make the error code be offset into idt + 1? 10560Sstevel@tonic-gate * Instead we should push a real (soft?) error code 10570Sstevel@tonic-gate * on the stack and #gp handler could know about fasttraps? 10580Sstevel@tonic-gate */ 10590Sstevel@tonic-gate subq $2, (%rsp) /* XXX int insn 2-bytes */ 10600Sstevel@tonic-gate pushq $_CONST(_MUL(T_FASTTRAP, GATE_DESC_SIZE) + 2) 10610Sstevel@tonic-gate jmp gptrap 10620Sstevel@tonic-gate SET_SIZE(fasttrap) 10630Sstevel@tonic-gate 10640Sstevel@tonic-gate#elif defined(__i386) 10650Sstevel@tonic-gate 10660Sstevel@tonic-gate ENTRY_NP(fasttrap) 10670Sstevel@tonic-gate cmpl $T_LASTFAST, %eax 10680Sstevel@tonic-gate ja 1f 10690Sstevel@tonic-gate jmp *%cs:fasttable(, %eax, CLONGSIZE) 10700Sstevel@tonic-gate1: 10710Sstevel@tonic-gate /* 10720Sstevel@tonic-gate * Fast syscall number was illegal. Make it look 10730Sstevel@tonic-gate * as if the INT failed. Modify %eip to point before the 10740Sstevel@tonic-gate * INT, push the expected error code and fake a GP fault. 10750Sstevel@tonic-gate * 10760Sstevel@tonic-gate * XXX Why make the error code be offset into idt + 1? 10770Sstevel@tonic-gate * Instead we should push a real (soft?) error code 10780Sstevel@tonic-gate * on the stack and #gp handler could know about fasttraps? 10790Sstevel@tonic-gate */ 10800Sstevel@tonic-gate subl $2, (%esp) /* XXX int insn 2-bytes */ 10810Sstevel@tonic-gate pushl $_CONST(_MUL(T_FASTTRAP, GATE_DESC_SIZE) + 2) 10820Sstevel@tonic-gate jmp gptrap 10830Sstevel@tonic-gate SET_SIZE(fasttrap) 10840Sstevel@tonic-gate 10850Sstevel@tonic-gate#endif /* __i386 */ 10860Sstevel@tonic-gate 10870Sstevel@tonic-gate ENTRY_NP(dtrace_ret) 10880Sstevel@tonic-gate TRAP_NOERR(T_DTRACE_RET) 10890Sstevel@tonic-gate jmp dtrace_trap 10900Sstevel@tonic-gate SET_SIZE(dtrace_ret) 10910Sstevel@tonic-gate 10920Sstevel@tonic-gate#if defined(__amd64) 10930Sstevel@tonic-gate 10940Sstevel@tonic-gate /* 10950Sstevel@tonic-gate * RFLAGS 24 bytes up the stack from %rsp. 10960Sstevel@tonic-gate * XXX a constant would be nicer. 10970Sstevel@tonic-gate */ 10980Sstevel@tonic-gate ENTRY_NP(fast_null) 10990Sstevel@tonic-gate orq $PS_C, 24(%rsp) /* set carry bit in user flags */ 11003446Smrj IRET 11013446Smrj /*NOTREACHED*/ 11020Sstevel@tonic-gate SET_SIZE(fast_null) 11030Sstevel@tonic-gate 11040Sstevel@tonic-gate#elif defined(__i386) 11050Sstevel@tonic-gate 11060Sstevel@tonic-gate ENTRY_NP(fast_null) 11070Sstevel@tonic-gate orw $PS_C, 8(%esp) /* set carry bit in user flags */ 11083446Smrj IRET 11090Sstevel@tonic-gate SET_SIZE(fast_null) 11100Sstevel@tonic-gate 11110Sstevel@tonic-gate#endif /* __i386 */ 11120Sstevel@tonic-gate 11130Sstevel@tonic-gate /* 11140Sstevel@tonic-gate * Interrupts start at 32 11150Sstevel@tonic-gate */ 11160Sstevel@tonic-gate#define MKIVCT(n) \ 11170Sstevel@tonic-gate ENTRY_NP(ivct/**/n) \ 11180Sstevel@tonic-gate push $0; \ 11190Sstevel@tonic-gate push $n - 0x20; \ 11200Sstevel@tonic-gate jmp cmnint; \ 11210Sstevel@tonic-gate SET_SIZE(ivct/**/n) 11220Sstevel@tonic-gate 11230Sstevel@tonic-gate MKIVCT(32) 11240Sstevel@tonic-gate MKIVCT(33) 11250Sstevel@tonic-gate MKIVCT(34) 11260Sstevel@tonic-gate MKIVCT(35) 11270Sstevel@tonic-gate MKIVCT(36) 11280Sstevel@tonic-gate MKIVCT(37) 11290Sstevel@tonic-gate MKIVCT(38) 11300Sstevel@tonic-gate MKIVCT(39) 11310Sstevel@tonic-gate MKIVCT(40) 11320Sstevel@tonic-gate MKIVCT(41) 11330Sstevel@tonic-gate MKIVCT(42) 11340Sstevel@tonic-gate MKIVCT(43) 11350Sstevel@tonic-gate MKIVCT(44) 11360Sstevel@tonic-gate MKIVCT(45) 11370Sstevel@tonic-gate MKIVCT(46) 11380Sstevel@tonic-gate MKIVCT(47) 11390Sstevel@tonic-gate MKIVCT(48) 11400Sstevel@tonic-gate MKIVCT(49) 11410Sstevel@tonic-gate MKIVCT(50) 11420Sstevel@tonic-gate MKIVCT(51) 11430Sstevel@tonic-gate MKIVCT(52) 11440Sstevel@tonic-gate MKIVCT(53) 11450Sstevel@tonic-gate MKIVCT(54) 11460Sstevel@tonic-gate MKIVCT(55) 11470Sstevel@tonic-gate MKIVCT(56) 11480Sstevel@tonic-gate MKIVCT(57) 11490Sstevel@tonic-gate MKIVCT(58) 11500Sstevel@tonic-gate MKIVCT(59) 11510Sstevel@tonic-gate MKIVCT(60) 11520Sstevel@tonic-gate MKIVCT(61) 11530Sstevel@tonic-gate MKIVCT(62) 11540Sstevel@tonic-gate MKIVCT(63) 11550Sstevel@tonic-gate MKIVCT(64) 11560Sstevel@tonic-gate MKIVCT(65) 11570Sstevel@tonic-gate MKIVCT(66) 11580Sstevel@tonic-gate MKIVCT(67) 11590Sstevel@tonic-gate MKIVCT(68) 11600Sstevel@tonic-gate MKIVCT(69) 11610Sstevel@tonic-gate MKIVCT(70) 11620Sstevel@tonic-gate MKIVCT(71) 11630Sstevel@tonic-gate MKIVCT(72) 11640Sstevel@tonic-gate MKIVCT(73) 11650Sstevel@tonic-gate MKIVCT(74) 11660Sstevel@tonic-gate MKIVCT(75) 11670Sstevel@tonic-gate MKIVCT(76) 11680Sstevel@tonic-gate MKIVCT(77) 11690Sstevel@tonic-gate MKIVCT(78) 11700Sstevel@tonic-gate MKIVCT(79) 11710Sstevel@tonic-gate MKIVCT(80) 11720Sstevel@tonic-gate MKIVCT(81) 11730Sstevel@tonic-gate MKIVCT(82) 11740Sstevel@tonic-gate MKIVCT(83) 11750Sstevel@tonic-gate MKIVCT(84) 11760Sstevel@tonic-gate MKIVCT(85) 11770Sstevel@tonic-gate MKIVCT(86) 11780Sstevel@tonic-gate MKIVCT(87) 11790Sstevel@tonic-gate MKIVCT(88) 11800Sstevel@tonic-gate MKIVCT(89) 11810Sstevel@tonic-gate MKIVCT(90) 11820Sstevel@tonic-gate MKIVCT(91) 11830Sstevel@tonic-gate MKIVCT(92) 11840Sstevel@tonic-gate MKIVCT(93) 11850Sstevel@tonic-gate MKIVCT(94) 11860Sstevel@tonic-gate MKIVCT(95) 11870Sstevel@tonic-gate MKIVCT(96) 11880Sstevel@tonic-gate MKIVCT(97) 11890Sstevel@tonic-gate MKIVCT(98) 11900Sstevel@tonic-gate MKIVCT(99) 11910Sstevel@tonic-gate MKIVCT(100) 11920Sstevel@tonic-gate MKIVCT(101) 11930Sstevel@tonic-gate MKIVCT(102) 11940Sstevel@tonic-gate MKIVCT(103) 11950Sstevel@tonic-gate MKIVCT(104) 11960Sstevel@tonic-gate MKIVCT(105) 11970Sstevel@tonic-gate MKIVCT(106) 11980Sstevel@tonic-gate MKIVCT(107) 11990Sstevel@tonic-gate MKIVCT(108) 12000Sstevel@tonic-gate MKIVCT(109) 12010Sstevel@tonic-gate MKIVCT(110) 12020Sstevel@tonic-gate MKIVCT(111) 12030Sstevel@tonic-gate MKIVCT(112) 12040Sstevel@tonic-gate MKIVCT(113) 12050Sstevel@tonic-gate MKIVCT(114) 12060Sstevel@tonic-gate MKIVCT(115) 12070Sstevel@tonic-gate MKIVCT(116) 12080Sstevel@tonic-gate MKIVCT(117) 12090Sstevel@tonic-gate MKIVCT(118) 12100Sstevel@tonic-gate MKIVCT(119) 12110Sstevel@tonic-gate MKIVCT(120) 12120Sstevel@tonic-gate MKIVCT(121) 12130Sstevel@tonic-gate MKIVCT(122) 12140Sstevel@tonic-gate MKIVCT(123) 12150Sstevel@tonic-gate MKIVCT(124) 12160Sstevel@tonic-gate MKIVCT(125) 12170Sstevel@tonic-gate MKIVCT(126) 12180Sstevel@tonic-gate MKIVCT(127) 12190Sstevel@tonic-gate MKIVCT(128) 12200Sstevel@tonic-gate MKIVCT(129) 12210Sstevel@tonic-gate MKIVCT(130) 12220Sstevel@tonic-gate MKIVCT(131) 12230Sstevel@tonic-gate MKIVCT(132) 12240Sstevel@tonic-gate MKIVCT(133) 12250Sstevel@tonic-gate MKIVCT(134) 12260Sstevel@tonic-gate MKIVCT(135) 12270Sstevel@tonic-gate MKIVCT(136) 12280Sstevel@tonic-gate MKIVCT(137) 12290Sstevel@tonic-gate MKIVCT(138) 12300Sstevel@tonic-gate MKIVCT(139) 12310Sstevel@tonic-gate MKIVCT(140) 12320Sstevel@tonic-gate MKIVCT(141) 12330Sstevel@tonic-gate MKIVCT(142) 12340Sstevel@tonic-gate MKIVCT(143) 12350Sstevel@tonic-gate MKIVCT(144) 12360Sstevel@tonic-gate MKIVCT(145) 12370Sstevel@tonic-gate MKIVCT(146) 12380Sstevel@tonic-gate MKIVCT(147) 12390Sstevel@tonic-gate MKIVCT(148) 12400Sstevel@tonic-gate MKIVCT(149) 12410Sstevel@tonic-gate MKIVCT(150) 12420Sstevel@tonic-gate MKIVCT(151) 12430Sstevel@tonic-gate MKIVCT(152) 12440Sstevel@tonic-gate MKIVCT(153) 12450Sstevel@tonic-gate MKIVCT(154) 12460Sstevel@tonic-gate MKIVCT(155) 12470Sstevel@tonic-gate MKIVCT(156) 12480Sstevel@tonic-gate MKIVCT(157) 12490Sstevel@tonic-gate MKIVCT(158) 12500Sstevel@tonic-gate MKIVCT(159) 12510Sstevel@tonic-gate MKIVCT(160) 12520Sstevel@tonic-gate MKIVCT(161) 12530Sstevel@tonic-gate MKIVCT(162) 12540Sstevel@tonic-gate MKIVCT(163) 12550Sstevel@tonic-gate MKIVCT(164) 12560Sstevel@tonic-gate MKIVCT(165) 12570Sstevel@tonic-gate MKIVCT(166) 12580Sstevel@tonic-gate MKIVCT(167) 12590Sstevel@tonic-gate MKIVCT(168) 12600Sstevel@tonic-gate MKIVCT(169) 12610Sstevel@tonic-gate MKIVCT(170) 12620Sstevel@tonic-gate MKIVCT(171) 12630Sstevel@tonic-gate MKIVCT(172) 12640Sstevel@tonic-gate MKIVCT(173) 12650Sstevel@tonic-gate MKIVCT(174) 12660Sstevel@tonic-gate MKIVCT(175) 12670Sstevel@tonic-gate MKIVCT(176) 12680Sstevel@tonic-gate MKIVCT(177) 12690Sstevel@tonic-gate MKIVCT(178) 12700Sstevel@tonic-gate MKIVCT(179) 12710Sstevel@tonic-gate MKIVCT(180) 12720Sstevel@tonic-gate MKIVCT(181) 12730Sstevel@tonic-gate MKIVCT(182) 12740Sstevel@tonic-gate MKIVCT(183) 12750Sstevel@tonic-gate MKIVCT(184) 12760Sstevel@tonic-gate MKIVCT(185) 12770Sstevel@tonic-gate MKIVCT(186) 12780Sstevel@tonic-gate MKIVCT(187) 12790Sstevel@tonic-gate MKIVCT(188) 12800Sstevel@tonic-gate MKIVCT(189) 12810Sstevel@tonic-gate MKIVCT(190) 12820Sstevel@tonic-gate MKIVCT(191) 12830Sstevel@tonic-gate MKIVCT(192) 12840Sstevel@tonic-gate MKIVCT(193) 12850Sstevel@tonic-gate MKIVCT(194) 12860Sstevel@tonic-gate MKIVCT(195) 12870Sstevel@tonic-gate MKIVCT(196) 12880Sstevel@tonic-gate MKIVCT(197) 12890Sstevel@tonic-gate MKIVCT(198) 12900Sstevel@tonic-gate MKIVCT(199) 12910Sstevel@tonic-gate MKIVCT(200) 12920Sstevel@tonic-gate MKIVCT(201) 12930Sstevel@tonic-gate MKIVCT(202) 12940Sstevel@tonic-gate MKIVCT(203) 12950Sstevel@tonic-gate MKIVCT(204) 12960Sstevel@tonic-gate MKIVCT(205) 12970Sstevel@tonic-gate MKIVCT(206) 12980Sstevel@tonic-gate MKIVCT(207) 12990Sstevel@tonic-gate MKIVCT(208) 13000Sstevel@tonic-gate MKIVCT(209) 13010Sstevel@tonic-gate MKIVCT(210) 13020Sstevel@tonic-gate MKIVCT(211) 13030Sstevel@tonic-gate MKIVCT(212) 13040Sstevel@tonic-gate MKIVCT(213) 13050Sstevel@tonic-gate MKIVCT(214) 13060Sstevel@tonic-gate MKIVCT(215) 13070Sstevel@tonic-gate MKIVCT(216) 13080Sstevel@tonic-gate MKIVCT(217) 13090Sstevel@tonic-gate MKIVCT(218) 13100Sstevel@tonic-gate MKIVCT(219) 13110Sstevel@tonic-gate MKIVCT(220) 13120Sstevel@tonic-gate MKIVCT(221) 13130Sstevel@tonic-gate MKIVCT(222) 13140Sstevel@tonic-gate MKIVCT(223) 13150Sstevel@tonic-gate MKIVCT(224) 13160Sstevel@tonic-gate MKIVCT(225) 13170Sstevel@tonic-gate MKIVCT(226) 13180Sstevel@tonic-gate MKIVCT(227) 13190Sstevel@tonic-gate MKIVCT(228) 13200Sstevel@tonic-gate MKIVCT(229) 13210Sstevel@tonic-gate MKIVCT(230) 13220Sstevel@tonic-gate MKIVCT(231) 13230Sstevel@tonic-gate MKIVCT(232) 13240Sstevel@tonic-gate MKIVCT(233) 13250Sstevel@tonic-gate MKIVCT(234) 13260Sstevel@tonic-gate MKIVCT(235) 13270Sstevel@tonic-gate MKIVCT(236) 13280Sstevel@tonic-gate MKIVCT(237) 13290Sstevel@tonic-gate MKIVCT(238) 13300Sstevel@tonic-gate MKIVCT(239) 13310Sstevel@tonic-gate MKIVCT(240) 13320Sstevel@tonic-gate MKIVCT(241) 13330Sstevel@tonic-gate MKIVCT(242) 13340Sstevel@tonic-gate MKIVCT(243) 13350Sstevel@tonic-gate MKIVCT(244) 13360Sstevel@tonic-gate MKIVCT(245) 13370Sstevel@tonic-gate MKIVCT(246) 13380Sstevel@tonic-gate MKIVCT(247) 13390Sstevel@tonic-gate MKIVCT(248) 13400Sstevel@tonic-gate MKIVCT(249) 13410Sstevel@tonic-gate MKIVCT(250) 13420Sstevel@tonic-gate MKIVCT(251) 13430Sstevel@tonic-gate MKIVCT(252) 13440Sstevel@tonic-gate MKIVCT(253) 13450Sstevel@tonic-gate MKIVCT(254) 13460Sstevel@tonic-gate MKIVCT(255) 13470Sstevel@tonic-gate 13480Sstevel@tonic-gate#endif /* __lint */ 1349