diff options
| author | Paolo Bonzini <pbonzini@redhat.com> | 2015-06-19 11:15:24 -0400 |
|---|---|---|
| committer | Paolo Bonzini <pbonzini@redhat.com> | 2015-06-19 11:15:24 -0400 |
| commit | 05fe125fa3237de2ec5bada80031e694de78909c (patch) | |
| tree | 9e8cec45a5ded37b04c92a7a94dd1eefb5259344 /virt | |
| parent | e80a4a9426adeaa34c009bc0bc61365e0580bf01 (diff) | |
| parent | c62e631d4a8e41493c6341d8259e996ed5fc11e3 (diff) | |
Merge tag 'kvm-arm-for-4.2' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into HEAD
KVM/ARM changes for v4.2:
- Proper guest time accounting
- FP access fix for 32bit
- The usual pile of GIC fixes
- PSCI fixes
- Random cleanups
Diffstat (limited to 'virt')
| -rw-r--r-- | virt/kvm/arm/vgic-v3-emul.c | 56 | ||||
| -rw-r--r-- | virt/kvm/arm/vgic.c | 7 |
2 files changed, 51 insertions, 12 deletions
diff --git a/virt/kvm/arm/vgic-v3-emul.c b/virt/kvm/arm/vgic-v3-emul.c index e9c3a7a83833..e661e7fb9d91 100644 --- a/virt/kvm/arm/vgic-v3-emul.c +++ b/virt/kvm/arm/vgic-v3-emul.c | |||
| @@ -76,8 +76,6 @@ static bool handle_mmio_ctlr(struct kvm_vcpu *vcpu, | |||
| 76 | vgic_reg_access(mmio, ®, offset, | 76 | vgic_reg_access(mmio, ®, offset, |
| 77 | ACCESS_READ_VALUE | ACCESS_WRITE_VALUE); | 77 | ACCESS_READ_VALUE | ACCESS_WRITE_VALUE); |
| 78 | if (mmio->is_write) { | 78 | if (mmio->is_write) { |
| 79 | if (reg & GICD_CTLR_ENABLE_SS_G0) | ||
| 80 | kvm_info("guest tried to enable unsupported Group0 interrupts\n"); | ||
| 81 | vcpu->kvm->arch.vgic.enabled = !!(reg & GICD_CTLR_ENABLE_SS_G1); | 79 | vcpu->kvm->arch.vgic.enabled = !!(reg & GICD_CTLR_ENABLE_SS_G1); |
| 82 | vgic_update_state(vcpu->kvm); | 80 | vgic_update_state(vcpu->kvm); |
| 83 | return true; | 81 | return true; |
| @@ -173,6 +171,32 @@ static bool handle_mmio_clear_pending_reg_dist(struct kvm_vcpu *vcpu, | |||
| 173 | return false; | 171 | return false; |
| 174 | } | 172 | } |
| 175 | 173 | ||
| 174 | static bool handle_mmio_set_active_reg_dist(struct kvm_vcpu *vcpu, | ||
| 175 | struct kvm_exit_mmio *mmio, | ||
| 176 | phys_addr_t offset) | ||
| 177 | { | ||
| 178 | if (likely(offset >= VGIC_NR_PRIVATE_IRQS / 8)) | ||
| 179 | return vgic_handle_set_active_reg(vcpu->kvm, mmio, offset, | ||
| 180 | vcpu->vcpu_id); | ||
| 181 | |||
| 182 | vgic_reg_access(mmio, NULL, offset, | ||
| 183 | ACCESS_READ_RAZ | ACCESS_WRITE_IGNORED); | ||
| 184 | return false; | ||
| 185 | } | ||
| 186 | |||
| 187 | static bool handle_mmio_clear_active_reg_dist(struct kvm_vcpu *vcpu, | ||
| 188 | struct kvm_exit_mmio *mmio, | ||
| 189 | phys_addr_t offset) | ||
| 190 | { | ||
| 191 | if (likely(offset >= VGIC_NR_PRIVATE_IRQS / 8)) | ||
| 192 | return vgic_handle_clear_active_reg(vcpu->kvm, mmio, offset, | ||
| 193 | vcpu->vcpu_id); | ||
| 194 | |||
| 195 | vgic_reg_access(mmio, NULL, offset, | ||
| 196 | ACCESS_READ_RAZ | ACCESS_WRITE_IGNORED); | ||
| 197 | return false; | ||
| 198 | } | ||
| 199 | |||
| 176 | static bool handle_mmio_priority_reg_dist(struct kvm_vcpu *vcpu, | 200 | static bool handle_mmio_priority_reg_dist(struct kvm_vcpu *vcpu, |
| 177 | struct kvm_exit_mmio *mmio, | 201 | struct kvm_exit_mmio *mmio, |
| 178 | phys_addr_t offset) | 202 | phys_addr_t offset) |
| @@ -428,13 +452,13 @@ static const struct vgic_io_range vgic_v3_dist_ranges[] = { | |||
| 428 | .base = GICD_ISACTIVER, | 452 | .base = GICD_ISACTIVER, |
| 429 | .len = 0x80, | 453 | .len = 0x80, |
| 430 | .bits_per_irq = 1, | 454 | .bits_per_irq = 1, |
| 431 | .handle_mmio = handle_mmio_raz_wi, | 455 | .handle_mmio = handle_mmio_set_active_reg_dist, |
| 432 | }, | 456 | }, |
| 433 | { | 457 | { |
| 434 | .base = GICD_ICACTIVER, | 458 | .base = GICD_ICACTIVER, |
| 435 | .len = 0x80, | 459 | .len = 0x80, |
| 436 | .bits_per_irq = 1, | 460 | .bits_per_irq = 1, |
| 437 | .handle_mmio = handle_mmio_raz_wi, | 461 | .handle_mmio = handle_mmio_clear_active_reg_dist, |
| 438 | }, | 462 | }, |
| 439 | { | 463 | { |
| 440 | .base = GICD_IPRIORITYR, | 464 | .base = GICD_IPRIORITYR, |
| @@ -561,6 +585,26 @@ static bool handle_mmio_clear_enable_reg_redist(struct kvm_vcpu *vcpu, | |||
| 561 | ACCESS_WRITE_CLEARBIT); | 585 | ACCESS_WRITE_CLEARBIT); |
| 562 | } | 586 | } |
| 563 | 587 | ||
| 588 | static bool handle_mmio_set_active_reg_redist(struct kvm_vcpu *vcpu, | ||
| 589 | struct kvm_exit_mmio *mmio, | ||
| 590 | phys_addr_t offset) | ||
| 591 | { | ||
| 592 | struct kvm_vcpu *redist_vcpu = mmio->private; | ||
| 593 | |||
| 594 | return vgic_handle_set_active_reg(vcpu->kvm, mmio, offset, | ||
| 595 | redist_vcpu->vcpu_id); | ||
| 596 | } | ||
| 597 | |||
| 598 | static bool handle_mmio_clear_active_reg_redist(struct kvm_vcpu *vcpu, | ||
| 599 | struct kvm_exit_mmio *mmio, | ||
| 600 | phys_addr_t offset) | ||
| 601 | { | ||
| 602 | struct kvm_vcpu *redist_vcpu = mmio->private; | ||
| 603 | |||
| 604 | return vgic_handle_clear_active_reg(vcpu->kvm, mmio, offset, | ||
| 605 | redist_vcpu->vcpu_id); | ||
| 606 | } | ||
| 607 | |||
| 564 | static bool handle_mmio_set_pending_reg_redist(struct kvm_vcpu *vcpu, | 608 | static bool handle_mmio_set_pending_reg_redist(struct kvm_vcpu *vcpu, |
| 565 | struct kvm_exit_mmio *mmio, | 609 | struct kvm_exit_mmio *mmio, |
| 566 | phys_addr_t offset) | 610 | phys_addr_t offset) |
| @@ -674,13 +718,13 @@ static const struct vgic_io_range vgic_redist_ranges[] = { | |||
| 674 | .base = SGI_base(GICR_ISACTIVER0), | 718 | .base = SGI_base(GICR_ISACTIVER0), |
| 675 | .len = 0x04, | 719 | .len = 0x04, |
| 676 | .bits_per_irq = 1, | 720 | .bits_per_irq = 1, |
| 677 | .handle_mmio = handle_mmio_raz_wi, | 721 | .handle_mmio = handle_mmio_set_active_reg_redist, |
| 678 | }, | 722 | }, |
| 679 | { | 723 | { |
| 680 | .base = SGI_base(GICR_ICACTIVER0), | 724 | .base = SGI_base(GICR_ICACTIVER0), |
| 681 | .len = 0x04, | 725 | .len = 0x04, |
| 682 | .bits_per_irq = 1, | 726 | .bits_per_irq = 1, |
| 683 | .handle_mmio = handle_mmio_raz_wi, | 727 | .handle_mmio = handle_mmio_clear_active_reg_redist, |
| 684 | }, | 728 | }, |
| 685 | { | 729 | { |
| 686 | .base = SGI_base(GICR_IPRIORITYR0), | 730 | .base = SGI_base(GICR_IPRIORITYR0), |
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c index 78fb8201014f..f94d887d20e6 100644 --- a/virt/kvm/arm/vgic.c +++ b/virt/kvm/arm/vgic.c | |||
| @@ -26,8 +26,6 @@ | |||
| 26 | #include <linux/of_irq.h> | 26 | #include <linux/of_irq.h> |
| 27 | #include <linux/uaccess.h> | 27 | #include <linux/uaccess.h> |
| 28 | 28 | ||
| 29 | #include <linux/irqchip/arm-gic.h> | ||
| 30 | |||
| 31 | #include <asm/kvm_emulate.h> | 29 | #include <asm/kvm_emulate.h> |
| 32 | #include <asm/kvm_arm.h> | 30 | #include <asm/kvm_arm.h> |
| 33 | #include <asm/kvm_mmu.h> | 31 | #include <asm/kvm_mmu.h> |
| @@ -1561,7 +1559,7 @@ int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num, | |||
| 1561 | goto out; | 1559 | goto out; |
| 1562 | } | 1560 | } |
| 1563 | 1561 | ||
| 1564 | if (irq_num >= kvm->arch.vgic.nr_irqs) | 1562 | if (irq_num >= min(kvm->arch.vgic.nr_irqs, 1020)) |
| 1565 | return -EINVAL; | 1563 | return -EINVAL; |
| 1566 | 1564 | ||
| 1567 | vcpu_id = vgic_update_irq_pending(kvm, cpuid, irq_num, level); | 1565 | vcpu_id = vgic_update_irq_pending(kvm, cpuid, irq_num, level); |
| @@ -2161,10 +2159,7 @@ int kvm_set_irq(struct kvm *kvm, int irq_source_id, | |||
| 2161 | 2159 | ||
| 2162 | BUG_ON(!vgic_initialized(kvm)); | 2160 | BUG_ON(!vgic_initialized(kvm)); |
| 2163 | 2161 | ||
| 2164 | if (spi > kvm->arch.vgic.nr_irqs) | ||
| 2165 | return -EINVAL; | ||
| 2166 | return kvm_vgic_inject_irq(kvm, 0, spi, level); | 2162 | return kvm_vgic_inject_irq(kvm, 0, spi, level); |
| 2167 | |||
| 2168 | } | 2163 | } |
| 2169 | 2164 | ||
| 2170 | /* MSI not implemented yet */ | 2165 | /* MSI not implemented yet */ |
