diff options
-rw-r--r-- | arch/ia64/kvm/kvm-ia64.c | 15 | ||||
-rw-r--r-- | arch/ia64/kvm/lapic.h | 1 | ||||
-rw-r--r-- | arch/x86/include/asm/kvm_host.h | 2 | ||||
-rw-r--r-- | arch/x86/kvm/lapic.c | 43 | ||||
-rw-r--r-- | virt/kvm/ioapic.h | 3 | ||||
-rw-r--r-- | virt/kvm/irq_comm.c | 19 |
6 files changed, 22 insertions, 61 deletions
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index 8eea9cba7b7c..1887a93a2bd5 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c | |||
@@ -1836,20 +1836,9 @@ int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda) | |||
1836 | return 0; | 1836 | return 0; |
1837 | } | 1837 | } |
1838 | 1838 | ||
1839 | struct kvm_vcpu *kvm_get_lowest_prio_vcpu(struct kvm *kvm, u8 vector, | 1839 | int kvm_apic_compare_prio(struct kvm_vcpu *vcpu1, struct kvm_vcpu *vcpu2) |
1840 | unsigned long *bitmap) | ||
1841 | { | 1840 | { |
1842 | struct kvm_vcpu *lvcpu = kvm->vcpus[0]; | 1841 | return vcpu1->arch.xtp - vcpu2->arch.xtp; |
1843 | int i; | ||
1844 | |||
1845 | for (i = 1; i < kvm->arch.online_vcpus; i++) { | ||
1846 | if (!kvm->vcpus[i]) | ||
1847 | continue; | ||
1848 | if (lvcpu->arch.xtp > kvm->vcpus[i]->arch.xtp) | ||
1849 | lvcpu = kvm->vcpus[i]; | ||
1850 | } | ||
1851 | |||
1852 | return lvcpu; | ||
1853 | } | 1842 | } |
1854 | 1843 | ||
1855 | int kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source, | 1844 | int kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source, |
diff --git a/arch/ia64/kvm/lapic.h b/arch/ia64/kvm/lapic.h index 31602e7338d7..e42109e6ca47 100644 --- a/arch/ia64/kvm/lapic.h +++ b/arch/ia64/kvm/lapic.h | |||
@@ -22,6 +22,7 @@ int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest); | |||
22 | int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda); | 22 | int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda); |
23 | int kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source, | 23 | int kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source, |
24 | int short_hand, int dest, int dest_mode); | 24 | int short_hand, int dest, int dest_mode); |
25 | int kvm_apic_compare_prio(struct kvm_vcpu *vcpu1, struct kvm_vcpu *vcpu2); | ||
25 | bool kvm_apic_present(struct kvm_vcpu *vcpu); | 26 | bool kvm_apic_present(struct kvm_vcpu *vcpu); |
26 | int kvm_apic_set_irq(struct kvm_vcpu *vcpu, u8 vec, u8 dmode, u8 trig); | 27 | int kvm_apic_set_irq(struct kvm_vcpu *vcpu, u8 vec, u8 dmode, u8 trig); |
27 | 28 | ||
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index f0faf58044ff..46276273a1a1 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h | |||
@@ -286,6 +286,7 @@ struct kvm_vcpu_arch { | |||
286 | u64 shadow_efer; | 286 | u64 shadow_efer; |
287 | u64 apic_base; | 287 | u64 apic_base; |
288 | struct kvm_lapic *apic; /* kernel irqchip context */ | 288 | struct kvm_lapic *apic; /* kernel irqchip context */ |
289 | int32_t apic_arb_prio; | ||
289 | int mp_state; | 290 | int mp_state; |
290 | int sipi_vector; | 291 | int sipi_vector; |
291 | u64 ia32_misc_enable_msr; | 292 | u64 ia32_misc_enable_msr; |
@@ -400,7 +401,6 @@ struct kvm_arch{ | |||
400 | struct hlist_head irq_ack_notifier_list; | 401 | struct hlist_head irq_ack_notifier_list; |
401 | int vapics_in_nmi_mode; | 402 | int vapics_in_nmi_mode; |
402 | 403 | ||
403 | int round_robin_prev_vcpu; | ||
404 | unsigned int tss_addr; | 404 | unsigned int tss_addr; |
405 | struct page *apic_access_page; | 405 | struct page *apic_access_page; |
406 | 406 | ||
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 998862a3c267..814466f455d9 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c | |||
@@ -338,8 +338,9 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode, | |||
338 | struct kvm_vcpu *vcpu = apic->vcpu; | 338 | struct kvm_vcpu *vcpu = apic->vcpu; |
339 | 339 | ||
340 | switch (delivery_mode) { | 340 | switch (delivery_mode) { |
341 | case APIC_DM_FIXED: | ||
342 | case APIC_DM_LOWEST: | 341 | case APIC_DM_LOWEST: |
342 | vcpu->arch.apic_arb_prio++; | ||
343 | case APIC_DM_FIXED: | ||
343 | /* FIXME add logic for vcpu on reset */ | 344 | /* FIXME add logic for vcpu on reset */ |
344 | if (unlikely(!apic_enabled(apic))) | 345 | if (unlikely(!apic_enabled(apic))) |
345 | break; | 346 | break; |
@@ -416,43 +417,9 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode, | |||
416 | return result; | 417 | return result; |
417 | } | 418 | } |
418 | 419 | ||
419 | static struct kvm_lapic *kvm_apic_round_robin(struct kvm *kvm, u8 vector, | 420 | int kvm_apic_compare_prio(struct kvm_vcpu *vcpu1, struct kvm_vcpu *vcpu2) |
420 | unsigned long *bitmap) | ||
421 | { | 421 | { |
422 | int last; | 422 | return vcpu1->arch.apic_arb_prio - vcpu2->arch.apic_arb_prio; |
423 | int next; | ||
424 | struct kvm_lapic *apic = NULL; | ||
425 | |||
426 | last = kvm->arch.round_robin_prev_vcpu; | ||
427 | next = last; | ||
428 | |||
429 | do { | ||
430 | if (++next == KVM_MAX_VCPUS) | ||
431 | next = 0; | ||
432 | if (kvm->vcpus[next] == NULL || !test_bit(next, bitmap)) | ||
433 | continue; | ||
434 | apic = kvm->vcpus[next]->arch.apic; | ||
435 | if (apic && apic_enabled(apic)) | ||
436 | break; | ||
437 | apic = NULL; | ||
438 | } while (next != last); | ||
439 | kvm->arch.round_robin_prev_vcpu = next; | ||
440 | |||
441 | if (!apic) | ||
442 | printk(KERN_DEBUG "vcpu not ready for apic_round_robin\n"); | ||
443 | |||
444 | return apic; | ||
445 | } | ||
446 | |||
447 | struct kvm_vcpu *kvm_get_lowest_prio_vcpu(struct kvm *kvm, u8 vector, | ||
448 | unsigned long *bitmap) | ||
449 | { | ||
450 | struct kvm_lapic *apic; | ||
451 | |||
452 | apic = kvm_apic_round_robin(kvm, vector, bitmap); | ||
453 | if (apic) | ||
454 | return apic->vcpu; | ||
455 | return NULL; | ||
456 | } | 423 | } |
457 | 424 | ||
458 | static void apic_set_eoi(struct kvm_lapic *apic) | 425 | static void apic_set_eoi(struct kvm_lapic *apic) |
@@ -908,6 +875,8 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu) | |||
908 | vcpu->arch.apic_base |= MSR_IA32_APICBASE_BSP; | 875 | vcpu->arch.apic_base |= MSR_IA32_APICBASE_BSP; |
909 | apic_update_ppr(apic); | 876 | apic_update_ppr(apic); |
910 | 877 | ||
878 | vcpu->arch.apic_arb_prio = 0; | ||
879 | |||
911 | apic_debug(KERN_INFO "%s: vcpu=%p, id=%d, base_msr=" | 880 | apic_debug(KERN_INFO "%s: vcpu=%p, id=%d, base_msr=" |
912 | "0x%016" PRIx64 ", base_address=0x%0lx.\n", __func__, | 881 | "0x%016" PRIx64 ", base_address=0x%0lx.\n", __func__, |
913 | vcpu, kvm_apic_id(apic), | 882 | vcpu, kvm_apic_id(apic), |
diff --git a/virt/kvm/ioapic.h b/virt/kvm/ioapic.h index d996c7abc466..e7bc92d895ff 100644 --- a/virt/kvm/ioapic.h +++ b/virt/kvm/ioapic.h | |||
@@ -64,10 +64,9 @@ static inline struct kvm_ioapic *ioapic_irqchip(struct kvm *kvm) | |||
64 | return kvm->arch.vioapic; | 64 | return kvm->arch.vioapic; |
65 | } | 65 | } |
66 | 66 | ||
67 | struct kvm_vcpu *kvm_get_lowest_prio_vcpu(struct kvm *kvm, u8 vector, | ||
68 | unsigned long *bitmap); | ||
69 | int kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source, | 67 | int kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source, |
70 | int short_hand, int dest, int dest_mode); | 68 | int short_hand, int dest, int dest_mode); |
69 | int kvm_apic_compare_prio(struct kvm_vcpu *vcpu1, struct kvm_vcpu *vcpu2); | ||
71 | void kvm_ioapic_update_eoi(struct kvm *kvm, int vector, int trigger_mode); | 70 | void kvm_ioapic_update_eoi(struct kvm *kvm, int vector, int trigger_mode); |
72 | int kvm_ioapic_init(struct kvm *kvm); | 71 | int kvm_ioapic_init(struct kvm *kvm); |
73 | int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level); | 72 | int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level); |
diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c index e43701c0a5c4..f5e059b67cd4 100644 --- a/virt/kvm/irq_comm.c +++ b/virt/kvm/irq_comm.c | |||
@@ -47,7 +47,7 @@ void kvm_get_intr_delivery_bitmask(struct kvm *kvm, struct kvm_lapic *src, | |||
47 | int dest_id, int dest_mode, bool low_prio, int short_hand, | 47 | int dest_id, int dest_mode, bool low_prio, int short_hand, |
48 | unsigned long *deliver_bitmask) | 48 | unsigned long *deliver_bitmask) |
49 | { | 49 | { |
50 | int i; | 50 | int i, lowest = -1; |
51 | struct kvm_vcpu *vcpu; | 51 | struct kvm_vcpu *vcpu; |
52 | 52 | ||
53 | if (dest_mode == 0 && dest_id == 0xff && low_prio) | 53 | if (dest_mode == 0 && dest_id == 0xff && low_prio) |
@@ -64,15 +64,18 @@ void kvm_get_intr_delivery_bitmask(struct kvm *kvm, struct kvm_lapic *src, | |||
64 | dest_mode)) | 64 | dest_mode)) |
65 | continue; | 65 | continue; |
66 | 66 | ||
67 | __set_bit(i, deliver_bitmask); | 67 | if (!low_prio) { |
68 | __set_bit(i, deliver_bitmask); | ||
69 | } else { | ||
70 | if (lowest < 0) | ||
71 | lowest = i; | ||
72 | if (kvm_apic_compare_prio(vcpu, kvm->vcpus[lowest]) < 0) | ||
73 | lowest = i; | ||
74 | } | ||
68 | } | 75 | } |
69 | 76 | ||
70 | if (low_prio) { | 77 | if (lowest != -1) |
71 | vcpu = kvm_get_lowest_prio_vcpu(kvm, 0, deliver_bitmask); | 78 | __set_bit(lowest, deliver_bitmask); |
72 | bitmap_zero(deliver_bitmask, KVM_MAX_VCPUS); | ||
73 | if (vcpu) | ||
74 | __set_bit(vcpu->vcpu_id, deliver_bitmask); | ||
75 | } | ||
76 | } | 79 | } |
77 | 80 | ||
78 | static int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, | 81 | static int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, |