diff options
author | Andrew Jones <drjones@redhat.com> | 2019-08-02 14:25:27 +0200 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2019-08-16 14:02:51 +0100 |
commit | ae502508f83e06abddab3ac1a11dd822718472e1 (patch) | |
tree | 32ef947bcf0e5eef0348f1792c623ed186df44f6 /target | |
parent | b9e758f0b5bc64b5800432c0a436dd1afc98ba33 (diff) | |
download | qemu-ae502508f83e06abddab3ac1a11dd822718472e1.zip qemu-ae502508f83e06abddab3ac1a11dd822718472e1.tar.gz qemu-ae502508f83e06abddab3ac1a11dd822718472e1.tar.bz2 |
target/arm/cpu: Ensure we can use the pmu with kvm
We first convert the pmu property from a static property to one with
its own accessors. Then we use the set accessor to check if the PMU is
supported when using KVM. Indeed a 32-bit KVM host does not support
the PMU, so this check will catch an attempt to use it at property-set
time.
Signed-off-by: Andrew Jones <drjones@redhat.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target')
-rw-r--r-- | target/arm/cpu.c | 30 | ||||
-rw-r--r-- | target/arm/kvm.c | 7 | ||||
-rw-r--r-- | target/arm/kvm_arm.h | 14 |
3 files changed, 46 insertions, 5 deletions
diff --git a/target/arm/cpu.c b/target/arm/cpu.c index ec2ab95..2399c14 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -994,10 +994,6 @@ static Property arm_cpu_has_el3_property = static Property arm_cpu_cfgend_property = DEFINE_PROP_BOOL("cfgend", ARMCPU, cfgend, false); -/* use property name "pmu" to match other archs and virt tools */ -static Property arm_cpu_has_pmu_property = - DEFINE_PROP_BOOL("pmu", ARMCPU, has_pmu, true); - static Property arm_cpu_has_vfp_property = DEFINE_PROP_BOOL("vfp", ARMCPU, has_vfp, true); @@ -1020,6 +1016,29 @@ static Property arm_cpu_pmsav7_dregion_property = pmsav7_dregion, qdev_prop_uint32, uint32_t); +static bool arm_get_pmu(Object *obj, Error **errp) +{ + ARMCPU *cpu = ARM_CPU(obj); + + return cpu->has_pmu; +} + +static void arm_set_pmu(Object *obj, bool value, Error **errp) +{ + ARMCPU *cpu = ARM_CPU(obj); + + if (value) { + if (kvm_enabled() && !kvm_arm_pmu_supported(CPU(cpu))) { + error_setg(errp, "'pmu' feature not supported by KVM on this host"); + return; + } + set_feature(&cpu->env, ARM_FEATURE_PMU); + } else { + unset_feature(&cpu->env, ARM_FEATURE_PMU); + } + cpu->has_pmu = value; +} + static void arm_get_init_svtor(Object *obj, Visitor *v, const char *name, void *opaque, Error **errp) { @@ -1094,7 +1113,8 @@ void arm_cpu_post_init(Object *obj) } if (arm_feature(&cpu->env, ARM_FEATURE_PMU)) { - qdev_property_add_static(DEVICE(obj), &arm_cpu_has_pmu_property, + cpu->has_pmu = true; + object_property_add_bool(obj, "pmu", arm_get_pmu, arm_set_pmu, &error_abort); } diff --git a/target/arm/kvm.c b/target/arm/kvm.c index fe4f461..bfe3d44 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -162,6 +162,13 @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu) env->features = arm_host_cpu_features.features; } +bool kvm_arm_pmu_supported(CPUState *cpu) +{ + KVMState *s = KVM_STATE(current_machine->accelerator); + + return kvm_check_extension(s, KVM_CAP_ARM_PMU_V3); +} + int kvm_arm_get_max_vm_ipa_size(MachineState *ms) { KVMState *s = KVM_STATE(ms->accelerator); diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h index 98af105..b3106c8 100644 --- a/target/arm/kvm_arm.h +++ b/target/arm/kvm_arm.h @@ -217,6 +217,15 @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu); bool kvm_arm_aarch32_supported(CPUState *cs); /** + * bool kvm_arm_pmu_supported: + * @cs: CPUState + * + * Returns: true if the KVM VCPU can enable its PMU + * and false otherwise. + */ +bool kvm_arm_pmu_supported(CPUState *cs); + +/** * kvm_arm_get_max_vm_ipa_size - Returns the number of bits in the * IPA address space supported by KVM * @@ -261,6 +270,11 @@ static inline bool kvm_arm_aarch32_supported(CPUState *cs) return false; } +static inline bool kvm_arm_pmu_supported(CPUState *cs) +{ + return false; +} + static inline int kvm_arm_get_max_vm_ipa_size(MachineState *ms) { return -ENOENT; |