diff options
author | Marcelo Tosatti <mtosatti@redhat.com> | 2013-05-09 19:21:41 -0400 |
---|---|---|
committer | Gleb Natapov <gleb@redhat.com> | 2013-05-15 13:36:09 -0400 |
commit | 0061d53daf26ff713ab43ab84ae5c44b5edbefa9 (patch) | |
tree | c9b86974498fb39210c355171c01afbae513bb59 /arch/x86 | |
parent | f1ed0450a5fac7067590317cbf027f566b6ccbca (diff) |
KVM: x86: limit difference between kvmclock updates
kvmclock updates which are isolated to a given vcpu, such as vcpu->cpu
migration, should not allow system_timestamp from the rest of the vcpus
to remain static. Otherwise ntp frequency correction applies to one
vcpu's system_timestamp but not the others.
So in those cases, request a kvmclock update for all vcpus. The worst
case for a remote vcpu to update its kvmclock is then bounded by maximum
nohz sleep latency.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Gleb Natapov <gleb@redhat.com>
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/kvm/x86.c | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 094b5d96ab14..8d28810a5f88 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -1588,6 +1588,30 @@ static int kvm_guest_time_update(struct kvm_vcpu *v) | |||
1588 | return 0; | 1588 | return 0; |
1589 | } | 1589 | } |
1590 | 1590 | ||
1591 | /* | ||
1592 | * kvmclock updates which are isolated to a given vcpu, such as | ||
1593 | * vcpu->cpu migration, should not allow system_timestamp from | ||
1594 | * the rest of the vcpus to remain static. Otherwise ntp frequency | ||
1595 | * correction applies to one vcpu's system_timestamp but not | ||
1596 | * the others. | ||
1597 | * | ||
1598 | * So in those cases, request a kvmclock update for all vcpus. | ||
1599 | * The worst case for a remote vcpu to update its kvmclock | ||
1600 | * is then bounded by maximum nohz sleep latency. | ||
1601 | */ | ||
1602 | |||
1603 | static void kvm_gen_kvmclock_update(struct kvm_vcpu *v) | ||
1604 | { | ||
1605 | int i; | ||
1606 | struct kvm *kvm = v->kvm; | ||
1607 | struct kvm_vcpu *vcpu; | ||
1608 | |||
1609 | kvm_for_each_vcpu(i, vcpu, kvm) { | ||
1610 | set_bit(KVM_REQ_CLOCK_UPDATE, &vcpu->requests); | ||
1611 | kvm_vcpu_kick(vcpu); | ||
1612 | } | ||
1613 | } | ||
1614 | |||
1591 | static bool msr_mtrr_valid(unsigned msr) | 1615 | static bool msr_mtrr_valid(unsigned msr) |
1592 | { | 1616 | { |
1593 | switch (msr) { | 1617 | switch (msr) { |
@@ -1985,7 +2009,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) | |||
1985 | kvmclock_reset(vcpu); | 2009 | kvmclock_reset(vcpu); |
1986 | 2010 | ||
1987 | vcpu->arch.time = data; | 2011 | vcpu->arch.time = data; |
1988 | kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu); | 2012 | kvm_make_request(KVM_REQ_GLOBAL_CLOCK_UPDATE, vcpu); |
1989 | 2013 | ||
1990 | /* we verify if the enable bit is set... */ | 2014 | /* we verify if the enable bit is set... */ |
1991 | if (!(data & 1)) | 2015 | if (!(data & 1)) |
@@ -2702,7 +2726,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | |||
2702 | * kvmclock on vcpu->cpu migration | 2726 | * kvmclock on vcpu->cpu migration |
2703 | */ | 2727 | */ |
2704 | if (!vcpu->kvm->arch.use_master_clock || vcpu->cpu == -1) | 2728 | if (!vcpu->kvm->arch.use_master_clock || vcpu->cpu == -1) |
2705 | kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu); | 2729 | kvm_make_request(KVM_REQ_GLOBAL_CLOCK_UPDATE, vcpu); |
2706 | if (vcpu->cpu != cpu) | 2730 | if (vcpu->cpu != cpu) |
2707 | kvm_migrate_timers(vcpu); | 2731 | kvm_migrate_timers(vcpu); |
2708 | vcpu->cpu = cpu; | 2732 | vcpu->cpu = cpu; |
@@ -5703,6 +5727,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) | |||
5703 | __kvm_migrate_timers(vcpu); | 5727 | __kvm_migrate_timers(vcpu); |
5704 | if (kvm_check_request(KVM_REQ_MASTERCLOCK_UPDATE, vcpu)) | 5728 | if (kvm_check_request(KVM_REQ_MASTERCLOCK_UPDATE, vcpu)) |
5705 | kvm_gen_update_masterclock(vcpu->kvm); | 5729 | kvm_gen_update_masterclock(vcpu->kvm); |
5730 | if (kvm_check_request(KVM_REQ_GLOBAL_CLOCK_UPDATE, vcpu)) | ||
5731 | kvm_gen_kvmclock_update(vcpu); | ||
5706 | if (kvm_check_request(KVM_REQ_CLOCK_UPDATE, vcpu)) { | 5732 | if (kvm_check_request(KVM_REQ_CLOCK_UPDATE, vcpu)) { |
5707 | r = kvm_guest_time_update(vcpu); | 5733 | r = kvm_guest_time_update(vcpu); |
5708 | if (unlikely(r)) | 5734 | if (unlikely(r)) |