75e972dab5
As a rule, CPU internal state should never be updated when !cpu->kvm_vcpu_dirty (or the HAX equivalent). If that is done, then subsequent calls to cpu_synchronize_state() - usually safe and idempotent - will clobber state. However, we routinely do this during a loadvm or incoming migration. Usually this is called shortly after a reset, which will clear all the cpu dirty flags with cpu_synchronize_all_post_reset(). Nothing is expected to set the dirty flags again before the cpu state is loaded from the incoming stream. This means that it isn't safe to call cpu_synchronize_state() from a post_load handler, which is non-obvious and potentially inconvenient. We could cpu_synchronize_all_state() before the loadvm, but that would be overkill since a) we expect the state to already be synchronized from the reset and b) we expect to completely rewrite the state with a call to cpu_synchronize_all_post_init() at the end of qemu_loadvm_state(). To clear this up, this patch introduces cpu_synchronize_pre_loadvm() and associated helpers, which simply marks the cpu state as dirty without actually changing anything. i.e. it says we want to discard any existing KVM (or HAX) state and replace it with what we're going to load. Cc: Juan Quintela <quintela@redhat.com> Cc: Dave Gilbert <dgilbert@redhat.com> Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Juan Quintela <quintela@redhat.com>
46 lines
1.1 KiB
C
46 lines
1.1 KiB
C
#ifndef QEMU_CPUS_H
|
|
#define QEMU_CPUS_H
|
|
|
|
#include "qemu/timer.h"
|
|
|
|
/* cpus.c */
|
|
bool qemu_in_vcpu_thread(void);
|
|
void qemu_init_cpu_loop(void);
|
|
void resume_all_vcpus(void);
|
|
void pause_all_vcpus(void);
|
|
void cpu_stop_current(void);
|
|
void cpu_ticks_init(void);
|
|
|
|
void configure_icount(QemuOpts *opts, Error **errp);
|
|
extern int use_icount;
|
|
extern int icount_align_option;
|
|
|
|
/* drift information for info jit command */
|
|
extern int64_t max_delay;
|
|
extern int64_t max_advance;
|
|
void dump_drift_info(FILE *f, fprintf_function cpu_fprintf);
|
|
|
|
/* Unblock cpu */
|
|
void qemu_cpu_kick_self(void);
|
|
void qemu_timer_notify_cb(void *opaque, QEMUClockType type);
|
|
|
|
void cpu_synchronize_all_states(void);
|
|
void cpu_synchronize_all_post_reset(void);
|
|
void cpu_synchronize_all_post_init(void);
|
|
void cpu_synchronize_all_pre_loadvm(void);
|
|
|
|
void qtest_clock_warp(int64_t dest);
|
|
|
|
#ifndef CONFIG_USER_ONLY
|
|
/* vl.c */
|
|
/* *-user doesn't have configurable SMP topology */
|
|
extern int smp_cores;
|
|
extern int smp_threads;
|
|
#endif
|
|
|
|
void list_cpus(FILE *f, fprintf_function cpu_fprintf, const char *optarg);
|
|
|
|
void qemu_tcg_configure(QemuOpts *opts, Error **errp);
|
|
|
|
#endif
|