diff options
author | He, Qing <qing.he@intel.com> | 2007-09-03 17:01:36 +0300 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2007-10-13 10:18:26 +0200 |
commit | 932f72adbe76f098922c746737cb0bd75fc21e27 (patch) | |
tree | 55a98bd0692094289d4bea4f5b2c58835f8b59df | |
parent | 40487c680d5855459dfdce340df13d40071bb774 (diff) |
KVM: round robin for APIC lowest priority delivery mode
Signed-off-by: Qing He <qing.he@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
-rw-r--r-- | drivers/kvm/kvm.h | 1 | ||||
-rw-r--r-- | drivers/kvm/lapic.c | 33 |
2 files changed, 29 insertions, 5 deletions
diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h index f8fe87d3ddb..dbb929d8a31 100644 --- a/drivers/kvm/kvm.h +++ b/drivers/kvm/kvm.h @@ -413,6 +413,7 @@ struct kvm { struct kvm_io_bus pio_bus; struct kvm_pic *vpic; struct kvm_ioapic *vioapic; + int round_robin_prev_vcpu; }; static inline struct kvm_pic *pic_irqchip(struct kvm *kvm) diff --git a/drivers/kvm/lapic.c b/drivers/kvm/lapic.c index 01e769672dc..ca1db3852ac 100644 --- a/drivers/kvm/lapic.c +++ b/drivers/kvm/lapic.c @@ -371,12 +371,35 @@ 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; + + last = kvm->round_robin_prev_vcpu; + next = last; + + do { + if (++next == KVM_MAX_VCPUS) + next = 0; + if (kvm->vcpus[next] == NULL || !test_bit(next, &bitmap)) + continue; + apic = kvm->vcpus[next]->apic; + if (apic && apic_enabled(apic)) + break; + apic = NULL; + } 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; + } - /* TODO for real round robin */ - vcpu_id = fls(bitmap) - 1; - if (vcpu_id < 0) - printk(KERN_DEBUG "vcpu not ready for apic_round_robin\n"); - return kvm->vcpus[vcpu_id]->apic; + return apic; } static void apic_set_eoi(struct kvm_lapic *apic) |