mirror of
https://github.com/torvalds/linux.git
synced 2026-04-18 06:44:00 -04:00
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: Sascha Bischoff <sascha.bischoff@arm.com> Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com> Reviewed-by: Joey Gouly <joey.gouly@arm.com> Link: https://patch.msgid.link/20260319154937.3619520-33-sascha.bischoff@arm.com Signed-off-by: Marc Zyngier <maz@kernel.org>
This commit is contained in:
committed by
Marc Zyngier
parent
9491c63b6c
commit
7c31c06e2d
@@ -37,7 +37,8 @@ Returns:
|
|||||||
A value describing the PMUv3 (Performance Monitor Unit v3) overflow interrupt
|
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
|
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
|
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
|
1.2 ATTRIBUTE: KVM_ARM_VCPU_PMU_V3_INIT
|
||||||
---------------------------------------
|
---------------------------------------
|
||||||
@@ -50,7 +51,7 @@ Returns:
|
|||||||
-EEXIST Interrupt number already used
|
-EEXIST Interrupt number already used
|
||||||
-ENODEV PMUv3 not supported or GIC not initialized
|
-ENODEV PMUv3 not supported or GIC not initialized
|
||||||
-ENXIO PMUv3 not supported, missing VCPU feature or interrupt
|
-ENXIO PMUv3 not supported, missing VCPU feature or interrupt
|
||||||
number not set
|
number not set (non-GICv5 guests, only)
|
||||||
-EBUSY PMUv3 already initialized
|
-EBUSY PMUv3 already initialized
|
||||||
======= ======================================================
|
======= ======================================================
|
||||||
|
|
||||||
|
|||||||
@@ -962,8 +962,13 @@ static int kvm_arm_pmu_v3_init(struct kvm_vcpu *vcpu)
|
|||||||
if (!vgic_initialized(vcpu->kvm))
|
if (!vgic_initialized(vcpu->kvm))
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
if (!kvm_arm_pmu_irq_initialized(vcpu))
|
if (!kvm_arm_pmu_irq_initialized(vcpu)) {
|
||||||
return -ENXIO;
|
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,
|
ret = kvm_vgic_set_owner(vcpu, vcpu->arch.pmu.irq_num,
|
||||||
&vcpu->arch.pmu);
|
&vcpu->arch.pmu);
|
||||||
@@ -988,6 +993,10 @@ static bool pmu_irq_is_valid(struct kvm *kvm, int irq)
|
|||||||
unsigned long i;
|
unsigned long i;
|
||||||
struct kvm_vcpu *vcpu;
|
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) {
|
kvm_for_each_vcpu(i, vcpu, kvm) {
|
||||||
if (!kvm_arm_pmu_irq_initialized(vcpu))
|
if (!kvm_arm_pmu_irq_initialized(vcpu))
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -12,6 +12,9 @@
|
|||||||
|
|
||||||
#define KVM_ARMV8_PMU_MAX_COUNTERS 32
|
#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)
|
#if IS_ENABLED(CONFIG_HW_PERF_EVENTS) && IS_ENABLED(CONFIG_KVM)
|
||||||
struct kvm_pmc {
|
struct kvm_pmc {
|
||||||
u8 idx; /* index into the pmu->pmc array */
|
u8 idx; /* index into the pmu->pmc array */
|
||||||
@@ -38,7 +41,7 @@ struct arm_pmu_entry {
|
|||||||
};
|
};
|
||||||
|
|
||||||
bool kvm_supports_guest_pmuv3(void);
|
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);
|
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(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);
|
void kvm_pmu_set_counter_value_user(struct kvm_vcpu *vcpu, u64 select_idx, u64 val);
|
||||||
|
|||||||
Reference in New Issue
Block a user