diff options
| author | Paolo Bonzini <pbonzini@redhat.com> | 2019-04-30 15:23:06 -0400 |
|---|---|---|
| committer | Paolo Bonzini <pbonzini@redhat.com> | 2019-04-30 15:23:06 -0400 |
| commit | 6245242d9145815c3f4be71f7d8af858f7c66319 (patch) | |
| tree | ddfa711ca06d00c55adbddb4ba64b09acf427a02 | |
| parent | eba3afde1cea7dbd7881683232f2a85e2ed86bfe (diff) | |
| parent | 6bc210003dff7b789efae5bb02a0320dc24dd416 (diff) | |
Merge tag 'kvmarm-fixes-for-5.1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into kvm-master
KVM/ARM fixes for 5.1, take #2:
- Don't try to emulate timers on userspace access
- Fix unaligned huge mappings, again
- Properly reset a vcpu that fails to reset(!)
- Properly retire pending LPIs on reset
- Fix computation of emulated CNTP_TVAL
| -rw-r--r-- | virt/kvm/arm/arch_timer.c | 17 | ||||
| -rw-r--r-- | virt/kvm/arm/arm.c | 11 | ||||
| -rw-r--r-- | virt/kvm/arm/mmu.c | 6 | ||||
| -rw-r--r-- | virt/kvm/arm/vgic/vgic-mmio-v3.c | 3 | ||||
| -rw-r--r-- | virt/kvm/arm/vgic/vgic.c | 21 | ||||
| -rw-r--r-- | virt/kvm/arm/vgic/vgic.h | 1 |
6 files changed, 48 insertions, 11 deletions
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c index 3417f2dbc366..7fc272ecae16 100644 --- a/virt/kvm/arm/arch_timer.c +++ b/virt/kvm/arm/arch_timer.c | |||
| @@ -508,6 +508,14 @@ static void kvm_timer_vcpu_load_nogic(struct kvm_vcpu *vcpu) | |||
| 508 | struct arch_timer_context *vtimer = vcpu_vtimer(vcpu); | 508 | struct arch_timer_context *vtimer = vcpu_vtimer(vcpu); |
| 509 | 509 | ||
| 510 | /* | 510 | /* |
| 511 | * Update the timer output so that it is likely to match the | ||
| 512 | * state we're about to restore. If the timer expires between | ||
| 513 | * this point and the register restoration, we'll take the | ||
| 514 | * interrupt anyway. | ||
| 515 | */ | ||
| 516 | kvm_timer_update_irq(vcpu, kvm_timer_should_fire(vtimer), vtimer); | ||
| 517 | |||
| 518 | /* | ||
| 511 | * When using a userspace irqchip with the architected timers and a | 519 | * When using a userspace irqchip with the architected timers and a |
| 512 | * host interrupt controller that doesn't support an active state, we | 520 | * host interrupt controller that doesn't support an active state, we |
| 513 | * must still prevent continuously exiting from the guest, and | 521 | * must still prevent continuously exiting from the guest, and |
| @@ -730,7 +738,6 @@ static void kvm_timer_init_interrupt(void *info) | |||
| 730 | int kvm_arm_timer_set_reg(struct kvm_vcpu *vcpu, u64 regid, u64 value) | 738 | int kvm_arm_timer_set_reg(struct kvm_vcpu *vcpu, u64 regid, u64 value) |
| 731 | { | 739 | { |
| 732 | struct arch_timer_context *timer; | 740 | struct arch_timer_context *timer; |
| 733 | bool level; | ||
| 734 | 741 | ||
| 735 | switch (regid) { | 742 | switch (regid) { |
| 736 | case KVM_REG_ARM_TIMER_CTL: | 743 | case KVM_REG_ARM_TIMER_CTL: |
| @@ -758,10 +765,6 @@ int kvm_arm_timer_set_reg(struct kvm_vcpu *vcpu, u64 regid, u64 value) | |||
| 758 | return -1; | 765 | return -1; |
| 759 | } | 766 | } |
| 760 | 767 | ||
| 761 | level = kvm_timer_should_fire(timer); | ||
| 762 | kvm_timer_update_irq(vcpu, level, timer); | ||
| 763 | timer_emulate(timer); | ||
| 764 | |||
| 765 | return 0; | 768 | return 0; |
| 766 | } | 769 | } |
| 767 | 770 | ||
| @@ -812,7 +815,7 @@ static u64 kvm_arm_timer_read(struct kvm_vcpu *vcpu, | |||
| 812 | 815 | ||
| 813 | switch (treg) { | 816 | switch (treg) { |
| 814 | case TIMER_REG_TVAL: | 817 | case TIMER_REG_TVAL: |
| 815 | val = kvm_phys_timer_read() - timer->cntvoff - timer->cnt_cval; | 818 | val = timer->cnt_cval - kvm_phys_timer_read() + timer->cntvoff; |
| 816 | break; | 819 | break; |
| 817 | 820 | ||
| 818 | case TIMER_REG_CTL: | 821 | case TIMER_REG_CTL: |
| @@ -858,7 +861,7 @@ static void kvm_arm_timer_write(struct kvm_vcpu *vcpu, | |||
| 858 | { | 861 | { |
| 859 | switch (treg) { | 862 | switch (treg) { |
| 860 | case TIMER_REG_TVAL: | 863 | case TIMER_REG_TVAL: |
| 861 | timer->cnt_cval = val - kvm_phys_timer_read() - timer->cntvoff; | 864 | timer->cnt_cval = kvm_phys_timer_read() - timer->cntvoff + val; |
| 862 | break; | 865 | break; |
| 863 | 866 | ||
| 864 | case TIMER_REG_CTL: | 867 | case TIMER_REG_CTL: |
diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c index 99c37384ba7b..f412ebc90610 100644 --- a/virt/kvm/arm/arm.c +++ b/virt/kvm/arm/arm.c | |||
| @@ -934,7 +934,7 @@ int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irq_level, | |||
| 934 | static int kvm_vcpu_set_target(struct kvm_vcpu *vcpu, | 934 | static int kvm_vcpu_set_target(struct kvm_vcpu *vcpu, |
| 935 | const struct kvm_vcpu_init *init) | 935 | const struct kvm_vcpu_init *init) |
| 936 | { | 936 | { |
| 937 | unsigned int i; | 937 | unsigned int i, ret; |
| 938 | int phys_target = kvm_target_cpu(); | 938 | int phys_target = kvm_target_cpu(); |
| 939 | 939 | ||
| 940 | if (init->target != phys_target) | 940 | if (init->target != phys_target) |
| @@ -969,9 +969,14 @@ static int kvm_vcpu_set_target(struct kvm_vcpu *vcpu, | |||
| 969 | vcpu->arch.target = phys_target; | 969 | vcpu->arch.target = phys_target; |
| 970 | 970 | ||
| 971 | /* Now we know what it is, we can reset it. */ | 971 | /* Now we know what it is, we can reset it. */ |
| 972 | return kvm_reset_vcpu(vcpu); | 972 | ret = kvm_reset_vcpu(vcpu); |
| 973 | } | 973 | if (ret) { |
| 974 | vcpu->arch.target = -1; | ||
| 975 | bitmap_zero(vcpu->arch.features, KVM_VCPU_MAX_FEATURES); | ||
| 976 | } | ||
| 974 | 977 | ||
| 978 | return ret; | ||
| 979 | } | ||
| 975 | 980 | ||
| 976 | static int kvm_arch_vcpu_ioctl_vcpu_init(struct kvm_vcpu *vcpu, | 981 | static int kvm_arch_vcpu_ioctl_vcpu_init(struct kvm_vcpu *vcpu, |
| 977 | struct kvm_vcpu_init *init) | 982 | struct kvm_vcpu_init *init) |
diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c index 27c958306449..a39dcfdbcc65 100644 --- a/virt/kvm/arm/mmu.c +++ b/virt/kvm/arm/mmu.c | |||
| @@ -1781,8 +1781,12 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, | |||
| 1781 | * Only PMD_SIZE transparent hugepages(THP) are | 1781 | * Only PMD_SIZE transparent hugepages(THP) are |
| 1782 | * currently supported. This code will need to be | 1782 | * currently supported. This code will need to be |
| 1783 | * updated to support other THP sizes. | 1783 | * updated to support other THP sizes. |
| 1784 | * | ||
| 1785 | * Make sure the host VA and the guest IPA are sufficiently | ||
| 1786 | * aligned and that the block is contained within the memslot. | ||
| 1784 | */ | 1787 | */ |
| 1785 | if (transparent_hugepage_adjust(&pfn, &fault_ipa)) | 1788 | if (fault_supports_stage2_huge_mapping(memslot, hva, PMD_SIZE) && |
| 1789 | transparent_hugepage_adjust(&pfn, &fault_ipa)) | ||
| 1786 | vma_pagesize = PMD_SIZE; | 1790 | vma_pagesize = PMD_SIZE; |
| 1787 | } | 1791 | } |
| 1788 | 1792 | ||
diff --git a/virt/kvm/arm/vgic/vgic-mmio-v3.c b/virt/kvm/arm/vgic/vgic-mmio-v3.c index 4a12322bf7df..9f4843fe9cda 100644 --- a/virt/kvm/arm/vgic/vgic-mmio-v3.c +++ b/virt/kvm/arm/vgic/vgic-mmio-v3.c | |||
| @@ -200,6 +200,9 @@ static void vgic_mmio_write_v3r_ctlr(struct kvm_vcpu *vcpu, | |||
| 200 | 200 | ||
| 201 | vgic_cpu->lpis_enabled = val & GICR_CTLR_ENABLE_LPIS; | 201 | vgic_cpu->lpis_enabled = val & GICR_CTLR_ENABLE_LPIS; |
| 202 | 202 | ||
| 203 | if (was_enabled && !vgic_cpu->lpis_enabled) | ||
| 204 | vgic_flush_pending_lpis(vcpu); | ||
| 205 | |||
| 203 | if (!was_enabled && vgic_cpu->lpis_enabled) | 206 | if (!was_enabled && vgic_cpu->lpis_enabled) |
| 204 | vgic_enable_lpis(vcpu); | 207 | vgic_enable_lpis(vcpu); |
| 205 | } | 208 | } |
diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c index 3af69f2a3866..191deccf60bf 100644 --- a/virt/kvm/arm/vgic/vgic.c +++ b/virt/kvm/arm/vgic/vgic.c | |||
| @@ -151,6 +151,27 @@ void vgic_put_irq(struct kvm *kvm, struct vgic_irq *irq) | |||
| 151 | kfree(irq); | 151 | kfree(irq); |
| 152 | } | 152 | } |
| 153 | 153 | ||
| 154 | void vgic_flush_pending_lpis(struct kvm_vcpu *vcpu) | ||
| 155 | { | ||
| 156 | struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; | ||
| 157 | struct vgic_irq *irq, *tmp; | ||
| 158 | unsigned long flags; | ||
| 159 | |||
| 160 | raw_spin_lock_irqsave(&vgic_cpu->ap_list_lock, flags); | ||
| 161 | |||
| 162 | list_for_each_entry_safe(irq, tmp, &vgic_cpu->ap_list_head, ap_list) { | ||
| 163 | if (irq->intid >= VGIC_MIN_LPI) { | ||
| 164 | raw_spin_lock(&irq->irq_lock); | ||
| 165 | list_del(&irq->ap_list); | ||
| 166 | irq->vcpu = NULL; | ||
| 167 | raw_spin_unlock(&irq->irq_lock); | ||
| 168 | vgic_put_irq(vcpu->kvm, irq); | ||
| 169 | } | ||
| 170 | } | ||
| 171 | |||
| 172 | raw_spin_unlock_irqrestore(&vgic_cpu->ap_list_lock, flags); | ||
| 173 | } | ||
| 174 | |||
| 154 | void vgic_irq_set_phys_pending(struct vgic_irq *irq, bool pending) | 175 | void vgic_irq_set_phys_pending(struct vgic_irq *irq, bool pending) |
| 155 | { | 176 | { |
| 156 | WARN_ON(irq_set_irqchip_state(irq->host_irq, | 177 | WARN_ON(irq_set_irqchip_state(irq->host_irq, |
diff --git a/virt/kvm/arm/vgic/vgic.h b/virt/kvm/arm/vgic/vgic.h index a90024718ca4..abeeffabc456 100644 --- a/virt/kvm/arm/vgic/vgic.h +++ b/virt/kvm/arm/vgic/vgic.h | |||
| @@ -238,6 +238,7 @@ void vgic_v3_put(struct kvm_vcpu *vcpu); | |||
| 238 | bool vgic_has_its(struct kvm *kvm); | 238 | bool vgic_has_its(struct kvm *kvm); |
| 239 | int kvm_vgic_register_its_device(void); | 239 | int kvm_vgic_register_its_device(void); |
| 240 | void vgic_enable_lpis(struct kvm_vcpu *vcpu); | 240 | void vgic_enable_lpis(struct kvm_vcpu *vcpu); |
| 241 | void vgic_flush_pending_lpis(struct kvm_vcpu *vcpu); | ||
| 241 | int vgic_its_inject_msi(struct kvm *kvm, struct kvm_msi *msi); | 242 | int vgic_its_inject_msi(struct kvm *kvm, struct kvm_msi *msi); |
| 242 | int vgic_v3_has_attr_regs(struct kvm_device *dev, struct kvm_device_attr *attr); | 243 | int vgic_v3_has_attr_regs(struct kvm_device *dev, struct kvm_device_attr *attr); |
| 243 | int vgic_v3_dist_uaccess(struct kvm_vcpu *vcpu, bool is_write, | 244 | int vgic_v3_dist_uaccess(struct kvm_vcpu *vcpu, bool is_write, |
