diff options
author | Marcelo Tosatti <mtosatti@redhat.com> | 2013-08-27 22:55:29 -0400 |
---|---|---|
committer | Gleb Natapov <gleb@redhat.com> | 2013-08-28 10:36:11 -0400 |
commit | 2e762ff79fd0793cfa71d3913e2eb664b7b11031 (patch) | |
tree | 0c8dd496830d9cf7e16e17b0e0a2cb7454175859 /arch/x86/kvm/x86.c | |
parent | 0912c9771e9902f752e890e93af495cc06a786ac (diff) |
KVM: x86: update masterclock when kvmclock_offset is calculated (v2)
The offset to add to the hosts monotonic time, kvmclock_offset, is
calculated against the monotonic time at KVM_SET_CLOCK ioctl time.
Request a master clock update at this time, to reduce a potentially
unbounded difference between the values of the masterclock and
the clock value used to calculate kvmclock_offset.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Gleb Natapov <gleb@redhat.com>
Diffstat (limited to 'arch/x86/kvm/x86.c')
-rw-r--r-- | arch/x86/kvm/x86.c | 47 |
1 files changed, 24 insertions, 23 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index e514b3cb8b93..e5ca72a5cdb6 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -1447,6 +1447,29 @@ static void pvclock_update_vm_gtod_copy(struct kvm *kvm) | |||
1447 | #endif | 1447 | #endif |
1448 | } | 1448 | } |
1449 | 1449 | ||
1450 | static void kvm_gen_update_masterclock(struct kvm *kvm) | ||
1451 | { | ||
1452 | #ifdef CONFIG_X86_64 | ||
1453 | int i; | ||
1454 | struct kvm_vcpu *vcpu; | ||
1455 | struct kvm_arch *ka = &kvm->arch; | ||
1456 | |||
1457 | spin_lock(&ka->pvclock_gtod_sync_lock); | ||
1458 | kvm_make_mclock_inprogress_request(kvm); | ||
1459 | /* no guest entries from this point */ | ||
1460 | pvclock_update_vm_gtod_copy(kvm); | ||
1461 | |||
1462 | kvm_for_each_vcpu(i, vcpu, kvm) | ||
1463 | set_bit(KVM_REQ_CLOCK_UPDATE, &vcpu->requests); | ||
1464 | |||
1465 | /* guest entries allowed */ | ||
1466 | kvm_for_each_vcpu(i, vcpu, kvm) | ||
1467 | clear_bit(KVM_REQ_MCLOCK_INPROGRESS, &vcpu->requests); | ||
1468 | |||
1469 | spin_unlock(&ka->pvclock_gtod_sync_lock); | ||
1470 | #endif | ||
1471 | } | ||
1472 | |||
1450 | static int kvm_guest_time_update(struct kvm_vcpu *v) | 1473 | static int kvm_guest_time_update(struct kvm_vcpu *v) |
1451 | { | 1474 | { |
1452 | unsigned long flags, this_tsc_khz; | 1475 | unsigned long flags, this_tsc_khz; |
@@ -3796,6 +3819,7 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
3796 | delta = user_ns.clock - now_ns; | 3819 | delta = user_ns.clock - now_ns; |
3797 | local_irq_enable(); | 3820 | local_irq_enable(); |
3798 | kvm->arch.kvmclock_offset = delta; | 3821 | kvm->arch.kvmclock_offset = delta; |
3822 | kvm_gen_update_masterclock(kvm); | ||
3799 | break; | 3823 | break; |
3800 | } | 3824 | } |
3801 | case KVM_GET_CLOCK: { | 3825 | case KVM_GET_CLOCK: { |
@@ -5804,29 +5828,6 @@ static void process_nmi(struct kvm_vcpu *vcpu) | |||
5804 | kvm_make_request(KVM_REQ_EVENT, vcpu); | 5828 | kvm_make_request(KVM_REQ_EVENT, vcpu); |
5805 | } | 5829 | } |
5806 | 5830 | ||
5807 | static void kvm_gen_update_masterclock(struct kvm *kvm) | ||
5808 | { | ||
5809 | #ifdef CONFIG_X86_64 | ||
5810 | int i; | ||
5811 | struct kvm_vcpu *vcpu; | ||
5812 | struct kvm_arch *ka = &kvm->arch; | ||
5813 | |||
5814 | spin_lock(&ka->pvclock_gtod_sync_lock); | ||
5815 | kvm_make_mclock_inprogress_request(kvm); | ||
5816 | /* no guest entries from this point */ | ||
5817 | pvclock_update_vm_gtod_copy(kvm); | ||
5818 | |||
5819 | kvm_for_each_vcpu(i, vcpu, kvm) | ||
5820 | set_bit(KVM_REQ_CLOCK_UPDATE, &vcpu->requests); | ||
5821 | |||
5822 | /* guest entries allowed */ | ||
5823 | kvm_for_each_vcpu(i, vcpu, kvm) | ||
5824 | clear_bit(KVM_REQ_MCLOCK_INPROGRESS, &vcpu->requests); | ||
5825 | |||
5826 | spin_unlock(&ka->pvclock_gtod_sync_lock); | ||
5827 | #endif | ||
5828 | } | ||
5829 | |||
5830 | static void vcpu_scan_ioapic(struct kvm_vcpu *vcpu) | 5831 | static void vcpu_scan_ioapic(struct kvm_vcpu *vcpu) |
5831 | { | 5832 | { |
5832 | u64 eoi_exit_bitmap[4]; | 5833 | u64 eoi_exit_bitmap[4]; |