}
static void audio_vm_change_state_handler (void *opaque, int running,
- int reason)
+ RunState state)
{
AudioState *s = opaque;
HWVoiceOut *hwo = NULL;
return !vm_running || env->stopped;
}
-static void do_vm_stop(int reason)
+static void do_vm_stop(RunState state)
{
if (vm_running) {
cpu_disable_ticks();
vm_running = 0;
pause_all_vcpus();
- vm_state_notify(0, reason);
+ vm_state_notify(0, state);
qemu_aio_flush();
bdrv_flush_all();
monitor_protocol_event(QEVENT_STOP, NULL);
}
}
-void vm_stop(int reason)
+void vm_stop(RunState state)
{
if (!qemu_thread_is_self(&io_thread)) {
- qemu_system_vmstop_request(reason);
+ qemu_system_vmstop_request(state);
/*
* FIXME: should not return to device code in case
* vm_stop() has been requested.
cpu_stop_current();
return;
}
- do_vm_stop(reason);
+ do_vm_stop(state);
}
static int tcg_cpu_exec(CPUState *env)
}
#ifndef CONFIG_USER_ONLY
-static void gdb_vm_state_change(void *opaque, int running, int reason)
+static void gdb_vm_state_change(void *opaque, int running, RunState state)
{
GDBState *s = gdbserver_state;
CPUState *env = s->c_cpu;
if (running || s->state == RS_INACTIVE || s->state == RS_SYSCALL) {
return;
}
- switch (reason) {
- case VMSTOP_DEBUG:
+ switch (state) {
+ case RSTATE_DEBUG:
if (env->watchpoint_hit) {
switch (env->watchpoint_hit->flags & BP_MEM_ACCESS) {
case BP_MEM_READ:
tb_flush(env);
ret = GDB_SIGNAL_TRAP;
break;
- case VMSTOP_USER:
+ case RSTATE_PAUSED:
ret = GDB_SIGNAL_INT;
break;
- case VMSTOP_SHUTDOWN:
+ case RSTATE_SHUTDOWN:
ret = GDB_SIGNAL_QUIT;
break;
- case VMSTOP_DISKFULL:
+ case RSTATE_IO_ERROR:
ret = GDB_SIGNAL_IO;
break;
- case VMSTOP_WATCHDOG:
+ case RSTATE_WATCHDOG:
ret = GDB_SIGNAL_ALRM;
break;
- case VMSTOP_PANIC:
+ case RSTATE_PANICKED:
ret = GDB_SIGNAL_ABRT;
break;
- case VMSTOP_SAVEVM:
- case VMSTOP_LOADVM:
+ case RSTATE_SAVEVM:
+ case RSTATE_RESTORE:
return;
- case VMSTOP_MIGRATE:
+ case RSTATE_PRE_MIGRATE:
ret = GDB_SIGNAL_XCPU;
break;
default:
gdb_current_syscall_cb = cb;
s->state = RS_SYSCALL;
#ifndef CONFIG_USER_ONLY
- vm_stop(VMSTOP_DEBUG);
+ vm_stop(RSTATE_DEBUG);
#endif
s->state = RS_IDLE;
va_start(va, fmt);
if (vm_running) {
/* when the CPU is running, we cannot do anything except stop
it when receiving a char */
- vm_stop(VMSTOP_USER);
+ vm_stop(RSTATE_PAUSED);
} else
#endif
{
{
switch (event) {
case CHR_EVENT_OPENED:
- vm_stop(VMSTOP_USER);
+ vm_stop(RSTATE_PAUSED);
gdb_has_xml = 0;
break;
default:
static void gdb_sigterm_handler(int signal)
{
if (vm_running) {
- vm_stop(VMSTOP_USER);
+ vm_stop(RSTATE_PAUSED);
}
}
#endif
{
}
-static void ahci_dma_restart_cb(void *opaque, int running, int reason)
+static void ahci_dma_restart_cb(void *opaque, int running, RunState state)
{
}
s->bus->dma->ops->set_unit(s->bus->dma, s->unit);
s->bus->error_status = op;
bdrv_mon_event(s->bs, BDRV_ACTION_STOP, is_read);
- vm_stop(VMSTOP_DISKFULL);
+ vm_stop(RSTATE_IO_ERROR);
} else {
if (op & BM_STATUS_DMA_RETRY) {
dma_buf_commit(s, 0);
return 0;
}
-static void ide_nop_restart(void *opaque, int x, int y)
+static void ide_nop_restart(void *opaque, int x, RunState y)
{
}
#include <hw/ide.h>
#include "iorange.h"
#include "dma.h"
+#include "sysemu.h"
/* debug IDE devices */
//#define DEBUG_IDE
typedef void DMAStartFunc(IDEDMA *, IDEState *, BlockDriverCompletionFunc *);
typedef int DMAFunc(IDEDMA *);
typedef int DMAIntFunc(IDEDMA *, int);
-typedef void DMARestartFunc(void *, int, int);
+typedef void DMARestartFunc(void *, int, RunState);
struct unreported_events {
bool eject_request;
}
}
-static void bmdma_restart_cb(void *opaque, int running, int reason)
+static void bmdma_restart_cb(void *opaque, int running, RunState state)
{
IDEDMA *dma = opaque;
BMDMAState *bm = DO_UPCAST(BMDMAState, dma, dma);
return kvm_vm_ioctl(kvm_state, KVM_SET_CLOCK, &data);
}
-static void kvmclock_vm_state_change(void *opaque, int running, int reason)
+static void kvmclock_vm_state_change(void *opaque, int running,
+ RunState state)
{
KVMClockState *s = opaque;
}
}
-static void qxl_vm_change_state_handler(void *opaque, int running, int reason)
+static void qxl_vm_change_state_handler(void *opaque, int running,
+ RunState state)
{
PCIQXLDevice *qxl = opaque;
- qemu_spice_vm_change_state_handler(&qxl->ssd, running, reason);
+ qemu_spice_vm_change_state_handler(&qxl->ssd, running, state);
if (running) {
/*
r->status |= SCSI_REQ_STATUS_RETRY | type;
bdrv_mon_event(s->bs, BDRV_ACTION_STOP, is_read);
- vm_stop(VMSTOP_DISKFULL);
+ vm_stop(RSTATE_IO_ERROR);
} else {
switch (error) {
case ENOMEM:
}
}
-static void scsi_dma_restart_cb(void *opaque, int running, int reason)
+static void scsi_dma_restart_cb(void *opaque, int running, RunState state)
{
SCSIDiskState *s = opaque;
req->next = s->rq;
s->rq = req;
bdrv_mon_event(s->bs, BDRV_ACTION_STOP, is_read);
- vm_stop(VMSTOP_DISKFULL);
+ vm_stop(RSTATE_IO_ERROR);
} else {
virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
bdrv_acct_done(s->bs, &req->acct);
virtio_submit_multiwrite(s->bs, &mrb);
}
-static void virtio_blk_dma_restart_cb(void *opaque, int running, int reason)
+static void virtio_blk_dma_restart_cb(void *opaque, int running,
+ RunState state)
{
VirtIOBlock *s = opaque;
g_free(vdev);
}
-static void virtio_vmstate_change(void *opaque, int running, int reason)
+static void virtio_vmstate_change(void *opaque, int running, RunState state)
{
VirtIODevice *vdev = opaque;
bool backend_run = running && (vdev->status & VIRTIO_CONFIG_S_DRIVER_OK);
case WDT_PAUSE: /* same as 'stop' command in monitor */
watchdog_mon_event("pause");
- vm_stop(VMSTOP_WATCHDOG);
+ vm_stop(RSTATE_WATCHDOG);
break;
case WDT_DEBUG:
if (ret < 0) {
cpu_dump_state(env, stderr, fprintf, CPU_DUMP_CODE);
- vm_stop(VMSTOP_PANIC);
+ vm_stop(RSTATE_PANICKED);
}
env->exit_request = 0;
int old_vm_running = vm_running;
DPRINTF("done iterating\n");
- vm_stop(VMSTOP_MIGRATE);
+ vm_stop(RSTATE_PRE_MIGRATE);
if ((qemu_savevm_state_complete(s->mon, s->file)) < 0) {
if (old_vm_running) {
*/
static int do_stop(Monitor *mon, const QDict *qdict, QObject **ret_data)
{
- vm_stop(VMSTOP_USER);
+ vm_stop(RSTATE_PAUSED);
return 0;
}
int saved_vm_running = vm_running;
const char *name = qdict_get_str(qdict, "name");
- vm_stop(VMSTOP_LOADVM);
+ vm_stop(RSTATE_RESTORE);
if (load_vmstate(name) == 0 && saved_vm_running) {
vm_start();
#endif /* _WIN32 */
-static void alarm_timer_on_change_state_rearm(void *opaque, int running, int reason)
+static void alarm_timer_on_change_state_rearm(void *opaque, int running,
+ RunState state)
{
if (running)
qemu_rearm_alarm_timer((struct qemu_alarm_timer *) opaque);
int ret;
saved_vm_running = vm_running;
- vm_stop(VMSTOP_SAVEVM);
+ vm_stop(RSTATE_SAVEVM);
if (qemu_savevm_state_blocked(mon)) {
ret = -EINVAL;
}
saved_vm_running = vm_running;
- vm_stop(VMSTOP_SAVEVM);
+ vm_stop(RSTATE_SAVEVM);
memset(sn, 0, sizeof(*sn));
#include "notify.h"
/* vl.c */
+
+typedef enum {
+ RSTATE_NO_STATE,
+ RSTATE_DEBUG, /* qemu is running under gdb */
+ RSTATE_PANICKED, /* paused due to an internal error */
+ RSTATE_IO_ERROR, /* paused due to an I/O error */
+ RSTATE_PAUSED, /* paused by the user (ie. the 'stop' command) */
+ RSTATE_PRE_MIGRATE, /* paused preparing to finish migrate */
+ RSTATE_RESTORE, /* paused restoring the VM state */
+ RSTATE_RUNNING, /* qemu is running */
+ RSTATE_SAVEVM, /* paused saving VM state */
+ RSTATE_SHUTDOWN, /* guest shut down and -no-shutdown is in use */
+ RSTATE_WATCHDOG /* watchdog fired and qemu is configured to pause */
+} RunState;
+
extern const char *bios_name;
extern int vm_running;
#define UUID_FMT "%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx"
typedef struct vm_change_state_entry VMChangeStateEntry;
-typedef void VMChangeStateHandler(void *opaque, int running, int reason);
+typedef void VMChangeStateHandler(void *opaque, int running, RunState state);
VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
void *opaque);
void qemu_del_vm_change_state_handler(VMChangeStateEntry *e);
-void vm_state_notify(int running, int reason);
-
-#define VMSTOP_USER 0
-#define VMSTOP_DEBUG 1
-#define VMSTOP_SHUTDOWN 2
-#define VMSTOP_DISKFULL 3
-#define VMSTOP_WATCHDOG 4
-#define VMSTOP_PANIC 5
-#define VMSTOP_SAVEVM 6
-#define VMSTOP_LOADVM 7
-#define VMSTOP_MIGRATE 8
+void vm_state_notify(int running, RunState state);
#define VMRESET_SILENT false
#define VMRESET_REPORT true
void vm_start(void);
-void vm_stop(int reason);
+void vm_stop(RunState state);
void qemu_system_reset_request(void);
void qemu_system_shutdown_request(void);
void qemu_system_powerdown_request(void);
void qemu_system_debug_request(void);
-void qemu_system_vmstop_request(int reason);
+void qemu_system_vmstop_request(RunState reason);
int qemu_shutdown_requested_get(void);
int qemu_reset_requested_get(void);
int qemu_shutdown_requested(void);
return 0;
}
-static void cpu_update_state(void *opaque, int running, int reason)
+static void cpu_update_state(void *opaque, int running, RunState state)
{
CPUState *env = opaque;
qemu_spice_destroy_primary_surface(ssd, 0, QXL_SYNC);
}
-void qemu_spice_vm_change_state_handler(void *opaque, int running, int reason)
+void qemu_spice_vm_change_state_handler(void *opaque, int running,
+ RunState state)
{
SimpleSpiceDisplay *ssd = opaque;
#include "qemu-thread.h"
#include "console.h"
#include "pflib.h"
+#include "sysemu.h"
#define NUM_MEMSLOTS 8
#define MEMSLOT_GENERATION_BITS 8
void qemu_spice_create_host_memslot(SimpleSpiceDisplay *ssd);
void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd);
void qemu_spice_destroy_host_primary(SimpleSpiceDisplay *ssd);
-void qemu_spice_vm_change_state_handler(void *opaque, int running, int reason);
+void qemu_spice_vm_change_state_handler(void *opaque, int running,
+ RunState state);
void qemu_spice_display_init_common(SimpleSpiceDisplay *ssd, DisplayState *ds);
void qemu_spice_display_update(SimpleSpiceDisplay *ssd,
g_free (e);
}
-void vm_state_notify(int running, int reason)
+void vm_state_notify(int running, RunState state)
{
VMChangeStateEntry *e;
- trace_vm_state_notify(running, reason);
+ trace_vm_state_notify(running, state);
for (e = vm_change_state_head.lh_first; e; e = e->entries.le_next) {
- e->cb(e->opaque, running, reason);
+ e->cb(e->opaque, running, state);
}
}
if (!vm_running) {
cpu_enable_ticks();
vm_running = 1;
- vm_state_notify(1, 0);
+ vm_state_notify(1, RSTATE_RUNNING);
resume_all_vcpus();
monitor_protocol_event(QEVENT_RESUME, NULL);
}
static pid_t shutdown_pid;
static int powerdown_requested;
static int debug_requested;
-static int vmstop_requested;
+static RunState vmstop_requested = RSTATE_NO_STATE;
int qemu_shutdown_requested_get(void)
{
return r;
}
-static int qemu_vmstop_requested(void)
+static RunState qemu_vmstop_requested(void)
{
- int r = vmstop_requested;
- vmstop_requested = 0;
- return r;
+ RunState s = vmstop_requested;
+ vmstop_requested = RSTATE_NO_STATE;
+ return s;
}
void qemu_register_reset(QEMUResetHandler *func, void *opaque)
qemu_notify_event();
}
-void qemu_system_vmstop_request(int reason)
+void qemu_system_vmstop_request(RunState state)
{
- vmstop_requested = reason;
+ vmstop_requested = state;
qemu_notify_event();
}
#endif
if (qemu_debug_requested()) {
- vm_stop(VMSTOP_DEBUG);
+ vm_stop(RSTATE_DEBUG);
}
if (qemu_shutdown_requested()) {
qemu_kill_report();
monitor_protocol_event(QEVENT_SHUTDOWN, NULL);
if (no_shutdown) {
- vm_stop(VMSTOP_SHUTDOWN);
+ vm_stop(RSTATE_SHUTDOWN);
} else
break;
}
/* Initialise Xen */
-static void xen_change_state_handler(void *opaque, int running, int reason)
+static void xen_change_state_handler(void *opaque, int running,
+ RunState state)
{
if (running) {
/* record state running */
}
}
-static void xen_hvm_change_state_handler(void *opaque, int running, int reason)
+static void xen_hvm_change_state_handler(void *opaque, int running,
+ RunState rstate)
{
- XenIOState *state = opaque;
+ XenIOState *xstate = opaque;
if (running) {
- xen_main_loop_prepare(state);
+ xen_main_loop_prepare(xstate);
}
}