All of lore.kernel.org
 help / color / mirror / Atom feed
From: Marc Zyngier <maz@kernel.org>
To: Alexandru Elisei <alexandru.elisei@arm.com>
Cc: kvm@vger.kernel.org, Hector Martin <marcan@marcan.st>,
	kernel-team@android.com, kvmarm@lists.cs.columbia.edu,
	linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH v4 6/9] KVM: arm64: vgic: Implement SW-driven deactivation
Date: Tue, 22 Jun 2021 17:12:07 +0100	[thread overview]
Message-ID: <87y2b1c208.wl-maz@kernel.org> (raw)
In-Reply-To: <b87fb2e9-a3f9-accc-86d9-64dc2ee90dea@arm.com>

On Thu, 17 Jun 2021 15:58:31 +0100,
Alexandru Elisei <alexandru.elisei@arm.com> wrote:
> 
> Hi Marc,
> 
> On 6/1/21 11:40 AM, Marc Zyngier wrote:
> > In order to deal with these systems that do not offer HW-based
> > deactivation of interrupts, let implement a SW-based approach:
> 
> Nitpick, but shouldn't that be "let's"?

"Let it be...". ;-) Yup.

> 
> >
> > - When the irq is queued into a LR, treat it as a pure virtual
> >   interrupt and set the EOI flag in the LR.
> >
> > - When the interrupt state is read back from the LR, force a
> >   deactivation when the state is invalid (neither active nor
> >   pending)
> >
> > Interrupts requiring such treatment get the VGIC_SW_RESAMPLE flag.
> >
> > Signed-off-by: Marc Zyngier <maz@kernel.org>
> > ---
> >  arch/arm64/kvm/vgic/vgic-v2.c | 19 +++++++++++++++----
> >  arch/arm64/kvm/vgic/vgic-v3.c | 19 +++++++++++++++----
> >  include/kvm/arm_vgic.h        | 10 ++++++++++
> >  3 files changed, 40 insertions(+), 8 deletions(-)
> >
> > diff --git a/arch/arm64/kvm/vgic/vgic-v2.c b/arch/arm64/kvm/vgic/vgic-v2.c
> > index 11934c2af2f4..2c580204f1dc 100644
> > --- a/arch/arm64/kvm/vgic/vgic-v2.c
> > +++ b/arch/arm64/kvm/vgic/vgic-v2.c
> > @@ -108,11 +108,22 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu)
> >  		 * If this causes us to lower the level, we have to also clear
> >  		 * the physical active state, since we will otherwise never be
> >  		 * told when the interrupt becomes asserted again.
> > +		 *
> > +		 * Another case is when the interrupt requires a helping hand
> > +		 * on deactivation (no HW deactivation, for example).
> >  		 */
> > -		if (vgic_irq_is_mapped_level(irq) && (val & GICH_LR_PENDING_BIT)) {
> > -			irq->line_level = vgic_get_phys_line_level(irq);
> > +		if (vgic_irq_is_mapped_level(irq)) {
> > +			bool resample = false;
> > +
> > +			if (val & GICH_LR_PENDING_BIT) {
> > +				irq->line_level = vgic_get_phys_line_level(irq);
> > +				resample = !irq->line_level;
> > +			} else if (vgic_irq_needs_resampling(irq) &&
> > +				   !(irq->active || irq->pending_latch)) {
> 
> I'm having a hard time figuring out when and why a level sensitive
> can have pending_latch = true.
> 
> I looked kvm_vgic_inject_irq(), and that function sets pending_latch
> only for edge triggered interrupts (it sets line_level for level
> sensitive ones). But irq_is_pending() looks at **both**
> pending_latch and line_level for level sensitive interrupts.

Yes, and that's what an implementation requires.

> The only place that I've found that sets pending_latch regardless of
> the  interrupt type  is in  vgic_mmio_write_spending() (called  on a
> trapped  write  to   GICD_ISENABLER).

Are you sure? It really should be GICD_ISPENDR. I'll assume that this
is what you mean below.

> vgic_v2_populate_lr()  clears
> pending_latch  only for  edge triggered  interrupts, so  that leaves
> vgic_v2_fold_lr_state()  as  the   only  function  pending_latch  is
> cleared for level sensitive interrupts,  when the interrupt has been
> handled by the guest.  Are we doing all of this  to emulate the fact
> that level sensitive interrupts (either purely virtual or hw mapped)
> made pending by a write  to GICD_ISENABLER remain pending until they
> are handled by the guest?

Yes, or cleared by a write to GICD_ICPENDR. You really need to think
of the input into the GIC as some sort of OR gate combining both the
line level and the PEND register. With a latch for edge interrupts.

Have a look at Figure 4-10 ("Logic of the pending status of a
level-sensitive interrupt") in the GICv2 arch spec (ARM IHI 0048B.b)
to see what I actually mean.

> If that is the case, then I think this is what the code is doing:
> 
> - There's no functional change when the irqchip has HW deactivation
> 
> - For level sensitive, hw mapped interrupts made pending by a write
> to GICD_ISENABLER and not yet handled by the guest (pending_latch ==
> true) we don't clear the pending state of the interrupt.
> 
> - For level sensitive, hw mapped interrupts we clear the pending
> state in the GIC and the device will assert the interrupt again if
> it's still pending at the device 1level. I have a question about
> this. Why don't we sample the interrupt state by calling
> vgic_get_phys_line_level()? Because that would be slower than the
> alternative that you are proposing here?

Yes. It is *much* faster to read the timer status register (for
example) than going via an MMIO access to read the (re)distributor
that will return the same value.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.
_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

WARNING: multiple messages have this Message-ID (diff)
From: Marc Zyngier <maz@kernel.org>
To: Alexandru Elisei <alexandru.elisei@arm.com>
Cc: linux-arm-kernel@lists.infradead.org, kvm@vger.kernel.org,
	kvmarm@lists.cs.columbia.edu, James Morse <james.morse@arm.com>,
	Suzuki K Poulose <suzuki.poulose@arm.com>,
	Eric Auger <eric.auger@redhat.com>,
	Hector Martin <marcan@marcan.st>,
	Mark Rutland <mark.rutland@arm.com>,
	Zenghui Yu <yuzenghui@huawei.com>,
	kernel-team@android.com
Subject: Re: [PATCH v4 6/9] KVM: arm64: vgic: Implement SW-driven deactivation
Date: Tue, 22 Jun 2021 17:12:07 +0100	[thread overview]
Message-ID: <87y2b1c208.wl-maz@kernel.org> (raw)
In-Reply-To: <b87fb2e9-a3f9-accc-86d9-64dc2ee90dea@arm.com>

On Thu, 17 Jun 2021 15:58:31 +0100,
Alexandru Elisei <alexandru.elisei@arm.com> wrote:
> 
> Hi Marc,
> 
> On 6/1/21 11:40 AM, Marc Zyngier wrote:
> > In order to deal with these systems that do not offer HW-based
> > deactivation of interrupts, let implement a SW-based approach:
> 
> Nitpick, but shouldn't that be "let's"?

"Let it be...". ;-) Yup.

> 
> >
> > - When the irq is queued into a LR, treat it as a pure virtual
> >   interrupt and set the EOI flag in the LR.
> >
> > - When the interrupt state is read back from the LR, force a
> >   deactivation when the state is invalid (neither active nor
> >   pending)
> >
> > Interrupts requiring such treatment get the VGIC_SW_RESAMPLE flag.
> >
> > Signed-off-by: Marc Zyngier <maz@kernel.org>
> > ---
> >  arch/arm64/kvm/vgic/vgic-v2.c | 19 +++++++++++++++----
> >  arch/arm64/kvm/vgic/vgic-v3.c | 19 +++++++++++++++----
> >  include/kvm/arm_vgic.h        | 10 ++++++++++
> >  3 files changed, 40 insertions(+), 8 deletions(-)
> >
> > diff --git a/arch/arm64/kvm/vgic/vgic-v2.c b/arch/arm64/kvm/vgic/vgic-v2.c
> > index 11934c2af2f4..2c580204f1dc 100644
> > --- a/arch/arm64/kvm/vgic/vgic-v2.c
> > +++ b/arch/arm64/kvm/vgic/vgic-v2.c
> > @@ -108,11 +108,22 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu)
> >  		 * If this causes us to lower the level, we have to also clear
> >  		 * the physical active state, since we will otherwise never be
> >  		 * told when the interrupt becomes asserted again.
> > +		 *
> > +		 * Another case is when the interrupt requires a helping hand
> > +		 * on deactivation (no HW deactivation, for example).
> >  		 */
> > -		if (vgic_irq_is_mapped_level(irq) && (val & GICH_LR_PENDING_BIT)) {
> > -			irq->line_level = vgic_get_phys_line_level(irq);
> > +		if (vgic_irq_is_mapped_level(irq)) {
> > +			bool resample = false;
> > +
> > +			if (val & GICH_LR_PENDING_BIT) {
> > +				irq->line_level = vgic_get_phys_line_level(irq);
> > +				resample = !irq->line_level;
> > +			} else if (vgic_irq_needs_resampling(irq) &&
> > +				   !(irq->active || irq->pending_latch)) {
> 
> I'm having a hard time figuring out when and why a level sensitive
> can have pending_latch = true.
> 
> I looked kvm_vgic_inject_irq(), and that function sets pending_latch
> only for edge triggered interrupts (it sets line_level for level
> sensitive ones). But irq_is_pending() looks at **both**
> pending_latch and line_level for level sensitive interrupts.

Yes, and that's what an implementation requires.

> The only place that I've found that sets pending_latch regardless of
> the  interrupt type  is in  vgic_mmio_write_spending() (called  on a
> trapped  write  to   GICD_ISENABLER).

Are you sure? It really should be GICD_ISPENDR. I'll assume that this
is what you mean below.

> vgic_v2_populate_lr()  clears
> pending_latch  only for  edge triggered  interrupts, so  that leaves
> vgic_v2_fold_lr_state()  as  the   only  function  pending_latch  is
> cleared for level sensitive interrupts,  when the interrupt has been
> handled by the guest.  Are we doing all of this  to emulate the fact
> that level sensitive interrupts (either purely virtual or hw mapped)
> made pending by a write  to GICD_ISENABLER remain pending until they
> are handled by the guest?

Yes, or cleared by a write to GICD_ICPENDR. You really need to think
of the input into the GIC as some sort of OR gate combining both the
line level and the PEND register. With a latch for edge interrupts.

Have a look at Figure 4-10 ("Logic of the pending status of a
level-sensitive interrupt") in the GICv2 arch spec (ARM IHI 0048B.b)
to see what I actually mean.

> If that is the case, then I think this is what the code is doing:
> 
> - There's no functional change when the irqchip has HW deactivation
> 
> - For level sensitive, hw mapped interrupts made pending by a write
> to GICD_ISENABLER and not yet handled by the guest (pending_latch ==
> true) we don't clear the pending state of the interrupt.
> 
> - For level sensitive, hw mapped interrupts we clear the pending
> state in the GIC and the device will assert the interrupt again if
> it's still pending at the device 1level. I have a question about
> this. Why don't we sample the interrupt state by calling
> vgic_get_phys_line_level()? Because that would be slower than the
> alternative that you are proposing here?

Yes. It is *much* faster to read the timer status register (for
example) than going via an MMIO access to read the (re)distributor
that will return the same value.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

WARNING: multiple messages have this Message-ID (diff)
From: Marc Zyngier <maz@kernel.org>
To: Alexandru Elisei <alexandru.elisei@arm.com>
Cc: linux-arm-kernel@lists.infradead.org, kvm@vger.kernel.org,
	kvmarm@lists.cs.columbia.edu, James Morse <james.morse@arm.com>,
	Suzuki K Poulose <suzuki.poulose@arm.com>,
	Eric Auger <eric.auger@redhat.com>,
	Hector Martin <marcan@marcan.st>,
	Mark Rutland <mark.rutland@arm.com>,
	Zenghui Yu <yuzenghui@huawei.com>,
	kernel-team@android.com
Subject: Re: [PATCH v4 6/9] KVM: arm64: vgic: Implement SW-driven deactivation
Date: Tue, 22 Jun 2021 17:12:07 +0100	[thread overview]
Message-ID: <87y2b1c208.wl-maz@kernel.org> (raw)
In-Reply-To: <b87fb2e9-a3f9-accc-86d9-64dc2ee90dea@arm.com>

On Thu, 17 Jun 2021 15:58:31 +0100,
Alexandru Elisei <alexandru.elisei@arm.com> wrote:
> 
> Hi Marc,
> 
> On 6/1/21 11:40 AM, Marc Zyngier wrote:
> > In order to deal with these systems that do not offer HW-based
> > deactivation of interrupts, let implement a SW-based approach:
> 
> Nitpick, but shouldn't that be "let's"?

"Let it be...". ;-) Yup.

> 
> >
> > - When the irq is queued into a LR, treat it as a pure virtual
> >   interrupt and set the EOI flag in the LR.
> >
> > - When the interrupt state is read back from the LR, force a
> >   deactivation when the state is invalid (neither active nor
> >   pending)
> >
> > Interrupts requiring such treatment get the VGIC_SW_RESAMPLE flag.
> >
> > Signed-off-by: Marc Zyngier <maz@kernel.org>
> > ---
> >  arch/arm64/kvm/vgic/vgic-v2.c | 19 +++++++++++++++----
> >  arch/arm64/kvm/vgic/vgic-v3.c | 19 +++++++++++++++----
> >  include/kvm/arm_vgic.h        | 10 ++++++++++
> >  3 files changed, 40 insertions(+), 8 deletions(-)
> >
> > diff --git a/arch/arm64/kvm/vgic/vgic-v2.c b/arch/arm64/kvm/vgic/vgic-v2.c
> > index 11934c2af2f4..2c580204f1dc 100644
> > --- a/arch/arm64/kvm/vgic/vgic-v2.c
> > +++ b/arch/arm64/kvm/vgic/vgic-v2.c
> > @@ -108,11 +108,22 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu)
> >  		 * If this causes us to lower the level, we have to also clear
> >  		 * the physical active state, since we will otherwise never be
> >  		 * told when the interrupt becomes asserted again.
> > +		 *
> > +		 * Another case is when the interrupt requires a helping hand
> > +		 * on deactivation (no HW deactivation, for example).
> >  		 */
> > -		if (vgic_irq_is_mapped_level(irq) && (val & GICH_LR_PENDING_BIT)) {
> > -			irq->line_level = vgic_get_phys_line_level(irq);
> > +		if (vgic_irq_is_mapped_level(irq)) {
> > +			bool resample = false;
> > +
> > +			if (val & GICH_LR_PENDING_BIT) {
> > +				irq->line_level = vgic_get_phys_line_level(irq);
> > +				resample = !irq->line_level;
> > +			} else if (vgic_irq_needs_resampling(irq) &&
> > +				   !(irq->active || irq->pending_latch)) {
> 
> I'm having a hard time figuring out when and why a level sensitive
> can have pending_latch = true.
> 
> I looked kvm_vgic_inject_irq(), and that function sets pending_latch
> only for edge triggered interrupts (it sets line_level for level
> sensitive ones). But irq_is_pending() looks at **both**
> pending_latch and line_level for level sensitive interrupts.

Yes, and that's what an implementation requires.

> The only place that I've found that sets pending_latch regardless of
> the  interrupt type  is in  vgic_mmio_write_spending() (called  on a
> trapped  write  to   GICD_ISENABLER).

Are you sure? It really should be GICD_ISPENDR. I'll assume that this
is what you mean below.

> vgic_v2_populate_lr()  clears
> pending_latch  only for  edge triggered  interrupts, so  that leaves
> vgic_v2_fold_lr_state()  as  the   only  function  pending_latch  is
> cleared for level sensitive interrupts,  when the interrupt has been
> handled by the guest.  Are we doing all of this  to emulate the fact
> that level sensitive interrupts (either purely virtual or hw mapped)
> made pending by a write  to GICD_ISENABLER remain pending until they
> are handled by the guest?

Yes, or cleared by a write to GICD_ICPENDR. You really need to think
of the input into the GIC as some sort of OR gate combining both the
line level and the PEND register. With a latch for edge interrupts.

Have a look at Figure 4-10 ("Logic of the pending status of a
level-sensitive interrupt") in the GICv2 arch spec (ARM IHI 0048B.b)
to see what I actually mean.

> If that is the case, then I think this is what the code is doing:
> 
> - There's no functional change when the irqchip has HW deactivation
> 
> - For level sensitive, hw mapped interrupts made pending by a write
> to GICD_ISENABLER and not yet handled by the guest (pending_latch ==
> true) we don't clear the pending state of the interrupt.
> 
> - For level sensitive, hw mapped interrupts we clear the pending
> state in the GIC and the device will assert the interrupt again if
> it's still pending at the device 1level. I have a question about
> this. Why don't we sample the interrupt state by calling
> vgic_get_phys_line_level()? Because that would be slower than the
> alternative that you are proposing here?

Yes. It is *much* faster to read the timer status register (for
example) than going via an MMIO access to read the (re)distributor
that will return the same value.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.

  reply	other threads:[~2021-06-22 16:12 UTC|newest]

Thread overview: 75+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-01 10:39 [PATCH v4 0/9] KVM: arm64: Initial host support for the Apple M1 Marc Zyngier
2021-06-01 10:39 ` Marc Zyngier
2021-06-01 10:39 ` Marc Zyngier
2021-06-01 10:39 ` [PATCH v4 1/9] irqchip/gic: Split vGIC probing information from the GIC code Marc Zyngier
2021-06-01 10:39   ` Marc Zyngier
2021-06-01 10:39   ` Marc Zyngier
2021-06-01 10:39 ` [PATCH v4 2/9] KVM: arm64: Handle physical FIQ as an IRQ while running a guest Marc Zyngier
2021-06-01 10:39   ` Marc Zyngier
2021-06-01 10:39   ` Marc Zyngier
2021-06-01 10:39 ` [PATCH v4 3/9] KVM: arm64: vgic: Be tolerant to the lack of maintenance interrupt masking Marc Zyngier
2021-06-01 10:39   ` Marc Zyngier
2021-06-01 10:39   ` Marc Zyngier
2021-06-11 16:38   ` Alexandru Elisei
2021-06-11 16:38     ` Alexandru Elisei
2021-06-11 16:38     ` Alexandru Elisei
2021-06-11 16:59     ` Alexandru Elisei
2021-06-11 16:59       ` Alexandru Elisei
2021-06-11 16:59       ` Alexandru Elisei
2021-06-01 10:40 ` [PATCH v4 4/9] KVM: arm64: vgic: Let an interrupt controller advertise lack of HW deactivation Marc Zyngier
2021-06-01 10:40   ` Marc Zyngier
2021-06-01 10:40   ` Marc Zyngier
2021-06-15 14:26   ` Alexandru Elisei
2021-06-15 14:26     ` Alexandru Elisei
2021-06-15 14:26     ` Alexandru Elisei
2021-06-22 16:19     ` Marc Zyngier
2021-06-22 16:19       ` Marc Zyngier
2021-06-22 16:19       ` Marc Zyngier
2021-06-01 10:40 ` [PATCH v4 5/9] KVM: arm64: vgic: move irq->get_input_level into an ops structure Marc Zyngier
2021-06-01 10:40   ` Marc Zyngier
2021-06-01 10:40   ` Marc Zyngier
2021-06-15 14:45   ` Alexandru Elisei
2021-06-15 14:45     ` Alexandru Elisei
2021-06-15 14:45     ` Alexandru Elisei
2021-06-22 15:55     ` Marc Zyngier
2021-06-22 15:55       ` Marc Zyngier
2021-06-22 15:55       ` Marc Zyngier
2021-06-01 10:40 ` [PATCH v4 6/9] KVM: arm64: vgic: Implement SW-driven deactivation Marc Zyngier
2021-06-01 10:40   ` Marc Zyngier
2021-06-01 10:40   ` Marc Zyngier
2021-06-17 14:58   ` Alexandru Elisei
2021-06-17 14:58     ` Alexandru Elisei
2021-06-17 14:58     ` Alexandru Elisei
2021-06-22 16:12     ` Marc Zyngier [this message]
2021-06-22 16:12       ` Marc Zyngier
2021-06-22 16:12       ` Marc Zyngier
2021-06-23 14:15       ` Alexandru Elisei
2021-06-23 14:15         ` Alexandru Elisei
2021-06-23 14:15         ` Alexandru Elisei
2021-06-01 10:40 ` [PATCH v4 7/9] KVM: arm64: timer: Refactor IRQ configuration Marc Zyngier
2021-06-01 10:40   ` Marc Zyngier
2021-06-01 10:40   ` Marc Zyngier
2021-06-21 16:19   ` Alexandru Elisei
2021-06-21 16:19     ` Alexandru Elisei
2021-06-21 16:19     ` Alexandru Elisei
2021-06-01 10:40 ` [PATCH v4 8/9] KVM: arm64: timer: Add support for SW-based deactivation Marc Zyngier
2021-06-01 10:40   ` Marc Zyngier
2021-06-01 10:40   ` Marc Zyngier
2021-06-01 10:40 ` [PATCH v4 9/9] irqchip/apple-aic: Advertise some level of vGICv3 compatibility Marc Zyngier
2021-06-01 10:40   ` Marc Zyngier
2021-06-01 10:40   ` Marc Zyngier
2021-06-22 15:39 ` [PATCH v4 0/9] KVM: arm64: Initial host support for the Apple M1 Alexandru Elisei
2021-06-22 15:39   ` Alexandru Elisei
2021-06-22 15:39   ` Alexandru Elisei
2021-06-22 15:51   ` Marc Zyngier
2021-06-22 15:51     ` Marc Zyngier
2021-06-22 15:51     ` Marc Zyngier
2021-06-22 16:03     ` Alexandru Elisei
2021-06-22 16:03       ` Alexandru Elisei
2021-06-22 16:03       ` Alexandru Elisei
2021-06-22 16:26       ` Marc Zyngier
2021-06-22 16:26         ` Marc Zyngier
2021-06-22 16:26         ` Marc Zyngier
2021-06-23 16:18         ` Alexandru Elisei
2021-06-23 16:18           ` Alexandru Elisei
2021-06-23 16:18           ` Alexandru Elisei

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=87y2b1c208.wl-maz@kernel.org \
    --to=maz@kernel.org \
    --cc=alexandru.elisei@arm.com \
    --cc=kernel-team@android.com \
    --cc=kvm@vger.kernel.org \
    --cc=kvmarm@lists.cs.columbia.edu \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=marcan@marcan.st \
    /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.