1 /* 2 * sigaltstack coroutine initialization code 3 * 4 * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws> 5 * Copyright (C) 2011 Kevin Wolf <kwolf@redhat.com> 6 * Copyright (C) 2012 Alex Barcelo <abarcelo@ac.upc.edu> 7 ** This file is partly based on pth_mctx.c, from the GNU Portable Threads 8 ** Copyright (c) 1999-2006 Ralf S. Engelschall <rse@engelschall.com> 9 * 10 * This library is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU Lesser General Public 12 * License as published by the Free Software Foundation; either 13 * version 2.1 of the License, or (at your option) any later version. 14 * 15 * This library is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 * Lesser General Public License for more details. 19 * 20 * You should have received a copy of the GNU Lesser General Public 21 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 22 */ 23 24 /* XXX Is there a nicer way to disable glibc's stack check for longjmp? */ 25 #ifdef _FORTIFY_SOURCE 26 #undef _FORTIFY_SOURCE 27 #endif 28 #include <stdlib.h> 29 #include <setjmp.h> 30 #include <stdint.h> 31 #include <pthread.h> 32 #include <signal.h> 33 #include "qemu-common.h" 34 #include "qemu/coroutine_int.h" 35 36 typedef struct { 37 Coroutine base; 38 void *stack; 39 sigjmp_buf env; 40 } CoroutineUContext; 41 42 /** 43 * Per-thread coroutine bookkeeping 44 */ 45 typedef struct { 46 /** Currently executing coroutine */ 47 Coroutine *current; 48 49 /** The default coroutine */ 50 CoroutineUContext leader; 51 52 /** Information for the signal handler (trampoline) */ 53 sigjmp_buf tr_reenter; 54 volatile sig_atomic_t tr_called; 55 void *tr_handler; 56 } CoroutineThreadState; 57 58 static pthread_key_t thread_state_key; 59 60 static CoroutineThreadState *coroutine_get_thread_state(void) 61 { 62 CoroutineThreadState *s = pthread_getspecific(thread_state_key); 63 64 if (!s) { 65 s = g_malloc0(sizeof(*s)); 66 s->current = &s->leader.base; 67 pthread_setspecific(thread_state_key, s); 68 } 69 return s; 70 } 71 72 static void qemu_coroutine_thread_cleanup(void *opaque) 73 { 74 CoroutineThreadState *s = opaque; 75 76 g_free(s); 77 } 78 79 static void __attribute__((constructor)) coroutine_init(void) 80 { 81 int ret; 82 83 ret = pthread_key_create(&thread_state_key, qemu_coroutine_thread_cleanup); 84 if (ret != 0) { 85 fprintf(stderr, "unable to create leader key: %s\n", strerror(errno)); 86 abort(); 87 } 88 } 89 90 /* "boot" function 91 * This is what starts the coroutine, is called from the trampoline 92 * (from the signal handler when it is not signal handling, read ahead 93 * for more information). 94 */ 95 static void coroutine_bootstrap(CoroutineUContext *self, Coroutine *co) 96 { 97 /* Initialize longjmp environment and switch back the caller */ 98 if (!sigsetjmp(self->env, 0)) { 99 siglongjmp(*(sigjmp_buf *)co->entry_arg, 1); 100 } 101 102 while (true) { 103 co->entry(co->entry_arg); 104 qemu_coroutine_switch(co, co->caller, COROUTINE_TERMINATE); 105 } 106 } 107 108 /* 109 * This is used as the signal handler. This is called with the brand new stack 110 * (thanks to sigaltstack). We have to return, given that this is a signal 111 * handler and the sigmask and some other things are changed. 112 */ 113 static void coroutine_trampoline(int signal) 114 { 115 CoroutineUContext *self; 116 Coroutine *co; 117 CoroutineThreadState *coTS; 118 119 /* Get the thread specific information */ 120 coTS = coroutine_get_thread_state(); 121 self = coTS->tr_handler; 122 coTS->tr_called = 1; 123 co = &self->base; 124 125 /* 126 * Here we have to do a bit of a ping pong between the caller, given that 127 * this is a signal handler and we have to do a return "soon". Then the 128 * caller can reestablish everything and do a siglongjmp here again. 129 */ 130 if (!sigsetjmp(coTS->tr_reenter, 0)) { 131 return; 132 } 133 134 /* 135 * Ok, the caller has siglongjmp'ed back to us, so now prepare 136 * us for the real machine state switching. We have to jump 137 * into another function here to get a new stack context for 138 * the auto variables (which have to be auto-variables 139 * because the start of the thread happens later). Else with 140 * PIC (i.e. Position Independent Code which is used when PTH 141 * is built as a shared library) most platforms would 142 * horrible core dump as experience showed. 143 */ 144 coroutine_bootstrap(self, co); 145 } 146 147 Coroutine *qemu_coroutine_new(void) 148 { 149 const size_t stack_size = 1 << 20; 150 CoroutineUContext *co; 151 CoroutineThreadState *coTS; 152 struct sigaction sa; 153 struct sigaction osa; 154 stack_t ss; 155 stack_t oss; 156 sigset_t sigs; 157 sigset_t osigs; 158 sigjmp_buf old_env; 159 160 /* The way to manipulate stack is with the sigaltstack function. We 161 * prepare a stack, with it delivering a signal to ourselves and then 162 * put sigsetjmp/siglongjmp where needed. 163 * This has been done keeping coroutine-ucontext as a model and with the 164 * pth ideas (GNU Portable Threads). See coroutine-ucontext for the basics 165 * of the coroutines and see pth_mctx.c (from the pth project) for the 166 * sigaltstack way of manipulating stacks. 167 */ 168 169 co = g_malloc0(sizeof(*co)); 170 co->stack = g_malloc(stack_size); 171 co->base.entry_arg = &old_env; /* stash away our jmp_buf */ 172 173 coTS = coroutine_get_thread_state(); 174 coTS->tr_handler = co; 175 176 /* 177 * Preserve the SIGUSR2 signal state, block SIGUSR2, 178 * and establish our signal handler. The signal will 179 * later transfer control onto the signal stack. 180 */ 181 sigemptyset(&sigs); 182 sigaddset(&sigs, SIGUSR2); 183 pthread_sigmask(SIG_BLOCK, &sigs, &osigs); 184 sa.sa_handler = coroutine_trampoline; 185 sigfillset(&sa.sa_mask); 186 sa.sa_flags = SA_ONSTACK; 187 if (sigaction(SIGUSR2, &sa, &osa) != 0) { 188 abort(); 189 } 190 191 /* 192 * Set the new stack. 193 */ 194 ss.ss_sp = co->stack; 195 ss.ss_size = stack_size; 196 ss.ss_flags = 0; 197 if (sigaltstack(&ss, &oss) < 0) { 198 abort(); 199 } 200 201 /* 202 * Now transfer control onto the signal stack and set it up. 203 * It will return immediately via "return" after the sigsetjmp() 204 * was performed. Be careful here with race conditions. The 205 * signal can be delivered the first time sigsuspend() is 206 * called. 207 */ 208 coTS->tr_called = 0; 209 pthread_kill(pthread_self(), SIGUSR2); 210 sigfillset(&sigs); 211 sigdelset(&sigs, SIGUSR2); 212 while (!coTS->tr_called) { 213 sigsuspend(&sigs); 214 } 215 216 /* 217 * Inform the system that we are back off the signal stack by 218 * removing the alternative signal stack. Be careful here: It 219 * first has to be disabled, before it can be removed. 220 */ 221 sigaltstack(NULL, &ss); 222 ss.ss_flags = SS_DISABLE; 223 if (sigaltstack(&ss, NULL) < 0) { 224 abort(); 225 } 226 sigaltstack(NULL, &ss); 227 if (!(oss.ss_flags & SS_DISABLE)) { 228 sigaltstack(&oss, NULL); 229 } 230 231 /* 232 * Restore the old SIGUSR2 signal handler and mask 233 */ 234 sigaction(SIGUSR2, &osa, NULL); 235 pthread_sigmask(SIG_SETMASK, &osigs, NULL); 236 237 /* 238 * Now enter the trampoline again, but this time not as a signal 239 * handler. Instead we jump into it directly. The functionally 240 * redundant ping-pong pointer arithmetic is necessary to avoid 241 * type-conversion warnings related to the `volatile' qualifier and 242 * the fact that `jmp_buf' usually is an array type. 243 */ 244 if (!sigsetjmp(old_env, 0)) { 245 siglongjmp(coTS->tr_reenter, 1); 246 } 247 248 /* 249 * Ok, we returned again, so now we're finished 250 */ 251 252 return &co->base; 253 } 254 255 void qemu_coroutine_delete(Coroutine *co_) 256 { 257 CoroutineUContext *co = DO_UPCAST(CoroutineUContext, base, co_); 258 259 g_free(co->stack); 260 g_free(co); 261 } 262 263 CoroutineAction qemu_coroutine_switch(Coroutine *from_, Coroutine *to_, 264 CoroutineAction action) 265 { 266 CoroutineUContext *from = DO_UPCAST(CoroutineUContext, base, from_); 267 CoroutineUContext *to = DO_UPCAST(CoroutineUContext, base, to_); 268 CoroutineThreadState *s = coroutine_get_thread_state(); 269 int ret; 270 271 s->current = to_; 272 273 ret = sigsetjmp(from->env, 0); 274 if (ret == 0) { 275 siglongjmp(to->env, action); 276 } 277 return ret; 278 } 279 280 Coroutine *qemu_coroutine_self(void) 281 { 282 CoroutineThreadState *s = coroutine_get_thread_state(); 283 284 return s->current; 285 } 286 287 bool qemu_in_coroutine(void) 288 { 289 CoroutineThreadState *s = pthread_getspecific(thread_state_key); 290 291 return s && s->current->caller; 292 } 293 294