xref: /openbmc/qemu/system/cpus.c (revision 78dfb7b0d325ed9433b2adbb77ffd075a8b6b89a)
18d7f2e76SPhilippe Mathieu-Daudé /*
28d7f2e76SPhilippe Mathieu-Daudé  * QEMU System Emulator
38d7f2e76SPhilippe Mathieu-Daudé  *
48d7f2e76SPhilippe Mathieu-Daudé  * Copyright (c) 2003-2008 Fabrice Bellard
58d7f2e76SPhilippe Mathieu-Daudé  *
68d7f2e76SPhilippe Mathieu-Daudé  * Permission is hereby granted, free of charge, to any person obtaining a copy
78d7f2e76SPhilippe Mathieu-Daudé  * of this software and associated documentation files (the "Software"), to deal
88d7f2e76SPhilippe Mathieu-Daudé  * in the Software without restriction, including without limitation the rights
98d7f2e76SPhilippe Mathieu-Daudé  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
108d7f2e76SPhilippe Mathieu-Daudé  * copies of the Software, and to permit persons to whom the Software is
118d7f2e76SPhilippe Mathieu-Daudé  * furnished to do so, subject to the following conditions:
128d7f2e76SPhilippe Mathieu-Daudé  *
138d7f2e76SPhilippe Mathieu-Daudé  * The above copyright notice and this permission notice shall be included in
148d7f2e76SPhilippe Mathieu-Daudé  * all copies or substantial portions of the Software.
158d7f2e76SPhilippe Mathieu-Daudé  *
168d7f2e76SPhilippe Mathieu-Daudé  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
178d7f2e76SPhilippe Mathieu-Daudé  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
188d7f2e76SPhilippe Mathieu-Daudé  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
198d7f2e76SPhilippe Mathieu-Daudé  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
208d7f2e76SPhilippe Mathieu-Daudé  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
218d7f2e76SPhilippe Mathieu-Daudé  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
228d7f2e76SPhilippe Mathieu-Daudé  * THE SOFTWARE.
238d7f2e76SPhilippe Mathieu-Daudé  */
248d7f2e76SPhilippe Mathieu-Daudé 
258d7f2e76SPhilippe Mathieu-Daudé #include "qemu/osdep.h"
268d7f2e76SPhilippe Mathieu-Daudé #include "monitor/monitor.h"
278d7f2e76SPhilippe Mathieu-Daudé #include "qemu/coroutine-tls.h"
288d7f2e76SPhilippe Mathieu-Daudé #include "qapi/error.h"
298d7f2e76SPhilippe Mathieu-Daudé #include "qapi/qapi-commands-machine.h"
308d7f2e76SPhilippe Mathieu-Daudé #include "qapi/qapi-commands-misc.h"
318d7f2e76SPhilippe Mathieu-Daudé #include "qapi/qapi-events-run-state.h"
328d7f2e76SPhilippe Mathieu-Daudé #include "qapi/qmp/qerror.h"
338d7f2e76SPhilippe Mathieu-Daudé #include "exec/gdbstub.h"
348d7f2e76SPhilippe Mathieu-Daudé #include "sysemu/hw_accel.h"
358d7f2e76SPhilippe Mathieu-Daudé #include "exec/cpu-common.h"
368d7f2e76SPhilippe Mathieu-Daudé #include "qemu/thread.h"
378d7f2e76SPhilippe Mathieu-Daudé #include "qemu/main-loop.h"
388d7f2e76SPhilippe Mathieu-Daudé #include "qemu/plugin.h"
398d7f2e76SPhilippe Mathieu-Daudé #include "sysemu/cpus.h"
408d7f2e76SPhilippe Mathieu-Daudé #include "qemu/guest-random.h"
418d7f2e76SPhilippe Mathieu-Daudé #include "hw/nmi.h"
428d7f2e76SPhilippe Mathieu-Daudé #include "sysemu/replay.h"
438d7f2e76SPhilippe Mathieu-Daudé #include "sysemu/runstate.h"
448d7f2e76SPhilippe Mathieu-Daudé #include "sysemu/cpu-timers.h"
458d7f2e76SPhilippe Mathieu-Daudé #include "sysemu/whpx.h"
468d7f2e76SPhilippe Mathieu-Daudé #include "hw/boards.h"
478d7f2e76SPhilippe Mathieu-Daudé #include "hw/hw.h"
488d7f2e76SPhilippe Mathieu-Daudé #include "trace.h"
498d7f2e76SPhilippe Mathieu-Daudé 
508d7f2e76SPhilippe Mathieu-Daudé #ifdef CONFIG_LINUX
518d7f2e76SPhilippe Mathieu-Daudé 
528d7f2e76SPhilippe Mathieu-Daudé #include <sys/prctl.h>
538d7f2e76SPhilippe Mathieu-Daudé 
548d7f2e76SPhilippe Mathieu-Daudé #ifndef PR_MCE_KILL
558d7f2e76SPhilippe Mathieu-Daudé #define PR_MCE_KILL 33
568d7f2e76SPhilippe Mathieu-Daudé #endif
578d7f2e76SPhilippe Mathieu-Daudé 
588d7f2e76SPhilippe Mathieu-Daudé #ifndef PR_MCE_KILL_SET
598d7f2e76SPhilippe Mathieu-Daudé #define PR_MCE_KILL_SET 1
608d7f2e76SPhilippe Mathieu-Daudé #endif
618d7f2e76SPhilippe Mathieu-Daudé 
628d7f2e76SPhilippe Mathieu-Daudé #ifndef PR_MCE_KILL_EARLY
638d7f2e76SPhilippe Mathieu-Daudé #define PR_MCE_KILL_EARLY 1
648d7f2e76SPhilippe Mathieu-Daudé #endif
658d7f2e76SPhilippe Mathieu-Daudé 
668d7f2e76SPhilippe Mathieu-Daudé #endif /* CONFIG_LINUX */
678d7f2e76SPhilippe Mathieu-Daudé 
68195801d7SStefan Hajnoczi /* The Big QEMU Lock (BQL) */
69195801d7SStefan Hajnoczi static QemuMutex bql;
708d7f2e76SPhilippe Mathieu-Daudé 
718d7f2e76SPhilippe Mathieu-Daudé /*
728d7f2e76SPhilippe Mathieu-Daudé  * The chosen accelerator is supposed to register this.
738d7f2e76SPhilippe Mathieu-Daudé  */
748d7f2e76SPhilippe Mathieu-Daudé static const AccelOpsClass *cpus_accel;
758d7f2e76SPhilippe Mathieu-Daudé 
cpu_is_stopped(CPUState * cpu)768d7f2e76SPhilippe Mathieu-Daudé bool cpu_is_stopped(CPUState *cpu)
778d7f2e76SPhilippe Mathieu-Daudé {
788d7f2e76SPhilippe Mathieu-Daudé     return cpu->stopped || !runstate_is_running();
798d7f2e76SPhilippe Mathieu-Daudé }
808d7f2e76SPhilippe Mathieu-Daudé 
cpu_work_list_empty(CPUState * cpu)818d7f2e76SPhilippe Mathieu-Daudé bool cpu_work_list_empty(CPUState *cpu)
828d7f2e76SPhilippe Mathieu-Daudé {
838d7f2e76SPhilippe Mathieu-Daudé     return QSIMPLEQ_EMPTY_ATOMIC(&cpu->work_list);
848d7f2e76SPhilippe Mathieu-Daudé }
858d7f2e76SPhilippe Mathieu-Daudé 
cpu_thread_is_idle(CPUState * cpu)868d7f2e76SPhilippe Mathieu-Daudé bool cpu_thread_is_idle(CPUState *cpu)
878d7f2e76SPhilippe Mathieu-Daudé {
888d7f2e76SPhilippe Mathieu-Daudé     if (cpu->stop || !cpu_work_list_empty(cpu)) {
898d7f2e76SPhilippe Mathieu-Daudé         return false;
908d7f2e76SPhilippe Mathieu-Daudé     }
918d7f2e76SPhilippe Mathieu-Daudé     if (cpu_is_stopped(cpu)) {
928d7f2e76SPhilippe Mathieu-Daudé         return true;
938d7f2e76SPhilippe Mathieu-Daudé     }
948d7f2e76SPhilippe Mathieu-Daudé     if (!cpu->halted || cpu_has_work(cpu)) {
958d7f2e76SPhilippe Mathieu-Daudé         return false;
968d7f2e76SPhilippe Mathieu-Daudé     }
978d7f2e76SPhilippe Mathieu-Daudé     if (cpus_accel->cpu_thread_is_idle) {
988d7f2e76SPhilippe Mathieu-Daudé         return cpus_accel->cpu_thread_is_idle(cpu);
998d7f2e76SPhilippe Mathieu-Daudé     }
1008d7f2e76SPhilippe Mathieu-Daudé     return true;
1018d7f2e76SPhilippe Mathieu-Daudé }
1028d7f2e76SPhilippe Mathieu-Daudé 
all_cpu_threads_idle(void)1038d7f2e76SPhilippe Mathieu-Daudé bool all_cpu_threads_idle(void)
1048d7f2e76SPhilippe Mathieu-Daudé {
1058d7f2e76SPhilippe Mathieu-Daudé     CPUState *cpu;
1068d7f2e76SPhilippe Mathieu-Daudé 
1078d7f2e76SPhilippe Mathieu-Daudé     CPU_FOREACH(cpu) {
1088d7f2e76SPhilippe Mathieu-Daudé         if (!cpu_thread_is_idle(cpu)) {
1098d7f2e76SPhilippe Mathieu-Daudé             return false;
1108d7f2e76SPhilippe Mathieu-Daudé         }
1118d7f2e76SPhilippe Mathieu-Daudé     }
1128d7f2e76SPhilippe Mathieu-Daudé     return true;
1138d7f2e76SPhilippe Mathieu-Daudé }
1148d7f2e76SPhilippe Mathieu-Daudé 
1158d7f2e76SPhilippe Mathieu-Daudé /***********************************************************/
hw_error(const char * fmt,...)1168d7f2e76SPhilippe Mathieu-Daudé void hw_error(const char *fmt, ...)
1178d7f2e76SPhilippe Mathieu-Daudé {
1188d7f2e76SPhilippe Mathieu-Daudé     va_list ap;
1198d7f2e76SPhilippe Mathieu-Daudé     CPUState *cpu;
1208d7f2e76SPhilippe Mathieu-Daudé 
1218d7f2e76SPhilippe Mathieu-Daudé     va_start(ap, fmt);
1228d7f2e76SPhilippe Mathieu-Daudé     fprintf(stderr, "qemu: hardware error: ");
1238d7f2e76SPhilippe Mathieu-Daudé     vfprintf(stderr, fmt, ap);
1248d7f2e76SPhilippe Mathieu-Daudé     fprintf(stderr, "\n");
1258d7f2e76SPhilippe Mathieu-Daudé     CPU_FOREACH(cpu) {
1268d7f2e76SPhilippe Mathieu-Daudé         fprintf(stderr, "CPU #%d:\n", cpu->cpu_index);
1278d7f2e76SPhilippe Mathieu-Daudé         cpu_dump_state(cpu, stderr, CPU_DUMP_FPU);
1288d7f2e76SPhilippe Mathieu-Daudé     }
1298d7f2e76SPhilippe Mathieu-Daudé     va_end(ap);
1308d7f2e76SPhilippe Mathieu-Daudé     abort();
1318d7f2e76SPhilippe Mathieu-Daudé }
1328d7f2e76SPhilippe Mathieu-Daudé 
cpu_synchronize_all_states(void)1338d7f2e76SPhilippe Mathieu-Daudé void cpu_synchronize_all_states(void)
1348d7f2e76SPhilippe Mathieu-Daudé {
1358d7f2e76SPhilippe Mathieu-Daudé     CPUState *cpu;
1368d7f2e76SPhilippe Mathieu-Daudé 
1378d7f2e76SPhilippe Mathieu-Daudé     CPU_FOREACH(cpu) {
1388d7f2e76SPhilippe Mathieu-Daudé         cpu_synchronize_state(cpu);
1398d7f2e76SPhilippe Mathieu-Daudé     }
1408d7f2e76SPhilippe Mathieu-Daudé }
1418d7f2e76SPhilippe Mathieu-Daudé 
cpu_synchronize_all_post_reset(void)1428d7f2e76SPhilippe Mathieu-Daudé void cpu_synchronize_all_post_reset(void)
1438d7f2e76SPhilippe Mathieu-Daudé {
1448d7f2e76SPhilippe Mathieu-Daudé     CPUState *cpu;
1458d7f2e76SPhilippe Mathieu-Daudé 
1468d7f2e76SPhilippe Mathieu-Daudé     CPU_FOREACH(cpu) {
1478d7f2e76SPhilippe Mathieu-Daudé         cpu_synchronize_post_reset(cpu);
1488d7f2e76SPhilippe Mathieu-Daudé     }
1498d7f2e76SPhilippe Mathieu-Daudé }
1508d7f2e76SPhilippe Mathieu-Daudé 
cpu_synchronize_all_post_init(void)1518d7f2e76SPhilippe Mathieu-Daudé void cpu_synchronize_all_post_init(void)
1528d7f2e76SPhilippe Mathieu-Daudé {
1538d7f2e76SPhilippe Mathieu-Daudé     CPUState *cpu;
1548d7f2e76SPhilippe Mathieu-Daudé 
1558d7f2e76SPhilippe Mathieu-Daudé     CPU_FOREACH(cpu) {
1568d7f2e76SPhilippe Mathieu-Daudé         cpu_synchronize_post_init(cpu);
1578d7f2e76SPhilippe Mathieu-Daudé     }
1588d7f2e76SPhilippe Mathieu-Daudé }
1598d7f2e76SPhilippe Mathieu-Daudé 
cpu_synchronize_all_pre_loadvm(void)1608d7f2e76SPhilippe Mathieu-Daudé void cpu_synchronize_all_pre_loadvm(void)
1618d7f2e76SPhilippe Mathieu-Daudé {
1628d7f2e76SPhilippe Mathieu-Daudé     CPUState *cpu;
1638d7f2e76SPhilippe Mathieu-Daudé 
1648d7f2e76SPhilippe Mathieu-Daudé     CPU_FOREACH(cpu) {
1658d7f2e76SPhilippe Mathieu-Daudé         cpu_synchronize_pre_loadvm(cpu);
1668d7f2e76SPhilippe Mathieu-Daudé     }
1678d7f2e76SPhilippe Mathieu-Daudé }
1688d7f2e76SPhilippe Mathieu-Daudé 
cpu_synchronize_state(CPUState * cpu)1698d7f2e76SPhilippe Mathieu-Daudé void cpu_synchronize_state(CPUState *cpu)
1708d7f2e76SPhilippe Mathieu-Daudé {
1718d7f2e76SPhilippe Mathieu-Daudé     if (cpus_accel->synchronize_state) {
1728d7f2e76SPhilippe Mathieu-Daudé         cpus_accel->synchronize_state(cpu);
1738d7f2e76SPhilippe Mathieu-Daudé     }
1748d7f2e76SPhilippe Mathieu-Daudé }
1758d7f2e76SPhilippe Mathieu-Daudé 
cpu_synchronize_post_reset(CPUState * cpu)1768d7f2e76SPhilippe Mathieu-Daudé void cpu_synchronize_post_reset(CPUState *cpu)
1778d7f2e76SPhilippe Mathieu-Daudé {
1788d7f2e76SPhilippe Mathieu-Daudé     if (cpus_accel->synchronize_post_reset) {
1798d7f2e76SPhilippe Mathieu-Daudé         cpus_accel->synchronize_post_reset(cpu);
1808d7f2e76SPhilippe Mathieu-Daudé     }
1818d7f2e76SPhilippe Mathieu-Daudé }
1828d7f2e76SPhilippe Mathieu-Daudé 
cpu_synchronize_post_init(CPUState * cpu)1838d7f2e76SPhilippe Mathieu-Daudé void cpu_synchronize_post_init(CPUState *cpu)
1848d7f2e76SPhilippe Mathieu-Daudé {
1858d7f2e76SPhilippe Mathieu-Daudé     if (cpus_accel->synchronize_post_init) {
1868d7f2e76SPhilippe Mathieu-Daudé         cpus_accel->synchronize_post_init(cpu);
1878d7f2e76SPhilippe Mathieu-Daudé     }
1888d7f2e76SPhilippe Mathieu-Daudé }
1898d7f2e76SPhilippe Mathieu-Daudé 
cpu_synchronize_pre_loadvm(CPUState * cpu)1908d7f2e76SPhilippe Mathieu-Daudé void cpu_synchronize_pre_loadvm(CPUState *cpu)
1918d7f2e76SPhilippe Mathieu-Daudé {
1928d7f2e76SPhilippe Mathieu-Daudé     if (cpus_accel->synchronize_pre_loadvm) {
1938d7f2e76SPhilippe Mathieu-Daudé         cpus_accel->synchronize_pre_loadvm(cpu);
1948d7f2e76SPhilippe Mathieu-Daudé     }
1958d7f2e76SPhilippe Mathieu-Daudé }
1968d7f2e76SPhilippe Mathieu-Daudé 
cpus_are_resettable(void)1978d7f2e76SPhilippe Mathieu-Daudé bool cpus_are_resettable(void)
1988d7f2e76SPhilippe Mathieu-Daudé {
1998d7f2e76SPhilippe Mathieu-Daudé     if (cpus_accel->cpus_are_resettable) {
2008d7f2e76SPhilippe Mathieu-Daudé         return cpus_accel->cpus_are_resettable();
2018d7f2e76SPhilippe Mathieu-Daudé     }
2028d7f2e76SPhilippe Mathieu-Daudé     return true;
2038d7f2e76SPhilippe Mathieu-Daudé }
2048d7f2e76SPhilippe Mathieu-Daudé 
cpu_exec_reset_hold(CPUState * cpu)2051b5120d7SPhilippe Mathieu-Daudé void cpu_exec_reset_hold(CPUState *cpu)
2061b5120d7SPhilippe Mathieu-Daudé {
2071b5120d7SPhilippe Mathieu-Daudé     if (cpus_accel->cpu_reset_hold) {
2081b5120d7SPhilippe Mathieu-Daudé         cpus_accel->cpu_reset_hold(cpu);
2091b5120d7SPhilippe Mathieu-Daudé     }
2101b5120d7SPhilippe Mathieu-Daudé }
2111b5120d7SPhilippe Mathieu-Daudé 
cpus_get_virtual_clock(void)2128d7f2e76SPhilippe Mathieu-Daudé int64_t cpus_get_virtual_clock(void)
2138d7f2e76SPhilippe Mathieu-Daudé {
2148d7f2e76SPhilippe Mathieu-Daudé     /*
2158d7f2e76SPhilippe Mathieu-Daudé      * XXX
2168d7f2e76SPhilippe Mathieu-Daudé      *
2178d7f2e76SPhilippe Mathieu-Daudé      * need to check that cpus_accel is not NULL, because qcow2 calls
2188d7f2e76SPhilippe Mathieu-Daudé      * qemu_get_clock_ns(CLOCK_VIRTUAL) without any accel initialized and
2198d7f2e76SPhilippe Mathieu-Daudé      * with ticks disabled in some io-tests:
2208d7f2e76SPhilippe Mathieu-Daudé      * 030 040 041 060 099 120 127 140 156 161 172 181 191 192 195 203 229 249 256 267
2218d7f2e76SPhilippe Mathieu-Daudé      *
2228d7f2e76SPhilippe Mathieu-Daudé      * is this expected?
2238d7f2e76SPhilippe Mathieu-Daudé      *
2248d7f2e76SPhilippe Mathieu-Daudé      * XXX
2258d7f2e76SPhilippe Mathieu-Daudé      */
2268d7f2e76SPhilippe Mathieu-Daudé     if (cpus_accel && cpus_accel->get_virtual_clock) {
2278d7f2e76SPhilippe Mathieu-Daudé         return cpus_accel->get_virtual_clock();
2288d7f2e76SPhilippe Mathieu-Daudé     }
2298d7f2e76SPhilippe Mathieu-Daudé     return cpu_get_clock();
2308d7f2e76SPhilippe Mathieu-Daudé }
2318d7f2e76SPhilippe Mathieu-Daudé 
2328d7f2e76SPhilippe Mathieu-Daudé /*
233113ac1d2SAlex Bennée  * Signal the new virtual time to the accelerator. This is only needed
234113ac1d2SAlex Bennée  * by accelerators that need to track the changes as we warp time.
235113ac1d2SAlex Bennée  */
cpus_set_virtual_clock(int64_t new_time)236113ac1d2SAlex Bennée void cpus_set_virtual_clock(int64_t new_time)
237113ac1d2SAlex Bennée {
238113ac1d2SAlex Bennée     if (cpus_accel && cpus_accel->set_virtual_clock) {
239113ac1d2SAlex Bennée         cpus_accel->set_virtual_clock(new_time);
240113ac1d2SAlex Bennée     }
241113ac1d2SAlex Bennée }
242113ac1d2SAlex Bennée 
243113ac1d2SAlex Bennée /*
2448d7f2e76SPhilippe Mathieu-Daudé  * return the time elapsed in VM between vm_start and vm_stop.  Unless
2458d7f2e76SPhilippe Mathieu-Daudé  * icount is active, cpus_get_elapsed_ticks() uses units of the host CPU cycle
2468d7f2e76SPhilippe Mathieu-Daudé  * counter.
2478d7f2e76SPhilippe Mathieu-Daudé  */
cpus_get_elapsed_ticks(void)2488d7f2e76SPhilippe Mathieu-Daudé int64_t cpus_get_elapsed_ticks(void)
2498d7f2e76SPhilippe Mathieu-Daudé {
2508d7f2e76SPhilippe Mathieu-Daudé     if (cpus_accel->get_elapsed_ticks) {
2518d7f2e76SPhilippe Mathieu-Daudé         return cpus_accel->get_elapsed_ticks();
2528d7f2e76SPhilippe Mathieu-Daudé     }
2538d7f2e76SPhilippe Mathieu-Daudé     return cpu_get_ticks();
2548d7f2e76SPhilippe Mathieu-Daudé }
2558d7f2e76SPhilippe Mathieu-Daudé 
generic_handle_interrupt(CPUState * cpu,int mask)2568d7f2e76SPhilippe Mathieu-Daudé static void generic_handle_interrupt(CPUState *cpu, int mask)
2578d7f2e76SPhilippe Mathieu-Daudé {
2588d7f2e76SPhilippe Mathieu-Daudé     cpu->interrupt_request |= mask;
2598d7f2e76SPhilippe Mathieu-Daudé 
2608d7f2e76SPhilippe Mathieu-Daudé     if (!qemu_cpu_is_self(cpu)) {
2618d7f2e76SPhilippe Mathieu-Daudé         qemu_cpu_kick(cpu);
2628d7f2e76SPhilippe Mathieu-Daudé     }
2638d7f2e76SPhilippe Mathieu-Daudé }
2648d7f2e76SPhilippe Mathieu-Daudé 
cpu_interrupt(CPUState * cpu,int mask)2658d7f2e76SPhilippe Mathieu-Daudé void cpu_interrupt(CPUState *cpu, int mask)
2668d7f2e76SPhilippe Mathieu-Daudé {
2678d7f2e76SPhilippe Mathieu-Daudé     if (cpus_accel->handle_interrupt) {
2688d7f2e76SPhilippe Mathieu-Daudé         cpus_accel->handle_interrupt(cpu, mask);
2698d7f2e76SPhilippe Mathieu-Daudé     } else {
2708d7f2e76SPhilippe Mathieu-Daudé         generic_handle_interrupt(cpu, mask);
2718d7f2e76SPhilippe Mathieu-Daudé     }
2728d7f2e76SPhilippe Mathieu-Daudé }
2738d7f2e76SPhilippe Mathieu-Daudé 
274f06f316dSSteve Sistare /*
275f06f316dSSteve Sistare  * True if the vm was previously suspended, and has not been woken or reset.
276f06f316dSSteve Sistare  */
277f06f316dSSteve Sistare static int vm_was_suspended;
278f06f316dSSteve Sistare 
vm_set_suspended(bool suspended)279f06f316dSSteve Sistare void vm_set_suspended(bool suspended)
280f06f316dSSteve Sistare {
281f06f316dSSteve Sistare     vm_was_suspended = suspended;
282f06f316dSSteve Sistare }
283f06f316dSSteve Sistare 
vm_get_suspended(void)284f06f316dSSteve Sistare bool vm_get_suspended(void)
285f06f316dSSteve Sistare {
286f06f316dSSteve Sistare     return vm_was_suspended;
287f06f316dSSteve Sistare }
288f06f316dSSteve Sistare 
do_vm_stop(RunState state,bool send_stop)2898d7f2e76SPhilippe Mathieu-Daudé static int do_vm_stop(RunState state, bool send_stop)
2908d7f2e76SPhilippe Mathieu-Daudé {
2918d7f2e76SPhilippe Mathieu-Daudé     int ret = 0;
292b9ae473dSSteve Sistare     RunState oldstate = runstate_get();
2938d7f2e76SPhilippe Mathieu-Daudé 
294b9ae473dSSteve Sistare     if (runstate_is_live(oldstate)) {
295b9ae473dSSteve Sistare         vm_was_suspended = (oldstate == RUN_STATE_SUSPENDED);
2968d7f2e76SPhilippe Mathieu-Daudé         runstate_set(state);
2978d7f2e76SPhilippe Mathieu-Daudé         cpu_disable_ticks();
298b9ae473dSSteve Sistare         if (oldstate == RUN_STATE_RUNNING) {
2998d7f2e76SPhilippe Mathieu-Daudé             pause_all_vcpus();
300b9ae473dSSteve Sistare         }
3018d7f2e76SPhilippe Mathieu-Daudé         vm_state_notify(0, state);
3028d7f2e76SPhilippe Mathieu-Daudé         if (send_stop) {
3038d7f2e76SPhilippe Mathieu-Daudé             qapi_event_send_stop();
3048d7f2e76SPhilippe Mathieu-Daudé         }
3058d7f2e76SPhilippe Mathieu-Daudé     }
3068d7f2e76SPhilippe Mathieu-Daudé 
3078d7f2e76SPhilippe Mathieu-Daudé     bdrv_drain_all();
3088d7f2e76SPhilippe Mathieu-Daudé     ret = bdrv_flush_all();
3098d7f2e76SPhilippe Mathieu-Daudé     trace_vm_stop_flush_all(ret);
3108d7f2e76SPhilippe Mathieu-Daudé 
3118d7f2e76SPhilippe Mathieu-Daudé     return ret;
3128d7f2e76SPhilippe Mathieu-Daudé }
3138d7f2e76SPhilippe Mathieu-Daudé 
3148d7f2e76SPhilippe Mathieu-Daudé /* Special vm_stop() variant for terminating the process.  Historically clients
3158d7f2e76SPhilippe Mathieu-Daudé  * did not expect a QMP STOP event and so we need to retain compatibility.
3168d7f2e76SPhilippe Mathieu-Daudé  */
vm_shutdown(void)3178d7f2e76SPhilippe Mathieu-Daudé int vm_shutdown(void)
3188d7f2e76SPhilippe Mathieu-Daudé {
3198d7f2e76SPhilippe Mathieu-Daudé     return do_vm_stop(RUN_STATE_SHUTDOWN, false);
3208d7f2e76SPhilippe Mathieu-Daudé }
3218d7f2e76SPhilippe Mathieu-Daudé 
cpu_can_run(CPUState * cpu)3228d7f2e76SPhilippe Mathieu-Daudé bool cpu_can_run(CPUState *cpu)
3238d7f2e76SPhilippe Mathieu-Daudé {
3248d7f2e76SPhilippe Mathieu-Daudé     if (cpu->stop) {
3258d7f2e76SPhilippe Mathieu-Daudé         return false;
3268d7f2e76SPhilippe Mathieu-Daudé     }
3278d7f2e76SPhilippe Mathieu-Daudé     if (cpu_is_stopped(cpu)) {
3288d7f2e76SPhilippe Mathieu-Daudé         return false;
3298d7f2e76SPhilippe Mathieu-Daudé     }
3308d7f2e76SPhilippe Mathieu-Daudé     return true;
3318d7f2e76SPhilippe Mathieu-Daudé }
3328d7f2e76SPhilippe Mathieu-Daudé 
cpu_handle_guest_debug(CPUState * cpu)3338d7f2e76SPhilippe Mathieu-Daudé void cpu_handle_guest_debug(CPUState *cpu)
3348d7f2e76SPhilippe Mathieu-Daudé {
3358d7f2e76SPhilippe Mathieu-Daudé     if (replay_running_debug()) {
3368d7f2e76SPhilippe Mathieu-Daudé         if (!cpu->singlestep_enabled) {
3378d7f2e76SPhilippe Mathieu-Daudé             /*
3388d7f2e76SPhilippe Mathieu-Daudé              * Report about the breakpoint and
3398d7f2e76SPhilippe Mathieu-Daudé              * make a single step to skip it
3408d7f2e76SPhilippe Mathieu-Daudé              */
3418d7f2e76SPhilippe Mathieu-Daudé             replay_breakpoint();
3428d7f2e76SPhilippe Mathieu-Daudé             cpu_single_step(cpu, SSTEP_ENABLE);
3438d7f2e76SPhilippe Mathieu-Daudé         } else {
3448d7f2e76SPhilippe Mathieu-Daudé             cpu_single_step(cpu, 0);
3458d7f2e76SPhilippe Mathieu-Daudé         }
3468d7f2e76SPhilippe Mathieu-Daudé     } else {
3478d7f2e76SPhilippe Mathieu-Daudé         gdb_set_stop_cpu(cpu);
3488d7f2e76SPhilippe Mathieu-Daudé         qemu_system_debug_request();
3498d7f2e76SPhilippe Mathieu-Daudé         cpu->stopped = true;
3508d7f2e76SPhilippe Mathieu-Daudé     }
3518d7f2e76SPhilippe Mathieu-Daudé }
3528d7f2e76SPhilippe Mathieu-Daudé 
3538d7f2e76SPhilippe Mathieu-Daudé #ifdef CONFIG_LINUX
sigbus_reraise(void)3548d7f2e76SPhilippe Mathieu-Daudé static void sigbus_reraise(void)
3558d7f2e76SPhilippe Mathieu-Daudé {
3568d7f2e76SPhilippe Mathieu-Daudé     sigset_t set;
3578d7f2e76SPhilippe Mathieu-Daudé     struct sigaction action;
3588d7f2e76SPhilippe Mathieu-Daudé 
3598d7f2e76SPhilippe Mathieu-Daudé     memset(&action, 0, sizeof(action));
3608d7f2e76SPhilippe Mathieu-Daudé     action.sa_handler = SIG_DFL;
3618d7f2e76SPhilippe Mathieu-Daudé     if (!sigaction(SIGBUS, &action, NULL)) {
3628d7f2e76SPhilippe Mathieu-Daudé         raise(SIGBUS);
3638d7f2e76SPhilippe Mathieu-Daudé         sigemptyset(&set);
3648d7f2e76SPhilippe Mathieu-Daudé         sigaddset(&set, SIGBUS);
3658d7f2e76SPhilippe Mathieu-Daudé         pthread_sigmask(SIG_UNBLOCK, &set, NULL);
3668d7f2e76SPhilippe Mathieu-Daudé     }
3678d7f2e76SPhilippe Mathieu-Daudé     perror("Failed to re-raise SIGBUS!");
3688d7f2e76SPhilippe Mathieu-Daudé     abort();
3698d7f2e76SPhilippe Mathieu-Daudé }
3708d7f2e76SPhilippe Mathieu-Daudé 
sigbus_handler(int n,siginfo_t * siginfo,void * ctx)3718d7f2e76SPhilippe Mathieu-Daudé static void sigbus_handler(int n, siginfo_t *siginfo, void *ctx)
3728d7f2e76SPhilippe Mathieu-Daudé {
3738d7f2e76SPhilippe Mathieu-Daudé     if (siginfo->si_code != BUS_MCEERR_AO && siginfo->si_code != BUS_MCEERR_AR) {
3748d7f2e76SPhilippe Mathieu-Daudé         sigbus_reraise();
3758d7f2e76SPhilippe Mathieu-Daudé     }
3768d7f2e76SPhilippe Mathieu-Daudé 
3778d7f2e76SPhilippe Mathieu-Daudé     if (current_cpu) {
3788d7f2e76SPhilippe Mathieu-Daudé         /* Called asynchronously in VCPU thread.  */
3798d7f2e76SPhilippe Mathieu-Daudé         if (kvm_on_sigbus_vcpu(current_cpu, siginfo->si_code, siginfo->si_addr)) {
3808d7f2e76SPhilippe Mathieu-Daudé             sigbus_reraise();
3818d7f2e76SPhilippe Mathieu-Daudé         }
3828d7f2e76SPhilippe Mathieu-Daudé     } else {
3838d7f2e76SPhilippe Mathieu-Daudé         /* Called synchronously (via signalfd) in main thread.  */
3848d7f2e76SPhilippe Mathieu-Daudé         if (kvm_on_sigbus(siginfo->si_code, siginfo->si_addr)) {
3858d7f2e76SPhilippe Mathieu-Daudé             sigbus_reraise();
3868d7f2e76SPhilippe Mathieu-Daudé         }
3878d7f2e76SPhilippe Mathieu-Daudé     }
3888d7f2e76SPhilippe Mathieu-Daudé }
3898d7f2e76SPhilippe Mathieu-Daudé 
qemu_init_sigbus(void)3908d7f2e76SPhilippe Mathieu-Daudé static void qemu_init_sigbus(void)
3918d7f2e76SPhilippe Mathieu-Daudé {
3928d7f2e76SPhilippe Mathieu-Daudé     struct sigaction action;
3938d7f2e76SPhilippe Mathieu-Daudé 
3948d7f2e76SPhilippe Mathieu-Daudé     /*
3958d7f2e76SPhilippe Mathieu-Daudé      * ALERT: when modifying this, take care that SIGBUS forwarding in
3968d7f2e76SPhilippe Mathieu-Daudé      * qemu_prealloc_mem() will continue working as expected.
3978d7f2e76SPhilippe Mathieu-Daudé      */
3988d7f2e76SPhilippe Mathieu-Daudé     memset(&action, 0, sizeof(action));
3998d7f2e76SPhilippe Mathieu-Daudé     action.sa_flags = SA_SIGINFO;
4008d7f2e76SPhilippe Mathieu-Daudé     action.sa_sigaction = sigbus_handler;
4018d7f2e76SPhilippe Mathieu-Daudé     sigaction(SIGBUS, &action, NULL);
4028d7f2e76SPhilippe Mathieu-Daudé 
4038d7f2e76SPhilippe Mathieu-Daudé     prctl(PR_MCE_KILL, PR_MCE_KILL_SET, PR_MCE_KILL_EARLY, 0, 0);
4048d7f2e76SPhilippe Mathieu-Daudé }
4058d7f2e76SPhilippe Mathieu-Daudé #else /* !CONFIG_LINUX */
qemu_init_sigbus(void)4068d7f2e76SPhilippe Mathieu-Daudé static void qemu_init_sigbus(void)
4078d7f2e76SPhilippe Mathieu-Daudé {
4088d7f2e76SPhilippe Mathieu-Daudé }
4098d7f2e76SPhilippe Mathieu-Daudé #endif /* !CONFIG_LINUX */
4108d7f2e76SPhilippe Mathieu-Daudé 
4118d7f2e76SPhilippe Mathieu-Daudé static QemuThread io_thread;
4128d7f2e76SPhilippe Mathieu-Daudé 
4138d7f2e76SPhilippe Mathieu-Daudé /* cpu creation */
4148d7f2e76SPhilippe Mathieu-Daudé static QemuCond qemu_cpu_cond;
4158d7f2e76SPhilippe Mathieu-Daudé /* system init */
4168d7f2e76SPhilippe Mathieu-Daudé static QemuCond qemu_pause_cond;
4178d7f2e76SPhilippe Mathieu-Daudé 
qemu_init_cpu_loop(void)4188d7f2e76SPhilippe Mathieu-Daudé void qemu_init_cpu_loop(void)
4198d7f2e76SPhilippe Mathieu-Daudé {
4208d7f2e76SPhilippe Mathieu-Daudé     qemu_init_sigbus();
4218d7f2e76SPhilippe Mathieu-Daudé     qemu_cond_init(&qemu_cpu_cond);
4228d7f2e76SPhilippe Mathieu-Daudé     qemu_cond_init(&qemu_pause_cond);
423195801d7SStefan Hajnoczi     qemu_mutex_init(&bql);
4248d7f2e76SPhilippe Mathieu-Daudé 
4258d7f2e76SPhilippe Mathieu-Daudé     qemu_thread_get_self(&io_thread);
4268d7f2e76SPhilippe Mathieu-Daudé }
4278d7f2e76SPhilippe Mathieu-Daudé 
run_on_cpu(CPUState * cpu,run_on_cpu_func func,run_on_cpu_data data)4288d7f2e76SPhilippe Mathieu-Daudé void run_on_cpu(CPUState *cpu, run_on_cpu_func func, run_on_cpu_data data)
4298d7f2e76SPhilippe Mathieu-Daudé {
430195801d7SStefan Hajnoczi     do_run_on_cpu(cpu, func, data, &bql);
4318d7f2e76SPhilippe Mathieu-Daudé }
4328d7f2e76SPhilippe Mathieu-Daudé 
qemu_cpu_stop(CPUState * cpu,bool exit)4338d7f2e76SPhilippe Mathieu-Daudé static void qemu_cpu_stop(CPUState *cpu, bool exit)
4348d7f2e76SPhilippe Mathieu-Daudé {
4358d7f2e76SPhilippe Mathieu-Daudé     g_assert(qemu_cpu_is_self(cpu));
4368d7f2e76SPhilippe Mathieu-Daudé     cpu->stop = false;
4378d7f2e76SPhilippe Mathieu-Daudé     cpu->stopped = true;
4388d7f2e76SPhilippe Mathieu-Daudé     if (exit) {
4398d7f2e76SPhilippe Mathieu-Daudé         cpu_exit(cpu);
4408d7f2e76SPhilippe Mathieu-Daudé     }
4418d7f2e76SPhilippe Mathieu-Daudé     qemu_cond_broadcast(&qemu_pause_cond);
4428d7f2e76SPhilippe Mathieu-Daudé }
4438d7f2e76SPhilippe Mathieu-Daudé 
qemu_wait_io_event_common(CPUState * cpu)4448d7f2e76SPhilippe Mathieu-Daudé void qemu_wait_io_event_common(CPUState *cpu)
4458d7f2e76SPhilippe Mathieu-Daudé {
4468d7f2e76SPhilippe Mathieu-Daudé     qatomic_set_mb(&cpu->thread_kicked, false);
4478d7f2e76SPhilippe Mathieu-Daudé     if (cpu->stop) {
4488d7f2e76SPhilippe Mathieu-Daudé         qemu_cpu_stop(cpu, false);
4498d7f2e76SPhilippe Mathieu-Daudé     }
4508d7f2e76SPhilippe Mathieu-Daudé     process_queued_cpu_work(cpu);
4518d7f2e76SPhilippe Mathieu-Daudé }
4528d7f2e76SPhilippe Mathieu-Daudé 
qemu_wait_io_event(CPUState * cpu)4538d7f2e76SPhilippe Mathieu-Daudé void qemu_wait_io_event(CPUState *cpu)
4548d7f2e76SPhilippe Mathieu-Daudé {
4558d7f2e76SPhilippe Mathieu-Daudé     bool slept = false;
4568d7f2e76SPhilippe Mathieu-Daudé 
4578d7f2e76SPhilippe Mathieu-Daudé     while (cpu_thread_is_idle(cpu)) {
4588d7f2e76SPhilippe Mathieu-Daudé         if (!slept) {
4598d7f2e76SPhilippe Mathieu-Daudé             slept = true;
4608d7f2e76SPhilippe Mathieu-Daudé             qemu_plugin_vcpu_idle_cb(cpu);
4618d7f2e76SPhilippe Mathieu-Daudé         }
462195801d7SStefan Hajnoczi         qemu_cond_wait(cpu->halt_cond, &bql);
4638d7f2e76SPhilippe Mathieu-Daudé     }
4648d7f2e76SPhilippe Mathieu-Daudé     if (slept) {
4658d7f2e76SPhilippe Mathieu-Daudé         qemu_plugin_vcpu_resume_cb(cpu);
4668d7f2e76SPhilippe Mathieu-Daudé     }
4678d7f2e76SPhilippe Mathieu-Daudé 
4688d7f2e76SPhilippe Mathieu-Daudé     qemu_wait_io_event_common(cpu);
4698d7f2e76SPhilippe Mathieu-Daudé }
4708d7f2e76SPhilippe Mathieu-Daudé 
cpus_kick_thread(CPUState * cpu)4718d7f2e76SPhilippe Mathieu-Daudé void cpus_kick_thread(CPUState *cpu)
4728d7f2e76SPhilippe Mathieu-Daudé {
4738d7f2e76SPhilippe Mathieu-Daudé     if (cpu->thread_kicked) {
4748d7f2e76SPhilippe Mathieu-Daudé         return;
4758d7f2e76SPhilippe Mathieu-Daudé     }
4768d7f2e76SPhilippe Mathieu-Daudé     cpu->thread_kicked = true;
4778d7f2e76SPhilippe Mathieu-Daudé 
4788d7f2e76SPhilippe Mathieu-Daudé #ifndef _WIN32
4798d7f2e76SPhilippe Mathieu-Daudé     int err = pthread_kill(cpu->thread->thread, SIG_IPI);
4808d7f2e76SPhilippe Mathieu-Daudé     if (err && err != ESRCH) {
4818d7f2e76SPhilippe Mathieu-Daudé         fprintf(stderr, "qemu:%s: %s", __func__, strerror(err));
4828d7f2e76SPhilippe Mathieu-Daudé         exit(1);
4838d7f2e76SPhilippe Mathieu-Daudé     }
4848d7f2e76SPhilippe Mathieu-Daudé #else
4858d7f2e76SPhilippe Mathieu-Daudé     qemu_sem_post(&cpu->sem);
4868d7f2e76SPhilippe Mathieu-Daudé #endif
4878d7f2e76SPhilippe Mathieu-Daudé }
4888d7f2e76SPhilippe Mathieu-Daudé 
qemu_cpu_kick(CPUState * cpu)4898d7f2e76SPhilippe Mathieu-Daudé void qemu_cpu_kick(CPUState *cpu)
4908d7f2e76SPhilippe Mathieu-Daudé {
4918d7f2e76SPhilippe Mathieu-Daudé     qemu_cond_broadcast(cpu->halt_cond);
4928d7f2e76SPhilippe Mathieu-Daudé     if (cpus_accel->kick_vcpu_thread) {
4938d7f2e76SPhilippe Mathieu-Daudé         cpus_accel->kick_vcpu_thread(cpu);
4948d7f2e76SPhilippe Mathieu-Daudé     } else { /* default */
4958d7f2e76SPhilippe Mathieu-Daudé         cpus_kick_thread(cpu);
4968d7f2e76SPhilippe Mathieu-Daudé     }
4978d7f2e76SPhilippe Mathieu-Daudé }
4988d7f2e76SPhilippe Mathieu-Daudé 
qemu_cpu_kick_self(void)4998d7f2e76SPhilippe Mathieu-Daudé void qemu_cpu_kick_self(void)
5008d7f2e76SPhilippe Mathieu-Daudé {
5018d7f2e76SPhilippe Mathieu-Daudé     assert(current_cpu);
5028d7f2e76SPhilippe Mathieu-Daudé     cpus_kick_thread(current_cpu);
5038d7f2e76SPhilippe Mathieu-Daudé }
5048d7f2e76SPhilippe Mathieu-Daudé 
qemu_cpu_is_self(CPUState * cpu)5058d7f2e76SPhilippe Mathieu-Daudé bool qemu_cpu_is_self(CPUState *cpu)
5068d7f2e76SPhilippe Mathieu-Daudé {
5078d7f2e76SPhilippe Mathieu-Daudé     return qemu_thread_is_self(cpu->thread);
5088d7f2e76SPhilippe Mathieu-Daudé }
5098d7f2e76SPhilippe Mathieu-Daudé 
qemu_in_vcpu_thread(void)5108d7f2e76SPhilippe Mathieu-Daudé bool qemu_in_vcpu_thread(void)
5118d7f2e76SPhilippe Mathieu-Daudé {
5128d7f2e76SPhilippe Mathieu-Daudé     return current_cpu && qemu_cpu_is_self(current_cpu);
5138d7f2e76SPhilippe Mathieu-Daudé }
5148d7f2e76SPhilippe Mathieu-Daudé 
QEMU_DEFINE_STATIC_CO_TLS(bool,bql_locked)515195801d7SStefan Hajnoczi QEMU_DEFINE_STATIC_CO_TLS(bool, bql_locked)
5168d7f2e76SPhilippe Mathieu-Daudé 
517195801d7SStefan Hajnoczi bool bql_locked(void)
5188d7f2e76SPhilippe Mathieu-Daudé {
519195801d7SStefan Hajnoczi     return get_bql_locked();
5208d7f2e76SPhilippe Mathieu-Daudé }
5218d7f2e76SPhilippe Mathieu-Daudé 
qemu_in_main_thread(void)5228d7f2e76SPhilippe Mathieu-Daudé bool qemu_in_main_thread(void)
5238d7f2e76SPhilippe Mathieu-Daudé {
524195801d7SStefan Hajnoczi     return bql_locked();
5258d7f2e76SPhilippe Mathieu-Daudé }
5268d7f2e76SPhilippe Mathieu-Daudé 
5278d7f2e76SPhilippe Mathieu-Daudé /*
5288d7f2e76SPhilippe Mathieu-Daudé  * The BQL is taken from so many places that it is worth profiling the
5298d7f2e76SPhilippe Mathieu-Daudé  * callers directly, instead of funneling them all through a single function.
5308d7f2e76SPhilippe Mathieu-Daudé  */
bql_lock_impl(const char * file,int line)531195801d7SStefan Hajnoczi void bql_lock_impl(const char *file, int line)
5328d7f2e76SPhilippe Mathieu-Daudé {
533195801d7SStefan Hajnoczi     QemuMutexLockFunc bql_lock_fn = qatomic_read(&bql_mutex_lock_func);
5348d7f2e76SPhilippe Mathieu-Daudé 
535195801d7SStefan Hajnoczi     g_assert(!bql_locked());
536195801d7SStefan Hajnoczi     bql_lock_fn(&bql, file, line);
537195801d7SStefan Hajnoczi     set_bql_locked(true);
5388d7f2e76SPhilippe Mathieu-Daudé }
5398d7f2e76SPhilippe Mathieu-Daudé 
bql_unlock(void)540195801d7SStefan Hajnoczi void bql_unlock(void)
5418d7f2e76SPhilippe Mathieu-Daudé {
542195801d7SStefan Hajnoczi     g_assert(bql_locked());
543195801d7SStefan Hajnoczi     set_bql_locked(false);
544195801d7SStefan Hajnoczi     qemu_mutex_unlock(&bql);
5458d7f2e76SPhilippe Mathieu-Daudé }
5468d7f2e76SPhilippe Mathieu-Daudé 
qemu_cond_wait_bql(QemuCond * cond)5477c754c78SStefan Hajnoczi void qemu_cond_wait_bql(QemuCond *cond)
5488d7f2e76SPhilippe Mathieu-Daudé {
549195801d7SStefan Hajnoczi     qemu_cond_wait(cond, &bql);
5508d7f2e76SPhilippe Mathieu-Daudé }
5518d7f2e76SPhilippe Mathieu-Daudé 
qemu_cond_timedwait_bql(QemuCond * cond,int ms)5527c754c78SStefan Hajnoczi void qemu_cond_timedwait_bql(QemuCond *cond, int ms)
5538d7f2e76SPhilippe Mathieu-Daudé {
554195801d7SStefan Hajnoczi     qemu_cond_timedwait(cond, &bql, ms);
5558d7f2e76SPhilippe Mathieu-Daudé }
5568d7f2e76SPhilippe Mathieu-Daudé 
5578d7f2e76SPhilippe Mathieu-Daudé /* signal CPU creation */
cpu_thread_signal_created(CPUState * cpu)5588d7f2e76SPhilippe Mathieu-Daudé void cpu_thread_signal_created(CPUState *cpu)
5598d7f2e76SPhilippe Mathieu-Daudé {
5608d7f2e76SPhilippe Mathieu-Daudé     cpu->created = true;
5618d7f2e76SPhilippe Mathieu-Daudé     qemu_cond_signal(&qemu_cpu_cond);
5628d7f2e76SPhilippe Mathieu-Daudé }
5638d7f2e76SPhilippe Mathieu-Daudé 
5648d7f2e76SPhilippe Mathieu-Daudé /* signal CPU destruction */
cpu_thread_signal_destroyed(CPUState * cpu)5658d7f2e76SPhilippe Mathieu-Daudé void cpu_thread_signal_destroyed(CPUState *cpu)
5668d7f2e76SPhilippe Mathieu-Daudé {
5678d7f2e76SPhilippe Mathieu-Daudé     cpu->created = false;
5688d7f2e76SPhilippe Mathieu-Daudé     qemu_cond_signal(&qemu_cpu_cond);
5698d7f2e76SPhilippe Mathieu-Daudé }
5708d7f2e76SPhilippe Mathieu-Daudé 
cpu_pause(CPUState * cpu)5716b659310SNicholas Piggin void cpu_pause(CPUState *cpu)
5726b659310SNicholas Piggin {
5736b659310SNicholas Piggin     if (qemu_cpu_is_self(cpu)) {
5746b659310SNicholas Piggin         qemu_cpu_stop(cpu, true);
5756b659310SNicholas Piggin     } else {
5766b659310SNicholas Piggin         cpu->stop = true;
5776b659310SNicholas Piggin         qemu_cpu_kick(cpu);
5786b659310SNicholas Piggin     }
5796b659310SNicholas Piggin }
5806b659310SNicholas Piggin 
cpu_resume(CPUState * cpu)5816b659310SNicholas Piggin void cpu_resume(CPUState *cpu)
5826b659310SNicholas Piggin {
5836b659310SNicholas Piggin     cpu->stop = false;
5846b659310SNicholas Piggin     cpu->stopped = false;
5856b659310SNicholas Piggin     qemu_cpu_kick(cpu);
5866b659310SNicholas Piggin }
5878d7f2e76SPhilippe Mathieu-Daudé 
all_vcpus_paused(void)5888d7f2e76SPhilippe Mathieu-Daudé static bool all_vcpus_paused(void)
5898d7f2e76SPhilippe Mathieu-Daudé {
5908d7f2e76SPhilippe Mathieu-Daudé     CPUState *cpu;
5918d7f2e76SPhilippe Mathieu-Daudé 
5928d7f2e76SPhilippe Mathieu-Daudé     CPU_FOREACH(cpu) {
5938d7f2e76SPhilippe Mathieu-Daudé         if (!cpu->stopped) {
5948d7f2e76SPhilippe Mathieu-Daudé             return false;
5958d7f2e76SPhilippe Mathieu-Daudé         }
5968d7f2e76SPhilippe Mathieu-Daudé     }
5978d7f2e76SPhilippe Mathieu-Daudé 
5988d7f2e76SPhilippe Mathieu-Daudé     return true;
5998d7f2e76SPhilippe Mathieu-Daudé }
6008d7f2e76SPhilippe Mathieu-Daudé 
pause_all_vcpus(void)6018d7f2e76SPhilippe Mathieu-Daudé void pause_all_vcpus(void)
6028d7f2e76SPhilippe Mathieu-Daudé {
6038d7f2e76SPhilippe Mathieu-Daudé     CPUState *cpu;
6048d7f2e76SPhilippe Mathieu-Daudé 
6058d7f2e76SPhilippe Mathieu-Daudé     qemu_clock_enable(QEMU_CLOCK_VIRTUAL, false);
6068d7f2e76SPhilippe Mathieu-Daudé     CPU_FOREACH(cpu) {
6076b659310SNicholas Piggin         cpu_pause(cpu);
6088d7f2e76SPhilippe Mathieu-Daudé     }
6098d7f2e76SPhilippe Mathieu-Daudé 
6108d7f2e76SPhilippe Mathieu-Daudé     /* We need to drop the replay_lock so any vCPU threads woken up
6118d7f2e76SPhilippe Mathieu-Daudé      * can finish their replay tasks
6128d7f2e76SPhilippe Mathieu-Daudé      */
6138d7f2e76SPhilippe Mathieu-Daudé     replay_mutex_unlock();
6148d7f2e76SPhilippe Mathieu-Daudé 
6158d7f2e76SPhilippe Mathieu-Daudé     while (!all_vcpus_paused()) {
616195801d7SStefan Hajnoczi         qemu_cond_wait(&qemu_pause_cond, &bql);
6178d7f2e76SPhilippe Mathieu-Daudé         CPU_FOREACH(cpu) {
6188d7f2e76SPhilippe Mathieu-Daudé             qemu_cpu_kick(cpu);
6198d7f2e76SPhilippe Mathieu-Daudé         }
6208d7f2e76SPhilippe Mathieu-Daudé     }
6218d7f2e76SPhilippe Mathieu-Daudé 
622195801d7SStefan Hajnoczi     bql_unlock();
6238d7f2e76SPhilippe Mathieu-Daudé     replay_mutex_lock();
624195801d7SStefan Hajnoczi     bql_lock();
6258d7f2e76SPhilippe Mathieu-Daudé }
6268d7f2e76SPhilippe Mathieu-Daudé 
resume_all_vcpus(void)6278d7f2e76SPhilippe Mathieu-Daudé void resume_all_vcpus(void)
6288d7f2e76SPhilippe Mathieu-Daudé {
6298d7f2e76SPhilippe Mathieu-Daudé     CPUState *cpu;
6308d7f2e76SPhilippe Mathieu-Daudé 
6318d7f2e76SPhilippe Mathieu-Daudé     if (!runstate_is_running()) {
6328d7f2e76SPhilippe Mathieu-Daudé         return;
6338d7f2e76SPhilippe Mathieu-Daudé     }
6348d7f2e76SPhilippe Mathieu-Daudé 
6358d7f2e76SPhilippe Mathieu-Daudé     qemu_clock_enable(QEMU_CLOCK_VIRTUAL, true);
6368d7f2e76SPhilippe Mathieu-Daudé     CPU_FOREACH(cpu) {
6378d7f2e76SPhilippe Mathieu-Daudé         cpu_resume(cpu);
6388d7f2e76SPhilippe Mathieu-Daudé     }
6398d7f2e76SPhilippe Mathieu-Daudé }
6408d7f2e76SPhilippe Mathieu-Daudé 
cpu_remove_sync(CPUState * cpu)6418d7f2e76SPhilippe Mathieu-Daudé void cpu_remove_sync(CPUState *cpu)
6428d7f2e76SPhilippe Mathieu-Daudé {
6438d7f2e76SPhilippe Mathieu-Daudé     cpu->stop = true;
6448d7f2e76SPhilippe Mathieu-Daudé     cpu->unplug = true;
6458d7f2e76SPhilippe Mathieu-Daudé     qemu_cpu_kick(cpu);
646195801d7SStefan Hajnoczi     bql_unlock();
6478d7f2e76SPhilippe Mathieu-Daudé     qemu_thread_join(cpu->thread);
648195801d7SStefan Hajnoczi     bql_lock();
6498d7f2e76SPhilippe Mathieu-Daudé }
6508d7f2e76SPhilippe Mathieu-Daudé 
cpus_register_accel(const AccelOpsClass * ops)6518d7f2e76SPhilippe Mathieu-Daudé void cpus_register_accel(const AccelOpsClass *ops)
6528d7f2e76SPhilippe Mathieu-Daudé {
6538d7f2e76SPhilippe Mathieu-Daudé     assert(ops != NULL);
6548d7f2e76SPhilippe Mathieu-Daudé     assert(ops->create_vcpu_thread != NULL); /* mandatory */
6558d7f2e76SPhilippe Mathieu-Daudé     cpus_accel = ops;
6568d7f2e76SPhilippe Mathieu-Daudé }
6578d7f2e76SPhilippe Mathieu-Daudé 
cpus_get_accel(void)6588d7f2e76SPhilippe Mathieu-Daudé const AccelOpsClass *cpus_get_accel(void)
6598d7f2e76SPhilippe Mathieu-Daudé {
6608d7f2e76SPhilippe Mathieu-Daudé     /* broken if we call this early */
6618d7f2e76SPhilippe Mathieu-Daudé     assert(cpus_accel);
6628d7f2e76SPhilippe Mathieu-Daudé     return cpus_accel;
6638d7f2e76SPhilippe Mathieu-Daudé }
6648d7f2e76SPhilippe Mathieu-Daudé 
qemu_init_vcpu(CPUState * cpu)6658d7f2e76SPhilippe Mathieu-Daudé void qemu_init_vcpu(CPUState *cpu)
6668d7f2e76SPhilippe Mathieu-Daudé {
6678d7f2e76SPhilippe Mathieu-Daudé     MachineState *ms = MACHINE(qdev_get_machine());
6688d7f2e76SPhilippe Mathieu-Daudé 
669958ac3c4SZhuocheng Ding     cpu->nr_cores = machine_topo_get_cores_per_socket(ms);
6708d7f2e76SPhilippe Mathieu-Daudé     cpu->nr_threads =  ms->smp.threads;
6718d7f2e76SPhilippe Mathieu-Daudé     cpu->stopped = true;
6728d7f2e76SPhilippe Mathieu-Daudé     cpu->random_seed = qemu_guest_random_seed_thread_part1();
6738d7f2e76SPhilippe Mathieu-Daudé 
6748d7f2e76SPhilippe Mathieu-Daudé     if (!cpu->as) {
6758d7f2e76SPhilippe Mathieu-Daudé         /* If the target cpu hasn't set up any address spaces itself,
6768d7f2e76SPhilippe Mathieu-Daudé          * give it the default one.
6778d7f2e76SPhilippe Mathieu-Daudé          */
6788d7f2e76SPhilippe Mathieu-Daudé         cpu->num_ases = 1;
6798d7f2e76SPhilippe Mathieu-Daudé         cpu_address_space_init(cpu, 0, "cpu-memory", cpu->memory);
6808d7f2e76SPhilippe Mathieu-Daudé     }
6818d7f2e76SPhilippe Mathieu-Daudé 
6828d7f2e76SPhilippe Mathieu-Daudé     /* accelerators all implement the AccelOpsClass */
6838d7f2e76SPhilippe Mathieu-Daudé     g_assert(cpus_accel != NULL && cpus_accel->create_vcpu_thread != NULL);
6848d7f2e76SPhilippe Mathieu-Daudé     cpus_accel->create_vcpu_thread(cpu);
6858d7f2e76SPhilippe Mathieu-Daudé 
6868d7f2e76SPhilippe Mathieu-Daudé     while (!cpu->created) {
687195801d7SStefan Hajnoczi         qemu_cond_wait(&qemu_cpu_cond, &bql);
6888d7f2e76SPhilippe Mathieu-Daudé     }
6898d7f2e76SPhilippe Mathieu-Daudé }
6908d7f2e76SPhilippe Mathieu-Daudé 
cpu_stop_current(void)6918d7f2e76SPhilippe Mathieu-Daudé void cpu_stop_current(void)
6928d7f2e76SPhilippe Mathieu-Daudé {
6938d7f2e76SPhilippe Mathieu-Daudé     if (current_cpu) {
6948d7f2e76SPhilippe Mathieu-Daudé         current_cpu->stop = true;
6958d7f2e76SPhilippe Mathieu-Daudé         cpu_exit(current_cpu);
6968d7f2e76SPhilippe Mathieu-Daudé     }
6978d7f2e76SPhilippe Mathieu-Daudé }
6988d7f2e76SPhilippe Mathieu-Daudé 
vm_stop(RunState state)6998d7f2e76SPhilippe Mathieu-Daudé int vm_stop(RunState state)
7008d7f2e76SPhilippe Mathieu-Daudé {
7018d7f2e76SPhilippe Mathieu-Daudé     if (qemu_in_vcpu_thread()) {
7028d7f2e76SPhilippe Mathieu-Daudé         qemu_system_vmstop_request_prepare();
7038d7f2e76SPhilippe Mathieu-Daudé         qemu_system_vmstop_request(state);
7048d7f2e76SPhilippe Mathieu-Daudé         /*
7058d7f2e76SPhilippe Mathieu-Daudé          * FIXME: should not return to device code in case
7068d7f2e76SPhilippe Mathieu-Daudé          * vm_stop() has been requested.
7078d7f2e76SPhilippe Mathieu-Daudé          */
7088d7f2e76SPhilippe Mathieu-Daudé         cpu_stop_current();
7098d7f2e76SPhilippe Mathieu-Daudé         return 0;
7108d7f2e76SPhilippe Mathieu-Daudé     }
7118d7f2e76SPhilippe Mathieu-Daudé 
7128d7f2e76SPhilippe Mathieu-Daudé     return do_vm_stop(state, true);
7138d7f2e76SPhilippe Mathieu-Daudé }
7148d7f2e76SPhilippe Mathieu-Daudé 
7158d7f2e76SPhilippe Mathieu-Daudé /**
7168d7f2e76SPhilippe Mathieu-Daudé  * Prepare for (re)starting the VM.
717b9ae473dSSteve Sistare  * Returns 0 if the vCPUs should be restarted, -1 on an error condition,
718b9ae473dSSteve Sistare  * and 1 otherwise.
7198d7f2e76SPhilippe Mathieu-Daudé  */
vm_prepare_start(bool step_pending)7208d7f2e76SPhilippe Mathieu-Daudé int vm_prepare_start(bool step_pending)
7218d7f2e76SPhilippe Mathieu-Daudé {
722b9ae473dSSteve Sistare     int ret = vm_was_suspended ? 1 : 0;
723b9ae473dSSteve Sistare     RunState state = vm_was_suspended ? RUN_STATE_SUSPENDED : RUN_STATE_RUNNING;
7248d7f2e76SPhilippe Mathieu-Daudé     RunState requested;
7258d7f2e76SPhilippe Mathieu-Daudé 
7268d7f2e76SPhilippe Mathieu-Daudé     qemu_vmstop_requested(&requested);
7278d7f2e76SPhilippe Mathieu-Daudé     if (runstate_is_running() && requested == RUN_STATE__MAX) {
7288d7f2e76SPhilippe Mathieu-Daudé         return -1;
7298d7f2e76SPhilippe Mathieu-Daudé     }
7308d7f2e76SPhilippe Mathieu-Daudé 
7318d7f2e76SPhilippe Mathieu-Daudé     /* Ensure that a STOP/RESUME pair of events is emitted if a
7328d7f2e76SPhilippe Mathieu-Daudé      * vmstop request was pending.  The BLOCK_IO_ERROR event, for
7338d7f2e76SPhilippe Mathieu-Daudé      * example, according to documentation is always followed by
7348d7f2e76SPhilippe Mathieu-Daudé      * the STOP event.
7358d7f2e76SPhilippe Mathieu-Daudé      */
7368d7f2e76SPhilippe Mathieu-Daudé     if (runstate_is_running()) {
7378d7f2e76SPhilippe Mathieu-Daudé         qapi_event_send_stop();
7388d7f2e76SPhilippe Mathieu-Daudé         qapi_event_send_resume();
7398d7f2e76SPhilippe Mathieu-Daudé         return -1;
7408d7f2e76SPhilippe Mathieu-Daudé     }
7418d7f2e76SPhilippe Mathieu-Daudé 
7428d7f2e76SPhilippe Mathieu-Daudé     /*
7438d7f2e76SPhilippe Mathieu-Daudé      * WHPX accelerator needs to know whether we are going to step
7448d7f2e76SPhilippe Mathieu-Daudé      * any CPUs, before starting the first one.
7458d7f2e76SPhilippe Mathieu-Daudé      */
7468d7f2e76SPhilippe Mathieu-Daudé     if (cpus_accel->synchronize_pre_resume) {
7478d7f2e76SPhilippe Mathieu-Daudé         cpus_accel->synchronize_pre_resume(step_pending);
7488d7f2e76SPhilippe Mathieu-Daudé     }
7498d7f2e76SPhilippe Mathieu-Daudé 
7508d7f2e76SPhilippe Mathieu-Daudé     /* We are sending this now, but the CPUs will be resumed shortly later */
7518d7f2e76SPhilippe Mathieu-Daudé     qapi_event_send_resume();
7528d7f2e76SPhilippe Mathieu-Daudé 
7538d7f2e76SPhilippe Mathieu-Daudé     cpu_enable_ticks();
754b9ae473dSSteve Sistare     runstate_set(state);
755b9ae473dSSteve Sistare     vm_state_notify(1, state);
756b9ae473dSSteve Sistare     vm_was_suspended = false;
757b9ae473dSSteve Sistare     return ret;
7588d7f2e76SPhilippe Mathieu-Daudé }
7598d7f2e76SPhilippe Mathieu-Daudé 
vm_start(void)7608d7f2e76SPhilippe Mathieu-Daudé void vm_start(void)
7618d7f2e76SPhilippe Mathieu-Daudé {
7628d7f2e76SPhilippe Mathieu-Daudé     if (!vm_prepare_start(false)) {
7638d7f2e76SPhilippe Mathieu-Daudé         resume_all_vcpus();
7648d7f2e76SPhilippe Mathieu-Daudé     }
7658d7f2e76SPhilippe Mathieu-Daudé }
7668d7f2e76SPhilippe Mathieu-Daudé 
vm_resume(RunState state)7679ff5e79fSSteve Sistare void vm_resume(RunState state)
7689ff5e79fSSteve Sistare {
7699ff5e79fSSteve Sistare     if (runstate_is_live(state)) {
7709ff5e79fSSteve Sistare         vm_start();
7719ff5e79fSSteve Sistare     } else {
7729ff5e79fSSteve Sistare         runstate_set(state);
7739ff5e79fSSteve Sistare     }
7749ff5e79fSSteve Sistare }
7759ff5e79fSSteve Sistare 
7768d7f2e76SPhilippe Mathieu-Daudé /* does a state transition even if the VM is already stopped,
7778d7f2e76SPhilippe Mathieu-Daudé    current state is forgotten forever */
vm_stop_force_state(RunState state)7788d7f2e76SPhilippe Mathieu-Daudé int vm_stop_force_state(RunState state)
7798d7f2e76SPhilippe Mathieu-Daudé {
780b9ae473dSSteve Sistare     if (runstate_is_live(runstate_get())) {
7818d7f2e76SPhilippe Mathieu-Daudé         return vm_stop(state);
7828d7f2e76SPhilippe Mathieu-Daudé     } else {
7838d7f2e76SPhilippe Mathieu-Daudé         int ret;
7848d7f2e76SPhilippe Mathieu-Daudé         runstate_set(state);
7858d7f2e76SPhilippe Mathieu-Daudé 
7868d7f2e76SPhilippe Mathieu-Daudé         bdrv_drain_all();
7878d7f2e76SPhilippe Mathieu-Daudé         /* Make sure to return an error if the flush in a previous vm_stop()
7888d7f2e76SPhilippe Mathieu-Daudé          * failed. */
7898d7f2e76SPhilippe Mathieu-Daudé         ret = bdrv_flush_all();
7908d7f2e76SPhilippe Mathieu-Daudé         trace_vm_stop_flush_all(ret);
7918d7f2e76SPhilippe Mathieu-Daudé         return ret;
7928d7f2e76SPhilippe Mathieu-Daudé     }
7938d7f2e76SPhilippe Mathieu-Daudé }
7948d7f2e76SPhilippe Mathieu-Daudé 
qmp_memsave(uint64_t addr,uint64_t size,const char * filename,bool has_cpu,int64_t cpu_index,Error ** errp)795*ef71d820SJosh Junon void qmp_memsave(uint64_t addr, uint64_t size, const char *filename,
7968d7f2e76SPhilippe Mathieu-Daudé                  bool has_cpu, int64_t cpu_index, Error **errp)
7978d7f2e76SPhilippe Mathieu-Daudé {
7988d7f2e76SPhilippe Mathieu-Daudé     FILE *f;
799*ef71d820SJosh Junon     uint64_t l;
8008d7f2e76SPhilippe Mathieu-Daudé     CPUState *cpu;
8018d7f2e76SPhilippe Mathieu-Daudé     uint8_t buf[1024];
802*ef71d820SJosh Junon     uint64_t orig_addr = addr, orig_size = size;
8038d7f2e76SPhilippe Mathieu-Daudé 
8048d7f2e76SPhilippe Mathieu-Daudé     if (!has_cpu) {
8058d7f2e76SPhilippe Mathieu-Daudé         cpu_index = 0;
8068d7f2e76SPhilippe Mathieu-Daudé     }
8078d7f2e76SPhilippe Mathieu-Daudé 
8088d7f2e76SPhilippe Mathieu-Daudé     cpu = qemu_get_cpu(cpu_index);
8098d7f2e76SPhilippe Mathieu-Daudé     if (cpu == NULL) {
8108d7f2e76SPhilippe Mathieu-Daudé         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "cpu-index",
8118d7f2e76SPhilippe Mathieu-Daudé                    "a CPU number");
8128d7f2e76SPhilippe Mathieu-Daudé         return;
8138d7f2e76SPhilippe Mathieu-Daudé     }
8148d7f2e76SPhilippe Mathieu-Daudé 
8158d7f2e76SPhilippe Mathieu-Daudé     f = fopen(filename, "wb");
8168d7f2e76SPhilippe Mathieu-Daudé     if (!f) {
8178d7f2e76SPhilippe Mathieu-Daudé         error_setg_file_open(errp, errno, filename);
8188d7f2e76SPhilippe Mathieu-Daudé         return;
8198d7f2e76SPhilippe Mathieu-Daudé     }
8208d7f2e76SPhilippe Mathieu-Daudé 
8218d7f2e76SPhilippe Mathieu-Daudé     while (size != 0) {
8228d7f2e76SPhilippe Mathieu-Daudé         l = sizeof(buf);
8238d7f2e76SPhilippe Mathieu-Daudé         if (l > size)
8248d7f2e76SPhilippe Mathieu-Daudé             l = size;
8258d7f2e76SPhilippe Mathieu-Daudé         if (cpu_memory_rw_debug(cpu, addr, buf, l, 0) != 0) {
826*ef71d820SJosh Junon             error_setg(errp, "Invalid addr 0x%016" PRIx64 "/size %" PRIu64
8278d7f2e76SPhilippe Mathieu-Daudé                              " specified", orig_addr, orig_size);
8288d7f2e76SPhilippe Mathieu-Daudé             goto exit;
8298d7f2e76SPhilippe Mathieu-Daudé         }
8308d7f2e76SPhilippe Mathieu-Daudé         if (fwrite(buf, 1, l, f) != l) {
831c59fb13bSMarkus Armbruster             error_setg(errp, "writing memory to '%s' failed",
832c59fb13bSMarkus Armbruster                        filename);
8338d7f2e76SPhilippe Mathieu-Daudé             goto exit;
8348d7f2e76SPhilippe Mathieu-Daudé         }
8358d7f2e76SPhilippe Mathieu-Daudé         addr += l;
8368d7f2e76SPhilippe Mathieu-Daudé         size -= l;
8378d7f2e76SPhilippe Mathieu-Daudé     }
8388d7f2e76SPhilippe Mathieu-Daudé 
8398d7f2e76SPhilippe Mathieu-Daudé exit:
8408d7f2e76SPhilippe Mathieu-Daudé     fclose(f);
8418d7f2e76SPhilippe Mathieu-Daudé }
8428d7f2e76SPhilippe Mathieu-Daudé 
qmp_pmemsave(uint64_t addr,uint64_t size,const char * filename,Error ** errp)843*ef71d820SJosh Junon void qmp_pmemsave(uint64_t addr, uint64_t size, const char *filename,
8448d7f2e76SPhilippe Mathieu-Daudé                   Error **errp)
8458d7f2e76SPhilippe Mathieu-Daudé {
8468d7f2e76SPhilippe Mathieu-Daudé     FILE *f;
847*ef71d820SJosh Junon     uint64_t l;
8488d7f2e76SPhilippe Mathieu-Daudé     uint8_t buf[1024];
8498d7f2e76SPhilippe Mathieu-Daudé 
8508d7f2e76SPhilippe Mathieu-Daudé     f = fopen(filename, "wb");
8518d7f2e76SPhilippe Mathieu-Daudé     if (!f) {
8528d7f2e76SPhilippe Mathieu-Daudé         error_setg_file_open(errp, errno, filename);
8538d7f2e76SPhilippe Mathieu-Daudé         return;
8548d7f2e76SPhilippe Mathieu-Daudé     }
8558d7f2e76SPhilippe Mathieu-Daudé 
8568d7f2e76SPhilippe Mathieu-Daudé     while (size != 0) {
8578d7f2e76SPhilippe Mathieu-Daudé         l = sizeof(buf);
8588d7f2e76SPhilippe Mathieu-Daudé         if (l > size)
8598d7f2e76SPhilippe Mathieu-Daudé             l = size;
8608d7f2e76SPhilippe Mathieu-Daudé         cpu_physical_memory_read(addr, buf, l);
8618d7f2e76SPhilippe Mathieu-Daudé         if (fwrite(buf, 1, l, f) != l) {
862c59fb13bSMarkus Armbruster             error_setg(errp, "writing memory to '%s' failed",
863c59fb13bSMarkus Armbruster                        filename);
8648d7f2e76SPhilippe Mathieu-Daudé             goto exit;
8658d7f2e76SPhilippe Mathieu-Daudé         }
8668d7f2e76SPhilippe Mathieu-Daudé         addr += l;
8678d7f2e76SPhilippe Mathieu-Daudé         size -= l;
8688d7f2e76SPhilippe Mathieu-Daudé     }
8698d7f2e76SPhilippe Mathieu-Daudé 
8708d7f2e76SPhilippe Mathieu-Daudé exit:
8718d7f2e76SPhilippe Mathieu-Daudé     fclose(f);
8728d7f2e76SPhilippe Mathieu-Daudé }
8738d7f2e76SPhilippe Mathieu-Daudé 
qmp_inject_nmi(Error ** errp)8748d7f2e76SPhilippe Mathieu-Daudé void qmp_inject_nmi(Error **errp)
8758d7f2e76SPhilippe Mathieu-Daudé {
8768d7f2e76SPhilippe Mathieu-Daudé     nmi_monitor_handle(monitor_get_cpu_index(monitor_cur()), errp);
8778d7f2e76SPhilippe Mathieu-Daudé }
8788d7f2e76SPhilippe Mathieu-Daudé 
879