xref: /titanic_44/usr/src/uts/intel/ia32/ml/exception.s (revision 8e50396accfa540cbe0b549256487d237e3d02f3)
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	/* &regs */
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