diff options
| -rw-r--r-- | arch/x86/include/asm/kvm_host.h | 2 | ||||
| -rw-r--r-- | arch/x86/kvm/lapic.c | 27 |
2 files changed, 21 insertions, 8 deletions
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 3ad10f634d4c..8e90488c3d56 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h | |||
| @@ -1455,7 +1455,7 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event); | |||
| 1455 | void kvm_vcpu_reload_apic_access_page(struct kvm_vcpu *vcpu); | 1455 | void kvm_vcpu_reload_apic_access_page(struct kvm_vcpu *vcpu); |
| 1456 | 1456 | ||
| 1457 | int kvm_pv_send_ipi(struct kvm *kvm, unsigned long ipi_bitmap_low, | 1457 | int kvm_pv_send_ipi(struct kvm *kvm, unsigned long ipi_bitmap_low, |
| 1458 | unsigned long ipi_bitmap_high, int min, | 1458 | unsigned long ipi_bitmap_high, u32 min, |
| 1459 | unsigned long icr, int op_64_bit); | 1459 | unsigned long icr, int op_64_bit); |
| 1460 | 1460 | ||
| 1461 | u64 kvm_get_arch_capabilities(void); | 1461 | u64 kvm_get_arch_capabilities(void); |
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 | } |
