[PATCH v2 21/36] KVM: arm64: gic-v5: Finalize GICv5 PPIs and generate mask
Jonathan Cameron
jonathan.cameron at huawei.com
Wed Jan 7 07:08:38 PST 2026
On Fri, 19 Dec 2025 15:52:43 +0000
Sascha Bischoff <Sascha.Bischoff at 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.
>
> Signed-off-by: Sascha Bischoff <sascha.bischoff at arm.com>
Minor suggestion inline. Either way
Reviewed-by: Jonathan Cameron <jonathan.cameron at huawei.com>
> diff --git a/arch/arm64/kvm/vgic/vgic-v5.c b/arch/arm64/kvm/vgic/vgic-v5.c
> index c7ecc4f40b1e5..f1fa63e67c1f6 100644
> --- a/arch/arm64/kvm/vgic/vgic-v5.c
> +++ b/arch/arm64/kvm/vgic/vgic-v5.c
> @@ -81,6 +81,66 @@ static u32 vgic_v5_get_effective_priority_mask(struct kvm_vcpu *vcpu)
> return priority_mask;
> }
>
> +static int vgic_v5_finalize_state(struct kvm_vcpu *vcpu)
> +{
> + if (!ppi_caps)
> + return -ENXIO;
> +
> + vcpu->arch.vgic_cpu.vgic_v5.vgic_ppi_mask[0] = 0;
> + vcpu->arch.vgic_cpu.vgic_v5.vgic_ppi_mask[1] = 0;
> + vcpu->arch.vgic_cpu.vgic_v5.vgic_ppi_hmr[0] = 0;
> + vcpu->arch.vgic_cpu.vgic_v5.vgic_ppi_hmr[1] = 0;
> + 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];
> +
> + raw_spin_lock(&irq->irq_lock);
> +
A little nicer perhaps with:
guard(raw_spin_lock(&irq->irq_lock);
> + /*
> + * We only expose PPIs with an owner or thw SW_PPI to
> + * the guest.
> + */
> + if (!irq->owner && irq->intid == GICV5_SW_PPI)
> + goto unlock;
and
continue;
> +
> + /*
> + * If the PPI isn't implemented, we can't pass it
> + * through to a guest anyhow.
> + */
> + if (!(ppi_caps->impl_ppi_mask[reg] & bit))
> + goto unlock;
and
continue;
> +
> + vcpu->arch.vgic_cpu.vgic_v5.vgic_ppi_mask[reg] |= bit;
> +
> + if (irq->config == VGIC_CONFIG_LEVEL)
> + vcpu->arch.vgic_cpu.vgic_v5.vgic_ppi_hmr[reg] |= bit;
> +
> +unlock:
> + raw_spin_unlock(&irq->irq_lock);
Then the label and unlock can go away.
> + }
> +
> + return 0;
> +}
More information about the linux-arm-kernel
mailing list