Commit 7c31c06e authored by Sascha Bischoff's avatar Sascha Bischoff Committed by Marc Zyngier
Browse files

KVM: arm64: gic-v5: Mandate architected PPI for PMU emulation on GICv5



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.

Additionally, KVM_ARM_VCPU_PMU_V3_INIT is relaxed to no longer require
KVM_ARM_VCPU_PMU_V3_IRQ to be called for GICv5-based guests. In this
case, the architectued PPI is automatically used.

Documentation is bumped accordingly.

Signed-off-by: default avatarSascha Bischoff <sascha.bischoff@arm.com>
Reviewed-by: default avatarJonathan Cameron <jonathan.cameron@huawei.com>
Reviewed-by: default avatarJoey Gouly <joey.gouly@arm.com>
Link: https://patch.msgid.link/20260319154937.3619520-33-sascha.bischoff@arm.com


Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
parent 9491c63b
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -37,7 +37,8 @@ Returns:
A value describing the PMUv3 (Performance Monitor Unit v3) overflow interrupt
number for this vcpu. This interrupt could be a PPI or SPI, but the interrupt
type must be same for each vcpu. As a PPI, the interrupt number is the same for
all vcpus, while as an SPI it must be a separate number per vcpu.
all vcpus, while as an SPI it must be a separate number per vcpu. For
GICv5-based guests, the architected PPI (23) must be used.

1.2 ATTRIBUTE: KVM_ARM_VCPU_PMU_V3_INIT
---------------------------------------
@@ -50,7 +51,7 @@ Returns:
	 -EEXIST  Interrupt number already used
	 -ENODEV  PMUv3 not supported or GIC not initialized
	 -ENXIO   PMUv3 not supported, missing VCPU feature or interrupt
		  number not set
		  number not set (non-GICv5 guests, only)
	 -EBUSY   PMUv3 already initialized
	 =======  ======================================================

+11 −2
Original line number Diff line number Diff line
@@ -962,9 +962,14 @@ 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))
		if (!kvm_arm_pmu_irq_initialized(vcpu)) {
			if (!vgic_is_v5(vcpu->kvm))
				return -ENXIO;

			/* Use the architected irq number for GICv5. */
			vcpu->arch.pmu.irq_num = KVM_ARMV8_PMU_GICV5_IRQ;
		}

		ret = kvm_vgic_set_owner(vcpu, vcpu->arch.pmu.irq_num,
					 &vcpu->arch.pmu);
		if (ret)
@@ -988,6 +993,10 @@ 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 (vgic_is_v5(kvm) && irq != KVM_ARMV8_PMU_GICV5_IRQ)
		return false;

	kvm_for_each_vcpu(i, vcpu, kvm) {
		if (!kvm_arm_pmu_irq_initialized(vcpu))
			continue;
+4 −1
Original line number Diff line number Diff line
@@ -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);