KVM: arm/arm64: Clean up vgic_retire_lr() and surroundings
authorPavel Fedin <p.fedin@samsung.com>
Tue, 27 Oct 2015 08:37:30 +0000 (11:37 +0300)
committerChristoffer Dall <christoffer.dall@linaro.org>
Wed, 4 Nov 2015 14:29:49 +0000 (15:29 +0100)
1. Remove unnecessary 'irq' argument, because irq number can be retrieved
   from the LR.
2. Since cff9211eb1a1f58ce7f5a2d596b617928fd4be0e
   ("arm/arm64: KVM: Fix arch timer behavior for disabled interrupts ")
   LR_STATE_PENDING is queued back by vgic_retire_lr() itself. Also, it
   clears vlr.state itself. Therefore, we remove the same, now duplicated,
   check with all accompanying bit manipulations from vgic_unqueue_irqs().
3. vgic_retire_lr() is always accompanied by vgic_irq_clear_queued(). Since
   it already does more than just clearing the LR, move
   vgic_irq_clear_queued() inside of it.

Signed-off-by: Pavel Fedin <p.fedin@samsung.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
virt/kvm/arm/vgic.c

index 265a410357283a98fd1183929b803c694badf371..96e45f3da534bc631b4b73622e382e2552433432 100644 (file)
 #include "vgic.h"
 
 static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu);
-static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu);
+static void vgic_retire_lr(int lr_nr, struct kvm_vcpu *vcpu);
 static struct vgic_lr vgic_get_lr(const struct kvm_vcpu *vcpu, int lr);
 static void vgic_set_lr(struct kvm_vcpu *vcpu, int lr, struct vgic_lr lr_desc);
 static u64 vgic_get_elrsr(struct kvm_vcpu *vcpu);
@@ -717,30 +717,14 @@ void vgic_unqueue_irqs(struct kvm_vcpu *vcpu)
                 * interrupt then move the active state to the
                 * distributor tracking bit.
                 */
-               if (lr.state & LR_STATE_ACTIVE) {
+               if (lr.state & LR_STATE_ACTIVE)
                        vgic_irq_set_active(vcpu, lr.irq);
-                       lr.state &= ~LR_STATE_ACTIVE;
-               }
 
                /*
                 * Reestablish the pending state on the distributor and the
-                * CPU interface.  It may have already been pending, but that
-                * is fine, then we are only setting a few bits that were
-                * already set.
+                * CPU interface and mark the LR as free for other use.
                 */
-               if (lr.state & LR_STATE_PENDING) {
-                       vgic_dist_irq_set_pending(vcpu, lr.irq);
-                       lr.state &= ~LR_STATE_PENDING;
-               }
-
-               vgic_set_lr(vcpu, i, lr);
-
-               /*
-                * Mark the LR as free for other use.
-                */
-               BUG_ON(lr.state & LR_STATE_MASK);
-               vgic_retire_lr(i, lr.irq, vcpu);
-               vgic_irq_clear_queued(vcpu, lr.irq);
+               vgic_retire_lr(i, vcpu);
 
                /* Finally update the VGIC state. */
                vgic_update_state(vcpu->kvm);
@@ -1099,16 +1083,18 @@ static inline void vgic_enable(struct kvm_vcpu *vcpu)
        vgic_ops->enable(vcpu);
 }
 
-static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu)
+static void vgic_retire_lr(int lr_nr, struct kvm_vcpu *vcpu)
 {
        struct vgic_lr vlr = vgic_get_lr(vcpu, lr_nr);
 
+       vgic_irq_clear_queued(vcpu, vlr.irq);
+
        /*
         * We must transfer the pending state back to the distributor before
         * retiring the LR, otherwise we may loose edge-triggered interrupts.
         */
        if (vlr.state & LR_STATE_PENDING) {
-               vgic_dist_irq_set_pending(vcpu, irq);
+               vgic_dist_irq_set_pending(vcpu, vlr.irq);
                vlr.hwirq = 0;
        }
 
@@ -1135,11 +1121,8 @@ static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu)
        for_each_clear_bit(lr, elrsr_ptr, vgic->nr_lr) {
                struct vgic_lr vlr = vgic_get_lr(vcpu, lr);
 
-               if (!vgic_irq_is_enabled(vcpu, vlr.irq)) {
-                       vgic_retire_lr(lr, vlr.irq, vcpu);
-                       if (vgic_irq_is_queued(vcpu, vlr.irq))
-                               vgic_irq_clear_queued(vcpu, vlr.irq);
-               }
+               if (!vgic_irq_is_enabled(vcpu, vlr.irq))
+                       vgic_retire_lr(lr, vcpu);
        }
 }