Lines Matching refs:stimer
41 static void stimer_mark_pending(struct kvm_vcpu_hv_stimer *stimer,
169 struct kvm_vcpu_hv_stimer *stimer;
175 for (idx = 0; idx < ARRAY_SIZE(hv_vcpu->stimer); idx++) {
176 stimer = &hv_vcpu->stimer[idx];
177 if (stimer->msg_pending && stimer->config.enable &&
178 !stimer->config.direct_mode &&
179 stimer->config.sintx == sint)
180 stimer_mark_pending(stimer, false);
540 static void stimer_mark_pending(struct kvm_vcpu_hv_stimer *stimer,
543 struct kvm_vcpu *vcpu = stimer_to_vcpu(stimer);
545 set_bit(stimer->index,
552 static void stimer_cleanup(struct kvm_vcpu_hv_stimer *stimer)
554 struct kvm_vcpu *vcpu = stimer_to_vcpu(stimer);
556 trace_kvm_hv_stimer_cleanup(stimer_to_vcpu(stimer)->vcpu_id,
557 stimer->index);
559 hrtimer_cancel(&stimer->timer);
560 clear_bit(stimer->index,
562 stimer->msg_pending = false;
563 stimer->exp_time = 0;
568 struct kvm_vcpu_hv_stimer *stimer;
570 stimer = container_of(timer, struct kvm_vcpu_hv_stimer, timer);
571 trace_kvm_hv_stimer_callback(stimer_to_vcpu(stimer)->vcpu_id,
572 stimer->index);
573 stimer_mark_pending(stimer, true);
580 * a) stimer->count is not equal to 0
581 * b) stimer->config has HV_STIMER_ENABLE flag
583 static int stimer_start(struct kvm_vcpu_hv_stimer *stimer)
588 time_now = get_time_ref_counter(stimer_to_vcpu(stimer)->kvm);
591 if (stimer->config.periodic) {
592 if (stimer->exp_time) {
593 if (time_now >= stimer->exp_time) {
596 div64_u64_rem(time_now - stimer->exp_time,
597 stimer->count, &remainder);
598 stimer->exp_time =
599 time_now + (stimer->count - remainder);
602 stimer->exp_time = time_now + stimer->count;
605 stimer_to_vcpu(stimer)->vcpu_id,
606 stimer->index,
607 time_now, stimer->exp_time);
609 hrtimer_start(&stimer->timer,
611 100 * (stimer->exp_time - time_now)),
615 stimer->exp_time = stimer->count;
616 if (time_now >= stimer->count) {
623 stimer_mark_pending(stimer, false);
627 trace_kvm_hv_stimer_start_one_shot(stimer_to_vcpu(stimer)->vcpu_id,
628 stimer->index,
629 time_now, stimer->count);
631 hrtimer_start(&stimer->timer,
632 ktime_add_ns(ktime_now, 100 * (stimer->count - time_now)),
637 static int stimer_set_config(struct kvm_vcpu_hv_stimer *stimer, u64 config,
641 old_config = {.as_uint64 = stimer->config.as_uint64};
642 struct kvm_vcpu *vcpu = stimer_to_vcpu(stimer);
648 trace_kvm_hv_stimer_set_config(stimer_to_vcpu(stimer)->vcpu_id,
649 stimer->index, config, host);
651 stimer_cleanup(stimer);
655 stimer->config.as_uint64 = new_config.as_uint64;
657 if (stimer->config.enable)
658 stimer_mark_pending(stimer, false);
663 static int stimer_set_count(struct kvm_vcpu_hv_stimer *stimer, u64 count,
666 struct kvm_vcpu *vcpu = stimer_to_vcpu(stimer);
672 trace_kvm_hv_stimer_set_count(stimer_to_vcpu(stimer)->vcpu_id,
673 stimer->index, count, host);
675 stimer_cleanup(stimer);
676 stimer->count = count;
678 if (stimer->count == 0)
679 stimer->config.enable = 0;
680 else if (stimer->config.auto_enable)
681 stimer->config.enable = 1;
684 if (stimer->config.enable)
685 stimer_mark_pending(stimer, false);
690 static int stimer_get_config(struct kvm_vcpu_hv_stimer *stimer, u64 *pconfig)
692 *pconfig = stimer->config.as_uint64;
696 static int stimer_get_count(struct kvm_vcpu_hv_stimer *stimer, u64 *pcount)
698 *pcount = stimer->count;
759 static int stimer_send_msg(struct kvm_vcpu_hv_stimer *stimer)
761 struct kvm_vcpu *vcpu = stimer_to_vcpu(stimer);
762 struct hv_message *msg = &stimer->msg;
770 bool no_retry = stimer->config.periodic;
772 payload->expiration_time = stimer->exp_time;
775 stimer->config.sintx, msg,
779 static int stimer_notify_direct(struct kvm_vcpu_hv_stimer *stimer)
781 struct kvm_vcpu *vcpu = stimer_to_vcpu(stimer);
784 .vector = stimer->config.apic_vector
792 static void stimer_expiration(struct kvm_vcpu_hv_stimer *stimer)
794 int r, direct = stimer->config.direct_mode;
796 stimer->msg_pending = true;
798 r = stimer_send_msg(stimer);
800 r = stimer_notify_direct(stimer);
801 trace_kvm_hv_stimer_expiration(stimer_to_vcpu(stimer)->vcpu_id,
802 stimer->index, direct, r);
804 stimer->msg_pending = false;
805 if (!(stimer->config.periodic))
806 stimer->config.enable = 0;
813 struct kvm_vcpu_hv_stimer *stimer;
817 for (i = 0; i < ARRAY_SIZE(hv_vcpu->stimer); i++)
819 stimer = &hv_vcpu->stimer[i];
820 if (stimer->config.enable) {
821 exp_time = stimer->exp_time;
827 stimer_expiration(stimer);
830 if ((stimer->config.enable) &&
831 stimer->count) {
832 if (!stimer->msg_pending)
833 stimer_start(stimer);
835 stimer_cleanup(stimer);
845 for (i = 0; i < ARRAY_SIZE(hv_vcpu->stimer); i++)
846 stimer_cleanup(&hv_vcpu->stimer[i]);
867 static void stimer_prepare_msg(struct kvm_vcpu_hv_stimer *stimer)
869 struct hv_message *msg = &stimer->msg;
877 payload->timer_index = stimer->index;
882 static void stimer_init(struct kvm_vcpu_hv_stimer *stimer, int timer_index)
884 memset(stimer, 0, sizeof(*stimer));
885 stimer->index = timer_index;
886 hrtimer_init(&stimer->timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
887 stimer->timer.function = stimer_timer_callback;
888 stimer_prepare_msg(stimer);
899 for (i = 0; i < ARRAY_SIZE(hv_vcpu->stimer); i++)
900 stimer_init(&hv_vcpu->stimer[i], i);