From: Christoffer Dall <christoffer.dall@linaro.org>
To: Eric Auger <eric.auger@linaro.org>
Cc: eric.auger@st.com, marc.zyngier@arm.com, andre.przywara@arm.com,
linux-arm-kernel@lists.infradead.org,
kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org,
alex.williamson@redhat.com, patches@linaro.org,
a.motakis@virtualopensystems.com, a.rigo@virtualopensystems.com,
b.reynal@virtualopensystems.com
Subject: Re: [RFC v2 2/4] KVM: arm: vgic: fix state machine for forwarded IRQ
Date: Wed, 6 May 2015 16:26:49 +0200 [thread overview]
Message-ID: <20150506142649.GB6796@cbox> (raw)
In-Reply-To: <1423642857-24240-3-git-send-email-eric.auger@linaro.org>
On Wed, Feb 11, 2015 at 09:20:55AM +0100, Eric Auger wrote:
> Fix multiple injection of level sensitive forwarded IRQs.
> With current code, the second injection fails since the state bitmaps
> are not reset (process_maintenance is not called anymore).
>
> New implementation follows those principles:
> - A forwarded IRQ only can be sampled when it is pending
why?
> - when queueing the IRQ (programming the LR), the pending state is removed
> as for edge sensitive IRQs
> - an injection of a forwarded IRQ is considered always valid since
> coming from the HW and level always is 1.
>
> Signed-off-by: Eric Auger <eric.auger@linaro.org>
>
> ---
>
> v1 -> v2:
> - integration in new vgic_can_sample_irq
> - remove the pending state when programming the LR
> ---
> virt/kvm/arm/vgic.c | 16 ++++++++++++----
> 1 file changed, 12 insertions(+), 4 deletions(-)
>
> diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
> index cd00cf2..433ecba 100644
> --- a/virt/kvm/arm/vgic.c
> +++ b/virt/kvm/arm/vgic.c
> @@ -361,7 +361,10 @@ static void vgic_cpu_irq_clear(struct kvm_vcpu *vcpu, int irq)
>
> static bool vgic_can_sample_irq(struct kvm_vcpu *vcpu, int irq)
> {
> - return vgic_irq_is_edge(vcpu, irq) || !vgic_irq_is_queued(vcpu, irq);
> + bool is_forwarded = (vgic_get_phys_irq(vcpu, irq) >= 0);
can you create a wrapper function for is_forwarded?
> +
> + return vgic_irq_is_edge(vcpu, irq) || !vgic_irq_is_queued(vcpu, irq) ||
> + (is_forwarded && vgic_dist_irq_is_pending(vcpu, irq));
> }
>
> static u32 mmio_data_read(struct kvm_exit_mmio *mmio, u32 mask)
> @@ -1296,6 +1299,7 @@ static bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq)
> struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
> struct vgic_lr vlr;
> int lr;
> + bool is_forwarded = (vgic_get_phys_irq(vcpu, irq) >= 0);
>
> /* Sanitize the input... */
> BUG_ON(sgi_source_id & ~7);
> @@ -1331,7 +1335,7 @@ static bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq)
> vlr.irq = irq;
> vlr.source = sgi_source_id;
> vlr.state = LR_STATE_PENDING;
> - if (!vgic_irq_is_edge(vcpu, irq))
> + if (!vgic_irq_is_edge(vcpu, irq) && !is_forwarded)
> vlr.state |= LR_EOI_INT;
>
> vgic_set_lr(vcpu, lr, vlr);
> @@ -1372,11 +1376,12 @@ static bool vgic_queue_sgi(struct kvm_vcpu *vcpu, int irq)
>
> static bool vgic_queue_hwirq(struct kvm_vcpu *vcpu, int irq)
> {
> + bool is_forwarded = (vgic_get_phys_irq(vcpu, irq) >= 0);
> if (!vgic_can_sample_irq(vcpu, irq))
> return true; /* level interrupt, already queued */
>
> if (vgic_queue_irq(vcpu, 0, irq)) {
> - if (vgic_irq_is_edge(vcpu, irq)) {
> + if (vgic_irq_is_edge(vcpu, irq) || is_forwarded) {
> vgic_dist_irq_clear_pending(vcpu, irq);
> vgic_cpu_irq_clear(vcpu, irq);
> } else {
> @@ -1626,14 +1631,17 @@ static int vgic_update_irq_pending(struct kvm *kvm, int cpuid,
> int edge_triggered, level_triggered;
> int enabled;
> bool ret = true;
> + bool is_forwarded;
>
> spin_lock(&dist->lock);
>
> vcpu = kvm_get_vcpu(kvm, cpuid);
> + is_forwarded = (vgic_get_phys_irq(vcpu, irq_num) >= 0);
> +
> edge_triggered = vgic_irq_is_edge(vcpu, irq_num);
> level_triggered = !edge_triggered;
>
> - if (!vgic_validate_injection(vcpu, irq_num, level)) {
> + if (!vgic_validate_injection(vcpu, irq_num, level) && !is_forwarded) {
why is it again that we don't trust validate for forwarded irqs? Should
it not be checked inside validate? Otherwise, this seems to deserve a
comment.
> ret = false;
> goto out;
> }
Thanks,
-Christoffer
WARNING: multiple messages have this Message-ID (diff)
From: christoffer.dall@linaro.org (Christoffer Dall)
To: linux-arm-kernel@lists.infradead.org
Subject: [RFC v2 2/4] KVM: arm: vgic: fix state machine for forwarded IRQ
Date: Wed, 6 May 2015 16:26:49 +0200 [thread overview]
Message-ID: <20150506142649.GB6796@cbox> (raw)
In-Reply-To: <1423642857-24240-3-git-send-email-eric.auger@linaro.org>
On Wed, Feb 11, 2015 at 09:20:55AM +0100, Eric Auger wrote:
> Fix multiple injection of level sensitive forwarded IRQs.
> With current code, the second injection fails since the state bitmaps
> are not reset (process_maintenance is not called anymore).
>
> New implementation follows those principles:
> - A forwarded IRQ only can be sampled when it is pending
why?
> - when queueing the IRQ (programming the LR), the pending state is removed
> as for edge sensitive IRQs
> - an injection of a forwarded IRQ is considered always valid since
> coming from the HW and level always is 1.
>
> Signed-off-by: Eric Auger <eric.auger@linaro.org>
>
> ---
>
> v1 -> v2:
> - integration in new vgic_can_sample_irq
> - remove the pending state when programming the LR
> ---
> virt/kvm/arm/vgic.c | 16 ++++++++++++----
> 1 file changed, 12 insertions(+), 4 deletions(-)
>
> diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
> index cd00cf2..433ecba 100644
> --- a/virt/kvm/arm/vgic.c
> +++ b/virt/kvm/arm/vgic.c
> @@ -361,7 +361,10 @@ static void vgic_cpu_irq_clear(struct kvm_vcpu *vcpu, int irq)
>
> static bool vgic_can_sample_irq(struct kvm_vcpu *vcpu, int irq)
> {
> - return vgic_irq_is_edge(vcpu, irq) || !vgic_irq_is_queued(vcpu, irq);
> + bool is_forwarded = (vgic_get_phys_irq(vcpu, irq) >= 0);
can you create a wrapper function for is_forwarded?
> +
> + return vgic_irq_is_edge(vcpu, irq) || !vgic_irq_is_queued(vcpu, irq) ||
> + (is_forwarded && vgic_dist_irq_is_pending(vcpu, irq));
> }
>
> static u32 mmio_data_read(struct kvm_exit_mmio *mmio, u32 mask)
> @@ -1296,6 +1299,7 @@ static bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq)
> struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
> struct vgic_lr vlr;
> int lr;
> + bool is_forwarded = (vgic_get_phys_irq(vcpu, irq) >= 0);
>
> /* Sanitize the input... */
> BUG_ON(sgi_source_id & ~7);
> @@ -1331,7 +1335,7 @@ static bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq)
> vlr.irq = irq;
> vlr.source = sgi_source_id;
> vlr.state = LR_STATE_PENDING;
> - if (!vgic_irq_is_edge(vcpu, irq))
> + if (!vgic_irq_is_edge(vcpu, irq) && !is_forwarded)
> vlr.state |= LR_EOI_INT;
>
> vgic_set_lr(vcpu, lr, vlr);
> @@ -1372,11 +1376,12 @@ static bool vgic_queue_sgi(struct kvm_vcpu *vcpu, int irq)
>
> static bool vgic_queue_hwirq(struct kvm_vcpu *vcpu, int irq)
> {
> + bool is_forwarded = (vgic_get_phys_irq(vcpu, irq) >= 0);
> if (!vgic_can_sample_irq(vcpu, irq))
> return true; /* level interrupt, already queued */
>
> if (vgic_queue_irq(vcpu, 0, irq)) {
> - if (vgic_irq_is_edge(vcpu, irq)) {
> + if (vgic_irq_is_edge(vcpu, irq) || is_forwarded) {
> vgic_dist_irq_clear_pending(vcpu, irq);
> vgic_cpu_irq_clear(vcpu, irq);
> } else {
> @@ -1626,14 +1631,17 @@ static int vgic_update_irq_pending(struct kvm *kvm, int cpuid,
> int edge_triggered, level_triggered;
> int enabled;
> bool ret = true;
> + bool is_forwarded;
>
> spin_lock(&dist->lock);
>
> vcpu = kvm_get_vcpu(kvm, cpuid);
> + is_forwarded = (vgic_get_phys_irq(vcpu, irq_num) >= 0);
> +
> edge_triggered = vgic_irq_is_edge(vcpu, irq_num);
> level_triggered = !edge_triggered;
>
> - if (!vgic_validate_injection(vcpu, irq_num, level)) {
> + if (!vgic_validate_injection(vcpu, irq_num, level) && !is_forwarded) {
why is it again that we don't trust validate for forwarded irqs? Should
it not be checked inside validate? Otherwise, this seems to deserve a
comment.
> ret = false;
> goto out;
> }
Thanks,
-Christoffer
next prev parent reply other threads:[~2015-05-06 14:26 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-02-11 8:20 [RFC v2 0/4] chip/vgic adaptations for forwarded irq Eric Auger
2015-02-11 8:20 ` Eric Auger
2015-02-11 8:20 ` [RFC v2 1/4] chip.c: complete the forwarded IRQ in case the handler is not reached Eric Auger
2015-02-11 8:20 ` Eric Auger
2015-02-11 8:20 ` [RFC v2 2/4] KVM: arm: vgic: fix state machine for forwarded IRQ Eric Auger
2015-02-11 8:20 ` Eric Auger
2015-05-06 14:26 ` Christoffer Dall [this message]
2015-05-06 14:26 ` Christoffer Dall
2015-05-07 7:48 ` Eric Auger
2015-05-07 7:48 ` Eric Auger
2015-05-07 9:20 ` Christoffer Dall
2015-05-07 9:20 ` Christoffer Dall
2015-05-07 9:38 ` Eric Auger
2015-05-07 9:38 ` Eric Auger
2015-02-11 8:20 ` [RFC v2 3/4] KVM: arm: vgic: add forwarded irq rbtree lock Eric Auger
2015-02-11 8:20 ` Eric Auger
2015-02-11 8:20 ` [RFC v2 4/4] KVM: arm: vgic: cleanup forwarded IRQs on destroy Eric Auger
2015-02-11 8:20 ` Eric Auger
2015-05-06 14:27 ` [RFC v2 0/4] chip/vgic adaptations for forwarded irq Christoffer Dall
2015-05-06 14:27 ` Christoffer Dall
2015-05-06 15:32 ` Eric Auger
2015-05-06 15:32 ` Eric Auger
2015-05-07 9:17 ` Christoffer Dall
2015-05-07 9:17 ` Christoffer Dall
2015-05-07 9:39 ` Eric Auger
2015-05-07 9:39 ` Eric Auger
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=20150506142649.GB6796@cbox \
--to=christoffer.dall@linaro.org \
--cc=a.motakis@virtualopensystems.com \
--cc=a.rigo@virtualopensystems.com \
--cc=alex.williamson@redhat.com \
--cc=andre.przywara@arm.com \
--cc=b.reynal@virtualopensystems.com \
--cc=eric.auger@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=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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.