aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/kvm/api.txt36
-rw-r--r--arch/x86/include/asm/kvm_host.h1
-rw-r--r--arch/x86/kvm/x86.c42
-rw-r--r--include/linux/kvm.h10
4 files changed, 88 insertions, 1 deletions
diff --git a/Documentation/kvm/api.txt b/Documentation/kvm/api.txt
index 3e8684e48506..36594ba57723 100644
--- a/Documentation/kvm/api.txt
+++ b/Documentation/kvm/api.txt
@@ -617,6 +617,42 @@ struct kvm_xen_hvm_config {
617 __u8 pad2[30]; 617 __u8 pad2[30];
618}; 618};
619 619
6204.27 KVM_GET_CLOCK
621
622Capability: KVM_CAP_ADJUST_CLOCK
623Architectures: x86
624Type: vm ioctl
625Parameters: struct kvm_clock_data (out)
626Returns: 0 on success, -1 on error
627
628Gets the current timestamp of kvmclock as seen by the current guest. In
629conjunction with KVM_SET_CLOCK, it is used to ensure monotonicity on scenarios
630such as migration.
631
632struct kvm_clock_data {
633 __u64 clock; /* kvmclock current value */
634 __u32 flags;
635 __u32 pad[9];
636};
637
6384.28 KVM_SET_CLOCK
639
640Capability: KVM_CAP_ADJUST_CLOCK
641Architectures: x86
642Type: vm ioctl
643Parameters: struct kvm_clock_data (in)
644Returns: 0 on success, -1 on error
645
646Sets the current timestamp of kvmclock to the valued specific in its parameter.
647In conjunction with KVM_GET_CLOCK, it is used to ensure monotonicity on scenarios
648such as migration.
649
650struct kvm_clock_data {
651 __u64 clock; /* kvmclock current value */
652 __u32 flags;
653 __u32 pad[9];
654};
655
6205. The kvm_run structure 6565. The kvm_run structure
621 657
622Application code obtains a pointer to the kvm_run structure by 658Application code obtains a pointer to the kvm_run structure by
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 4d994ad5051a..0558ff8c32ae 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -413,6 +413,7 @@ struct kvm_arch{
413 413
414 unsigned long irq_sources_bitmap; 414 unsigned long irq_sources_bitmap;
415 u64 vm_init_tsc; 415 u64 vm_init_tsc;
416 s64 kvmclock_offset;
416 417
417 struct kvm_xen_hvm_config xen_hvm_config; 418 struct kvm_xen_hvm_config xen_hvm_config;
418}; 419};
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 13f30aac460b..e16cdc9ec0c1 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -680,7 +680,8 @@ static void kvm_write_guest_time(struct kvm_vcpu *v)
680 /* With all the info we got, fill in the values */ 680 /* With all the info we got, fill in the values */
681 681
682 vcpu->hv_clock.system_time = ts.tv_nsec + 682 vcpu->hv_clock.system_time = ts.tv_nsec +
683 (NSEC_PER_SEC * (u64)ts.tv_sec); 683 (NSEC_PER_SEC * (u64)ts.tv_sec) + v->kvm->arch.kvmclock_offset;
684
684 /* 685 /*
685 * The interface expects us to write an even number signaling that the 686 * The interface expects us to write an even number signaling that the
686 * update is finished. Since the guest won't see the intermediate 687 * update is finished. Since the guest won't see the intermediate
@@ -1262,6 +1263,7 @@ int kvm_dev_ioctl_check_extension(long ext)
1262 case KVM_CAP_PIT_STATE2: 1263 case KVM_CAP_PIT_STATE2:
1263 case KVM_CAP_SET_IDENTITY_MAP_ADDR: 1264 case KVM_CAP_SET_IDENTITY_MAP_ADDR:
1264 case KVM_CAP_XEN_HVM: 1265 case KVM_CAP_XEN_HVM:
1266 case KVM_CAP_ADJUST_CLOCK:
1265 r = 1; 1267 r = 1;
1266 break; 1268 break;
1267 case KVM_CAP_COALESCED_MMIO: 1269 case KVM_CAP_COALESCED_MMIO:
@@ -2468,6 +2470,44 @@ long kvm_arch_vm_ioctl(struct file *filp,
2468 r = 0; 2470 r = 0;
2469 break; 2471 break;
2470 } 2472 }
2473 case KVM_SET_CLOCK: {
2474 struct timespec now;
2475 struct kvm_clock_data user_ns;
2476 u64 now_ns;
2477 s64 delta;
2478
2479 r = -EFAULT;
2480 if (copy_from_user(&user_ns, argp, sizeof(user_ns)))
2481 goto out;
2482
2483 r = -EINVAL;
2484 if (user_ns.flags)
2485 goto out;
2486
2487 r = 0;
2488 ktime_get_ts(&now);
2489 now_ns = timespec_to_ns(&now);
2490 delta = user_ns.clock - now_ns;
2491 kvm->arch.kvmclock_offset = delta;
2492 break;
2493 }
2494 case KVM_GET_CLOCK: {
2495 struct timespec now;
2496 struct kvm_clock_data user_ns;
2497 u64 now_ns;
2498
2499 ktime_get_ts(&now);
2500 now_ns = timespec_to_ns(&now);
2501 user_ns.clock = kvm->arch.kvmclock_offset + now_ns;
2502 user_ns.flags = 0;
2503
2504 r = -EFAULT;
2505 if (copy_to_user(argp, &user_ns, sizeof(user_ns)))
2506 goto out;
2507 r = 0;
2508 break;
2509 }
2510
2471 default: 2511 default:
2472 ; 2512 ;
2473 } 2513 }
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index b694c1d2f918..6ed1a12ed526 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -439,6 +439,7 @@ struct kvm_ioeventfd {
439#ifdef __KVM_HAVE_XEN_HVM 439#ifdef __KVM_HAVE_XEN_HVM
440#define KVM_CAP_XEN_HVM 38 440#define KVM_CAP_XEN_HVM 38
441#endif 441#endif
442#define KVM_CAP_ADJUST_CLOCK 39
442 443
443#ifdef KVM_CAP_IRQ_ROUTING 444#ifdef KVM_CAP_IRQ_ROUTING
444 445
@@ -512,6 +513,12 @@ struct kvm_irqfd {
512 __u8 pad[20]; 513 __u8 pad[20];
513}; 514};
514 515
516struct kvm_clock_data {
517 __u64 clock;
518 __u32 flags;
519 __u32 pad[9];
520};
521
515/* 522/*
516 * ioctls for VM fds 523 * ioctls for VM fds
517 */ 524 */
@@ -562,6 +569,9 @@ struct kvm_irqfd {
562#define KVM_SET_BOOT_CPU_ID _IO(KVMIO, 0x78) 569#define KVM_SET_BOOT_CPU_ID _IO(KVMIO, 0x78)
563#define KVM_IOEVENTFD _IOW(KVMIO, 0x79, struct kvm_ioeventfd) 570#define KVM_IOEVENTFD _IOW(KVMIO, 0x79, struct kvm_ioeventfd)
564#define KVM_XEN_HVM_CONFIG _IOW(KVMIO, 0x7a, struct kvm_xen_hvm_config) 571#define KVM_XEN_HVM_CONFIG _IOW(KVMIO, 0x7a, struct kvm_xen_hvm_config)
572#define KVM_SET_CLOCK _IOW(KVMIO, 0x7b, struct kvm_clock_data)
573#define KVM_GET_CLOCK _IOR(KVMIO, 0x7c, struct kvm_clock_data)
574
565 575
566/* 576/*
567 * ioctls for vcpu fds 577 * ioctls for vcpu fds