diff options
| author | Gleb Natapov <gleb@redhat.com> | 2009-03-05 09:34:54 -0500 |
|---|---|---|
| committer | Avi Kivity <avi@redhat.com> | 2009-06-10 04:48:27 -0400 |
| commit | 343f94fe4d16ec898da77720c03da9e09f8523d2 (patch) | |
| tree | fa0180a8446a90000086593b9fa8d4d81708ddd8 | |
| parent | a53c17d21c46a752f5ac6695376481bc27865b04 (diff) | |
KVM: consolidate ioapic/ipi interrupt delivery logic
Use kvm_apic_match_dest() in kvm_get_intr_delivery_bitmask() instead
of duplicating the same code. Use kvm_get_intr_delivery_bitmask() in
apic_send_ipi() to figure out ipi destination instead of reimplementing
the logic.
Signed-off-by: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
| -rw-r--r-- | arch/ia64/kvm/kvm-ia64.c | 8 | ||||
| -rw-r--r-- | arch/ia64/kvm/lapic.h | 3 | ||||
| -rw-r--r-- | arch/x86/kvm/lapic.c | 69 | ||||
| -rw-r--r-- | arch/x86/kvm/lapic.h | 2 | ||||
| -rw-r--r-- | include/linux/kvm_host.h | 5 | ||||
| -rw-r--r-- | virt/kvm/ioapic.c | 5 | ||||
| -rw-r--r-- | virt/kvm/ioapic.h | 10 | ||||
| -rw-r--r-- | virt/kvm/irq_comm.c | 74 |
8 files changed, 70 insertions, 106 deletions
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index 99d6d174d932..8eea9cba7b7c 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c | |||
| @@ -1852,6 +1852,14 @@ struct kvm_vcpu *kvm_get_lowest_prio_vcpu(struct kvm *kvm, u8 vector, | |||
| 1852 | return lvcpu; | 1852 | return lvcpu; |
| 1853 | } | 1853 | } |
| 1854 | 1854 | ||
| 1855 | int kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source, | ||
| 1856 | int short_hand, int dest, int dest_mode) | ||
| 1857 | { | ||
| 1858 | return (dest_mode == 0) ? | ||
| 1859 | kvm_apic_match_physical_addr(target, dest) : | ||
| 1860 | kvm_apic_match_logical_addr(target, dest); | ||
| 1861 | } | ||
| 1862 | |||
| 1855 | static int find_highest_bits(int *dat) | 1863 | static int find_highest_bits(int *dat) |
| 1856 | { | 1864 | { |
| 1857 | u32 bits, bitnum; | 1865 | u32 bits, bitnum; |
diff --git a/arch/ia64/kvm/lapic.h b/arch/ia64/kvm/lapic.h index cbcfaa6195c7..31602e7338d7 100644 --- a/arch/ia64/kvm/lapic.h +++ b/arch/ia64/kvm/lapic.h | |||
| @@ -20,6 +20,9 @@ void kvm_free_lapic(struct kvm_vcpu *vcpu); | |||
| 20 | 20 | ||
| 21 | int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest); | 21 | 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, | ||
| 24 | int short_hand, int dest, int dest_mode); | ||
| 25 | bool kvm_apic_present(struct kvm_vcpu *vcpu); | ||
| 23 | int kvm_apic_set_irq(struct kvm_vcpu *vcpu, u8 vec, u8 dmode, u8 trig); | 26 | int kvm_apic_set_irq(struct kvm_vcpu *vcpu, u8 vec, u8 dmode, u8 trig); |
| 24 | 27 | ||
| 25 | #endif | 28 | #endif |
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index a42f968a23e1..998862a3c267 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c | |||
| @@ -260,7 +260,7 @@ static void apic_set_tpr(struct kvm_lapic *apic, u32 tpr) | |||
| 260 | 260 | ||
| 261 | int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest) | 261 | int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest) |
| 262 | { | 262 | { |
| 263 | return kvm_apic_id(apic) == dest; | 263 | return dest == 0xff || kvm_apic_id(apic) == dest; |
| 264 | } | 264 | } |
| 265 | 265 | ||
| 266 | int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda) | 266 | int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda) |
| @@ -289,37 +289,34 @@ int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda) | |||
| 289 | return result; | 289 | return result; |
| 290 | } | 290 | } |
| 291 | 291 | ||
| 292 | static int apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source, | 292 | int kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source, |
| 293 | int short_hand, int dest, int dest_mode) | 293 | int short_hand, int dest, int dest_mode) |
| 294 | { | 294 | { |
| 295 | int result = 0; | 295 | int result = 0; |
| 296 | struct kvm_lapic *target = vcpu->arch.apic; | 296 | struct kvm_lapic *target = vcpu->arch.apic; |
| 297 | 297 | ||
| 298 | apic_debug("target %p, source %p, dest 0x%x, " | 298 | apic_debug("target %p, source %p, dest 0x%x, " |
| 299 | "dest_mode 0x%x, short_hand 0x%x", | 299 | "dest_mode 0x%x, short_hand 0x%x\n", |
| 300 | target, source, dest, dest_mode, short_hand); | 300 | target, source, dest, dest_mode, short_hand); |
| 301 | 301 | ||
| 302 | ASSERT(!target); | 302 | ASSERT(!target); |
| 303 | switch (short_hand) { | 303 | switch (short_hand) { |
| 304 | case APIC_DEST_NOSHORT: | 304 | case APIC_DEST_NOSHORT: |
| 305 | if (dest_mode == 0) { | 305 | if (dest_mode == 0) |
| 306 | /* Physical mode. */ | 306 | /* Physical mode. */ |
| 307 | if ((dest == 0xFF) || (dest == kvm_apic_id(target))) | 307 | result = kvm_apic_match_physical_addr(target, dest); |
| 308 | result = 1; | 308 | else |
| 309 | } else | ||
| 310 | /* Logical mode. */ | 309 | /* Logical mode. */ |
| 311 | result = kvm_apic_match_logical_addr(target, dest); | 310 | result = kvm_apic_match_logical_addr(target, dest); |
| 312 | break; | 311 | break; |
| 313 | case APIC_DEST_SELF: | 312 | case APIC_DEST_SELF: |
| 314 | if (target == source) | 313 | result = (target == source); |
| 315 | result = 1; | ||
| 316 | break; | 314 | break; |
| 317 | case APIC_DEST_ALLINC: | 315 | case APIC_DEST_ALLINC: |
| 318 | result = 1; | 316 | result = 1; |
| 319 | break; | 317 | break; |
| 320 | case APIC_DEST_ALLBUT: | 318 | case APIC_DEST_ALLBUT: |
| 321 | if (target != source) | 319 | result = (target != source); |
| 322 | result = 1; | ||
| 323 | break; | 320 | break; |
| 324 | default: | 321 | default: |
| 325 | printk(KERN_WARNING "Bad dest shorthand value %x\n", | 322 | printk(KERN_WARNING "Bad dest shorthand value %x\n", |
| @@ -492,38 +489,26 @@ static void apic_send_ipi(struct kvm_lapic *apic) | |||
| 492 | unsigned int delivery_mode = icr_low & APIC_MODE_MASK; | 489 | unsigned int delivery_mode = icr_low & APIC_MODE_MASK; |
| 493 | unsigned int vector = icr_low & APIC_VECTOR_MASK; | 490 | unsigned int vector = icr_low & APIC_VECTOR_MASK; |
| 494 | 491 | ||
| 495 | struct kvm_vcpu *target; | 492 | DECLARE_BITMAP(deliver_bitmask, KVM_MAX_VCPUS); |
| 496 | struct kvm_vcpu *vcpu; | ||
| 497 | DECLARE_BITMAP(lpr_map, KVM_MAX_VCPUS); | ||
| 498 | int i; | 493 | int i; |
| 499 | 494 | ||
| 500 | bitmap_zero(lpr_map, KVM_MAX_VCPUS); | ||
| 501 | apic_debug("icr_high 0x%x, icr_low 0x%x, " | 495 | apic_debug("icr_high 0x%x, icr_low 0x%x, " |
| 502 | "short_hand 0x%x, dest 0x%x, trig_mode 0x%x, level 0x%x, " | 496 | "short_hand 0x%x, dest 0x%x, trig_mode 0x%x, level 0x%x, " |
| 503 | "dest_mode 0x%x, delivery_mode 0x%x, vector 0x%x\n", | 497 | "dest_mode 0x%x, delivery_mode 0x%x, vector 0x%x\n", |
| 504 | icr_high, icr_low, short_hand, dest, | 498 | icr_high, icr_low, short_hand, dest, |
| 505 | trig_mode, level, dest_mode, delivery_mode, vector); | 499 | trig_mode, level, dest_mode, delivery_mode, vector); |
| 506 | 500 | ||
| 507 | for (i = 0; i < KVM_MAX_VCPUS; i++) { | 501 | kvm_get_intr_delivery_bitmask(apic->vcpu->kvm, apic, dest, dest_mode, |
| 508 | vcpu = apic->vcpu->kvm->vcpus[i]; | 502 | delivery_mode == APIC_DM_LOWEST, short_hand, |
| 509 | if (!vcpu) | 503 | deliver_bitmask); |
| 510 | continue; | 504 | |
| 511 | 505 | while ((i = find_first_bit(deliver_bitmask, KVM_MAX_VCPUS)) | |
| 512 | if (vcpu->arch.apic && | 506 | < KVM_MAX_VCPUS) { |
| 513 | apic_match_dest(vcpu, apic, short_hand, dest, dest_mode)) { | 507 | struct kvm_vcpu *vcpu = apic->vcpu->kvm->vcpus[i]; |
| 514 | if (delivery_mode == APIC_DM_LOWEST) | 508 | __clear_bit(i, deliver_bitmask); |
| 515 | __set_bit(vcpu->vcpu_id, lpr_map); | 509 | if (vcpu) |
| 516 | else | 510 | __apic_accept_irq(vcpu->arch.apic, delivery_mode, |
| 517 | __apic_accept_irq(vcpu->arch.apic, delivery_mode, | 511 | vector, level, trig_mode); |
| 518 | vector, level, trig_mode); | ||
| 519 | } | ||
| 520 | } | ||
| 521 | |||
| 522 | if (delivery_mode == APIC_DM_LOWEST) { | ||
| 523 | target = kvm_get_lowest_prio_vcpu(vcpu->kvm, vector, lpr_map); | ||
| 524 | if (target != NULL) | ||
| 525 | __apic_accept_irq(target->arch.apic, delivery_mode, | ||
| 526 | vector, level, trig_mode); | ||
| 527 | } | 512 | } |
| 528 | } | 513 | } |
| 529 | 514 | ||
| @@ -930,16 +915,14 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu) | |||
| 930 | } | 915 | } |
| 931 | EXPORT_SYMBOL_GPL(kvm_lapic_reset); | 916 | EXPORT_SYMBOL_GPL(kvm_lapic_reset); |
| 932 | 917 | ||
| 933 | int kvm_lapic_enabled(struct kvm_vcpu *vcpu) | 918 | bool kvm_apic_present(struct kvm_vcpu *vcpu) |
| 934 | { | 919 | { |
| 935 | struct kvm_lapic *apic = vcpu->arch.apic; | 920 | return vcpu->arch.apic && apic_hw_enabled(vcpu->arch.apic); |
| 936 | int ret = 0; | 921 | } |
| 937 | |||
| 938 | if (!apic) | ||
| 939 | return 0; | ||
| 940 | ret = apic_enabled(apic); | ||
| 941 | 922 | ||
| 942 | return ret; | 923 | int kvm_lapic_enabled(struct kvm_vcpu *vcpu) |
| 924 | { | ||
| 925 | return kvm_apic_present(vcpu) && apic_sw_enabled(vcpu->arch.apic); | ||
| 943 | } | 926 | } |
| 944 | EXPORT_SYMBOL_GPL(kvm_lapic_enabled); | 927 | EXPORT_SYMBOL_GPL(kvm_lapic_enabled); |
| 945 | 928 | ||
diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h index 1b0e3c03cb34..b66dc14a9698 100644 --- a/arch/x86/kvm/lapic.h +++ b/arch/x86/kvm/lapic.h | |||
| @@ -37,6 +37,8 @@ u64 kvm_get_apic_base(struct kvm_vcpu *vcpu); | |||
| 37 | void kvm_set_apic_base(struct kvm_vcpu *vcpu, u64 data); | 37 | void kvm_set_apic_base(struct kvm_vcpu *vcpu, u64 data); |
| 38 | void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu); | 38 | void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu); |
| 39 | int kvm_lapic_enabled(struct kvm_vcpu *vcpu); | 39 | int kvm_lapic_enabled(struct kvm_vcpu *vcpu); |
| 40 | bool kvm_apic_present(struct kvm_vcpu *vcpu); | ||
| 41 | bool kvm_lapic_present(struct kvm_vcpu *vcpu); | ||
| 40 | int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu); | 42 | int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu); |
| 41 | 43 | ||
| 42 | void kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr); | 44 | void kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr); |
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index ec9d078b1e8e..fb60f31c4fb3 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h | |||
| @@ -363,11 +363,6 @@ void kvm_unregister_irq_mask_notifier(struct kvm *kvm, int irq, | |||
| 363 | struct kvm_irq_mask_notifier *kimn); | 363 | struct kvm_irq_mask_notifier *kimn); |
| 364 | void kvm_fire_mask_notifiers(struct kvm *kvm, int irq, bool mask); | 364 | void kvm_fire_mask_notifiers(struct kvm *kvm, int irq, bool mask); |
| 365 | 365 | ||
| 366 | #ifdef __KVM_HAVE_IOAPIC | ||
| 367 | void kvm_get_intr_delivery_bitmask(struct kvm *kvm, | ||
| 368 | union kvm_ioapic_redirect_entry *entry, | ||
| 369 | unsigned long *deliver_bitmask); | ||
| 370 | #endif | ||
| 371 | int kvm_set_irq(struct kvm *kvm, int irq_source_id, int irq, int level); | 366 | int kvm_set_irq(struct kvm *kvm, int irq_source_id, int irq, int level); |
| 372 | void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin); | 367 | void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin); |
| 373 | void kvm_register_irq_ack_notifier(struct kvm *kvm, | 368 | void kvm_register_irq_ack_notifier(struct kvm *kvm, |
diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c index b71c0442cecf..43969bbf127f 100644 --- a/virt/kvm/ioapic.c +++ b/virt/kvm/ioapic.c | |||
| @@ -147,7 +147,10 @@ int ioapic_deliver_entry(struct kvm *kvm, union kvm_ioapic_redirect_entry *e) | |||
| 147 | DECLARE_BITMAP(deliver_bitmask, KVM_MAX_VCPUS); | 147 | DECLARE_BITMAP(deliver_bitmask, KVM_MAX_VCPUS); |
| 148 | int i, r = -1; | 148 | int i, r = -1; |
| 149 | 149 | ||
| 150 | kvm_get_intr_delivery_bitmask(kvm, e, deliver_bitmask); | 150 | kvm_get_intr_delivery_bitmask(kvm, NULL, e->fields.dest_id, |
| 151 | e->fields.dest_mode, | ||
| 152 | e->fields.delivery_mode == IOAPIC_LOWEST_PRIORITY, | ||
| 153 | 0, deliver_bitmask); | ||
| 151 | 154 | ||
| 152 | if (find_first_bit(deliver_bitmask, KVM_MAX_VCPUS) >= KVM_MAX_VCPUS) { | 155 | if (find_first_bit(deliver_bitmask, KVM_MAX_VCPUS) >= KVM_MAX_VCPUS) { |
| 153 | ioapic_debug("no target on destination\n"); | 156 | ioapic_debug("no target on destination\n"); |
diff --git a/virt/kvm/ioapic.h b/virt/kvm/ioapic.h index bedeea59cc1c..d996c7abc466 100644 --- a/virt/kvm/ioapic.h +++ b/virt/kvm/ioapic.h | |||
| @@ -65,13 +65,15 @@ static inline struct kvm_ioapic *ioapic_irqchip(struct kvm *kvm) | |||
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | struct kvm_vcpu *kvm_get_lowest_prio_vcpu(struct kvm *kvm, u8 vector, | 67 | struct kvm_vcpu *kvm_get_lowest_prio_vcpu(struct kvm *kvm, u8 vector, |
| 68 | unsigned long *bitmap); | 68 | unsigned long *bitmap); |
| 69 | int kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source, | ||
| 70 | int short_hand, int dest, int dest_mode); | ||
| 69 | void kvm_ioapic_update_eoi(struct kvm *kvm, int vector, int trigger_mode); | 71 | void kvm_ioapic_update_eoi(struct kvm *kvm, int vector, int trigger_mode); |
| 70 | int kvm_ioapic_init(struct kvm *kvm); | 72 | int kvm_ioapic_init(struct kvm *kvm); |
| 71 | int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level); | 73 | int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level); |
| 72 | void kvm_ioapic_reset(struct kvm_ioapic *ioapic); | 74 | void kvm_ioapic_reset(struct kvm_ioapic *ioapic); |
| 73 | void kvm_get_intr_delivery_bitmask(struct kvm *kvm, | 75 | void kvm_get_intr_delivery_bitmask(struct kvm *kvm, struct kvm_lapic *src, |
| 74 | union kvm_ioapic_redirect_entry *entry, | 76 | int dest_id, int dest_mode, bool low_prio, int short_hand, |
| 75 | unsigned long *deliver_bitmask); | 77 | unsigned long *deliver_bitmask); |
| 76 | int ioapic_deliver_entry(struct kvm *kvm, union kvm_ioapic_redirect_entry *e); | 78 | int ioapic_deliver_entry(struct kvm *kvm, union kvm_ioapic_redirect_entry *e); |
| 77 | #endif | 79 | #endif |
diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c index 35397a569b24..e43701c0a5c4 100644 --- a/virt/kvm/irq_comm.c +++ b/virt/kvm/irq_comm.c | |||
| @@ -43,67 +43,35 @@ static int kvm_set_ioapic_irq(struct kvm_kernel_irq_routing_entry *e, | |||
| 43 | return kvm_ioapic_set_irq(kvm->arch.vioapic, e->irqchip.pin, level); | 43 | return kvm_ioapic_set_irq(kvm->arch.vioapic, e->irqchip.pin, level); |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | void kvm_get_intr_delivery_bitmask(struct kvm *kvm, | 46 | void kvm_get_intr_delivery_bitmask(struct kvm *kvm, struct kvm_lapic *src, |
| 47 | union kvm_ioapic_redirect_entry *entry, | 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; |
| 51 | struct kvm_vcpu *vcpu; | 51 | struct kvm_vcpu *vcpu; |
| 52 | 52 | ||
| 53 | if (dest_mode == 0 && dest_id == 0xff && low_prio) | ||
| 54 | printk(KERN_INFO "kvm: apic: phys broadcast and lowest prio\n"); | ||
| 55 | |||
| 53 | bitmap_zero(deliver_bitmask, KVM_MAX_VCPUS); | 56 | bitmap_zero(deliver_bitmask, KVM_MAX_VCPUS); |
| 57 | for (i = 0; i < KVM_MAX_VCPUS; i++) { | ||
| 58 | vcpu = kvm->vcpus[i]; | ||
| 54 | 59 | ||
| 55 | if (entry->fields.dest_mode == 0) { /* Physical mode. */ | 60 | if (!vcpu || !kvm_apic_present(vcpu)) |
| 56 | if (entry->fields.dest_id == 0xFF) { /* Broadcast. */ | 61 | continue; |
| 57 | for (i = 0; i < KVM_MAX_VCPUS; ++i) | ||
| 58 | if (kvm->vcpus[i] && kvm->vcpus[i]->arch.apic) | ||
| 59 | __set_bit(i, deliver_bitmask); | ||
| 60 | /* Lowest priority shouldn't combine with broadcast */ | ||
| 61 | if (entry->fields.delivery_mode == | ||
| 62 | IOAPIC_LOWEST_PRIORITY && printk_ratelimit()) | ||
| 63 | printk(KERN_INFO "kvm: apic: phys broadcast " | ||
| 64 | "and lowest prio\n"); | ||
| 65 | return; | ||
| 66 | } | ||
| 67 | for (i = 0; i < KVM_MAX_VCPUS; ++i) { | ||
| 68 | vcpu = kvm->vcpus[i]; | ||
| 69 | if (!vcpu) | ||
| 70 | continue; | ||
| 71 | if (kvm_apic_match_physical_addr(vcpu->arch.apic, | ||
| 72 | entry->fields.dest_id)) { | ||
| 73 | if (vcpu->arch.apic) | ||
| 74 | __set_bit(i, deliver_bitmask); | ||
| 75 | break; | ||
| 76 | } | ||
| 77 | } | ||
| 78 | } else if (entry->fields.dest_id != 0) /* Logical mode, MDA non-zero. */ | ||
| 79 | for (i = 0; i < KVM_MAX_VCPUS; ++i) { | ||
| 80 | vcpu = kvm->vcpus[i]; | ||
| 81 | if (!vcpu) | ||
| 82 | continue; | ||
| 83 | if (vcpu->arch.apic && | ||
| 84 | kvm_apic_match_logical_addr(vcpu->arch.apic, | ||
| 85 | entry->fields.dest_id)) | ||
| 86 | __set_bit(i, deliver_bitmask); | ||
| 87 | } | ||
| 88 | 62 | ||
| 89 | switch (entry->fields.delivery_mode) { | 63 | if (!kvm_apic_match_dest(vcpu, src, short_hand, dest_id, |
| 90 | case IOAPIC_LOWEST_PRIORITY: | 64 | dest_mode)) |
| 91 | /* Select one in deliver_bitmask */ | 65 | continue; |
| 92 | vcpu = kvm_get_lowest_prio_vcpu(kvm, | 66 | |
| 93 | entry->fields.vector, deliver_bitmask); | 67 | __set_bit(i, deliver_bitmask); |
| 94 | bitmap_zero(deliver_bitmask, KVM_MAX_VCPUS); | 68 | } |
| 95 | if (!vcpu) | 69 | |
| 96 | return; | 70 | if (low_prio) { |
| 97 | __set_bit(vcpu->vcpu_id, deliver_bitmask); | 71 | vcpu = kvm_get_lowest_prio_vcpu(kvm, 0, deliver_bitmask); |
| 98 | break; | ||
| 99 | case IOAPIC_FIXED: | ||
| 100 | case IOAPIC_NMI: | ||
| 101 | break; | ||
| 102 | default: | ||
| 103 | if (printk_ratelimit()) | ||
| 104 | printk(KERN_INFO "kvm: unsupported delivery mode %d\n", | ||
| 105 | entry->fields.delivery_mode); | ||
| 106 | bitmap_zero(deliver_bitmask, KVM_MAX_VCPUS); | 72 | bitmap_zero(deliver_bitmask, KVM_MAX_VCPUS); |
| 73 | if (vcpu) | ||
| 74 | __set_bit(vcpu->vcpu_id, deliver_bitmask); | ||
| 107 | } | 75 | } |
| 108 | } | 76 | } |
| 109 | 77 | ||
