From: eric.auger@linaro.org (Eric Auger)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v2 3/8] arm/arm64: KVM: vgic: Factor out level irq processing on guest exit
Date: Mon, 7 Sep 2015 17:32:35 +0200 [thread overview]
Message-ID: <55EDAE13.7020905@linaro.org> (raw)
In-Reply-To: <1441395650-19663-4-git-send-email-christoffer.dall@linaro.org>
On 09/04/2015 09:40 PM, Christoffer Dall wrote:
> Currently vgic_process_maintenance() processes dealing with a completed
> level-triggered interrupt directly, but we are soon going to reuse this
> logic for level-triggered mapped interrupts with the HW bit set, so
> move this logic into a separate static function.
>
> Probably the most scary part of this commit is convincing yourself that
> the current flow is safe compared to the old one. In the following I
> try to list the changes and why they are harmless:
>
> Move vgic_irq_clear_queued after kvm_notify_acked_irq:
> Harmless because the effect of clearing the queued flag wrt.
> kvm_set_irq is only that vgic_update_irq_pending does not set the
> pending bit on the emulated CPU interface or in the pending_on_cpu
> bitmask,
well actually the notifier calls vgic_update_irq_pending with level ==0
so it does not reach the can_sample.
but we set this in __kvm_vgic_sync_hwstate later on if the
> level is stil high.
still
Reviewed-by: Eric Auger <eric.auger@linaro.org>
Eric
>
> Move vgic_set_lr before kvm_notify_acked_irq:
> Also, harmless because the LR are cpu-local operations and
> kvm_notify_acked only affects the dist
>
> Move vgic_dist_irq_clear_soft_pend after kvm_notify_acked_irq:
> Also harmless because it's just a bit which is cleared and altering
> the line state does not affect this bit.
>
> Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
> Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
> ---
> virt/kvm/arm/vgic.c | 88 ++++++++++++++++++++++++++++++-----------------------
> 1 file changed, 50 insertions(+), 38 deletions(-)
>
> diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
> index 6bd1c9b..fe0e5db 100644
> --- a/virt/kvm/arm/vgic.c
> +++ b/virt/kvm/arm/vgic.c
> @@ -1322,12 +1322,56 @@ epilog:
> }
> }
>
> +static int process_level_irq(struct kvm_vcpu *vcpu, int lr, struct vgic_lr vlr)
> +{
> + int level_pending = 0;
> +
> + vlr.state = 0;
> + vlr.hwirq = 0;
> + vgic_set_lr(vcpu, lr, vlr);
> +
> + /*
> + * If the IRQ was EOIed (called from vgic_process_maintenance) or it
> + * went from active to non-active (called from vgic_sync_hwirq) it was
> + * also ACKed and we we therefore assume we can clear the soft pending
> + * state (should it had been set) for this interrupt.
> + *
> + * Note: if the IRQ soft pending state was set after the IRQ was
> + * acked, it actually shouldn't be cleared, but we have no way of
> + * knowing that unless we start trapping ACKs when the soft-pending
> + * state is set.
> + */
> + vgic_dist_irq_clear_soft_pend(vcpu, vlr.irq);
> +
> + /*
> + * Tell the gic to start sampling the line of this interrupt again.
> + */
> + vgic_irq_clear_queued(vcpu, vlr.irq);
> +
> + /* Any additional pending interrupt? */
> + if (vgic_dist_irq_get_level(vcpu, vlr.irq)) {
> + vgic_cpu_irq_set(vcpu, vlr.irq);
> + level_pending = 1;
> + } else {
> + vgic_dist_irq_clear_pending(vcpu, vlr.irq);
> + vgic_cpu_irq_clear(vcpu, vlr.irq);
> + }
> +
> + /*
> + * Despite being EOIed, the LR may not have
> + * been marked as empty.
> + */
> + vgic_sync_lr_elrsr(vcpu, lr, vlr);
> +
> + return level_pending;
> +}
> +
> static bool vgic_process_maintenance(struct kvm_vcpu *vcpu)
> {
> u32 status = vgic_get_interrupt_status(vcpu);
> struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
> - bool level_pending = false;
> struct kvm *kvm = vcpu->kvm;
> + int level_pending = 0;
>
> kvm_debug("STATUS = %08x\n", status);
>
> @@ -1342,54 +1386,22 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu)
>
> for_each_set_bit(lr, eisr_ptr, vgic->nr_lr) {
> struct vgic_lr vlr = vgic_get_lr(vcpu, lr);
> - WARN_ON(vgic_irq_is_edge(vcpu, vlr.irq));
>
> - spin_lock(&dist->lock);
> - vgic_irq_clear_queued(vcpu, vlr.irq);
> + WARN_ON(vgic_irq_is_edge(vcpu, vlr.irq));
> WARN_ON(vlr.state & LR_STATE_MASK);
> - vlr.state = 0;
> - vgic_set_lr(vcpu, lr, vlr);
>
> - /*
> - * If the IRQ was EOIed it was also ACKed and we we
> - * therefore assume we can clear the soft pending
> - * state (should it had been set) for this interrupt.
> - *
> - * Note: if the IRQ soft pending state was set after
> - * the IRQ was acked, it actually shouldn't be
> - * cleared, but we have no way of knowing that unless
> - * we start trapping ACKs when the soft-pending state
> - * is set.
> - */
> - vgic_dist_irq_clear_soft_pend(vcpu, vlr.irq);
>
> /*
> * kvm_notify_acked_irq calls kvm_set_irq()
> - * to reset the IRQ level. Need to release the
> - * lock for kvm_set_irq to grab it.
> + * to reset the IRQ level, which grabs the dist->lock
> + * so we call this before taking the dist->lock.
> */
> - spin_unlock(&dist->lock);
> -
> kvm_notify_acked_irq(kvm, 0,
> vlr.irq - VGIC_NR_PRIVATE_IRQS);
> - spin_lock(&dist->lock);
> -
> - /* Any additional pending interrupt? */
> - if (vgic_dist_irq_get_level(vcpu, vlr.irq)) {
> - vgic_cpu_irq_set(vcpu, vlr.irq);
> - level_pending = true;
> - } else {
> - vgic_dist_irq_clear_pending(vcpu, vlr.irq);
> - vgic_cpu_irq_clear(vcpu, vlr.irq);
> - }
>
> + spin_lock(&dist->lock);
> + level_pending |= process_level_irq(vcpu, lr, vlr);
> spin_unlock(&dist->lock);
> -
> - /*
> - * Despite being EOIed, the LR may not have
> - * been marked as empty.
> - */
> - vgic_sync_lr_elrsr(vcpu, lr, vlr);
> }
> }
>
>
next prev parent reply other threads:[~2015-09-07 15:32 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-09-04 19:40 [PATCH v2 0/8] Rework architected timer and forwarded IRQs handling Christoffer Dall
2015-09-04 19:40 ` [PATCH v2 1/8] KVM: Add kvm_arch_vcpu_{un}blocking callbacks Christoffer Dall
2015-09-04 19:40 ` [PATCH v2 2/8] arm/arm64: KVM: arch_timer: Only schedule soft timer on vcpu_block Christoffer Dall
2015-09-07 15:01 ` Eric Auger
2015-09-13 15:56 ` Christoffer Dall
2015-09-04 19:40 ` [PATCH v2 3/8] arm/arm64: KVM: vgic: Factor out level irq processing on guest exit Christoffer Dall
2015-09-07 15:32 ` Eric Auger [this message]
2015-09-14 11:31 ` Christoffer Dall
2015-09-04 19:40 ` [PATCH v2 4/8] arm/arm64: KVM: Implement GICD_ICFGR as RO for PPIs Christoffer Dall
2015-09-04 19:40 ` [PATCH v2 5/8] arm/arm64: KVM: Use appropriate define in VGIC reset code Christoffer Dall
2015-09-04 19:40 ` [PATCH v2 6/8] arm/arm64: KVM: Add forwarded physical interrupts documentation Christoffer Dall
2015-09-07 11:25 ` Andre Przywara
2015-09-08 8:43 ` Eric Auger
2015-09-08 16:57 ` Andre Przywara
2015-09-09 8:49 ` Christoffer Dall
2015-09-09 8:57 ` Eric Auger
2015-09-11 11:21 ` Andre Przywara
2015-09-14 11:42 ` Christoffer Dall
2015-09-15 15:16 ` Andre Przywara
2015-09-15 19:09 ` Christoffer Dall
2015-09-08 14:18 ` Christoffer Dall
2015-09-07 16:45 ` Eric Auger
2015-09-07 17:50 ` Marc Zyngier
2015-09-08 7:44 ` Eric Auger
2015-09-14 11:46 ` Christoffer Dall
2015-09-04 19:40 ` [PATCH v2 7/8] arm/arm64: KVM: Rework the arch timer to use level-triggered semantics Christoffer Dall
2015-09-14 9:29 ` Eric Auger
2015-09-14 11:48 ` Christoffer Dall
2015-09-14 15:51 ` Andre Przywara
2015-09-23 17:44 ` Andre Przywara
2015-09-29 14:30 ` Christoffer Dall
2015-09-04 19:40 ` [PATCH v2 8/8] arm/arm64: KVM: Support edge-triggered forwarded interrupts Christoffer Dall
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=55EDAE13.7020905@linaro.org \
--to=eric.auger@linaro.org \
--cc=linux-arm-kernel@lists.infradead.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;
as well as URLs for NNTP newsgroup(s).