@@ -97,6 +97,9 @@ void cpu_synchronize_all_post_init(void)
for (cpu = first_cpu; cpu; cpu = cpu->next_cpu) {
cpu_synchronize_post_init(cpu);
}
+ if (kvm_enabled()) {
+ kvmclock_register_savevm();
+ }
}
int cpu_is_stopped(CPUState *env)
@@ -504,6 +504,9 @@ static void kvmclock_pre_save(void *opaque)
{
struct kvm_clock_data *cl = opaque;
+ if (!kvmclock_enabled)
+ return;
+
kvm_vm_ioctl(kvm_state, KVM_GET_CLOCK, cl);
}
@@ -528,6 +531,16 @@ static const VMStateDescription vmstate_kvmclock= {
};
#endif
+/* This has to happen after vcpu setup*/
+void kvmclock_register_savevm(void)
+{
+#ifdef KVM_CAP_ADJUST_CLOCK
+ if (kvmclock_enabled && kvm_check_extension(kvm_state, KVM_CAP_ADJUST_CLOCK)) {
+ vmstate_register(NULL, 0, &vmstate_kvmclock, &kvmclock_data);
+ }
+#endif
+}
+
int kvm_arch_qemu_create_context(void)
{
int r;
@@ -545,12 +558,6 @@ int kvm_arch_qemu_create_context(void)
return -1;
}
-#ifdef KVM_CAP_ADJUST_CLOCK
- if (kvm_check_extension(kvm_state, KVM_CAP_ADJUST_CLOCK)) {
- vmstate_register(NULL, 0, &vmstate_kvmclock, &kvmclock_data);
- }
-#endif
-
r = kvm_set_boot_cpu_id(0);
if (r < 0 && r != -ENOSYS) {
return r;
@@ -752,6 +752,9 @@ int handle_tpr_access(void *opaque, CPUState *env, uint64_t rip,
#define qemu_kvm_cpu_stop(env) do {} while(0)
#endif
+extern int kvmclock_enabled;
+void kvmclock_register_savevm(void);
+
#ifdef CONFIG_KVM
typedef struct KVMSlot {
@@ -293,6 +293,7 @@ void kvm_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
}
static int _kvm_arch_init_vcpu(CPUState *env);
+int kvmclock_enabled = 1;
int kvm_arch_init_vcpu(CPUState *env)
{
@@ -350,6 +351,12 @@ int kvm_arch_init_vcpu(CPUState *env)
memset(c, 0, sizeof(*c));
c->function = KVM_CPUID_FEATURES;
c->eax = env->cpuid_kvm_features & get_para_features(env);
+
+ if (!(c->eax & (1 << KVM_FEATURE_CLOCKSOURCE))) {
+ /* In theory cpuid is per-cpu, and this is a global variable,
+ * but we don't expect kvmclock enabled in some cpus only */
+ kvmclock_enabled = 0;
+ }
#endif
cpu_x86_cpuid(env, 0, 0, &limit, &unused, &unused, &unused);