KVM: Add instruction emulation statistics
[safe/jmp/linux-2.6] / drivers / kvm / lapic.c
index 238fcad..64f74bd 100644 (file)
@@ -18,6 +18,8 @@
  */
 
 #include "kvm.h"
+#include "x86.h"
+
 #include <linux/kvm.h>
 #include <linux/mm.h>
 #include <linux/highmem.h>
@@ -172,7 +174,7 @@ static inline int apic_find_highest_irr(struct kvm_lapic *apic)
 
 int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu)
 {
-       struct kvm_lapic *apic = (struct kvm_lapic *)vcpu->apic;
+       struct kvm_lapic *apic = vcpu->apic;
        int highest_irr;
 
        if (!apic)
@@ -395,10 +397,9 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
 struct kvm_lapic *kvm_apic_round_robin(struct kvm *kvm, u8 vector,
                                       unsigned long bitmap)
 {
-       int vcpu_id;
        int last;
        int next;
-       struct kvm_lapic *apic;
+       struct kvm_lapic *apic = NULL;
 
        last = kvm->round_robin_prev_vcpu;
        next = last;
@@ -415,14 +416,8 @@ struct kvm_lapic *kvm_apic_round_robin(struct kvm *kvm, u8 vector,
        } while (next != last);
        kvm->round_robin_prev_vcpu = next;
 
-       if (!apic) {
-               vcpu_id = ffs(bitmap) - 1;
-               if (vcpu_id < 0) {
-                       vcpu_id = 0;
-                       printk(KERN_DEBUG "vcpu not ready for apic_round_robin\n");
-               }
-               apic = kvm->vcpus[vcpu_id]->apic;
-       }
+       if (!apic)
+               printk(KERN_DEBUG "vcpu not ready for apic_round_robin\n");
 
        return apic;
 }
@@ -762,19 +757,17 @@ static int apic_mmio_range(struct kvm_io_device *this, gpa_t addr)
        return ret;
 }
 
-void kvm_free_apic(struct kvm_lapic *apic)
+void kvm_free_lapic(struct kvm_vcpu *vcpu)
 {
-       if (!apic)
+       if (!vcpu->apic)
                return;
 
-       hrtimer_cancel(&apic->timer.dev);
+       hrtimer_cancel(&vcpu->apic->timer.dev);
 
-       if (apic->regs_page) {
-               __free_page(apic->regs_page);
-               apic->regs_page = 0;
-       }
+       if (vcpu->apic->regs_page)
+               __free_page(vcpu->apic->regs_page);
 
-       kfree(apic);
+       kfree(vcpu->apic);
 }
 
 /*
@@ -785,7 +778,7 @@ void kvm_free_apic(struct kvm_lapic *apic)
 
 void kvm_lapic_set_tpr(struct kvm_vcpu *vcpu, unsigned long cr8)
 {
-       struct kvm_lapic *apic = (struct kvm_lapic *)vcpu->apic;
+       struct kvm_lapic *apic = vcpu->apic;
 
        if (!apic)
                return;
@@ -794,7 +787,7 @@ void kvm_lapic_set_tpr(struct kvm_vcpu *vcpu, unsigned long cr8)
 
 u64 kvm_lapic_get_cr8(struct kvm_vcpu *vcpu)
 {
-       struct kvm_lapic *apic = (struct kvm_lapic *)vcpu->apic;
+       struct kvm_lapic *apic = vcpu->apic;
        u64 tpr;
 
        if (!apic)
@@ -807,7 +800,7 @@ EXPORT_SYMBOL_GPL(kvm_lapic_get_cr8);
 
 void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value)
 {
-       struct kvm_lapic *apic = (struct kvm_lapic *)vcpu->apic;
+       struct kvm_lapic *apic = vcpu->apic;
 
        if (!apic) {
                value |= MSR_IA32_APICBASE_BSP;
@@ -884,7 +877,7 @@ EXPORT_SYMBOL_GPL(kvm_lapic_reset);
 
 int kvm_lapic_enabled(struct kvm_vcpu *vcpu)
 {
-       struct kvm_lapic *apic = (struct kvm_lapic *)vcpu->apic;
+       struct kvm_lapic *apic = vcpu->apic;
        int ret = 0;
 
        if (!apic)
@@ -908,8 +901,7 @@ static int __apic_timer_fn(struct kvm_lapic *apic)
        wait_queue_head_t *q = &apic->vcpu->wq;
 
        atomic_inc(&apic->timer.pending);
-       if (waitqueue_active(q))
-       {
+       if (waitqueue_active(q)) {
                apic->vcpu->mp_state = VCPU_MP_STATE_RUNNABLE;
                wake_up_interruptible(q);
        }
@@ -962,7 +954,7 @@ int kvm_create_lapic(struct kvm_vcpu *vcpu)
        if (apic->regs_page == NULL) {
                printk(KERN_ERR "malloc apic regs error for vcpu %x\n",
                       vcpu->vcpu_id);
-               goto nomem;
+               goto nomem_free_apic;
        }
        apic->regs = page_address(apic->regs_page);
        memset(apic->regs, 0, PAGE_SIZE);
@@ -980,8 +972,9 @@ int kvm_create_lapic(struct kvm_vcpu *vcpu)
        apic->dev.private = apic;
 
        return 0;
+nomem_free_apic:
+       kfree(apic);
 nomem:
-       kvm_free_apic(apic);
        return -ENOMEM;
 }
 EXPORT_SYMBOL_GPL(kvm_create_lapic);