timer.c 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. /*
  2. * Kernel-based Virtual Machine driver for Linux
  3. *
  4. * This module enables machines with Intel VT-x extensions to run virtual
  5. * machines without emulation or binary translation.
  6. *
  7. * timer support
  8. *
  9. * Copyright 2010 Red Hat, Inc. and/or its affiliates.
  10. *
  11. * This work is licensed under the terms of the GNU GPL, version 2. See
  12. * the COPYING file in the top-level directory.
  13. */
  14. #include <linux/kvm_host.h>
  15. #include <linux/kvm.h>
  16. #include <linux/hrtimer.h>
  17. #include <asm/atomic.h>
  18. #include "kvm_timer.h"
  19. static int __kvm_timer_fn(struct kvm_vcpu *vcpu, struct kvm_timer *ktimer)
  20. {
  21. int restart_timer = 0;
  22. wait_queue_head_t *q = &vcpu->wq;
  23. /*
  24. * There is a race window between reading and incrementing, but we do
  25. * not care about potentially losing timer events in the !reinject
  26. * case anyway. Note: KVM_REQ_PENDING_TIMER is implicitly checked
  27. * in vcpu_enter_guest.
  28. */
  29. if (ktimer->reinject || !atomic_read(&ktimer->pending)) {
  30. atomic_inc(&ktimer->pending);
  31. /* FIXME: this code should not know anything about vcpus */
  32. kvm_make_request(KVM_REQ_PENDING_TIMER, vcpu);
  33. }
  34. if (waitqueue_active(q))
  35. wake_up_interruptible(q);
  36. if (ktimer->t_ops->is_periodic(ktimer)) {
  37. hrtimer_add_expires_ns(&ktimer->timer, ktimer->period);
  38. restart_timer = 1;
  39. }
  40. return restart_timer;
  41. }
  42. enum hrtimer_restart kvm_timer_fn(struct hrtimer *data)
  43. {
  44. int restart_timer;
  45. struct kvm_vcpu *vcpu;
  46. struct kvm_timer *ktimer = container_of(data, struct kvm_timer, timer);
  47. vcpu = ktimer->vcpu;
  48. if (!vcpu)
  49. return HRTIMER_NORESTART;
  50. restart_timer = __kvm_timer_fn(vcpu, ktimer);
  51. if (restart_timer)
  52. return HRTIMER_RESTART;
  53. else
  54. return HRTIMER_NORESTART;
  55. }