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 2015 Nexenta Systems, Inc. All rights reserved. 24 * Copyright 2023 Oxide Computer Company 25 * 26 * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 27 * Use is subject to license terms. 28 */ 29 30 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 31 /* All Rights Reserved */ 32 33 #ifndef _SYS_UCONTEXT_H 34 #define _SYS_UCONTEXT_H 35 36 #include <sys/feature_tests.h> 37 38 #include <sys/types.h> 39 #include <sys/mcontext.h> 40 #if !defined(_XPG4_2) || defined(__EXTENSIONS__) 41 #include <sys/signal.h> 42 #endif 43 44 #ifdef __cplusplus 45 extern "C" { 46 #endif 47 48 /* 49 * Inclusion of <sys/signal.h> for sigset_t and stack_t definitions 50 * breaks XPG4v2 namespace. Therefore we must duplicate the defines 51 * for these types here when _XPG4_2 is defined. 52 */ 53 54 #if defined(_XPG4_2) && !defined(__EXTENSIONS__) 55 #ifndef _SIGSET_T 56 #define _SIGSET_T 57 typedef struct { /* signal set type */ 58 unsigned long __sigbits[4]; 59 } sigset_t; 60 #endif /* _SIGSET_T */ 61 62 #ifndef _STACK_T 63 #define _STACK_T 64 typedef struct { 65 void *ss_sp; 66 size_t ss_size; 67 int ss_flags; 68 } stack_t; 69 #endif /* _STACK_T */ 70 #endif /* defined(_XPG4_2) && !defined(__EXTENSIONS__) */ 71 72 #if !defined(_XPG4_2) || defined(__EXTENSIONS__) 73 typedef struct ucontext ucontext_t; 74 #else 75 typedef struct __ucontext ucontext_t; 76 #endif /* !defined(_XPG4_2) || defined(__EXTENSIONS__) */ 77 78 #if !defined(_XPG4_2) || defined(__EXTENSIONS__) 79 struct ucontext { 80 #else 81 struct __ucontext { 82 #endif 83 unsigned long uc_flags; 84 ucontext_t *uc_link; 85 sigset_t uc_sigmask; 86 stack_t uc_stack; 87 mcontext_t uc_mcontext; 88 /* 89 * The first three entries have been borrowed by the lx brand right now. 90 * That should be consolidated into a single uc_brand entry with a 91 * UC_BRAND flag. Until such time, to help folks downstream who have the 92 * lx brand, we leave them as is. 93 */ 94 long uc_filler[3]; 95 long uc_xsave; 96 long uc_filler1; 97 }; 98 99 #if defined(_SYSCALL32) 100 101 /* Kernel view of user ILP32 ucontext structure */ 102 103 typedef struct ucontext32 { 104 uint32_t uc_flags; 105 caddr32_t uc_link; 106 sigset_t uc_sigmask; 107 stack32_t uc_stack; 108 mcontext32_t uc_mcontext; 109 int32_t uc_filler[3]; 110 int32_t uc_xsave; 111 int32_t uc_filler1; 112 } ucontext32_t; 113 114 #if defined(_KERNEL) 115 extern void ucontext_nto32(const ucontext_t *src, ucontext32_t *dest); 116 extern void ucontext_32ton(const ucontext32_t *src, ucontext_t *dest); 117 #endif 118 119 #endif /* _SYSCALL32 */ 120 121 #if !defined(_XPG4_2) || defined(__EXTENSIONS__) 122 #define GETCONTEXT 0 123 #define SETCONTEXT 1 124 #define GETUSTACK 2 125 #define SETUSTACK 3 126 #define GETCONTEXT_EXTD 4 127 128 /* 129 * values for uc_flags 130 * these are implementation dependent flags, that should be hidden 131 * from the user interface, defining which elements of ucontext 132 * are valid, and should be restored on call to setcontext 133 */ 134 135 #define UC_SIGMASK 0x01 136 #define UC_STACK 0x02 137 #define UC_CPU 0x04 138 #define UC_MAU 0x08 139 #define UC_FPU UC_MAU 140 #define UC_XSAVE 0x10 141 142 #define UC_MCONTEXT (UC_CPU|UC_FPU) 143 144 /* 145 * UC_ALL specifies the default context 146 */ 147 148 #define UC_ALL (UC_SIGMASK|UC_STACK|UC_MCONTEXT) 149 #endif /* !defined(_XPG4_2) || defined(__EXTENSIONS__) */ 150 151 #ifdef _KERNEL 152 /* 153 * This structure is the private header for the xsave data that we end up 154 * sending to the stack. This is basically our own compressed form. See, 155 * uts/intel/os/fpu.c for more information. To help maintain the private nature, 156 * this is unfortunately duplicated in the xsave tests. If you change this you 157 * must update test/os-tests/tests/xsave/xsave_util.h. 158 */ 159 #define UC_XSAVE_VERS (('u' << 24) | ('c' << 16) | 0x01) 160 typedef struct uc_xsave { 161 uint32_t ucx_vers; 162 uint32_t ucx_len; 163 uint64_t ucx_bv; 164 } uc_xsave_t; 165 166 typedef enum { 167 /* 168 * Do a boring old savecontext() where we assume that only the data 169 * structure that we're given must be filled in. 170 */ 171 SAVECTXT_F_NONE = 0, 172 /* 173 * Indicate that we should treat the ucontext_t as having valid user 174 * pointers for copying out extended state. Currently this means that we 175 * treat the uc_xsave member as something that points to a user address. 176 */ 177 SAVECTXT_F_EXTD = 1 << 0, 178 /* 179 * This indicates that we shouldn't do normal copyout handling and need 180 * to actually avoid potentially triggering a watchpoint because we're 181 * probably in signal handling context. 182 */ 183 SAVECTXT_F_ONFAULT = 1 << 1 184 } savecontext_flags_t; 185 186 int savecontext(ucontext_t *, const k_sigset_t *, savecontext_flags_t); 187 void restorecontext(ucontext_t *); 188 189 #ifdef _SYSCALL32 190 extern int savecontext32(ucontext32_t *, const k_sigset_t *, 191 savecontext_flags_t); 192 #endif 193 #endif 194 195 #ifdef __cplusplus 196 } 197 #endif 198 199 #endif /* _SYS_UCONTEXT_H */ 200