linux/arch/x86/kvm/timer.c
<<
>>
Prefs
   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
  15#include <linux/kvm_host.h>
  16#include <linux/kvm.h>
  17#include <linux/hrtimer.h>
  18#include <linux/atomic.h>
  19#include "kvm_timer.h"
  20
  21static int __kvm_timer_fn(struct kvm_vcpu *vcpu, struct kvm_timer *ktimer)
  22{
  23        int restart_timer = 0;
  24        wait_queue_head_t *q = &vcpu->wq;
  25
  26        /*
  27         * There is a race window between reading and incrementing, but we do
  28         * not care about potentially losing timer events in the !reinject
  29         * case anyway. Note: KVM_REQ_PENDING_TIMER is implicitly checked
  30         * in vcpu_enter_guest.
  31         */
  32        if (ktimer->reinject || !atomic_read(&ktimer->pending)) {
  33                atomic_inc(&ktimer->pending);
  34                /* FIXME: this code should not know anything about vcpus */
  35                kvm_make_request(KVM_REQ_PENDING_TIMER, vcpu);
  36        }
  37
  38        if (waitqueue_active(q))
  39                wake_up_interruptible(q);
  40
  41        if (ktimer->t_ops->is_periodic(ktimer)) {
  42                hrtimer_add_expires_ns(&ktimer->timer, ktimer->period);
  43                restart_timer = 1;
  44        }
  45
  46        return restart_timer;
  47}
  48
  49enum hrtimer_restart kvm_timer_fn(struct hrtimer *data)
  50{
  51        int restart_timer;
  52        struct kvm_vcpu *vcpu;
  53        struct kvm_timer *ktimer = container_of(data, struct kvm_timer, timer);
  54
  55        vcpu = ktimer->vcpu;
  56        if (!vcpu)
  57                return HRTIMER_NORESTART;
  58
  59        restart_timer = __kvm_timer_fn(vcpu, ktimer);
  60        if (restart_timer)
  61                return HRTIMER_RESTART;
  62        else
  63                return HRTIMER_NORESTART;
  64}
  65
  66