From: Eric Auger <eric.auger@linaro.org>
To: eric.auger@st.com, eric.auger@linaro.org,
christoffer.dall@linaro.org, marc.zyngier@arm.com,
linux-arm-kernel@lists.infradead.org,
kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org
Cc: andre.przywara@arm.com, linux-kernel@vger.kernel.org, patches@linaro.org
Subject: [PATCH] KVM: arm/arm64: vgic: leave the LR active state on GICD_ICENABLERn access
Date: Thu, 19 Nov 2015 14:52:27 +0000 [thread overview]
Message-ID: <1447944747-17689-1-git-send-email-eric.auger@linaro.org> (raw)
Currently on clear-enable MMIO we retire the corresponding LR whatever
its state. More precisely we do not sync ACTIVE state but we erase the LR
state.
In case of a forwarded IRQ, the physical IRQ source is also erased meaning
the physical IRQ will never be deactivated. In case of a non forwarded
IRQ, the LR can be reused (since the state was reset) and the guest can
deactivate an IRQ that is not marked in the LR anymore.
This patch adds a parameter to vgic_retire_lr that makes possible to select
the type of the LR that must be retired. unqueue will retire/sync all LR's
while disable will leave the active LR's.
Signed-off-by: Eric Auger <eric.auger@linaro.org>
---
virt/kvm/arm/vgic.c | 45 +++++++++++++++++++++++----------------------
1 file changed, 23 insertions(+), 22 deletions(-)
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 5335383..bc30d93 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -105,7 +105,7 @@
#include "vgic.h"
static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu);
-static void vgic_retire_lr(int lr_nr, struct kvm_vcpu *vcpu);
+static void vgic_retire_lr(int lr_nr, struct kvm_vcpu *vcpu, unsigned state);
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);
@@ -713,18 +713,10 @@ void vgic_unqueue_irqs(struct kvm_vcpu *vcpu)
add_sgi_source(vcpu, lr.irq, lr.source);
/*
- * If the LR holds an active (10) or a pending and active (11)
- * interrupt then move the active state to the
- * distributor tracking bit.
+ * retire pending, active, active and pending LR's and
+ * sync their state back to the distributor
*/
- if (lr.state & LR_STATE_ACTIVE)
- vgic_irq_set_active(vcpu, lr.irq);
-
- /*
- * Reestablish the pending state on the distributor and the
- * CPU interface and mark the LR as free for other use.
- */
- vgic_retire_lr(i, vcpu);
+ vgic_retire_lr(i, vcpu, LR_STATE_ACTIVE | LR_STATE_PENDING);
/* Finally update the VGIC state. */
vgic_update_state(vcpu->kvm);
@@ -1077,22 +1069,25 @@ static inline void vgic_enable(struct kvm_vcpu *vcpu)
vgic_ops->enable(vcpu);
}
-static void vgic_retire_lr(int lr_nr, struct kvm_vcpu *vcpu)
+static void vgic_retire_lr(int lr_nr, struct kvm_vcpu *vcpu, unsigned state)
{
struct vgic_lr vlr = vgic_get_lr(vcpu, lr_nr);
- vgic_irq_clear_queued(vcpu, vlr.irq);
+ if (vlr.state & LR_STATE_ACTIVE & state) {
+ vgic_irq_set_active(vcpu, vlr.irq);
+ vlr.state &= ~LR_STATE_ACTIVE;
+ }
- /*
- * 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) {
+ if (vlr.state & LR_STATE_PENDING & state) {
vgic_dist_irq_set_pending(vcpu, vlr.irq);
- vlr.hwirq = 0;
+ vlr.state &= ~LR_STATE_PENDING;
}
- vlr.state = 0;
+ if (!(vlr.state & LR_STATE_MASK)) {
+ vlr.hwirq = 0;
+ vlr.state = 0;
+ vgic_irq_clear_queued(vcpu, vlr.irq);
+ }
vgic_set_lr(vcpu, lr_nr, vlr);
}
@@ -1114,8 +1109,14 @@ 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);
+ /*
+ * retire pending only LR's and sync their state
+ * back to the distributor. Active LR's cannot be
+ * retired since the guest will attempt to deactivate
+ * the IRQ.
+ */
if (!vgic_irq_is_enabled(vcpu, vlr.irq))
- vgic_retire_lr(lr, vcpu);
+ vgic_retire_lr(lr, vcpu, LR_STATE_PENDING);
}
}
--
1.9.1
reply other threads:[~2015-11-19 14:52 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1447944747-17689-1-git-send-email-eric.auger@linaro.org \
--to=eric.auger@linaro.org \
--cc=andre.przywara@arm.com \
--cc=christoffer.dall@linaro.org \
--cc=eric.auger@st.com \
--cc=kvm@vger.kernel.org \
--cc=kvmarm@lists.cs.columbia.edu \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=marc.zyngier@arm.com \
--cc=patches@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®