Register a notifier for clocksource change event. In case the host switches to clock other than TSC, disable master clock usage. Signed-off-by: Marcelo Tosatti <mtosatti@xxxxxxxxxx> Index: vsyscall/arch/x86/kvm/x86.c =================================================================== --- vsyscall.orig/arch/x86/kvm/x86.c +++ vsyscall/arch/x86/kvm/x86.c @@ -1218,6 +1218,7 @@ static bool kvm_get_time_and_clockread(s return true; } +static atomic_t kvm_guest_has_master_clock = ATOMIC_INIT(0); /* * @@ -1271,6 +1272,8 @@ static void pvclock_update_vm_gtod_copy( ka->use_master_clock = kvm_get_time_and_clockread( &ka->master_kernel_ns, &ka->master_cycle_now); + if (ka->use_master_clock) + atomic_set(&kvm_guest_has_master_clock, 1); vclock_mode = pvclock_gtod_data.clock.vclock_mode; trace_kvm_update_master_clock(ka->use_master_clock, vclock_mode); @@ -5124,6 +5127,44 @@ static void kvm_set_mmio_spte_mask(void) kvm_mmu_set_mmio_spte_mask(mask); } +static void pvclock_gtod_update_fn(struct work_struct *work) +{ + struct kvm *kvm; + struct kvm_vcpu *vcpu; + int i; + + raw_spin_lock(&kvm_lock); + list_for_each_entry(kvm, &vm_list, vm_list) + kvm_for_each_vcpu(i, vcpu, kvm) + set_bit(KVM_REQ_MASTERCLOCK_UPDATE, &vcpu->requests); + atomic_set(&kvm_guest_has_master_clock, 0); + raw_spin_unlock(&kvm_lock); +} + +static DECLARE_WORK(pvclock_gtod_work, pvclock_gtod_update_fn); + +/* + * Notification about pvclock gtod data update. + */ +static int pvclock_gtod_notify(struct notifier_block *nb, unsigned long unused, + void *unused2) +{ + struct pvclock_gtod_data *gtod = &pvclock_gtod_data; + + /* disable master clock if host does not trust, or does not + * use, TSC clocksource + */ + if (gtod->clock.vclock_mode != VCLOCK_TSC && + atomic_read(&kvm_guest_has_master_clock) != 0) + queue_work(system_long_wq, &pvclock_gtod_work); + + return 0; +} + +static struct notifier_block pvclock_gtod_notifier = { + .notifier_call = pvclock_gtod_notify, +}; + int kvm_arch_init(void *opaque) { int r; @@ -5165,6 +5206,8 @@ int kvm_arch_init(void *opaque) host_xcr0 = xgetbv(XCR_XFEATURE_ENABLED_MASK); kvm_lapic_init(); + pvclock_gtod_register_notifier(&pvclock_gtod_notifier); + return 0; out: @@ -5179,6 +5222,7 @@ void kvm_arch_exit(void) cpufreq_unregister_notifier(&kvmclock_cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER); unregister_hotcpu_notifier(&kvmclock_cpu_notifier_block); + pvclock_gtod_unregister_notifier(&pvclock_gtod_notifier); kvm_x86_ops = NULL; kvm_mmu_module_exit(); } -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html