From 3f07cb2aabdfcc27ee30cf85c39619a82d364f83 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Mon, 4 Sep 2017 15:21:54 +0100 Subject: target/arm/kvm: pmu: split init and set-irq stages When adding a PMU with a userspace irqchip we skip the set-irq stage of device creation. Split the 'create' function into two functions 'init' and 'set-irq' so they may be called separately. Signed-off-by: Andrew Jones Reviewed-by: Christoffer Dall Message-id: 1500471597-2517-3-git-send-email-drjones@redhat.com Signed-off-by: Peter Maydell --- target/arm/kvm32.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'target/arm/kvm32.c') diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c index 069da0c5fd..e3aab89a1a 100644 --- a/target/arm/kvm32.c +++ b/target/arm/kvm32.c @@ -522,7 +522,13 @@ bool kvm_arm_hw_debug_active(CPUState *cs) return false; } -int kvm_arm_pmu_create(CPUState *cs, int irq) +int kvm_arm_pmu_set_irq(CPUState *cs, int irq) +{ + qemu_log_mask(LOG_UNIMP, "%s: not implemented\n", __func__); + return 0; +} + +int kvm_arm_pmu_init(CPUState *cs) { qemu_log_mask(LOG_UNIMP, "%s: not implemented\n", __func__); return 0; -- cgit v1.2.3-55-g7522 From b2bfe9f7f1f7e3aa5edf9c3c4c7408082778ae17 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Mon, 4 Sep 2017 15:21:54 +0100 Subject: target/arm/kvm: pmu: improve error handling If a KVM PMU init or set-irq attr call fails we just silently stop the PMU DT node generation. The only way they could fail, though, is if the attr's respective KVM has-attr call fails. But that should never happen if KVM advertises the PMU capability, because both attrs have been available since the capability was introduced. Let's just abort if this should-never-happen stuff does happen, because, if it does, then something is obviously horribly wrong. Signed-off-by: Andrew Jones Reviewed-by: Christoffer Dall Message-id: 1500471597-2517-5-git-send-email-drjones@redhat.com [PMM: change kvm32.c kvm_arm_pmu_init() to the new API too] Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/arm/virt.c | 9 +++------ target/arm/kvm32.c | 6 ++---- target/arm/kvm64.c | 28 ++++++++++++++++++++-------- target/arm/kvm_arm.h | 15 ++++----------- 4 files changed, 29 insertions(+), 29 deletions(-) (limited to 'target/arm/kvm32.c') diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 999f448af2..fe96557997 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -496,13 +496,10 @@ static void fdt_add_pmu_nodes(const VirtMachineState *vms) return; } if (kvm_enabled()) { - if (kvm_irqchip_in_kernel() && - !kvm_arm_pmu_set_irq(cpu, PPI(VIRTUAL_PMU_IRQ))) { - return; - } - if (!kvm_arm_pmu_init(cpu)) { - return; + if (kvm_irqchip_in_kernel()) { + kvm_arm_pmu_set_irq(cpu, PPI(VIRTUAL_PMU_IRQ)); } + kvm_arm_pmu_init(cpu); } } diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c index e3aab89a1a..f925a21481 100644 --- a/target/arm/kvm32.c +++ b/target/arm/kvm32.c @@ -522,14 +522,12 @@ bool kvm_arm_hw_debug_active(CPUState *cs) return false; } -int kvm_arm_pmu_set_irq(CPUState *cs, int irq) +void kvm_arm_pmu_set_irq(CPUState *cs, int irq) { qemu_log_mask(LOG_UNIMP, "%s: not implemented\n", __func__); - return 0; } -int kvm_arm_pmu_init(CPUState *cs) +void kvm_arm_pmu_init(CPUState *cs) { qemu_log_mask(LOG_UNIMP, "%s: not implemented\n", __func__); - return 0; } diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c index ec7d85314a..6554c30007 100644 --- a/target/arm/kvm64.c +++ b/target/arm/kvm64.c @@ -387,30 +387,36 @@ static bool kvm_arm_pmu_set_attr(CPUState *cs, struct kvm_device_attr *attr) err = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, attr); if (err != 0) { + error_report("PMU: KVM_HAS_DEVICE_ATTR: %s", strerror(-err)); return false; } err = kvm_vcpu_ioctl(cs, KVM_SET_DEVICE_ATTR, attr); - if (err < 0) { - fprintf(stderr, "KVM_SET_DEVICE_ATTR failed: %s\n", - strerror(-err)); - abort(); + if (err != 0) { + error_report("PMU: KVM_SET_DEVICE_ATTR: %s", strerror(-err)); + return false; } return true; } -int kvm_arm_pmu_init(CPUState *cs) +void kvm_arm_pmu_init(CPUState *cs) { struct kvm_device_attr attr = { .group = KVM_ARM_VCPU_PMU_V3_CTRL, .attr = KVM_ARM_VCPU_PMU_V3_INIT, }; - return kvm_arm_pmu_set_attr(cs, &attr); + if (!ARM_CPU(cs)->has_pmu) { + return; + } + if (!kvm_arm_pmu_set_attr(cs, &attr)) { + error_report("failed to init PMU"); + abort(); + } } -int kvm_arm_pmu_set_irq(CPUState *cs, int irq) +void kvm_arm_pmu_set_irq(CPUState *cs, int irq) { struct kvm_device_attr attr = { .group = KVM_ARM_VCPU_PMU_V3_CTRL, @@ -418,7 +424,13 @@ int kvm_arm_pmu_set_irq(CPUState *cs, int irq) .attr = KVM_ARM_VCPU_PMU_V3_IRQ, }; - return kvm_arm_pmu_set_attr(cs, &attr); + if (!ARM_CPU(cs)->has_pmu) { + return; + } + if (!kvm_arm_pmu_set_attr(cs, &attr)) { + error_report("failed to set irq for PMU"); + abort(); + } } static inline void set_feature(uint64_t *features, int feature) diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h index cab5ea9be5..ff53e9fafb 100644 --- a/target/arm/kvm_arm.h +++ b/target/arm/kvm_arm.h @@ -195,8 +195,8 @@ int kvm_arm_sync_mpstate_to_qemu(ARMCPU *cpu); int kvm_arm_vgic_probe(void); -int kvm_arm_pmu_set_irq(CPUState *cs, int irq); -int kvm_arm_pmu_init(CPUState *cs); +void kvm_arm_pmu_set_irq(CPUState *cs, int irq); +void kvm_arm_pmu_init(CPUState *cs); #else @@ -205,15 +205,8 @@ static inline int kvm_arm_vgic_probe(void) return 0; } -static inline int kvm_arm_pmu_set_irq(CPUState *cs, int irq) -{ - return 0; -} - -static inline int kvm_arm_pmu_init(CPUState *cs) -{ - return 0; -} +static inline void kvm_arm_pmu_set_irq(CPUState *cs, int irq) {} +static inline void kvm_arm_pmu_init(CPUState *cs) {} #endif -- cgit v1.2.3-55-g7522