[PATCH v2 27/36] KVM: arm64: gic-v5: Mandate architected PPI for PMU emulation on GICv5

Sascha Bischoff Sascha.Bischoff at arm.com
Wed Jan 7 01:48:59 PST 2026


On Tue, 2026-01-06 at 15:06 +0000, Joey Gouly wrote:
> Question,
> 
> On Fri, Dec 19, 2025 at 03:52:45PM +0000, Sascha Bischoff wrote:
> > Make it mandatory to use the architected PPI when running a GICv5
> > guest. Attempts to set anything other than the architected PPI (23)
> > are rejected.
> > 
> > Signed-off-by: Sascha Bischoff <sascha.bischoff at arm.com>
> > ---
> >  arch/arm64/kvm/pmu-emul.c | 14 ++++++++++++--
> >  include/kvm/arm_pmu.h     |  5 ++++-
> >  2 files changed, 16 insertions(+), 3 deletions(-)
> > 
> > diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
> > index afc838ea2503e..2d3b50dec6c5d 100644
> > --- a/arch/arm64/kvm/pmu-emul.c
> > +++ b/arch/arm64/kvm/pmu-emul.c
> > @@ -962,8 +962,13 @@ static int kvm_arm_pmu_v3_init(struct kvm_vcpu
> > *vcpu)
> >  		if (!vgic_initialized(vcpu->kvm))
> >  			return -ENODEV;
> >  
> > -		if (!kvm_arm_pmu_irq_initialized(vcpu))
> > -			return -ENXIO;
> > +		if (!kvm_arm_pmu_irq_initialized(vcpu)) {
> > +			/* Use the architected irq number for
> > GICv5. */
> > +			if (vcpu->kvm->arch.vgic.vgic_model ==
> > KVM_DEV_TYPE_ARM_VGIC_V5)
> > +				vcpu->arch.pmu.irq_num =
> > KVM_ARMV8_PMU_GICV5_IRQ;
> > +			else
> > +				return -ENXIO;
> > +		}
> 
> This relaxes the KVM_ARM_VCPU_PMU_V3_INIT uAPI to not need
> KVM_ARM_VCPU_PMU_V3_IRQ to be called first for gic-v5, right?
> 
> Maybe that's intentional, but it should be mentioned in the commit
> and maybe
> even in the docs (Documentation/virt/kvm/devices/vcpu.rst)?
> 
> Thanks,
> Joey

Hi Joey,

That's a good point - it does relax that.

I'll go and bump that documentation. In addition, it should be
documented that GICv5 requires the architected PPI to be used
irrespective of making the IRQ init optional, so will call that out
too.

Thanks,
Sascha

> 
> >  
> >  		ret = kvm_vgic_set_owner(vcpu, vcpu-
> > >arch.pmu.irq_num,
> >  					 &vcpu->arch.pmu);
> > @@ -988,6 +993,11 @@ static bool pmu_irq_is_valid(struct kvm *kvm,
> > int irq)
> >  	unsigned long i;
> >  	struct kvm_vcpu *vcpu;
> >  
> > +	/* On GICv5, the PMUIRQ is architecturally mandated to be
> > PPI 23 */
> > +	if (kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V5
> > &&
> > +	    irq != KVM_ARMV8_PMU_GICV5_IRQ)
> > +		return false;
> > +
> >  	kvm_for_each_vcpu(i, vcpu, kvm) {
> >  		if (!kvm_arm_pmu_irq_initialized(vcpu))
> >  			continue;
> > diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h
> > index 96754b51b4116..0a36a3d5c8944 100644
> > --- a/include/kvm/arm_pmu.h
> > +++ b/include/kvm/arm_pmu.h
> > @@ -12,6 +12,9 @@
> >  
> >  #define KVM_ARMV8_PMU_MAX_COUNTERS	32
> >  
> > +/* PPI #23 - architecturally specified for GICv5 */
> > +#define KVM_ARMV8_PMU_GICV5_IRQ		0x20000017
> > +
> >  #if IS_ENABLED(CONFIG_HW_PERF_EVENTS) && IS_ENABLED(CONFIG_KVM)
> >  struct kvm_pmc {
> >  	u8 idx;	/* index into the pmu->pmc array */
> > @@ -38,7 +41,7 @@ struct arm_pmu_entry {
> >  };
> >  
> >  bool kvm_supports_guest_pmuv3(void);
> > -#define kvm_arm_pmu_irq_initialized(v)	((v)->arch.pmu.irq_num >=
> > VGIC_NR_SGIS)
> > +#define kvm_arm_pmu_irq_initialized(v)	((v)->arch.pmu.irq_num !=
> > 0)
> >  u64 kvm_pmu_get_counter_value(struct kvm_vcpu *vcpu, u64
> > select_idx);
> >  void kvm_pmu_set_counter_value(struct kvm_vcpu *vcpu, u64
> > select_idx, u64 val);
> >  void kvm_pmu_set_counter_value_user(struct kvm_vcpu *vcpu, u64
> > select_idx, u64 val);
> > -- 
> > 2.34.1



More information about the linux-arm-kernel mailing list