No need to check for interrupts to be retired on the run path. We can as well do it when accessing the clear_enable register. Also fix a bug when retiring level interrupts, they could be left active forever. Signed-off-by: Marc Zyngier <marc.zyngier@xxxxxxx> --- arch/arm/kvm/vgic.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/arm/kvm/vgic.c b/arch/arm/kvm/vgic.c index d666df7..df4f19d 100644 --- a/arch/arm/kvm/vgic.c +++ b/arch/arm/kvm/vgic.c @@ -86,6 +86,7 @@ static struct device_node *vgic_node; #define ACCESS_WRITE_VALUE (3 << 1) #define ACCESS_WRITE_MASK(x) ((x) & (3 << 1)) +static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu); static void vgic_update_state(struct kvm *kvm); static void vgic_kick_vcpus(struct kvm *kvm); static void vgic_dispatch_sgi(struct kvm_vcpu *vcpu, u32 reg); @@ -357,6 +358,7 @@ static bool handle_mmio_clear_enable_reg(struct kvm_vcpu *vcpu, if (mmio->is_write) { if (offset < 4) /* Force SGI enabled */ *reg |= 0xffff; + vgic_retire_disabled_irqs(vcpu); vgic_update_state(vcpu->kvm); return true; } @@ -825,6 +827,8 @@ static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu) vgic_cpu->vgic_irq_lr_map[irq] = LR_EMPTY; clear_bit(lr, vgic_cpu->lr_used); vgic_cpu->vgic_lr[lr] &= ~VGIC_LR_STATE; + if (vgic_irq_is_active(vcpu, irq)) + vgic_irq_clear_active(vcpu, irq); } } } @@ -940,8 +944,6 @@ static void __kvm_vgic_sync_to_cpu(struct kvm_vcpu *vcpu) vcpu_id = vcpu->vcpu_id; - vgic_retire_disabled_irqs(vcpu); - /* * We may not have any pending interrupt, or the interrupts * may have been serviced from another vcpu. In all cases, -- 1.8.0.1 _______________________________________________ kvmarm mailing list kvmarm@xxxxxxxxxxxxxxxxxxxxx https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm