If the machine is stopped, we should not record two different tsc values
upon a save operation. The same problem happens with kvmclock.
But kvmclock is taking a different diretion, being now seen as a separate
device. Since this is unlikely to happen with the tsc, I am taking the
approach here of simply registering a handler for state change, and
using a per-CPUState variable that prevents double updates for the TSC.
Signed-off-by: Glauber Costa <[email protected]>
CC: Jan Kiszka <[email protected]>
Signed-off-by: Marcelo Tosatti <[email protected]>
uint32_t sipi_vector;
uint32_t cpuid_kvm_features;
uint32_t cpuid_svm_features;
+ bool tsc_valid;
/* in order to simplify APIC support, we leave this pointer to the
user */
#endif
}
+static void cpu_update_state(void *opaque, int running, int reason)
+{
+ CPUState *env = opaque;
+
+ if (running) {
+ env->tsc_valid = false;
+ }
+}
+
int kvm_arch_init_vcpu(CPUState *env)
{
struct {
}
#endif
+ qemu_add_vm_change_state_handler(cpu_update_state, env);
+
return kvm_vcpu_ioctl(env, KVM_SET_CPUID2, &cpuid_data);
}
if (has_msr_hsave_pa) {
msrs[n++].index = MSR_VM_HSAVE_PA;
}
- msrs[n++].index = MSR_IA32_TSC;
+
+ if (!env->tsc_valid) {
+ msrs[n++].index = MSR_IA32_TSC;
+ env->tsc_valid = !vm_running;
+ }
+
#ifdef TARGET_X86_64
if (lm_capable_kernel) {
msrs[n++].index = MSR_CSTAR;