timer.c 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. #include <linux/kvm_host.h>
  2. #include <linux/kvm.h>
  3. #include <linux/hrtimer.h>
  4. #include <asm/atomic.h>
  5. #include "kvm_timer.h"
  6. static int __kvm_timer_fn(struct kvm_vcpu *vcpu, struct kvm_timer *ktimer)
  7. {
  8. int restart_timer = 0;
  9. wait_queue_head_t *q = &vcpu->wq;
  10. /* FIXME: this code should not know anything about vcpus */
  11. if (!atomic_inc_and_test(&ktimer->pending))
  12. set_bit(KVM_REQ_PENDING_TIMER, &vcpu->requests);
  13. if (!ktimer->reinject)
  14. atomic_set(&ktimer->pending, 1);
  15. if (waitqueue_active(q))
  16. wake_up_interruptible(q);
  17. if (ktimer->t_ops->is_periodic(ktimer)) {
  18. hrtimer_add_expires_ns(&ktimer->timer, ktimer->period);
  19. restart_timer = 1;
  20. }
  21. return restart_timer;
  22. }
  23. enum hrtimer_restart kvm_timer_fn(struct hrtimer *data)
  24. {
  25. int restart_timer;
  26. struct kvm_vcpu *vcpu;
  27. struct kvm_timer *ktimer = container_of(data, struct kvm_timer, timer);
  28. vcpu = ktimer->kvm->vcpus[ktimer->vcpu_id];
  29. if (!vcpu)
  30. return HRTIMER_NORESTART;
  31. restart_timer = __kvm_timer_fn(vcpu, ktimer);
  32. if (restart_timer)
  33. return HRTIMER_RESTART;
  34. else
  35. return HRTIMER_NORESTART;
  36. }