aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Fedin <p.fedin@samsung.com>2015-10-27 04:37:30 -0400
committerChristoffer Dall <christoffer.dall@linaro.org>2015-11-04 09:29:49 -0500
commit212c76545dde8370ebde2a170e4f8e1ed8441dc0 (patch)
tree29f75e26593b1fc78e492e70beeb0c3190e69c4a
parentc4cd4c168b81dad53e659d18cdae653bc0ec2384 (diff)
KVM: arm/arm64: Clean up vgic_retire_lr() and surroundings
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>
-rw-r--r--virt/kvm/arm/vgic.c37
1 files changed, 10 insertions, 27 deletions
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 265a41035728..96e45f3da534 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -105,7 +105,7 @@
105#include "vgic.h" 105#include "vgic.h"
106 106
107static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu); 107static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu);
108static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu); 108static void vgic_retire_lr(int lr_nr, struct kvm_vcpu *vcpu);
109static struct vgic_lr vgic_get_lr(const struct kvm_vcpu *vcpu, int lr); 109static struct vgic_lr vgic_get_lr(const struct kvm_vcpu *vcpu, int lr);
110static void vgic_set_lr(struct kvm_vcpu *vcpu, int lr, struct vgic_lr lr_desc); 110static void vgic_set_lr(struct kvm_vcpu *vcpu, int lr, struct vgic_lr lr_desc);
111static u64 vgic_get_elrsr(struct kvm_vcpu *vcpu); 111static u64 vgic_get_elrsr(struct kvm_vcpu *vcpu);
@@ -717,30 +717,14 @@ void vgic_unqueue_irqs(struct kvm_vcpu *vcpu)
717 * interrupt then move the active state to the 717 * interrupt then move the active state to the
718 * distributor tracking bit. 718 * distributor tracking bit.
719 */ 719 */
720 if (lr.state & LR_STATE_ACTIVE) { 720 if (lr.state & LR_STATE_ACTIVE)
721 vgic_irq_set_active(vcpu, lr.irq); 721 vgic_irq_set_active(vcpu, lr.irq);
722 lr.state &= ~LR_STATE_ACTIVE;
723 }
724 722
725 /* 723 /*
726 * Reestablish the pending state on the distributor and the 724 * Reestablish the pending state on the distributor and the
727 * CPU interface. It may have already been pending, but that 725 * CPU interface and mark the LR as free for other use.
728 * is fine, then we are only setting a few bits that were
729 * already set.
730 */ 726 */
731 if (lr.state & LR_STATE_PENDING) { 727 vgic_retire_lr(i, vcpu);
732 vgic_dist_irq_set_pending(vcpu, lr.irq);
733 lr.state &= ~LR_STATE_PENDING;
734 }
735
736 vgic_set_lr(vcpu, i, lr);
737
738 /*
739 * Mark the LR as free for other use.
740 */
741 BUG_ON(lr.state & LR_STATE_MASK);
742 vgic_retire_lr(i, lr.irq, vcpu);
743 vgic_irq_clear_queued(vcpu, lr.irq);
744 728
745 /* Finally update the VGIC state. */ 729 /* Finally update the VGIC state. */
746 vgic_update_state(vcpu->kvm); 730 vgic_update_state(vcpu->kvm);
@@ -1099,16 +1083,18 @@ static inline void vgic_enable(struct kvm_vcpu *vcpu)
1099 vgic_ops->enable(vcpu); 1083 vgic_ops->enable(vcpu);
1100} 1084}
1101 1085
1102static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu) 1086static void vgic_retire_lr(int lr_nr, struct kvm_vcpu *vcpu)
1103{ 1087{
1104 struct vgic_lr vlr = vgic_get_lr(vcpu, lr_nr); 1088 struct vgic_lr vlr = vgic_get_lr(vcpu, lr_nr);
1105 1089
1090 vgic_irq_clear_queued(vcpu, vlr.irq);
1091
1106 /* 1092 /*
1107 * We must transfer the pending state back to the distributor before 1093 * We must transfer the pending state back to the distributor before
1108 * retiring the LR, otherwise we may loose edge-triggered interrupts. 1094 * retiring the LR, otherwise we may loose edge-triggered interrupts.
1109 */ 1095 */
1110 if (vlr.state & LR_STATE_PENDING) { 1096 if (vlr.state & LR_STATE_PENDING) {
1111 vgic_dist_irq_set_pending(vcpu, irq); 1097 vgic_dist_irq_set_pending(vcpu, vlr.irq);
1112 vlr.hwirq = 0; 1098 vlr.hwirq = 0;
1113 } 1099 }
1114 1100
@@ -1135,11 +1121,8 @@ static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu)
1135 for_each_clear_bit(lr, elrsr_ptr, vgic->nr_lr) { 1121 for_each_clear_bit(lr, elrsr_ptr, vgic->nr_lr) {
1136 struct vgic_lr vlr = vgic_get_lr(vcpu, lr); 1122 struct vgic_lr vlr = vgic_get_lr(vcpu, lr);
1137 1123
1138 if (!vgic_irq_is_enabled(vcpu, vlr.irq)) { 1124 if (!vgic_irq_is_enabled(vcpu, vlr.irq))
1139 vgic_retire_lr(lr, vlr.irq, vcpu); 1125 vgic_retire_lr(lr, vcpu);
1140 if (vgic_irq_is_queued(vcpu, vlr.irq))
1141 vgic_irq_clear_queued(vcpu, vlr.irq);
1142 }
1143 } 1126 }
1144} 1127}
1145 1128