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 /virt | |
| 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>
Diffstat (limited to 'virt')
| -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 | ||
