#include "qemu/host-utils.h"
#include "sysemu/sysemu.h"
#include "sysemu/kvm.h"
+#include "sysemu/hw_accel.h"
#include "kvm_i386.h"
#include "hw/sysbus.h"
#include "hw/kvm/clock.h"
+#include "qapi/error.h"
#include <linux/kvm.h>
#include <linux/kvm_para.h>
{
CPUState *cpu = first_cpu;
CPUX86State *env = cpu->env_ptr;
- hwaddr kvmclock_struct_pa = env->system_time_msr & ~1ULL;
+ hwaddr kvmclock_struct_pa;
uint64_t migration_tsc = env->tsc;
struct pvclock_vcpu_time_info time;
uint64_t delta;
uint64_t nsec_hi;
uint64_t nsec;
+ cpu_synchronize_state(cpu);
+
if (!(env->system_time_msr & 1ULL)) {
/* KVM clock not active */
return 0;
}
+ kvmclock_struct_pa = env->system_time_msr & ~1ULL;
cpu_physical_memory_read(kvmclock_struct_pa, &time, sizeof(time));
assert(time.tsc_timestamp <= migration_tsc);
{
KVMClockState *s = KVM_CLOCK(dev);
+ if (!kvm_enabled()) {
+ error_setg(errp, "kvmclock device requires KVM");
+ return;
+ }
+
kvm_update_clock(s);
qemu_add_vm_change_state_handler(kvmclock_vm_state_change, s);
}
};
+/*
+ * When migrating, assume the source has an unreliable
+ * KVM_GET_CLOCK unless told otherwise.
+ */
+static int kvmclock_pre_load(void *opaque)
+{
+ KVMClockState *s = opaque;
+
+ s->clock_is_reliable = false;
+
+ return 0;
+}
+
/*
* When migrating, read the clock just before migration,
* so that the guest clock counts during the events
* final pages of memory (which happens between vm_stop()
* and pre_save()) takes max_downtime.
*/
-static void kvmclock_pre_save(void *opaque)
+static int kvmclock_pre_save(void *opaque)
{
KVMClockState *s = opaque;
kvm_update_clock(s);
+
+ return 0;
}
static const VMStateDescription kvmclock_vmsd = {
.name = "kvmclock",
.version_id = 1,
.minimum_version_id = 1,
+ .pre_load = kvmclock_pre_load,
.pre_save = kvmclock_pre_save,
.fields = (VMStateField[]) {
VMSTATE_UINT64(clock, KVMClockState),