All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sascha Bischoff <Sascha.Bischoff@arm.com>
To: "maz@kernel.org" <maz@kernel.org>
Cc: "yuzenghui@huawei.com" <yuzenghui@huawei.com>,
	Timothy Hayes <Timothy.Hayes@arm.com>,
	Suzuki Poulose <Suzuki.Poulose@arm.com>, nd <nd@arm.com>,
	"peter.maydell@linaro.org" <peter.maydell@linaro.org>,
	"kvmarm@lists.linux.dev" <kvmarm@lists.linux.dev>,
	"jonathan.cameron@huawei.com" <jonathan.cameron@huawei.com>,
	"linux-arm-kernel@lists.infradead.org"
	<linux-arm-kernel@lists.infradead.org>,
	"kvm@vger.kernel.org" <kvm@vger.kernel.org>,
	Joey Gouly <Joey.Gouly@arm.com>,
	"lpieralisi@kernel.org" <lpieralisi@kernel.org>,
	"oliver.upton@linux.dev" <oliver.upton@linux.dev>
Subject: Re: [PATCH v6 19/39] KVM: arm64: gic-v5: Implement PPI interrupt injection
Date: Wed, 18 Mar 2026 17:31:31 +0000	[thread overview]
Message-ID: <cb4d0804b253595bb6d95847ef1628ed1f0c0b80.camel@arm.com> (raw)
In-Reply-To: <86ikau5sf8.wl-maz@kernel.org>

On Tue, 2026-03-17 at 16:31 +0000, Marc Zyngier wrote:
> On Tue, 17 Mar 2026 11:44:55 +0000,
> Sascha Bischoff <Sascha.Bischoff@arm.com> wrote:
> > 
> > This change introduces interrupt injection for PPIs for GICv5-based
> > guests.
> > 
> > The lifecycle of PPIs is largely managed by the hardware for a
> > GICv5
> > system. The hypervisor injects pending state into the guest by
> > using
> > the ICH_PPI_PENDRx_EL2 registers. These are used by the hardware to
> > pick a Highest Priority Pending Interrupt (HPPI) for the guest
> > based
> > on the enable state of each individual interrupt. The enable state
> > and
> > priority for each interrupt are provided by the guest itself
> > (through
> > writes to the PPI registers).
> > 
> > When Direct Virtual Interrupt (DVI) is set for a particular PPI,
> > the
> > hypervisor is even able to skip the injection of the pending state
> > altogether - it all happens in hardware.
> > 
> > The result of the above is that no AP lists are required for GICv5,
> > unlike for older GICs. Instead, for PPIs the ICH_PPI_* registers
> > fulfil the same purpose for all 128 PPIs. Hence, as long as the
> > ICH_PPI_* registers are populated prior to guest entry, and merged
> > back into the KVM shadow state on exit, the PPI state is preserved,
> > and interrupts can be injected.
> > 
> > When injecting the state of a PPI the state is merged into the
> > PPI-specific vgic_irq structure. The PPIs are made pending via the
> > ICH_PPI_PENDRx_EL2 registers, the value of which is generated from
> > the
> > vgic_irq structures for each PPI exposed on guest entry. The
> > queue_irq_unlock() irq_op is required to kick the vCPU to ensure
> > that
> > it seems the new state. The result is that no AP lists are used for
> > private interrupts on GICv5.
> > 
> > Prior to entering the guest, vgic_v5_flush_ppi_state() is called
> > from
> > kvm_vgic_flush_hwstate(). This generates the pending state to
> > inject
> > into the guest, and snapshots it (twice - an entry and an exit
> > copy)
> > in order to track any changes. These changes can come from a guest
> > consuming an interrupt or from a guest making an Edge-triggered
> > interrupt pending.
> > 
> > When returning from running a guest, the guest's PPI state is
> > merged
> > back into KVM's vgic_irq state in vgic_v5_merge_ppi_state() from
> > kvm_vgic_sync_hwstate(). The Enable and Active state is synced back
> > for
> > all PPIs, and the pending state is synced back for Edge PPIs (Level
> > is
> > driven directly by the devices generating said levels). The
> > incoming
> > pending state from the guest is merged with KVM's shadow state to
> > avoid losing any incoming interrupts.
> > 
> > Signed-off-by: Sascha Bischoff <sascha.bischoff@arm.com>
> > Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
> > ---
> >  arch/arm64/kvm/vgic/vgic-v5.c | 143
> > ++++++++++++++++++++++++++++++++++
> >  arch/arm64/kvm/vgic/vgic.c    |  41 ++++++++--
> >  arch/arm64/kvm/vgic/vgic.h    |  25 +++---
> >  3 files changed, 194 insertions(+), 15 deletions(-)
> > 
> > diff --git a/arch/arm64/kvm/vgic/vgic-v5.c
> > b/arch/arm64/kvm/vgic/vgic-v5.c
> > index 07f416fbc4bc8..e080fce61dc35 100644
> > --- a/arch/arm64/kvm/vgic/vgic-v5.c
> > +++ b/arch/arm64/kvm/vgic/vgic-v5.c
> > @@ -122,6 +122,149 @@ int vgic_v5_finalize_ppi_state(struct kvm
> > *kvm)
> >  	return 0;
> >  }
> >  
> > +/*
> > + * For GICv5, the PPIs are mostly directly managed by the
> > hardware. We (the
> > + * hypervisor) handle the pending, active, enable state
> > save/restore, but don't
> > + * need the PPIs to be queued on a per-VCPU AP list. Therefore,
> > sanity check the
> > + * state, unlock, and return.
> > + */
> > +static bool vgic_v5_ppi_queue_irq_unlock(struct kvm *kvm, struct
> > vgic_irq *irq,
> > +					 unsigned long flags)
> > +	__releases(&irq->irq_lock)
> > +{
> > +	struct kvm_vcpu *vcpu;
> > +
> > +	lockdep_assert_held(&irq->irq_lock);
> > +
> > +	if (WARN_ON_ONCE(!__irq_is_ppi(KVM_DEV_TYPE_ARM_VGIC_V5,
> > irq->intid)))
> > +		goto out_unlock_fail;
> > +
> > +	vcpu = irq->target_vcpu;
> > +	if (WARN_ON_ONCE(!vcpu))
> > +		goto out_unlock_fail;
> > +
> > +	raw_spin_unlock_irqrestore(&irq->irq_lock, flags);
> > +
> > +	/* Directly kick the target VCPU to make sure it sees the
> > IRQ */
> > +	kvm_make_request(KVM_REQ_IRQ_PENDING, vcpu);
> > +	kvm_vcpu_kick(vcpu);
> > +
> > +	return true;
> > +
> > +out_unlock_fail:
> > +	raw_spin_unlock_irqrestore(&irq->irq_lock, flags);
> > +
> > +	return false;
> > +}
> > +
> > +static struct irq_ops vgic_v5_ppi_irq_ops = {
> > +	.queue_irq_unlock = vgic_v5_ppi_queue_irq_unlock,
> > +};
> > +
> > +void vgic_v5_set_ppi_ops(struct vgic_irq *irq)
> > +{
> > +	if (WARN_ON(!irq))
> > +		return;
> > +
> > +	guard(raw_spinlock_irqsave)(&irq->irq_lock);
> > +
> > +	if (!WARN_ON(irq->ops))
> > +		irq->ops = &vgic_v5_ppi_irq_ops;
> > +}
> 
> Why isn't this a call to kvm_vgic_set_irq_ops()? It feels very odd to
> have two ways to do the same thing.

