blob: ded21007e7b16e07f2b8a9d83df1da80b66a0890 [file] [log] [blame]
Blue Swirl296af7c2010-03-29 19:23:50 +00001/*
2 * QEMU System Emulator
3 *
4 * Copyright (c) 2003-2008 Fabrice Bellard
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
25/* Needed early for CONFIG_BSD etc. */
26#include "config-host.h"
27
28#include "monitor.h"
29#include "sysemu.h"
30#include "gdbstub.h"
31#include "dma.h"
32#include "kvm.h"
Jan Kiszka262ea182010-07-06 10:49:57 +020033#include "exec-all.h"
Blue Swirl296af7c2010-03-29 19:23:50 +000034
Paolo Bonzini96284e82011-03-12 17:43:53 +010035#include "qemu-thread.h"
Blue Swirl296af7c2010-03-29 19:23:50 +000036#include "cpus.h"
Jan Kiszka0ff0fc12011-06-23 10:15:55 +020037
38#ifndef _WIN32
Marcelo Tosattia8486bc2010-10-11 15:31:16 -030039#include "compatfd.h"
Jan Kiszka0ff0fc12011-06-23 10:15:55 +020040#endif
Blue Swirl296af7c2010-03-29 19:23:50 +000041
Blue Swirl7277e022010-04-12 17:19:06 +000042#ifdef SIGRTMIN
43#define SIG_IPI (SIGRTMIN+4)
44#else
45#define SIG_IPI SIGUSR1
46#endif
47
Jan Kiszka6d9cb732011-02-01 22:15:58 +010048#ifdef CONFIG_LINUX
49
50#include <sys/prctl.h>
51
Marcelo Tosattic0532a72010-10-11 15:31:21 -030052#ifndef PR_MCE_KILL
53#define PR_MCE_KILL 33
54#endif
55
Jan Kiszka6d9cb732011-02-01 22:15:58 +010056#ifndef PR_MCE_KILL_SET
57#define PR_MCE_KILL_SET 1
58#endif
59
60#ifndef PR_MCE_KILL_EARLY
61#define PR_MCE_KILL_EARLY 1
62#endif
63
64#endif /* CONFIG_LINUX */
65
Blue Swirl296af7c2010-03-29 19:23:50 +000066static CPUState *next_cpu;
67
68/***********************************************************/
69void hw_error(const char *fmt, ...)
70{
71 va_list ap;
72 CPUState *env;
73
74 va_start(ap, fmt);
75 fprintf(stderr, "qemu: hardware error: ");
76 vfprintf(stderr, fmt, ap);
77 fprintf(stderr, "\n");
78 for(env = first_cpu; env != NULL; env = env->next_cpu) {
79 fprintf(stderr, "CPU #%d:\n", env->cpu_index);
80#ifdef TARGET_I386
81 cpu_dump_state(env, stderr, fprintf, X86_DUMP_FPU);
82#else
83 cpu_dump_state(env, stderr, fprintf, 0);
84#endif
85 }
86 va_end(ap);
87 abort();
88}
89
90void cpu_synchronize_all_states(void)
91{
92 CPUState *cpu;
93
94 for (cpu = first_cpu; cpu; cpu = cpu->next_cpu) {
95 cpu_synchronize_state(cpu);
96 }
97}
98
99void cpu_synchronize_all_post_reset(void)
100{
101 CPUState *cpu;
102
103 for (cpu = first_cpu; cpu; cpu = cpu->next_cpu) {
104 cpu_synchronize_post_reset(cpu);
105 }
106}
107
108void cpu_synchronize_all_post_init(void)
109{
110 CPUState *cpu;
111
112 for (cpu = first_cpu; cpu; cpu = cpu->next_cpu) {
113 cpu_synchronize_post_init(cpu);
114 }
115}
116
Marcelo Tosatti3ae95012010-05-04 09:45:24 -0300117int cpu_is_stopped(CPUState *env)
118{
119 return !vm_running || env->stopped;
120}
121
Blue Swirl296af7c2010-03-29 19:23:50 +0000122static void do_vm_stop(int reason)
123{
124 if (vm_running) {
125 cpu_disable_ticks();
126 vm_running = 0;
127 pause_all_vcpus();
128 vm_state_notify(0, reason);
Michael S. Tsirkin55df6f32010-11-22 19:52:22 +0200129 qemu_aio_flush();
130 bdrv_flush_all();
Blue Swirl296af7c2010-03-29 19:23:50 +0000131 monitor_protocol_event(QEVENT_STOP, NULL);
132 }
133}
134
135static int cpu_can_run(CPUState *env)
136{
Jan Kiszka0ab07c62011-02-07 12:19:14 +0100137 if (env->stop) {
Blue Swirl296af7c2010-03-29 19:23:50 +0000138 return 0;
Jan Kiszka0ab07c62011-02-07 12:19:14 +0100139 }
140 if (env->stopped || !vm_running) {
Blue Swirl296af7c2010-03-29 19:23:50 +0000141 return 0;
Jan Kiszka0ab07c62011-02-07 12:19:14 +0100142 }
Blue Swirl296af7c2010-03-29 19:23:50 +0000143 return 1;
144}
145
Jan Kiszka16400322011-02-09 16:29:37 +0100146static bool cpu_thread_is_idle(CPUState *env)
Blue Swirl296af7c2010-03-29 19:23:50 +0000147{
Jan Kiszka16400322011-02-09 16:29:37 +0100148 if (env->stop || env->queued_work_first) {
149 return false;
150 }
151 if (env->stopped || !vm_running) {
152 return true;
153 }
Jan Kiszkaf2c1cc82011-03-15 12:26:18 +0100154 if (!env->halted || qemu_cpu_has_work(env) ||
155 (kvm_enabled() && kvm_irqchip_in_kernel())) {
Jan Kiszka16400322011-02-09 16:29:37 +0100156 return false;
157 }
158 return true;
Blue Swirl296af7c2010-03-29 19:23:50 +0000159}
160
Paolo Bonziniab33fcd2011-04-13 10:03:44 +0200161bool all_cpu_threads_idle(void)
Blue Swirl296af7c2010-03-29 19:23:50 +0000162{
163 CPUState *env;
164
Jan Kiszka16400322011-02-09 16:29:37 +0100165 for (env = first_cpu; env != NULL; env = env->next_cpu) {
166 if (!cpu_thread_is_idle(env)) {
167 return false;
168 }
169 }
170 return true;
Blue Swirl296af7c2010-03-29 19:23:50 +0000171}
172
Jan Kiszka1009d2e2011-03-15 12:26:13 +0100173static void cpu_handle_guest_debug(CPUState *env)
Jan Kiszka3c638d02010-06-25 16:56:56 +0200174{
175 gdb_set_stop_cpu(env);
Jan Kiszka8cf71712011-02-07 12:19:16 +0100176 qemu_system_debug_request();
Jan Kiszka83f338f2011-02-07 12:19:17 +0100177#ifdef CONFIG_IOTHREAD
178 env->stopped = 1;
179#endif
Jan Kiszka3c638d02010-06-25 16:56:56 +0200180}
181
Paolo Bonzini714bd042011-03-12 17:44:06 +0100182#ifdef CONFIG_IOTHREAD
183static void cpu_signal(int sig)
184{
185 if (cpu_single_env) {
186 cpu_exit(cpu_single_env);
187 }
188 exit_request = 1;
189}
190#endif
191
Jan Kiszka6d9cb732011-02-01 22:15:58 +0100192#ifdef CONFIG_LINUX
193static void sigbus_reraise(void)
194{
195 sigset_t set;
196 struct sigaction action;
197
198 memset(&action, 0, sizeof(action));
199 action.sa_handler = SIG_DFL;
200 if (!sigaction(SIGBUS, &action, NULL)) {
201 raise(SIGBUS);
202 sigemptyset(&set);
203 sigaddset(&set, SIGBUS);
204 sigprocmask(SIG_UNBLOCK, &set, NULL);
205 }
206 perror("Failed to re-raise SIGBUS!\n");
207 abort();
208}
209
210static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo,
211 void *ctx)
212{
213 if (kvm_on_sigbus(siginfo->ssi_code,
214 (void *)(intptr_t)siginfo->ssi_addr)) {
215 sigbus_reraise();
216 }
217}
218
219static void qemu_init_sigbus(void)
220{
221 struct sigaction action;
222
223 memset(&action, 0, sizeof(action));
224 action.sa_flags = SA_SIGINFO;
225 action.sa_sigaction = (void (*)(int, siginfo_t*, void*))sigbus_handler;
226 sigaction(SIGBUS, &action, NULL);
227
228 prctl(PR_MCE_KILL, PR_MCE_KILL_SET, PR_MCE_KILL_EARLY, 0, 0);
229}
230
Jan Kiszka1ab3c6c2011-03-15 12:26:12 +0100231static void qemu_kvm_eat_signals(CPUState *env)
232{
233 struct timespec ts = { 0, 0 };
234 siginfo_t siginfo;
235 sigset_t waitset;
236 sigset_t chkset;
237 int r;
238
239 sigemptyset(&waitset);
240 sigaddset(&waitset, SIG_IPI);
241 sigaddset(&waitset, SIGBUS);
242
243 do {
244 r = sigtimedwait(&waitset, &siginfo, &ts);
245 if (r == -1 && !(errno == EAGAIN || errno == EINTR)) {
246 perror("sigtimedwait");
247 exit(1);
248 }
249
250 switch (r) {
251 case SIGBUS:
252 if (kvm_on_sigbus_vcpu(env, siginfo.si_code, siginfo.si_addr)) {
253 sigbus_reraise();
254 }
255 break;
256 default:
257 break;
258 }
259
260 r = sigpending(&chkset);
261 if (r == -1) {
262 perror("sigpending");
263 exit(1);
264 }
265 } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS));
266
267#ifndef CONFIG_IOTHREAD
268 if (sigismember(&chkset, SIGIO) || sigismember(&chkset, SIGALRM)) {
269 qemu_notify_event();
270 }
271#endif
272}
273
Jan Kiszka6d9cb732011-02-01 22:15:58 +0100274#else /* !CONFIG_LINUX */
275
276static void qemu_init_sigbus(void)
277{
278}
Jan Kiszka1ab3c6c2011-03-15 12:26:12 +0100279
280static void qemu_kvm_eat_signals(CPUState *env)
281{
282}
Jan Kiszka6d9cb732011-02-01 22:15:58 +0100283#endif /* !CONFIG_LINUX */
284
Blue Swirl296af7c2010-03-29 19:23:50 +0000285#ifndef _WIN32
286static int io_thread_fd = -1;
287
288static void qemu_event_increment(void)
289{
290 /* Write 8 bytes to be compatible with eventfd. */
Blue Swirl26a82332010-05-14 19:32:21 +0000291 static const uint64_t val = 1;
Blue Swirl296af7c2010-03-29 19:23:50 +0000292 ssize_t ret;
293
Jan Kiszka0ab07c62011-02-07 12:19:14 +0100294 if (io_thread_fd == -1) {
Blue Swirl296af7c2010-03-29 19:23:50 +0000295 return;
Jan Kiszka0ab07c62011-02-07 12:19:14 +0100296 }
Blue Swirl296af7c2010-03-29 19:23:50 +0000297 do {
298 ret = write(io_thread_fd, &val, sizeof(val));
299 } while (ret < 0 && errno == EINTR);
300
301 /* EAGAIN is fine, a read must be pending. */
302 if (ret < 0 && errno != EAGAIN) {
Alexandre Raymond77bec682011-06-13 22:16:36 -0400303 fprintf(stderr, "qemu_event_increment: write() failed: %s\n",
Blue Swirl296af7c2010-03-29 19:23:50 +0000304 strerror(errno));
305 exit (1);
306 }
307}
308
309static void qemu_event_read(void *opaque)
310{
Stefan Weile0efb992011-02-23 19:09:16 +0100311 int fd = (intptr_t)opaque;
Blue Swirl296af7c2010-03-29 19:23:50 +0000312 ssize_t len;
313 char buffer[512];
314
315 /* Drain the notify pipe. For eventfd, only 8 bytes will be read. */
316 do {
317 len = read(fd, buffer, sizeof(buffer));
318 } while ((len == -1 && errno == EINTR) || len == sizeof(buffer));
319}
320
321static int qemu_event_init(void)
322{
323 int err;
324 int fds[2];
325
326 err = qemu_eventfd(fds);
Jan Kiszka0ab07c62011-02-07 12:19:14 +0100327 if (err == -1) {
Blue Swirl296af7c2010-03-29 19:23:50 +0000328 return -errno;
Jan Kiszka0ab07c62011-02-07 12:19:14 +0100329 }
Blue Swirl296af7c2010-03-29 19:23:50 +0000330 err = fcntl_setfl(fds[0], O_NONBLOCK);
Jan Kiszka0ab07c62011-02-07 12:19:14 +0100331 if (err < 0) {
Blue Swirl296af7c2010-03-29 19:23:50 +0000332 goto fail;
Jan Kiszka0ab07c62011-02-07 12:19:14 +0100333 }
Blue Swirl296af7c2010-03-29 19:23:50 +0000334 err = fcntl_setfl(fds[1], O_NONBLOCK);
Jan Kiszka0ab07c62011-02-07 12:19:14 +0100335 if (err < 0) {
Blue Swirl296af7c2010-03-29 19:23:50 +0000336 goto fail;
Jan Kiszka0ab07c62011-02-07 12:19:14 +0100337 }
Blue Swirl296af7c2010-03-29 19:23:50 +0000338 qemu_set_fd_handler2(fds[0], NULL, qemu_event_read, NULL,
Stefan Weile0efb992011-02-23 19:09:16 +0100339 (void *)(intptr_t)fds[0]);
Blue Swirl296af7c2010-03-29 19:23:50 +0000340
341 io_thread_fd = fds[1];
342 return 0;
343
344fail:
345 close(fds[0]);
346 close(fds[1]);
347 return err;
348}
Blue Swirl296af7c2010-03-29 19:23:50 +0000349
Jan Kiszka55f8d6a2011-02-01 22:15:52 +0100350static void dummy_signal(int sig)
Blue Swirl296af7c2010-03-29 19:23:50 +0000351{
352}
353
Marcelo Tosattia8486bc2010-10-11 15:31:16 -0300354/* If we have signalfd, we mask out the signals we want to handle and then
355 * use signalfd to listen for them. We rely on whatever the current signal
356 * handler is to dispatch the signals when we receive them.
357 */
358static void sigfd_handler(void *opaque)
359{
Stefan Weile0efb992011-02-23 19:09:16 +0100360 int fd = (intptr_t)opaque;
Marcelo Tosattia8486bc2010-10-11 15:31:16 -0300361 struct qemu_signalfd_siginfo info;
362 struct sigaction action;
363 ssize_t len;
364
365 while (1) {
366 do {
367 len = read(fd, &info, sizeof(info));
368 } while (len == -1 && errno == EINTR);
369
370 if (len == -1 && errno == EAGAIN) {
371 break;
372 }
373
374 if (len != sizeof(info)) {
375 printf("read from sigfd returned %zd: %m\n", len);
376 return;
377 }
378
379 sigaction(info.ssi_signo, NULL, &action);
380 if ((action.sa_flags & SA_SIGINFO) && action.sa_sigaction) {
381 action.sa_sigaction(info.ssi_signo,
382 (siginfo_t *)&info, NULL);
383 } else if (action.sa_handler) {
384 action.sa_handler(info.ssi_signo);
385 }
386 }
387}
388
Paolo Bonzini712ae482011-03-12 17:44:05 +0100389static int qemu_signal_init(void)
Marcelo Tosattia8486bc2010-10-11 15:31:16 -0300390{
391 int sigfd;
Paolo Bonzini712ae482011-03-12 17:44:05 +0100392 sigset_t set;
Marcelo Tosattia8486bc2010-10-11 15:31:16 -0300393
Paolo Bonzini712ae482011-03-12 17:44:05 +0100394#ifdef CONFIG_IOTHREAD
395 /* SIGUSR2 used by posix-aio-compat.c */
396 sigemptyset(&set);
397 sigaddset(&set, SIGUSR2);
398 pthread_sigmask(SIG_UNBLOCK, &set, NULL);
399
400 sigemptyset(&set);
401 sigaddset(&set, SIGIO);
402 sigaddset(&set, SIGALRM);
403 sigaddset(&set, SIG_IPI);
404 sigaddset(&set, SIGBUS);
405 pthread_sigmask(SIG_BLOCK, &set, NULL);
406#else
407 sigemptyset(&set);
408 sigaddset(&set, SIGBUS);
409 if (kvm_enabled()) {
410 /*
411 * We need to process timer signals synchronously to avoid a race
412 * between exit_request check and KVM vcpu entry.
413 */
414 sigaddset(&set, SIGIO);
415 sigaddset(&set, SIGALRM);
416 }
417#endif
418
419 sigfd = qemu_signalfd(&set);
Marcelo Tosattia8486bc2010-10-11 15:31:16 -0300420 if (sigfd == -1) {
421 fprintf(stderr, "failed to create signalfd\n");
422 return -errno;
423 }
424
425 fcntl_setfl(sigfd, O_NONBLOCK);
426
427 qemu_set_fd_handler2(sigfd, NULL, sigfd_handler, NULL,
Stefan Weile0efb992011-02-23 19:09:16 +0100428 (void *)(intptr_t)sigfd);
Marcelo Tosattia8486bc2010-10-11 15:31:16 -0300429
430 return 0;
431}
Blue Swirl296af7c2010-03-29 19:23:50 +0000432
Paolo Bonzini714bd042011-03-12 17:44:06 +0100433static void qemu_kvm_init_cpu_signals(CPUState *env)
434{
435 int r;
436 sigset_t set;
437 struct sigaction sigact;
438
439 memset(&sigact, 0, sizeof(sigact));
440 sigact.sa_handler = dummy_signal;
441 sigaction(SIG_IPI, &sigact, NULL);
442
443#ifdef CONFIG_IOTHREAD
444 pthread_sigmask(SIG_BLOCK, NULL, &set);
445 sigdelset(&set, SIG_IPI);
446 sigdelset(&set, SIGBUS);
447 r = kvm_set_signal_mask(env, &set);
448 if (r) {
449 fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(-r));
450 exit(1);
451 }
452#else
453 sigemptyset(&set);
454 sigaddset(&set, SIG_IPI);
455 sigaddset(&set, SIGIO);
456 sigaddset(&set, SIGALRM);
457 pthread_sigmask(SIG_BLOCK, &set, NULL);
458
459 pthread_sigmask(SIG_BLOCK, NULL, &set);
460 sigdelset(&set, SIGIO);
461 sigdelset(&set, SIGALRM);
462#endif
463 sigdelset(&set, SIG_IPI);
464 sigdelset(&set, SIGBUS);
465 r = kvm_set_signal_mask(env, &set);
466 if (r) {
467 fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(-r));
468 exit(1);
469 }
470}
471
472static void qemu_tcg_init_cpu_signals(void)
473{
474#ifdef CONFIG_IOTHREAD
475 sigset_t set;
476 struct sigaction sigact;
477
478 memset(&sigact, 0, sizeof(sigact));
479 sigact.sa_handler = cpu_signal;
480 sigaction(SIG_IPI, &sigact, NULL);
481
482 sigemptyset(&set);
483 sigaddset(&set, SIG_IPI);
484 pthread_sigmask(SIG_UNBLOCK, &set, NULL);
485#endif
486}
487
Jan Kiszka55f8d6a2011-02-01 22:15:52 +0100488#else /* _WIN32 */
489
Blue Swirl296af7c2010-03-29 19:23:50 +0000490HANDLE qemu_event_handle;
491
492static void dummy_event_handler(void *opaque)
493{
494}
495
496static int qemu_event_init(void)
497{
498 qemu_event_handle = CreateEvent(NULL, FALSE, FALSE, NULL);
499 if (!qemu_event_handle) {
500 fprintf(stderr, "Failed CreateEvent: %ld\n", GetLastError());
501 return -1;
502 }
503 qemu_add_wait_object(qemu_event_handle, dummy_event_handler, NULL);
504 return 0;
505}
506
507static void qemu_event_increment(void)
508{
509 if (!SetEvent(qemu_event_handle)) {
510 fprintf(stderr, "qemu_event_increment: SetEvent failed: %ld\n",
511 GetLastError());
512 exit (1);
513 }
514}
Jan Kiszka9a360852011-02-01 22:15:55 +0100515
Paolo Bonzini712ae482011-03-12 17:44:05 +0100516static int qemu_signal_init(void)
517{
518 return 0;
519}
520
Paolo Bonzini714bd042011-03-12 17:44:06 +0100521static void qemu_kvm_init_cpu_signals(CPUState *env)
522{
523 abort();
524}
525
526static void qemu_tcg_init_cpu_signals(void)
527{
528}
Jan Kiszka55f8d6a2011-02-01 22:15:52 +0100529#endif /* _WIN32 */
Blue Swirl296af7c2010-03-29 19:23:50 +0000530
531#ifndef CONFIG_IOTHREAD
532int qemu_init_main_loop(void)
533{
Jan Kiszkad0f294c2011-02-01 22:15:56 +0100534 int ret;
535
Paolo Bonzini712ae482011-03-12 17:44:05 +0100536 ret = qemu_signal_init();
Jan Kiszkad0f294c2011-02-01 22:15:56 +0100537 if (ret) {
538 return ret;
539 }
Blue Swirl296af7c2010-03-29 19:23:50 +0000540
Jan Kiszka6d9cb732011-02-01 22:15:58 +0100541 qemu_init_sigbus();
542
Blue Swirl296af7c2010-03-29 19:23:50 +0000543 return qemu_event_init();
544}
545
546void qemu_main_loop_start(void)
547{
548}
549
550void qemu_init_vcpu(void *_env)
551{
552 CPUState *env = _env;
Jan Kiszka84b49152011-02-01 22:15:50 +0100553 int r;
Blue Swirl296af7c2010-03-29 19:23:50 +0000554
555 env->nr_cores = smp_cores;
556 env->nr_threads = smp_threads;
Jan Kiszka84b49152011-02-01 22:15:50 +0100557
558 if (kvm_enabled()) {
559 r = kvm_init_vcpu(env);
560 if (r < 0) {
561 fprintf(stderr, "kvm_init_vcpu failed: %s\n", strerror(-r));
562 exit(1);
563 }
Jan Kiszkaff48eb52011-02-01 22:15:53 +0100564 qemu_kvm_init_cpu_signals(env);
Paolo Bonzini714bd042011-03-12 17:44:06 +0100565 } else {
566 qemu_tcg_init_cpu_signals();
Jan Kiszka84b49152011-02-01 22:15:50 +0100567 }
Blue Swirl296af7c2010-03-29 19:23:50 +0000568}
569
Jan Kiszkab7680cb2011-03-12 17:43:51 +0100570int qemu_cpu_is_self(void *env)
Blue Swirl296af7c2010-03-29 19:23:50 +0000571{
572 return 1;
573}
574
575void run_on_cpu(CPUState *env, void (*func)(void *data), void *data)
576{
577 func(data);
578}
579
580void resume_all_vcpus(void)
581{
582}
583
584void pause_all_vcpus(void)
585{
586}
587
588void qemu_cpu_kick(void *env)
589{
Blue Swirl296af7c2010-03-29 19:23:50 +0000590}
591
Jan Kiszka46d62fa2011-02-01 22:15:59 +0100592void qemu_cpu_kick_self(void)
593{
594#ifndef _WIN32
595 assert(cpu_single_env);
596
597 raise(SIG_IPI);
598#else
599 abort();
600#endif
601}
602
Blue Swirl296af7c2010-03-29 19:23:50 +0000603void qemu_notify_event(void)
604{
605 CPUState *env = cpu_single_env;
606
607 qemu_event_increment ();
608 if (env) {
609 cpu_exit(env);
610 }
611 if (next_cpu && env != next_cpu) {
612 cpu_exit(next_cpu);
613 }
Jan Kiszka38145df2011-02-01 22:15:45 +0100614 exit_request = 1;
Blue Swirl296af7c2010-03-29 19:23:50 +0000615}
616
617void qemu_mutex_lock_iothread(void) {}
618void qemu_mutex_unlock_iothread(void) {}
619
Jan Kiszkab4a3d962011-02-01 22:15:43 +0100620void cpu_stop_current(void)
621{
622}
623
Blue Swirl296af7c2010-03-29 19:23:50 +0000624void vm_stop(int reason)
625{
626 do_vm_stop(reason);
627}
628
629#else /* CONFIG_IOTHREAD */
630
Blue Swirl296af7c2010-03-29 19:23:50 +0000631QemuMutex qemu_global_mutex;
632static QemuMutex qemu_fair_mutex;
633
634static QemuThread io_thread;
635
636static QemuThread *tcg_cpu_thread;
637static QemuCond *tcg_halt_cond;
638
639static int qemu_system_ready;
640/* cpu creation */
641static QemuCond qemu_cpu_cond;
642/* system init */
643static QemuCond qemu_system_cond;
644static QemuCond qemu_pause_cond;
645static QemuCond qemu_work_cond;
646
Blue Swirl296af7c2010-03-29 19:23:50 +0000647int qemu_init_main_loop(void)
648{
649 int ret;
650
Jan Kiszka6d9cb732011-02-01 22:15:58 +0100651 qemu_init_sigbus();
Jan Kiszka3c638d02010-06-25 16:56:56 +0200652
Paolo Bonzini712ae482011-03-12 17:44:05 +0100653 ret = qemu_signal_init();
Jan Kiszka0ab07c62011-02-07 12:19:14 +0100654 if (ret) {
Marcelo Tosattia8486bc2010-10-11 15:31:16 -0300655 return ret;
Jan Kiszka0ab07c62011-02-07 12:19:14 +0100656 }
Marcelo Tosattia8486bc2010-10-11 15:31:16 -0300657
658 /* Note eventfd must be drained before signalfd handlers run */
Blue Swirl296af7c2010-03-29 19:23:50 +0000659 ret = qemu_event_init();
Jan Kiszka0ab07c62011-02-07 12:19:14 +0100660 if (ret) {
Blue Swirl296af7c2010-03-29 19:23:50 +0000661 return ret;
Jan Kiszka0ab07c62011-02-07 12:19:14 +0100662 }
Blue Swirl296af7c2010-03-29 19:23:50 +0000663
Anthony Liguoried945922011-02-08 18:18:18 +0100664 qemu_cond_init(&qemu_cpu_cond);
Jan Kiszkaf8ca7b42010-06-25 16:56:51 +0200665 qemu_cond_init(&qemu_system_cond);
Anthony Liguoried945922011-02-08 18:18:18 +0100666 qemu_cond_init(&qemu_pause_cond);
667 qemu_cond_init(&qemu_work_cond);
Blue Swirl296af7c2010-03-29 19:23:50 +0000668 qemu_mutex_init(&qemu_fair_mutex);
669 qemu_mutex_init(&qemu_global_mutex);
670 qemu_mutex_lock(&qemu_global_mutex);
671
Jan Kiszkab7680cb2011-03-12 17:43:51 +0100672 qemu_thread_get_self(&io_thread);
Blue Swirl296af7c2010-03-29 19:23:50 +0000673
674 return 0;
675}
676
Blue Swirl7277e022010-04-12 17:19:06 +0000677void qemu_main_loop_start(void)
678{
679 qemu_system_ready = 1;
680 qemu_cond_broadcast(&qemu_system_cond);
681}
682
Marcelo Tosattie82bcec2010-05-04 09:45:22 -0300683void run_on_cpu(CPUState *env, void (*func)(void *data), void *data)
684{
685 struct qemu_work_item wi;
686
Jan Kiszkab7680cb2011-03-12 17:43:51 +0100687 if (qemu_cpu_is_self(env)) {
Marcelo Tosattie82bcec2010-05-04 09:45:22 -0300688 func(data);
689 return;
690 }
691
692 wi.func = func;
693 wi.data = data;
Jan Kiszka0ab07c62011-02-07 12:19:14 +0100694 if (!env->queued_work_first) {
Marcelo Tosattie82bcec2010-05-04 09:45:22 -0300695 env->queued_work_first = &wi;
Jan Kiszka0ab07c62011-02-07 12:19:14 +0100696 } else {
Marcelo Tosattie82bcec2010-05-04 09:45:22 -0300697 env->queued_work_last->next = &wi;
Jan Kiszka0ab07c62011-02-07 12:19:14 +0100698 }
Marcelo Tosattie82bcec2010-05-04 09:45:22 -0300699 env->queued_work_last = &wi;
700 wi.next = NULL;
701 wi.done = false;
702
703 qemu_cpu_kick(env);
704 while (!wi.done) {
705 CPUState *self_env = cpu_single_env;
706
707 qemu_cond_wait(&qemu_work_cond, &qemu_global_mutex);
708 cpu_single_env = self_env;
709 }
710}
711
712static void flush_queued_work(CPUState *env)
713{
714 struct qemu_work_item *wi;
715
Jan Kiszka0ab07c62011-02-07 12:19:14 +0100716 if (!env->queued_work_first) {
Marcelo Tosattie82bcec2010-05-04 09:45:22 -0300717 return;
Jan Kiszka0ab07c62011-02-07 12:19:14 +0100718 }
Marcelo Tosattie82bcec2010-05-04 09:45:22 -0300719
720 while ((wi = env->queued_work_first)) {
721 env->queued_work_first = wi->next;
722 wi->func(wi->data);
723 wi->done = true;
724 }
725 env->queued_work_last = NULL;
726 qemu_cond_broadcast(&qemu_work_cond);
727}
728
Blue Swirl296af7c2010-03-29 19:23:50 +0000729static void qemu_wait_io_event_common(CPUState *env)
730{
731 if (env->stop) {
732 env->stop = 0;
733 env->stopped = 1;
734 qemu_cond_signal(&qemu_pause_cond);
735 }
Marcelo Tosattie82bcec2010-05-04 09:45:22 -0300736 flush_queued_work(env);
Jan Kiszkaaa2c3642011-02-01 22:15:42 +0100737 env->thread_kicked = false;
Blue Swirl296af7c2010-03-29 19:23:50 +0000738}
739
Jan Kiszka6cabe1f2010-06-25 16:56:53 +0200740static void qemu_tcg_wait_io_event(void)
Blue Swirl296af7c2010-03-29 19:23:50 +0000741{
Jan Kiszka6cabe1f2010-06-25 16:56:53 +0200742 CPUState *env;
743
Jan Kiszka16400322011-02-09 16:29:37 +0100744 while (all_cpu_threads_idle()) {
Paolo Bonziniab33fcd2011-04-13 10:03:44 +0200745 /* Start accounting real time to the virtual clock if the CPUs
746 are idle. */
747 qemu_clock_warp(vm_clock);
Paolo Bonzini9705fbb2011-03-12 17:44:00 +0100748 qemu_cond_wait(tcg_halt_cond, &qemu_global_mutex);
Jan Kiszka16400322011-02-09 16:29:37 +0100749 }
Blue Swirl296af7c2010-03-29 19:23:50 +0000750
751 qemu_mutex_unlock(&qemu_global_mutex);
752
753 /*
754 * Users of qemu_global_mutex can be starved, having no chance
755 * to acquire it since this path will get to it first.
756 * So use another lock to provide fairness.
757 */
758 qemu_mutex_lock(&qemu_fair_mutex);
759 qemu_mutex_unlock(&qemu_fair_mutex);
760
761 qemu_mutex_lock(&qemu_global_mutex);
Jan Kiszka6cabe1f2010-06-25 16:56:53 +0200762
763 for (env = first_cpu; env != NULL; env = env->next_cpu) {
764 qemu_wait_io_event_common(env);
765 }
Blue Swirl296af7c2010-03-29 19:23:50 +0000766}
767
Blue Swirl296af7c2010-03-29 19:23:50 +0000768static void qemu_kvm_wait_io_event(CPUState *env)
769{
Jan Kiszka16400322011-02-09 16:29:37 +0100770 while (cpu_thread_is_idle(env)) {
Paolo Bonzini9705fbb2011-03-12 17:44:00 +0100771 qemu_cond_wait(env->halt_cond, &qemu_global_mutex);
Jan Kiszka16400322011-02-09 16:29:37 +0100772 }
Blue Swirl296af7c2010-03-29 19:23:50 +0000773
Jan Kiszka5db5bda2011-02-01 22:15:54 +0100774 qemu_kvm_eat_signals(env);
Blue Swirl296af7c2010-03-29 19:23:50 +0000775 qemu_wait_io_event_common(env);
776}
777
Jan Kiszka7e97cd82011-02-07 12:19:12 +0100778static void *qemu_kvm_cpu_thread_fn(void *arg)
Blue Swirl296af7c2010-03-29 19:23:50 +0000779{
780 CPUState *env = arg;
Jan Kiszka84b49152011-02-01 22:15:50 +0100781 int r;
Blue Swirl296af7c2010-03-29 19:23:50 +0000782
Marcelo Tosatti6164e6d2010-03-23 13:37:13 -0300783 qemu_mutex_lock(&qemu_global_mutex);
Jan Kiszkab7680cb2011-03-12 17:43:51 +0100784 qemu_thread_get_self(env->thread);
Jan Kiszkadc7a09c2011-03-15 12:26:31 +0100785 env->thread_id = qemu_get_thread_id();
Blue Swirl296af7c2010-03-29 19:23:50 +0000786
Jan Kiszka84b49152011-02-01 22:15:50 +0100787 r = kvm_init_vcpu(env);
788 if (r < 0) {
789 fprintf(stderr, "kvm_init_vcpu failed: %s\n", strerror(-r));
790 exit(1);
791 }
Blue Swirl296af7c2010-03-29 19:23:50 +0000792
Jan Kiszka55f8d6a2011-02-01 22:15:52 +0100793 qemu_kvm_init_cpu_signals(env);
Blue Swirl296af7c2010-03-29 19:23:50 +0000794
795 /* signal CPU creation */
Blue Swirl296af7c2010-03-29 19:23:50 +0000796 env->created = 1;
797 qemu_cond_signal(&qemu_cpu_cond);
798
799 /* and wait for machine initialization */
Jan Kiszka0ab07c62011-02-07 12:19:14 +0100800 while (!qemu_system_ready) {
Paolo Bonzinie0098942011-03-12 17:44:01 +0100801 qemu_cond_wait(&qemu_system_cond, &qemu_global_mutex);
Jan Kiszka0ab07c62011-02-07 12:19:14 +0100802 }
Blue Swirl296af7c2010-03-29 19:23:50 +0000803
804 while (1) {
Jan Kiszka0ab07c62011-02-07 12:19:14 +0100805 if (cpu_can_run(env)) {
Jan Kiszka6792a572011-02-07 12:19:18 +0100806 r = kvm_cpu_exec(env);
Jan Kiszka83f338f2011-02-07 12:19:17 +0100807 if (r == EXCP_DEBUG) {
Jan Kiszka1009d2e2011-03-15 12:26:13 +0100808 cpu_handle_guest_debug(env);
Jan Kiszka83f338f2011-02-07 12:19:17 +0100809 }
Jan Kiszka0ab07c62011-02-07 12:19:14 +0100810 }
Blue Swirl296af7c2010-03-29 19:23:50 +0000811 qemu_kvm_wait_io_event(env);
812 }
813
814 return NULL;
815}
816
Jan Kiszka7e97cd82011-02-07 12:19:12 +0100817static void *qemu_tcg_cpu_thread_fn(void *arg)
Blue Swirl296af7c2010-03-29 19:23:50 +0000818{
819 CPUState *env = arg;
820
Jan Kiszka55f8d6a2011-02-01 22:15:52 +0100821 qemu_tcg_init_cpu_signals();
Jan Kiszkab7680cb2011-03-12 17:43:51 +0100822 qemu_thread_get_self(env->thread);
Blue Swirl296af7c2010-03-29 19:23:50 +0000823
824 /* signal CPU creation */
825 qemu_mutex_lock(&qemu_global_mutex);
Jan Kiszka0ab07c62011-02-07 12:19:14 +0100826 for (env = first_cpu; env != NULL; env = env->next_cpu) {
Jan Kiszkadc7a09c2011-03-15 12:26:31 +0100827 env->thread_id = qemu_get_thread_id();
Blue Swirl296af7c2010-03-29 19:23:50 +0000828 env->created = 1;
Jan Kiszka0ab07c62011-02-07 12:19:14 +0100829 }
Blue Swirl296af7c2010-03-29 19:23:50 +0000830 qemu_cond_signal(&qemu_cpu_cond);
831
832 /* and wait for machine initialization */
Jan Kiszka0ab07c62011-02-07 12:19:14 +0100833 while (!qemu_system_ready) {
Paolo Bonzinie0098942011-03-12 17:44:01 +0100834 qemu_cond_wait(&qemu_system_cond, &qemu_global_mutex);
Jan Kiszka0ab07c62011-02-07 12:19:14 +0100835 }
Blue Swirl296af7c2010-03-29 19:23:50 +0000836
837 while (1) {
Jan Kiszka472fb0c2010-06-25 16:56:55 +0200838 cpu_exec_all();
Paolo Bonzinicb842c92011-04-13 10:03:46 +0200839 if (use_icount && qemu_next_icount_deadline() <= 0) {
Paolo Bonzini3b2319a2011-04-13 10:03:43 +0200840 qemu_notify_event();
841 }
Jan Kiszka6cabe1f2010-06-25 16:56:53 +0200842 qemu_tcg_wait_io_event();
Blue Swirl296af7c2010-03-29 19:23:50 +0000843 }
844
845 return NULL;
846}
847
Paolo Bonzinicc015e92011-03-12 17:44:08 +0100848static void qemu_cpu_kick_thread(CPUState *env)
849{
850#ifndef _WIN32
851 int err;
852
853 err = pthread_kill(env->thread->thread, SIG_IPI);
854 if (err) {
855 fprintf(stderr, "qemu:%s: %s", __func__, strerror(err));
856 exit(1);
857 }
858#else /* _WIN32 */
859 if (!qemu_cpu_is_self(env)) {
860 SuspendThread(env->thread->thread);
861 cpu_signal(0);
862 ResumeThread(env->thread->thread);
863 }
864#endif
865}
866
Blue Swirl296af7c2010-03-29 19:23:50 +0000867void qemu_cpu_kick(void *_env)
868{
869 CPUState *env = _env;
Jan Kiszka0ab07c62011-02-07 12:19:14 +0100870
Blue Swirl296af7c2010-03-29 19:23:50 +0000871 qemu_cond_broadcast(env->halt_cond);
Jan Kiszkaaa2c3642011-02-01 22:15:42 +0100872 if (!env->thread_kicked) {
Paolo Bonzinicc015e92011-03-12 17:44:08 +0100873 qemu_cpu_kick_thread(env);
Jan Kiszkaaa2c3642011-02-01 22:15:42 +0100874 env->thread_kicked = true;
875 }
Blue Swirl296af7c2010-03-29 19:23:50 +0000876}
877
Jan Kiszka46d62fa2011-02-01 22:15:59 +0100878void qemu_cpu_kick_self(void)
879{
Paolo Bonzinib55c22c2011-03-12 17:44:07 +0100880#ifndef _WIN32
Jan Kiszka46d62fa2011-02-01 22:15:59 +0100881 assert(cpu_single_env);
882
883 if (!cpu_single_env->thread_kicked) {
Paolo Bonzinicc015e92011-03-12 17:44:08 +0100884 qemu_cpu_kick_thread(cpu_single_env);
Jan Kiszka46d62fa2011-02-01 22:15:59 +0100885 cpu_single_env->thread_kicked = true;
886 }
Paolo Bonzinib55c22c2011-03-12 17:44:07 +0100887#else
888 abort();
889#endif
Blue Swirl296af7c2010-03-29 19:23:50 +0000890}
891
Jan Kiszkab7680cb2011-03-12 17:43:51 +0100892int qemu_cpu_is_self(void *_env)
Blue Swirl296af7c2010-03-29 19:23:50 +0000893{
894 CPUState *env = _env;
Blue Swirl296af7c2010-03-29 19:23:50 +0000895
Jan Kiszkab7680cb2011-03-12 17:43:51 +0100896 return qemu_thread_is_self(env->thread);
Blue Swirl296af7c2010-03-29 19:23:50 +0000897}
898
Blue Swirl296af7c2010-03-29 19:23:50 +0000899void qemu_mutex_lock_iothread(void)
900{
901 if (kvm_enabled()) {
Blue Swirl296af7c2010-03-29 19:23:50 +0000902 qemu_mutex_lock(&qemu_global_mutex);
Marcelo Tosatti1a28cac2010-05-04 09:45:20 -0300903 } else {
904 qemu_mutex_lock(&qemu_fair_mutex);
905 if (qemu_mutex_trylock(&qemu_global_mutex)) {
Paolo Bonzinicc015e92011-03-12 17:44:08 +0100906 qemu_cpu_kick_thread(first_cpu);
Marcelo Tosatti1a28cac2010-05-04 09:45:20 -0300907 qemu_mutex_lock(&qemu_global_mutex);
908 }
909 qemu_mutex_unlock(&qemu_fair_mutex);
910 }
Blue Swirl296af7c2010-03-29 19:23:50 +0000911}
912
913void qemu_mutex_unlock_iothread(void)
914{
915 qemu_mutex_unlock(&qemu_global_mutex);
916}
917
918static int all_vcpus_paused(void)
919{
920 CPUState *penv = first_cpu;
921
922 while (penv) {
Jan Kiszka0ab07c62011-02-07 12:19:14 +0100923 if (!penv->stopped) {
Blue Swirl296af7c2010-03-29 19:23:50 +0000924 return 0;
Jan Kiszka0ab07c62011-02-07 12:19:14 +0100925 }
Blue Swirl296af7c2010-03-29 19:23:50 +0000926 penv = (CPUState *)penv->next_cpu;
927 }
928
929 return 1;
930}
931
932void pause_all_vcpus(void)
933{
934 CPUState *penv = first_cpu;
935
936 while (penv) {
937 penv->stop = 1;
Blue Swirl296af7c2010-03-29 19:23:50 +0000938 qemu_cpu_kick(penv);
939 penv = (CPUState *)penv->next_cpu;
940 }
941
942 while (!all_vcpus_paused()) {
Paolo Bonzinibe7d6c52011-03-12 17:44:02 +0100943 qemu_cond_wait(&qemu_pause_cond, &qemu_global_mutex);
Blue Swirl296af7c2010-03-29 19:23:50 +0000944 penv = first_cpu;
945 while (penv) {
Marcelo Tosatti1fbb22e2010-05-04 09:45:21 -0300946 qemu_cpu_kick(penv);
Blue Swirl296af7c2010-03-29 19:23:50 +0000947 penv = (CPUState *)penv->next_cpu;
948 }
949 }
950}
951
952void resume_all_vcpus(void)
953{
954 CPUState *penv = first_cpu;
955
956 while (penv) {
957 penv->stop = 0;
958 penv->stopped = 0;
Blue Swirl296af7c2010-03-29 19:23:50 +0000959 qemu_cpu_kick(penv);
960 penv = (CPUState *)penv->next_cpu;
961 }
962}
963
Jan Kiszka7e97cd82011-02-07 12:19:12 +0100964static void qemu_tcg_init_vcpu(void *_env)
Blue Swirl296af7c2010-03-29 19:23:50 +0000965{
966 CPUState *env = _env;
Jan Kiszka0ab07c62011-02-07 12:19:14 +0100967
Blue Swirl296af7c2010-03-29 19:23:50 +0000968 /* share a single thread for all cpus with TCG */
969 if (!tcg_cpu_thread) {
970 env->thread = qemu_mallocz(sizeof(QemuThread));
971 env->halt_cond = qemu_mallocz(sizeof(QemuCond));
972 qemu_cond_init(env->halt_cond);
Jan Kiszka7e97cd82011-02-07 12:19:12 +0100973 qemu_thread_create(env->thread, qemu_tcg_cpu_thread_fn, env);
Jan Kiszka0ab07c62011-02-07 12:19:14 +0100974 while (env->created == 0) {
Paolo Bonzini18a85722011-03-12 17:44:03 +0100975 qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex);
Jan Kiszka0ab07c62011-02-07 12:19:14 +0100976 }
Blue Swirl296af7c2010-03-29 19:23:50 +0000977 tcg_cpu_thread = env->thread;
978 tcg_halt_cond = env->halt_cond;
979 } else {
980 env->thread = tcg_cpu_thread;
981 env->halt_cond = tcg_halt_cond;
982 }
983}
984
Jan Kiszka7e97cd82011-02-07 12:19:12 +0100985static void qemu_kvm_start_vcpu(CPUState *env)
Blue Swirl296af7c2010-03-29 19:23:50 +0000986{
987 env->thread = qemu_mallocz(sizeof(QemuThread));
988 env->halt_cond = qemu_mallocz(sizeof(QemuCond));
989 qemu_cond_init(env->halt_cond);
Jan Kiszka7e97cd82011-02-07 12:19:12 +0100990 qemu_thread_create(env->thread, qemu_kvm_cpu_thread_fn, env);
Jan Kiszka0ab07c62011-02-07 12:19:14 +0100991 while (env->created == 0) {
Paolo Bonzini18a85722011-03-12 17:44:03 +0100992 qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex);
Jan Kiszka0ab07c62011-02-07 12:19:14 +0100993 }
Blue Swirl296af7c2010-03-29 19:23:50 +0000994}
995
996void qemu_init_vcpu(void *_env)
997{
998 CPUState *env = _env;
999
1000 env->nr_cores = smp_cores;
1001 env->nr_threads = smp_threads;
Jan Kiszka0ab07c62011-02-07 12:19:14 +01001002 if (kvm_enabled()) {
Jan Kiszka7e97cd82011-02-07 12:19:12 +01001003 qemu_kvm_start_vcpu(env);
Jan Kiszka0ab07c62011-02-07 12:19:14 +01001004 } else {
Jan Kiszka7e97cd82011-02-07 12:19:12 +01001005 qemu_tcg_init_vcpu(env);
Jan Kiszka0ab07c62011-02-07 12:19:14 +01001006 }
Blue Swirl296af7c2010-03-29 19:23:50 +00001007}
1008
1009void qemu_notify_event(void)
1010{
1011 qemu_event_increment();
1012}
1013
Jan Kiszkab4a3d962011-02-01 22:15:43 +01001014void cpu_stop_current(void)
Blue Swirl296af7c2010-03-29 19:23:50 +00001015{
Jan Kiszkab4a3d962011-02-01 22:15:43 +01001016 if (cpu_single_env) {
Paolo Bonzini67bb1722011-03-12 17:43:59 +01001017 cpu_single_env->stop = 0;
Jan Kiszkab4a3d962011-02-01 22:15:43 +01001018 cpu_single_env->stopped = 1;
1019 cpu_exit(cpu_single_env);
Paolo Bonzini67bb1722011-03-12 17:43:59 +01001020 qemu_cond_signal(&qemu_pause_cond);
Jan Kiszkab4a3d962011-02-01 22:15:43 +01001021 }
Blue Swirl296af7c2010-03-29 19:23:50 +00001022}
1023
1024void vm_stop(int reason)
1025{
Jan Kiszkab7680cb2011-03-12 17:43:51 +01001026 if (!qemu_thread_is_self(&io_thread)) {
Blue Swirl296af7c2010-03-29 19:23:50 +00001027 qemu_system_vmstop_request(reason);
1028 /*
1029 * FIXME: should not return to device code in case
1030 * vm_stop() has been requested.
1031 */
Jan Kiszkab4a3d962011-02-01 22:15:43 +01001032 cpu_stop_current();
Blue Swirl296af7c2010-03-29 19:23:50 +00001033 return;
1034 }
1035 do_vm_stop(reason);
1036}
1037
1038#endif
1039
Jan Kiszka6792a572011-02-07 12:19:18 +01001040static int tcg_cpu_exec(CPUState *env)
Blue Swirl296af7c2010-03-29 19:23:50 +00001041{
1042 int ret;
1043#ifdef CONFIG_PROFILER
1044 int64_t ti;
1045#endif
1046
1047#ifdef CONFIG_PROFILER
1048 ti = profile_getclock();
1049#endif
1050 if (use_icount) {
1051 int64_t count;
1052 int decr;
1053 qemu_icount -= (env->icount_decr.u16.low + env->icount_extra);
1054 env->icount_decr.u16.low = 0;
1055 env->icount_extra = 0;
Paolo Bonzinicb842c92011-04-13 10:03:46 +02001056 count = qemu_icount_round(qemu_next_icount_deadline());
Blue Swirl296af7c2010-03-29 19:23:50 +00001057 qemu_icount += count;
1058 decr = (count > 0xffff) ? 0xffff : count;
1059 count -= decr;
1060 env->icount_decr.u16.low = decr;
1061 env->icount_extra = count;
1062 }
1063 ret = cpu_exec(env);
1064#ifdef CONFIG_PROFILER
1065 qemu_time += profile_getclock() - ti;
1066#endif
1067 if (use_icount) {
1068 /* Fold pending instructions back into the
1069 instruction counter, and clear the interrupt flag. */
1070 qemu_icount -= (env->icount_decr.u16.low
1071 + env->icount_extra);
1072 env->icount_decr.u32 = 0;
1073 env->icount_extra = 0;
1074 }
1075 return ret;
1076}
1077
Jan Kiszka472fb0c2010-06-25 16:56:55 +02001078bool cpu_exec_all(void)
Blue Swirl296af7c2010-03-29 19:23:50 +00001079{
Jan Kiszka9a360852011-02-01 22:15:55 +01001080 int r;
1081
Paolo Bonziniab33fcd2011-04-13 10:03:44 +02001082 /* Account partial waits to the vm_clock. */
1083 qemu_clock_warp(vm_clock);
1084
Jan Kiszka0ab07c62011-02-07 12:19:14 +01001085 if (next_cpu == NULL) {
Blue Swirl296af7c2010-03-29 19:23:50 +00001086 next_cpu = first_cpu;
Jan Kiszka0ab07c62011-02-07 12:19:14 +01001087 }
Jan Kiszkac629a4b2010-06-25 16:56:52 +02001088 for (; next_cpu != NULL && !exit_request; next_cpu = next_cpu->next_cpu) {
Jan Kiszka345f4422010-06-25 16:56:54 +02001089 CPUState *env = next_cpu;
Blue Swirl296af7c2010-03-29 19:23:50 +00001090
1091 qemu_clock_enable(vm_clock,
Jan Kiszka345f4422010-06-25 16:56:54 +02001092 (env->singlestep_enabled & SSTEP_NOTIMER) == 0);
Blue Swirl296af7c2010-03-29 19:23:50 +00001093
Paolo Bonzini8cf3f222011-03-12 17:44:04 +01001094#ifndef CONFIG_IOTHREAD
Jan Kiszka0ab07c62011-02-07 12:19:14 +01001095 if (qemu_alarm_pending()) {
Blue Swirl296af7c2010-03-29 19:23:50 +00001096 break;
Jan Kiszka0ab07c62011-02-07 12:19:14 +01001097 }
Paolo Bonzini8cf3f222011-03-12 17:44:04 +01001098#endif
Jan Kiszka3c638d02010-06-25 16:56:56 +02001099 if (cpu_can_run(env)) {
Jan Kiszka9a360852011-02-01 22:15:55 +01001100 if (kvm_enabled()) {
Jan Kiszka6792a572011-02-07 12:19:18 +01001101 r = kvm_cpu_exec(env);
Jan Kiszka9a360852011-02-01 22:15:55 +01001102 qemu_kvm_eat_signals(env);
Jan Kiszka6792a572011-02-07 12:19:18 +01001103 } else {
1104 r = tcg_cpu_exec(env);
Jan Kiszka9a360852011-02-01 22:15:55 +01001105 }
1106 if (r == EXCP_DEBUG) {
Jan Kiszka1009d2e2011-03-15 12:26:13 +01001107 cpu_handle_guest_debug(env);
Jan Kiszka3c638d02010-06-25 16:56:56 +02001108 break;
1109 }
Paolo Bonzinidf646df2011-03-12 17:43:58 +01001110 } else if (env->stop || env->stopped) {
Blue Swirl296af7c2010-03-29 19:23:50 +00001111 break;
1112 }
1113 }
Jan Kiszkac629a4b2010-06-25 16:56:52 +02001114 exit_request = 0;
Jan Kiszka16400322011-02-09 16:29:37 +01001115 return !all_cpu_threads_idle();
Blue Swirl296af7c2010-03-29 19:23:50 +00001116}
1117
1118void set_numa_modes(void)
1119{
1120 CPUState *env;
1121 int i;
1122
1123 for (env = first_cpu; env != NULL; env = env->next_cpu) {
1124 for (i = 0; i < nb_numa_nodes; i++) {
1125 if (node_cpumask[i] & (1 << env->cpu_index)) {
1126 env->numa_node = i;
1127 }
1128 }
1129 }
1130}
1131
1132void set_cpu_log(const char *optarg)
1133{
1134 int mask;
1135 const CPULogItem *item;
1136
1137 mask = cpu_str_to_log_mask(optarg);
1138 if (!mask) {
1139 printf("Log items (comma separated):\n");
1140 for (item = cpu_log_items; item->mask != 0; item++) {
1141 printf("%-10s %s\n", item->name, item->help);
1142 }
1143 exit(1);
1144 }
1145 cpu_set_log(mask);
1146}
Blue Swirl29e922b2010-03-29 19:24:00 +00001147
Matthew Fernandezc235d732011-06-07 16:32:40 +00001148void set_cpu_log_filename(const char *optarg)
1149{
1150 cpu_set_log_filename(optarg);
1151}
1152
Blue Swirl29e922b2010-03-29 19:24:00 +00001153/* Return the virtual CPU time, based on the instruction counter. */
1154int64_t cpu_get_icount(void)
1155{
1156 int64_t icount;
1157 CPUState *env = cpu_single_env;;
1158
1159 icount = qemu_icount;
1160 if (env) {
1161 if (!can_do_io(env)) {
1162 fprintf(stderr, "Bad clock read\n");
1163 }
1164 icount -= (env->icount_decr.u16.low + env->icount_extra);
1165 }
1166 return qemu_icount_bias + (icount << icount_time_shift);
1167}
Blue Swirl262353c2010-05-04 19:55:35 +00001168
Stefan Weil9a78eea2010-10-22 23:03:33 +02001169void list_cpus(FILE *f, fprintf_function cpu_fprintf, const char *optarg)
Blue Swirl262353c2010-05-04 19:55:35 +00001170{
1171 /* XXX: implement xxx_cpu_list for targets that still miss it */
1172#if defined(cpu_list_id)
1173 cpu_list_id(f, cpu_fprintf, optarg);
1174#elif defined(cpu_list)
1175 cpu_list(f, cpu_fprintf); /* deprecated */
1176#endif
1177}