diff options
Diffstat (limited to 'arch/x86/kvm/lapic.c')
-rw-r--r-- | arch/x86/kvm/lapic.c | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 0cefba28c864..17c0472c5b34 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c | |||
@@ -548,7 +548,7 @@ int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq, | |||
548 | } | 548 | } |
549 | 549 | ||
550 | int kvm_pv_send_ipi(struct kvm *kvm, unsigned long ipi_bitmap_low, | 550 | int kvm_pv_send_ipi(struct kvm *kvm, unsigned long ipi_bitmap_low, |
551 | unsigned long ipi_bitmap_high, int min, | 551 | unsigned long ipi_bitmap_high, u32 min, |
552 | unsigned long icr, int op_64_bit) | 552 | unsigned long icr, int op_64_bit) |
553 | { | 553 | { |
554 | int i; | 554 | int i; |
@@ -571,18 +571,31 @@ int kvm_pv_send_ipi(struct kvm *kvm, unsigned long ipi_bitmap_low, | |||
571 | rcu_read_lock(); | 571 | rcu_read_lock(); |
572 | map = rcu_dereference(kvm->arch.apic_map); | 572 | map = rcu_dereference(kvm->arch.apic_map); |
573 | 573 | ||
574 | if (min > map->max_apic_id) | ||
575 | goto out; | ||
574 | /* Bits above cluster_size are masked in the caller. */ | 576 | /* Bits above cluster_size are masked in the caller. */ |
575 | for_each_set_bit(i, &ipi_bitmap_low, BITS_PER_LONG) { | 577 | for_each_set_bit(i, &ipi_bitmap_low, |
576 | vcpu = map->phys_map[min + i]->vcpu; | 578 | min((u32)BITS_PER_LONG, (map->max_apic_id - min + 1))) { |
577 | count += kvm_apic_set_irq(vcpu, &irq, NULL); | 579 | if (map->phys_map[min + i]) { |
580 | vcpu = map->phys_map[min + i]->vcpu; | ||
581 | count += kvm_apic_set_irq(vcpu, &irq, NULL); | ||
582 | } | ||
578 | } | 583 | } |
579 | 584 | ||
580 | min += cluster_size; | 585 | min += cluster_size; |
581 | for_each_set_bit(i, &ipi_bitmap_high, BITS_PER_LONG) { | 586 | |
582 | vcpu = map->phys_map[min + i]->vcpu; | 587 | if (min > map->max_apic_id) |
583 | count += kvm_apic_set_irq(vcpu, &irq, NULL); | 588 | goto out; |
589 | |||
590 | for_each_set_bit(i, &ipi_bitmap_high, | ||
591 | min((u32)BITS_PER_LONG, (map->max_apic_id - min + 1))) { | ||
592 | if (map->phys_map[min + i]) { | ||
593 | vcpu = map->phys_map[min + i]->vcpu; | ||
594 | count += kvm_apic_set_irq(vcpu, &irq, NULL); | ||
595 | } | ||
584 | } | 596 | } |
585 | 597 | ||
598 | out: | ||
586 | rcu_read_unlock(); | 599 | rcu_read_unlock(); |
587 | return count; | 600 | return count; |
588 | } | 601 | } |