Commit 2defaff4 authored by Andre Przywara's avatar Andre Przywara Committed by Christoffer Dall

KVM: arm/arm64: pmu: abstract access to number of SPIs

Currently the PMU uses a member of the struct vgic_dist directly,
which not only breaks abstraction, but will fail with the new VGIC.
Abstract this access in the VGIC header file and refactor the validity
check in the PMU code.
Signed-off-by: default avatarAndre Przywara <andre.przywara@arm.com>
parent d5a5a0ef
...@@ -348,6 +348,8 @@ bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int virt_irq); ...@@ -348,6 +348,8 @@ bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int virt_irq);
#define irqchip_in_kernel(k) (!!((k)->arch.vgic.in_kernel)) #define irqchip_in_kernel(k) (!!((k)->arch.vgic.in_kernel))
#define vgic_initialized(k) (!!((k)->arch.vgic.nr_cpus)) #define vgic_initialized(k) (!!((k)->arch.vgic.nr_cpus))
#define vgic_ready(k) ((k)->arch.vgic.ready) #define vgic_ready(k) ((k)->arch.vgic.ready)
#define vgic_valid_spi(k, i) (((i) >= VGIC_NR_PRIVATE_IRQS) && \
((i) < (k)->arch.vgic.nr_irqs))
int vgic_v2_probe(const struct gic_kvm_info *gic_kvm_info, int vgic_v2_probe(const struct gic_kvm_info *gic_kvm_info,
const struct vgic_ops **ops, const struct vgic_ops **ops,
......
...@@ -436,7 +436,14 @@ static int kvm_arm_pmu_v3_init(struct kvm_vcpu *vcpu) ...@@ -436,7 +436,14 @@ static int kvm_arm_pmu_v3_init(struct kvm_vcpu *vcpu)
return 0; return 0;
} }
static bool irq_is_valid(struct kvm *kvm, int irq, bool is_ppi) #define irq_is_ppi(irq) ((irq) >= VGIC_NR_SGIS && (irq) < VGIC_NR_PRIVATE_IRQS)
/*
* For one VM 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.
*/
static bool pmu_irq_is_valid(struct kvm *kvm, int irq)
{ {
int i; int i;
struct kvm_vcpu *vcpu; struct kvm_vcpu *vcpu;
...@@ -445,7 +452,7 @@ static bool irq_is_valid(struct kvm *kvm, int irq, bool is_ppi) ...@@ -445,7 +452,7 @@ static bool irq_is_valid(struct kvm *kvm, int irq, bool is_ppi)
if (!kvm_arm_pmu_irq_initialized(vcpu)) if (!kvm_arm_pmu_irq_initialized(vcpu))
continue; continue;
if (is_ppi) { if (irq_is_ppi(irq)) {
if (vcpu->arch.pmu.irq_num != irq) if (vcpu->arch.pmu.irq_num != irq)
return false; return false;
} else { } else {
...@@ -457,7 +464,6 @@ static bool irq_is_valid(struct kvm *kvm, int irq, bool is_ppi) ...@@ -457,7 +464,6 @@ static bool irq_is_valid(struct kvm *kvm, int irq, bool is_ppi)
return true; return true;
} }
int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr) int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
{ {
switch (attr->attr) { switch (attr->attr) {
...@@ -471,14 +477,11 @@ int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr) ...@@ -471,14 +477,11 @@ int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
if (get_user(irq, uaddr)) if (get_user(irq, uaddr))
return -EFAULT; return -EFAULT;
/* /* The PMU overflow interrupt can be a PPI or a valid SPI. */
* The PMU overflow interrupt could be a PPI or SPI, but for one if (!(irq_is_ppi(irq) || vgic_valid_spi(vcpu->kvm, irq)))
* VM the interrupt type must be same for each vcpu. As a PPI, return -EINVAL;
* the interrupt number is the same for all vcpus, while as an
* SPI it must be a separate number per vcpu. if (!pmu_irq_is_valid(vcpu->kvm, irq))
*/
if (irq < VGIC_NR_SGIS || irq >= vcpu->kvm->arch.vgic.nr_irqs ||
!irq_is_valid(vcpu->kvm, irq, irq < VGIC_NR_PRIVATE_IRQS))
return -EINVAL; return -EINVAL;
if (kvm_arm_pmu_irq_initialized(vcpu)) if (kvm_arm_pmu_irq_initialized(vcpu))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment