KVM: x86: disable master clock if TSC is reset during suspend
Updating system_time from the kernel clock once master clock has been enabled can result in time backwards event, in case kernel clock frequency is lower than TSC frequency.
Disable master clock in case its necessary to update it from the resume path.
arch/x86/kvm/x86.c +5 -0
@@ -106,6 +106,8 @@ EXPORT_SYMBOL_GPL(kvm_max_guest_tsc_khz);static u32 tsc_tolerance_ppm =250 ;module_param (tsc_tolerance_ppm, uint,S_IRUGO |S_IWUSR ); +static bool suspend_backwards_tsc = false; +#define KVM_NR_SHARED_MSRS 16struct kvm_shared_msrs_global {
@@ -1472,6 +1474,8 @@ static void pvclock_update_vm_gtod_copy(struct kvm *kvm) &ka->master_cycle_now); ka->use_master_clock = host_tsc_clocksource & vcpus_matched; +if (suspend_backwards_tsc) + ka->use_master_clock =0 ;if (ka->use_master_clock)atomic_set (&kvm_guest_has_master_clock,1 );
@@ -6939,6 +6943,7 @@ int kvm_arch_hardware_enable(void *garbage)*/ if (backwards_tsc) {u64 delta_cyc = max_tsc - local_tsc; + suspend_backwards_tsc = true;list_for_each_entry (kvm, &vm_list, vm_list) {kvm_for_each_vcpu (i, vcpu, kvm) { vcpu->arch.tsc_offset_adjustment += delta_cyc;
Paolo Bonzini
maintainerIl 14/05/2014 09:26, Marcelo Tosatti ha scritto:
Quoted 24 lines
Updating
system_timefrom the kernel clock once master clock has been enabled can result in time backwards event, in case kernel clock frequency is lower than TSC frequency.Disable master clock in case its necessary to update it from the resume path.
Signed-off-by Marcelo Tosatti <[email protected]>arch/x86/kvm/x86.c +2
-0@@ -106,6 +106,8 @@ EXPORT_SYMBOL_GPL(kvm_max_guest_tsc_khz);static u32 tsc_tolerance_ppm =250 ;module_param (tsc_tolerance_ppm, uint,S_IRUGO |S_IWUSR ); +static bool suspend_backwards_tsc = false; +#define KVM_NR_SHARED_MSRS 16struct kvm_shared_msrs_global {
arch/x86/kvm/x86.c static void pvclock_update_vm_gtod_copy(struct kvm *kvm) · line 1478
Quoted 5 lines
arch/x86/kvm/x86.c +2
-0@@ -1472,6 +1474,8 @@ static void pvclock_update_vm_gtod_copy(struct kvm *kvm) &ka->master_cycle_now); ka->use_master_clock = host_tsc_clocksource & vcpus_matched; +if (suspend_backwards_tsc) + ka->use_master_clock =0 ;
Use an && instead of an "if"? (Also, why "&" in the other assignment of ka->use_master_clock)?
arch/x86/kvm/x86.c int kvm_arch_hardware_enable(void *garbage) · line 6949
Quoted 11 lines
arch/x86/kvm/x86.c +1
-0if (ka->use_master_clock)atomic_set (&kvm_guest_has_master_clock,1 );@@ -6939,6 +6943,7 @@ int kvm_arch_hardware_enable(void *garbage)*/ if (backwards_tsc) {u64 delta_cyc = max_tsc - local_tsc; + suspend_backwards_tsc = true;list_for_each_entry (kvm, &vm_list, vm_list) {kvm_for_each_vcpu (i, vcpu, kvm) { vcpu->arch.tsc_offset_adjustment += delta_cyc;
Why a global and not a variable inside kvm? The same question holds for kvm_guest_has_master_clock.
Paolo
Quoted 27 lines · Paolo Bonzini
Il 14/05/2014 09:26, Marcelo Tosatti ha scritto:
Quoted 26 lines
Updating
system_timefrom the kernel clock once master clock has been enabled can result in time backwards event, in case kernel clock frequency is lower than TSC frequency.Disable master clock in case its necessary to update it from the resume path.
Signed-off-by Marcelo Tosatti <[email protected]>arch/x86/kvm/x86.c +2
-0@@ -106,6 +106,8 @@ EXPORT_SYMBOL_GPL(kvm_max_guest_tsc_khz);static u32 tsc_tolerance_ppm =250 ;module_param (tsc_tolerance_ppm, uint,S_IRUGO |S_IWUSR ); +static bool suspend_backwards_tsc = false; +#define KVM_NR_SHARED_MSRS 16struct kvm_shared_msrs_global {@@ -1472,6 +1474,8 @@ static void pvclock_update_vm_gtod_copy(struct kvm *kvm) &ka->master_cycle_now);
Quoted 6 lines
arch/x86/kvm/x86.c static void pvclock_update_vm_gtod_copy(struct kvm *kvm) · line 1478
Quoted 3 lines
arch/x86/kvm/x86.c +2
-0ka->use_master_clock = host_tsc_clocksource & vcpus_matched; +if (suspend_backwards_tsc) + ka->use_master_clock =0 ;Use an && instead of an "if"? (Also, why "&" in the other assignment of
ka->use_master_clock)?
I was asking myself the same.
Quoted 6 lines
Quoted 6 lines
arch/x86/kvm/x86.c +0
-0if (ka->use_master_clock)atomic_set (&kvm_guest_has_master_clock,1 );@@ -6939,6 +6943,7 @@ int kvm_arch_hardware_enable(void *garbage)*/ if (backwards_tsc) {u64 delta_cyc = max_tsc - local_tsc;
Quoted 8 lines
arch/x86/kvm/x86.c int kvm_arch_hardware_enable(void *garbage) · line 6949
Quoted 5 lines
arch/x86/kvm/x86.c +1
-0+ suspend_backwards_tsc = true;list_for_each_entry (kvm, &vm_list, vm_list) {kvm_for_each_vcpu (i, vcpu, kvm) { vcpu->arch.tsc_offset_adjustment += delta_cyc;Why a global and not a variable inside kvm? The same question holds for
kvm_guest_has_master_clock.
Because these are global properties: reset-tsc-on-suspend is global, kvm_guest_has_master_clock is global.
KVM: x86: disable master clock if TSC is reset during suspend (v2)
In reply to Paolo BonziniUpdating system_time from the kernel clock once master clock has been enabled can result in time backwards event, in case kernel clock frequency is lower than TSC frequency.
Disable master clock in case its necessary to update it from the resume path.
arch/x86/kvm/x86.c +5 -1
@@ -106,6 +106,8 @@ EXPORT_SYMBOL_GPL(kvm_max_guest_tsc_khz);static u32 tsc_tolerance_ppm =250 ;module_param (tsc_tolerance_ppm, uint,S_IRUGO |S_IWUSR ); +static bool suspend_backwards_tsc = false; +#define KVM_NR_SHARED_MSRS 16struct kvm_shared_msrs_global {
@@ -1471,7 +1473,8 @@ static void pvclock_update_vm_gtod_copy(struct kvm *kvm) &ka->master_kernel_ns, &ka->master_cycle_now); - ka->use_master_clock = host_tsc_clocksource & vcpus_matched; + ka->use_master_clock = host_tsc_clocksource && vcpus_matched + && suspend_backwards_tsc;if (ka->use_master_clock)atomic_set (&kvm_guest_has_master_clock,1 );
@@ -6939,6 +6942,7 @@ int kvm_arch_hardware_enable(void *garbage)*/ if (backwards_tsc) {u64 delta_cyc = max_tsc - local_tsc; + suspend_backwards_tsc = true;list_for_each_entry (kvm, &vm_list, vm_list) {kvm_for_each_vcpu (i, vcpu, kvm) { vcpu->arch.tsc_offset_adjustment += delta_cyc;
Paolo Bonzini
maintainerRe: KVM: x86: disable master clock if TSC is reset during suspend (v2)
Il 14/05/2014 12:06, Marcelo Tosatti ha scritto:
Quoted 24 lines
Updating
system_timefrom the kernel clock once master clock has been enabled can result in time backwards event, in case kernel clock frequency is lower than TSC frequency.Disable master clock in case its necessary to update it from the resume path.
Signed-off-by Marcelo Tosatti <[email protected]>arch/x86/kvm/x86.c +2
-0@@ -106,6 +106,8 @@ EXPORT_SYMBOL_GPL(kvm_max_guest_tsc_khz);static u32 tsc_tolerance_ppm =250 ;module_param (tsc_tolerance_ppm, uint,S_IRUGO |S_IWUSR ); +static bool suspend_backwards_tsc = false; +#define KVM_NR_SHARED_MSRS 16struct kvm_shared_msrs_global {
arch/x86/kvm/x86.c static void pvclock_update_vm_gtod_copy(struct kvm *kvm) · line 1477
Quoted 6 lines
arch/x86/kvm/x86.c +2
-1@@ -1471,7 +1473,8 @@ static void pvclock_update_vm_gtod_copy(struct kvm *kvm) &ka->master_kernel_ns, &ka->master_cycle_now); - ka->use_master_clock = host_tsc_clocksource & vcpus_matched; + ka->use_master_clock = host_tsc_clocksource && vcpus_matched + && suspend_backwards_tsc;
Missing "!" here. Also, perhaps "backwards_tsc_observed" is a better name for the variable?
Paolo
Quoted 12 lines
arch/x86/kvm/x86.c +1
-0if (ka->use_master_clock)atomic_set (&kvm_guest_has_master_clock,1 );@@ -6939,6 +6942,7 @@ int kvm_arch_hardware_enable(void *garbage)*/ if (backwards_tsc) {u64 delta_cyc = max_tsc - local_tsc; + suspend_backwards_tsc = true;list_for_each_entry (kvm, &vm_list, vm_list) {kvm_for_each_vcpu (i, vcpu, kvm) { vcpu->arch.tsc_offset_adjustment += delta_cyc;
KVM: x86: disable master clock if TSC is reset during suspend (v3)
Updating system_time from the kernel clock once master clock has been enabled can result in time backwards event, in case kernel clock frequency is lower than TSC frequency.
Disable master clock in case its necessary to update it from the resume path.
arch/x86/kvm/x86.c +5 -1
@@ -106,6 +106,8 @@ EXPORT_SYMBOL_GPL(kvm_max_guest_tsc_khz);static u32 tsc_tolerance_ppm =250 ;module_param (tsc_tolerance_ppm, uint,S_IRUGO |S_IWUSR ); +static bool backwards_tsc_observed = false; +#define KVM_NR_SHARED_MSRS 16struct kvm_shared_msrs_global {
@@ -1471,7 +1473,8 @@ static void pvclock_update_vm_gtod_copy(struct kvm *kvm) &ka->master_kernel_ns, &ka->master_cycle_now); - ka->use_master_clock = host_tsc_clocksource & vcpus_matched; + ka->use_master_clock = host_tsc_clocksource && vcpus_matched + && !backwards_tsc_observed;if (ka->use_master_clock)atomic_set (&kvm_guest_has_master_clock,1 );
@@ -6939,6 +6942,7 @@ int kvm_arch_hardware_enable(void *garbage)*/ if (backwards_tsc) {u64 delta_cyc = max_tsc - local_tsc; + backwards_tsc_observed = true;list_for_each_entry (kvm, &vm_list, vm_list) {kvm_for_each_vcpu (i, vcpu, kvm) { vcpu->arch.tsc_offset_adjustment += delta_cyc;
Paolo Bonzini
maintainerRe: KVM: x86: disable master clock if TSC is reset during suspend (v3)
Il 14/05/2014 17:43, Marcelo Tosatti ha scritto:
Quoted 35 lines
Updating
system_timefrom the kernel clock once master clock has been enabled can result in time backwards event, in case kernel clock frequency is lower than TSC frequency.Disable master clock in case its necessary to update it from the resume path.
Signed-off-by Marcelo Tosatti <[email protected]>arch/x86/kvm/x86.c +4
-1@@ -106,6 +106,8 @@ EXPORT_SYMBOL_GPL(kvm_max_guest_tsc_khz);static u32 tsc_tolerance_ppm =250 ;module_param (tsc_tolerance_ppm, uint,S_IRUGO |S_IWUSR ); +static bool backwards_tsc_observed = false; +#define KVM_NR_SHARED_MSRS 16struct kvm_shared_msrs_global {@@ -1471,7 +1473,8 @@ static void pvclock_update_vm_gtod_copy(struct kvm *kvm) &ka->master_kernel_ns, &ka->master_cycle_now); - ka->use_master_clock = host_tsc_clocksource & vcpus_matched; + ka->use_master_clock = host_tsc_clocksource && vcpus_matched + && !backwards_tsc_observed;if (ka->use_master_clock)atomic_set (&kvm_guest_has_master_clock,1 );
arch/x86/kvm/x86.c int kvm_arch_hardware_enable(void *garbage) · line 6948
Quoted 7 lines
arch/x86/kvm/x86.c +1
-0@@ -6939,6 +6942,7 @@ int kvm_arch_hardware_enable(void *garbage)*/ if (backwards_tsc) {u64 delta_cyc = max_tsc - local_tsc; + backwards_tsc_observed = true;list_for_each_entry (kvm, &vm_list, vm_list) {kvm_for_each_vcpu (i, vcpu, kvm) { vcpu->arch.tsc_offset_adjustment += delta_cyc;
Applying to kvm/master, thanks.
Paolo
Re: KVM: x86: disable master clock if TSC is reset during suspend (v3)
Quoted 33 lines · Paolo Bonzini
Il 14/05/2014 17:43, Marcelo Tosatti ha scritto:
Quoted 32 lines
Updating
system_timefrom the kernel clock once master clock has been enabled can result in time backwards event, in case kernel clock frequency is lower than TSC frequency.Disable master clock in case its necessary to update it from the resume path.
Signed-off-by Marcelo Tosatti <[email protected]>arch/x86/kvm/x86.c +4
-1@@ -106,6 +106,8 @@ EXPORT_SYMBOL_GPL(kvm_max_guest_tsc_khz);static u32 tsc_tolerance_ppm =250 ;module_param (tsc_tolerance_ppm, uint,S_IRUGO |S_IWUSR ); +static bool backwards_tsc_observed = false; +#define KVM_NR_SHARED_MSRS 16struct kvm_shared_msrs_global {@@ -1471,7 +1473,8 @@ static void pvclock_update_vm_gtod_copy(struct kvm *kvm) &ka->master_kernel_ns, &ka->master_cycle_now); - ka->use_master_clock = host_tsc_clocksource & vcpus_matched; + ka->use_master_clock = host_tsc_clocksource && vcpus_matched + && !backwards_tsc_observed;
Quoted 13 lines
arch/x86/kvm/x86.c int kvm_arch_hardware_enable(void *garbage) · line 6948
Quoted 11 lines
arch/x86/kvm/x86.c +0
-0if (ka->use_master_clock)atomic_set(&kvm_guest_has_master_clock, 1);arch/x86/kvm/x86.c +1
-0@@ -6939,6 +6942,7 @@ int kvm_arch_hardware_enable(void *garbage)*/ if (backwards_tsc) {u64 delta_cyc = max_tsc - local_tsc; + backwards_tsc_observed = true;list_for_each_entry (kvm, &vm_list, vm_list) {kvm_for_each_vcpu (i, vcpu, kvm) { vcpu->arch.tsc_offset_adjustment += delta_cyc;Applying to kvm/master, thanks.
Thanks. Can you please make sure to CC qemu-stable when sending a pull request?
Alex
Paolo Bonzini
maintainerRe: KVM: x86: disable master clock if TSC is reset during suspend (v3)
Il 21/05/2014 10:26, Alexander Graf ha scritto:
Quoted 49 lines · Paolo Bonzini
Quoted 33 lines
Il 14/05/2014 17:43, Marcelo Tosatti ha scritto:
Quoted 32 lines
Updating
system_timefrom the kernel clock once master clock has been enabled can result in time backwards event, in case kernel clock frequency is lower than TSC frequency.Disable master clock in case its necessary to update it from the resume path.
Signed-off-by Marcelo Tosatti <[email protected]>arch/x86/kvm/x86.c +4
-1@@ -106,6 +106,8 @@ EXPORT_SYMBOL_GPL(kvm_max_guest_tsc_khz);static u32 tsc_tolerance_ppm =250 ;module_param (tsc_tolerance_ppm, uint,S_IRUGO |S_IWUSR ); +static bool backwards_tsc_observed = false; +#define KVM_NR_SHARED_MSRS 16struct kvm_shared_msrs_global {@@ -1471,7 +1473,8 @@ static void pvclock_update_vm_gtod_copy(struct kvm *kvm) &ka->master_kernel_ns, &ka->master_cycle_now); - ka->use_master_clock = host_tsc_clocksource & vcpus_matched; + ka->use_master_clock = host_tsc_clocksource && vcpus_matched + && !backwards_tsc_observed;Quoted 13 lines
arch/x86/kvm/x86.c int kvm_arch_hardware_enable(void *garbage) · line 6948
Quoted 11 lines
arch/x86/kvm/x86.c +0
-0if (ka->use_master_clock)atomic_set(&kvm_guest_has_master_clock, 1);arch/x86/kvm/x86.c +1
-0@@ -6939,6 +6942,7 @@ int kvm_arch_hardware_enable(void *garbage)*/ if (backwards_tsc) {u64 delta_cyc = max_tsc - local_tsc; + backwards_tsc_observed = true;list_for_each_entry (kvm, &vm_list, vm_list) {kvm_for_each_vcpu (i, vcpu, kvm) { vcpu->arch.tsc_offset_adjustment += delta_cyc;Applying to kvm/master, thanks.
Quoted 2 lines
Thanks. Can you please make sure to CC qemu-stable when sending a pull request?
Now I will.
Paolo :)