aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Jones <drjones@redhat.com>2017-09-04 15:21:54 +0100
committerPeter Maydell <peter.maydell@linaro.org>2017-09-04 15:21:54 +0100
commitb2bfe9f7f1f7e3aa5edf9c3c4c7408082778ae17 (patch)
treec2630b47c2ac75da59e835987ca88230377a6006
parentb16595275bc9b9ce6a36bfb0344d514ab77e6b98 (diff)
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 <drjones@redhat.com> Reviewed-by: Christoffer Dall <cdall@linaro.org> 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 <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--hw/arm/virt.c9
-rw-r--r--target/arm/kvm32.c6
-rw-r--r--target/arm/kvm64.c28
-rw-r--r--target/arm/kvm_arm.h15
4 files changed, 29 insertions, 29 deletions
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