===================================================================
@@ -4172,8 +4172,9 @@
break;
}
case KVM_SET_CLOCK: {
- struct kvm_clock_data user_ns;
u64 now_ns;
+ struct kvm_clock_data user_ns;
+ struct kvm_arch *ka = &kvm->arch;
r = -EFAULT;
if (copy_from_user(&user_ns, argp, sizeof(user_ns)))
@@ -4184,9 +4185,31 @@
goto out;
r = 0;
- now_ns = get_kvmclock_ns(kvm);
- kvm->arch.kvmclock_offset += user_ns.clock - now_ns;
+
kvm_gen_update_masterclock(kvm);
+ spin_lock(&ka->pvclock_gtod_sync_lock);
+ if (ka->use_master_clock) {
+ int i;
+ struct kvm_vcpu *vcpu;
+
+ /*
+ * In the masterclock enabled case,
+ * kvmclock_offset must be adjusted so that
+ * user_ns.clock = master_kernel_ns + kvmclock_offset
+ * (that is, the value set from KVM_SET_CLOCK is the
+ * one visible at system_timestamp).
+ */
+ kvm->arch.kvmclock_offset = user_ns.clock -
+ ka->master_kernel_ns;
+ spin_unlock(&ka->pvclock_gtod_sync_lock);
+
+ kvm_for_each_vcpu(i, vcpu, kvm)
+ kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu);
+ } else {
+ spin_unlock(&ka->pvclock_gtod_sync_lock);
+ now_ns = get_kvmclock_ns(kvm);
+ kvm->arch.kvmclock_offset += user_ns.clock - now_ns;
+ }
break;
}
case KVM_GET_CLOCK: {
In the masterclock enabled case, kvmclock_offset must be adjusted so that user_ns.clock = master_kernel_ns + kvmclock_offset (that is, the value set from KVM_SET_CLOCK is the one visible at system_timestamp). Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> --- arch/x86/kvm/x86.c | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) v2: grab pvclock_gtod_sync_lock spinlock (Paolo)