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