xref: /illumos-gate/usr/src/uts/i86pc/sys/machprivregs.h (revision 49ee6bfbbe326d1f0bbc34934ab8b07a000305c4)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  *
26  * Copyright 2018 Joyent, Inc.
27  */
28 
29 #ifndef	_SYS_MACHPRIVREGS_H
30 #define	_SYS_MACHPRIVREGS_H
31 
32 /*
33  * Platform dependent instruction sequences for manipulating
34  * privileged state
35  */
36 
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
40 
41 #define	ASSERT_UPCALL_MASK_IS_SET		/* empty */
42 
43 /*
44  * CLI and STI
45  */
46 
47 #define	CLI(r)			\
48 	cli
49 
50 #define	STI			\
51 	sti
52 
53 /*
54  * Used to re-enable interrupts in the body of exception handlers
55  */
56 
57 #if defined(__amd64)
58 
59 #define	ENABLE_INTR_FLAGS		\
60 	pushq	$F_ON;			\
61 	popfq
62 
63 #elif defined(__i386)
64 
65 #define	ENABLE_INTR_FLAGS		\
66 	pushl	$F_ON;			\
67 	popfl
68 
69 #endif	/* __i386 */
70 
71 /*
72  * IRET and SWAPGS
73  */
74 #if defined(__amd64)
75 
76 #define	IRET	iretq
77 #define	SYSRETQ	sysretq
78 #define	SYSRETL	sysretl
79 #define	SWAPGS	swapgs
80 
81 #elif defined(__i386)
82 
83 #define	IRET	iret
84 
85 #endif	/* __i386 */
86 
87 #define	XPV_TRAP_POP	/* empty */
88 #define	XPV_TRAP_PUSH	/* empty */
89 #define	CLEAN_CS	/* empty */
90 
91 
92 /*
93  * Macros for saving the original segment registers and restoring them
94  * for fast traps.
95  */
96 #if defined(__amd64)
97 
98 /*
99  * Smaller versions of INTR_PUSH and INTR_POP for fast traps.
100  * The following registers have been pushed onto the stack by
101  * hardware at this point:
102  *
103  *	greg_t  r_rip;
104  *	greg_t  r_cs;
105  *	greg_t  r_rfl;
106  *	greg_t  r_rsp;
107  *	greg_t  r_ss;
108  *
109  * This handler is executed both by 32-bit and 64-bit applications.
110  * 64-bit applications allow us to treat the set (%rdi, %rsi, %rdx,
111  * %rcx, %r8, %r9, %r10, %r11, %rax) as volatile across function calls.
112  * However, 32-bit applications only expect (%eax, %edx, %ecx) to be volatile
113  * across a function call -- in particular, %esi and %edi MUST be saved!
114  *
115  * We could do this differently by making a FAST_INTR_PUSH32 for 32-bit
116  * programs, and FAST_INTR_PUSH for 64-bit programs, but it doesn't seem
117  * particularly worth it.
118  */
119 #define	FAST_INTR_PUSH			\
120 	INTGATE_INIT_KERNEL_FLAGS;	\
121 	subq	$REGOFF_RIP, %rsp;	\
122 	movq	%rsi, REGOFF_RSI(%rsp);	\
123 	movq	%rdi, REGOFF_RDI(%rsp);	\
124 	swapgs
125 
126 #define	FAST_INTR_POP			\
127 	swapgs;				\
128 	movq	REGOFF_RSI(%rsp), %rsi;	\
129 	movq	REGOFF_RDI(%rsp), %rdi;	\
130 	addq	$REGOFF_RIP, %rsp
131 
132 #define	FAST_INTR_RETURN	jmp tr_iret_user
133 
134 #elif defined(__i386)
135 
136 #define	FAST_INTR_PUSH          \
137 	cld;                    \
138 	__SEGREGS_PUSH          \
139 	__SEGREGS_LOAD_KERNEL
140 
141 #define	FAST_INTR_POP		\
142 	__SEGREGS_POP
143 
144 #define	FAST_INTR_RETURN	iret
145 
146 #endif	/* __i386 */
147 
148 /*
149  * Handling the CR0.TS bit for floating point handling.
150  *
151  * When the TS bit is *set*, attempts to touch the floating
152  * point hardware will result in a #nm trap.
153  */
154 #if defined(__amd64)
155 
156 #define	STTS(rtmp)		\
157 	movq	%cr0, rtmp;	\
158 	orq	$CR0_TS, rtmp;	\
159 	movq	rtmp, %cr0
160 
161 #elif defined(__i386)
162 
163 #define	STTS(rtmp)		\
164 	movl	%cr0, rtmp;	\
165 	orl	$CR0_TS, rtmp;	\
166 	movl	rtmp, %cr0
167 
168 #endif	/* __i386 */
169 
170 #define	CLTS			\
171 	clts
172 
173 #ifdef __cplusplus
174 }
175 #endif
176 
177 #endif	/* _SYS_MACHPRIVREGS_H */
178