__u8 pad2[30];
 };
 
+4.27 KVM_GET_CLOCK
+
+Capability: KVM_CAP_ADJUST_CLOCK
+Architectures: x86
+Type: vm ioctl
+Parameters: struct kvm_clock_data (out)
+Returns: 0 on success, -1 on error
+
+Gets the current timestamp of kvmclock as seen by the current guest. In
+conjunction with KVM_SET_CLOCK, it is used to ensure monotonicity on scenarios
+such as migration.
+
+struct kvm_clock_data {
+       __u64 clock;  /* kvmclock current value */
+       __u32 flags;
+       __u32 pad[9];
+};
+
+4.28 KVM_SET_CLOCK
+
+Capability: KVM_CAP_ADJUST_CLOCK
+Architectures: x86
+Type: vm ioctl
+Parameters: struct kvm_clock_data (in)
+Returns: 0 on success, -1 on error
+
+Sets the current timestamp of kvmclock to the valued specific in its parameter.
+In conjunction with KVM_GET_CLOCK, it is used to ensure monotonicity on scenarios
+such as migration.
+
+struct kvm_clock_data {
+       __u64 clock;  /* kvmclock current value */
+       __u32 flags;
+       __u32 pad[9];
+};
+
 5. The kvm_run structure
 
 Application code obtains a pointer to the kvm_run structure by
 
 
        unsigned long irq_sources_bitmap;
        u64 vm_init_tsc;
+       s64 kvmclock_offset;
 
        struct kvm_xen_hvm_config xen_hvm_config;
 };
 
        /* 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
        case KVM_CAP_PIT_STATE2:
        case KVM_CAP_SET_IDENTITY_MAP_ADDR:
        case KVM_CAP_XEN_HVM:
+       case KVM_CAP_ADJUST_CLOCK:
                r = 1;
                break;
        case KVM_CAP_COALESCED_MMIO:
                r = 0;
                break;
        }
+       case KVM_SET_CLOCK: {
+               struct timespec now;
+               struct kvm_clock_data user_ns;
+               u64 now_ns;
+               s64 delta;
+
+               r = -EFAULT;
+               if (copy_from_user(&user_ns, argp, sizeof(user_ns)))
+                       goto out;
+
+               r = -EINVAL;
+               if (user_ns.flags)
+                       goto out;
+
+               r = 0;
+               ktime_get_ts(&now);
+               now_ns = timespec_to_ns(&now);
+               delta = user_ns.clock - now_ns;
+               kvm->arch.kvmclock_offset = delta;
+               break;
+       }
+       case KVM_GET_CLOCK: {
+               struct timespec now;
+               struct kvm_clock_data user_ns;
+               u64 now_ns;
+
+               ktime_get_ts(&now);
+               now_ns = timespec_to_ns(&now);
+               user_ns.clock = kvm->arch.kvmclock_offset + now_ns;
+               user_ns.flags = 0;
+
+               r = -EFAULT;
+               if (copy_to_user(argp, &user_ns, sizeof(user_ns)))
+                       goto out;
+               r = 0;
+               break;
+       }
+
        default:
                ;
        }
 
 #ifdef __KVM_HAVE_XEN_HVM
 #define KVM_CAP_XEN_HVM 38
 #endif
+#define KVM_CAP_ADJUST_CLOCK 39
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
        __u8  pad[20];
 };
 
+struct kvm_clock_data {
+       __u64 clock;
+       __u32 flags;
+       __u32 pad[9];
+};
+
 /*
  * ioctls for VM fds
  */
 #define KVM_SET_BOOT_CPU_ID        _IO(KVMIO, 0x78)
 #define KVM_IOEVENTFD             _IOW(KVMIO, 0x79, struct kvm_ioeventfd)
 #define KVM_XEN_HVM_CONFIG        _IOW(KVMIO, 0x7a, struct kvm_xen_hvm_config)
+#define KVM_SET_CLOCK             _IOW(KVMIO, 0x7b, struct kvm_clock_data)
+#define KVM_GET_CLOCK             _IOR(KVMIO, 0x7c, struct kvm_clock_data)
+
 
 /*
  * ioctls for vcpu fds