]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/x86/kvm/lapic.c
KVM: close timer injection race window in __vcpu_run
[linux-2.6-omap-h63xx.git] / arch / x86 / kvm / lapic.c
index 57ac4e4c556a5a3ca5bc79a8acbd1e35f3f33d9d..ebc03f5ae162e2702974c122e27a580fa6556ac2 100644 (file)
 #include <linux/hrtimer.h>
 #include <linux/io.h>
 #include <linux/module.h>
+#include <linux/math64.h>
 #include <asm/processor.h>
 #include <asm/msr.h>
 #include <asm/page.h>
 #include <asm/current.h>
 #include <asm/apicdef.h>
 #include <asm/atomic.h>
-#include <asm/div64.h>
 #include "irq.h"
 
 #define PRId64 "d"
@@ -526,8 +526,8 @@ static u32 apic_get_tmcct(struct kvm_lapic *apic)
        } else
                passed = ktime_sub(now, apic->timer.last_update);
 
-       counter_passed = div64_64(ktime_to_ns(passed),
-                                 (APIC_BUS_CYCLE_NS * apic->timer.divide_count));
+       counter_passed = div64_u64(ktime_to_ns(passed),
+                                  (APIC_BUS_CYCLE_NS * apic->timer.divide_count));
 
        if (counter_passed > tmcct) {
                if (unlikely(!apic_lvtt_period(apic))) {
@@ -940,6 +940,7 @@ static int __apic_timer_fn(struct kvm_lapic *apic)
        wait_queue_head_t *q = &apic->vcpu->wq;
 
        atomic_inc(&apic->timer.pending);
+       set_bit(KVM_REQ_PENDING_TIMER, &apic->vcpu->requests);
        if (waitqueue_active(q)) {
                apic->vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
                wake_up_interruptible(q);
@@ -957,7 +958,7 @@ int apic_has_pending_timer(struct kvm_vcpu *vcpu)
 {
        struct kvm_lapic *lapic = vcpu->arch.apic;
 
-       if (lapic)
+       if (lapic && apic_enabled(lapic) && apic_lvt_enabled(lapic, APIC_LVTT))
                return atomic_read(&lapic->timer.pending);
 
        return 0;