diff options
Diffstat (limited to 'arch/x86/kvm/lapic.c')
-rw-r--r-- | arch/x86/kvm/lapic.c | 49 |
1 files changed, 39 insertions, 10 deletions
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 0cefba28c864..fbb0e6df121b 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 | } |
@@ -1331,9 +1344,8 @@ EXPORT_SYMBOL_GPL(kvm_lapic_reg_read); | |||
1331 | 1344 | ||
1332 | static int apic_mmio_in_range(struct kvm_lapic *apic, gpa_t addr) | 1345 | static int apic_mmio_in_range(struct kvm_lapic *apic, gpa_t addr) |
1333 | { | 1346 | { |
1334 | return kvm_apic_hw_enabled(apic) && | 1347 | return addr >= apic->base_address && |
1335 | addr >= apic->base_address && | 1348 | addr < apic->base_address + LAPIC_MMIO_LENGTH; |
1336 | addr < apic->base_address + LAPIC_MMIO_LENGTH; | ||
1337 | } | 1349 | } |
1338 | 1350 | ||
1339 | static int apic_mmio_read(struct kvm_vcpu *vcpu, struct kvm_io_device *this, | 1351 | static int apic_mmio_read(struct kvm_vcpu *vcpu, struct kvm_io_device *this, |
@@ -1345,6 +1357,15 @@ static int apic_mmio_read(struct kvm_vcpu *vcpu, struct kvm_io_device *this, | |||
1345 | if (!apic_mmio_in_range(apic, address)) | 1357 | if (!apic_mmio_in_range(apic, address)) |
1346 | return -EOPNOTSUPP; | 1358 | return -EOPNOTSUPP; |
1347 | 1359 | ||
1360 | if (!kvm_apic_hw_enabled(apic) || apic_x2apic_mode(apic)) { | ||
1361 | if (!kvm_check_has_quirk(vcpu->kvm, | ||
1362 | KVM_X86_QUIRK_LAPIC_MMIO_HOLE)) | ||
1363 | return -EOPNOTSUPP; | ||
1364 | |||
1365 | memset(data, 0xff, len); | ||
1366 | return 0; | ||
1367 | } | ||
1368 | |||
1348 | kvm_lapic_reg_read(apic, offset, len, data); | 1369 | kvm_lapic_reg_read(apic, offset, len, data); |
1349 | 1370 | ||
1350 | return 0; | 1371 | return 0; |
@@ -1904,6 +1925,14 @@ static int apic_mmio_write(struct kvm_vcpu *vcpu, struct kvm_io_device *this, | |||
1904 | if (!apic_mmio_in_range(apic, address)) | 1925 | if (!apic_mmio_in_range(apic, address)) |
1905 | return -EOPNOTSUPP; | 1926 | return -EOPNOTSUPP; |
1906 | 1927 | ||
1928 | if (!kvm_apic_hw_enabled(apic) || apic_x2apic_mode(apic)) { | ||
1929 | if (!kvm_check_has_quirk(vcpu->kvm, | ||
1930 | KVM_X86_QUIRK_LAPIC_MMIO_HOLE)) | ||
1931 | return -EOPNOTSUPP; | ||
1932 | |||
1933 | return 0; | ||
1934 | } | ||
1935 | |||
1907 | /* | 1936 | /* |
1908 | * APIC register must be aligned on 128-bits boundary. | 1937 | * APIC register must be aligned on 128-bits boundary. |
1909 | * 32/64/128 bits registers must be accessed thru 32 bits. | 1938 | * 32/64/128 bits registers must be accessed thru 32 bits. |