@@ -410,6 +410,7 @@ struct kvm_arch{
unsigned long irq_sources_bitmap;
u64 vm_init_tsc;
+ s64 kvmclock_offset;
};
struct kvm_vm_stat {
@@ -699,7 +699,8 @@ static void kvm_write_guest_time(struct kvm_vcpu *v)
/* With all the info we got, fill in the values */
vcpu->hv_clock.system_time = ts.tv_nsec +
- (NSEC_PER_SEC * (u64)ts.tv_sec);
+ (NSEC_PER_SEC * (u64)ts.tv_sec) + v->kvm->arch.kvmclock_offset;
+
/*
* The interface expects us to write an even number signaling that the
* update is finished. Since the guest won't see the intermediate
@@ -2437,6 +2438,22 @@ long kvm_arch_vm_ioctl(struct file *filp,
r = 0;
break;
}
+ case KVM_ADJUST_CLOCK: {
+ struct timespec now;
+ u64 now_ns, user_ns;
+ long delta;
+
+ r = -EFAULT;
+ if (copy_from_user(&user_ns, argp, sizeof(user_ns)))
+ goto out;
+
+ r = 0;
+ ktime_get_ts(&now);
+ now_ns = timespec_to_ns(&now) + kvm->arch.kvmclock_offset;
+ delta = user_ns - now_ns;
+ kvm->arch.kvmclock_offset = delta;
+ break;
+ }
default:
;
}
@@ -546,6 +546,7 @@ struct kvm_irqfd {
#define KVM_CREATE_PIT2 _IOW(KVMIO, 0x77, struct kvm_pit_config)
#define KVM_SET_BOOT_CPU_ID _IO(KVMIO, 0x78)
#define KVM_IOEVENTFD _IOW(KVMIO, 0x79, struct kvm_ioeventfd)
+#define KVM_ADJUST_CLOCK _IOW(KVMIO, 0x7a, __u64)
/*
* ioctls for vcpu fds