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 2019 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 /* 82 * As of GNU binutils 2.37, the assembler has split the 'sysexit' instruction 83 * into 'sysexitl' and 'sysexitq'. Using a plain 'sysexit' is interpreted as 84 * 'sysexitl' but comes with a warning about the assumption being made. Since 85 * all warnings are treated as errors in the kernel build, this results in a 86 * build failure. Unfortunately the desired 'sysexitl' cannot be used since 87 * older versions of the GNU assembler do not understand it. 88 * The following macro emits the correct byte sequence for 'sysexitl' on this 89 * platform. 90 */ 91 #define SYSEXITL .byte 0x0f, 0x35 92 93 #elif defined(__i386) 94 95 #define IRET iret 96 97 #endif /* __i386 */ 98 99 #define XPV_TRAP_POP /* empty */ 100 #define XPV_TRAP_PUSH /* empty */ 101 #define CLEAN_CS /* empty */ 102 103 104 /* 105 * Macros for saving the original segment registers and restoring them 106 * for fast traps. 107 */ 108 #if defined(__amd64) 109 110 /* 111 * Smaller versions of INTR_PUSH and INTR_POP for fast traps. 112 * The following registers have been pushed onto the stack by 113 * hardware at this point: 114 * 115 * greg_t r_rip; 116 * greg_t r_cs; 117 * greg_t r_rfl; 118 * greg_t r_rsp; 119 * greg_t r_ss; 120 * 121 * This handler is executed both by 32-bit and 64-bit applications. 122 * 64-bit applications allow us to treat the set (%rdi, %rsi, %rdx, 123 * %rcx, %r8, %r9, %r10, %r11, %rax) as volatile across function calls. 124 * However, 32-bit applications only expect (%eax, %edx, %ecx) to be volatile 125 * across a function call -- in particular, %esi and %edi MUST be saved! 126 * 127 * We could do this differently by making a FAST_INTR_PUSH32 for 32-bit 128 * programs, and FAST_INTR_PUSH for 64-bit programs, but it doesn't seem 129 * particularly worth it. 130 */ 131 #define FAST_INTR_PUSH \ 132 INTGATE_INIT_KERNEL_FLAGS; \ 133 subq $REGOFF_RIP, %rsp; \ 134 movq %rsi, REGOFF_RSI(%rsp); \ 135 movq %rdi, REGOFF_RDI(%rsp); \ 136 swapgs 137 138 #define FAST_INTR_POP \ 139 swapgs; \ 140 movq REGOFF_RSI(%rsp), %rsi; \ 141 movq REGOFF_RDI(%rsp), %rdi; \ 142 addq $REGOFF_RIP, %rsp 143 144 #define FAST_INTR_RETURN call x86_md_clear; jmp tr_iret_user 145 146 #elif defined(__i386) 147 148 #define FAST_INTR_PUSH \ 149 cld; \ 150 __SEGREGS_PUSH \ 151 __SEGREGS_LOAD_KERNEL 152 153 #define FAST_INTR_POP \ 154 __SEGREGS_POP 155 156 #define FAST_INTR_RETURN iret 157 158 #endif /* __i386 */ 159 160 /* 161 * Handling the CR0.TS bit for floating point handling. 162 * 163 * When the TS bit is *set*, attempts to touch the floating 164 * point hardware will result in a #nm trap. 165 */ 166 #if defined(__amd64) 167 168 #define STTS(rtmp) \ 169 movq %cr0, rtmp; \ 170 orq $CR0_TS, rtmp; \ 171 movq rtmp, %cr0 172 173 #elif defined(__i386) 174 175 #define STTS(rtmp) \ 176 movl %cr0, rtmp; \ 177 orl $CR0_TS, rtmp; \ 178 movl rtmp, %cr0 179 180 #endif /* __i386 */ 181 182 #define CLTS \ 183 clts 184 185 #ifdef __cplusplus 186 } 187 #endif 188 189 #endif /* _SYS_MACHPRIVREGS_H */ 190