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 | } |
