diff options
author | Andrey Smetanin | 2015-12-28 18:27:20 +0300 |
---|---|---|
committer | Paolo Bonzini | 2016-01-08 19:04:40 +0100 |
commit | f808495da56f28e94c6448125158f1175009fcfc (patch) | |
tree | aee959706591136856acbbeb8c29c854018b3491 /arch/x86/kvm | |
parent | 019b9781ccd667d4160f3636c8735e3baa085555 (diff) |
kvm/x86: Hyper-V unify stimer_start() and stimer_restart()
This will be used in future to start Hyper-V SynIC timer
in several places by one logic in one function.
Changes v2:
* drop stimer->count == 0 check inside stimer_start()
* comment stimer_start() assumptions
Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
Reviewed-by: Roman Kagan <rkagan@virtuozzo.com>
CC: Gleb Natapov <gleb@kernel.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Roman Kagan <rkagan@virtuozzo.com>
CC: Denis V. Lunev <den@openvz.org>
CC: qemu-devel@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'arch/x86/kvm')
-rw-r--r-- | arch/x86/kvm/hyperv.c | 43 |
1 files changed, 20 insertions, 23 deletions
diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c index 6b2ed930bf18..0dd7d1731c22 100644 --- a/arch/x86/kvm/hyperv.c +++ b/arch/x86/kvm/hyperv.c @@ -408,6 +408,7 @@ static void stimer_cleanup(struct kvm_vcpu_hv_stimer *stimer) clear_bit(stimer->index, vcpu_to_hv_vcpu(vcpu)->stimer_pending_bitmap); stimer->msg_pending = false; + stimer->exp_time = 0; } static enum hrtimer_restart stimer_timer_callback(struct hrtimer *timer) @@ -420,24 +421,11 @@ static enum hrtimer_restart stimer_timer_callback(struct hrtimer *timer) return HRTIMER_NORESTART; } -static void stimer_restart(struct kvm_vcpu_hv_stimer *stimer) -{ - u64 time_now; - ktime_t ktime_now; - u64 remainder; - - time_now = get_time_ref_counter(stimer_to_vcpu(stimer)->kvm); - ktime_now = ktime_get(); - - div64_u64_rem(time_now - stimer->exp_time, stimer->count, &remainder); - stimer->exp_time = time_now + (stimer->count - remainder); - - hrtimer_start(&stimer->timer, - ktime_add_ns(ktime_now, - 100 * (stimer->exp_time - time_now)), - HRTIMER_MODE_ABS); -} - +/* + * stimer_start() assumptions: + * a) stimer->count is not equal to 0 + * b) stimer->config has HV_STIMER_ENABLE flag + */ static int stimer_start(struct kvm_vcpu_hv_stimer *stimer) { u64 time_now; @@ -447,12 +435,21 @@ static int stimer_start(struct kvm_vcpu_hv_stimer *stimer) ktime_now = ktime_get(); if (stimer->config & HV_STIMER_PERIODIC) { - if (stimer->count == 0) - return -EINVAL; + if (stimer->exp_time) { + if (time_now >= stimer->exp_time) { + u64 remainder; + + div64_u64_rem(time_now - stimer->exp_time, + stimer->count, &remainder); + stimer->exp_time = + time_now + (stimer->count - remainder); + } + } else + stimer->exp_time = time_now + stimer->count; - stimer->exp_time = time_now + stimer->count; hrtimer_start(&stimer->timer, - ktime_add_ns(ktime_now, 100 * stimer->count), + ktime_add_ns(ktime_now, + 100 * (stimer->exp_time - time_now)), HRTIMER_MODE_ABS); return 0; } @@ -580,7 +577,7 @@ static void stimer_expiration(struct kvm_vcpu_hv_stimer *stimer) if (!(stimer->config & HV_STIMER_PERIODIC)) stimer->config &= ~HV_STIMER_ENABLE; else - stimer_restart(stimer); + stimer_start(stimer); } void kvm_hv_process_stimers(struct kvm_vcpu *vcpu) |