17c478bd9Sstevel@tonic-gate/* 27af88ac7SKuriakose Kuruvilla * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. 3*8e50396aSAdam H. Leventhal * Copyright (c) 2013, 2014 by Delphix. All rights reserved. 47c478bd9Sstevel@tonic-gate */ 57c478bd9Sstevel@tonic-gate 67c478bd9Sstevel@tonic-gate/* 77c478bd9Sstevel@tonic-gate * Copyright (c) 1989, 1990 William F. Jolitz. 87c478bd9Sstevel@tonic-gate * Copyright (c) 1990 The Regents of the University of California. 97c478bd9Sstevel@tonic-gate * All rights reserved. 107c478bd9Sstevel@tonic-gate * 117c478bd9Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without 127c478bd9Sstevel@tonic-gate * modification, are permitted provided that the following conditions 137c478bd9Sstevel@tonic-gate * are met: 147c478bd9Sstevel@tonic-gate * 1. Redistributions of source code must retain the above copyright 157c478bd9Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer. 167c478bd9Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright 177c478bd9Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in the 187c478bd9Sstevel@tonic-gate * documentation and/or other materials provided with the distribution. 197c478bd9Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this software 207c478bd9Sstevel@tonic-gate * must display the following acknowledgement: 217c478bd9Sstevel@tonic-gate * This product includes software developed by the University of 227c478bd9Sstevel@tonic-gate * California, Berkeley and its contributors. 237c478bd9Sstevel@tonic-gate * 4. Neither the name of the University nor the names of its contributors 247c478bd9Sstevel@tonic-gate * may be used to endorse or promote products derived from this software 257c478bd9Sstevel@tonic-gate * without specific prior written permission. 267c478bd9Sstevel@tonic-gate * 277c478bd9Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 287c478bd9Sstevel@tonic-gate * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 297c478bd9Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 307c478bd9Sstevel@tonic-gate * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 317c478bd9Sstevel@tonic-gate * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 327c478bd9Sstevel@tonic-gate * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 337c478bd9Sstevel@tonic-gate * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 347c478bd9Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 357c478bd9Sstevel@tonic-gate * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 367c478bd9Sstevel@tonic-gate * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 377c478bd9Sstevel@tonic-gate * SUCH DAMAGE. 387c478bd9Sstevel@tonic-gate * 397c478bd9Sstevel@tonic-gate * $FreeBSD: src/sys/amd64/amd64/exception.S,v 1.113 2003/10/15 02:04:52 peter Exp $ 407c478bd9Sstevel@tonic-gate */ 417c478bd9Sstevel@tonic-gate 427c478bd9Sstevel@tonic-gate#include <sys/asm_linkage.h> 437c478bd9Sstevel@tonic-gate#include <sys/asm_misc.h> 447c478bd9Sstevel@tonic-gate#include <sys/trap.h> 457c478bd9Sstevel@tonic-gate#include <sys/psw.h> 467c478bd9Sstevel@tonic-gate#include <sys/regset.h> 477c478bd9Sstevel@tonic-gate#include <sys/privregs.h> 487c478bd9Sstevel@tonic-gate#include <sys/dtrace.h> 49ae115bc7Smrj#include <sys/x86_archext.h> 507c478bd9Sstevel@tonic-gate#include <sys/traptrace.h> 5141791439Sandrei#include <sys/machparam.h> 527c478bd9Sstevel@tonic-gate 537c478bd9Sstevel@tonic-gate/* 547c478bd9Sstevel@tonic-gate * only one routine in this file is interesting to lint 557c478bd9Sstevel@tonic-gate */ 567c478bd9Sstevel@tonic-gate 577c478bd9Sstevel@tonic-gate#if defined(__lint) 587c478bd9Sstevel@tonic-gate 597c478bd9Sstevel@tonic-gatevoid 607c478bd9Sstevel@tonic-gatendptrap_frstor(void) 617c478bd9Sstevel@tonic-gate{} 627c478bd9Sstevel@tonic-gate 637c478bd9Sstevel@tonic-gate#else 647c478bd9Sstevel@tonic-gate 657c478bd9Sstevel@tonic-gate#include "assym.h" 667c478bd9Sstevel@tonic-gate 677c478bd9Sstevel@tonic-gate/* 687c478bd9Sstevel@tonic-gate * push $0 on stack for traps that do not 697c478bd9Sstevel@tonic-gate * generate an error code. This is so the rest 707c478bd9Sstevel@tonic-gate * of the kernel can expect a consistent stack 717c478bd9Sstevel@tonic-gate * from from any exception. 72843e1988Sjohnlev * 73843e1988Sjohnlev * Note that for all exceptions for amd64 74843e1988Sjohnlev * %r11 and %rcx are on the stack. Just pop 75843e1988Sjohnlev * them back into their appropriate registers and let 76843e1988Sjohnlev * it get saved as is running native. 777c478bd9Sstevel@tonic-gate */ 78ae115bc7Smrj 79843e1988Sjohnlev#if defined(__xpv) && defined(__amd64) 80843e1988Sjohnlev 81843e1988Sjohnlev#define NPTRAP_NOERR(trapno) \ 82843e1988Sjohnlev pushq $0; \ 83843e1988Sjohnlev pushq $trapno 84843e1988Sjohnlev 85843e1988Sjohnlev#define TRAP_NOERR(trapno) \ 86843e1988Sjohnlev XPV_TRAP_POP; \ 87843e1988Sjohnlev NPTRAP_NOERR(trapno) 88843e1988Sjohnlev 89843e1988Sjohnlev/* 90843e1988Sjohnlev * error code already pushed by hw 91843e1988Sjohnlev * onto stack. 92843e1988Sjohnlev */ 93843e1988Sjohnlev#define TRAP_ERR(trapno) \ 94843e1988Sjohnlev XPV_TRAP_POP; \ 95843e1988Sjohnlev pushq $trapno 96843e1988Sjohnlev 97843e1988Sjohnlev#else /* __xpv && __amd64 */ 98843e1988Sjohnlev 997c478bd9Sstevel@tonic-gate#define TRAP_NOERR(trapno) \ 1007c478bd9Sstevel@tonic-gate push $0; \ 1017c478bd9Sstevel@tonic-gate push $trapno 1027c478bd9Sstevel@tonic-gate 103ae115bc7Smrj#define NPTRAP_NOERR(trapno) TRAP_NOERR(trapno) 104ae115bc7Smrj 1057c478bd9Sstevel@tonic-gate/* 1067c478bd9Sstevel@tonic-gate * error code already pushed by hw 1077c478bd9Sstevel@tonic-gate * onto stack. 1087c478bd9Sstevel@tonic-gate */ 1097c478bd9Sstevel@tonic-gate#define TRAP_ERR(trapno) \ 1107c478bd9Sstevel@tonic-gate push $trapno 1117c478bd9Sstevel@tonic-gate 112843e1988Sjohnlev#endif /* __xpv && __amd64 */ 113843e1988Sjohnlev 114ae115bc7Smrj 1157c478bd9Sstevel@tonic-gate /* 1167c478bd9Sstevel@tonic-gate * #DE 1177c478bd9Sstevel@tonic-gate */ 1187c478bd9Sstevel@tonic-gate ENTRY_NP(div0trap) 1197c478bd9Sstevel@tonic-gate TRAP_NOERR(T_ZERODIV) /* $0 */ 1207c478bd9Sstevel@tonic-gate jmp cmntrap 1217c478bd9Sstevel@tonic-gate SET_SIZE(div0trap) 1227c478bd9Sstevel@tonic-gate 1237c478bd9Sstevel@tonic-gate /* 1247c478bd9Sstevel@tonic-gate * #DB 1257c478bd9Sstevel@tonic-gate * 126ae115bc7Smrj * Fetch %dr6 and clear it, handing off the value to the 127ae115bc7Smrj * cmntrap code in %r15/%esi 128ae115bc7Smrj */ 129ae115bc7Smrj ENTRY_NP(dbgtrap) 130ae115bc7Smrj TRAP_NOERR(T_SGLSTP) /* $1 */ 131ae115bc7Smrj 132ae115bc7Smrj#if defined(__amd64) 133843e1988Sjohnlev#if !defined(__xpv) /* no sysenter support yet */ 134ae115bc7Smrj /* 1357c478bd9Sstevel@tonic-gate * If we get here as a result of single-stepping a sysenter 1367c478bd9Sstevel@tonic-gate * instruction, we suddenly find ourselves taking a #db 1377c478bd9Sstevel@tonic-gate * in kernel mode -before- we've swapgs'ed. So before we can 1387c478bd9Sstevel@tonic-gate * take the trap, we do the swapgs here, and fix the return 1397c478bd9Sstevel@tonic-gate * %rip in trap() so that we return immediately after the 1407c478bd9Sstevel@tonic-gate * swapgs in the sysenter handler to avoid doing the swapgs again. 1417c478bd9Sstevel@tonic-gate * 1427c478bd9Sstevel@tonic-gate * Nobody said that the design of sysenter was particularly 1437c478bd9Sstevel@tonic-gate * elegant, did they? 1447c478bd9Sstevel@tonic-gate */ 14505456effSsherrym 1467c478bd9Sstevel@tonic-gate pushq %r11 14705456effSsherrym 14805456effSsherrym /* 14905456effSsherrym * At this point the stack looks like this: 15005456effSsherrym * 15105456effSsherrym * (high address) r_ss 15205456effSsherrym * r_rsp 15305456effSsherrym * r_rfl 15405456effSsherrym * r_cs 15505456effSsherrym * r_rip <-- %rsp + 24 15605456effSsherrym * r_err <-- %rsp + 16 15705456effSsherrym * r_trapno <-- %rsp + 8 15805456effSsherrym * (low address) %r11 <-- %rsp 15905456effSsherrym */ 1607c478bd9Sstevel@tonic-gate leaq sys_sysenter(%rip), %r11 16105456effSsherrym cmpq %r11, 24(%rsp) /* Compare to saved r_rip on the stack */ 1620022570dSjv227347 je 1f 1630022570dSjv227347 leaq brand_sys_sysenter(%rip), %r11 1640022570dSjv227347 cmpq %r11, 24(%rsp) /* Compare to saved r_rip on the stack */ 1650022570dSjv227347 jne 2f 1660022570dSjv2273471: SWAPGS 1670022570dSjv2273472: popq %r11 168843e1988Sjohnlev#endif /* !__xpv */ 169ae115bc7Smrj 170ae115bc7Smrj INTR_PUSH 171843e1988Sjohnlev#if defined(__xpv) 172843e1988Sjohnlev movl $6, %edi 173843e1988Sjohnlev call kdi_dreg_get 174843e1988Sjohnlev movq %rax, %r15 /* %db6 -> %r15 */ 175843e1988Sjohnlev movl $6, %edi 176843e1988Sjohnlev movl $0, %esi 177843e1988Sjohnlev call kdi_dreg_set /* 0 -> %db6 */ 178843e1988Sjohnlev#else 179ae115bc7Smrj movq %db6, %r15 180ae115bc7Smrj xorl %eax, %eax 181ae115bc7Smrj movq %rax, %db6 182843e1988Sjohnlev#endif 1837c478bd9Sstevel@tonic-gate 1847c478bd9Sstevel@tonic-gate#elif defined(__i386) 185ae115bc7Smrj 186ae115bc7Smrj INTR_PUSH 187843e1988Sjohnlev#if defined(__xpv) 188843e1988Sjohnlev pushl $6 189843e1988Sjohnlev call kdi_dreg_get 190843e1988Sjohnlev addl $4, %esp 191843e1988Sjohnlev movl %eax, %esi /* %dr6 -> %esi */ 192843e1988Sjohnlev pushl $0 193843e1988Sjohnlev pushl $6 194843e1988Sjohnlev call kdi_dreg_set /* 0 -> %dr6 */ 195843e1988Sjohnlev addl $8, %esp 196843e1988Sjohnlev#else 197ae115bc7Smrj movl %db6, %esi 198ae115bc7Smrj xorl %eax, %eax 199ae115bc7Smrj movl %eax, %db6 200843e1988Sjohnlev#endif 201ae115bc7Smrj#endif /* __i386 */ 202ae115bc7Smrj 203ae115bc7Smrj jmp cmntrap_pushed 2047c478bd9Sstevel@tonic-gate SET_SIZE(dbgtrap) 2057c478bd9Sstevel@tonic-gate 2067c478bd9Sstevel@tonic-gate#if defined(__amd64) 207843e1988Sjohnlev#if !defined(__xpv) 2087c478bd9Sstevel@tonic-gate 2097c478bd9Sstevel@tonic-gate/* 2107c478bd9Sstevel@tonic-gate * Macro to set the gsbase or kgsbase to the address of the struct cpu 211ae115bc7Smrj * for this processor. If we came from userland, set kgsbase else 212ae115bc7Smrj * set gsbase. We find the proper cpu struct by looping through 2137c478bd9Sstevel@tonic-gate * the cpu structs for all processors till we find a match for the gdt 2147c478bd9Sstevel@tonic-gate * of the trapping processor. The stack is expected to be pointing at 215ae115bc7Smrj * the standard regs pushed by hardware on a trap (plus error code and trapno). 2167c478bd9Sstevel@tonic-gate */ 2177c478bd9Sstevel@tonic-gate#define SET_CPU_GSBASE \ 2187c478bd9Sstevel@tonic-gate subq $REGOFF_TRAPNO, %rsp; /* save regs */ \ 2197c478bd9Sstevel@tonic-gate movq %rax, REGOFF_RAX(%rsp); \ 2207c478bd9Sstevel@tonic-gate movq %rbx, REGOFF_RBX(%rsp); \ 2217c478bd9Sstevel@tonic-gate movq %rcx, REGOFF_RCX(%rsp); \ 2227c478bd9Sstevel@tonic-gate movq %rdx, REGOFF_RDX(%rsp); \ 2237c478bd9Sstevel@tonic-gate movq %rbp, REGOFF_RBP(%rsp); \ 2247c478bd9Sstevel@tonic-gate movq %rsp, %rbp; \ 2257c478bd9Sstevel@tonic-gate subq $16, %rsp; /* space for gdt */ \ 2267c478bd9Sstevel@tonic-gate sgdt 6(%rsp); \ 2277c478bd9Sstevel@tonic-gate movq 8(%rsp), %rcx; /* %rcx has gdt to match */ \ 2287c478bd9Sstevel@tonic-gate xorl %ebx, %ebx; /* loop index */ \ 2297c478bd9Sstevel@tonic-gate leaq cpu(%rip), %rdx; /* cpu pointer array */ \ 2307c478bd9Sstevel@tonic-gate1: \ 2317c478bd9Sstevel@tonic-gate movq (%rdx, %rbx, CLONGSIZE), %rax; /* get cpu[i] */ \ 2327c478bd9Sstevel@tonic-gate cmpq $0x0, %rax; /* cpu[i] == NULL ? */ \ 2337c478bd9Sstevel@tonic-gate je 2f; /* yes, continue */ \ 2347c478bd9Sstevel@tonic-gate cmpq %rcx, CPU_GDT(%rax); /* gdt == cpu[i]->cpu_gdt ? */ \ 2357c478bd9Sstevel@tonic-gate je 3f; /* yes, go set gsbase */ \ 2367c478bd9Sstevel@tonic-gate2: \ 2377c478bd9Sstevel@tonic-gate incl %ebx; /* i++ */ \ 2387c478bd9Sstevel@tonic-gate cmpl $NCPU, %ebx; /* i < NCPU ? */ \ 2397c478bd9Sstevel@tonic-gate jb 1b; /* yes, loop */ \ 2407c478bd9Sstevel@tonic-gate/* XXX BIG trouble if we fall thru here. We didn't find a gdt match */ \ 2417c478bd9Sstevel@tonic-gate3: \ 2427c478bd9Sstevel@tonic-gate movl $MSR_AMD_KGSBASE, %ecx; \ 2437c478bd9Sstevel@tonic-gate cmpw $KCS_SEL, REGOFF_CS(%rbp); /* trap from kernel? */ \ 2447c478bd9Sstevel@tonic-gate jne 4f; /* no, go set KGSBASE */ \ 2457c478bd9Sstevel@tonic-gate movl $MSR_AMD_GSBASE, %ecx; /* yes, set GSBASE */ \ 2467c478bd9Sstevel@tonic-gate mfence; /* OPTERON_ERRATUM_88 */ \ 2477c478bd9Sstevel@tonic-gate4: \ 2487c478bd9Sstevel@tonic-gate movq %rax, %rdx; /* write base register */ \ 2497c478bd9Sstevel@tonic-gate shrq $32, %rdx; \ 2507c478bd9Sstevel@tonic-gate wrmsr; \ 2517c478bd9Sstevel@tonic-gate movq REGOFF_RDX(%rbp), %rdx; /* restore regs */ \ 2527c478bd9Sstevel@tonic-gate movq REGOFF_RCX(%rbp), %rcx; \ 2537c478bd9Sstevel@tonic-gate movq REGOFF_RBX(%rbp), %rbx; \ 2547c478bd9Sstevel@tonic-gate movq REGOFF_RAX(%rbp), %rax; \ 2557c478bd9Sstevel@tonic-gate movq %rbp, %rsp; \ 2567c478bd9Sstevel@tonic-gate movq REGOFF_RBP(%rsp), %rbp; \ 2577c478bd9Sstevel@tonic-gate addq $REGOFF_TRAPNO, %rsp /* pop stack */ 258ae115bc7Smrj 259843e1988Sjohnlev#else /* __xpv */ 260843e1988Sjohnlev 261843e1988Sjohnlev#define SET_CPU_GSBASE /* noop on the hypervisor */ 262843e1988Sjohnlev 263843e1988Sjohnlev#endif /* __xpv */ 2647c478bd9Sstevel@tonic-gate#endif /* __amd64 */ 2657c478bd9Sstevel@tonic-gate 2667c478bd9Sstevel@tonic-gate 2677c478bd9Sstevel@tonic-gate#if defined(__amd64) 2687c478bd9Sstevel@tonic-gate 2697c478bd9Sstevel@tonic-gate /* 2707c478bd9Sstevel@tonic-gate * #NMI 271843e1988Sjohnlev * 272843e1988Sjohnlev * XXPV: See 6532669. 2737c478bd9Sstevel@tonic-gate */ 2747c478bd9Sstevel@tonic-gate ENTRY_NP(nmiint) 2757c478bd9Sstevel@tonic-gate TRAP_NOERR(T_NMIFLT) /* $2 */ 2767c478bd9Sstevel@tonic-gate 2777c478bd9Sstevel@tonic-gate SET_CPU_GSBASE 2787c478bd9Sstevel@tonic-gate 2797c478bd9Sstevel@tonic-gate /* 2807c478bd9Sstevel@tonic-gate * Save all registers and setup segment registers 2817c478bd9Sstevel@tonic-gate * with kernel selectors. 2827c478bd9Sstevel@tonic-gate */ 2837c478bd9Sstevel@tonic-gate INTR_PUSH 284ae115bc7Smrj INTGATE_INIT_KERNEL_FLAGS 2857c478bd9Sstevel@tonic-gate 2867c478bd9Sstevel@tonic-gate TRACE_PTR(%r12, %rax, %eax, %rdx, $TT_TRAP) 2877c478bd9Sstevel@tonic-gate TRACE_REGS(%r12, %rsp, %rax, %rbx) 2887c478bd9Sstevel@tonic-gate TRACE_STAMP(%r12) 2897c478bd9Sstevel@tonic-gate 2907c478bd9Sstevel@tonic-gate movq %rsp, %rbp 2917c478bd9Sstevel@tonic-gate 2927c478bd9Sstevel@tonic-gate movq %rbp, %rdi 2937c478bd9Sstevel@tonic-gate call av_dispatch_nmivect 2947c478bd9Sstevel@tonic-gate 2957c478bd9Sstevel@tonic-gate INTR_POP 296ae115bc7Smrj IRET 297ae115bc7Smrj /*NOTREACHED*/ 2987c478bd9Sstevel@tonic-gate SET_SIZE(nmiint) 2997c478bd9Sstevel@tonic-gate 3007c478bd9Sstevel@tonic-gate#elif defined(__i386) 3017c478bd9Sstevel@tonic-gate 3027c478bd9Sstevel@tonic-gate /* 3037c478bd9Sstevel@tonic-gate * #NMI 3047c478bd9Sstevel@tonic-gate */ 3057c478bd9Sstevel@tonic-gate ENTRY_NP(nmiint) 3067c478bd9Sstevel@tonic-gate TRAP_NOERR(T_NMIFLT) /* $2 */ 3077c478bd9Sstevel@tonic-gate 3087c478bd9Sstevel@tonic-gate /* 3097c478bd9Sstevel@tonic-gate * Save all registers and setup segment registers 3107c478bd9Sstevel@tonic-gate * with kernel selectors. 3117c478bd9Sstevel@tonic-gate */ 3127c478bd9Sstevel@tonic-gate INTR_PUSH 313ae115bc7Smrj INTGATE_INIT_KERNEL_FLAGS 3147c478bd9Sstevel@tonic-gate 315ae115bc7Smrj TRACE_PTR(%edi, %ebx, %ebx, %ecx, $TT_TRAP) 316ae115bc7Smrj TRACE_REGS(%edi, %esp, %ebx, %ecx) 317ae115bc7Smrj TRACE_STAMP(%edi) 318ae115bc7Smrj 3197c478bd9Sstevel@tonic-gate movl %esp, %ebp 320ae115bc7Smrj 3217c478bd9Sstevel@tonic-gate pushl %ebp 322ae115bc7Smrj call av_dispatch_nmivect 3237c478bd9Sstevel@tonic-gate addl $4, %esp 3247c478bd9Sstevel@tonic-gate 3257c478bd9Sstevel@tonic-gate INTR_POP_USER 326ae115bc7Smrj IRET 3277c478bd9Sstevel@tonic-gate SET_SIZE(nmiint) 3287c478bd9Sstevel@tonic-gate 3297c478bd9Sstevel@tonic-gate#endif /* __i386 */ 3307c478bd9Sstevel@tonic-gate 3317c478bd9Sstevel@tonic-gate /* 3327c478bd9Sstevel@tonic-gate * #BP 3337c478bd9Sstevel@tonic-gate */ 3347c478bd9Sstevel@tonic-gate ENTRY_NP(brktrap) 335ae115bc7Smrj 3367c478bd9Sstevel@tonic-gate#if defined(__amd64) 337843e1988Sjohnlev XPV_TRAP_POP 3387c478bd9Sstevel@tonic-gate cmpw $KCS_SEL, 8(%rsp) 339ae115bc7Smrj jne bp_user 3407c478bd9Sstevel@tonic-gate 3417c478bd9Sstevel@tonic-gate /* 3427c478bd9Sstevel@tonic-gate * This is a breakpoint in the kernel -- it is very likely that this 3437c478bd9Sstevel@tonic-gate * is DTrace-induced. To unify DTrace handling, we spoof this as an 3447c478bd9Sstevel@tonic-gate * invalid opcode (#UD) fault. Note that #BP is a trap, not a fault -- 3457c478bd9Sstevel@tonic-gate * we must decrement the trapping %rip to make it appear as a fault. 3467c478bd9Sstevel@tonic-gate * We then push a non-zero error code to indicate that this is coming 3477c478bd9Sstevel@tonic-gate * from #BP. 3487c478bd9Sstevel@tonic-gate */ 3497c478bd9Sstevel@tonic-gate decq (%rsp) 3507c478bd9Sstevel@tonic-gate push $1 /* error code -- non-zero for #BP */ 3517c478bd9Sstevel@tonic-gate jmp ud_kernel 352ae115bc7Smrj 353ae115bc7Smrjbp_user: 354ae115bc7Smrj#endif /* __amd64 */ 355ae115bc7Smrj 356ae115bc7Smrj NPTRAP_NOERR(T_BPTFLT) /* $3 */ 357ae115bc7Smrj jmp dtrace_trap 3587c478bd9Sstevel@tonic-gate 3597c478bd9Sstevel@tonic-gate SET_SIZE(brktrap) 3607c478bd9Sstevel@tonic-gate 3617c478bd9Sstevel@tonic-gate /* 3627c478bd9Sstevel@tonic-gate * #OF 3637c478bd9Sstevel@tonic-gate */ 3647c478bd9Sstevel@tonic-gate ENTRY_NP(ovflotrap) 3657c478bd9Sstevel@tonic-gate TRAP_NOERR(T_OVFLW) /* $4 */ 3667c478bd9Sstevel@tonic-gate jmp cmntrap 3677c478bd9Sstevel@tonic-gate SET_SIZE(ovflotrap) 3687c478bd9Sstevel@tonic-gate 3697c478bd9Sstevel@tonic-gate /* 3707c478bd9Sstevel@tonic-gate * #BR 3717c478bd9Sstevel@tonic-gate */ 3727c478bd9Sstevel@tonic-gate ENTRY_NP(boundstrap) 3737c478bd9Sstevel@tonic-gate TRAP_NOERR(T_BOUNDFLT) /* $5 */ 3747c478bd9Sstevel@tonic-gate jmp cmntrap 3757c478bd9Sstevel@tonic-gate SET_SIZE(boundstrap) 3767c478bd9Sstevel@tonic-gate 3777c478bd9Sstevel@tonic-gate#if defined(__amd64) 3787c478bd9Sstevel@tonic-gate 3797c478bd9Sstevel@tonic-gate ENTRY_NP(invoptrap) 380ae115bc7Smrj 381843e1988Sjohnlev XPV_TRAP_POP 382843e1988Sjohnlev 3837c478bd9Sstevel@tonic-gate cmpw $KCS_SEL, 8(%rsp) 3847c478bd9Sstevel@tonic-gate jne ud_user 3857c478bd9Sstevel@tonic-gate 386843e1988Sjohnlev#if defined(__xpv) 387843e1988Sjohnlev movb $0, 12(%rsp) /* clear saved upcall_mask from %cs */ 388843e1988Sjohnlev#endif 3897c478bd9Sstevel@tonic-gate push $0 /* error code -- zero for #UD */ 3907c478bd9Sstevel@tonic-gateud_kernel: 3917c478bd9Sstevel@tonic-gate push $0xdddd /* a dummy trap number */ 392ae115bc7Smrj INTR_PUSH 3937c478bd9Sstevel@tonic-gate movq REGOFF_RIP(%rsp), %rdi 3947c478bd9Sstevel@tonic-gate movq REGOFF_RSP(%rsp), %rsi 3957c478bd9Sstevel@tonic-gate movq REGOFF_RAX(%rsp), %rdx 3967c478bd9Sstevel@tonic-gate pushq (%rsi) 3977c478bd9Sstevel@tonic-gate movq %rsp, %rsi 398*8e50396aSAdam H. Leventhal subq $8, %rsp 3997c478bd9Sstevel@tonic-gate call dtrace_invop 4007c478bd9Sstevel@tonic-gate ALTENTRY(dtrace_invop_callsite) 401*8e50396aSAdam H. Leventhal addq $16, %rsp 4027c478bd9Sstevel@tonic-gate cmpl $DTRACE_INVOP_PUSHL_EBP, %eax 4037c478bd9Sstevel@tonic-gate je ud_push 4047c478bd9Sstevel@tonic-gate cmpl $DTRACE_INVOP_LEAVE, %eax 4057c478bd9Sstevel@tonic-gate je ud_leave 4067c478bd9Sstevel@tonic-gate cmpl $DTRACE_INVOP_NOP, %eax 4077c478bd9Sstevel@tonic-gate je ud_nop 4087c478bd9Sstevel@tonic-gate cmpl $DTRACE_INVOP_RET, %eax 4097c478bd9Sstevel@tonic-gate je ud_ret 4107c478bd9Sstevel@tonic-gate jmp ud_trap 4117c478bd9Sstevel@tonic-gate 4127c478bd9Sstevel@tonic-gateud_push: 4137c478bd9Sstevel@tonic-gate /* 4147c478bd9Sstevel@tonic-gate * We must emulate a "pushq %rbp". To do this, we pull the stack 4157c478bd9Sstevel@tonic-gate * down 8 bytes, and then store the base pointer. 4167c478bd9Sstevel@tonic-gate */ 4177c478bd9Sstevel@tonic-gate INTR_POP 4187c478bd9Sstevel@tonic-gate subq $16, %rsp /* make room for %rbp */ 4197c478bd9Sstevel@tonic-gate pushq %rax /* push temp */ 4207c478bd9Sstevel@tonic-gate movq 24(%rsp), %rax /* load calling RIP */ 4217c478bd9Sstevel@tonic-gate addq $1, %rax /* increment over trapping instr */ 4227c478bd9Sstevel@tonic-gate movq %rax, 8(%rsp) /* store calling RIP */ 4237c478bd9Sstevel@tonic-gate movq 32(%rsp), %rax /* load calling CS */ 4247c478bd9Sstevel@tonic-gate movq %rax, 16(%rsp) /* store calling CS */ 4257c478bd9Sstevel@tonic-gate movq 40(%rsp), %rax /* load calling RFLAGS */ 4267c478bd9Sstevel@tonic-gate movq %rax, 24(%rsp) /* store calling RFLAGS */ 4277c478bd9Sstevel@tonic-gate movq 48(%rsp), %rax /* load calling RSP */ 4287c478bd9Sstevel@tonic-gate subq $8, %rax /* make room for %rbp */ 4297c478bd9Sstevel@tonic-gate movq %rax, 32(%rsp) /* store calling RSP */ 4307c478bd9Sstevel@tonic-gate movq 56(%rsp), %rax /* load calling SS */ 4317c478bd9Sstevel@tonic-gate movq %rax, 40(%rsp) /* store calling SS */ 4327c478bd9Sstevel@tonic-gate movq 32(%rsp), %rax /* reload calling RSP */ 4337c478bd9Sstevel@tonic-gate movq %rbp, (%rax) /* store %rbp there */ 4347c478bd9Sstevel@tonic-gate popq %rax /* pop off temp */ 435ae115bc7Smrj IRET /* return from interrupt */ 436ae115bc7Smrj /*NOTREACHED*/ 4377c478bd9Sstevel@tonic-gate 4387c478bd9Sstevel@tonic-gateud_leave: 4397c478bd9Sstevel@tonic-gate /* 4407c478bd9Sstevel@tonic-gate * We must emulate a "leave", which is the same as a "movq %rbp, %rsp" 4417c478bd9Sstevel@tonic-gate * followed by a "popq %rbp". This is quite a bit simpler on amd64 4427c478bd9Sstevel@tonic-gate * than it is on i386 -- we can exploit the fact that the %rsp is 4437c478bd9Sstevel@tonic-gate * explicitly saved to effect the pop without having to reshuffle 4447c478bd9Sstevel@tonic-gate * the other data pushed for the trap. 4457c478bd9Sstevel@tonic-gate */ 4467c478bd9Sstevel@tonic-gate INTR_POP 4477c478bd9Sstevel@tonic-gate pushq %rax /* push temp */ 4487c478bd9Sstevel@tonic-gate movq 8(%rsp), %rax /* load calling RIP */ 4497c478bd9Sstevel@tonic-gate addq $1, %rax /* increment over trapping instr */ 4507c478bd9Sstevel@tonic-gate movq %rax, 8(%rsp) /* store calling RIP */ 4517c478bd9Sstevel@tonic-gate movq (%rbp), %rax /* get new %rbp */ 4527c478bd9Sstevel@tonic-gate addq $8, %rbp /* adjust new %rsp */ 4537c478bd9Sstevel@tonic-gate movq %rbp, 32(%rsp) /* store new %rsp */ 4547c478bd9Sstevel@tonic-gate movq %rax, %rbp /* set new %rbp */ 4557c478bd9Sstevel@tonic-gate popq %rax /* pop off temp */ 456ae115bc7Smrj IRET /* return from interrupt */ 457ae115bc7Smrj /*NOTREACHED*/ 4587c478bd9Sstevel@tonic-gate 4597c478bd9Sstevel@tonic-gateud_nop: 4607c478bd9Sstevel@tonic-gate /* 4617c478bd9Sstevel@tonic-gate * We must emulate a "nop". This is obviously not hard: we need only 4627c478bd9Sstevel@tonic-gate * advance the %rip by one. 4637c478bd9Sstevel@tonic-gate */ 4647c478bd9Sstevel@tonic-gate INTR_POP 4657c478bd9Sstevel@tonic-gate incq (%rsp) 466ae115bc7Smrj IRET 467ae115bc7Smrj /*NOTREACHED*/ 4687c478bd9Sstevel@tonic-gate 4697c478bd9Sstevel@tonic-gateud_ret: 4707c478bd9Sstevel@tonic-gate INTR_POP 4717c478bd9Sstevel@tonic-gate pushq %rax /* push temp */ 4727c478bd9Sstevel@tonic-gate movq 32(%rsp), %rax /* load %rsp */ 4737c478bd9Sstevel@tonic-gate movq (%rax), %rax /* load calling RIP */ 4747c478bd9Sstevel@tonic-gate movq %rax, 8(%rsp) /* store calling RIP */ 4757c478bd9Sstevel@tonic-gate addq $8, 32(%rsp) /* adjust new %rsp */ 4767c478bd9Sstevel@tonic-gate popq %rax /* pop off temp */ 477ae115bc7Smrj IRET /* return from interrupt */ 478ae115bc7Smrj /*NOTREACHED*/ 4797c478bd9Sstevel@tonic-gate 4807c478bd9Sstevel@tonic-gateud_trap: 4817c478bd9Sstevel@tonic-gate /* 4827c478bd9Sstevel@tonic-gate * We're going to let the kernel handle this as a normal #UD. If, 4837c478bd9Sstevel@tonic-gate * however, we came through #BP and are spoofing #UD (in this case, 4847c478bd9Sstevel@tonic-gate * the stored error value will be non-zero), we need to de-spoof 4857c478bd9Sstevel@tonic-gate * the trap by incrementing %rip and pushing T_BPTFLT. 4867c478bd9Sstevel@tonic-gate */ 4877c478bd9Sstevel@tonic-gate cmpq $0, REGOFF_ERR(%rsp) 4887c478bd9Sstevel@tonic-gate je ud_ud 4897c478bd9Sstevel@tonic-gate incq REGOFF_RIP(%rsp) 4907c478bd9Sstevel@tonic-gate addq $REGOFF_RIP, %rsp 491ae115bc7Smrj NPTRAP_NOERR(T_BPTFLT) /* $3 */ 4927c478bd9Sstevel@tonic-gate jmp cmntrap 4937c478bd9Sstevel@tonic-gate 4947c478bd9Sstevel@tonic-gateud_ud: 4957c478bd9Sstevel@tonic-gate addq $REGOFF_RIP, %rsp 4967c478bd9Sstevel@tonic-gateud_user: 497ae115bc7Smrj NPTRAP_NOERR(T_ILLINST) 4987c478bd9Sstevel@tonic-gate jmp cmntrap 4997c478bd9Sstevel@tonic-gate SET_SIZE(invoptrap) 5007c478bd9Sstevel@tonic-gate 5017c478bd9Sstevel@tonic-gate#elif defined(__i386) 5027c478bd9Sstevel@tonic-gate 5037c478bd9Sstevel@tonic-gate /* 5047c478bd9Sstevel@tonic-gate * #UD 5057c478bd9Sstevel@tonic-gate */ 5067c478bd9Sstevel@tonic-gate ENTRY_NP(invoptrap) 5077c478bd9Sstevel@tonic-gate /* 5087c478bd9Sstevel@tonic-gate * If we are taking an invalid opcode trap while in the kernel, this 5097c478bd9Sstevel@tonic-gate * is likely an FBT probe point. 5107c478bd9Sstevel@tonic-gate */ 5117c478bd9Sstevel@tonic-gate pushl %gs 5127c478bd9Sstevel@tonic-gate cmpw $KGS_SEL, (%esp) 5137c478bd9Sstevel@tonic-gate jne 8f 514ae115bc7Smrj 5157c478bd9Sstevel@tonic-gate addl $4, %esp 516843e1988Sjohnlev#if defined(__xpv) 517843e1988Sjohnlev movb $0, 6(%esp) /* clear saved upcall_mask from %cs */ 518843e1988Sjohnlev#endif /* __xpv */ 5197c478bd9Sstevel@tonic-gate pusha 5207c478bd9Sstevel@tonic-gate pushl %eax /* push %eax -- may be return value */ 5217c478bd9Sstevel@tonic-gate pushl %esp /* push stack pointer */ 5227c478bd9Sstevel@tonic-gate addl $48, (%esp) /* adjust to incoming args */ 5237c478bd9Sstevel@tonic-gate pushl 40(%esp) /* push calling EIP */ 5247c478bd9Sstevel@tonic-gate call dtrace_invop 5257c478bd9Sstevel@tonic-gate ALTENTRY(dtrace_invop_callsite) 5267c478bd9Sstevel@tonic-gate addl $12, %esp 5277c478bd9Sstevel@tonic-gate cmpl $DTRACE_INVOP_PUSHL_EBP, %eax 5287c478bd9Sstevel@tonic-gate je 1f 5297c478bd9Sstevel@tonic-gate cmpl $DTRACE_INVOP_POPL_EBP, %eax 5307c478bd9Sstevel@tonic-gate je 2f 5317c478bd9Sstevel@tonic-gate cmpl $DTRACE_INVOP_LEAVE, %eax 5327c478bd9Sstevel@tonic-gate je 3f 5337c478bd9Sstevel@tonic-gate cmpl $DTRACE_INVOP_NOP, %eax 5347c478bd9Sstevel@tonic-gate je 4f 5357c478bd9Sstevel@tonic-gate jmp 7f 5367c478bd9Sstevel@tonic-gate1: 5377c478bd9Sstevel@tonic-gate /* 5387c478bd9Sstevel@tonic-gate * We must emulate a "pushl %ebp". To do this, we pull the stack 5397c478bd9Sstevel@tonic-gate * down 4 bytes, and then store the base pointer. 5407c478bd9Sstevel@tonic-gate */ 5417c478bd9Sstevel@tonic-gate popa 5427c478bd9Sstevel@tonic-gate subl $4, %esp /* make room for %ebp */ 5437c478bd9Sstevel@tonic-gate pushl %eax /* push temp */ 5447c478bd9Sstevel@tonic-gate movl 8(%esp), %eax /* load calling EIP */ 5457c478bd9Sstevel@tonic-gate incl %eax /* increment over LOCK prefix */ 5467c478bd9Sstevel@tonic-gate movl %eax, 4(%esp) /* store calling EIP */ 5477c478bd9Sstevel@tonic-gate movl 12(%esp), %eax /* load calling CS */ 5487c478bd9Sstevel@tonic-gate movl %eax, 8(%esp) /* store calling CS */ 5497c478bd9Sstevel@tonic-gate movl 16(%esp), %eax /* load calling EFLAGS */ 5507c478bd9Sstevel@tonic-gate movl %eax, 12(%esp) /* store calling EFLAGS */ 5517c478bd9Sstevel@tonic-gate movl %ebp, 16(%esp) /* push %ebp */ 5527c478bd9Sstevel@tonic-gate popl %eax /* pop off temp */ 553ae115bc7Smrj jmp _emul_done 5547c478bd9Sstevel@tonic-gate2: 5557c478bd9Sstevel@tonic-gate /* 5567c478bd9Sstevel@tonic-gate * We must emulate a "popl %ebp". To do this, we do the opposite of 5577c478bd9Sstevel@tonic-gate * the above: we remove the %ebp from the stack, and squeeze up the 5587c478bd9Sstevel@tonic-gate * saved state from the trap. 5597c478bd9Sstevel@tonic-gate */ 5607c478bd9Sstevel@tonic-gate popa 5617c478bd9Sstevel@tonic-gate pushl %eax /* push temp */ 5627c478bd9Sstevel@tonic-gate movl 16(%esp), %ebp /* pop %ebp */ 5637c478bd9Sstevel@tonic-gate movl 12(%esp), %eax /* load calling EFLAGS */ 5647c478bd9Sstevel@tonic-gate movl %eax, 16(%esp) /* store calling EFLAGS */ 5657c478bd9Sstevel@tonic-gate movl 8(%esp), %eax /* load calling CS */ 5667c478bd9Sstevel@tonic-gate movl %eax, 12(%esp) /* store calling CS */ 5677c478bd9Sstevel@tonic-gate movl 4(%esp), %eax /* load calling EIP */ 5687c478bd9Sstevel@tonic-gate incl %eax /* increment over LOCK prefix */ 5697c478bd9Sstevel@tonic-gate movl %eax, 8(%esp) /* store calling EIP */ 5707c478bd9Sstevel@tonic-gate popl %eax /* pop off temp */ 5717c478bd9Sstevel@tonic-gate addl $4, %esp /* adjust stack pointer */ 572ae115bc7Smrj jmp _emul_done 5737c478bd9Sstevel@tonic-gate3: 5747c478bd9Sstevel@tonic-gate /* 5757c478bd9Sstevel@tonic-gate * We must emulate a "leave", which is the same as a "movl %ebp, %esp" 5767c478bd9Sstevel@tonic-gate * followed by a "popl %ebp". This looks similar to the above, but 5777c478bd9Sstevel@tonic-gate * requires two temporaries: one for the new base pointer, and one 5787c478bd9Sstevel@tonic-gate * for the staging register. 5797c478bd9Sstevel@tonic-gate */ 5807c478bd9Sstevel@tonic-gate popa 5817c478bd9Sstevel@tonic-gate pushl %eax /* push temp */ 5827c478bd9Sstevel@tonic-gate pushl %ebx /* push temp */ 5837c478bd9Sstevel@tonic-gate movl %ebp, %ebx /* set temp to old %ebp */ 5847c478bd9Sstevel@tonic-gate movl (%ebx), %ebp /* pop %ebp */ 5857c478bd9Sstevel@tonic-gate movl 16(%esp), %eax /* load calling EFLAGS */ 5867c478bd9Sstevel@tonic-gate movl %eax, (%ebx) /* store calling EFLAGS */ 5877c478bd9Sstevel@tonic-gate movl 12(%esp), %eax /* load calling CS */ 5887c478bd9Sstevel@tonic-gate movl %eax, -4(%ebx) /* store calling CS */ 5897c478bd9Sstevel@tonic-gate movl 8(%esp), %eax /* load calling EIP */ 5907c478bd9Sstevel@tonic-gate incl %eax /* increment over LOCK prefix */ 5917c478bd9Sstevel@tonic-gate movl %eax, -8(%ebx) /* store calling EIP */ 5927c478bd9Sstevel@tonic-gate movl %ebx, -4(%esp) /* temporarily store new %esp */ 5937c478bd9Sstevel@tonic-gate popl %ebx /* pop off temp */ 5947c478bd9Sstevel@tonic-gate popl %eax /* pop off temp */ 5957c478bd9Sstevel@tonic-gate movl -12(%esp), %esp /* set stack pointer */ 5967c478bd9Sstevel@tonic-gate subl $8, %esp /* adjust for three pushes, one pop */ 597ae115bc7Smrj jmp _emul_done 5987c478bd9Sstevel@tonic-gate4: 5997c478bd9Sstevel@tonic-gate /* 6007c478bd9Sstevel@tonic-gate * We must emulate a "nop". This is obviously not hard: we need only 6017c478bd9Sstevel@tonic-gate * advance the %eip by one. 6027c478bd9Sstevel@tonic-gate */ 6037c478bd9Sstevel@tonic-gate popa 6047c478bd9Sstevel@tonic-gate incl (%esp) 605ae115bc7Smrj_emul_done: 606ae115bc7Smrj IRET /* return from interrupt */ 6077c478bd9Sstevel@tonic-gate7: 6087c478bd9Sstevel@tonic-gate popa 6097c478bd9Sstevel@tonic-gate pushl $0 6107c478bd9Sstevel@tonic-gate pushl $T_ILLINST /* $6 */ 6117c478bd9Sstevel@tonic-gate jmp cmntrap 6127c478bd9Sstevel@tonic-gate8: 6137c478bd9Sstevel@tonic-gate addl $4, %esp 6147c478bd9Sstevel@tonic-gate pushl $0 6157c478bd9Sstevel@tonic-gate pushl $T_ILLINST /* $6 */ 6167c478bd9Sstevel@tonic-gate jmp cmntrap 6177c478bd9Sstevel@tonic-gate SET_SIZE(invoptrap) 6187c478bd9Sstevel@tonic-gate 6197c478bd9Sstevel@tonic-gate#endif /* __i386 */ 6207c478bd9Sstevel@tonic-gate 6217c478bd9Sstevel@tonic-gate#if defined(__amd64) 6227c478bd9Sstevel@tonic-gate 6237c478bd9Sstevel@tonic-gate /* 6247c478bd9Sstevel@tonic-gate * #NM 6257c478bd9Sstevel@tonic-gate */ 626843e1988Sjohnlev#if defined(__xpv) 627843e1988Sjohnlev 628843e1988Sjohnlev ENTRY_NP(ndptrap) 629843e1988Sjohnlev /* 630843e1988Sjohnlev * (On the hypervisor we must make a hypercall so we might as well 631843e1988Sjohnlev * save everything and handle as in a normal trap.) 632843e1988Sjohnlev */ 633843e1988Sjohnlev TRAP_NOERR(T_NOEXTFLT) /* $7 */ 634843e1988Sjohnlev INTR_PUSH 635843e1988Sjohnlev 636843e1988Sjohnlev /* 637843e1988Sjohnlev * We want to do this quickly as every lwp using fp will take this 638843e1988Sjohnlev * after a context switch -- we do the frequent path in ndptrap_frstor 639843e1988Sjohnlev * below; for all other cases, we let the trap code handle it 640843e1988Sjohnlev */ 6417af88ac7SKuriakose Kuruvilla LOADCPU(%rax) /* swapgs handled in hypervisor */ 642843e1988Sjohnlev cmpl $0, fpu_exists(%rip) 643843e1988Sjohnlev je .handle_in_trap /* let trap handle no fp case */ 6447af88ac7SKuriakose Kuruvilla movq CPU_THREAD(%rax), %rbx /* %rbx = curthread */ 6457af88ac7SKuriakose Kuruvilla movl $FPU_EN, %eax 6467af88ac7SKuriakose Kuruvilla movq T_LWP(%rbx), %rbx /* %rbx = lwp */ 6477af88ac7SKuriakose Kuruvilla testq %rbx, %rbx 648843e1988Sjohnlev jz .handle_in_trap /* should not happen? */ 649843e1988Sjohnlev#if LWP_PCB_FPU != 0 6507af88ac7SKuriakose Kuruvilla addq $LWP_PCB_FPU, %rbx /* &lwp->lwp_pcb.pcb_fpu */ 651843e1988Sjohnlev#endif 6527af88ac7SKuriakose Kuruvilla testl %eax, PCB_FPU_FLAGS(%rbx) 653843e1988Sjohnlev jz .handle_in_trap /* must be the first fault */ 654843e1988Sjohnlev CLTS 6557af88ac7SKuriakose Kuruvilla andl $_BITNOT(FPU_VALID), PCB_FPU_FLAGS(%rbx) 656843e1988Sjohnlev#if FPU_CTX_FPU_REGS != 0 6577af88ac7SKuriakose Kuruvilla addq $FPU_CTX_FPU_REGS, %rbx 658843e1988Sjohnlev#endif 6597af88ac7SKuriakose Kuruvilla 6607af88ac7SKuriakose Kuruvilla movl FPU_CTX_FPU_XSAVE_MASK(%rbx), %eax /* for xrstor */ 6617af88ac7SKuriakose Kuruvilla movl FPU_CTX_FPU_XSAVE_MASK+4(%rbx), %edx /* for xrstor */ 6627af88ac7SKuriakose Kuruvilla 663843e1988Sjohnlev /* 664843e1988Sjohnlev * the label below is used in trap.c to detect FP faults in 665843e1988Sjohnlev * kernel due to user fault. 666843e1988Sjohnlev */ 667843e1988Sjohnlev ALTENTRY(ndptrap_frstor) 6687af88ac7SKuriakose Kuruvilla .globl _patch_xrstorq_rbx 6697af88ac7SKuriakose Kuruvilla_patch_xrstorq_rbx: 6707af88ac7SKuriakose Kuruvilla FXRSTORQ ((%rbx)) 671843e1988Sjohnlev cmpw $KCS_SEL, REGOFF_CS(%rsp) 672843e1988Sjohnlev je .return_to_kernel 673843e1988Sjohnlev 674843e1988Sjohnlev ASSERT_UPCALL_MASK_IS_SET 675843e1988Sjohnlev USER_POP 676843e1988Sjohnlev IRET /* return to user mode */ 677843e1988Sjohnlev /*NOTREACHED*/ 678843e1988Sjohnlev 679843e1988Sjohnlev.return_to_kernel: 680843e1988Sjohnlev INTR_POP 681843e1988Sjohnlev IRET 682843e1988Sjohnlev /*NOTREACHED*/ 683843e1988Sjohnlev 684843e1988Sjohnlev.handle_in_trap: 685843e1988Sjohnlev INTR_POP 686843e1988Sjohnlev pushq $0 /* can not use TRAP_NOERR */ 687843e1988Sjohnlev pushq $T_NOEXTFLT 688843e1988Sjohnlev jmp cmninttrap 689843e1988Sjohnlev SET_SIZE(ndptrap_frstor) 690843e1988Sjohnlev SET_SIZE(ndptrap) 691843e1988Sjohnlev 692843e1988Sjohnlev#else /* __xpv */ 693843e1988Sjohnlev 6947c478bd9Sstevel@tonic-gate ENTRY_NP(ndptrap) 6957c478bd9Sstevel@tonic-gate /* 6967c478bd9Sstevel@tonic-gate * We want to do this quickly as every lwp using fp will take this 6977c478bd9Sstevel@tonic-gate * after a context switch -- we do the frequent path in ndptrap_frstor 6987c478bd9Sstevel@tonic-gate * below; for all other cases, we let the trap code handle it 6997c478bd9Sstevel@tonic-gate */ 7007c478bd9Sstevel@tonic-gate pushq %rax 7017c478bd9Sstevel@tonic-gate pushq %rbx 7027c478bd9Sstevel@tonic-gate cmpw $KCS_SEL, 24(%rsp) /* did we come from kernel mode? */ 7037c478bd9Sstevel@tonic-gate jne 1f 7047af88ac7SKuriakose Kuruvilla LOADCPU(%rax) /* if yes, don't swapgs */ 7057c478bd9Sstevel@tonic-gate jmp 2f 7067c478bd9Sstevel@tonic-gate1: 707ae115bc7Smrj SWAPGS /* if from user, need swapgs */ 7087af88ac7SKuriakose Kuruvilla LOADCPU(%rax) 709ae115bc7Smrj SWAPGS 7107c478bd9Sstevel@tonic-gate2: 7117af88ac7SKuriakose Kuruvilla /* 7127af88ac7SKuriakose Kuruvilla * Xrstor needs to use edx as part of its flag. 7137af88ac7SKuriakose Kuruvilla * NOTE: have to push rdx after "cmpw ...24(%rsp)", otherwise rsp+$24 7147af88ac7SKuriakose Kuruvilla * will not point to CS. 7157af88ac7SKuriakose Kuruvilla */ 7167af88ac7SKuriakose Kuruvilla pushq %rdx 7177c478bd9Sstevel@tonic-gate cmpl $0, fpu_exists(%rip) 7187c478bd9Sstevel@tonic-gate je .handle_in_trap /* let trap handle no fp case */ 7197af88ac7SKuriakose Kuruvilla movq CPU_THREAD(%rax), %rbx /* %rbx = curthread */ 7207af88ac7SKuriakose Kuruvilla movl $FPU_EN, %eax 7217af88ac7SKuriakose Kuruvilla movq T_LWP(%rbx), %rbx /* %rbx = lwp */ 7227af88ac7SKuriakose Kuruvilla testq %rbx, %rbx 7237c478bd9Sstevel@tonic-gate jz .handle_in_trap /* should not happen? */ 7247c478bd9Sstevel@tonic-gate#if LWP_PCB_FPU != 0 7257af88ac7SKuriakose Kuruvilla addq $LWP_PCB_FPU, %rbx /* &lwp->lwp_pcb.pcb_fpu */ 7267c478bd9Sstevel@tonic-gate#endif 7277af88ac7SKuriakose Kuruvilla testl %eax, PCB_FPU_FLAGS(%rbx) 7287c478bd9Sstevel@tonic-gate jz .handle_in_trap /* must be the first fault */ 7297c478bd9Sstevel@tonic-gate clts 7307af88ac7SKuriakose Kuruvilla andl $_BITNOT(FPU_VALID), PCB_FPU_FLAGS(%rbx) 7317c478bd9Sstevel@tonic-gate#if FPU_CTX_FPU_REGS != 0 7327af88ac7SKuriakose Kuruvilla addq $FPU_CTX_FPU_REGS, %rbx 7337c478bd9Sstevel@tonic-gate#endif 7347af88ac7SKuriakose Kuruvilla 7357af88ac7SKuriakose Kuruvilla movl FPU_CTX_FPU_XSAVE_MASK(%rbx), %eax /* for xrstor */ 7367af88ac7SKuriakose Kuruvilla movl FPU_CTX_FPU_XSAVE_MASK+4(%rbx), %edx /* for xrstor */ 7377af88ac7SKuriakose Kuruvilla 7387c478bd9Sstevel@tonic-gate /* 7397c478bd9Sstevel@tonic-gate * the label below is used in trap.c to detect FP faults in 7407c478bd9Sstevel@tonic-gate * kernel due to user fault. 7417c478bd9Sstevel@tonic-gate */ 7427c478bd9Sstevel@tonic-gate ALTENTRY(ndptrap_frstor) 7437af88ac7SKuriakose Kuruvilla .globl _patch_xrstorq_rbx 7447af88ac7SKuriakose Kuruvilla_patch_xrstorq_rbx: 7457af88ac7SKuriakose Kuruvilla FXRSTORQ ((%rbx)) 7467af88ac7SKuriakose Kuruvilla popq %rdx 7477c478bd9Sstevel@tonic-gate popq %rbx 7487c478bd9Sstevel@tonic-gate popq %rax 749ae115bc7Smrj IRET 750ae115bc7Smrj /*NOTREACHED*/ 7517c478bd9Sstevel@tonic-gate 7527c478bd9Sstevel@tonic-gate.handle_in_trap: 7537af88ac7SKuriakose Kuruvilla popq %rdx 7547c478bd9Sstevel@tonic-gate popq %rbx 7557c478bd9Sstevel@tonic-gate popq %rax 7567c478bd9Sstevel@tonic-gate TRAP_NOERR(T_NOEXTFLT) /* $7 */ 7577c478bd9Sstevel@tonic-gate jmp cmninttrap 7587c478bd9Sstevel@tonic-gate SET_SIZE(ndptrap_frstor) 7597c478bd9Sstevel@tonic-gate SET_SIZE(ndptrap) 7607c478bd9Sstevel@tonic-gate 761843e1988Sjohnlev#endif /* __xpv */ 762843e1988Sjohnlev 7637c478bd9Sstevel@tonic-gate#elif defined(__i386) 7647c478bd9Sstevel@tonic-gate 7657c478bd9Sstevel@tonic-gate ENTRY_NP(ndptrap) 7667c478bd9Sstevel@tonic-gate /* 7677c478bd9Sstevel@tonic-gate * We want to do this quickly as every lwp using fp will take this 7687c478bd9Sstevel@tonic-gate * after a context switch -- we do the frequent path in fpnoextflt 7697c478bd9Sstevel@tonic-gate * below; for all other cases, we let the trap code handle it 7707c478bd9Sstevel@tonic-gate */ 7717c478bd9Sstevel@tonic-gate pushl %eax 7727c478bd9Sstevel@tonic-gate pushl %ebx 7737af88ac7SKuriakose Kuruvilla pushl %edx /* for xrstor */ 7747c478bd9Sstevel@tonic-gate pushl %ds 7757c478bd9Sstevel@tonic-gate pushl %gs 7767c478bd9Sstevel@tonic-gate movl $KDS_SEL, %ebx 7777c478bd9Sstevel@tonic-gate movw %bx, %ds 7787c478bd9Sstevel@tonic-gate movl $KGS_SEL, %eax 7797c478bd9Sstevel@tonic-gate movw %ax, %gs 780ae115bc7Smrj LOADCPU(%eax) 7817c478bd9Sstevel@tonic-gate cmpl $0, fpu_exists 7827c478bd9Sstevel@tonic-gate je .handle_in_trap /* let trap handle no fp case */ 783ae115bc7Smrj movl CPU_THREAD(%eax), %ebx /* %ebx = curthread */ 784ae115bc7Smrj movl $FPU_EN, %eax 785ae115bc7Smrj movl T_LWP(%ebx), %ebx /* %ebx = lwp */ 786ae115bc7Smrj testl %ebx, %ebx 7877c478bd9Sstevel@tonic-gate jz .handle_in_trap /* should not happen? */ 7887c478bd9Sstevel@tonic-gate#if LWP_PCB_FPU != 0 789ae115bc7Smrj addl $LWP_PCB_FPU, %ebx /* &lwp->lwp_pcb.pcb_fpu */ 7907c478bd9Sstevel@tonic-gate#endif 791ae115bc7Smrj testl %eax, PCB_FPU_FLAGS(%ebx) 7927c478bd9Sstevel@tonic-gate jz .handle_in_trap /* must be the first fault */ 793ae115bc7Smrj CLTS 794ae115bc7Smrj andl $_BITNOT(FPU_VALID), PCB_FPU_FLAGS(%ebx) 7957c478bd9Sstevel@tonic-gate#if FPU_CTX_FPU_REGS != 0 796ae115bc7Smrj addl $FPU_CTX_FPU_REGS, %ebx 7977c478bd9Sstevel@tonic-gate#endif 7987af88ac7SKuriakose Kuruvilla 7997af88ac7SKuriakose Kuruvilla movl FPU_CTX_FPU_XSAVE_MASK(%ebx), %eax /* for xrstor */ 8007af88ac7SKuriakose Kuruvilla movl FPU_CTX_FPU_XSAVE_MASK+4(%ebx), %edx /* for xrstor */ 8017af88ac7SKuriakose Kuruvilla 8027c478bd9Sstevel@tonic-gate /* 8037c478bd9Sstevel@tonic-gate * the label below is used in trap.c to detect FP faults in kernel 8047c478bd9Sstevel@tonic-gate * due to user fault. 8057c478bd9Sstevel@tonic-gate */ 8067c478bd9Sstevel@tonic-gate ALTENTRY(ndptrap_frstor) 807ae115bc7Smrj .globl _patch_fxrstor_ebx 808ae115bc7Smrj_patch_fxrstor_ebx: 8097af88ac7SKuriakose Kuruvilla .globl _patch_xrstor_ebx 8107af88ac7SKuriakose Kuruvilla_patch_xrstor_ebx: 811ae115bc7Smrj frstor (%ebx) /* may be patched to fxrstor */ 8127c478bd9Sstevel@tonic-gate nop /* (including this byte) */ 8137c478bd9Sstevel@tonic-gate popl %gs 8147c478bd9Sstevel@tonic-gate popl %ds 8157af88ac7SKuriakose Kuruvilla popl %edx 8167c478bd9Sstevel@tonic-gate popl %ebx 8177c478bd9Sstevel@tonic-gate popl %eax 818ae115bc7Smrj IRET 8197c478bd9Sstevel@tonic-gate 8207c478bd9Sstevel@tonic-gate.handle_in_trap: 8217c478bd9Sstevel@tonic-gate popl %gs 8227c478bd9Sstevel@tonic-gate popl %ds 8237af88ac7SKuriakose Kuruvilla popl %edx 8247c478bd9Sstevel@tonic-gate popl %ebx 8257c478bd9Sstevel@tonic-gate popl %eax 826ae115bc7Smrj TRAP_NOERR(T_NOEXTFLT) /* $7 */ 8277c478bd9Sstevel@tonic-gate jmp cmninttrap 8287c478bd9Sstevel@tonic-gate SET_SIZE(ndptrap_frstor) 8297c478bd9Sstevel@tonic-gate SET_SIZE(ndptrap) 8307c478bd9Sstevel@tonic-gate 8317c478bd9Sstevel@tonic-gate#endif /* __i386 */ 8327c478bd9Sstevel@tonic-gate 833843e1988Sjohnlev#if !defined(__xpv) 8347c478bd9Sstevel@tonic-gate#if defined(__amd64) 8357c478bd9Sstevel@tonic-gate 8367c478bd9Sstevel@tonic-gate /* 8377c478bd9Sstevel@tonic-gate * #DF 8387c478bd9Sstevel@tonic-gate */ 8397c478bd9Sstevel@tonic-gate ENTRY_NP(syserrtrap) 8407c478bd9Sstevel@tonic-gate pushq $T_DBLFLT 8417c478bd9Sstevel@tonic-gate SET_CPU_GSBASE 8427c478bd9Sstevel@tonic-gate 8437c478bd9Sstevel@tonic-gate /* 844843e1988Sjohnlev * We share this handler with kmdb (if kmdb is loaded). As such, we 845843e1988Sjohnlev * may have reached this point after encountering a #df in kmdb. If 846843e1988Sjohnlev * that happens, we'll still be on kmdb's IDT. We need to switch back 847843e1988Sjohnlev * to this CPU's IDT before proceeding. Furthermore, if we did arrive 848843e1988Sjohnlev * here from kmdb, kmdb is probably in a very sickly state, and 849843e1988Sjohnlev * shouldn't be entered from the panic flow. We'll suppress that 850843e1988Sjohnlev * entry by setting nopanicdebug. 8517c478bd9Sstevel@tonic-gate */ 8527c478bd9Sstevel@tonic-gate pushq %rax 8537c478bd9Sstevel@tonic-gate subq $DESCTBR_SIZE, %rsp 8547c478bd9Sstevel@tonic-gate sidt (%rsp) 8557c478bd9Sstevel@tonic-gate movq %gs:CPU_IDT, %rax 8567c478bd9Sstevel@tonic-gate cmpq %rax, DTR_BASE(%rsp) 8577c478bd9Sstevel@tonic-gate je 1f 8587c478bd9Sstevel@tonic-gate 8597c478bd9Sstevel@tonic-gate movq %rax, DTR_BASE(%rsp) 8607c478bd9Sstevel@tonic-gate movw $_MUL(NIDT, GATE_DESC_SIZE), DTR_LIMIT(%rsp) 8617c478bd9Sstevel@tonic-gate lidt (%rsp) 8627c478bd9Sstevel@tonic-gate 8637c478bd9Sstevel@tonic-gate movl $1, nopanicdebug 8647c478bd9Sstevel@tonic-gate 8657c478bd9Sstevel@tonic-gate1: addq $DESCTBR_SIZE, %rsp 8667c478bd9Sstevel@tonic-gate popq %rax 8677c478bd9Sstevel@tonic-gate 8687c478bd9Sstevel@tonic-gate DFTRAP_PUSH 8697c478bd9Sstevel@tonic-gate 8707c478bd9Sstevel@tonic-gate /* 8717c478bd9Sstevel@tonic-gate * freeze trap trace. 8727c478bd9Sstevel@tonic-gate */ 8737c478bd9Sstevel@tonic-gate#ifdef TRAPTRACE 8747c478bd9Sstevel@tonic-gate leaq trap_trace_freeze(%rip), %r11 8757c478bd9Sstevel@tonic-gate incl (%r11) 8767c478bd9Sstevel@tonic-gate#endif 8777c478bd9Sstevel@tonic-gate 8787c478bd9Sstevel@tonic-gate ENABLE_INTR_FLAGS 8797c478bd9Sstevel@tonic-gate 8807c478bd9Sstevel@tonic-gate movq %rsp, %rdi /* ®s */ 8817c478bd9Sstevel@tonic-gate xorl %esi, %esi /* clear address */ 8827c478bd9Sstevel@tonic-gate xorl %edx, %edx /* cpuid = 0 */ 8837c478bd9Sstevel@tonic-gate call trap 8847c478bd9Sstevel@tonic-gate 8857c478bd9Sstevel@tonic-gate SET_SIZE(syserrtrap) 8867c478bd9Sstevel@tonic-gate 8877c478bd9Sstevel@tonic-gate#elif defined(__i386) 8887c478bd9Sstevel@tonic-gate 8897c478bd9Sstevel@tonic-gate /* 8907c478bd9Sstevel@tonic-gate * #DF 8917c478bd9Sstevel@tonic-gate */ 8927c478bd9Sstevel@tonic-gate ENTRY_NP(syserrtrap) 8937c478bd9Sstevel@tonic-gate cli /* disable interrupts */ 8947c478bd9Sstevel@tonic-gate 8957c478bd9Sstevel@tonic-gate /* 896843e1988Sjohnlev * We share this handler with kmdb (if kmdb is loaded). As such, we 897843e1988Sjohnlev * may have reached this point after encountering a #df in kmdb. If 898843e1988Sjohnlev * that happens, we'll still be on kmdb's IDT. We need to switch back 899843e1988Sjohnlev * to this CPU's IDT before proceeding. Furthermore, if we did arrive 900843e1988Sjohnlev * here from kmdb, kmdb is probably in a very sickly state, and 901843e1988Sjohnlev * shouldn't be entered from the panic flow. We'll suppress that 902843e1988Sjohnlev * entry by setting nopanicdebug. 9037c478bd9Sstevel@tonic-gate */ 904843e1988Sjohnlev 9057c478bd9Sstevel@tonic-gate subl $DESCTBR_SIZE, %esp 9067c478bd9Sstevel@tonic-gate movl %gs:CPU_IDT, %eax 9077c478bd9Sstevel@tonic-gate sidt (%esp) 9087c478bd9Sstevel@tonic-gate cmpl DTR_BASE(%esp), %eax 9097c478bd9Sstevel@tonic-gate je 1f 9107c478bd9Sstevel@tonic-gate 9117c478bd9Sstevel@tonic-gate movl %eax, DTR_BASE(%esp) 9127c478bd9Sstevel@tonic-gate movw $_MUL(NIDT, GATE_DESC_SIZE), DTR_LIMIT(%esp) 9137c478bd9Sstevel@tonic-gate lidt (%esp) 9147c478bd9Sstevel@tonic-gate 9157c478bd9Sstevel@tonic-gate movl $1, nopanicdebug 9167c478bd9Sstevel@tonic-gate 9177c478bd9Sstevel@tonic-gate1: addl $DESCTBR_SIZE, %esp 9187c478bd9Sstevel@tonic-gate 9197c478bd9Sstevel@tonic-gate /* 9207c478bd9Sstevel@tonic-gate * Check the CPL in the TSS to see what mode 9217c478bd9Sstevel@tonic-gate * (user or kernel) we took the fault in. At this 9227c478bd9Sstevel@tonic-gate * point we are running in the context of the double 9237c478bd9Sstevel@tonic-gate * fault task (dftss) but the CPU's task points to 9247c478bd9Sstevel@tonic-gate * the previous task (ktss) where the process context 9257c478bd9Sstevel@tonic-gate * has been saved as the result of the task switch. 9267c478bd9Sstevel@tonic-gate */ 9277c478bd9Sstevel@tonic-gate movl %gs:CPU_TSS, %eax /* get the TSS */ 9287c478bd9Sstevel@tonic-gate movl TSS_SS(%eax), %ebx /* save the fault SS */ 9297c478bd9Sstevel@tonic-gate movl TSS_ESP(%eax), %edx /* save the fault ESP */ 9307c478bd9Sstevel@tonic-gate testw $CPL_MASK, TSS_CS(%eax) /* user mode ? */ 9317c478bd9Sstevel@tonic-gate jz make_frame 9327c478bd9Sstevel@tonic-gate movw TSS_SS0(%eax), %ss /* get on the kernel stack */ 9337c478bd9Sstevel@tonic-gate movl TSS_ESP0(%eax), %esp 9347c478bd9Sstevel@tonic-gate 9357c478bd9Sstevel@tonic-gate /* 9367c478bd9Sstevel@tonic-gate * Clear the NT flag to avoid a task switch when the process 9377c478bd9Sstevel@tonic-gate * finally pops the EFL off the stack via an iret. Clear 9387c478bd9Sstevel@tonic-gate * the TF flag since that is what the processor does for 9397c478bd9Sstevel@tonic-gate * a normal exception. Clear the IE flag so that interrupts 9407c478bd9Sstevel@tonic-gate * remain disabled. 9417c478bd9Sstevel@tonic-gate */ 9427c478bd9Sstevel@tonic-gate movl TSS_EFL(%eax), %ecx 9437c478bd9Sstevel@tonic-gate andl $_BITNOT(PS_NT|PS_T|PS_IE), %ecx 9447c478bd9Sstevel@tonic-gate pushl %ecx 9457c478bd9Sstevel@tonic-gate popfl /* restore the EFL */ 9467c478bd9Sstevel@tonic-gate movw TSS_LDT(%eax), %cx /* restore the LDT */ 9477c478bd9Sstevel@tonic-gate lldt %cx 9487c478bd9Sstevel@tonic-gate 9497c478bd9Sstevel@tonic-gate /* 9507c478bd9Sstevel@tonic-gate * Restore process segment selectors. 9517c478bd9Sstevel@tonic-gate */ 9527c478bd9Sstevel@tonic-gate movw TSS_DS(%eax), %ds 9537c478bd9Sstevel@tonic-gate movw TSS_ES(%eax), %es 9547c478bd9Sstevel@tonic-gate movw TSS_FS(%eax), %fs 9557c478bd9Sstevel@tonic-gate movw TSS_GS(%eax), %gs 9567c478bd9Sstevel@tonic-gate 9577c478bd9Sstevel@tonic-gate /* 9587c478bd9Sstevel@tonic-gate * Restore task segment selectors. 9597c478bd9Sstevel@tonic-gate */ 9607c478bd9Sstevel@tonic-gate movl $KDS_SEL, TSS_DS(%eax) 9617c478bd9Sstevel@tonic-gate movl $KDS_SEL, TSS_ES(%eax) 9627c478bd9Sstevel@tonic-gate movl $KDS_SEL, TSS_SS(%eax) 9637c478bd9Sstevel@tonic-gate movl $KFS_SEL, TSS_FS(%eax) 9647c478bd9Sstevel@tonic-gate movl $KGS_SEL, TSS_GS(%eax) 9657c478bd9Sstevel@tonic-gate 9667c478bd9Sstevel@tonic-gate /* 9677c478bd9Sstevel@tonic-gate * Clear the TS bit, the busy bits in both task 9687c478bd9Sstevel@tonic-gate * descriptors, and switch tasks. 9697c478bd9Sstevel@tonic-gate */ 9707c478bd9Sstevel@tonic-gate clts 9717c478bd9Sstevel@tonic-gate leal gdt0, %ecx 9727c478bd9Sstevel@tonic-gate movl DFTSS_SEL+4(%ecx), %esi 9737c478bd9Sstevel@tonic-gate andl $_BITNOT(0x200), %esi 9747c478bd9Sstevel@tonic-gate movl %esi, DFTSS_SEL+4(%ecx) 9757c478bd9Sstevel@tonic-gate movl KTSS_SEL+4(%ecx), %esi 9767c478bd9Sstevel@tonic-gate andl $_BITNOT(0x200), %esi 9777c478bd9Sstevel@tonic-gate movl %esi, KTSS_SEL+4(%ecx) 9787c478bd9Sstevel@tonic-gate movw $KTSS_SEL, %cx 9797c478bd9Sstevel@tonic-gate ltr %cx 9807c478bd9Sstevel@tonic-gate 9817c478bd9Sstevel@tonic-gate /* 9827c478bd9Sstevel@tonic-gate * Restore part of the process registers. 9837c478bd9Sstevel@tonic-gate */ 9847c478bd9Sstevel@tonic-gate movl TSS_EBP(%eax), %ebp 9857c478bd9Sstevel@tonic-gate movl TSS_ECX(%eax), %ecx 9867c478bd9Sstevel@tonic-gate movl TSS_ESI(%eax), %esi 9877c478bd9Sstevel@tonic-gate movl TSS_EDI(%eax), %edi 9887c478bd9Sstevel@tonic-gate 9897c478bd9Sstevel@tonic-gatemake_frame: 9907c478bd9Sstevel@tonic-gate /* 9917c478bd9Sstevel@tonic-gate * Make a trap frame. Leave the error code (0) on 9927c478bd9Sstevel@tonic-gate * the stack since the first word on a trap stack is 9937c478bd9Sstevel@tonic-gate * unused anyway. 9947c478bd9Sstevel@tonic-gate */ 9957c478bd9Sstevel@tonic-gate pushl %ebx / fault SS 9967c478bd9Sstevel@tonic-gate pushl %edx / fault ESP 9977c478bd9Sstevel@tonic-gate pushl TSS_EFL(%eax) / fault EFL 9987c478bd9Sstevel@tonic-gate pushl TSS_CS(%eax) / fault CS 9997c478bd9Sstevel@tonic-gate pushl TSS_EIP(%eax) / fault EIP 10007c478bd9Sstevel@tonic-gate pushl $0 / error code 10017c478bd9Sstevel@tonic-gate pushl $T_DBLFLT / trap number 8 10027c478bd9Sstevel@tonic-gate movl TSS_EBX(%eax), %ebx / restore EBX 10037c478bd9Sstevel@tonic-gate movl TSS_EDX(%eax), %edx / restore EDX 10047c478bd9Sstevel@tonic-gate movl TSS_EAX(%eax), %eax / restore EAX 10057c478bd9Sstevel@tonic-gate sti / enable interrupts 10067c478bd9Sstevel@tonic-gate jmp cmntrap 10077c478bd9Sstevel@tonic-gate SET_SIZE(syserrtrap) 10087c478bd9Sstevel@tonic-gate 10097c478bd9Sstevel@tonic-gate#endif /* __i386 */ 1010843e1988Sjohnlev#endif /* !__xpv */ 10117c478bd9Sstevel@tonic-gate 10127c478bd9Sstevel@tonic-gate ENTRY_NP(overrun) 10137c478bd9Sstevel@tonic-gate push $0 10147c478bd9Sstevel@tonic-gate TRAP_NOERR(T_EXTOVRFLT) /* $9 i386 only - not generated */ 10157c478bd9Sstevel@tonic-gate jmp cmninttrap 10167c478bd9Sstevel@tonic-gate SET_SIZE(overrun) 10177c478bd9Sstevel@tonic-gate 10187c478bd9Sstevel@tonic-gate /* 10197c478bd9Sstevel@tonic-gate * #TS 10207c478bd9Sstevel@tonic-gate */ 10217c478bd9Sstevel@tonic-gate ENTRY_NP(invtsstrap) 10227c478bd9Sstevel@tonic-gate TRAP_ERR(T_TSSFLT) /* $10 already have error code on stack */ 10237c478bd9Sstevel@tonic-gate jmp cmntrap 10247c478bd9Sstevel@tonic-gate SET_SIZE(invtsstrap) 10257c478bd9Sstevel@tonic-gate 10267c478bd9Sstevel@tonic-gate /* 10277c478bd9Sstevel@tonic-gate * #NP 10287c478bd9Sstevel@tonic-gate */ 10297c478bd9Sstevel@tonic-gate ENTRY_NP(segnptrap) 10307c478bd9Sstevel@tonic-gate TRAP_ERR(T_SEGFLT) /* $11 already have error code on stack */ 10317c478bd9Sstevel@tonic-gate#if defined(__amd64) 10327c478bd9Sstevel@tonic-gate SET_CPU_GSBASE 10337c478bd9Sstevel@tonic-gate#endif 10347c478bd9Sstevel@tonic-gate jmp cmntrap 10357c478bd9Sstevel@tonic-gate SET_SIZE(segnptrap) 10367c478bd9Sstevel@tonic-gate 10377c478bd9Sstevel@tonic-gate /* 10387c478bd9Sstevel@tonic-gate * #SS 10397c478bd9Sstevel@tonic-gate */ 10407c478bd9Sstevel@tonic-gate ENTRY_NP(stktrap) 10417c478bd9Sstevel@tonic-gate TRAP_ERR(T_STKFLT) /* $12 already have error code on stack */ 10427c478bd9Sstevel@tonic-gate jmp cmntrap 10437c478bd9Sstevel@tonic-gate SET_SIZE(stktrap) 10447c478bd9Sstevel@tonic-gate 10457c478bd9Sstevel@tonic-gate /* 10467c478bd9Sstevel@tonic-gate * #GP 10477c478bd9Sstevel@tonic-gate */ 10487c478bd9Sstevel@tonic-gate ENTRY_NP(gptrap) 10497c478bd9Sstevel@tonic-gate TRAP_ERR(T_GPFLT) /* $13 already have error code on stack */ 10507c478bd9Sstevel@tonic-gate#if defined(__amd64) 10517c478bd9Sstevel@tonic-gate SET_CPU_GSBASE 10527c478bd9Sstevel@tonic-gate#endif 10537c478bd9Sstevel@tonic-gate jmp cmntrap 10547c478bd9Sstevel@tonic-gate SET_SIZE(gptrap) 10557c478bd9Sstevel@tonic-gate 10567c478bd9Sstevel@tonic-gate /* 10577c478bd9Sstevel@tonic-gate * #PF 10587c478bd9Sstevel@tonic-gate */ 10597c478bd9Sstevel@tonic-gate ENTRY_NP(pftrap) 10607c478bd9Sstevel@tonic-gate TRAP_ERR(T_PGFLT) /* $14 already have error code on stack */ 1061ae115bc7Smrj INTR_PUSH 1062843e1988Sjohnlev#if defined(__xpv) 1063843e1988Sjohnlev 1064843e1988Sjohnlev#if defined(__amd64) 1065843e1988Sjohnlev movq %gs:CPU_VCPU_INFO, %r15 1066843e1988Sjohnlev movq VCPU_INFO_ARCH_CR2(%r15), %r15 /* vcpu[].arch.cr2 */ 1067843e1988Sjohnlev#elif defined(__i386) 1068843e1988Sjohnlev movl %gs:CPU_VCPU_INFO, %esi 1069843e1988Sjohnlev movl VCPU_INFO_ARCH_CR2(%esi), %esi /* vcpu[].arch.cr2 */ 1070843e1988Sjohnlev#endif /* __i386 */ 1071843e1988Sjohnlev 1072843e1988Sjohnlev#else /* __xpv */ 1073ae115bc7Smrj 1074ae115bc7Smrj#if defined(__amd64) 1075ae115bc7Smrj movq %cr2, %r15 1076ae115bc7Smrj#elif defined(__i386) 1077ae115bc7Smrj movl %cr2, %esi 1078ae115bc7Smrj#endif /* __i386 */ 1079ae115bc7Smrj 1080843e1988Sjohnlev#endif /* __xpv */ 1081ae115bc7Smrj jmp cmntrap_pushed 10827c478bd9Sstevel@tonic-gate SET_SIZE(pftrap) 10837c478bd9Sstevel@tonic-gate 10847c478bd9Sstevel@tonic-gate#if !defined(__amd64) 10857c478bd9Sstevel@tonic-gate 1086ae115bc7Smrj .globl idt0_default_r 1087ae115bc7Smrj 10887c478bd9Sstevel@tonic-gate /* 10897c478bd9Sstevel@tonic-gate * #PF pentium bug workaround 10907c478bd9Sstevel@tonic-gate */ 10917c478bd9Sstevel@tonic-gate ENTRY_NP(pentium_pftrap) 10927c478bd9Sstevel@tonic-gate pushl %eax 10937c478bd9Sstevel@tonic-gate movl %cr2, %eax 10947c478bd9Sstevel@tonic-gate andl $MMU_STD_PAGEMASK, %eax 10957c478bd9Sstevel@tonic-gate 10967c478bd9Sstevel@tonic-gate cmpl %eax, %cs:idt0_default_r+2 /* fixme */ 10977c478bd9Sstevel@tonic-gate 10987c478bd9Sstevel@tonic-gate je check_for_user_address 10997c478bd9Sstevel@tonic-gateuser_mode: 11007c478bd9Sstevel@tonic-gate popl %eax 11017c478bd9Sstevel@tonic-gate pushl $T_PGFLT /* $14 */ 11027c478bd9Sstevel@tonic-gate jmp cmntrap 11037c478bd9Sstevel@tonic-gatecheck_for_user_address: 11047c478bd9Sstevel@tonic-gate /* 11057c478bd9Sstevel@tonic-gate * Before we assume that we have an unmapped trap on our hands, 11067c478bd9Sstevel@tonic-gate * check to see if this is a fault from user mode. If it is, 11077c478bd9Sstevel@tonic-gate * we'll kick back into the page fault handler. 11087c478bd9Sstevel@tonic-gate */ 11097c478bd9Sstevel@tonic-gate movl 4(%esp), %eax /* error code */ 11107c478bd9Sstevel@tonic-gate andl $PF_ERR_USER, %eax 11117c478bd9Sstevel@tonic-gate jnz user_mode 11127c478bd9Sstevel@tonic-gate 11137c478bd9Sstevel@tonic-gate /* 11147c478bd9Sstevel@tonic-gate * We now know that this is the invalid opcode trap. 11157c478bd9Sstevel@tonic-gate */ 11167c478bd9Sstevel@tonic-gate popl %eax 11177c478bd9Sstevel@tonic-gate addl $4, %esp /* pop error code */ 11187c478bd9Sstevel@tonic-gate jmp invoptrap 11197c478bd9Sstevel@tonic-gate SET_SIZE(pentium_pftrap) 11207c478bd9Sstevel@tonic-gate 11217c478bd9Sstevel@tonic-gate#endif /* !__amd64 */ 11227c478bd9Sstevel@tonic-gate 11237c478bd9Sstevel@tonic-gate ENTRY_NP(resvtrap) 11247c478bd9Sstevel@tonic-gate TRAP_NOERR(15) /* (reserved) */ 11257c478bd9Sstevel@tonic-gate jmp cmntrap 11267c478bd9Sstevel@tonic-gate SET_SIZE(resvtrap) 11277c478bd9Sstevel@tonic-gate 11287c478bd9Sstevel@tonic-gate /* 11297c478bd9Sstevel@tonic-gate * #MF 11307c478bd9Sstevel@tonic-gate */ 11317c478bd9Sstevel@tonic-gate ENTRY_NP(ndperr) 11327c478bd9Sstevel@tonic-gate TRAP_NOERR(T_EXTERRFLT) /* $16 */ 11337c478bd9Sstevel@tonic-gate jmp cmninttrap 11347c478bd9Sstevel@tonic-gate SET_SIZE(ndperr) 11357c478bd9Sstevel@tonic-gate 11367c478bd9Sstevel@tonic-gate /* 11377c478bd9Sstevel@tonic-gate * #AC 11387c478bd9Sstevel@tonic-gate */ 11397c478bd9Sstevel@tonic-gate ENTRY_NP(achktrap) 11407c478bd9Sstevel@tonic-gate TRAP_ERR(T_ALIGNMENT) /* $17 */ 11417c478bd9Sstevel@tonic-gate jmp cmntrap 11427c478bd9Sstevel@tonic-gate SET_SIZE(achktrap) 11437c478bd9Sstevel@tonic-gate 11447c478bd9Sstevel@tonic-gate /* 11457c478bd9Sstevel@tonic-gate * #MC 11467c478bd9Sstevel@tonic-gate */ 11477aec1d6eScindi .globl cmi_mca_trap /* see uts/i86pc/os/cmi.c */ 11487aec1d6eScindi 11497aec1d6eScindi#if defined(__amd64) 11507aec1d6eScindi 11517c478bd9Sstevel@tonic-gate ENTRY_NP(mcetrap) 11527c478bd9Sstevel@tonic-gate TRAP_NOERR(T_MCE) /* $18 */ 1153ae115bc7Smrj 11547c035692Skucharsk SET_CPU_GSBASE 1155ae115bc7Smrj 11567aec1d6eScindi INTR_PUSH 1157ae115bc7Smrj INTGATE_INIT_KERNEL_FLAGS 11587aec1d6eScindi 11597aec1d6eScindi TRACE_PTR(%rdi, %rbx, %ebx, %rcx, $TT_TRAP) 11607aec1d6eScindi TRACE_REGS(%rdi, %rsp, %rbx, %rcx) 11617aec1d6eScindi TRACE_STAMP(%rdi) 11627aec1d6eScindi 11637aec1d6eScindi movq %rsp, %rbp 11647aec1d6eScindi 11657aec1d6eScindi movq %rsp, %rdi /* arg0 = struct regs *rp */ 11667aec1d6eScindi call cmi_mca_trap /* cmi_mca_trap(rp); */ 11677aec1d6eScindi 11687aec1d6eScindi jmp _sys_rtt 11697c478bd9Sstevel@tonic-gate SET_SIZE(mcetrap) 11707c478bd9Sstevel@tonic-gate 11717aec1d6eScindi#else 11727aec1d6eScindi 11737aec1d6eScindi ENTRY_NP(mcetrap) 11747aec1d6eScindi TRAP_NOERR(T_MCE) /* $18 */ 11757aec1d6eScindi 1176ae115bc7Smrj INTR_PUSH 1177ae115bc7Smrj INTGATE_INIT_KERNEL_FLAGS 1178ae115bc7Smrj 1179ae115bc7Smrj TRACE_PTR(%edi, %ebx, %ebx, %ecx, $TT_TRAP) 1180ae115bc7Smrj TRACE_REGS(%edi, %esp, %ebx, %ecx) 1181ae115bc7Smrj TRACE_STAMP(%edi) 1182ae115bc7Smrj 11837aec1d6eScindi movl %esp, %ebp 11847aec1d6eScindi 11857aec1d6eScindi movl %esp, %ecx 11867aec1d6eScindi pushl %ecx /* arg0 = struct regs *rp */ 11877aec1d6eScindi call cmi_mca_trap /* cmi_mca_trap(rp) */ 11887aec1d6eScindi addl $4, %esp /* pop arg0 */ 11897aec1d6eScindi 11907aec1d6eScindi jmp _sys_rtt 11917aec1d6eScindi SET_SIZE(mcetrap) 11927aec1d6eScindi 11937aec1d6eScindi#endif 11947aec1d6eScindi 11957c478bd9Sstevel@tonic-gate /* 11967c478bd9Sstevel@tonic-gate * #XF 11977c478bd9Sstevel@tonic-gate */ 11987c478bd9Sstevel@tonic-gate ENTRY_NP(xmtrap) 11997c478bd9Sstevel@tonic-gate TRAP_NOERR(T_SIMDFPE) /* $19 */ 1200eae0da43Ssethg jmp cmninttrap 12017c478bd9Sstevel@tonic-gate SET_SIZE(xmtrap) 12027c478bd9Sstevel@tonic-gate 12037c478bd9Sstevel@tonic-gate ENTRY_NP(invaltrap) 12047c478bd9Sstevel@tonic-gate TRAP_NOERR(30) /* very invalid */ 12057c478bd9Sstevel@tonic-gate jmp cmntrap 12067c478bd9Sstevel@tonic-gate SET_SIZE(invaltrap) 12077c478bd9Sstevel@tonic-gate 12087c478bd9Sstevel@tonic-gate ENTRY_NP(invalint) 12097c478bd9Sstevel@tonic-gate TRAP_NOERR(31) /* even more so */ 12107c478bd9Sstevel@tonic-gate jmp cmnint 12117c478bd9Sstevel@tonic-gate SET_SIZE(invalint) 12127c478bd9Sstevel@tonic-gate 12137c478bd9Sstevel@tonic-gate .globl fasttable 12147c478bd9Sstevel@tonic-gate 12157c478bd9Sstevel@tonic-gate#if defined(__amd64) 12167c478bd9Sstevel@tonic-gate 12177c478bd9Sstevel@tonic-gate ENTRY_NP(fasttrap) 12187c478bd9Sstevel@tonic-gate cmpl $T_LASTFAST, %eax 12197c478bd9Sstevel@tonic-gate ja 1f 12207c478bd9Sstevel@tonic-gate orl %eax, %eax /* (zero extend top 32-bits) */ 12217c478bd9Sstevel@tonic-gate leaq fasttable(%rip), %r11 12227c478bd9Sstevel@tonic-gate leaq (%r11, %rax, CLONGSIZE), %r11 12237c478bd9Sstevel@tonic-gate jmp *(%r11) 12247c478bd9Sstevel@tonic-gate1: 12257c478bd9Sstevel@tonic-gate /* 12267c478bd9Sstevel@tonic-gate * Fast syscall number was illegal. Make it look 12277c478bd9Sstevel@tonic-gate * as if the INT failed. Modify %rip to point before the 12287c478bd9Sstevel@tonic-gate * INT, push the expected error code and fake a GP fault. 12297c478bd9Sstevel@tonic-gate * 12307c478bd9Sstevel@tonic-gate * XXX Why make the error code be offset into idt + 1? 12317c478bd9Sstevel@tonic-gate * Instead we should push a real (soft?) error code 12327c478bd9Sstevel@tonic-gate * on the stack and #gp handler could know about fasttraps? 12337c478bd9Sstevel@tonic-gate */ 1234843e1988Sjohnlev XPV_TRAP_POP 1235843e1988Sjohnlev 12367c478bd9Sstevel@tonic-gate subq $2, (%rsp) /* XXX int insn 2-bytes */ 12377c478bd9Sstevel@tonic-gate pushq $_CONST(_MUL(T_FASTTRAP, GATE_DESC_SIZE) + 2) 1238843e1988Sjohnlev 1239843e1988Sjohnlev#if defined(__xpv) 1240843e1988Sjohnlev pushq %r11 1241843e1988Sjohnlev pushq %rcx 1242843e1988Sjohnlev#endif 12437c478bd9Sstevel@tonic-gate jmp gptrap 12447c478bd9Sstevel@tonic-gate SET_SIZE(fasttrap) 12457c478bd9Sstevel@tonic-gate 12467c478bd9Sstevel@tonic-gate#elif defined(__i386) 12477c478bd9Sstevel@tonic-gate 12487c478bd9Sstevel@tonic-gate ENTRY_NP(fasttrap) 12497c478bd9Sstevel@tonic-gate cmpl $T_LASTFAST, %eax 12507c478bd9Sstevel@tonic-gate ja 1f 12517c478bd9Sstevel@tonic-gate jmp *%cs:fasttable(, %eax, CLONGSIZE) 12527c478bd9Sstevel@tonic-gate1: 12537c478bd9Sstevel@tonic-gate /* 12547c478bd9Sstevel@tonic-gate * Fast syscall number was illegal. Make it look 12557c478bd9Sstevel@tonic-gate * as if the INT failed. Modify %eip to point before the 12567c478bd9Sstevel@tonic-gate * INT, push the expected error code and fake a GP fault. 12577c478bd9Sstevel@tonic-gate * 12587c478bd9Sstevel@tonic-gate * XXX Why make the error code be offset into idt + 1? 12597c478bd9Sstevel@tonic-gate * Instead we should push a real (soft?) error code 12607c478bd9Sstevel@tonic-gate * on the stack and #gp handler could know about fasttraps? 12617c478bd9Sstevel@tonic-gate */ 12627c478bd9Sstevel@tonic-gate subl $2, (%esp) /* XXX int insn 2-bytes */ 12637c478bd9Sstevel@tonic-gate pushl $_CONST(_MUL(T_FASTTRAP, GATE_DESC_SIZE) + 2) 12647c478bd9Sstevel@tonic-gate jmp gptrap 12657c478bd9Sstevel@tonic-gate SET_SIZE(fasttrap) 12667c478bd9Sstevel@tonic-gate 12677c478bd9Sstevel@tonic-gate#endif /* __i386 */ 12687c478bd9Sstevel@tonic-gate 12697c478bd9Sstevel@tonic-gate ENTRY_NP(dtrace_ret) 12707c478bd9Sstevel@tonic-gate TRAP_NOERR(T_DTRACE_RET) 12717c478bd9Sstevel@tonic-gate jmp dtrace_trap 12727c478bd9Sstevel@tonic-gate SET_SIZE(dtrace_ret) 12737c478bd9Sstevel@tonic-gate 12747c478bd9Sstevel@tonic-gate#if defined(__amd64) 12757c478bd9Sstevel@tonic-gate 12767c478bd9Sstevel@tonic-gate /* 12777c478bd9Sstevel@tonic-gate * RFLAGS 24 bytes up the stack from %rsp. 12787c478bd9Sstevel@tonic-gate * XXX a constant would be nicer. 12797c478bd9Sstevel@tonic-gate */ 12807c478bd9Sstevel@tonic-gate ENTRY_NP(fast_null) 1281843e1988Sjohnlev XPV_TRAP_POP 12827c478bd9Sstevel@tonic-gate orq $PS_C, 24(%rsp) /* set carry bit in user flags */ 1283ae115bc7Smrj IRET 1284ae115bc7Smrj /*NOTREACHED*/ 12857c478bd9Sstevel@tonic-gate SET_SIZE(fast_null) 12867c478bd9Sstevel@tonic-gate 12877c478bd9Sstevel@tonic-gate#elif defined(__i386) 12887c478bd9Sstevel@tonic-gate 12897c478bd9Sstevel@tonic-gate ENTRY_NP(fast_null) 12907c478bd9Sstevel@tonic-gate orw $PS_C, 8(%esp) /* set carry bit in user flags */ 1291ae115bc7Smrj IRET 12927c478bd9Sstevel@tonic-gate SET_SIZE(fast_null) 12937c478bd9Sstevel@tonic-gate 12947c478bd9Sstevel@tonic-gate#endif /* __i386 */ 12957c478bd9Sstevel@tonic-gate 12967c478bd9Sstevel@tonic-gate /* 12977c478bd9Sstevel@tonic-gate * Interrupts start at 32 12987c478bd9Sstevel@tonic-gate */ 12997c478bd9Sstevel@tonic-gate#define MKIVCT(n) \ 13007c478bd9Sstevel@tonic-gate ENTRY_NP(ivct/**/n) \ 13017c478bd9Sstevel@tonic-gate push $0; \ 13027c478bd9Sstevel@tonic-gate push $n - 0x20; \ 13037c478bd9Sstevel@tonic-gate jmp cmnint; \ 13047c478bd9Sstevel@tonic-gate SET_SIZE(ivct/**/n) 13057c478bd9Sstevel@tonic-gate 13067c478bd9Sstevel@tonic-gate MKIVCT(32) 13077c478bd9Sstevel@tonic-gate MKIVCT(33) 13087c478bd9Sstevel@tonic-gate MKIVCT(34) 13097c478bd9Sstevel@tonic-gate MKIVCT(35) 13107c478bd9Sstevel@tonic-gate MKIVCT(36) 13117c478bd9Sstevel@tonic-gate MKIVCT(37) 13127c478bd9Sstevel@tonic-gate MKIVCT(38) 13137c478bd9Sstevel@tonic-gate MKIVCT(39) 13147c478bd9Sstevel@tonic-gate MKIVCT(40) 13157c478bd9Sstevel@tonic-gate MKIVCT(41) 13167c478bd9Sstevel@tonic-gate MKIVCT(42) 13177c478bd9Sstevel@tonic-gate MKIVCT(43) 13187c478bd9Sstevel@tonic-gate MKIVCT(44) 13197c478bd9Sstevel@tonic-gate MKIVCT(45) 13207c478bd9Sstevel@tonic-gate MKIVCT(46) 13217c478bd9Sstevel@tonic-gate MKIVCT(47) 13227c478bd9Sstevel@tonic-gate MKIVCT(48) 13237c478bd9Sstevel@tonic-gate MKIVCT(49) 13247c478bd9Sstevel@tonic-gate MKIVCT(50) 13257c478bd9Sstevel@tonic-gate MKIVCT(51) 13267c478bd9Sstevel@tonic-gate MKIVCT(52) 13277c478bd9Sstevel@tonic-gate MKIVCT(53) 13287c478bd9Sstevel@tonic-gate MKIVCT(54) 13297c478bd9Sstevel@tonic-gate MKIVCT(55) 13307c478bd9Sstevel@tonic-gate MKIVCT(56) 13317c478bd9Sstevel@tonic-gate MKIVCT(57) 13327c478bd9Sstevel@tonic-gate MKIVCT(58) 13337c478bd9Sstevel@tonic-gate MKIVCT(59) 13347c478bd9Sstevel@tonic-gate MKIVCT(60) 13357c478bd9Sstevel@tonic-gate MKIVCT(61) 13367c478bd9Sstevel@tonic-gate MKIVCT(62) 13377c478bd9Sstevel@tonic-gate MKIVCT(63) 13387c478bd9Sstevel@tonic-gate MKIVCT(64) 13397c478bd9Sstevel@tonic-gate MKIVCT(65) 13407c478bd9Sstevel@tonic-gate MKIVCT(66) 13417c478bd9Sstevel@tonic-gate MKIVCT(67) 13427c478bd9Sstevel@tonic-gate MKIVCT(68) 13437c478bd9Sstevel@tonic-gate MKIVCT(69) 13447c478bd9Sstevel@tonic-gate MKIVCT(70) 13457c478bd9Sstevel@tonic-gate MKIVCT(71) 13467c478bd9Sstevel@tonic-gate MKIVCT(72) 13477c478bd9Sstevel@tonic-gate MKIVCT(73) 13487c478bd9Sstevel@tonic-gate MKIVCT(74) 13497c478bd9Sstevel@tonic-gate MKIVCT(75) 13507c478bd9Sstevel@tonic-gate MKIVCT(76) 13517c478bd9Sstevel@tonic-gate MKIVCT(77) 13527c478bd9Sstevel@tonic-gate MKIVCT(78) 13537c478bd9Sstevel@tonic-gate MKIVCT(79) 13547c478bd9Sstevel@tonic-gate MKIVCT(80) 13557c478bd9Sstevel@tonic-gate MKIVCT(81) 13567c478bd9Sstevel@tonic-gate MKIVCT(82) 13577c478bd9Sstevel@tonic-gate MKIVCT(83) 13587c478bd9Sstevel@tonic-gate MKIVCT(84) 13597c478bd9Sstevel@tonic-gate MKIVCT(85) 13607c478bd9Sstevel@tonic-gate MKIVCT(86) 13617c478bd9Sstevel@tonic-gate MKIVCT(87) 13627c478bd9Sstevel@tonic-gate MKIVCT(88) 13637c478bd9Sstevel@tonic-gate MKIVCT(89) 13647c478bd9Sstevel@tonic-gate MKIVCT(90) 13657c478bd9Sstevel@tonic-gate MKIVCT(91) 13667c478bd9Sstevel@tonic-gate MKIVCT(92) 13677c478bd9Sstevel@tonic-gate MKIVCT(93) 13687c478bd9Sstevel@tonic-gate MKIVCT(94) 13697c478bd9Sstevel@tonic-gate MKIVCT(95) 13707c478bd9Sstevel@tonic-gate MKIVCT(96) 13717c478bd9Sstevel@tonic-gate MKIVCT(97) 13727c478bd9Sstevel@tonic-gate MKIVCT(98) 13737c478bd9Sstevel@tonic-gate MKIVCT(99) 13747c478bd9Sstevel@tonic-gate MKIVCT(100) 13757c478bd9Sstevel@tonic-gate MKIVCT(101) 13767c478bd9Sstevel@tonic-gate MKIVCT(102) 13777c478bd9Sstevel@tonic-gate MKIVCT(103) 13787c478bd9Sstevel@tonic-gate MKIVCT(104) 13797c478bd9Sstevel@tonic-gate MKIVCT(105) 13807c478bd9Sstevel@tonic-gate MKIVCT(106) 13817c478bd9Sstevel@tonic-gate MKIVCT(107) 13827c478bd9Sstevel@tonic-gate MKIVCT(108) 13837c478bd9Sstevel@tonic-gate MKIVCT(109) 13847c478bd9Sstevel@tonic-gate MKIVCT(110) 13857c478bd9Sstevel@tonic-gate MKIVCT(111) 13867c478bd9Sstevel@tonic-gate MKIVCT(112) 13877c478bd9Sstevel@tonic-gate MKIVCT(113) 13887c478bd9Sstevel@tonic-gate MKIVCT(114) 13897c478bd9Sstevel@tonic-gate MKIVCT(115) 13907c478bd9Sstevel@tonic-gate MKIVCT(116) 13917c478bd9Sstevel@tonic-gate MKIVCT(117) 13927c478bd9Sstevel@tonic-gate MKIVCT(118) 13937c478bd9Sstevel@tonic-gate MKIVCT(119) 13947c478bd9Sstevel@tonic-gate MKIVCT(120) 13957c478bd9Sstevel@tonic-gate MKIVCT(121) 13967c478bd9Sstevel@tonic-gate MKIVCT(122) 13977c478bd9Sstevel@tonic-gate MKIVCT(123) 13987c478bd9Sstevel@tonic-gate MKIVCT(124) 13997c478bd9Sstevel@tonic-gate MKIVCT(125) 14007c478bd9Sstevel@tonic-gate MKIVCT(126) 14017c478bd9Sstevel@tonic-gate MKIVCT(127) 14027c478bd9Sstevel@tonic-gate MKIVCT(128) 14037c478bd9Sstevel@tonic-gate MKIVCT(129) 14047c478bd9Sstevel@tonic-gate MKIVCT(130) 14057c478bd9Sstevel@tonic-gate MKIVCT(131) 14067c478bd9Sstevel@tonic-gate MKIVCT(132) 14077c478bd9Sstevel@tonic-gate MKIVCT(133) 14087c478bd9Sstevel@tonic-gate MKIVCT(134) 14097c478bd9Sstevel@tonic-gate MKIVCT(135) 14107c478bd9Sstevel@tonic-gate MKIVCT(136) 14117c478bd9Sstevel@tonic-gate MKIVCT(137) 14127c478bd9Sstevel@tonic-gate MKIVCT(138) 14137c478bd9Sstevel@tonic-gate MKIVCT(139) 14147c478bd9Sstevel@tonic-gate MKIVCT(140) 14157c478bd9Sstevel@tonic-gate MKIVCT(141) 14167c478bd9Sstevel@tonic-gate MKIVCT(142) 14177c478bd9Sstevel@tonic-gate MKIVCT(143) 14187c478bd9Sstevel@tonic-gate MKIVCT(144) 14197c478bd9Sstevel@tonic-gate MKIVCT(145) 14207c478bd9Sstevel@tonic-gate MKIVCT(146) 14217c478bd9Sstevel@tonic-gate MKIVCT(147) 14227c478bd9Sstevel@tonic-gate MKIVCT(148) 14237c478bd9Sstevel@tonic-gate MKIVCT(149) 14247c478bd9Sstevel@tonic-gate MKIVCT(150) 14257c478bd9Sstevel@tonic-gate MKIVCT(151) 14267c478bd9Sstevel@tonic-gate MKIVCT(152) 14277c478bd9Sstevel@tonic-gate MKIVCT(153) 14287c478bd9Sstevel@tonic-gate MKIVCT(154) 14297c478bd9Sstevel@tonic-gate MKIVCT(155) 14307c478bd9Sstevel@tonic-gate MKIVCT(156) 14317c478bd9Sstevel@tonic-gate MKIVCT(157) 14327c478bd9Sstevel@tonic-gate MKIVCT(158) 14337c478bd9Sstevel@tonic-gate MKIVCT(159) 14347c478bd9Sstevel@tonic-gate MKIVCT(160) 14357c478bd9Sstevel@tonic-gate MKIVCT(161) 14367c478bd9Sstevel@tonic-gate MKIVCT(162) 14377c478bd9Sstevel@tonic-gate MKIVCT(163) 14387c478bd9Sstevel@tonic-gate MKIVCT(164) 14397c478bd9Sstevel@tonic-gate MKIVCT(165) 14407c478bd9Sstevel@tonic-gate MKIVCT(166) 14417c478bd9Sstevel@tonic-gate MKIVCT(167) 14427c478bd9Sstevel@tonic-gate MKIVCT(168) 14437c478bd9Sstevel@tonic-gate MKIVCT(169) 14447c478bd9Sstevel@tonic-gate MKIVCT(170) 14457c478bd9Sstevel@tonic-gate MKIVCT(171) 14467c478bd9Sstevel@tonic-gate MKIVCT(172) 14477c478bd9Sstevel@tonic-gate MKIVCT(173) 14487c478bd9Sstevel@tonic-gate MKIVCT(174) 14497c478bd9Sstevel@tonic-gate MKIVCT(175) 14507c478bd9Sstevel@tonic-gate MKIVCT(176) 14517c478bd9Sstevel@tonic-gate MKIVCT(177) 14527c478bd9Sstevel@tonic-gate MKIVCT(178) 14537c478bd9Sstevel@tonic-gate MKIVCT(179) 14547c478bd9Sstevel@tonic-gate MKIVCT(180) 14557c478bd9Sstevel@tonic-gate MKIVCT(181) 14567c478bd9Sstevel@tonic-gate MKIVCT(182) 14577c478bd9Sstevel@tonic-gate MKIVCT(183) 14587c478bd9Sstevel@tonic-gate MKIVCT(184) 14597c478bd9Sstevel@tonic-gate MKIVCT(185) 14607c478bd9Sstevel@tonic-gate MKIVCT(186) 14617c478bd9Sstevel@tonic-gate MKIVCT(187) 14627c478bd9Sstevel@tonic-gate MKIVCT(188) 14637c478bd9Sstevel@tonic-gate MKIVCT(189) 14647c478bd9Sstevel@tonic-gate MKIVCT(190) 14657c478bd9Sstevel@tonic-gate MKIVCT(191) 14667c478bd9Sstevel@tonic-gate MKIVCT(192) 14677c478bd9Sstevel@tonic-gate MKIVCT(193) 14687c478bd9Sstevel@tonic-gate MKIVCT(194) 14697c478bd9Sstevel@tonic-gate MKIVCT(195) 14707c478bd9Sstevel@tonic-gate MKIVCT(196) 14717c478bd9Sstevel@tonic-gate MKIVCT(197) 14727c478bd9Sstevel@tonic-gate MKIVCT(198) 14737c478bd9Sstevel@tonic-gate MKIVCT(199) 14747c478bd9Sstevel@tonic-gate MKIVCT(200) 14757c478bd9Sstevel@tonic-gate MKIVCT(201) 14767c478bd9Sstevel@tonic-gate MKIVCT(202) 14777c478bd9Sstevel@tonic-gate MKIVCT(203) 14787c478bd9Sstevel@tonic-gate MKIVCT(204) 14797c478bd9Sstevel@tonic-gate MKIVCT(205) 14807c478bd9Sstevel@tonic-gate MKIVCT(206) 14817c478bd9Sstevel@tonic-gate MKIVCT(207) 14827c478bd9Sstevel@tonic-gate MKIVCT(208) 14837c478bd9Sstevel@tonic-gate MKIVCT(209) 14847c478bd9Sstevel@tonic-gate MKIVCT(210) 14857c478bd9Sstevel@tonic-gate MKIVCT(211) 14867c478bd9Sstevel@tonic-gate MKIVCT(212) 14877c478bd9Sstevel@tonic-gate MKIVCT(213) 14887c478bd9Sstevel@tonic-gate MKIVCT(214) 14897c478bd9Sstevel@tonic-gate MKIVCT(215) 14907c478bd9Sstevel@tonic-gate MKIVCT(216) 14917c478bd9Sstevel@tonic-gate MKIVCT(217) 14927c478bd9Sstevel@tonic-gate MKIVCT(218) 14937c478bd9Sstevel@tonic-gate MKIVCT(219) 14947c478bd9Sstevel@tonic-gate MKIVCT(220) 14957c478bd9Sstevel@tonic-gate MKIVCT(221) 14967c478bd9Sstevel@tonic-gate MKIVCT(222) 14977c478bd9Sstevel@tonic-gate MKIVCT(223) 14987c478bd9Sstevel@tonic-gate MKIVCT(224) 14997c478bd9Sstevel@tonic-gate MKIVCT(225) 15007c478bd9Sstevel@tonic-gate MKIVCT(226) 15017c478bd9Sstevel@tonic-gate MKIVCT(227) 15027c478bd9Sstevel@tonic-gate MKIVCT(228) 15037c478bd9Sstevel@tonic-gate MKIVCT(229) 15047c478bd9Sstevel@tonic-gate MKIVCT(230) 15057c478bd9Sstevel@tonic-gate MKIVCT(231) 15067c478bd9Sstevel@tonic-gate MKIVCT(232) 15077c478bd9Sstevel@tonic-gate MKIVCT(233) 15087c478bd9Sstevel@tonic-gate MKIVCT(234) 15097c478bd9Sstevel@tonic-gate MKIVCT(235) 15107c478bd9Sstevel@tonic-gate MKIVCT(236) 15117c478bd9Sstevel@tonic-gate MKIVCT(237) 15127c478bd9Sstevel@tonic-gate MKIVCT(238) 15137c478bd9Sstevel@tonic-gate MKIVCT(239) 15147c478bd9Sstevel@tonic-gate MKIVCT(240) 15157c478bd9Sstevel@tonic-gate MKIVCT(241) 15167c478bd9Sstevel@tonic-gate MKIVCT(242) 15177c478bd9Sstevel@tonic-gate MKIVCT(243) 15187c478bd9Sstevel@tonic-gate MKIVCT(244) 15197c478bd9Sstevel@tonic-gate MKIVCT(245) 15207c478bd9Sstevel@tonic-gate MKIVCT(246) 15217c478bd9Sstevel@tonic-gate MKIVCT(247) 15227c478bd9Sstevel@tonic-gate MKIVCT(248) 15237c478bd9Sstevel@tonic-gate MKIVCT(249) 15247c478bd9Sstevel@tonic-gate MKIVCT(250) 15257c478bd9Sstevel@tonic-gate MKIVCT(251) 15267c478bd9Sstevel@tonic-gate MKIVCT(252) 15277c478bd9Sstevel@tonic-gate MKIVCT(253) 15287c478bd9Sstevel@tonic-gate MKIVCT(254) 15297c478bd9Sstevel@tonic-gate MKIVCT(255) 15307c478bd9Sstevel@tonic-gate 15317c478bd9Sstevel@tonic-gate#endif /* __lint */ 1532