This patch removes "static" specifier from several qemu function to make them visible to the replay module. It also invents several system functions that will be used by replay.
Signed-off-by: Pavel Dovgalyuk <pavel.dovga...@ispras.ru> --- cpus.c | 4 ++-- include/exec/exec-all.h | 1 + include/qom/cpu.h | 10 ++++++++++ include/sysemu/cpus.h | 1 + include/sysemu/sysemu.h | 1 + savevm.c | 25 ++++++++++++++++++++----- translate-all.c | 8 ++++++++ 7 files changed, 43 insertions(+), 7 deletions(-) diff --git a/cpus.c b/cpus.c index 0c33458..e53d605 100644 --- a/cpus.c +++ b/cpus.c @@ -88,7 +88,7 @@ static bool cpu_thread_is_idle(CPUState *cpu) return true; } -static bool all_cpu_threads_idle(void) +bool all_cpu_threads_idle(void) { CPUState *cpu; @@ -1112,7 +1112,7 @@ bool qemu_cpu_is_self(CPUState *cpu) return qemu_thread_is_self(cpu->thread); } -static bool qemu_in_vcpu_thread(void) +bool qemu_in_vcpu_thread(void) { return current_cpu && qemu_cpu_is_self(current_cpu); } diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index ab956f2..1d17f75 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -212,6 +212,7 @@ static inline unsigned int tb_phys_hash_func(tb_page_addr_t pc) void tb_free(TranslationBlock *tb); void tb_flush(CPUArchState *env); +void tb_flush_all(void); void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr); #if defined(USE_DIRECT_JUMP) diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 2098f1c..5afb44c 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -480,6 +480,16 @@ static inline bool cpu_has_work(CPUState *cpu) bool qemu_cpu_is_self(CPUState *cpu); /** + * qemu_in_vcpu_thread: + * + * Checks whether the caller is executing on the vCPU thread + * of the current vCPU. + * + * Returns: %true if called from vCPU's thread, %false otherwise. + */ +bool qemu_in_vcpu_thread(void); + +/** * qemu_cpu_kick: * @cpu: The vCPU to kick. * diff --git a/include/sysemu/cpus.h b/include/sysemu/cpus.h index 3f162a9..86ae556 100644 --- a/include/sysemu/cpus.h +++ b/include/sysemu/cpus.h @@ -6,6 +6,7 @@ void qemu_init_cpu_loop(void); void resume_all_vcpus(void); void pause_all_vcpus(void); void cpu_stop_current(void); +bool all_cpu_threads_idle(void); void cpu_synchronize_all_states(void); void cpu_synchronize_all_post_reset(void); diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index 0037a69..72bc093 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -76,6 +76,7 @@ void qemu_add_machine_init_done_notifier(Notifier *notify); void do_savevm(Monitor *mon, const QDict *qdict); int load_vmstate(const char *name); +int save_vmstate(Monitor *mon, const char *name); void do_delvm(Monitor *mon, const QDict *qdict); void do_info_snapshots(Monitor *mon, const QDict *qdict); diff --git a/savevm.c b/savevm.c index 2d8eb96..b4fe8d3 100644 --- a/savevm.c +++ b/savevm.c @@ -42,7 +42,7 @@ #include "qemu/iov.h" #include "block/snapshot.h" #include "block/qapi.h" - +#include "replay/replay.h" #ifndef ETH_P_RARP #define ETH_P_RARP 0x8035 @@ -1039,7 +1039,7 @@ static int del_existing_snapshots(Monitor *mon, const char *name) return 0; } -void do_savevm(Monitor *mon, const QDict *qdict) +int save_vmstate(Monitor *mon, const char *name) { BlockDriverState *bs, *bs1; QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1; @@ -1049,7 +1049,7 @@ void do_savevm(Monitor *mon, const QDict *qdict) uint64_t vm_state_size; qemu_timeval tv; struct tm tm; - const char *name = qdict_get_try_str(qdict, "name"); + int success = 0; /* Verify if there is a device that doesn't support snapshots and is writable */ bs = NULL; @@ -1062,14 +1062,19 @@ void do_savevm(Monitor *mon, const QDict *qdict) if (!bdrv_can_snapshot(bs)) { monitor_printf(mon, "Device '%s' is writable but does not support snapshots.\n", bdrv_get_device_name(bs)); - return; + return success; } } bs = find_vmstate_bs(); if (!bs) { monitor_printf(mon, "No block device can accept snapshots\n"); - return; + if (replay_mode != REPLAY_MODE_NONE) { + fprintf(stderr, + "At least one hdd should be attached to QEMU for replay\n"); + exit(1); + } + return success; } saved_vm_running = runstate_is_running(); @@ -1118,6 +1123,7 @@ void do_savevm(Monitor *mon, const QDict *qdict) /* create the snapshots */ + success = 1; bs1 = NULL; while ((bs1 = bdrv_next(bs1))) { if (bdrv_can_snapshot(bs1)) { @@ -1127,6 +1133,7 @@ void do_savevm(Monitor *mon, const QDict *qdict) if (ret < 0) { monitor_printf(mon, "Error while creating snapshot on '%s'\n", bdrv_get_device_name(bs1)); + success = 0; } } } @@ -1135,6 +1142,14 @@ void do_savevm(Monitor *mon, const QDict *qdict) if (saved_vm_running) { vm_start(); } + + return success; +} + +void do_savevm(Monitor *mon, const QDict *qdict) +{ + const char *name = qdict_get_try_str(qdict, "name"); + save_vmstate(mon, name); } void qmp_xen_save_devices_state(const char *filename, Error **errp) diff --git a/translate-all.c b/translate-all.c index ba5c840..7177b71 100644 --- a/translate-all.c +++ b/translate-all.c @@ -806,6 +806,14 @@ void tb_flush(CPUArchState *env1) tcg_ctx.tb_ctx.tb_flush_count++; } +void tb_flush_all(void) +{ + CPUState *cpu; + for (cpu = first_cpu ; cpu != NULL ; cpu = CPU_NEXT(cpu)) { + tb_flush(cpu->env_ptr); + } +} + #ifdef DEBUG_TB_CHECK static void tb_invalidate_check(target_ulong address)