From: Marc Zyngier <maz@kernel.org>
To: Sascha Bischoff <Sascha.Bischoff@arm.com>
Cc: "linux-arm-kernel@lists.infradead.org"
<linux-arm-kernel@lists.infradead.org>,
"kvmarm@lists.linux.dev" <kvmarm@lists.linux.dev>,
"kvm@vger.kernel.org" <kvm@vger.kernel.org>, nd <nd@arm.com>,
"oliver.upton@linux.dev" <oliver.upton@linux.dev>,
Joey Gouly <Joey.Gouly@arm.com>,
Suzuki Poulose <Suzuki.Poulose@arm.com>,
"yuzenghui@huawei.com" <yuzenghui@huawei.com>,
"peter.maydell@linaro.org" <peter.maydell@linaro.org>,
"lpieralisi@kernel.org" <lpieralisi@kernel.org>,
Timothy Hayes <Timothy.Hayes@arm.com>,
"jonathan.cameron@huawei.com" <jonathan.cameron@huawei.com>
Subject: Re: [PATCH v5 17/36] KVM: arm64: gic-v5: Finalize GICv5 PPIs and generate mask
Date: Wed, 04 Mar 2026 10:50:27 +0000 [thread overview]
Message-ID: <86342f98cs.wl-maz@kernel.org> (raw)
In-Reply-To: <20260226155515.1164292-18-sascha.bischoff@arm.com>
On Thu, 26 Feb 2026 15:59:48 +0000,
Sascha Bischoff <Sascha.Bischoff@arm.com> wrote:
>
> We only want to expose a subset of the PPIs to a guest. If a PPI does
> not have an owner, it is not being actively driven by a device. The
> SW_PPI is a special case, as it is likely for userspace to wish to
> inject that.
>
> Therefore, just prior to running the guest for the first time, we need
> to finalize the PPIs. A mask is generated which, when combined with
> trapping a guest's PPI accesses, allows for the guest's view of the
> PPI to be filtered. This mask is global to the VM as all VCPUs PPI
> configurations must match.
>
> In addition, the PPI HMR is calculated.
>
> Signed-off-by: Sascha Bischoff <sascha.bischoff@arm.com>
> Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
> ---
> arch/arm64/kvm/arm.c | 4 +++
> arch/arm64/kvm/vgic/vgic-v5.c | 46 ++++++++++++++++++++++++++++++
> include/kvm/arm_vgic.h | 9 ++++++
> include/linux/irqchip/arm-gic-v5.h | 17 +++++++++++
> 4 files changed, 76 insertions(+)
>
> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> index eb2ca65dc7297..8290c5df0616e 100644
> --- a/arch/arm64/kvm/arm.c
> +++ b/arch/arm64/kvm/arm.c
> @@ -935,6 +935,10 @@ int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu)
> return ret;
> }
>
> + ret = vgic_v5_finalize_ppi_state(kvm);
> + if (ret)
> + return ret;
> +
> if (is_protected_kvm_enabled()) {
> ret = pkvm_create_hyp_vm(kvm);
> if (ret)
> diff --git a/arch/arm64/kvm/vgic/vgic-v5.c b/arch/arm64/kvm/vgic/vgic-v5.c
> index f5cd9decfc26e..db2225aefb130 100644
> --- a/arch/arm64/kvm/vgic/vgic-v5.c
> +++ b/arch/arm64/kvm/vgic/vgic-v5.c
> @@ -86,6 +86,52 @@ int vgic_v5_probe(const struct gic_kvm_info *info)
> return 0;
> }
>
> +int vgic_v5_finalize_ppi_state(struct kvm *kvm)
> +{
> + struct kvm_vcpu *vcpu;
> +
> + if (!vgic_is_v5(kvm))
> + return 0;
> +
> + /* The PPI state for all VCPUs should be the same. Pick the first. */
> + vcpu = kvm_get_vcpu(kvm, 0);
> +
> + vcpu->kvm->arch.vgic.gicv5_vm.vgic_ppi_mask[0] = 0;
> + vcpu->kvm->arch.vgic.gicv5_vm.vgic_ppi_mask[1] = 0;
> + vcpu->kvm->arch.vgic.gicv5_vm.vgic_ppi_hmr[0] = 0;
> + vcpu->kvm->arch.vgic.gicv5_vm.vgic_ppi_hmr[1] = 0;
vcpu->kvm == kvm. You don't need the indirection (same in most of the
function).
> +
> + for (int i = 0; i < VGIC_V5_NR_PRIVATE_IRQS; i++) {
> + int reg = i / 64;
> + u64 bit = BIT_ULL(i % 64);
> + struct vgic_irq *irq = &vcpu->arch.vgic_cpu.private_irqs[i];
vgic_get_vcpu_irq()?
> +
> + guard(raw_spinlock_irqsave)(&irq->irq_lock);
> +
> + /*
> + * We only expose PPIs with an owner or the SW_PPI to the
> + * guest.
> + */
> + if (!irq->owner &&
> + FIELD_GET(GICV5_HWIRQ_ID, irq->intid) != GICV5_ARCH_PPI_SW_PPI)
> + continue;
This sort of construct is rather cumbersome, and I see it replicated
in quite a few places. How about introducing a couple of basic
accessors:
#define vgic_v5_get_hwirq_id(x) FIELD_GET(GICV5_HWIRQ_ID, (x))
#define vgic_v5_set_hwirq_id(x) FIELD_PREP(GICV5_HWIRQ_ID, (x))
which is a bit easier on the eye?
> +
> + /*
> + * If the PPI isn't implemented, we can't pass it through to a
> + * guest anyhow.
> + */
> + if (!(ppi_caps.impl_ppi_mask[reg] & bit))
> + continue;
> +
> + vcpu->kvm->arch.vgic.gicv5_vm.vgic_ppi_mask[reg] |= bit;
> +
> + if (irq->config == VGIC_CONFIG_LEVEL)
> + vcpu->kvm->arch.vgic.gicv5_vm.vgic_ppi_hmr[reg] |= bit;
> + }
> +
> + return 0;
> +}
> +
> /*
> * Sets/clears the corresponding bit in the ICH_PPI_DVIR register.
> */
> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
> index d828861f8298a..a4416afca5efc 100644
> --- a/include/kvm/arm_vgic.h
> +++ b/include/kvm/arm_vgic.h
> @@ -32,6 +32,8 @@
> #define VGIC_MIN_LPI 8192
> #define KVM_IRQCHIP_NUM_PINS (1020 - 32)
>
> +#define VGIC_V5_NR_PRIVATE_IRQS 128
> +
> #define is_v5_type(t, i) (FIELD_GET(GICV5_HWIRQ_TYPE, (i)) == (t))
>
> #define __irq_is_sgi(t, i) \
> @@ -381,6 +383,11 @@ struct vgic_dist {
> * else.
> */
> struct its_vm its_vm;
> +
> + /*
> + * GICv5 per-VM data.
> + */
> + struct gicv5_vm gicv5_vm;
Depending how this grows, we may have to move that as part of a union
with the previous member (which is obviously v4 specific).
> };
>
> struct vgic_v2_cpu_if {
> @@ -567,6 +574,8 @@ int vgic_v4_load(struct kvm_vcpu *vcpu);
> void vgic_v4_commit(struct kvm_vcpu *vcpu);
> int vgic_v4_put(struct kvm_vcpu *vcpu);
>
> +int vgic_v5_finalize_ppi_state(struct kvm *kvm);
> +
> bool vgic_state_is_nested(struct kvm_vcpu *vcpu);
>
> /* CPU HP callbacks */
> diff --git a/include/linux/irqchip/arm-gic-v5.h b/include/linux/irqchip/arm-gic-v5.h
> index 3e838a3058861..30a1b656daa35 100644
> --- a/include/linux/irqchip/arm-gic-v5.h
> +++ b/include/linux/irqchip/arm-gic-v5.h
> @@ -380,6 +380,23 @@ struct gicv5_vpe {
> bool resident;
> };
>
> +struct gicv5_vm {
> + /*
> + * We only expose a subset of PPIs to the guest. This subset
> + * is a combination of the PPIs that are actually implemented
> + * and what we actually choose to expose.
> + */
> + u64 vgic_ppi_mask[2];
> +
> + /*
> + * The HMR itself is handled by the hardware, but we still need to have
> + * a mask that we can use when merging in pending state (only the state
> + * of Edge PPIs is merged back in from the guest an the HMR provides a
> + * convenient way to do that).
> + */
> + u64 vgic_ppi_hmr[2];
> +};
> +
> struct gicv5_its_devtab_cfg {
> union {
> struct {
Thanks,
M.
--
Without deviation from the norm, progress is not possible.
next prev parent reply other threads:[~2026-03-04 10:50 UTC|newest]
Thread overview: 56+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-26 15:55 [PATCH v5 00/36] KVM: arm64: Introduce vGIC-v5 with PPI support Sascha Bischoff
2026-02-26 15:55 ` [PATCH v5 01/36] KVM: arm64: vgic-v3: Drop userspace write sanitization for ID_AA64PFR0.GIC on GICv5 Sascha Bischoff
2026-02-26 15:55 ` [PATCH v5 02/36] KVM: arm64: vgic: Rework vgic_is_v3() and add vgic_host_has_gicvX() Sascha Bischoff
2026-02-26 15:56 ` [PATCH v5 03/36] KVM: arm64: Return early from kvm_finalize_sys_regs() if guest has run Sascha Bischoff
2026-02-26 15:56 ` [PATCH v5 04/36] arm64/sysreg: Add remaining GICv5 ICC_ & ICH_ sysregs for KVM support Sascha Bischoff
2026-02-26 15:56 ` [PATCH v5 05/36] arm64/sysreg: Add GICR CDNMIA encoding Sascha Bischoff
2026-02-26 15:56 ` [PATCH v5 06/36] KVM: arm64: gic-v5: Add ARM_VGIC_V5 device to KVM headers Sascha Bischoff
2026-02-26 15:57 ` [PATCH v5 07/36] KVM: arm64: gic: Introduce interrupt type helpers Sascha Bischoff
2026-03-03 15:04 ` Marc Zyngier
2026-03-03 17:21 ` Sascha Bischoff
2026-02-26 15:57 ` [PATCH v5 08/36] KVM: arm64: gic-v5: Add Arm copyright header Sascha Bischoff
2026-02-26 15:57 ` [PATCH v5 09/36] KVM: arm64: gic-v5: Detect implemented PPIs on boot Sascha Bischoff
2026-03-03 15:10 ` Marc Zyngier
2026-03-03 17:22 ` Sascha Bischoff
2026-02-26 15:58 ` [PATCH v5 10/36] KVM: arm64: gic-v5: Sanitize ID_AA64PFR2_EL1.GCIE Sascha Bischoff
2026-03-03 15:54 ` Marc Zyngier
2026-03-03 17:49 ` Sascha Bischoff
2026-02-26 15:58 ` [PATCH v5 11/36] KVM: arm64: gic-v5: Support GICv5 FGTs & FGUs Sascha Bischoff
2026-02-26 15:58 ` [PATCH v5 12/36] KVM: arm64: gic-v5: Add emulation for ICC_IAFFIDR_EL1 accesses Sascha Bischoff
2026-03-03 16:02 ` Marc Zyngier
2026-03-03 17:54 ` Sascha Bischoff
2026-02-26 15:58 ` [PATCH v5 13/36] KVM: arm64: gic-v5: Trap and emulate ICC_IDR0_EL1 accesses Sascha Bischoff
2026-02-26 15:59 ` [PATCH v5 14/36] KVM: arm64: gic-v5: Add vgic-v5 save/restore hyp interface Sascha Bischoff
2026-03-03 17:10 ` Marc Zyngier
2026-03-04 11:32 ` Sascha Bischoff
2026-02-26 15:59 ` [PATCH v5 15/36] KVM: arm64: gic-v5: Implement GICv5 load/put and save/restore Sascha Bischoff
2026-03-04 9:26 ` Marc Zyngier
2026-03-04 14:21 ` Sascha Bischoff
2026-02-26 15:59 ` [PATCH v5 16/36] KVM: arm64: gic-v5: Implement direct injection of PPIs Sascha Bischoff
2026-03-04 9:35 ` Marc Zyngier
2026-03-05 11:22 ` Sascha Bischoff
2026-02-26 15:59 ` [PATCH v5 17/36] KVM: arm64: gic-v5: Finalize GICv5 PPIs and generate mask Sascha Bischoff
2026-03-04 10:50 ` Marc Zyngier [this message]
2026-03-04 17:38 ` Sascha Bischoff
2026-02-26 16:00 ` [PATCH v5 18/36] KVM: arm64: gic: Introduce queue_irq_unlock to irq_ops Sascha Bischoff
2026-02-26 16:00 ` [PATCH v5 19/36] KVM: arm64: gic-v5: Implement PPI interrupt injection Sascha Bischoff
2026-03-04 13:08 ` Marc Zyngier
2026-02-26 16:00 ` [PATCH v5 20/36] KVM: arm64: gic-v5: Init Private IRQs (PPIs) for GICv5 Sascha Bischoff
2026-03-04 14:21 ` Marc Zyngier
2026-03-05 13:35 ` Sascha Bischoff
2026-02-26 16:00 ` [PATCH v5 21/36] KVM: arm64: gic-v5: Check for pending PPIs Sascha Bischoff
2026-02-26 16:01 ` [PATCH v5 22/36] KVM: arm64: gic-v5: Trap and mask guest ICC_PPI_ENABLERx_EL1 writes Sascha Bischoff
2026-02-26 16:01 ` [PATCH v5 23/36] KVM: arm64: gic-v5: Support GICv5 interrupts with KVM_IRQ_LINE Sascha Bischoff
2026-02-26 16:01 ` [PATCH v5 24/36] KVM: arm64: gic-v5: Create and initialise vgic_v5 Sascha Bischoff
2026-02-26 16:01 ` [PATCH v5 25/36] KVM: arm64: gic-v5: Initialise ID and priority bits when resetting vcpu Sascha Bischoff
2026-02-26 16:02 ` [PATCH v5 26/36] KVM: arm64: gic-v5: Enlighten arch timer for GICv5 Sascha Bischoff
2026-02-26 16:02 ` [PATCH v5 27/36] KVM: arm64: gic-v5: Mandate architected PPI for PMU emulation on GICv5 Sascha Bischoff
2026-02-26 16:02 ` [PATCH v5 28/36] KVM: arm64: gic: Hide GICv5 for protected guests Sascha Bischoff
2026-02-26 16:02 ` [PATCH v5 29/36] KVM: arm64: gic-v5: Hide FEAT_GCIE from NV GICv5 guests Sascha Bischoff
2026-02-26 16:03 ` [PATCH v5 30/36] KVM: arm64: gic-v5: Introduce kvm_arm_vgic_v5_ops and register them Sascha Bischoff
2026-02-26 16:03 ` [PATCH v5 31/36] KVM: arm64: gic-v5: Set ICH_VCTLR_EL2.En on boot Sascha Bischoff
2026-02-26 16:03 ` [PATCH v5 32/36] KVM: arm64: gic-v5: Probe for GICv5 device Sascha Bischoff
2026-02-26 16:04 ` [PATCH v5 33/36] Documentation: KVM: Introduce documentation for VGICv5 Sascha Bischoff
2026-02-26 16:04 ` [PATCH v5 34/36] KVM: arm64: selftests: Introduce a minimal GICv5 PPI selftest Sascha Bischoff
2026-02-26 16:04 ` [PATCH v5 35/36] KVM: arm64: gic-v5: Communicate userspace-driveable PPIs via a UAPI Sascha Bischoff
2026-02-26 16:04 ` [PATCH v5 36/36] 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=86342f98cs.wl-maz@kernel.org \
--to=maz@kernel.org \
--cc=Joey.Gouly@arm.com \
--cc=Sascha.Bischoff@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=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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox