2010-05-23 18:37:00 +03:00
/*
* Kernel - based Virtual Machine driver for Linux
*
* This module enables machines with Intel VT - x extensions to run virtual
* machines without emulation or binary translation .
*
* timer support
*
2010-10-06 14:23:22 +02:00
* Copyright 2010 Red Hat , Inc . and / or its affiliates .
2010-05-23 18:37:00 +03:00
*
* This work is licensed under the terms of the GNU GPL , version 2. See
* the COPYING file in the top - level directory .
*/
2009-02-23 10:57:41 -03:00
# include <linux/kvm_host.h>
# include <linux/kvm.h>
# include <linux/hrtimer.h>
2011-07-26 16:09:06 -07:00
# include <linux/atomic.h>
2009-02-23 10:57:41 -03:00
# include "kvm_timer.h"
2011-09-14 09:58:32 +02:00
enum hrtimer_restart kvm_timer_fn ( struct hrtimer * data )
2009-02-23 10:57:41 -03:00
{
2011-09-14 09:58:32 +02:00
struct kvm_timer * ktimer = container_of ( data , struct kvm_timer , timer ) ;
struct kvm_vcpu * vcpu = ktimer - > vcpu ;
2009-02-23 10:57:41 -03:00
wait_queue_head_t * q = & vcpu - > wq ;
2009-06-09 15:37:01 +02:00
/*
* There is a race window between reading and incrementing , but we do
2011-03-17 16:24:16 -03:00
* not care about potentially losing timer events in the ! reinject
2010-03-23 14:15:53 -03:00
* case anyway . Note : KVM_REQ_PENDING_TIMER is implicitly checked
* in vcpu_enter_guest .
2009-06-09 15:37:01 +02:00
*/
if ( ktimer - > reinject | | ! atomic_read ( & ktimer - > pending ) ) {
2009-06-09 15:37:03 +02:00
atomic_inc ( & ktimer - > pending ) ;
2009-06-09 15:37:01 +02:00
/* FIXME: this code should not know anything about vcpus */
2010-05-10 12:34:53 +03:00
kvm_make_request ( KVM_REQ_PENDING_TIMER , vcpu ) ;
2009-06-09 15:37:01 +02:00
}
2009-02-23 10:57:41 -03:00
if ( waitqueue_active ( q ) )
wake_up_interruptible ( q ) ;
if ( ktimer - > t_ops - > is_periodic ( ktimer ) ) {
hrtimer_add_expires_ns ( & ktimer - > timer , ktimer - > period ) ;
return HRTIMER_RESTART ;
2011-09-14 09:58:32 +02:00
} else
2009-02-23 10:57:41 -03:00
return HRTIMER_NORESTART ;
}