[PATCH v2 36/36] KVM: arm64: gic-v5: Communicate userspace-drivable PPIs via a UAPI

Jonathan Cameron jonathan.cameron at huawei.com
Wed Jan 7 08:51:10 PST 2026


On Fri, 19 Dec 2025 15:52:48 +0000
Sascha Bischoff <Sascha.Bischoff at arm.com> wrote:

> GICv5 systems will likely not support the full set of PPIs. The
> presence of any virtual PPI is tied to the presence of the physical
> PPI. Therefore, the available PPIs will be limited by the physical
> host. Userspace cannot drive any PPIs that are not implemented.
> 
> Moreover, it is not desirable to expose all PPIs to the guest in the
> first place, even if they are supported in hardware. Some devices,
> such as the arch timer, are implemented in KVM, and hence those PPIs
> shouldn't be driven by userspace, either.
> 
> Provided a new UAPI:
>   KVM_DEV_ARM_VGIC_GRP_CTRL => KVM_DEV_ARM_VGIC_USERPSPACE_PPIs
> 
> This allows userspace to query which PPIs it is able to drive via
> KVM_IRQ_LINE.
> 
> Signed-off-by: Sascha Bischoff <sascha.bischoff at arm.com>

A couple of trivial comments on this patch.

Overall, to me as a definite non expert in kvm GIC emulation this
series looks to be in a pretty good state.

Thanks,

Jonathan
> ---
>  .../virt/kvm/devices/arm-vgic-v5.rst          | 13 ++++++++++
>  arch/arm64/include/uapi/asm/kvm.h             |  1 +
>  arch/arm64/kvm/vgic/vgic-kvm-device.c         | 25 +++++++++++++++++++
>  arch/arm64/kvm/vgic/vgic-v5.c                 |  8 ++++++
>  include/kvm/arm_vgic.h                        |  5 ++++
>  include/linux/irqchip/arm-gic-v5.h            |  4 +++
>  tools/arch/arm64/include/uapi/asm/kvm.h       |  1 +
>  7 files changed, 57 insertions(+)
> 
> diff --git a/Documentation/virt/kvm/devices/arm-vgic-v5.rst b/Documentation/virt/kvm/devices/arm-vgic-v5.rst
> index 9904cb888277d..d9f2917b609c5 100644
> --- a/Documentation/virt/kvm/devices/arm-vgic-v5.rst
> +++ b/Documentation/virt/kvm/devices/arm-vgic-v5.rst
> @@ -25,6 +25,19 @@ Groups:
>        request the initialization of the VGIC, no additional parameter in
>        kvm_device_attr.addr. Must be called after all VCPUs have been created.
>  
> +   KVM_DEV_ARM_VGIC_USERPSPACE_PPIs
> +      request the mask of userspace-drivable PPIs. Only a subset of the PPIs can
> +      be directly driven from userspace with GICv5, and the returned mask
> +      informs userspace of which it is allowed to drive via KVM_IRQ_LINE.
> +
> +      Userspace must allocate and point to __u64[2] with of data in

with of?

> +      kvm_device_attr.addr. When this call returns, the provided memory will be
> +      populated with the userspace PPI mask. The lower __u64 contains the mask
> +      for the lower 64 PPIS, with the remaining 64 being in the second __u64.
> +
> +      This is a read-only attribute, and cannot be set. Attempts to set it are
> +      rejected.
> +
>    Errors:
>  
>      =======  ========================================================

> diff --git a/arch/arm64/kvm/vgic/vgic-kvm-device.c b/arch/arm64/kvm/vgic/vgic-kvm-device.c
> index 78903182bba08..360c78ed4f104 100644
> --- a/arch/arm64/kvm/vgic/vgic-kvm-device.c
> +++ b/arch/arm64/kvm/vgic/vgic-kvm-device.c
> @@ -719,6 +719,25 @@ struct kvm_device_ops kvm_arm_vgic_v3_ops = {
>  	.has_attr = vgic_v3_has_attr,
>  };
>  
> +static int vgic_v5_get_userspace_ppis(struct kvm_device *dev,
> +				      struct kvm_device_attr *attr)
> +{
> +	u64 __user *uaddr = (u64 __user *)(long)attr->addr;
> +	struct gicv5_vm *gicv5_vm = &dev->kvm->arch.vgic.gicv5_vm;
> +	int i, ret;
> +
> +	guard(mutex)(&dev->kvm->arch.config_lock);
> +
> +	for (i = 0; i < 2; ++i) {

Can drag declaration of i into loop init.
Also I just noticed the series is rather random wrt to pre or post increment
in cases where it doesn't matter. I'd go with post increment for for loops.
I took a quick look at a random file in this directory and that's what is used there.


> +		ret = put_user(gicv5_vm->userspace_ppis[i], uaddr);
> +		if (ret)
> +			return ret;
> +		uaddr++;
> +	}
> +
> +	return 0;
> +}

> diff --git a/arch/arm64/kvm/vgic/vgic-v5.c b/arch/arm64/kvm/vgic/vgic-v5.c
> index bf72982d6a2e8..04300926683b6 100644
> --- a/arch/arm64/kvm/vgic/vgic-v5.c
> +++ b/arch/arm64/kvm/vgic/vgic-v5.c
> @@ -122,6 +122,14 @@ int vgic_v5_init(struct kvm *kvm)
>  		}
>  	}
>  
> +	/*
> +	 * We only allow userspace to drive the SW_PPI, if it is
> +	 * implemented.
> +	 */

	/* We only allow userspace to drive the SW_PPI, if it is implemented. */

Is under 80 chars (just) so go with that.


> +	kvm->arch.vgic.gicv5_vm.userspace_ppis[0] = GICV5_SW_PPI & GICV5_HWIRQ_ID;
> +	kvm->arch.vgic.gicv5_vm.userspace_ppis[0] &= ppi_caps->impl_ppi_mask[0];
> +	kvm->arch.vgic.gicv5_vm.userspace_ppis[1] = 0;
> +
>  	return 0;
>  }





More information about the linux-arm-kernel mailing list