]> err.no Git - linux-2.6/blobdiff - arch/x86/kvm/i8254.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[linux-2.6] / arch / x86 / kvm / i8254.c
index 8642f9d1206ad6025f3e4d40e66bb9ca9f233334..3324d90038e438ab1361d53f31be78948d72aba8 100644 (file)
@@ -35,7 +35,7 @@
 #include "i8254.h"
 
 #ifndef CONFIG_X86_64
-#define mod_64(x, y) ((x) - (y) * div64_64(x, y))
+#define mod_64(x, y) ((x) - (y) * div64_u64(x, y))
 #else
 #define mod_64(x, y) ((x) % (y))
 #endif
@@ -60,8 +60,8 @@ static u64 muldiv64(u64 a, u32 b, u32 c)
        rl = (u64)u.l.low * (u64)b;
        rh = (u64)u.l.high * (u64)b;
        rh += (rl >> 32);
-       res.l.high = div64_64(rh, c);
-       res.l.low = div64_64(((mod_64(rh, c) << 32) + (rl & 0xffffffff)), c);
+       res.l.high = div64_u64(rh, c);
+       res.l.low = div64_u64(((mod_64(rh, c) << 32) + (rl & 0xffffffff)), c);
        return res.ll;
 }
 
@@ -202,7 +202,7 @@ int __pit_timer_fn(struct kvm_kpit_state *ps)
        smp_mb__after_atomic_inc();
        /* FIXME: handle case where the guest is in guest mode */
        if (vcpu0 && waitqueue_active(&vcpu0->wq)) {
-               vcpu0->arch.mp_state = VCPU_MP_STATE_RUNNABLE;
+               vcpu0->arch.mp_state = KVM_MP_STATE_RUNNABLE;
                wake_up_interruptible(&vcpu0->wq);
        }
 
@@ -212,6 +212,16 @@ int __pit_timer_fn(struct kvm_kpit_state *ps)
        return (pt->period == 0 ? 0 : 1);
 }
 
+int pit_has_pending_timer(struct kvm_vcpu *vcpu)
+{
+       struct kvm_pit *pit = vcpu->kvm->arch.vpit;
+
+       if (pit && vcpu->vcpu_id == 0)
+               return atomic_read(&pit->pit_state.pit_timer.pending);
+
+       return 0;
+}
+
 static enum hrtimer_restart pit_timer_fn(struct hrtimer *data)
 {
        struct kvm_kpit_state *ps;
@@ -278,6 +288,8 @@ static void pit_load_count(struct kvm *kvm, int channel, u32 val)
         * mode 1 is one shot, mode 2 is period, otherwise del timer */
        switch (ps->channels[0].mode) {
        case 1:
+        /* FIXME: enhance mode 4 precision */
+       case 4:
                create_pit_timer(&ps->pit_timer, val, 0);
                break;
        case 2:
@@ -478,12 +490,28 @@ static int speaker_in_range(struct kvm_io_device *this, gpa_t addr)
        return (addr == KVM_SPEAKER_BASE_ADDRESS);
 }
 
-struct kvm_pit *kvm_create_pit(struct kvm *kvm)
+void kvm_pit_reset(struct kvm_pit *pit)
 {
        int i;
+       struct kvm_kpit_channel_state *c;
+
+       mutex_lock(&pit->pit_state.lock);
+       for (i = 0; i < 3; i++) {
+               c = &pit->pit_state.channels[i];
+               c->mode = 0xff;
+               c->gate = (i != 2);
+               pit_load_count(pit->kvm, i, 0);
+       }
+       mutex_unlock(&pit->pit_state.lock);
+
+       atomic_set(&pit->pit_state.pit_timer.pending, 0);
+       pit->pit_state.inject_pending = 1;
+}
+
+struct kvm_pit *kvm_create_pit(struct kvm *kvm)
+{
        struct kvm_pit *pit;
        struct kvm_kpit_state *pit_state;
-       struct kvm_kpit_channel_state *c;
 
        pit = kzalloc(sizeof(struct kvm_pit), GFP_KERNEL);
        if (!pit)
@@ -512,17 +540,9 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm)
        pit_state->pit = pit;
        hrtimer_init(&pit_state->pit_timer.timer,
                     CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
-       atomic_set(&pit_state->pit_timer.pending, 0);
-       for (i = 0; i < 3; i++) {
-               c = &pit_state->channels[i];
-               c->mode = 0xff;
-               c->gate = (i != 2);
-               pit_load_count(kvm, i, 0);
-       }
-
        mutex_unlock(&pit->pit_state.lock);
 
-       pit->pit_state.inject_pending = 1;
+       kvm_pit_reset(pit);
 
        return pit;
 }