diff options
author | Pavel Fedin <p.fedin@samsung.com> | 2015-10-27 04:37:30 -0400 |
---|---|---|
committer | Christoffer Dall <christoffer.dall@linaro.org> | 2015-11-04 09:29:49 -0500 |
commit | 212c76545dde8370ebde2a170e4f8e1ed8441dc0 (patch) | |
tree | 29f75e26593b1fc78e492e70beeb0c3190e69c4a | |
parent | c4cd4c168b81dad53e659d18cdae653bc0ec2384 (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.c | 37 |
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 | ||
107 | static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu); | 107 | static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu); |
108 | static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu); | 108 | static void vgic_retire_lr(int lr_nr, struct kvm_vcpu *vcpu); |
109 | static struct vgic_lr vgic_get_lr(const struct kvm_vcpu *vcpu, int lr); | 109 | static struct vgic_lr vgic_get_lr(const struct kvm_vcpu *vcpu, int lr); |
110 | static void vgic_set_lr(struct kvm_vcpu *vcpu, int lr, struct vgic_lr lr_desc); | 110 | static void vgic_set_lr(struct kvm_vcpu *vcpu, int lr, struct vgic_lr lr_desc); |
111 | static u64 vgic_get_elrsr(struct kvm_vcpu *vcpu); | 111 | static 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 | ||
1102 | static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu) | 1086 | static 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 | ||