Absolutely no good reason not to do that. This needs to drop the taking
of the lock to avoid double locking, of course, but it makes sense.

I think this becomes:

diff --git a/arch/arm64/kvm/vgic/vgic-v5.c b/arch/arm64/kvm/vgic/vgic-
v5.c
index e080fce61dc35..a66e8bc1ca256 100644
--- a/arch/arm64/kvm/vgic/vgic-v5.c
+++ b/arch/arm64/kvm/vgic/vgic-v5.c
@@ -161,15 +161,9 @@ static struct irq_ops vgic_v5_ppi_irq_ops = {
        .queue_irq_unlock = vgic_v5_ppi_queue_irq_unlock,
 };
 
-void vgic_v5_set_ppi_ops(struct vgic_irq *irq)
+void vgic_v5_set_ppi_ops(struct kvm_vcpu *vcpu, u32 vintid)
 {
-       if (WARN_ON(!irq))
-               return;
-
-       guard(raw_spinlock_irqsave)(&irq->irq_lock);
-
-       if (!WARN_ON(irq->ops))
-               irq->ops = &vgic_v5_ppi_irq_ops;
+       kvm_vgic_set_irq_ops(vcpu, vintid, &vgic_v5_ppi_irq_ops);
 }
 
 /*
diff --git a/arch/arm64/kvm/vgic/vgic.h b/arch/arm64/kvm/vgic/vgic.h
index ef4e3fb7159dd..d90af676d5d06 100644
--- a/arch/arm64/kvm/vgic/vgic.h
+++ b/arch/arm64/kvm/vgic/vgic.h
@@ -364,7 +364,7 @@ void vgic_debug_init(struct kvm *kvm);
 void vgic_debug_destroy(struct kvm *kvm);
 
 int vgic_v5_probe(const struct gic_kvm_info *info);
-void vgic_v5_set_ppi_ops(struct vgic_irq *irq);
+void vgic_v5_set_ppi_ops(struct kvm_vcpu *vcpu, u32 vintid);
 void vgic_v5_flush_ppi_state(struct kvm_vcpu *vcpu);
 void vgic_v5_fold_ppi_state(struct kvm_vcpu *vcpu);
 void vgic_v5_load(struct kvm_vcpu *vcpu);

Thanks,
Sascha

> 
> Thanks,
> 
> 	M.
> 


  reply	other threads:[~2026-03-18 17:32 UTC|newest]

Thread overview: 61+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-17 11:39 [PATCH v6 00/39] KVM: arm64: Introduce vGIC-v5 with PPI support Sascha Bischoff
2026-03-17 11:40 ` [PATCH v6 01/39] KVM: arm64: vgic-v3: Drop userspace write sanitization for ID_AA64PFR0.GIC on GICv5 Sascha Bischoff
2026-03-19 10:02   ` Jonathan Cameron
2026-03-19 11:35     ` Sascha Bischoff
2026-03-20 10:27       ` Jonathan Cameron
2026-03-17 11:40 ` [PATCH v6 02/39] KVM: arm64: vgic: Rework vgic_is_v3() and add vgic_host_has_gicvX() Sascha Bischoff
2026-03-17 11:40 ` [PATCH v6 03/39] KVM: arm64: Return early from kvm_finalize_sys_regs() if guest has run Sascha Bischoff
2026-03-19 10:12   ` Jonathan Cameron
2026-03-19 11:41     ` Sascha Bischoff
2026-03-17 11:40 ` [PATCH v6 04/39] KVM: arm64: vgic: Split out mapping IRQs and setting irq_ops Sascha Bischoff
2026-03-17 16:00   ` Marc Zyngier
2026-03-18 17:30     ` Sascha Bischoff
2026-03-17 11:41 ` [PATCH v6 05/39] arm64/sysreg: Add remaining GICv5 ICC_ & ICH_ sysregs for KVM support Sascha Bischoff
2026-03-17 11:41 ` [PATCH v6 06/39] arm64/sysreg: Add GICR CDNMIA encoding Sascha Bischoff
2026-03-17 11:41 ` [PATCH v6 07/39] KVM: arm64: gic-v5: Add ARM_VGIC_V5 device to KVM headers Sascha Bischoff
2026-03-17 11:42 ` [PATCH v6 08/39] KVM: arm64: gic: Introduce interrupt type helpers Sascha Bischoff
2026-03-17 11:42 ` [PATCH v6 09/39] KVM: arm64: gic-v5: Add Arm copyright header Sascha Bischoff
2026-03-17 11:42 ` [PATCH v6 10/39] KVM: arm64: gic-v5: Detect implemented PPIs on boot Sascha Bischoff
2026-03-17 11:42 ` [PATCH v6 11/39] KVM: arm64: gic-v5: Sanitize ID_AA64PFR2_EL1.GCIE Sascha Bischoff
2026-03-19 10:31   ` Jonathan Cameron
2026-03-19 14:02     ` Sascha Bischoff
2026-03-17 11:43 ` [PATCH v6 12/39] KVM: arm64: gic-v5: Support GICv5 FGTs & FGUs Sascha Bischoff
2026-03-17 11:43 ` [PATCH v6 13/39] KVM: arm64: gic-v5: Add emulation for ICC_IAFFIDR_EL1 accesses Sascha Bischoff
2026-03-19 10:34   ` Jonathan Cameron
2026-03-17 11:43 ` [PATCH v6 14/39] KVM: arm64: gic-v5: Trap and emulate ICC_IDR0_EL1 accesses Sascha Bischoff
2026-03-19 10:38   ` Jonathan Cameron
2026-03-17 11:43 ` [PATCH v6 15/39] KVM: arm64: gic-v5: Add vgic-v5 save/restore hyp interface Sascha Bischoff
2026-03-17 11:44 ` [PATCH v6 16/39] KVM: arm64: gic-v5: Implement GICv5 load/put and save/restore Sascha Bischoff
2026-03-17 11:44 ` [PATCH v6 17/39] KVM: arm64: gic-v5: Finalize GICv5 PPIs and generate mask Sascha Bischoff
2026-03-17 11:44 ` [PATCH v6 18/39] KVM: arm64: gic: Introduce queue_irq_unlock to irq_ops Sascha Bischoff
2026-03-17 11:44 ` [PATCH v6 19/39] KVM: arm64: gic-v5: Implement PPI interrupt injection Sascha Bischoff
2026-03-17 16:31   ` Marc Zyngier
2026-03-18 17:31     ` Sascha Bischoff [this message]
2026-03-17 11:45 ` [PATCH v6 20/39] KVM: arm64: gic-v5: Init Private IRQs (PPIs) for GICv5 Sascha Bischoff
2026-03-17 16:42   ` Marc Zyngier
2026-03-18 17:34     ` Sascha Bischoff
2026-03-17 11:45 ` [PATCH v6 21/39] KVM: arm64: gic-v5: Clear TWI if single task running Sascha Bischoff
2026-03-17 11:45 ` [PATCH v6 22/39] KVM: arm64: gic-v5: Check for pending PPIs Sascha Bischoff
2026-03-17 17:08   ` Marc Zyngier
2026-03-19  8:27     ` Sascha Bischoff
2026-03-17 11:45 ` [PATCH v6 23/39] KVM: arm64: gic-v5: Trap and mask guest ICC_PPI_ENABLERx_EL1 writes Sascha Bischoff
2026-03-17 11:46 ` [PATCH v6 24/39] KVM: arm64: Introduce set_direct_injection irq_op Sascha Bischoff
2026-03-17 11:46 ` [PATCH v6 25/39] KVM: arm64: gic-v5: Implement direct injection of PPIs Sascha Bischoff
2026-03-17 11:46 ` [PATCH v6 26/39] KVM: arm64: gic-v5: Support GICv5 interrupts with KVM_IRQ_LINE Sascha Bischoff
2026-03-17 11:46 ` [PATCH v6 27/39] KVM: arm64: gic-v5: Create and initialise vgic_v5 Sascha Bischoff
2026-03-17 11:47 ` [PATCH v6 28/39] KVM: arm64: gic-v5: Initialise ID and priority bits when resetting vcpu Sascha Bischoff
2026-03-17 11:47 ` [PATCH v6 29/39] KVM: arm64: gic-v5: Enlighten arch timer for GICv5 Sascha Bischoff
2026-03-17 18:05   ` Marc Zyngier
2026-03-19  8:59     ` Sascha Bischoff
2026-03-17 11:47 ` [PATCH v6 30/39] KVM: arm64: gic-v5: Mandate architected PPI for PMU emulation on GICv5 Sascha Bischoff
2026-03-17 11:48 ` [PATCH v6 31/39] KVM: arm64: gic: Hide GICv5 for protected guests Sascha Bischoff
2026-03-17 11:48 ` [PATCH v6 32/39] KVM: arm64: gic-v5: Hide FEAT_GCIE from NV GICv5 guests Sascha Bischoff
2026-03-17 11:48 ` [PATCH v6 33/39] KVM: arm64: gic-v5: Introduce kvm_arm_vgic_v5_ops and register them Sascha Bischoff
2026-03-17 11:48 ` [PATCH v6 34/39] KVM: arm64: gic-v5: Set ICH_VCTLR_EL2.En on boot Sascha Bischoff
2026-03-17 11:49 ` [PATCH v6 35/39] KVM: arm64: gic-v5: Probe for GICv5 device Sascha Bischoff
2026-03-18 15:34   ` Joey Gouly
2026-03-19  8:36     ` Sascha Bischoff
2026-03-17 11:49 ` [PATCH v6 36/39] Documentation: KVM: Introduce documentation for VGICv5 Sascha Bischoff
2026-03-17 11:49 ` [PATCH v6 37/39] KVM: arm64: gic-v5: Communicate userspace-driveable PPIs via a UAPI Sascha Bischoff
2026-03-17 11:49 ` [PATCH v6 38/39] KVM: arm64: selftests: Introduce a minimal GICv5 PPI selftest Sascha Bischoff
2026-03-17 11:50 ` [PATCH v6 39/39] KVM: arm64: selftests: Add no-vgic-v5 selftest Sascha Bischoff

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=cb4d0804b253595bb6d95847ef1628ed1f0c0b80.camel@arm.com \
    --to=sascha.bischoff@arm.com \
    --cc=Joey.Gouly@arm.com \
    --cc=Suzuki.Poulose@arm.com \
    --cc=Timothy.Hayes@arm.com \
    --cc=jonathan.cameron@huawei.com \
    --cc=kvm@vger.kernel.org \
    --cc=kvmarm@lists.linux.dev \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=lpieralisi@kernel.org \
    --cc=maz@kernel.org \
    --cc=nd@arm.com \
    --cc=oliver.upton@linux.dev \
    --cc=peter.maydell@linaro.org \
    --cc=yuzenghui@huawei.com \
    /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.