timer.c 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  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. /*
  11. * There is a race window between reading and incrementing, but we do
  12. * not care about potentially loosing timer events in the !reinject
  13. * case anyway.
  14. */
  15. if (ktimer->reinject || !atomic_read(&ktimer->pending)) {
  16. atomic_inc(&ktimer->pending);
  17. /* FIXME: this code should not know anything about vcpus */
  18. set_bit(KVM_REQ_PENDING_TIMER, &vcpu->requests);
  19. }
  20. if (waitqueue_active(q))
  21. wake_up_interruptible(q);
  22. if (ktimer->t_ops->is_periodic(ktimer)) {
  23. hrtimer_add_expires_ns(&ktimer->timer, ktimer->period);
  24. restart_timer = 1;
  25. }
  26. return restart_timer;
  27. }
  28. enum hrtimer_restart kvm_timer_fn(struct hrtimer *data)
  29. {
  30. int restart_timer;
  31. struct kvm_vcpu *vcpu;
  32. struct kvm_timer *ktimer = container_of(data, struct kvm_timer, timer);
  33. vcpu = ktimer->vcpu;
  34. if (!vcpu)
  35. return HRTIMER_NORESTART;
  36. restart_timer = __kvm_timer_fn(vcpu, ktimer);
  37. if (restart_timer)
  38. return HRTIMER_RESTART;
  39. else
  40. return HRTIMER_NORESTART;
  41. }